From 48cd32116451c85c4b37b3a9474a61831bc9b66f Mon Sep 17 00:00:00 2001 From: Tom Close Date: Wed, 22 Nov 2023 16:11:41 +1100 Subject: [PATCH 001/224] setup auto conv --- .flake8 | 15 + .github/workflows/ci-cd.yaml | 305 ++++++++++++++ .gitignore | 10 +- .pre-commit-config.yaml | 3 +- LICENSE | 2 +- README.rst | 154 +++++++ codecov.yml | 2 - docs/Makefile | 20 + docs/conf.py | 51 +++ docs/index.rst | 15 + docs/make.bat | 35 ++ nipype-auto-conv/generate | 72 ++++ nipype-auto-conv/requirements.txt | 11 + nipype-auto-conv/specs/accuracy_tester.yaml | 80 ++++ .../specs/accuracy_tester_callables.py | 1 + nipype-auto-conv/specs/apply_mask.yaml | 91 ++++ .../specs/apply_mask_callables.py | 1 + nipype-auto-conv/specs/apply_topup.yaml | 173 ++++++++ .../specs/apply_topup_callables.py | 1 + nipype-auto-conv/specs/apply_warp.yaml | 126 ++++++ .../specs/apply_warp_callables.py | 1 + nipype-auto-conv/specs/apply_xfm.yaml | 224 ++++++++++ nipype-auto-conv/specs/apply_xfm_callables.py | 1 + nipype-auto-conv/specs/ar1_image.yaml | 92 +++++ nipype-auto-conv/specs/ar1_image_callables.py | 1 + nipype-auto-conv/specs/av_scale.yaml | 86 ++++ nipype-auto-conv/specs/av_scale_callables.py | 1 + nipype-auto-conv/specs/b0_calc.yaml | 163 ++++++++ nipype-auto-conv/specs/b0_calc_callables.py | 1 + nipype-auto-conv/specs/bedpostx5.yaml | 208 ++++++++++ nipype-auto-conv/specs/bedpostx5_callables.py | 1 + nipype-auto-conv/specs/bet.yaml | 198 +++++++++ nipype-auto-conv/specs/bet_callables.py | 1 + nipype-auto-conv/specs/binary_maths.yaml | 98 +++++ .../specs/binary_maths_callables.py | 1 + nipype-auto-conv/specs/change_data_type.yaml | 87 ++++ .../specs/change_data_type_callables.py | 1 + nipype-auto-conv/specs/classifier.yaml | 85 ++++ .../specs/classifier_callables.py | 1 + nipype-auto-conv/specs/cleaner.yaml | 92 +++++ nipype-auto-conv/specs/cleaner_callables.py | 1 + nipype-auto-conv/specs/cluster.yaml | 202 +++++++++ nipype-auto-conv/specs/cluster_callables.py | 1 + nipype-auto-conv/specs/complex.yaml | 164 ++++++++ nipype-auto-conv/specs/complex_callables.py | 1 + nipype-auto-conv/specs/contrast_mgr.yaml | 101 +++++ .../specs/contrast_mgr_callables.py | 1 + nipype-auto-conv/specs/convert_warp.yaml | 184 +++++++++ .../specs/convert_warp_callables.py | 1 + nipype-auto-conv/specs/convert_xfm.yaml | 149 +++++++ .../specs/convert_xfm_callables.py | 1 + nipype-auto-conv/specs/copy_geom.yaml | 87 ++++ nipype-auto-conv/specs/copy_geom_callables.py | 1 + nipype-auto-conv/specs/dilate_image.yaml | 97 +++++ .../specs/dilate_image_callables.py | 1 + nipype-auto-conv/specs/distance_map.yaml | 104 +++++ .../specs/distance_map_callables.py | 1 + nipype-auto-conv/specs/dti_fit.yaml | 203 +++++++++ nipype-auto-conv/specs/dti_fit_callables.py | 1 + nipype-auto-conv/specs/dual_regression.yaml | 167 ++++++++ .../specs/dual_regression_callables.py | 1 + nipype-auto-conv/specs/eddy.yaml | 375 +++++++++++++++++ nipype-auto-conv/specs/eddy_callables.py | 1 + nipype-auto-conv/specs/eddy_correct.yaml | 135 ++++++ .../specs/eddy_correct_callables.py | 1 + nipype-auto-conv/specs/eddy_quad.yaml | 172 ++++++++ nipype-auto-conv/specs/eddy_quad_callables.py | 1 + nipype-auto-conv/specs/epi_de_warp.yaml | 185 +++++++++ .../specs/epi_de_warp_callables.py | 1 + nipype-auto-conv/specs/epi_reg.yaml | 229 +++++++++++ nipype-auto-conv/specs/epi_reg_callables.py | 1 + nipype-auto-conv/specs/erode_image.yaml | 97 +++++ .../specs/erode_image_callables.py | 1 + nipype-auto-conv/specs/extract_roi.yaml | 172 ++++++++ .../specs/extract_roi_callables.py | 1 + nipype-auto-conv/specs/fast.yaml | 181 ++++++++ nipype-auto-conv/specs/fast_callables.py | 1 + nipype-auto-conv/specs/feat.yaml | 72 ++++ nipype-auto-conv/specs/feat_callables.py | 1 + nipype-auto-conv/specs/feat_model.yaml | 86 ++++ .../specs/feat_model_callables.py | 1 + nipype-auto-conv/specs/feat_register.yaml | 74 ++++ .../specs/feat_register_callables.py | 1 + nipype-auto-conv/specs/feature_extractor.yaml | 71 ++++ .../specs/feature_extractor_callables.py | 1 + nipype-auto-conv/specs/filmgls.yaml | 152 +++++++ nipype-auto-conv/specs/filmgls_callables.py | 1 + nipype-auto-conv/specs/filter_regressor.yaml | 100 +++++ .../specs/filter_regressor_callables.py | 1 + nipype-auto-conv/specs/find_the_biggest.yaml | 135 ++++++ .../specs/find_the_biggest_callables.py | 1 + nipype-auto-conv/specs/first.yaml | 109 +++++ nipype-auto-conv/specs/first_callables.py | 1 + nipype-auto-conv/specs/flameo.yaml | 196 +++++++++ nipype-auto-conv/specs/flameo_callables.py | 1 + nipype-auto-conv/specs/flirt.yaml | 277 +++++++++++++ nipype-auto-conv/specs/flirt_callables.py | 1 + nipype-auto-conv/specs/fnirt.yaml | 264 ++++++++++++ nipype-auto-conv/specs/fnirt_callables.py | 1 + nipype-auto-conv/specs/fslx_command.yaml | 130 ++++++ .../specs/fslx_command_callables.py | 1 + nipype-auto-conv/specs/fugue.yaml | 387 ++++++++++++++++++ nipype-auto-conv/specs/fugue_callables.py | 1 + nipype-auto-conv/specs/glm.yaml | 201 +++++++++ nipype-auto-conv/specs/glm_callables.py | 1 + nipype-auto-conv/specs/ica__aroma.yaml | 191 +++++++++ .../specs/ica__aroma_callables.py | 1 + nipype-auto-conv/specs/image_maths.yaml | 156 +++++++ .../specs/image_maths_callables.py | 1 + nipype-auto-conv/specs/image_meants.yaml | 103 +++++ .../specs/image_meants_callables.py | 1 + nipype-auto-conv/specs/image_stats.yaml | 139 +++++++ .../specs/image_stats_callables.py | 1 + nipype-auto-conv/specs/inv_warp.yaml | 157 +++++++ nipype-auto-conv/specs/inv_warp_callables.py | 1 + nipype-auto-conv/specs/isotropic_smooth.yaml | 91 ++++ .../specs/isotropic_smooth_callables.py | 1 + nipype-auto-conv/specs/l2_model.yaml | 78 ++++ nipype-auto-conv/specs/l2_model_callables.py | 1 + nipype-auto-conv/specs/level_1_design.yaml | 85 ++++ .../specs/level_1_design_callables.py | 1 + .../specs/make_dyadic_vectors.yaml | 91 ++++ .../specs/make_dyadic_vectors_callables.py | 1 + nipype-auto-conv/specs/maths_command.yaml | 87 ++++ .../specs/maths_command_callables.py | 1 + nipype-auto-conv/specs/max_image.yaml | 133 ++++++ nipype-auto-conv/specs/max_image_callables.py | 1 + nipype-auto-conv/specs/maxn_image.yaml | 92 +++++ .../specs/maxn_image_callables.py | 1 + nipype-auto-conv/specs/mcflirt.yaml | 188 +++++++++ nipype-auto-conv/specs/mcflirt_callables.py | 1 + nipype-auto-conv/specs/mean_image.yaml | 89 ++++ .../specs/mean_image_callables.py | 1 + nipype-auto-conv/specs/median_image.yaml | 89 ++++ .../specs/median_image_callables.py | 1 + nipype-auto-conv/specs/melodic.yaml | 291 +++++++++++++ nipype-auto-conv/specs/melodic_callables.py | 1 + nipype-auto-conv/specs/merge.yaml | 154 +++++++ nipype-auto-conv/specs/merge_callables.py | 1 + nipype-auto-conv/specs/min_image.yaml | 89 ++++ nipype-auto-conv/specs/min_image_callables.py | 1 + nipype-auto-conv/specs/motion_outliers.yaml | 154 +++++++ .../specs/motion_outliers_callables.py | 1 + nipype-auto-conv/specs/multi_image_maths.yaml | 153 +++++++ .../specs/multi_image_maths_callables.py | 1 + .../specs/multiple_regress_design.yaml | 94 +++++ .../multiple_regress_design_callables.py | 1 + nipype-auto-conv/specs/overlay.yaml | 124 ++++++ nipype-auto-conv/specs/overlay_callables.py | 1 + nipype-auto-conv/specs/percentile_image.yaml | 136 ++++++ .../specs/percentile_image_callables.py | 1 + .../specs/plot_motion_params.yaml | 110 +++++ .../specs/plot_motion_params_callables.py | 1 + nipype-auto-conv/specs/plot_time_series.yaml | 120 ++++++ .../specs/plot_time_series_callables.py | 1 + nipype-auto-conv/specs/power_spectrum.yaml | 92 +++++ .../specs/power_spectrum_callables.py | 1 + nipype-auto-conv/specs/prelude.yaml | 128 ++++++ nipype-auto-conv/specs/prelude_callables.py | 1 + nipype-auto-conv/specs/prepare_fieldmap.yaml | 153 +++++++ .../specs/prepare_fieldmap_callables.py | 1 + nipype-auto-conv/specs/prob_track_x.yaml | 273 ++++++++++++ nipype-auto-conv/specs/prob_track_x2.yaml | 296 ++++++++++++++ .../specs/prob_track_x2_callables.py | 1 + .../specs/prob_track_x_callables.py | 1 + nipype-auto-conv/specs/proj_thresh.yaml | 124 ++++++ .../specs/proj_thresh_callables.py | 1 + nipype-auto-conv/specs/randomise.yaml | 191 +++++++++ nipype-auto-conv/specs/randomise_callables.py | 1 + nipype-auto-conv/specs/reorient_2_std.yaml | 93 +++++ .../specs/reorient_2_std_callables.py | 1 + nipype-auto-conv/specs/robust_fov.yaml | 96 +++++ .../specs/robust_fov_callables.py | 1 + nipype-auto-conv/specs/sig_loss.yaml | 100 +++++ nipype-auto-conv/specs/sig_loss_callables.py | 1 + nipype-auto-conv/specs/slice.yaml | 125 ++++++ nipype-auto-conv/specs/slice_callables.py | 1 + nipype-auto-conv/specs/slice_timer.yaml | 107 +++++ .../specs/slice_timer_callables.py | 1 + nipype-auto-conv/specs/slicer.yaml | 130 ++++++ nipype-auto-conv/specs/slicer_callables.py | 1 + nipype-auto-conv/specs/smm.yaml | 88 ++++ nipype-auto-conv/specs/smm_callables.py | 1 + nipype-auto-conv/specs/smooth.yaml | 239 +++++++++++ nipype-auto-conv/specs/smooth_callables.py | 1 + nipype-auto-conv/specs/smooth_estimate.yaml | 130 ++++++ .../specs/smooth_estimate_callables.py | 1 + nipype-auto-conv/specs/spatial_filter.yaml | 97 +++++ .../specs/spatial_filter_callables.py | 1 + nipype-auto-conv/specs/split.yaml | 78 ++++ nipype-auto-conv/specs/split_callables.py | 1 + nipype-auto-conv/specs/std_image.yaml | 91 ++++ nipype-auto-conv/specs/std_image_callables.py | 1 + nipype-auto-conv/specs/susan.yaml | 105 +++++ nipype-auto-conv/specs/susan_callables.py | 1 + nipype-auto-conv/specs/swap_dimensions.yaml | 90 ++++ .../specs/swap_dimensions_callables.py | 1 + nipype-auto-conv/specs/temporal_filter.yaml | 94 +++++ .../specs/temporal_filter_callables.py | 1 + nipype-auto-conv/specs/text_2_vest.yaml | 133 ++++++ .../specs/text_2_vest_callables.py | 1 + nipype-auto-conv/specs/threshold.yaml | 95 +++++ nipype-auto-conv/specs/threshold_callables.py | 1 + nipype-auto-conv/specs/topup.yaml | 217 ++++++++++ nipype-auto-conv/specs/topup_callables.py | 1 + nipype-auto-conv/specs/tract_skeleton.yaml | 135 ++++++ .../specs/tract_skeleton_callables.py | 1 + nipype-auto-conv/specs/training.yaml | 78 ++++ nipype-auto-conv/specs/training_callables.py | 1 + .../specs/training_set_creator.yaml | 73 ++++ .../specs/training_set_creator_callables.py | 1 + nipype-auto-conv/specs/unary_maths.yaml | 89 ++++ .../specs/unary_maths_callables.py | 1 + nipype-auto-conv/specs/vec_reg.yaml | 170 ++++++++ nipype-auto-conv/specs/vec_reg_callables.py | 1 + nipype-auto-conv/specs/vest_2_text.yaml | 126 ++++++ .../specs/vest_2_text_callables.py | 1 + nipype-auto-conv/specs/warp_points.yaml | 169 ++++++++ .../specs/warp_points_callables.py | 1 + .../specs/warp_points_from_std.yaml | 162 ++++++++ .../specs/warp_points_from_std_callables.py | 1 + .../specs/warp_points_to_std.yaml | 175 ++++++++ .../specs/warp_points_to_std_callables.py | 1 + nipype-auto-conv/specs/warp_utils.yaml | 172 ++++++++ .../specs/warp_utils_callables.py | 1 + nipype-auto-conv/specs/x_fibres_5.yaml | 135 ++++++ .../specs/x_fibres_5_callables.py | 1 + pydra/tasks/fsl/__init__.py | 35 +- pydra/tasks/fsl/latest.py | 3 + pydra/tasks/fsl/v1/__init__.py | 0 pyproject.toml | 78 ++-- related-packages/conftest.py | 37 ++ related-packages/fileformats-extras/LICENSE | 13 + .../fileformats-extras/README.rst | 29 ++ .../extras/medimage_fsl/__init__.py | 13 + .../fileformats-extras/pyproject.toml | 87 ++++ related-packages/fileformats/LICENSE | 13 + related-packages/fileformats/README.rst | 39 ++ .../fileformats/medimage_fsl/__init__.py | 5 + related-packages/fileformats/pyproject.toml | 84 ++++ 240 files changed, 16296 insertions(+), 46 deletions(-) create mode 100644 .flake8 create mode 100644 .github/workflows/ci-cd.yaml create mode 100644 README.rst create mode 100644 docs/Makefile create mode 100644 docs/conf.py create mode 100644 docs/index.rst create mode 100644 docs/make.bat create mode 100755 nipype-auto-conv/generate create mode 100644 nipype-auto-conv/requirements.txt create mode 100644 nipype-auto-conv/specs/accuracy_tester.yaml create mode 100644 nipype-auto-conv/specs/accuracy_tester_callables.py create mode 100644 nipype-auto-conv/specs/apply_mask.yaml create mode 100644 nipype-auto-conv/specs/apply_mask_callables.py create mode 100644 nipype-auto-conv/specs/apply_topup.yaml create mode 100644 nipype-auto-conv/specs/apply_topup_callables.py create mode 100644 nipype-auto-conv/specs/apply_warp.yaml create mode 100644 nipype-auto-conv/specs/apply_warp_callables.py create mode 100644 nipype-auto-conv/specs/apply_xfm.yaml create mode 100644 nipype-auto-conv/specs/apply_xfm_callables.py create mode 100644 nipype-auto-conv/specs/ar1_image.yaml create mode 100644 nipype-auto-conv/specs/ar1_image_callables.py create mode 100644 nipype-auto-conv/specs/av_scale.yaml create mode 100644 nipype-auto-conv/specs/av_scale_callables.py create mode 100644 nipype-auto-conv/specs/b0_calc.yaml create mode 100644 nipype-auto-conv/specs/b0_calc_callables.py create mode 100644 nipype-auto-conv/specs/bedpostx5.yaml create mode 100644 nipype-auto-conv/specs/bedpostx5_callables.py create mode 100644 nipype-auto-conv/specs/bet.yaml create mode 100644 nipype-auto-conv/specs/bet_callables.py create mode 100644 nipype-auto-conv/specs/binary_maths.yaml create mode 100644 nipype-auto-conv/specs/binary_maths_callables.py create mode 100644 nipype-auto-conv/specs/change_data_type.yaml create mode 100644 nipype-auto-conv/specs/change_data_type_callables.py create mode 100644 nipype-auto-conv/specs/classifier.yaml create mode 100644 nipype-auto-conv/specs/classifier_callables.py create mode 100644 nipype-auto-conv/specs/cleaner.yaml create mode 100644 nipype-auto-conv/specs/cleaner_callables.py create mode 100644 nipype-auto-conv/specs/cluster.yaml create mode 100644 nipype-auto-conv/specs/cluster_callables.py create mode 100644 nipype-auto-conv/specs/complex.yaml create mode 100644 nipype-auto-conv/specs/complex_callables.py create mode 100644 nipype-auto-conv/specs/contrast_mgr.yaml create mode 100644 nipype-auto-conv/specs/contrast_mgr_callables.py create mode 100644 nipype-auto-conv/specs/convert_warp.yaml create mode 100644 nipype-auto-conv/specs/convert_warp_callables.py create mode 100644 nipype-auto-conv/specs/convert_xfm.yaml create mode 100644 nipype-auto-conv/specs/convert_xfm_callables.py create mode 100644 nipype-auto-conv/specs/copy_geom.yaml create mode 100644 nipype-auto-conv/specs/copy_geom_callables.py create mode 100644 nipype-auto-conv/specs/dilate_image.yaml create mode 100644 nipype-auto-conv/specs/dilate_image_callables.py create mode 100644 nipype-auto-conv/specs/distance_map.yaml create mode 100644 nipype-auto-conv/specs/distance_map_callables.py create mode 100644 nipype-auto-conv/specs/dti_fit.yaml create mode 100644 nipype-auto-conv/specs/dti_fit_callables.py create mode 100644 nipype-auto-conv/specs/dual_regression.yaml create mode 100644 nipype-auto-conv/specs/dual_regression_callables.py create mode 100644 nipype-auto-conv/specs/eddy.yaml create mode 100644 nipype-auto-conv/specs/eddy_callables.py create mode 100644 nipype-auto-conv/specs/eddy_correct.yaml create mode 100644 nipype-auto-conv/specs/eddy_correct_callables.py create mode 100644 nipype-auto-conv/specs/eddy_quad.yaml create mode 100644 nipype-auto-conv/specs/eddy_quad_callables.py create mode 100644 nipype-auto-conv/specs/epi_de_warp.yaml create mode 100644 nipype-auto-conv/specs/epi_de_warp_callables.py create mode 100644 nipype-auto-conv/specs/epi_reg.yaml create mode 100644 nipype-auto-conv/specs/epi_reg_callables.py create mode 100644 nipype-auto-conv/specs/erode_image.yaml create mode 100644 nipype-auto-conv/specs/erode_image_callables.py create mode 100644 nipype-auto-conv/specs/extract_roi.yaml create mode 100644 nipype-auto-conv/specs/extract_roi_callables.py create mode 100644 nipype-auto-conv/specs/fast.yaml create mode 100644 nipype-auto-conv/specs/fast_callables.py create mode 100644 nipype-auto-conv/specs/feat.yaml create mode 100644 nipype-auto-conv/specs/feat_callables.py create mode 100644 nipype-auto-conv/specs/feat_model.yaml create mode 100644 nipype-auto-conv/specs/feat_model_callables.py create mode 100644 nipype-auto-conv/specs/feat_register.yaml create mode 100644 nipype-auto-conv/specs/feat_register_callables.py create mode 100644 nipype-auto-conv/specs/feature_extractor.yaml create mode 100644 nipype-auto-conv/specs/feature_extractor_callables.py create mode 100644 nipype-auto-conv/specs/filmgls.yaml create mode 100644 nipype-auto-conv/specs/filmgls_callables.py create mode 100644 nipype-auto-conv/specs/filter_regressor.yaml create mode 100644 nipype-auto-conv/specs/filter_regressor_callables.py create mode 100644 nipype-auto-conv/specs/find_the_biggest.yaml create mode 100644 nipype-auto-conv/specs/find_the_biggest_callables.py create mode 100644 nipype-auto-conv/specs/first.yaml create mode 100644 nipype-auto-conv/specs/first_callables.py create mode 100644 nipype-auto-conv/specs/flameo.yaml create mode 100644 nipype-auto-conv/specs/flameo_callables.py create mode 100644 nipype-auto-conv/specs/flirt.yaml create mode 100644 nipype-auto-conv/specs/flirt_callables.py create mode 100644 nipype-auto-conv/specs/fnirt.yaml create mode 100644 nipype-auto-conv/specs/fnirt_callables.py create mode 100644 nipype-auto-conv/specs/fslx_command.yaml create mode 100644 nipype-auto-conv/specs/fslx_command_callables.py create mode 100644 nipype-auto-conv/specs/fugue.yaml create mode 100644 nipype-auto-conv/specs/fugue_callables.py create mode 100644 nipype-auto-conv/specs/glm.yaml create mode 100644 nipype-auto-conv/specs/glm_callables.py create mode 100644 nipype-auto-conv/specs/ica__aroma.yaml create mode 100644 nipype-auto-conv/specs/ica__aroma_callables.py create mode 100644 nipype-auto-conv/specs/image_maths.yaml create mode 100644 nipype-auto-conv/specs/image_maths_callables.py create mode 100644 nipype-auto-conv/specs/image_meants.yaml create mode 100644 nipype-auto-conv/specs/image_meants_callables.py create mode 100644 nipype-auto-conv/specs/image_stats.yaml create mode 100644 nipype-auto-conv/specs/image_stats_callables.py create mode 100644 nipype-auto-conv/specs/inv_warp.yaml create mode 100644 nipype-auto-conv/specs/inv_warp_callables.py create mode 100644 nipype-auto-conv/specs/isotropic_smooth.yaml create mode 100644 nipype-auto-conv/specs/isotropic_smooth_callables.py create mode 100644 nipype-auto-conv/specs/l2_model.yaml create mode 100644 nipype-auto-conv/specs/l2_model_callables.py create mode 100644 nipype-auto-conv/specs/level_1_design.yaml create mode 100644 nipype-auto-conv/specs/level_1_design_callables.py create mode 100644 nipype-auto-conv/specs/make_dyadic_vectors.yaml create mode 100644 nipype-auto-conv/specs/make_dyadic_vectors_callables.py create mode 100644 nipype-auto-conv/specs/maths_command.yaml create mode 100644 nipype-auto-conv/specs/maths_command_callables.py create mode 100644 nipype-auto-conv/specs/max_image.yaml create mode 100644 nipype-auto-conv/specs/max_image_callables.py create mode 100644 nipype-auto-conv/specs/maxn_image.yaml create mode 100644 nipype-auto-conv/specs/maxn_image_callables.py create mode 100644 nipype-auto-conv/specs/mcflirt.yaml create mode 100644 nipype-auto-conv/specs/mcflirt_callables.py create mode 100644 nipype-auto-conv/specs/mean_image.yaml create mode 100644 nipype-auto-conv/specs/mean_image_callables.py create mode 100644 nipype-auto-conv/specs/median_image.yaml create mode 100644 nipype-auto-conv/specs/median_image_callables.py create mode 100644 nipype-auto-conv/specs/melodic.yaml create mode 100644 nipype-auto-conv/specs/melodic_callables.py create mode 100644 nipype-auto-conv/specs/merge.yaml create mode 100644 nipype-auto-conv/specs/merge_callables.py create mode 100644 nipype-auto-conv/specs/min_image.yaml create mode 100644 nipype-auto-conv/specs/min_image_callables.py create mode 100644 nipype-auto-conv/specs/motion_outliers.yaml create mode 100644 nipype-auto-conv/specs/motion_outliers_callables.py create mode 100644 nipype-auto-conv/specs/multi_image_maths.yaml create mode 100644 nipype-auto-conv/specs/multi_image_maths_callables.py create mode 100644 nipype-auto-conv/specs/multiple_regress_design.yaml create mode 100644 nipype-auto-conv/specs/multiple_regress_design_callables.py create mode 100644 nipype-auto-conv/specs/overlay.yaml create mode 100644 nipype-auto-conv/specs/overlay_callables.py create mode 100644 nipype-auto-conv/specs/percentile_image.yaml create mode 100644 nipype-auto-conv/specs/percentile_image_callables.py create mode 100644 nipype-auto-conv/specs/plot_motion_params.yaml create mode 100644 nipype-auto-conv/specs/plot_motion_params_callables.py create mode 100644 nipype-auto-conv/specs/plot_time_series.yaml create mode 100644 nipype-auto-conv/specs/plot_time_series_callables.py create mode 100644 nipype-auto-conv/specs/power_spectrum.yaml create mode 100644 nipype-auto-conv/specs/power_spectrum_callables.py create mode 100644 nipype-auto-conv/specs/prelude.yaml create mode 100644 nipype-auto-conv/specs/prelude_callables.py create mode 100644 nipype-auto-conv/specs/prepare_fieldmap.yaml create mode 100644 nipype-auto-conv/specs/prepare_fieldmap_callables.py create mode 100644 nipype-auto-conv/specs/prob_track_x.yaml create mode 100644 nipype-auto-conv/specs/prob_track_x2.yaml create mode 100644 nipype-auto-conv/specs/prob_track_x2_callables.py create mode 100644 nipype-auto-conv/specs/prob_track_x_callables.py create mode 100644 nipype-auto-conv/specs/proj_thresh.yaml create mode 100644 nipype-auto-conv/specs/proj_thresh_callables.py create mode 100644 nipype-auto-conv/specs/randomise.yaml create mode 100644 nipype-auto-conv/specs/randomise_callables.py create mode 100644 nipype-auto-conv/specs/reorient_2_std.yaml create mode 100644 nipype-auto-conv/specs/reorient_2_std_callables.py create mode 100644 nipype-auto-conv/specs/robust_fov.yaml create mode 100644 nipype-auto-conv/specs/robust_fov_callables.py create mode 100644 nipype-auto-conv/specs/sig_loss.yaml create mode 100644 nipype-auto-conv/specs/sig_loss_callables.py create mode 100644 nipype-auto-conv/specs/slice.yaml create mode 100644 nipype-auto-conv/specs/slice_callables.py create mode 100644 nipype-auto-conv/specs/slice_timer.yaml create mode 100644 nipype-auto-conv/specs/slice_timer_callables.py create mode 100644 nipype-auto-conv/specs/slicer.yaml create mode 100644 nipype-auto-conv/specs/slicer_callables.py create mode 100644 nipype-auto-conv/specs/smm.yaml create mode 100644 nipype-auto-conv/specs/smm_callables.py create mode 100644 nipype-auto-conv/specs/smooth.yaml create mode 100644 nipype-auto-conv/specs/smooth_callables.py create mode 100644 nipype-auto-conv/specs/smooth_estimate.yaml create mode 100644 nipype-auto-conv/specs/smooth_estimate_callables.py create mode 100644 nipype-auto-conv/specs/spatial_filter.yaml create mode 100644 nipype-auto-conv/specs/spatial_filter_callables.py create mode 100644 nipype-auto-conv/specs/split.yaml create mode 100644 nipype-auto-conv/specs/split_callables.py create mode 100644 nipype-auto-conv/specs/std_image.yaml create mode 100644 nipype-auto-conv/specs/std_image_callables.py create mode 100644 nipype-auto-conv/specs/susan.yaml create mode 100644 nipype-auto-conv/specs/susan_callables.py create mode 100644 nipype-auto-conv/specs/swap_dimensions.yaml create mode 100644 nipype-auto-conv/specs/swap_dimensions_callables.py create mode 100644 nipype-auto-conv/specs/temporal_filter.yaml create mode 100644 nipype-auto-conv/specs/temporal_filter_callables.py create mode 100644 nipype-auto-conv/specs/text_2_vest.yaml create mode 100644 nipype-auto-conv/specs/text_2_vest_callables.py create mode 100644 nipype-auto-conv/specs/threshold.yaml create mode 100644 nipype-auto-conv/specs/threshold_callables.py create mode 100644 nipype-auto-conv/specs/topup.yaml create mode 100644 nipype-auto-conv/specs/topup_callables.py create mode 100644 nipype-auto-conv/specs/tract_skeleton.yaml create mode 100644 nipype-auto-conv/specs/tract_skeleton_callables.py create mode 100644 nipype-auto-conv/specs/training.yaml create mode 100644 nipype-auto-conv/specs/training_callables.py create mode 100644 nipype-auto-conv/specs/training_set_creator.yaml create mode 100644 nipype-auto-conv/specs/training_set_creator_callables.py create mode 100644 nipype-auto-conv/specs/unary_maths.yaml create mode 100644 nipype-auto-conv/specs/unary_maths_callables.py create mode 100644 nipype-auto-conv/specs/vec_reg.yaml create mode 100644 nipype-auto-conv/specs/vec_reg_callables.py create mode 100644 nipype-auto-conv/specs/vest_2_text.yaml create mode 100644 nipype-auto-conv/specs/vest_2_text_callables.py create mode 100644 nipype-auto-conv/specs/warp_points.yaml create mode 100644 nipype-auto-conv/specs/warp_points_callables.py create mode 100644 nipype-auto-conv/specs/warp_points_from_std.yaml create mode 100644 nipype-auto-conv/specs/warp_points_from_std_callables.py create mode 100644 nipype-auto-conv/specs/warp_points_to_std.yaml create mode 100644 nipype-auto-conv/specs/warp_points_to_std_callables.py create mode 100644 nipype-auto-conv/specs/warp_utils.yaml create mode 100644 nipype-auto-conv/specs/warp_utils_callables.py create mode 100644 nipype-auto-conv/specs/x_fibres_5.yaml create mode 100644 nipype-auto-conv/specs/x_fibres_5_callables.py create mode 100644 pydra/tasks/fsl/latest.py create mode 100644 pydra/tasks/fsl/v1/__init__.py create mode 100644 related-packages/conftest.py create mode 100644 related-packages/fileformats-extras/LICENSE create mode 100644 related-packages/fileformats-extras/README.rst create mode 100644 related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py create mode 100644 related-packages/fileformats-extras/pyproject.toml create mode 100644 related-packages/fileformats/LICENSE create mode 100644 related-packages/fileformats/README.rst create mode 100644 related-packages/fileformats/fileformats/medimage_fsl/__init__.py create mode 100644 related-packages/fileformats/pyproject.toml diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..40e811e --- /dev/null +++ b/.flake8 @@ -0,0 +1,15 @@ + +[flake8] +doctests = True +exclude = + **/__init__.py + *build/ + docs/sphinxext/ + docs/tools/ + docs/conf.py + docs/source/conf.py +max-line-length = 88 +select = C,E,F,W,B,B950 +extend-ignore = E203,E501,E129,W503 +per-file-ignores = + __init__.py:F401,F403 diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml new file mode 100644 index 0000000..d1dc4fd --- /dev/null +++ b/.github/workflows/ci-cd.yaml @@ -0,0 +1,305 @@ +#This workflow will install Python dependencies, run tests and lint with a variety of Python versions +# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions + +# For deployment, it will be necessary to create a PyPI API token and store it as a secret +# https://docs.github.com/en/actions/reference/encrypted-secrets + +name: CI/CD + +on: + push: + branches: [ main, develop ] + tags: [ '*' ] + pull_request: + branches: [ main, develop ] + repository_dispatch: + types: [create-release] + +jobs: + + nipype-conv: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Revert version to most recent tag on upstream update + if: github.event_name == 'repository_dispatch' + run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + - name: Install build dependencies + run: python -m pip install --upgrade pip + - name: Install requirements + run: python -m pip install ./related-packages/fileformats -r ./nipype-auto-conv/requirements.txt + - name: Run automatic Nipype > Pydra conversion + run: ./nipype-auto-conv/generate + - uses: actions/upload-artifact@v3 + with: + name: converted-nipype + path: pydra/tasks/fsl/auto + + devcheck: + needs: [nipype-conv] + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.8', '3.11'] # Check oldest and newest versions + pip-flags: ['', '--editable'] + pydra: + - 'pydra' + - '--editable git+https://github.com/nipype/pydra.git#egg=pydra' + steps: + - name: Checkout + uses: actions/checkout@v3 + - name: Revert version to most recent tag on upstream update + if: github.event_name == 'repository_dispatch' + run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + - name: Download tasks converted from Nipype + uses: actions/download-artifact@v3 + with: + name: converted-nipype + path: pydra/tasks/fsl/auto + - name: Strip auto package from gitignore so it is included in package + run: | + sed -i '/\/pydra\/tasks\/fsl\/auto/d' .gitignore + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + - name: Install Pydra + run: | + pushd $HOME + pip install ${{ matrix.pydra }} + popd + python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + - name: Install task package + run: | + pip install "./related-packages/fileformats[dev]" "related-packages/fileformats-extras[dev]" + pip install ${{ matrix.pip-flags }} ".[dev]" + python -c "import pydra.tasks.fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + python -c "import fileformats.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + python -c "import fileformats.extras.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + + fileformats-test: + runs-on: ubuntu-latest + strategy: + matrix: + python-version: ['3.8', '3.11'] + steps: + - uses: actions/checkout@v3 + - name: Revert version to most recent tag on upstream update + if: github.event_name == 'repository_dispatch' + run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + - name: Install task package + run: | + pip install "./related-packages/fileformats[test]" "./related-packages/fileformats-extras[test]" + python -c "import fileformats.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + - name: Test fileformats with pytest + run: | + cd ./fileformats + pytest -sv --cov fileformats.medimage_fsl --cov fileformats.extras.medimage_fsl --cov-report xml . + + test: + needs: [nipype-conv, fileformats-test] + runs-on: ubuntu-22.04 + strategy: + matrix: + python-version: ['3.8'] # '3.11' + steps: + - name: Removed unnecessary tools to free space + run: | + sudo rm -rf /usr/share/dotnet + sudo rm -rf "$AGENT_TOOLSDIRECTORY" + - name: Get Download cache Key + id: cache-key + run: echo "::set-output name=key::fsl-linux-ubuntu22_amd64-7.4.1" + - name: Cache FreeSurfer + uses: actions/cache@v2 + with: + path: $HOME/downloads/fsl + key: ${{ steps.cache-key.outputs.key }} + restore-keys: | + fsl-linux-ubuntu22_amd64-7.4.1 + - name: Download FreeSurfer + if: steps.cache-key.outputs.key != steps.cache-hit.outputs.key + run: | + mkdir -p $HOME/downloads/fsl + curl -s -o $HOME/downloads/fsl/fsl-linux-ubuntu22_amd64-7.4.1.tar.gz https://surfer.nmr.mgh.harvard.edu/pub/dist/fsl/7.4.1/fsl-linux-ubuntu22_amd64-7.4.1.tar.gz + shell: bash + - name: Install Freesurfer + env: + FREESURFER_LICENCE: ${{ secrets.FREESURFER_LICENCE }} + run: | + pushd $HOME/downloads/fsl + tar -zxpf fsl-linux-ubuntu22_amd64-7.4.1.tar.gz + mv fsl $HOME/ + popd + export FREESURFER_HOME=$HOME/fsl + source $FREESURFER_HOME/SetUpFreeSurfer.sh + echo $FREESURFER_LICENCE > $FREESURFER_HOME/license.txt + export PATH=$FREESURFER_HOME/bin:$PATH + - uses: actions/checkout@v3 + - name: Revert version to most recent tag on upstream update + if: github.event_name == 'repository_dispatch' + run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + - name: Download tasks converted from Nipype + uses: actions/download-artifact@v3 + with: + name: converted-nipype + path: pydra/tasks/fsl/auto + - name: Strip auto package from gitignore so it is included in package + run: | + sed -i '/\/src\/pydra\/tasks\/fsl\/auto/d' .gitignore + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install build dependencies + run: | + python -m pip install --upgrade pip + - name: Install task package + run: | + pip install "./related-packages/fileformats" "./related-packages/fileformats-extras" ".[test]" + python -c "import pydra.tasks.fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + - name: Test with pytest + run: | + pytest -sv --doctest-modules ./pydra/tasks/fsl \ + --cov pydra.tasks.fsl --cov-report xml + - uses: codecov/codecov-action@v3 + if: ${{ always() }} + with: + files: coverage.xml,./fileformats/coverage.xml + name: pydra-fsl + + deploy-fileformats: + needs: [devcheck, test] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install build tools + run: python -m pip install build twine + - name: Build source and wheel distributions + run: python -m build ./related-packages/fileformats + - name: Check distributions + run: twine check ./related-packages/fileformats/dist/* + - name: Check for PyPI token on tag + id: deployable + if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || github.event_name == 'repository_dispatch' + env: + PYPI_API_TOKEN: "${{ secrets.PYPI_FILEFORMATS_API_TOKEN }}" + run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI + if: steps.deployable.outputs.DEPLOY + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_FILEFORMATS_API_TOKEN }} + packages-dir: ./related-packages/fileformats/dist + + deploy-fileformats-extras: + needs: [deploy-fileformats] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install build tools + run: python -m pip install build twine + - name: Build source and wheel distributions + run: python -m build ./related-packages/fileformats-extras + - name: Check distributions + run: twine check ./related-packages/fileformats-extras/dist/* + - name: Check for PyPI token on tag + id: deployable + if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || github.event_name == 'repository_dispatch' + env: + PYPI_API_TOKEN: "${{ secrets.PYPI_FILEFORMATS_EXTRAS_API_TOKEN }}" + run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI + if: steps.deployable.outputs.DEPLOY + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_FILEFORMATS_EXTRAS_API_TOKEN }} + packages-dir: ./related-packages/fileformats-extras/dist + + deploy: + needs: [deploy-fileformats-extras] + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + fetch-depth: 0 + - name: Download tasks converted from Nipype + uses: actions/download-artifact@v3 + with: + name: converted-nipype + path: pydra/tasks/fsl/auto + - name: Tag release with a post-release based on Nipype and Nipype2Pydra versions + if: github.event_name == 'repository_dispatch' + run: | + TAG=$(git tag -l | tail -n 1 | awk -F post '{print $1}') + POST=$(python -c "from pydra.tasks.fsl.auto._version import *; print(post_release)") + git checkout $TAG + git add -f pydra/tasks/fsl/auto/_version.py + git commit -am"added auto-generated version to make new tag for package version" + git tag ${TAG}post${POST} + - name: Set up Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + - name: Install build tools + run: python -m pip install build twine + - name: Strip auto package from gitignore so it is included in package + run: | + sed -i '/\/pydra\/tasks\/fsl\/auto/d' .gitignore + - name: Build source and wheel distributions + run: python -m build . + - name: Check distributions + run: twine check dist/* + - uses: actions/upload-artifact@v3 + with: + name: distributions + path: dist/ + - name: Check for PyPI token on tag + id: deployable + if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || github.event_name == 'repository_dispatch' + env: + PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" + run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI + if: steps.deployable.outputs.DEPLOY + uses: pypa/gh-action-pypi-publish@release/v1 + with: + user: __token__ + password: ${{ secrets.PYPI_API_TOKEN }} + +# Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. +# Secrets are not accessible in the if: condition [0], so set an output variable [1] +# [0] https://github.community/t/16928 +# [1] https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter \ No newline at end of file diff --git a/.gitignore b/.gitignore index b57b697..600b434 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -.DS_Store # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] @@ -131,3 +130,12 @@ dmypy.json # Pycharm .idea + +# VS Code +.vscode + +# Mac garbarge +.DS_store + +/pydra/tasks/fsl/auto +/pydra/tasks/fsl/_version.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index d0b7515..6cc0006 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,6 @@ repos: - id: check-yaml - id: check-added-large-files - repo: https://github.com/psf/black - rev: 23.1.0 + rev: 22.12.0 hooks: - id: black - exclude: (_version\.py|versioneer\.py)$ diff --git a/LICENSE b/LICENSE index b826500..e00bcb3 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,4 @@ - Copyright 2020-2021 Nipype developers + Copyright 2021 Nipype developers Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.rst b/README.rst new file mode 100644 index 0000000..c78a403 --- /dev/null +++ b/README.rst @@ -0,0 +1,154 @@ +=============================== +Pydra task package for fsl +=============================== + +.. image:: https://github.com/nipype/pydra-fsl/actions/workflows/pythonpackage.yaml/badge.svg + :target: https://github.com/nipype/pydra-fsl/actions/workflows/pythonpackage.yaml +.. .. image:: https://codecov.io/gh/nipype/pydra-fsl/branch/main/graph/badge.svg?token=UIS0OGPST7 +.. :target: https://codecov.io/gh/nipype/pydra-fsl +.. image:: https://img.shields.io/pypi/pyversions/pydra-fsl.svg + :target: https://pypi.python.org/pypi/pydra-fsl/ + :alt: Supported Python versions +.. image:: https://img.shields.io/pypi/v/pydra-fsl.svg + :target: https://pypi.python.org/pypi/pydra-fsl/ + :alt: Latest Version + + +This package contains a collection of Pydra task interfaces for the fsl toolkit. +The basis of this collection has been formed by the semi-automatic conversion of +existing `Nipype `__ interfaces to Pydra using the +`Nipype2Pydra `__ tool + + +Automatically-generated vs manually-curated tasks +------------------------------------------------- + +Automatically generated tasks can be found in the `pydra.tasks.fsl.auto` package. +These packages should be treated with extreme caution as they likely do not pass testing. +Generated tasks that have been edited and pass testing are imported into one or more of the +`pydra.tasks.fsl.v*` packages, corresponding to the version of the fsl toolkit +they are designed for. + +Tests +----- + +This package comes with a battery of automatically generated test modules. To install +the necessary dependencies to run the tests + +.. code-block:: + + $ pip install -e .[test] + +Then the tests, including `doctests` `__, can be launched using + +.. code-block:: + + $ pytest --doctest-modules pydra/tasks/* + +By default, the tests are set to time-out after 10s, after which the underlying tool is +assumed to have passed the validation/initialisation phase and we assume that it will +run to completion. To disable this and run the test(s) through to completion run + +.. code-block:: + + $ pytest --doctest-modules --timeout-pass 0 pydra/tasks/* + +Continuous integration +---------------------- + +This template uses `GitHub Actions `__` to run tests and +deploy packages to PYPI. New packages are built and uploaded when releases are created on +GitHub, or new releases of Nipype or the Nipype2Pydra conversion tool are released. +Releases triggered by updates to Nipype or Nipype2Pydra are signified by the `postN` +suffix where `N = ` with the '.'s stripped, e.g. +`v0.2.3post185010` corresponds to the v0.2.3 tag of this repository with auto-generated +packages from Nipype 1.8.5 using Nipype2Pydra 0.1.0. + + +Contributing to this package +---------------------------- + +Developer installation +~~~~~~~~~~~~~~~~~~~~~~ + + +Install repo in developer mode from the source directory and install pre-commit to +ensure consistent code-style and quality. + +.. code-block:: + + $ pip install -e .[test,dev] +$ pre-commit install + +Next install the requirements for running the auto-conversion script and generate the +Pydra task interfaces from their Nipype counterparts + +.. code-block:: + + $ pip install -r nipype-auto-conv/requirements.txt + +The run the conversion script to convert Nipype interfaces to Pydra + +.. code-block:: + + $ nipype-auto-conv/generate + +## Methodology + +The development of this package is expected to have two phases + +1. Where the corresponding Nipype interfaces are considered to be the ground truth, and + the Pydra tasks are generated from them +2. When the Pydra tasks are considered be mature and they are edited by hand + +Different tasks will probably mature at different times so there will probably be an +intermediate phase between 1 and 2. + +Auto-conversion phase +~~~~~~~~~~~~~~~~~~~~~ + +The auto-converted Pydra tasks are generated from their corresponding Nipype interface +in combination with "conversion hints" contained in YAML specs +located in `nipype-auto-conv/specs/`. The self-documented conversion specs are +to be edited by hand in order to assist the auto-converter produce valid pydra tasks. +After editing one or more conversion specs the `pydra.tasks.fsl.auto` package should +be regenerated by running + +.. code-block:: + + $ nipype-auto-conv/generate + +The tests should be run on the auto-generated tasks to see if they are valid + +.. code-block:: + + $ pytest --doctest-modules pydra/tasks/fsl/auto/tests/test_.py + +If the test passes you should then edit the `pydra/tasks/fsl/v/__init__.py` file +to import the now valid task interface to signify that it has been validated and is ready +for use, e.g. + +.. code-block::python + + from pydra.tasks.fsl.auto import + + +Typing and sample test data +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The automatically generated tests will attempt to provided the task instance to be tested +with sensible default values based on the type of the field and any constraints it has +on it. However, these will often need to be manually overridden after consulting the +underlying tool's documentation. + +For file-based data, automatically generated file-system objects will be created for +selected format types, e.g. Nifti, Dicom. Therefore, it is important to specify the +format of the file using the "mime-like" string corresponding to a +`fileformats `__ class +in the ``inputs > types`` and ``outputs > types`` dicts of the YAML spec. + +If the required file-type is not found implemented within fileformats, please see the `fileformats +docs `__ for instructions on how to define +new fileformat types, and see +`fileformats-medimage-extras `__ +for an example on how to implement methods to generate sample data for them. diff --git a/codecov.yml b/codecov.yml index bbf806c..a203b50 100644 --- a/codecov.yml +++ b/codecov.yml @@ -3,8 +3,6 @@ coverage: ignore: # files and folders that will be removed during processing - "**/tests" - "**/_version.py" - - "setup.py" - - "versioneer.py" status: project: default: diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..d4bb2cb --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,20 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line, and also +# from the environment for the first two. +SPHINXOPTS ?= +SPHINXBUILD ?= sphinx-build +SOURCEDIR = . +BUILDDIR = _build + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..66d60bd --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,51 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath('.')) + + +# -- Project information ----------------------------------------------------- + +project = "pydra-fsl" +copyright = "2020, Xihe Xie" +author = "Xihe Xie" + + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom +# ones. +extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "alabaster" + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = ["_static"] diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..81d6410 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,15 @@ +Welcome to pydra-fsl's documentation! +========================================= + +.. toctree:: + :maxdepth: 2 + :caption: Contents: + + + +Indices and tables +================== + +* :ref:`genindex` +* :ref:`modindex` +* :ref:`search` diff --git a/docs/make.bat b/docs/make.bat new file mode 100644 index 0000000..922152e --- /dev/null +++ b/docs/make.bat @@ -0,0 +1,35 @@ +@ECHO OFF + +pushd %~dp0 + +REM Command file for Sphinx documentation + +if "%SPHINXBUILD%" == "" ( + set SPHINXBUILD=sphinx-build +) +set SOURCEDIR=. +set BUILDDIR=_build + +if "%1" == "" goto help + +%SPHINXBUILD% >NUL 2>NUL +if errorlevel 9009 ( + echo. + echo.The 'sphinx-build' command was not found. Make sure you have Sphinx + echo.installed, then set the SPHINXBUILD environment variable to point + echo.to the full path of the 'sphinx-build' executable. Alternatively you + echo.may add the Sphinx directory to PATH. + echo. + echo.If you don't have Sphinx installed, grab it from + echo.http://sphinx-doc.org/ + exit /b 1 +) + +%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% +goto end + +:help +%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% + +:end +popd diff --git a/nipype-auto-conv/generate b/nipype-auto-conv/generate new file mode 100755 index 0000000..e77ca16 --- /dev/null +++ b/nipype-auto-conv/generate @@ -0,0 +1,72 @@ +#!/usr/bin/env python3 +import sys +import os.path +from warnings import warn +from pathlib import Path +import shutil +from importlib import import_module +import yaml +import nipype +import nipype2pydra.utils +from nipype2pydra.task import TaskConverter + + +SPECS_DIR = Path(__file__).parent / "specs" +PKG_ROOT = Path(__file__).parent.parent +PKG_NAME = "fsl" + +if ".dev" in nipype.__version__: + raise RuntimeError( + f"Cannot use a development version of Nipype {nipype.__version__}" + ) + +if ".dev" in nipype2pydra.__version__: + warn( + f"using development version of nipype2pydra ({nipype2pydra.__version__}), " + f"development component will be dropped in {PKG_NAME} package version" + ) + +# Insert specs dir into path so we can load callables modules +sys.path.insert(0, str(SPECS_DIR)) + +auto_init = f"# Auto-generated by {__file__}, do not edit as it will be overwritten\n\n" + +auto_dir = PKG_ROOT / "pydra" / "tasks" / PKG_NAME / "auto" +if auto_dir.exists(): + shutil.rmtree(auto_dir) + +for fspath in sorted(SPECS_DIR.glob("**/*.yaml")): + with open(fspath) as f: + spec = yaml.load(f, Loader=yaml.SafeLoader) + + rel_pkg_path = str(fspath.parent.relative_to(SPECS_DIR)).replace(os.path.sep, ".") + if rel_pkg_path == ".": + rel_pkg_path = fspath.stem + else: + rel_pkg_path += "." + fspath.stem + + callables = import_module(rel_pkg_path + "_callables") + + module_name = nipype2pydra.utils.to_snake_case(spec["task_name"]) + + converter = TaskConverter( + output_module=f"pydra.tasks.{PKG_NAME}.auto.{module_name}", + callables_module=callables, # type: ignore + **spec, + ) + converter.generate(PKG_ROOT) + auto_init += f"from .{module_name} import {converter.task_name}\n" + + +with open(PKG_ROOT / "pydra" / "tasks" / PKG_NAME / "auto" / "_version.py", "w") as f: + f.write( + f"""# Auto-generated by {__file__}, do not edit as it will be overwritten + +nipype_version = "{nipype.__version__.split('.dev')[0]}" +nipype2pydra_version = "{nipype2pydra.__version__.split('.dev')[0]}" +post_release = (nipype_version + nipype2pydra_version).replace(".", "") +""" + ) + +with open(PKG_ROOT / "pydra" / "tasks" / PKG_NAME / "auto" / "__init__.py", "w") as f: + f.write(auto_init) diff --git a/nipype-auto-conv/requirements.txt b/nipype-auto-conv/requirements.txt new file mode 100644 index 0000000..fccc3a6 --- /dev/null +++ b/nipype-auto-conv/requirements.txt @@ -0,0 +1,11 @@ +black +attrs>=22.1.0 +nipype +pydra +PyYAML>=6.0 +fileformats >=0.8 +fileformats-medimage >=0.4 +fileformats-datascience >= 0.1 +fileformats-medimage-fsl +traits +nipype2pydra \ No newline at end of file diff --git a/nipype-auto-conv/specs/accuracy_tester.yaml b/nipype-auto-conv/specs/accuracy_tester.yaml new file mode 100644 index 0000000..fb17bf4 --- /dev/null +++ b/nipype-auto-conv/specs/accuracy_tester.yaml @@ -0,0 +1,80 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.fix.AccuracyTester' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Test the accuracy of an existing training dataset on a set of hand-labelled subjects. +# Note: This may or may not be working. Couldn't presently not confirm because fix fails on this (even outside of nipype) without leaving an error msg. +# +task_name: AccuracyTester +nipype_name: AccuracyTester +nipype_module: nipype.interfaces.fsl.fix +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mel_icas: generic/file+list-of + # type=inputmultiobject|default=[]: Melodic output directories + trained_wts_file: generic/file + # type=file|default=: trained-weights file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mel_icas: + # type=inputmultiobject|default=[]: Melodic output directories + trained_wts_file: + # type=file|default=: trained-weights file + output_directory: + # type=directory: Path to folder in which to store the results of the accuracy test. + # type=directory|default=: Path to folder in which to store the results of the accuracy test. + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/accuracy_tester_callables.py b/nipype-auto-conv/specs/accuracy_tester_callables.py new file mode 100644 index 0000000..5c3eb00 --- /dev/null +++ b/nipype-auto-conv/specs/accuracy_tester_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in AccuracyTester.yaml""" diff --git a/nipype-auto-conv/specs/apply_mask.yaml b/nipype-auto-conv/specs/apply_mask.yaml new file mode 100644 index 0000000..617a7b3 --- /dev/null +++ b/nipype-auto-conv/specs/apply_mask.yaml @@ -0,0 +1,91 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.ApplyMask' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to apply a binary mask to another image. +task_name: ApplyMask +nipype_name: ApplyMask +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mask_file: generic/file + # type=file|default=: binary image defining mask space + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mask_file: + # type=file|default=: binary image defining mask space + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/apply_mask_callables.py b/nipype-auto-conv/specs/apply_mask_callables.py new file mode 100644 index 0000000..ce0e94d --- /dev/null +++ b/nipype-auto-conv/specs/apply_mask_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ApplyMask.yaml""" diff --git a/nipype-auto-conv/specs/apply_topup.yaml b/nipype-auto-conv/specs/apply_topup.yaml new file mode 100644 index 0000000..29127fb --- /dev/null +++ b/nipype-auto-conv/specs/apply_topup.yaml @@ -0,0 +1,173 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.ApplyTOPUP' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Interface for FSL topup, a tool for estimating and correcting +# susceptibility induced distortions. +# `General reference +# `_ +# and `use example +# `_. +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import ApplyTOPUP +# >>> applytopup = ApplyTOPUP() +# >>> applytopup.inputs.in_files = ["epi.nii", "epi_rev.nii"] +# >>> applytopup.inputs.encoding_file = "topup_encoding.txt" +# >>> applytopup.inputs.in_topup_fieldcoef = "topup_fieldcoef.nii.gz" +# >>> applytopup.inputs.in_topup_movpar = "topup_movpar.txt" +# >>> applytopup.inputs.output_type = "NIFTI_GZ" +# >>> applytopup.cmdline # doctest: +ELLIPSIS +# 'applytopup --datain=topup_encoding.txt --imain=epi.nii,epi_rev.nii --inindex=1,2 --topup=topup --out=epi_corrected.nii.gz' +# >>> res = applytopup.run() # doctest: +SKIP +# +# +task_name: ApplyTOPUP +nipype_name: ApplyTOPUP +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: name of file with images + encoding_file: text/text-file + # type=file|default=: name of text file with PE directions/times + in_topup_fieldcoef: medimage/nifti-gz + # type=file|default=: topup file containing the field coefficients + in_topup_movpar: text/text-file + # type=file|default=: topup movpar.txt file + out_corrected: generic/file + # type=file: name of 4D image file with unwarped images + # type=file|default=: output (warped) image + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_corrected: generic/file + # type=file: name of 4D image file with unwarped images + # type=file|default=: output (warped) image + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: name of file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + in_index: + # type=list|default=[]: comma separated list of indices corresponding to --datain + in_topup_fieldcoef: + # type=file|default=: topup file containing the field coefficients + in_topup_movpar: + # type=file|default=: topup movpar.txt file + out_corrected: + # type=file: name of 4D image file with unwarped images + # type=file|default=: output (warped) image + method: + # type=enum|default='jac'|allowed['jac','lsr']: use jacobian modulation (jac) or least-squares resampling (lsr) + interp: + # type=enum|default='trilinear'|allowed['spline','trilinear']: interpolation method + datatype: + # type=enum|default='char'|allowed['char','double','float','int','short']: force output data type + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: name of file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + in_topup_fieldcoef: + # type=file|default=: topup file containing the field coefficients + in_topup_movpar: + # type=file|default=: topup movpar.txt file + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: applytopup --datain=topup_encoding.txt --imain=epi.nii,epi_rev.nii --inindex=1,2 --topup=topup --out=epi_corrected.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_files: + # type=inputmultiobject|default=[]: name of file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + in_topup_fieldcoef: + # type=file|default=: topup file containing the field coefficients + in_topup_movpar: + # type=file|default=: topup movpar.txt file + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/apply_topup_callables.py b/nipype-auto-conv/specs/apply_topup_callables.py new file mode 100644 index 0000000..62f411a --- /dev/null +++ b/nipype-auto-conv/specs/apply_topup_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ApplyTOPUP.yaml""" diff --git a/nipype-auto-conv/specs/apply_warp.yaml b/nipype-auto-conv/specs/apply_warp.yaml new file mode 100644 index 0000000..348c504 --- /dev/null +++ b/nipype-auto-conv/specs/apply_warp.yaml @@ -0,0 +1,126 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.ApplyWarp' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL's applywarp wrapper to apply the results of a FNIRT registration +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import example_data +# >>> aw = fsl.ApplyWarp() +# >>> aw.inputs.in_file = example_data('structural.nii') +# >>> aw.inputs.ref_file = example_data('mni.nii') +# >>> aw.inputs.field_file = 'my_coefficients_filed.nii' #doctest: +SKIP +# >>> res = aw.run() #doctest: +SKIP +# +# +# +task_name: ApplyWarp +nipype_name: ApplyWarp +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to be warped + ref_file: generic/file + # type=file|default=: reference image + field_file: generic/file + # type=file|default=: file containing warp field + premat: generic/file + # type=file|default=: filename for pre-transform (affine matrix) + postmat: generic/file + # type=file|default=: filename for post-transform (affine matrix) + mask_file: generic/file + # type=file|default=: filename for mask image (in reference space) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: Warped output file + # type=file|default=: output filename + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: Warped output file + # type=file|default=: output filename + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to be warped + out_file: + # type=file: Warped output file + # type=file|default=: output filename + ref_file: + # type=file|default=: reference image + field_file: + # type=file|default=: file containing warp field + abswarp: + # type=bool|default=False: treat warp field as absolute: x' = w(x) + relwarp: + # type=bool|default=False: treat warp field as relative: x' = x + w(x) + datatype: + # type=enum|default='char'|allowed['char','double','float','int','short']: Force output data type [char short int float double]. + supersample: + # type=bool|default=False: intermediary supersampling of output, default is off + superlevel: + # type=traitcompound|default=None: level of intermediary supersampling, a for 'automatic' or integer level. Default = 2 + premat: + # type=file|default=: filename for pre-transform (affine matrix) + postmat: + # type=file|default=: filename for post-transform (affine matrix) + mask_file: + # type=file|default=: filename for mask image (in reference space) + interp: + # type=enum|default='nn'|allowed['nn','sinc','spline','trilinear']: interpolation method + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/apply_warp_callables.py b/nipype-auto-conv/specs/apply_warp_callables.py new file mode 100644 index 0000000..827cf9f --- /dev/null +++ b/nipype-auto-conv/specs/apply_warp_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ApplyWarp.yaml""" diff --git a/nipype-auto-conv/specs/apply_xfm.yaml b/nipype-auto-conv/specs/apply_xfm.yaml new file mode 100644 index 0000000..fa55e07 --- /dev/null +++ b/nipype-auto-conv/specs/apply_xfm.yaml @@ -0,0 +1,224 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.ApplyXFM' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Currently just a light wrapper around FLIRT, +# with no modifications +# +# ApplyXFM is used to apply an existing transform to an image +# +# +# Examples +# -------- +# +# >>> import nipype.interfaces.fsl as fsl +# >>> from nipype.testing import example_data +# >>> applyxfm = fsl.preprocess.ApplyXFM() +# >>> applyxfm.inputs.in_file = example_data('structural.nii') +# >>> applyxfm.inputs.in_matrix_file = example_data('trans.mat') +# >>> applyxfm.inputs.out_file = 'newfile.nii' +# >>> applyxfm.inputs.reference = example_data('mni.nii') +# >>> applyxfm.inputs.apply_xfm = True +# >>> result = applyxfm.run() # doctest: +SKIP +# +# +task_name: ApplyXFM +nipype_name: ApplyXFM +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input file + reference: generic/file + # type=file|default=: reference file + out_file: generic/file + # type=file: path/name of registered file (if generated) + # type=file|default=: registered output file + out_matrix_file: generic/file + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format + out_log: generic/file + # type=file: path/name of output log (if generated) + # type=file|default=: output log + in_matrix_file: generic/file + # type=file|default=: input 4x4 affine matrix + schedule: generic/file + # type=file|default=: replaces default schedule + ref_weight: generic/file + # type=file|default=: File for reference weighting volume + in_weight: generic/file + # type=file|default=: File for input weighting volume + wm_seg: generic/file + # type=file|default=: white matter segmentation volume needed by BBR cost function + wmcoords: generic/file + # type=file|default=: white matter boundary coordinates for BBR cost function + wmnorms: generic/file + # type=file|default=: white matter boundary normals for BBR cost function + fieldmap: generic/file + # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image + fieldmapmask: generic/file + # type=file|default=: mask for fieldmap image + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: path/name of registered file (if generated) + # type=file|default=: registered output file + out_matrix_file: generic/file + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format + out_log: generic/file + # type=file: path/name of output log (if generated) + # type=file|default=: output log + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + apply_xfm: + # type=bool|default=True: apply transformation supplied by in_matrix_file or uses_qform to use the affine matrix stored in the reference header + in_file: + # type=file|default=: input file + reference: + # type=file|default=: reference file + out_file: + # type=file: path/name of registered file (if generated) + # type=file|default=: registered output file + out_matrix_file: + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format + out_log: + # type=file: path/name of output log (if generated) + # type=file|default=: output log + in_matrix_file: + # type=file|default=: input 4x4 affine matrix + apply_isoxfm: + # type=float|default=0.0: as applyxfm but forces isotropic resampling + datatype: + # type=enum|default='char'|allowed['char','double','float','int','short']: force output data type + cost: + # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function + cost_func: + # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function + uses_qform: + # type=bool|default=False: initialize using sform or qform + display_init: + # type=bool|default=False: display initial matrix + angle_rep: + # type=enum|default='quaternion'|allowed['euler','quaternion']: representation of rotation angles + interp: + # type=enum|default='trilinear'|allowed['nearestneighbour','sinc','spline','trilinear']: final interpolation method used in reslicing + sinc_width: + # type=int|default=0: full-width in voxels + sinc_window: + # type=enum|default='rectangular'|allowed['blackman','hanning','rectangular']: sinc window + bins: + # type=int|default=0: number of histogram bins + dof: + # type=int|default=0: number of transform degrees of freedom + no_resample: + # type=bool|default=False: do not change input sampling + force_scaling: + # type=bool|default=False: force rescaling even for low-res images + min_sampling: + # type=float|default=0.0: set minimum voxel dimension for sampling + padding_size: + # type=int|default=0: for applyxfm: interpolates outside image by size + searchr_x: + # type=list|default=[]: search angles along x-axis, in degrees + searchr_y: + # type=list|default=[]: search angles along y-axis, in degrees + searchr_z: + # type=list|default=[]: search angles along z-axis, in degrees + no_search: + # type=bool|default=False: set all angular searches to ranges 0 to 0 + coarse_search: + # type=int|default=0: coarse search delta angle + fine_search: + # type=int|default=0: fine search delta angle + schedule: + # type=file|default=: replaces default schedule + ref_weight: + # type=file|default=: File for reference weighting volume + in_weight: + # type=file|default=: File for input weighting volume + no_clamp: + # type=bool|default=False: do not use intensity clamping + no_resample_blur: + # type=bool|default=False: do not use blurring on downsampling + rigid2D: + # type=bool|default=False: use 2D rigid body mode - ignores dof + save_log: + # type=bool|default=False: save to log file + verbose: + # type=int|default=0: verbose mode, 0 is least + bgvalue: + # type=float|default=0: use specified background value for points outside FOV + wm_seg: + # type=file|default=: white matter segmentation volume needed by BBR cost function + wmcoords: + # type=file|default=: white matter boundary coordinates for BBR cost function + wmnorms: + # type=file|default=: white matter boundary normals for BBR cost function + fieldmap: + # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image + fieldmapmask: + # type=file|default=: mask for fieldmap image + pedir: + # type=int|default=0: phase encode direction of EPI - 1/2/3=x/y/z & -1/-2/-3=-x/-y/-z + echospacing: + # type=float|default=0.0: value of EPI echo spacing - units of seconds + bbrtype: + # type=enum|default='signed'|allowed['global_abs','local_abs','signed']: type of bbr cost function: signed [default], global_abs, local_abs + bbrslope: + # type=float|default=0.0: value of bbr slope + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/apply_xfm_callables.py b/nipype-auto-conv/specs/apply_xfm_callables.py new file mode 100644 index 0000000..3b6054b --- /dev/null +++ b/nipype-auto-conv/specs/apply_xfm_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ApplyXFM.yaml""" diff --git a/nipype-auto-conv/specs/ar1_image.yaml b/nipype-auto-conv/specs/ar1_image.yaml new file mode 100644 index 0000000..ac9b296 --- /dev/null +++ b/nipype-auto-conv/specs/ar1_image.yaml @@ -0,0 +1,92 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.AR1Image' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate an AR1 coefficient image across a +# given dimension. (Should use -odt float and probably demean first) +# +# +task_name: AR1Image +nipype_name: AR1Image +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to find AR(1) coefficientacross + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/ar1_image_callables.py b/nipype-auto-conv/specs/ar1_image_callables.py new file mode 100644 index 0000000..7bd8155 --- /dev/null +++ b/nipype-auto-conv/specs/ar1_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in AR1Image.yaml""" diff --git a/nipype-auto-conv/specs/av_scale.yaml b/nipype-auto-conv/specs/av_scale.yaml new file mode 100644 index 0000000..cc334ff --- /dev/null +++ b/nipype-auto-conv/specs/av_scale.yaml @@ -0,0 +1,86 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.AvScale' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL avscale command to extract info from mat file output of FLIRT +# +# Examples +# -------- +# +# >>> avscale = AvScale() +# >>> avscale.inputs.mat_file = 'flirt.mat' +# >>> res = avscale.run() # doctest: +SKIP +# +# +# +task_name: AvScale +nipype_name: AvScale +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mat_file: generic/file + # type=file|default=: mat file to read + ref_file: generic/file + # type=file|default=: reference file to get center of rotation + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + all_param: + # type=bool|default=False: + mat_file: + # type=file|default=: mat file to read + ref_file: + # type=file|default=: reference file to get center of rotation + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/av_scale_callables.py b/nipype-auto-conv/specs/av_scale_callables.py new file mode 100644 index 0000000..236bd30 --- /dev/null +++ b/nipype-auto-conv/specs/av_scale_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in AvScale.yaml""" diff --git a/nipype-auto-conv/specs/b0_calc.yaml b/nipype-auto-conv/specs/b0_calc.yaml new file mode 100644 index 0000000..103b9c1 --- /dev/null +++ b/nipype-auto-conv/specs/b0_calc.yaml @@ -0,0 +1,163 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.possum.B0Calc' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# B0 inhomogeneities occur at interfaces of materials with different magnetic susceptibilities, +# such as tissue-air interfaces. These differences lead to distortion in the local magnetic field, +# as Maxwell’s equations need to be satisfied. An example of B0 inhomogneity is the first volume +# of the 4D volume ```$FSLDIR/data/possum/b0_ppm.nii.gz```. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import B0Calc +# >>> b0calc = B0Calc() +# >>> b0calc.inputs.in_file = 'tissue+air_map.nii' +# >>> b0calc.inputs.z_b0 = 3.0 +# >>> b0calc.inputs.output_type = "NIFTI_GZ" +# >>> b0calc.cmdline +# 'b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii.gz --chi0=4.000000e-07 -d -9.450000e-06 --extendboundary=1.00 --b0x=0.00 --gx=0.0000 --b0y=0.00 --gy=0.0000 --b0=3.00 --gz=0.0000' +# +# +task_name: B0Calc +nipype_name: B0Calc +nipype_module: nipype.interfaces.fsl.possum +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: filename of input image (usually a tissue/air segmentation) + out_file: generic/file + # type=file: filename of B0 output volume + # type=file|default=: filename of B0 output volume + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: filename of B0 output volume + # type=file|default=: filename of B0 output volume + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input image (usually a tissue/air segmentation) + out_file: + # type=file: filename of B0 output volume + # type=file|default=: filename of B0 output volume + x_grad: + # type=float|default=0.0: Value for zeroth-order x-gradient field (per mm) + y_grad: + # type=float|default=0.0: Value for zeroth-order y-gradient field (per mm) + z_grad: + # type=float|default=0.0: Value for zeroth-order z-gradient field (per mm) + x_b0: + # type=float|default=0.0: Value for zeroth-order b0 field (x-component), in Tesla + y_b0: + # type=float|default=0.0: Value for zeroth-order b0 field (y-component), in Tesla + z_b0: + # type=float|default=1.0: Value for zeroth-order b0 field (z-component), in Tesla + xyz_b0: + # type=tuple|default=(0.0, 0.0, 0.0): Zeroth-order B0 field in Tesla + delta: + # type=float|default=-9.45e-06: Delta value (chi_tissue - chi_air) + chi_air: + # type=float|default=4e-07: susceptibility of air + compute_xyz: + # type=bool|default=False: calculate and save all 3 field components (i.e. x,y,z) + extendboundary: + # type=float|default=1.0: Relative proportion to extend voxels at boundary + directconv: + # type=bool|default=False: use direct (image space) convolution, not FFT + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input image (usually a tissue/air segmentation) + z_b0: '3.0' + # type=float|default=1.0: Value for zeroth-order b0 field (z-component), in Tesla + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii.gz --chi0=4.000000e-07 -d -9.450000e-06 --extendboundary=1.00 --b0x=0.00 --gx=0.0000 --b0y=0.00 --gy=0.0000 --b0=3.00 --gz=0.0000 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: filename of input image (usually a tissue/air segmentation) + z_b0: '3.0' + # type=float|default=1.0: Value for zeroth-order b0 field (z-component), in Tesla + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/b0_calc_callables.py b/nipype-auto-conv/specs/b0_calc_callables.py new file mode 100644 index 0000000..4c30d1f --- /dev/null +++ b/nipype-auto-conv/specs/b0_calc_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in B0Calc.yaml""" diff --git a/nipype-auto-conv/specs/bedpostx5.yaml b/nipype-auto-conv/specs/bedpostx5.yaml new file mode 100644 index 0000000..92e9c8b --- /dev/null +++ b/nipype-auto-conv/specs/bedpostx5.yaml @@ -0,0 +1,208 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.BEDPOSTX5' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# BEDPOSTX stands for Bayesian Estimation of Diffusion Parameters Obtained +# using Sampling Techniques. The X stands for modelling Crossing Fibres. +# bedpostx runs Markov Chain Monte Carlo sampling to build up distributions +# on diffusion parameters at each voxel. It creates all the files necessary +# for running probabilistic tractography. For an overview of the modelling +# carried out within bedpostx see this `technical report +# `_. +# +# +# .. note:: Consider using +# :func:`niflow.nipype1.workflows.fsl.dmri.create_bedpostx_pipeline` instead. +# +# +# Example +# ------- +# +# >>> from nipype.interfaces import fsl +# >>> bedp = fsl.BEDPOSTX5(bvecs='bvecs', bvals='bvals', dwi='diffusion.nii', +# ... mask='mask.nii', n_fibres=1) +# >>> bedp.cmdline +# 'bedpostx bedpostx -b 0 --burnin_noard=0 --forcedir -n 1 -j 5000 -s 1 --updateproposalevery=40' +# +# +task_name: BEDPOSTX5 +nipype_name: BEDPOSTX5 +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + dwi: medimage/nifti1 + # type=file|default=: diffusion weighted image data file + mask: medimage/nifti1 + # type=file|default=: bet binary mask file + bvecs: medimage/bvec + # type=file|default=: b vectors file + bvals: medimage/bval + # type=file|default=: b values file + grad_dev: generic/file + # type=file|default=: grad_dev file, if gradnonlin, -g is True + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mean_dsamples: generic/file + # type=file: Mean of distribution on diffusivity d + mean_S0samples: generic/file + # type=file: Mean of distribution on T2wbaseline signal intensity S0 + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: bet binary mask file + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + logdir: + # type=directory|default=: + n_fibres: + # type=range|default=2: Maximum number of fibres to fit in each voxel + model: + # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model + fudge: + # type=int|default=0: ARD fudge factor + n_jumps: + # type=int|default=5000: Num of jumps to be made by MCMC + burn_in: + # type=range|default=0: Total num of jumps at start of MCMC to be discarded + sample_every: + # type=range|default=1: Num of jumps for each sample (MCMC) + out_dir: + # type=directory|default='bedpostx': output directory + gradnonlin: + # type=bool|default=False: consider gradient nonlinearities, default off + grad_dev: + # type=file|default=: grad_dev file, if gradnonlin, -g is True + use_gpu: + # type=bool|default=False: Use the GPU version of bedpostx + burn_in_no_ard: + # type=range|default=0: num of burnin jumps before the ard is imposed + update_proposal_every: + # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) + seed: + # type=int|default=0: seed for pseudo random number generator + no_ard: + # type=bool|default=False: Turn ARD off on all fibres + all_ard: + # type=bool|default=False: Turn ARD on on all fibres + no_spat: + # type=bool|default=False: Initialise with tensor, not spatially + non_linear: + # type=bool|default=False: Initialise with nonlinear fitting + cnlinear: + # type=bool|default=False: Initialise with constrained nonlinear fitting + rician: + # type=bool|default=False: use Rician noise modeling + f0_noard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + f0_ard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + force_dir: + # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: bet binary mask file + n_fibres: '1' + # type=range|default=2: Maximum number of fibres to fit in each voxel + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: bedpostx bedpostx -b 0 --burnin_noard=0 --forcedir -n 1 -j 5000 -s 1 --updateproposalevery=40 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: bet binary mask file + n_fibres: '1' + # type=range|default=2: Maximum number of fibres to fit in each voxel + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/bedpostx5_callables.py b/nipype-auto-conv/specs/bedpostx5_callables.py new file mode 100644 index 0000000..3f67f67 --- /dev/null +++ b/nipype-auto-conv/specs/bedpostx5_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in BEDPOSTX5.yaml""" diff --git a/nipype-auto-conv/specs/bet.yaml b/nipype-auto-conv/specs/bet.yaml new file mode 100644 index 0000000..e754808 --- /dev/null +++ b/nipype-auto-conv/specs/bet.yaml @@ -0,0 +1,198 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.BET' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL BET wrapper for skull stripping +# +# For complete details, see the `BET Documentation. +# `_ +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> btr = fsl.BET() +# >>> btr.inputs.in_file = 'structural.nii' +# >>> btr.inputs.frac = 0.7 +# >>> btr.inputs.out_file = 'brain_anat.nii' +# >>> btr.cmdline +# 'bet structural.nii brain_anat.nii -f 0.70' +# >>> res = btr.run() # doctest: +SKIP +# +# +task_name: BET +nipype_name: BET +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: input file to skull strip + t2_guided: generic/file + # type=file|default=: as with creating surfaces, when also feeding in non-brain-extracted T2 (includes registrations) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: medimage/nifti1 + # type=file: path/name of skullstripped file (if generated) + # type=file|default=: name of output skull stripped image + mask_file: generic/file + # type=file: path/name of binary brain mask (if generated) + outline_file: generic/file + # type=file: path/name of outline file (if generated) + meshfile: generic/file + # type=file: path/name of vtk mesh file (if generated) + inskull_mask_file: generic/file + # type=file: path/name of inskull mask (if generated) + inskull_mesh_file: generic/file + # type=file: path/name of inskull mesh outline (if generated) + outskull_mask_file: generic/file + # type=file: path/name of outskull mask (if generated) + outskull_mesh_file: generic/file + # type=file: path/name of outskull mesh outline (if generated) + outskin_mask_file: generic/file + # type=file: path/name of outskin mask (if generated) + outskin_mesh_file: generic/file + # type=file: path/name of outskin mesh outline (if generated) + skull_mask_file: generic/file + # type=file: path/name of skull mask (if generated) + skull_file: generic/file + # type=file: path/name of skull file (if generated) + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"brain_anat.nii"' + # type=file: path/name of skullstripped file (if generated) + # type=file|default=: name of output skull stripped image + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file to skull strip + out_file: + # type=file: path/name of skullstripped file (if generated) + # type=file|default=: name of output skull stripped image + outline: + # type=bool|default=False: create surface outline image + mask: + # type=bool|default=False: create binary mask image + skull: + # type=bool|default=False: create skull image + no_output: + # type=bool|default=False: Don't generate segmented output + frac: + # type=float|default=0.0: fractional intensity threshold + vertical_gradient: + # type=float|default=0.0: vertical gradient in fractional intensity threshold (-1, 1) + radius: + # type=int|default=0: head radius + center: + # type=list|default=[]: center of gravity in voxels + threshold: + # type=bool|default=False: apply thresholding to segmented brain image and mask + mesh: + # type=bool|default=False: generate a vtk mesh brain surface + robust: + # type=bool|default=False: robust brain centre estimation (iterates BET several times) + padding: + # type=bool|default=False: improve BET if FOV is very small in Z (by temporarily padding end slices) + remove_eyes: + # type=bool|default=False: eye & optic nerve cleanup (can be useful in SIENA) + surfaces: + # type=bool|default=False: run bet2 and then betsurf to get additional skull and scalp surfaces (includes registrations) + t2_guided: + # type=file|default=: as with creating surfaces, when also feeding in non-brain-extracted T2 (includes registrations) + functional: + # type=bool|default=False: apply to 4D fMRI data + reduce_bias: + # type=bool|default=False: bias field and neck cleanup + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file to skull strip + frac: '0.7' + # type=float|default=0.0: fractional intensity threshold + out_file: '"brain_anat.nii"' + # type=file: path/name of skullstripped file (if generated) + # type=file|default=: name of output skull stripped image + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: bet structural.nii brain_anat.nii -f 0.70 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input file to skull strip + frac: '0.7' + # type=float|default=0.0: fractional intensity threshold + out_file: '"brain_anat.nii"' + # type=file: path/name of skullstripped file (if generated) + # type=file|default=: name of output skull stripped image + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/bet_callables.py b/nipype-auto-conv/specs/bet_callables.py new file mode 100644 index 0000000..8b4d7f5 --- /dev/null +++ b/nipype-auto-conv/specs/bet_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in BET.yaml""" diff --git a/nipype-auto-conv/specs/binary_maths.yaml b/nipype-auto-conv/specs/binary_maths.yaml new file mode 100644 index 0000000..2ea42f0 --- /dev/null +++ b/nipype-auto-conv/specs/binary_maths.yaml @@ -0,0 +1,98 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.BinaryMaths' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to perform mathematical operations using a second image or +# a numeric value. +# +# +task_name: BinaryMaths +nipype_name: BinaryMaths +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + operand_file: generic/file + # type=file|default=: second image to perform operation with + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + operation: + # type=enum|default='add'|allowed['add','div','max','min','mul','rem','sub']: operation to perform + operand_file: + # type=file|default=: second image to perform operation with + operand_value: + # type=float|default=0.0: value to perform operation with + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/binary_maths_callables.py b/nipype-auto-conv/specs/binary_maths_callables.py new file mode 100644 index 0000000..68e6b72 --- /dev/null +++ b/nipype-auto-conv/specs/binary_maths_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in BinaryMaths.yaml""" diff --git a/nipype-auto-conv/specs/change_data_type.yaml b/nipype-auto-conv/specs/change_data_type.yaml new file mode 100644 index 0000000..07f91a5 --- /dev/null +++ b/nipype-auto-conv/specs/change_data_type.yaml @@ -0,0 +1,87 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.ChangeDataType' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to change the datatype of an image. +task_name: ChangeDataType +nipype_name: ChangeDataType +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: output data type + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/change_data_type_callables.py b/nipype-auto-conv/specs/change_data_type_callables.py new file mode 100644 index 0000000..2eb3367 --- /dev/null +++ b/nipype-auto-conv/specs/change_data_type_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ChangeDataType.yaml""" diff --git a/nipype-auto-conv/specs/classifier.yaml b/nipype-auto-conv/specs/classifier.yaml new file mode 100644 index 0000000..3f29445 --- /dev/null +++ b/nipype-auto-conv/specs/classifier.yaml @@ -0,0 +1,85 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.fix.Classifier' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Classify ICA components using a specific training dataset ( is in the range 0-100, typically 5-20). +# +task_name: Classifier +nipype_name: Classifier +nipype_module: nipype.interfaces.fsl.fix +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + trained_wts_file: generic/file + # type=file|default=: trained-weights file + artifacts_list_file: generic/file + # type=file: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + artifacts_list_file: generic/file + # type=file: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mel_ica: + # type=directory|default=: Melodic output directory or directories + trained_wts_file: + # type=file|default=: trained-weights file + thresh: + # type=int|default=0: Threshold for cleanup. + artifacts_list_file: + # type=file: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/classifier_callables.py b/nipype-auto-conv/specs/classifier_callables.py new file mode 100644 index 0000000..4f49e90 --- /dev/null +++ b/nipype-auto-conv/specs/classifier_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Classifier.yaml""" diff --git a/nipype-auto-conv/specs/cleaner.yaml b/nipype-auto-conv/specs/cleaner.yaml new file mode 100644 index 0000000..8f1d242 --- /dev/null +++ b/nipype-auto-conv/specs/cleaner.yaml @@ -0,0 +1,92 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.fix.Cleaner' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Extract features (for later training and/or classifying) +# +task_name: Cleaner +nipype_name: Cleaner +nipype_module: nipype.interfaces.fsl.fix +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + artifacts_list_file: generic/file + # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + confound_file: generic/file + # type=file|default=: Include additional confound file. + confound_file_1: generic/file + # type=file|default=: Include additional confound file. + confound_file_2: generic/file + # type=file|default=: Include additional confound file. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + cleaned_functional_file: generic/file + # type=file: Cleaned session data + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + artifacts_list_file: + # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + cleanup_motion: + # type=bool|default=False: cleanup motion confounds, looks for design.fsf for highpass filter cut-off + highpass: + # type=float|default=100: cleanup motion confounds + aggressive: + # type=bool|default=False: Apply aggressive (full variance) cleanup, instead of the default less-aggressive (unique variance) cleanup. + confound_file: + # type=file|default=: Include additional confound file. + confound_file_1: + # type=file|default=: Include additional confound file. + confound_file_2: + # type=file|default=: Include additional confound file. + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/cleaner_callables.py b/nipype-auto-conv/specs/cleaner_callables.py new file mode 100644 index 0000000..625e2af --- /dev/null +++ b/nipype-auto-conv/specs/cleaner_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Cleaner.yaml""" diff --git a/nipype-auto-conv/specs/cluster.yaml b/nipype-auto-conv/specs/cluster.yaml new file mode 100644 index 0000000..82f5aad --- /dev/null +++ b/nipype-auto-conv/specs/cluster.yaml @@ -0,0 +1,202 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.Cluster' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Uses FSL cluster to perform clustering on statistical output +# +# Examples +# -------- +# +# >>> cl = Cluster() +# >>> cl.inputs.threshold = 2.3 +# >>> cl.inputs.in_file = 'zstat1.nii.gz' +# >>> cl.inputs.out_localmax_txt_file = 'stats.txt' +# >>> cl.inputs.use_mm = True +# >>> cl.cmdline +# 'cluster --in=zstat1.nii.gz --olmax=stats.txt --thresh=2.3000000000 --mm' +# +# +task_name: Cluster +nipype_name: Cluster +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti-gz + # type=file|default=: input volume + cope_file: generic/file + # type=file|default=: cope volume + xfm_file: generic/file + # type=file|default=: filename for Linear: input->standard-space transform. Non-linear: input->highres transform + std_space_file: generic/file + # type=file|default=: filename for standard-space volume + warpfield_file: generic/file + # type=file|default=: file contining warpfield + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + index_file: generic/file + # type=file: output of cluster index (in size order) + threshold_file: generic/file + # type=file: thresholded image + localmax_txt_file: generic/file + # type=file: local maxima text file + localmax_vol_file: generic/file + # type=file: output of local maxima volume + size_file: generic/file + # type=file: filename for output of size image + max_file: generic/file + # type=file: filename for output of max image + mean_file: generic/file + # type=file: filename for output of mean image + pval_file: generic/file + # type=file: filename for image output of log pvals + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input volume + threshold: + # type=float|default=0.0: threshold for input volume + out_index_file: + # type=traitcompound|default=None: output of cluster index (in size order) + out_threshold_file: + # type=traitcompound|default=None: thresholded image + out_localmax_txt_file: + # type=traitcompound|default=None: local maxima text file + out_localmax_vol_file: + # type=traitcompound|default=None: output of local maxima volume + out_size_file: + # type=traitcompound|default=None: filename for output of size image + out_max_file: + # type=traitcompound|default=None: filename for output of max image + out_mean_file: + # type=traitcompound|default=None: filename for output of mean image + out_pval_file: + # type=traitcompound|default=None: filename for image output of log pvals + pthreshold: + # type=float|default=0.0: p-threshold for clusters + peak_distance: + # type=float|default=0.0: minimum distance between local maxima/minima, in mm (default 0) + cope_file: + # type=file|default=: cope volume + volume: + # type=int|default=0: number of voxels in the mask + dlh: + # type=float|default=0.0: smoothness estimate = sqrt(det(Lambda)) + fractional: + # type=bool|default=False: interprets the threshold as a fraction of the robust range + connectivity: + # type=int|default=0: the connectivity of voxels (default 26) + use_mm: + # type=bool|default=False: use mm, not voxel, coordinates + find_min: + # type=bool|default=False: find minima instead of maxima + no_table: + # type=bool|default=False: suppresses printing of the table info + minclustersize: + # type=bool|default=False: prints out minimum significant cluster size + xfm_file: + # type=file|default=: filename for Linear: input->standard-space transform. Non-linear: input->highres transform + std_space_file: + # type=file|default=: filename for standard-space volume + num_maxima: + # type=int|default=0: no of local maxima to report + warpfield_file: + # type=file|default=: file contining warpfield + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + threshold: '2.3' + # type=float|default=0.0: threshold for input volume + in_file: + # type=file|default=: input volume + out_localmax_txt_file: '"stats.txt"' + # type=traitcompound|default=None: local maxima text file + use_mm: 'True' + # type=bool|default=False: use mm, not voxel, coordinates + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: cluster --in=zstat1.nii.gz --olmax=stats.txt --thresh=2.3000000000 --mm + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + threshold: '2.3' + # type=float|default=0.0: threshold for input volume + in_file: + # type=file|default=: input volume + out_localmax_txt_file: '"stats.txt"' + # type=traitcompound|default=None: local maxima text file + use_mm: 'True' + # type=bool|default=False: use mm, not voxel, coordinates + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/cluster_callables.py b/nipype-auto-conv/specs/cluster_callables.py new file mode 100644 index 0000000..bca8cde --- /dev/null +++ b/nipype-auto-conv/specs/cluster_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Cluster.yaml""" diff --git a/nipype-auto-conv/specs/complex.yaml b/nipype-auto-conv/specs/complex.yaml new file mode 100644 index 0000000..cc22fea --- /dev/null +++ b/nipype-auto-conv/specs/complex.yaml @@ -0,0 +1,164 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Complex' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# fslcomplex is a tool for converting complex data +# +# Examples +# -------- +# +# >>> cplx = Complex() +# >>> cplx.inputs.complex_in_file = "complex.nii" +# >>> cplx.real_polar = True +# >>> res = cplx.run() # doctest: +SKIP +# +# +# +task_name: Complex +nipype_name: Complex +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + complex_in_file: generic/file + # type=file|default=: + complex_in_file2: generic/file + # type=file|default=: + real_in_file: generic/file + # type=file|default=: + imaginary_in_file: generic/file + # type=file|default=: + magnitude_in_file: generic/file + # type=file|default=: + phase_in_file: generic/file + # type=file|default=: + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + magnitude_out_file: generic/file + # type=file: + # type=file|default=: + phase_out_file: generic/file + # type=file: + # type=file|default=: + real_out_file: generic/file + # type=file: + # type=file|default=: + imaginary_out_file: generic/file + # type=file: + # type=file|default=: + complex_out_file: generic/file + # type=file: + # type=file|default=: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + complex_out_file: complex_out_file + # type=file: + # type=file|default=: + magnitude_out_file: magnitude_out_file + # type=file: + # type=file|default=: + phase_out_file: phase_out_file + # type=file: + # type=file|default=: + real_out_file: real_out_file + # type=file: + # type=file|default=: + imaginary_out_file: imaginary_out_file + # type=file: + # type=file|default=: + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + complex_in_file: + # type=file|default=: + complex_in_file2: + # type=file|default=: + real_in_file: + # type=file|default=: + imaginary_in_file: + # type=file|default=: + magnitude_in_file: + # type=file|default=: + phase_in_file: + # type=file|default=: + complex_out_file: + # type=file: + # type=file|default=: + magnitude_out_file: + # type=file: + # type=file|default=: + phase_out_file: + # type=file: + # type=file|default=: + real_out_file: + # type=file: + # type=file|default=: + imaginary_out_file: + # type=file: + # type=file|default=: + start_vol: + # type=int|default=0: + end_vol: + # type=int|default=0: + real_polar: + # type=bool|default=False: + real_cartesian: + # type=bool|default=False: + complex_cartesian: + # type=bool|default=False: + complex_polar: + # type=bool|default=False: + complex_split: + # type=bool|default=False: + complex_merge: + # type=bool|default=False: + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/complex_callables.py b/nipype-auto-conv/specs/complex_callables.py new file mode 100644 index 0000000..566f01d --- /dev/null +++ b/nipype-auto-conv/specs/complex_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Complex.yaml""" diff --git a/nipype-auto-conv/specs/contrast_mgr.yaml b/nipype-auto-conv/specs/contrast_mgr.yaml new file mode 100644 index 0000000..18f8961 --- /dev/null +++ b/nipype-auto-conv/specs/contrast_mgr.yaml @@ -0,0 +1,101 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.ContrastMgr' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL contrast_mgr command to evaluate contrasts +# +# In interface mode this file assumes that all the required inputs are in the +# same location. This has deprecated for FSL versions 5.0.7+ as the necessary +# corrections file is no longer generated by FILMGLS. +# +task_name: ContrastMgr +nipype_name: ContrastMgr +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + tcon_file: generic/file + # type=file|default=: contrast file containing T-contrasts + fcon_file: generic/file + # type=file|default=: contrast file containing F-contrasts + param_estimates: generic/file+list-of + # type=inputmultiobject|default=[]: Parameter estimates for each column of the design matrix + corrections: generic/file + # type=file|default=: statistical corrections used within FILM modelling + dof_file: generic/file + # type=file|default=: degrees of freedom + sigmasquareds: generic/file + # type=file|default=: summary of residuals, See Woolrich, et. al., 2001 + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + tcon_file: + # type=file|default=: contrast file containing T-contrasts + fcon_file: + # type=file|default=: contrast file containing F-contrasts + param_estimates: + # type=inputmultiobject|default=[]: Parameter estimates for each column of the design matrix + corrections: + # type=file|default=: statistical corrections used within FILM modelling + dof_file: + # type=file|default=: degrees of freedom + sigmasquareds: + # type=file|default=: summary of residuals, See Woolrich, et. al., 2001 + contrast_num: + # type=range|default=1: contrast number to start labeling copes from + suffix: + # type=str|default='': suffix to put on the end of the cope filename before the contrast number, default is nothing + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/contrast_mgr_callables.py b/nipype-auto-conv/specs/contrast_mgr_callables.py new file mode 100644 index 0000000..ff62f09 --- /dev/null +++ b/nipype-auto-conv/specs/contrast_mgr_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ContrastMgr.yaml""" diff --git a/nipype-auto-conv/specs/convert_warp.yaml b/nipype-auto-conv/specs/convert_warp.yaml new file mode 100644 index 0000000..498e441 --- /dev/null +++ b/nipype-auto-conv/specs/convert_warp.yaml @@ -0,0 +1,184 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.ConvertWarp' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL `convertwarp `_ +# for combining multiple transforms into one. +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import ConvertWarp +# >>> warputils = ConvertWarp() +# >>> warputils.inputs.warp1 = "warpfield.nii" +# >>> warputils.inputs.reference = "T1.nii" +# >>> warputils.inputs.relwarp = True +# >>> warputils.inputs.output_type = "NIFTI_GZ" +# >>> warputils.cmdline # doctest: +ELLIPSIS +# 'convertwarp --ref=T1.nii --rel --warp1=warpfield.nii --out=T1_concatwarp.nii.gz' +# >>> res = warputils.run() # doctest: +SKIP +# +# +# +task_name: ConvertWarp +nipype_name: ConvertWarp +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + reference: medimage/nifti1 + # type=file|default=: Name of a file in target space of the full transform. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: Name of output file, containing warps that are the combination of all those given as arguments. The format of this will be a field-file (rather than spline coefficients) with any affine components included. + premat: generic/file + # type=file|default=: filename for pre-transform (affine matrix) + warp1: medimage/nifti1 + # type=file|default=: Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects. + midmat: generic/file + # type=file|default=: Name of file containing mid-warp-affine transform + warp2: generic/file + # type=file|default=: Name of file containing secondary warp-fields/coefficients (after warp1/midmat but before postmat). This could e.g. be a fnirt-transform from the average of a group of subjects to some standard space (e.g. MNI152). + postmat: generic/file + # type=file|default=: Name of file containing an affine transform (applied last). It could e.g. be an affine transform that maps the MNI152-space into a better approximation to the Talairach-space (if indeed there is one). + shift_in_file: generic/file + # type=file|default=: Name of file containing a "shiftmap", a non-linear transform with displacements only in one direction (applied first, before premat). This would typically be a fieldmap that has been pre-processed using fugue that maps a subjects functional (EPI) data onto an undistorted space (i.e. a space that corresponds to his/her true anatomy). + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: Name of output file, containing warps that are the combination of all those given as arguments. The format of this will be a field-file (rather than spline coefficients) with any affine components included. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + reference: + # type=file|default=: Name of a file in target space of the full transform. + out_file: + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: Name of output file, containing warps that are the combination of all those given as arguments. The format of this will be a field-file (rather than spline coefficients) with any affine components included. + premat: + # type=file|default=: filename for pre-transform (affine matrix) + warp1: + # type=file|default=: Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects. + midmat: + # type=file|default=: Name of file containing mid-warp-affine transform + warp2: + # type=file|default=: Name of file containing secondary warp-fields/coefficients (after warp1/midmat but before postmat). This could e.g. be a fnirt-transform from the average of a group of subjects to some standard space (e.g. MNI152). + postmat: + # type=file|default=: Name of file containing an affine transform (applied last). It could e.g. be an affine transform that maps the MNI152-space into a better approximation to the Talairach-space (if indeed there is one). + shift_in_file: + # type=file|default=: Name of file containing a "shiftmap", a non-linear transform with displacements only in one direction (applied first, before premat). This would typically be a fieldmap that has been pre-processed using fugue that maps a subjects functional (EPI) data onto an undistorted space (i.e. a space that corresponds to his/her true anatomy). + shift_direction: + # type=enum|default='y-'|allowed['x','x-','y','y-','z','z-']: Indicates the direction that the distortions from --shiftmap goes. It depends on the direction and polarity of the phase-encoding in the EPI sequence. + cons_jacobian: + # type=bool|default=False: Constrain the Jacobian of the warpfield to lie within specified min/max limits. + jacobian_min: + # type=float|default=0.0: Minimum acceptable Jacobian value for constraint (default 0.01) + jacobian_max: + # type=float|default=0.0: Maximum acceptable Jacobian value for constraint (default 100.0) + abswarp: + # type=bool|default=False: If set it indicates that the warps in --warp1 and --warp2 should be interpreted as absolute. I.e. the values in --warp1/2 are the coordinates in the next space, rather than displacements. This flag is ignored if --warp1/2 was created by fnirt, which always creates relative displacements. + relwarp: + # type=bool|default=False: If set it indicates that the warps in --warp1/2 should be interpreted as relative. I.e. the values in --warp1/2 are displacements from the coordinates in the next space. + out_abswarp: + # type=bool|default=False: If set it indicates that the warps in --out should be absolute, i.e. the values in --out are displacements from the coordinates in --ref. + out_relwarp: + # type=bool|default=False: If set it indicates that the warps in --out should be relative, i.e. the values in --out are displacements from the coordinates in --ref. + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + warp1: + # type=file|default=: Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects. + reference: + # type=file|default=: Name of a file in target space of the full transform. + relwarp: 'True' + # type=bool|default=False: If set it indicates that the warps in --warp1/2 should be interpreted as relative. I.e. the values in --warp1/2 are displacements from the coordinates in the next space. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: convertwarp --ref=T1.nii --rel --warp1=warpfield.nii --out=T1_concatwarp.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + warp1: + # type=file|default=: Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects. + reference: + # type=file|default=: Name of a file in target space of the full transform. + relwarp: 'True' + # type=bool|default=False: If set it indicates that the warps in --warp1/2 should be interpreted as relative. I.e. the values in --warp1/2 are displacements from the coordinates in the next space. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/convert_warp_callables.py b/nipype-auto-conv/specs/convert_warp_callables.py new file mode 100644 index 0000000..b6a046c --- /dev/null +++ b/nipype-auto-conv/specs/convert_warp_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ConvertWarp.yaml""" diff --git a/nipype-auto-conv/specs/convert_xfm.yaml b/nipype-auto-conv/specs/convert_xfm.yaml new file mode 100644 index 0000000..19f5a17 --- /dev/null +++ b/nipype-auto-conv/specs/convert_xfm.yaml @@ -0,0 +1,149 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.ConvertXFM' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use the FSL utility convert_xfm to modify FLIRT transformation matrices. +# +# Examples +# -------- +# +# >>> import nipype.interfaces.fsl as fsl +# >>> invt = fsl.ConvertXFM() +# >>> invt.inputs.in_file = "flirt.mat" +# >>> invt.inputs.invert_xfm = True +# >>> invt.inputs.out_file = 'flirt_inv.mat' +# >>> invt.cmdline +# 'convert_xfm -omat flirt_inv.mat -inverse flirt.mat' +# +# +# +task_name: ConvertXFM +nipype_name: ConvertXFM +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: datascience/text-matrix + # type=file|default=: input transformation matrix + in_file2: generic/file + # type=file|default=: second input matrix (for use with fix_scale_skew or concat_xfm) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: datascience/text-matrix + # type=file: output transformation matrix + # type=file|default=: final transformation matrix + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"flirt_inv.mat"' + # type=file: output transformation matrix + # type=file|default=: final transformation matrix + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input transformation matrix + in_file2: + # type=file|default=: second input matrix (for use with fix_scale_skew or concat_xfm) + invert_xfm: + # type=bool|default=False: invert input transformation + concat_xfm: + # type=bool|default=False: write joint transformation of two input matrices + fix_scale_skew: + # type=bool|default=False: use secondary matrix to fix scale and skew + out_file: + # type=file: output transformation matrix + # type=file|default=: final transformation matrix + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input transformation matrix + invert_xfm: 'True' + # type=bool|default=False: invert input transformation + out_file: '"flirt_inv.mat"' + # type=file: output transformation matrix + # type=file|default=: final transformation matrix + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.interfaces.fsl as fsl + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: convert_xfm -omat flirt_inv.mat -inverse flirt.mat + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input transformation matrix + invert_xfm: 'True' + # type=bool|default=False: invert input transformation + out_file: '"flirt_inv.mat"' + # type=file: output transformation matrix + # type=file|default=: final transformation matrix + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/convert_xfm_callables.py b/nipype-auto-conv/specs/convert_xfm_callables.py new file mode 100644 index 0000000..c81ca18 --- /dev/null +++ b/nipype-auto-conv/specs/convert_xfm_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ConvertXFM.yaml""" diff --git a/nipype-auto-conv/specs/copy_geom.yaml b/nipype-auto-conv/specs/copy_geom.yaml new file mode 100644 index 0000000..e5714c6 --- /dev/null +++ b/nipype-auto-conv/specs/copy_geom.yaml @@ -0,0 +1,87 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.CopyGeom' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslcpgeom to copy the header geometry information to another image. +# Copy certain parts of the header information (image dimensions, voxel +# dimensions, voxel dimensions units string, image orientation/origin or +# qform/sform info) from one image to another. Note that only copies from +# Analyze to Analyze or Nifti to Nifti will work properly. Copying from +# different files will result in loss of information or potentially incorrect +# settings. +# +task_name: CopyGeom +nipype_name: CopyGeom +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: source image + dest_file: generic/file + # type=file|default=: destination image + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image with new geometry header + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: source image + dest_file: + # type=file|default=: destination image + ignore_dims: + # type=bool|default=False: Do not copy image dimensions + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/copy_geom_callables.py b/nipype-auto-conv/specs/copy_geom_callables.py new file mode 100644 index 0000000..384cdef --- /dev/null +++ b/nipype-auto-conv/specs/copy_geom_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in CopyGeom.yaml""" diff --git a/nipype-auto-conv/specs/dilate_image.yaml b/nipype-auto-conv/specs/dilate_image.yaml new file mode 100644 index 0000000..1bf03b5 --- /dev/null +++ b/nipype-auto-conv/specs/dilate_image.yaml @@ -0,0 +1,97 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.DilateImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to perform a spatial dilation of an image. +task_name: DilateImage +nipype_name: DilateImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + kernel_file: generic/file + # type=file|default=: use external file for kernel + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + operation: + # type=enum|default='mean'|allowed['max','mean','modal']: filtering operation to perform in dilation + kernel_shape: + # type=enum|default='3D'|allowed['2D','3D','box','boxv','file','gauss','sphere']: kernel shape to use + kernel_size: + # type=float|default=0.0: kernel size - voxels for box/boxv, mm for sphere, mm sigma for gauss + kernel_file: + # type=file|default=: use external file for kernel + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/dilate_image_callables.py b/nipype-auto-conv/specs/dilate_image_callables.py new file mode 100644 index 0000000..a27b1b0 --- /dev/null +++ b/nipype-auto-conv/specs/dilate_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in DilateImage.yaml""" diff --git a/nipype-auto-conv/specs/distance_map.yaml b/nipype-auto-conv/specs/distance_map.yaml new file mode 100644 index 0000000..b2486ad --- /dev/null +++ b/nipype-auto-conv/specs/distance_map.yaml @@ -0,0 +1,104 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.DistanceMap' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL's distancemap to generate a map of the distance to the nearest +# nonzero voxel. +# +# Example +# ------- +# +# >>> import nipype.interfaces.fsl as fsl +# >>> mapper = fsl.DistanceMap() +# >>> mapper.inputs.in_file = "skeleton_mask.nii.gz" +# >>> mapper.run() # doctest: +SKIP +# +# +task_name: DistanceMap +nipype_name: DistanceMap +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to calculate distance values for + mask_file: generic/file + # type=file|default=: binary mask to constrain calculations + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + distance_map: generic/file + # type=file: value is distance to nearest nonzero voxels + # type=file|default=: distance map to write + local_max_file: generic/file + # type=file: image of local maxima + # type=traitcompound|default=None: write an image of the local maxima + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + distance_map: distance_map + # type=file: value is distance to nearest nonzero voxels + # type=file|default=: distance map to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to calculate distance values for + mask_file: + # type=file|default=: binary mask to constrain calculations + invert_input: + # type=bool|default=False: invert input image + local_max_file: + # type=file: image of local maxima + # type=traitcompound|default=None: write an image of the local maxima + distance_map: + # type=file: value is distance to nearest nonzero voxels + # type=file|default=: distance map to write + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/distance_map_callables.py b/nipype-auto-conv/specs/distance_map_callables.py new file mode 100644 index 0000000..e8ef0b5 --- /dev/null +++ b/nipype-auto-conv/specs/distance_map_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in DistanceMap.yaml""" diff --git a/nipype-auto-conv/specs/dti_fit.yaml b/nipype-auto-conv/specs/dti_fit.yaml new file mode 100644 index 0000000..9ace4d9 --- /dev/null +++ b/nipype-auto-conv/specs/dti_fit.yaml @@ -0,0 +1,203 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.DTIFit' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL dtifit command for fitting a diffusion tensor model at each +# voxel +# +# Example +# ------- +# +# >>> from nipype.interfaces import fsl +# >>> dti = fsl.DTIFit() +# >>> dti.inputs.dwi = 'diffusion.nii' +# >>> dti.inputs.bvecs = 'bvecs' +# >>> dti.inputs.bvals = 'bvals' +# >>> dti.inputs.base_name = 'TP' +# >>> dti.inputs.mask = 'mask.nii' +# >>> dti.cmdline +# 'dtifit -k diffusion.nii -o TP -m mask.nii -r bvecs -b bvals' +# +# +task_name: DTIFit +nipype_name: DTIFit +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + dwi: medimage/nifti1 + # type=file|default=: diffusion weighted image data file + mask: medimage/nifti1 + # type=file|default=: bet binary mask file + bvecs: medimage/bvec + # type=file|default=: b vectors file + bvals: medimage/bval + # type=file|default=: b values file + cni: generic/file + # type=file|default=: input counfound regressors + gradnonlin: generic/file + # type=file|default=: gradient non linearities + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + V1: generic/file + # type=file: path/name of file with the 1st eigenvector + V2: generic/file + # type=file: path/name of file with the 2nd eigenvector + V3: generic/file + # type=file: path/name of file with the 3rd eigenvector + L1: generic/file + # type=file: path/name of file with the 1st eigenvalue + L2: generic/file + # type=file: path/name of file with the 2nd eigenvalue + L3: generic/file + # type=file: path/name of file with the 3rd eigenvalue + MD: generic/file + # type=file: path/name of file with the mean diffusivity + FA: generic/file + # type=file: path/name of file with the fractional anisotropy + MO: generic/file + # type=file: path/name of file with the mode of anisotropy + S0: generic/file + # type=file: path/name of file with the raw T2 signal with no diffusion weighting + tensor: generic/file + # type=file: path/name of file with the 4D tensor volume + sse: generic/file + # type=file: path/name of file with the summed squared error + # type=bool|default=False: output sum of squared errors + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dwi: + # type=file|default=: diffusion weighted image data file + base_name: + # type=str|default='dtifit_': base_name that all output files will start with + mask: + # type=file|default=: bet binary mask file + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + min_z: + # type=int|default=0: min z + max_z: + # type=int|default=0: max z + min_y: + # type=int|default=0: min y + max_y: + # type=int|default=0: max y + min_x: + # type=int|default=0: min x + max_x: + # type=int|default=0: max x + save_tensor: + # type=bool|default=False: save the elements of the tensor + sse: + # type=file: path/name of file with the summed squared error + # type=bool|default=False: output sum of squared errors + cni: + # type=file|default=: input counfound regressors + little_bit: + # type=bool|default=False: only process small area of brain + gradnonlin: + # type=file|default=: gradient non linearities + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dwi: + # type=file|default=: diffusion weighted image data file + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + base_name: '"TP"' + # type=str|default='dtifit_': base_name that all output files will start with + mask: + # type=file|default=: bet binary mask file + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: dtifit -k diffusion.nii -o TP -m mask.nii -r bvecs -b bvals + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + dwi: + # type=file|default=: diffusion weighted image data file + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + base_name: '"TP"' + # type=str|default='dtifit_': base_name that all output files will start with + mask: + # type=file|default=: bet binary mask file + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/dti_fit_callables.py b/nipype-auto-conv/specs/dti_fit_callables.py new file mode 100644 index 0000000..5d71e93 --- /dev/null +++ b/nipype-auto-conv/specs/dti_fit_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in DTIFit.yaml""" diff --git a/nipype-auto-conv/specs/dual_regression.yaml b/nipype-auto-conv/specs/dual_regression.yaml new file mode 100644 index 0000000..6b873a8 --- /dev/null +++ b/nipype-auto-conv/specs/dual_regression.yaml @@ -0,0 +1,167 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.DualRegression' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Wrapper Script for Dual Regression Workflow +# +# Examples +# -------- +# +# >>> dual_regression = DualRegression() +# >>> dual_regression.inputs.in_files = ["functional.nii", "functional2.nii", "functional3.nii"] +# >>> dual_regression.inputs.group_IC_maps_4D = "allFA.nii" +# >>> dual_regression.inputs.des_norm = False +# >>> dual_regression.inputs.one_sample_group_mean = True +# >>> dual_regression.inputs.n_perm = 10 +# >>> dual_regression.inputs.out_dir = "my_output_directory" +# >>> dual_regression.cmdline +# 'dual_regression allFA.nii 0 -1 10 my_output_directory functional.nii functional2.nii functional3.nii' +# >>> dual_regression.run() # doctest: +SKIP +# +# +task_name: DualRegression +nipype_name: DualRegression +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets + group_IC_maps_4D: medimage/nifti1 + # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis + design_file: generic/file + # type=file|default=: Design matrix for final cross-subject modelling with randomise + con_file: generic/file + # type=file|default=: Design contrasts for final cross-subject modelling with randomise + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_dir: '"my_output_directory"' + # type=directory: + # type=directory|default='output': This directory will be created to hold all output and logfiles + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets + group_IC_maps_4D: + # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis + des_norm: + # type=bool|default=True: Whether to variance-normalise the timecourses used as the stage-2 regressors; True is default and recommended + one_sample_group_mean: + # type=bool|default=False: perform 1-sample group-mean test instead of generic permutation test + design_file: + # type=file|default=: Design matrix for final cross-subject modelling with randomise + con_file: + # type=file|default=: Design contrasts for final cross-subject modelling with randomise + n_perm: + # type=int|default=0: Number of permutations for randomise; set to 1 for just raw tstat output, set to 0 to not run randomise at all. + out_dir: + # type=directory: + # type=directory|default='output': This directory will be created to hold all output and logfiles + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets + group_IC_maps_4D: + # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis + des_norm: 'False' + # type=bool|default=True: Whether to variance-normalise the timecourses used as the stage-2 regressors; True is default and recommended + one_sample_group_mean: 'True' + # type=bool|default=False: perform 1-sample group-mean test instead of generic permutation test + n_perm: '10' + # type=int|default=0: Number of permutations for randomise; set to 1 for just raw tstat output, set to 0 to not run randomise at all. + out_dir: '"my_output_directory"' + # type=directory: + # type=directory|default='output': This directory will be created to hold all output and logfiles + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: dual_regression allFA.nii 0 -1 10 my_output_directory functional.nii functional2.nii functional3.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_files: + # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets + group_IC_maps_4D: + # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis + des_norm: 'False' + # type=bool|default=True: Whether to variance-normalise the timecourses used as the stage-2 regressors; True is default and recommended + one_sample_group_mean: 'True' + # type=bool|default=False: perform 1-sample group-mean test instead of generic permutation test + n_perm: '10' + # type=int|default=0: Number of permutations for randomise; set to 1 for just raw tstat output, set to 0 to not run randomise at all. + out_dir: '"my_output_directory"' + # type=directory: + # type=directory|default='output': This directory will be created to hold all output and logfiles + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/dual_regression_callables.py b/nipype-auto-conv/specs/dual_regression_callables.py new file mode 100644 index 0000000..1e6cc35 --- /dev/null +++ b/nipype-auto-conv/specs/dual_regression_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in DualRegression.yaml""" diff --git a/nipype-auto-conv/specs/eddy.yaml b/nipype-auto-conv/specs/eddy.yaml new file mode 100644 index 0000000..7ae120f --- /dev/null +++ b/nipype-auto-conv/specs/eddy.yaml @@ -0,0 +1,375 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.Eddy' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Interface for FSL eddy, a tool for estimating and correcting eddy +# currents induced distortions. `User guide +# `__ and +# `more info regarding acqp file +# `_. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import Eddy +# +# Running eddy on a CPU using OpenMP: +# >>> eddy = Eddy() +# >>> eddy.inputs.in_file = 'epi.nii' +# >>> eddy.inputs.in_mask = 'epi_mask.nii' +# >>> eddy.inputs.in_index = 'epi_index.txt' +# >>> eddy.inputs.in_acqp = 'epi_acqp.txt' +# >>> eddy.inputs.in_bvec = 'bvecs.scheme' +# >>> eddy.inputs.in_bval = 'bvals.scheme' +# >>> eddy.cmdline # doctest: +ELLIPSIS +# 'eddy_openmp --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none' +# +# Running eddy on an Nvidia GPU using cuda: +# >>> eddy.inputs.use_cuda = True +# >>> eddy.cmdline # doctest: +ELLIPSIS +# 'eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none' +# +# Running eddy with slice-to-volume motion correction: +# >>> eddy.inputs.mporder = 6 +# >>> eddy.inputs.slice2vol_niter = 5 +# >>> eddy.inputs.slice2vol_lambda = 1 +# >>> eddy.inputs.slice2vol_interp = 'trilinear' +# >>> eddy.inputs.slice_order = 'epi_slspec.txt' +# >>> eddy.cmdline # doctest: +ELLIPSIS +# 'eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --mporder=6 --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --s2v_interp=trilinear --s2v_lambda=1 --s2v_niter=5 --slspec=epi_slspec.txt --slm=none' +# >>> res = eddy.run() # doctest: +SKIP +# +# +task_name: Eddy +nipype_name: Eddy +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: File containing all the images to estimate distortions for + in_mask: generic/file + # type=file|default=: Mask to indicate brain + in_index: text/text-file + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + in_acqp: generic/file + # type=file|default=: File containing acquisition parameters + in_bvec: generic/file + # type=file|default=: File containing the b-vectors for all volumes in --imain + in_bval: generic/file + # type=file|default=: File containing the b-values for all volumes in --imain + session: generic/file + # type=file|default=: File containing session indices for all volumes in --imain + in_topup_fieldcoef: generic/file + # type=file|default=: Topup results file containing the field coefficients + in_topup_movpar: generic/file + # type=file|default=: Topup results file containing the movement parameters (movpar.txt) + field: generic/file + # type=file|default=: Non-topup derived fieldmap scaled in Hz + field_mat: generic/file + # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain + slice_order: text/text-file + # type=file|default='': Name of text file completely specifying slice/group acquisition + json: generic/file + # type=file|default='': Name of .json text file with information about slice timing + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_corrected: generic/file + # type=file: 4D image file containing all the corrected volumes + out_parameter: generic/file + # type=file: Text file with parameters defining the field and movement for each scan + out_rotated_bvecs: generic/file + # type=file: File containing rotated b-values for all volumes + out_movement_rms: generic/file + # type=file: Summary of the 'total movement' in each volume + out_restricted_movement_rms: generic/file + # type=file: Summary of the 'total movement' in each volume disregarding translation in the PE direction + out_shell_alignment_parameters: generic/file + # type=file: Text file containing rigid body movement parameters between the different shells as estimated by a post-hoc mutual information based registration + out_shell_pe_translation_parameters: generic/file + # type=file: Text file containing translation along the PE-direction between the different shells as estimated by a post-hoc mutual information based registration + out_outlier_map: generic/file + # type=file: Matrix where rows represent volumes and columns represent slices. "0" indicates that scan-slice is not an outlier and "1" indicates that it is + out_outlier_n_stdev_map: generic/file + # type=file: Matrix where rows represent volumes and columns represent slices. Values indicate number of standard deviations off the mean difference between observation and prediction is + out_outlier_n_sqr_stdev_map: generic/file + # type=file: Matrix where rows represent volumes and columns represent slices. Values indicate number of standard deivations off the square root of the mean squared difference between observation and prediction is + out_outlier_report: generic/file + # type=file: Text file with a plain language report on what outlier slices eddy has found + out_outlier_free: generic/file + # type=file: 4D image file not corrected for susceptibility or eddy-current distortions or subject movement but with outlier slices replaced + out_movement_over_time: generic/file + # type=file: Text file containing translations (mm) and rotations (radians) for each excitation + out_cnr_maps: generic/file + # type=file: path/name of file with the cnr_maps + out_residuals: generic/file + # type=file: path/name of file with the residuals + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: File containing all the images to estimate distortions for + in_mask: + # type=file|default=: Mask to indicate brain + in_index: + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + in_acqp: + # type=file|default=: File containing acquisition parameters + in_bvec: + # type=file|default=: File containing the b-vectors for all volumes in --imain + in_bval: + # type=file|default=: File containing the b-values for all volumes in --imain + out_base: + # type=str|default='eddy_corrected': Basename for output image + session: + # type=file|default=: File containing session indices for all volumes in --imain + in_topup_fieldcoef: + # type=file|default=: Topup results file containing the field coefficients + in_topup_movpar: + # type=file|default=: Topup results file containing the movement parameters (movpar.txt) + field: + # type=file|default=: Non-topup derived fieldmap scaled in Hz + field_mat: + # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain + flm: + # type=enum|default='quadratic'|allowed['cubic','linear','quadratic']: First level EC model + slm: + # type=enum|default='none'|allowed['linear','none','quadratic']: Second level EC model + fep: + # type=bool|default=False: Fill empty planes in x- or y-directions + initrand: + # type=bool|default=False: Resets rand for when selecting voxels + interp: + # type=enum|default='spline'|allowed['spline','trilinear']: Interpolation model for estimation step + nvoxhp: + # type=int|default=1000: # of voxels used to estimate the hyperparameters + fudge_factor: + # type=float|default=10.0: Fudge factor for hyperparameter error variance + dont_sep_offs_move: + # type=bool|default=False: Do NOT attempt to separate field offset from subject movement + dont_peas: + # type=bool|default=False: Do NOT perform a post-eddy alignment of shells + fwhm: + # type=float|default=0.0: FWHM for conditioning filter when estimating the parameters + niter: + # type=int|default=5: Number of iterations + method: + # type=enum|default='jac'|allowed['jac','lsr']: Final resampling method (jacobian/least squares) + repol: + # type=bool|default=False: Detect and replace outlier slices + outlier_nstd: + # type=int|default=0: Number of std off to qualify as outlier + outlier_nvox: + # type=int|default=0: Min # of voxels in a slice for inclusion in outlier detection + outlier_type: + # type=enum|default='sw'|allowed['both','gw','sw']: Type of outliers, slicewise (sw), groupwise (gw) or both (both) + outlier_pos: + # type=bool|default=False: Consider both positive and negative outliers if set + outlier_sqr: + # type=bool|default=False: Consider outliers among sums-of-squared differences if set + multiband_factor: + # type=int|default=0: Multi-band factor + multiband_offset: + # type=enum|default=0|allowed[-1,0,1]: Multi-band offset (-1 if bottom slice removed, 1 if top slice removed + mporder: + # type=int|default=0: Order of slice-to-vol movement model + slice2vol_niter: + # type=int|default=0: Number of iterations for slice-to-vol + slice2vol_lambda: + # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) + slice2vol_interp: + # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step + slice_order: + # type=file|default='': Name of text file completely specifying slice/group acquisition + json: + # type=file|default='': Name of .json text file with information about slice timing + estimate_move_by_susceptibility: + # type=bool|default=False: Estimate how susceptibility field changes with subject movement + mbs_niter: + # type=int|default=0: Number of iterations for MBS estimation + mbs_lambda: + # type=int|default=0: Weighting of regularisation for MBS estimation + mbs_ksp: + # type=int|default=0: Knot-spacing for MBS field estimation + num_threads: + # type=int|default=1: Number of openmp threads to use + is_shelled: + # type=bool|default=False: Override internal check to ensure that date are acquired on a set of b-value shells + use_cuda: + # type=bool|default=False: Run eddy using cuda gpu + cnr_maps: + # type=bool|default=False: Output CNR-Maps + residuals: + # type=bool|default=False: Output Residuals + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: File containing all the images to estimate distortions for + in_index: + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + use_cuda: 'True' + # type=bool|default=False: Run eddy using cuda gpu + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mporder: '6' + # type=int|default=0: Order of slice-to-vol movement model + slice2vol_niter: '5' + # type=int|default=0: Number of iterations for slice-to-vol + slice2vol_lambda: '1' + # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) + slice2vol_interp: '"trilinear"' + # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step + slice_order: + # type=file|default='': Name of text file completely specifying slice/group acquisition + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: eddy_openmp --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: File containing all the images to estimate distortions for + in_index: + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS +- cmdline: eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + use_cuda: 'True' + # type=bool|default=False: Run eddy using cuda gpu + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS +- cmdline: eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --mporder=6 --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --s2v_interp=trilinear --s2v_lambda=1 --s2v_niter=5 --slspec=epi_slspec.txt --slm=none + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + mporder: '6' + # type=int|default=0: Order of slice-to-vol movement model + slice2vol_niter: '5' + # type=int|default=0: Number of iterations for slice-to-vol + slice2vol_lambda: '1' + # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) + slice2vol_interp: '"trilinear"' + # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step + slice_order: + # type=file|default='': Name of text file completely specifying slice/group acquisition + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_callables.py b/nipype-auto-conv/specs/eddy_callables.py new file mode 100644 index 0000000..8b90e54 --- /dev/null +++ b/nipype-auto-conv/specs/eddy_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Eddy.yaml""" diff --git a/nipype-auto-conv/specs/eddy_correct.yaml b/nipype-auto-conv/specs/eddy_correct.yaml new file mode 100644 index 0000000..a3bde33 --- /dev/null +++ b/nipype-auto-conv/specs/eddy_correct.yaml @@ -0,0 +1,135 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.EddyCorrect' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# +# .. warning:: Deprecated in FSL. Please use +# :class:`nipype.interfaces.fsl.epi.Eddy` instead +# +# Example +# ------- +# +# >>> from nipype.interfaces.fsl import EddyCorrect +# >>> eddyc = EddyCorrect(in_file='diffusion.nii', +# ... out_file="diffusion_edc.nii", ref_num=0) +# >>> eddyc.cmdline +# 'eddy_correct diffusion.nii diffusion_edc.nii 0' +# +# +task_name: EddyCorrect +nipype_name: EddyCorrect +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: 4D input file + out_file: medimage/nifti1 + # type=file|default=: 4D output file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + eddy_corrected: generic/file + # type=file: path/name of 4D eddy corrected output file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: 4D input file + out_file: + # type=file|default=: 4D output file + ref_num: + # type=int|default=0: reference number + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: 4D input file + out_file: + # type=file|default=: 4D output file + ref_num: '0' + # type=int|default=0: reference number + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: eddy_correct diffusion.nii diffusion_edc.nii 0 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: 4D input file + out_file: + # type=file|default=: 4D output file + ref_num: '0' + # type=int|default=0: reference number + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_correct_callables.py b/nipype-auto-conv/specs/eddy_correct_callables.py new file mode 100644 index 0000000..dfb3b96 --- /dev/null +++ b/nipype-auto-conv/specs/eddy_correct_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in EddyCorrect.yaml""" diff --git a/nipype-auto-conv/specs/eddy_quad.yaml b/nipype-auto-conv/specs/eddy_quad.yaml new file mode 100644 index 0000000..833fa37 --- /dev/null +++ b/nipype-auto-conv/specs/eddy_quad.yaml @@ -0,0 +1,172 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.EddyQuad' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Interface for FSL eddy_quad, a tool for generating single subject reports +# and storing the quality assessment indices for each subject. +# `User guide `__ +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import EddyQuad +# >>> quad = EddyQuad() +# >>> quad.inputs.base_name = 'eddy_corrected' +# >>> quad.inputs.idx_file = 'epi_index.txt' +# >>> quad.inputs.param_file = 'epi_acqp.txt' +# >>> quad.inputs.mask_file = 'epi_mask.nii' +# >>> quad.inputs.bval_file = 'bvals.scheme' +# >>> quad.inputs.bvec_file = 'bvecs.scheme' +# >>> quad.inputs.output_dir = 'eddy_corrected.qc' +# >>> quad.inputs.field = 'fieldmap_phase_fslprepared.nii' +# >>> quad.inputs.verbose = True +# >>> quad.cmdline +# 'eddy_quad eddy_corrected --bvals bvals.scheme --bvecs bvecs.scheme --field fieldmap_phase_fslprepared.nii --eddyIdx epi_index.txt --mask epi_mask.nii --output-dir eddy_corrected.qc --eddyParams epi_acqp.txt --verbose' +# >>> res = quad.run() # doctest: +SKIP +# +# +task_name: EddyQuad +nipype_name: EddyQuad +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + idx_file: generic/file + # type=file|default=: File containing indices for all volumes into acquisition parameters + param_file: text/text-file + # type=file|default=: File containing acquisition parameters + mask_file: generic/file + # type=file|default=: Binary mask file + bval_file: generic/file + # type=file|default=: b-values file + bvec_file: generic/file + # type=file|default=: b-vectors file - only used when .eddy_residuals file is present + field: generic/file + # type=file|default=: TOPUP estimated field (in Hz) + slice_spec: generic/file + # type=file|default=: Text file specifying slice/group acquisition + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + qc_json: generic/file + # type=file: Single subject database containing quality metrics and data info. + qc_pdf: generic/file + # type=file: Single subject QC report. + vdm_png: generic/file + # type=file: Image showing mid-sagittal, -coronal and -axial slices of the voxel displacement map. Generated when using the -f option. + residuals: generic/file + # type=file: Text file containing the volume-wise mask-averaged squared residuals. Generated when residual maps are available. + clean_volumes: generic/file + # type=file: Text file containing a list of clean volumes, based on the eddy squared residuals. To generate a version of the pre-processed dataset without outlier volumes, use: `fslselectvols -i -o eddy_corrected_data_clean --vols=vols_no_outliers.txt` + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + base_name: + # type=str|default='eddy_corrected': Basename (including path) for EDDY output files, i.e., corrected images and QC files + idx_file: + # type=file|default=: File containing indices for all volumes into acquisition parameters + param_file: + # type=file|default=: File containing acquisition parameters + mask_file: + # type=file|default=: Binary mask file + bval_file: + # type=file|default=: b-values file + bvec_file: + # type=file|default=: b-vectors file - only used when .eddy_residuals file is present + output_dir: + # type=str|default='': Output directory - default = '.qc' + field: + # type=file|default=: TOPUP estimated field (in Hz) + slice_spec: + # type=file|default=: Text file specifying slice/group acquisition + verbose: + # type=bool|default=False: Display debug messages + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + param_file: + # type=file|default=: File containing acquisition parameters + output_dir: '"eddy_corrected.qc"' + # type=str|default='': Output directory - default = '.qc' + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: eddy_quad eddy_corrected --bvals bvals.scheme --bvecs bvecs.scheme --field fieldmap_phase_fslprepared.nii --eddyIdx epi_index.txt --mask epi_mask.nii --output-dir eddy_corrected.qc --eddyParams epi_acqp.txt --verbose + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + param_file: + # type=file|default=: File containing acquisition parameters + output_dir: '"eddy_corrected.qc"' + # type=str|default='': Output directory - default = '.qc' + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_quad_callables.py b/nipype-auto-conv/specs/eddy_quad_callables.py new file mode 100644 index 0000000..1720ae1 --- /dev/null +++ b/nipype-auto-conv/specs/eddy_quad_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in EddyQuad.yaml""" diff --git a/nipype-auto-conv/specs/epi_de_warp.yaml b/nipype-auto-conv/specs/epi_de_warp.yaml new file mode 100644 index 0000000..69baeb1 --- /dev/null +++ b/nipype-auto-conv/specs/epi_de_warp.yaml @@ -0,0 +1,185 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.EPIDeWarp' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Wraps the unwarping script `epidewarp.fsl +# `_. +# +# .. warning:: deprecated in FSL, please use +# :func:`niflow.nipype1.workflows.dmri.preprocess.epi.sdc_fmb` instead. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import EPIDeWarp +# >>> dewarp = EPIDeWarp() +# >>> dewarp.inputs.epi_file = "functional.nii" +# >>> dewarp.inputs.mag_file = "magnitude.nii" +# >>> dewarp.inputs.dph_file = "phase.nii" +# >>> dewarp.inputs.output_type = "NIFTI_GZ" +# >>> dewarp.cmdline # doctest: +ELLIPSIS +# 'epidewarp.fsl --mag magnitude.nii --dph phase.nii --epi functional.nii --esp 0.58 --exfdw .../exfdw.nii.gz --nocleanup --sigma 2 --tediff 2.46 --tmpdir .../temp --vsm .../vsm.nii.gz' +# >>> res = dewarp.run() # doctest: +SKIP +# +# +# +task_name: EPIDeWarp +nipype_name: EPIDeWarp +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mag_file: medimage/nifti1 + # type=file|default=: Magnitude file + dph_file: medimage/nifti1 + # type=file|default=: Phase file assumed to be scaled from 0 to 4095 + exf_file: generic/file + # type=file|default=: example func volume (or use epi) + epi_file: medimage/nifti1 + # type=file|default=: EPI volume to unwarp + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + unwarped_file: generic/file + # type=file: unwarped epi file + vsm_file: generic/file + # type=file: voxel shift map + exfdw: generic/file + # type=file: dewarped functional volume example + # type=string|default='': dewarped example func volume + exf_mask: generic/file + # type=file: Mask from example functional volume + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + vsm: vsm + # type=string|default='': voxel shift map + exfdw: exfdw + # type=file: dewarped functional volume example + # type=string|default='': dewarped example func volume + tmpdir: tmpdir + # type=string|default='': tmpdir + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mag_file: + # type=file|default=: Magnitude file + dph_file: + # type=file|default=: Phase file assumed to be scaled from 0 to 4095 + exf_file: + # type=file|default=: example func volume (or use epi) + epi_file: + # type=file|default=: EPI volume to unwarp + tediff: + # type=float|default=2.46: difference in B0 field map TEs + esp: + # type=float|default=0.58: EPI echo spacing + sigma: + # type=int|default=2: 2D spatial gaussing smoothing stdev (default = 2mm) + vsm: + # type=string|default='': voxel shift map + exfdw: + # type=file: dewarped functional volume example + # type=string|default='': dewarped example func volume + epidw: + # type=string|default='': dewarped epi volume + tmpdir: + # type=string|default='': tmpdir + nocleanup: + # type=bool|default=True: no cleanup + cleanup: + # type=bool|default=False: cleanup + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + epi_file: + # type=file|default=: EPI volume to unwarp + mag_file: + # type=file|default=: Magnitude file + dph_file: + # type=file|default=: Phase file assumed to be scaled from 0 to 4095 + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: epidewarp.fsl --mag magnitude.nii --dph phase.nii --epi functional.nii --esp 0.58 --exfdw .../exfdw.nii.gz --nocleanup --sigma 2 --tediff 2.46 --tmpdir .../temp --vsm .../vsm.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + epi_file: + # type=file|default=: EPI volume to unwarp + mag_file: + # type=file|default=: Magnitude file + dph_file: + # type=file|default=: Phase file assumed to be scaled from 0 to 4095 + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/epi_de_warp_callables.py b/nipype-auto-conv/specs/epi_de_warp_callables.py new file mode 100644 index 0000000..33f2aea --- /dev/null +++ b/nipype-auto-conv/specs/epi_de_warp_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in EPIDeWarp.yaml""" diff --git a/nipype-auto-conv/specs/epi_reg.yaml b/nipype-auto-conv/specs/epi_reg.yaml new file mode 100644 index 0000000..c5e5dad --- /dev/null +++ b/nipype-auto-conv/specs/epi_reg.yaml @@ -0,0 +1,229 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.EpiReg' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# +# Runs FSL epi_reg script for simultaneous coregistration and fieldmap +# unwarping. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import EpiReg +# >>> epireg = EpiReg() +# >>> epireg.inputs.epi='epi.nii' +# >>> epireg.inputs.t1_head='T1.nii' +# >>> epireg.inputs.t1_brain='T1_brain.nii' +# >>> epireg.inputs.out_base='epi2struct' +# >>> epireg.inputs.fmap='fieldmap_phase_fslprepared.nii' +# >>> epireg.inputs.fmapmag='fieldmap_mag.nii' +# >>> epireg.inputs.fmapmagbrain='fieldmap_mag_brain.nii' +# >>> epireg.inputs.echospacing=0.00067 +# >>> epireg.inputs.pedir='y' +# >>> epireg.cmdline # doctest: +ELLIPSIS +# 'epi_reg --echospacing=0.000670 --fmap=fieldmap_phase_fslprepared.nii --fmapmag=fieldmap_mag.nii --fmapmagbrain=fieldmap_mag_brain.nii --noclean --pedir=y --epi=epi.nii --t1=T1.nii --t1brain=T1_brain.nii --out=epi2struct' +# >>> epireg.run() # doctest: +SKIP +# +# +task_name: EpiReg +nipype_name: EpiReg +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + epi: medimage/nifti1 + # type=file|default=: EPI image + t1_head: medimage/nifti1 + # type=file|default=: wholehead T1 image + t1_brain: medimage/nifti1 + # type=file|default=: brain extracted T1 image + fmap: medimage/nifti1 + # type=file|default=: fieldmap image (in rad/s) + fmapmag: medimage/nifti1 + # type=file|default=: fieldmap magnitude image - wholehead + fmapmagbrain: medimage/nifti1 + # type=file|default=: fieldmap magnitude image - brain extracted + wmseg: generic/file + # type=file: white matter segmentation used in flirt bbr + # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg + weight_image: generic/file + # type=file|default=: weighting image (in T1 space) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: unwarped and coregistered epi input + out_1vol: generic/file + # type=file: unwarped and coregistered single volume + fmap2str_mat: generic/file + # type=file: rigid fieldmap-to-structural transform + fmap2epi_mat: generic/file + # type=file: rigid fieldmap-to-epi transform + fmap_epi: generic/file + # type=file: fieldmap in epi space + fmap_str: generic/file + # type=file: fieldmap in structural space + fmapmag_str: generic/file + # type=file: fieldmap magnitude image in structural space + epi2str_inv: generic/file + # type=file: rigid structural-to-epi transform + epi2str_mat: generic/file + # type=file: rigid epi-to-structural transform + shiftmap: generic/file + # type=file: shiftmap in epi space + fullwarp: generic/file + # type=file: warpfield to unwarp epi and transform into structural space + wmseg: generic/file + # type=file: white matter segmentation used in flirt bbr + # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg + seg: generic/file + # type=file: white matter, gray matter, csf segmentation + wmedge: generic/file + # type=file: white matter edges for visualization + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + epi: + # type=file|default=: EPI image + t1_head: + # type=file|default=: wholehead T1 image + t1_brain: + # type=file|default=: brain extracted T1 image + out_base: + # type=string|default='epi2struct': output base name + fmap: + # type=file|default=: fieldmap image (in rad/s) + fmapmag: + # type=file|default=: fieldmap magnitude image - wholehead + fmapmagbrain: + # type=file|default=: fieldmap magnitude image - brain extracted + wmseg: + # type=file: white matter segmentation used in flirt bbr + # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg + echospacing: + # type=float|default=0.0: Effective EPI echo spacing (sometimes called dwell time) - in seconds + pedir: + # type=enum|default='x'|allowed['-x','-y','-z','x','y','z']: phase encoding direction, dir = x/y/z/-x/-y/-z + weight_image: + # type=file|default=: weighting image (in T1 space) + no_fmapreg: + # type=bool|default=False: do not perform registration of fmap to T1 (use if fmap already registered) + no_clean: + # type=bool|default=True: do not clean up intermediate files + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + epi: + # type=file|default=: EPI image + t1_head: + # type=file|default=: wholehead T1 image + t1_brain: + # type=file|default=: brain extracted T1 image + out_base: '"epi2struct"' + # type=string|default='epi2struct': output base name + fmap: + # type=file|default=: fieldmap image (in rad/s) + fmapmag: + # type=file|default=: fieldmap magnitude image - wholehead + fmapmagbrain: + # type=file|default=: fieldmap magnitude image - brain extracted + echospacing: '0.00067' + # type=float|default=0.0: Effective EPI echo spacing (sometimes called dwell time) - in seconds + pedir: '"y"' + # type=enum|default='x'|allowed['-x','-y','-z','x','y','z']: phase encoding direction, dir = x/y/z/-x/-y/-z + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: epi_reg --echospacing=0.000670 --fmap=fieldmap_phase_fslprepared.nii --fmapmag=fieldmap_mag.nii --fmapmagbrain=fieldmap_mag_brain.nii --noclean --pedir=y --epi=epi.nii --t1=T1.nii --t1brain=T1_brain.nii --out=epi2struct + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + epi: + # type=file|default=: EPI image + t1_head: + # type=file|default=: wholehead T1 image + t1_brain: + # type=file|default=: brain extracted T1 image + out_base: '"epi2struct"' + # type=string|default='epi2struct': output base name + fmap: + # type=file|default=: fieldmap image (in rad/s) + fmapmag: + # type=file|default=: fieldmap magnitude image - wholehead + fmapmagbrain: + # type=file|default=: fieldmap magnitude image - brain extracted + echospacing: '0.00067' + # type=float|default=0.0: Effective EPI echo spacing (sometimes called dwell time) - in seconds + pedir: '"y"' + # type=enum|default='x'|allowed['-x','-y','-z','x','y','z']: phase encoding direction, dir = x/y/z/-x/-y/-z + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/epi_reg_callables.py b/nipype-auto-conv/specs/epi_reg_callables.py new file mode 100644 index 0000000..06d672a --- /dev/null +++ b/nipype-auto-conv/specs/epi_reg_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in EpiReg.yaml""" diff --git a/nipype-auto-conv/specs/erode_image.yaml b/nipype-auto-conv/specs/erode_image.yaml new file mode 100644 index 0000000..948c0e1 --- /dev/null +++ b/nipype-auto-conv/specs/erode_image.yaml @@ -0,0 +1,97 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.ErodeImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to perform a spatial erosion of an image. +task_name: ErodeImage +nipype_name: ErodeImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + kernel_file: generic/file + # type=file|default=: use external file for kernel + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + minimum_filter: + # type=bool|default=False: if true, minimum filter rather than erosion by zeroing-out + kernel_shape: + # type=enum|default='3D'|allowed['2D','3D','box','boxv','file','gauss','sphere']: kernel shape to use + kernel_size: + # type=float|default=0.0: kernel size - voxels for box/boxv, mm for sphere, mm sigma for gauss + kernel_file: + # type=file|default=: use external file for kernel + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/erode_image_callables.py b/nipype-auto-conv/specs/erode_image_callables.py new file mode 100644 index 0000000..545fa4d --- /dev/null +++ b/nipype-auto-conv/specs/erode_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ErodeImage.yaml""" diff --git a/nipype-auto-conv/specs/extract_roi.yaml b/nipype-auto-conv/specs/extract_roi.yaml new file mode 100644 index 0000000..d0db703 --- /dev/null +++ b/nipype-auto-conv/specs/extract_roi.yaml @@ -0,0 +1,172 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.ExtractROI' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Uses FSL Fslroi command to extract region of interest (ROI) +# from an image. +# +# You can a) take a 3D ROI from a 3D data set (or if it is 4D, the +# same ROI is taken from each time point and a new 4D data set is +# created), b) extract just some time points from a 4D data set, or +# c) control time and space limits to the ROI. Note that the +# arguments are minimum index and size (not maximum index). So to +# extract voxels 10 to 12 inclusive you would specify 10 and 3 (not +# 10 and 12). +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import ExtractROI +# >>> from nipype.testing import anatfile +# >>> fslroi = ExtractROI(in_file=anatfile, roi_file='bar.nii', t_min=0, +# ... t_size=1) +# >>> fslroi.cmdline == 'fslroi %s bar.nii 0 1' % anatfile +# True +# +# +# +task_name: ExtractROI +nipype_name: ExtractROI +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + roi_file: medimage/nifti1 + # type=file: + # type=file|default=: output file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + roi_file: '"bar.nii"' + # type=file: + # type=file|default=: output file + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file + roi_file: + # type=file: + # type=file|default=: output file + x_min: + # type=int|default=0: + x_size: + # type=int|default=0: + y_min: + # type=int|default=0: + y_size: + # type=int|default=0: + z_min: + # type=int|default=0: + z_size: + # type=int|default=0: + t_min: + # type=int|default=0: + t_size: + # type=int|default=0: + crop_list: + # type=list|default=[]: list of two tuples specifying crop options + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file + roi_file: '"bar.nii"' + # type=file: + # type=file|default=: output file + t_min: '0' + # type=int|default=0: + t_size: '1' + # type=int|default=0: + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.testing + name: anatfile + alias: + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input file + roi_file: '"bar.nii"' + # type=file: + # type=file|default=: output file + t_min: '0' + # type=int|default=0: + t_size: '1' + # type=int|default=0: + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/extract_roi_callables.py b/nipype-auto-conv/specs/extract_roi_callables.py new file mode 100644 index 0000000..9292403 --- /dev/null +++ b/nipype-auto-conv/specs/extract_roi_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ExtractROI.yaml""" diff --git a/nipype-auto-conv/specs/fast.yaml b/nipype-auto-conv/specs/fast.yaml new file mode 100644 index 0000000..2ffd753 --- /dev/null +++ b/nipype-auto-conv/specs/fast.yaml @@ -0,0 +1,181 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.FAST' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL FAST wrapper for segmentation and bias correction +# +# For complete details, see the `FAST Documentation. +# `_ +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> fastr = fsl.FAST() +# >>> fastr.inputs.in_files = 'structural.nii' +# >>> fastr.inputs.out_basename = 'fast_' +# >>> fastr.cmdline +# 'fast -o fast_ -S 1 structural.nii' +# >>> out = fastr.run() # doctest: +SKIP +# +# +task_name: FAST +nipype_name: FAST +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented + out_basename: generic/file + # type=file|default=: base name of output files + init_transform: generic/file + # type=file|default=: initialise using priors + other_priors: generic/file+list-of + # type=inputmultiobject|default=[]: alternative prior images + manual_seg: generic/file + # type=file|default=: Filename containing intensities + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + tissue_class_map: generic/file + # type=file: path/name of binary segmented volume file one val for each class _seg + mixeltype: generic/file + # type=file: path/name of mixeltype volume file _mixeltype + partial_volume_map: generic/file + # type=file: path/name of partial volume file _pveseg + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented + out_basename: + # type=file|default=: base name of output files + number_classes: + # type=range|default=1: number of tissue-type classes + output_biasfield: + # type=bool|default=False: output estimated bias field + output_biascorrected: + # type=bool|default=False: output restored image (bias-corrected image) + img_type: + # type=enum|default=1|allowed[1,2,3]: int specifying type of image: (1 = T1, 2 = T2, 3 = PD) + bias_iters: + # type=range|default=1: number of main-loop iterations during bias-field removal + bias_lowpass: + # type=range|default=4: bias field smoothing extent (FWHM) in mm + init_seg_smooth: + # type=range|default=0.0001: initial segmentation spatial smoothness (during bias field estimation) + segments: + # type=bool|default=False: outputs a separate binary image for each tissue type + init_transform: + # type=file|default=: initialise using priors + other_priors: + # type=inputmultiobject|default=[]: alternative prior images + no_pve: + # type=bool|default=False: turn off PVE (partial volume estimation) + no_bias: + # type=bool|default=False: do not remove bias field + use_priors: + # type=bool|default=False: use priors throughout + segment_iters: + # type=range|default=1: number of segmentation-initialisation iterations + mixel_smooth: + # type=range|default=0.0: spatial smoothness for mixeltype + iters_afterbias: + # type=range|default=1: number of main-loop iterations after bias-field removal + hyper: + # type=range|default=0.0: segmentation spatial smoothness + verbose: + # type=bool|default=False: switch on diagnostic messages + manual_seg: + # type=file|default=: Filename containing intensities + probability_maps: + # type=outputmultiobject: + # type=bool|default=False: outputs individual probability maps + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented + out_basename: + # type=file|default=: base name of output files + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fast -o fast_ -S 1 structural.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_files: + # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented + out_basename: + # type=file|default=: base name of output files + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fast_callables.py b/nipype-auto-conv/specs/fast_callables.py new file mode 100644 index 0000000..4e29548 --- /dev/null +++ b/nipype-auto-conv/specs/fast_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FAST.yaml""" diff --git a/nipype-auto-conv/specs/feat.yaml b/nipype-auto-conv/specs/feat.yaml new file mode 100644 index 0000000..94af3ad --- /dev/null +++ b/nipype-auto-conv/specs/feat.yaml @@ -0,0 +1,72 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.FEAT' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Uses FSL feat to calculate first level stats +task_name: FEAT +nipype_name: FEAT +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + fsf_file: generic/file + # type=file|default=: File specifying the feat design spec file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + fsf_file: + # type=file|default=: File specifying the feat design spec file + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/feat_callables.py b/nipype-auto-conv/specs/feat_callables.py new file mode 100644 index 0000000..ac5b32f --- /dev/null +++ b/nipype-auto-conv/specs/feat_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FEAT.yaml""" diff --git a/nipype-auto-conv/specs/feat_model.yaml b/nipype-auto-conv/specs/feat_model.yaml new file mode 100644 index 0000000..6594e63 --- /dev/null +++ b/nipype-auto-conv/specs/feat_model.yaml @@ -0,0 +1,86 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.FEATModel' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Uses FSL feat_model to generate design.mat files +task_name: FEATModel +nipype_name: FEATModel +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + fsf_file: generic/file + # type=file|default=: File specifying the feat design spec file + ev_files: generic/file+list-of + # type=list|default=[]: Event spec files generated by level1design + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + design_file: generic/file + # type=file: Mat file containing ascii matrix for design + design_image: generic/file + # type=file: Graphical representation of design matrix + design_cov: generic/file + # type=file: Graphical representation of design covariance + con_file: generic/file + # type=file: Contrast file containing contrast vectors + fcon_file: generic/file + # type=file: Contrast file containing contrast vectors + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + fsf_file: + # type=file|default=: File specifying the feat design spec file + ev_files: + # type=list|default=[]: Event spec files generated by level1design + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/feat_model_callables.py b/nipype-auto-conv/specs/feat_model_callables.py new file mode 100644 index 0000000..ddb4019 --- /dev/null +++ b/nipype-auto-conv/specs/feat_model_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FEATModel.yaml""" diff --git a/nipype-auto-conv/specs/feat_register.yaml b/nipype-auto-conv/specs/feat_register.yaml new file mode 100644 index 0000000..fadda16 --- /dev/null +++ b/nipype-auto-conv/specs/feat_register.yaml @@ -0,0 +1,74 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.FEATRegister' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Register feat directories to a specific standard +task_name: FEATRegister +nipype_name: FEATRegister +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + feat_dirs: generic/file+list-of + # type=inputmultiobject|default=[]: Lower level feat dirs + reg_image: generic/file + # type=file|default=: image to register to (will be treated as standard) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + fsf_file: generic/file + # type=file: FSL feat specification file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + feat_dirs: + # type=inputmultiobject|default=[]: Lower level feat dirs + reg_image: + # type=file|default=: image to register to (will be treated as standard) + reg_dof: + # type=int|default=12: registration degrees of freedom + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/feat_register_callables.py b/nipype-auto-conv/specs/feat_register_callables.py new file mode 100644 index 0000000..8271252 --- /dev/null +++ b/nipype-auto-conv/specs/feat_register_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FEATRegister.yaml""" diff --git a/nipype-auto-conv/specs/feature_extractor.yaml b/nipype-auto-conv/specs/feature_extractor.yaml new file mode 100644 index 0000000..0e017da --- /dev/null +++ b/nipype-auto-conv/specs/feature_extractor.yaml @@ -0,0 +1,71 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.fix.FeatureExtractor' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Extract features (for later training and/or classifying) +# +task_name: FeatureExtractor +nipype_name: FeatureExtractor +nipype_module: nipype.interfaces.fsl.fix +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mel_ica: + # type=directory: Melodic output directory or directories + # type=directory|default=: Melodic output directory or directories + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/feature_extractor_callables.py b/nipype-auto-conv/specs/feature_extractor_callables.py new file mode 100644 index 0000000..1bcc7da --- /dev/null +++ b/nipype-auto-conv/specs/feature_extractor_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FeatureExtractor.yaml""" diff --git a/nipype-auto-conv/specs/filmgls.yaml b/nipype-auto-conv/specs/filmgls.yaml new file mode 100644 index 0000000..2df9dc4 --- /dev/null +++ b/nipype-auto-conv/specs/filmgls.yaml @@ -0,0 +1,152 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.FILMGLS' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL film_gls command to fit a design matrix to voxel timeseries +# +# Examples +# -------- +# +# Initialize with no options, assigning them when calling run: +# +# >>> from nipype.interfaces import fsl +# >>> fgls = fsl.FILMGLS() +# >>> res = fgls.run('in_file', 'design_file', 'thresh', rn='stats') #doctest: +SKIP +# +# Assign options through the ``inputs`` attribute: +# +# >>> fgls = fsl.FILMGLS() +# >>> fgls.inputs.in_file = 'functional.nii' +# >>> fgls.inputs.design_file = 'design.mat' +# >>> fgls.inputs.threshold = 10 +# >>> fgls.inputs.results_dir = 'stats' +# >>> res = fgls.run() #doctest: +SKIP +# +# Specify options when creating an instance: +# +# >>> fgls = fsl.FILMGLS(in_file='functional.nii', design_file='design.mat', threshold=10, results_dir='stats') +# >>> res = fgls.run() #doctest: +SKIP +# +# +task_name: FILMGLS +nipype_name: FILMGLS +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + tcon_file: generic/file + # type=file|default=: contrast file containing T-contrasts + fcon_file: generic/file + # type=file|default=: contrast file containing F-contrasts + surface: generic/file + # type=file|default=: input surface for autocorr smoothing in surface-based analyses + in_file: generic/file + # type=file|default=: input data file + design_file: generic/file + # type=file|default=: design matrix file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + residual4d: generic/file + # type=file: Model fit residual mean-squared error for each time point + dof_file: generic/file + # type=file: degrees of freedom + sigmasquareds: generic/file + # type=file: summary of residuals, See Woolrich, et. al., 2001 + thresholdac: generic/file + # type=file: The FILM autocorrelation parameters + logfile: generic/file + # type=file: FILM run logfile + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + threshold: + # type=float|default=-1000.0: threshold + tcon_file: + # type=file|default=: contrast file containing T-contrasts + fcon_file: + # type=file|default=: contrast file containing F-contrasts + mode: + # type=enum|default='volumetric'|allowed['surface','volumetric']: Type of analysis to be done + surface: + # type=file|default=: input surface for autocorr smoothing in surface-based analyses + in_file: + # type=file|default=: input data file + design_file: + # type=file|default=: design matrix file + smooth_autocorr: + # type=bool|default=False: Smooth auto corr estimates + mask_size: + # type=int|default=0: susan mask size + brightness_threshold: + # type=range|default=0: susan brightness threshold, otherwise it is estimated + full_data: + # type=bool|default=False: output full data + autocorr_estimate_only: + # type=bool|default=False: perform autocorrelation estimation only + fit_armodel: + # type=bool|default=False: fits autoregressive model - default is to use tukey with M=sqrt(numvols) + tukey_window: + # type=int|default=0: tukey window size to estimate autocorr + multitaper_product: + # type=int|default=0: multitapering with slepian tapers and num is the time-bandwidth product + use_pava: + # type=bool|default=False: estimates autocorr using PAVA + autocorr_noestimate: + # type=bool|default=False: do not estimate autocorrs + output_pwdata: + # type=bool|default=False: output prewhitened data and average design matrix + results_dir: + # type=directory: directory storing model estimation output + # type=directory|default='results': directory to store results in + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/filmgls_callables.py b/nipype-auto-conv/specs/filmgls_callables.py new file mode 100644 index 0000000..2911e6a --- /dev/null +++ b/nipype-auto-conv/specs/filmgls_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FILMGLS.yaml""" diff --git a/nipype-auto-conv/specs/filter_regressor.yaml b/nipype-auto-conv/specs/filter_regressor.yaml new file mode 100644 index 0000000..68f738f --- /dev/null +++ b/nipype-auto-conv/specs/filter_regressor.yaml @@ -0,0 +1,100 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.FilterRegressor' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Data de-noising by regressing out part of a design matrix +# +# Uses simple OLS regression on 4D images +# +task_name: FilterRegressor +nipype_name: FilterRegressor +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input file name (4D image) + design_file: generic/file + # type=file|default=: name of the matrix with time courses (e.g. GLM design or MELODIC mixing matrix) + mask: generic/file + # type=file|default=: mask image file name + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: output file name for the filtered data + # type=file|default=: output file name for the filtered data + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: output file name for the filtered data + # type=file|default=: output file name for the filtered data + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file name (4D image) + out_file: + # type=file: output file name for the filtered data + # type=file|default=: output file name for the filtered data + design_file: + # type=file|default=: name of the matrix with time courses (e.g. GLM design or MELODIC mixing matrix) + filter_columns: + # type=list|default=[]: (1-based) column indices to filter out of the data + filter_all: + # type=bool|default=False: use all columns in the design file in denoising + mask: + # type=file|default=: mask image file name + var_norm: + # type=bool|default=False: perform variance-normalization on data + out_vnscales: + # type=bool|default=False: output scaling factors for variance normalization + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/filter_regressor_callables.py b/nipype-auto-conv/specs/filter_regressor_callables.py new file mode 100644 index 0000000..9e1cd02 --- /dev/null +++ b/nipype-auto-conv/specs/filter_regressor_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FilterRegressor.yaml""" diff --git a/nipype-auto-conv/specs/find_the_biggest.yaml b/nipype-auto-conv/specs/find_the_biggest.yaml new file mode 100644 index 0000000..d44c932 --- /dev/null +++ b/nipype-auto-conv/specs/find_the_biggest.yaml @@ -0,0 +1,135 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.FindTheBiggest' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL find_the_biggest for performing hard segmentation on +# the outputs of connectivity-based thresholding in probtrack. +# For complete details, see the `FDT +# Documentation. `_ +# +# Example +# ------- +# +# >>> from nipype.interfaces import fsl +# >>> ldir = ['seeds_to_M1.nii', 'seeds_to_M2.nii'] +# >>> fBig = fsl.FindTheBiggest(in_files=ldir, out_file='biggestSegmentation') +# >>> fBig.cmdline +# 'find_the_biggest seeds_to_M1.nii seeds_to_M2.nii biggestSegmentation' +# +# +task_name: FindTheBiggest +nipype_name: FindTheBiggest +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: generic/file+list-of + # type=list|default=[]: a list of input volumes or a singleMatrixFile + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: output file indexed in order of input files + # type=file|default=: file with the resulting segmentation + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"biggestSegmentation"' + # type=file: output file indexed in order of input files + # type=file|default=: file with the resulting segmentation + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=list|default=[]: a list of input volumes or a singleMatrixFile + out_file: + # type=file: output file indexed in order of input files + # type=file|default=: file with the resulting segmentation + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=list|default=[]: a list of input volumes or a singleMatrixFile + out_file: '"biggestSegmentation"' + # type=file: output file indexed in order of input files + # type=file|default=: file with the resulting segmentation + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: find_the_biggest seeds_to_M1.nii seeds_to_M2.nii biggestSegmentation + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_files: + # type=list|default=[]: a list of input volumes or a singleMatrixFile + out_file: '"biggestSegmentation"' + # type=file: output file indexed in order of input files + # type=file|default=: file with the resulting segmentation + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/find_the_biggest_callables.py b/nipype-auto-conv/specs/find_the_biggest_callables.py new file mode 100644 index 0000000..a666e9d --- /dev/null +++ b/nipype-auto-conv/specs/find_the_biggest_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FindTheBiggest.yaml""" diff --git a/nipype-auto-conv/specs/first.yaml b/nipype-auto-conv/specs/first.yaml new file mode 100644 index 0000000..b19e26e --- /dev/null +++ b/nipype-auto-conv/specs/first.yaml @@ -0,0 +1,109 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.FIRST' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL run_first_all wrapper for segmentation of subcortical volumes +# +# http://www.fmrib.ox.ac.uk/fsl/first/index.html +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> first = fsl.FIRST() +# >>> first.inputs.in_file = 'structural.nii' +# >>> first.inputs.out_file = 'segmented.nii' +# >>> res = first.run() #doctest: +SKIP +# +# +task_name: FIRST +nipype_name: FIRST +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input data file + out_file: generic/file + # type=file|default='segmented': output data file + affine_file: generic/file + # type=file|default=: Affine matrix to use (e.g. img2std.mat) (does not re-run registration) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + original_segmentations: generic/file + # type=file: 3D image file containing the segmented regions as integer values. Uses CMA labelling + segmentation_file: generic/file + # type=file: 4D image file containing a single volume per segmented region + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input data file + out_file: + # type=file|default='segmented': output data file + verbose: + # type=bool|default=False: Use verbose logging. + brain_extracted: + # type=bool|default=False: Input structural image is already brain-extracted + no_cleanup: + # type=bool|default=False: Input structural image is already brain-extracted + method: + # type=enum|default='auto'|allowed['auto','fast','none']: Method must be one of auto, fast, none, or it can be entered using the 'method_as_numerical_threshold' input + method_as_numerical_threshold: + # type=float|default=0.0: Specify a numerical threshold value or use the 'method' input to choose auto, fast, or none + list_of_specific_structures: + # type=list|default=[]: Runs only on the specified structures (e.g. L_Hipp, R_HippL_Accu, R_Accu, L_Amyg, R_AmygL_Caud, R_Caud, L_Pall, R_PallL_Puta, R_Puta, L_Thal, R_Thal, BrStem + affine_file: + # type=file|default=: Affine matrix to use (e.g. img2std.mat) (does not re-run registration) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/first_callables.py b/nipype-auto-conv/specs/first_callables.py new file mode 100644 index 0000000..08786d5 --- /dev/null +++ b/nipype-auto-conv/specs/first_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FIRST.yaml""" diff --git a/nipype-auto-conv/specs/flameo.yaml b/nipype-auto-conv/specs/flameo.yaml new file mode 100644 index 0000000..b3d3c8d --- /dev/null +++ b/nipype-auto-conv/specs/flameo.yaml @@ -0,0 +1,196 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.FLAMEO' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL flameo command to perform higher level model fits +# +# Examples +# -------- +# +# Initialize FLAMEO with no options, assigning them when calling run: +# +# >>> from nipype.interfaces import fsl +# >>> flameo = fsl.FLAMEO() +# >>> flameo.inputs.cope_file = 'cope.nii.gz' +# >>> flameo.inputs.var_cope_file = 'varcope.nii.gz' +# >>> flameo.inputs.cov_split_file = 'cov_split.mat' +# >>> flameo.inputs.design_file = 'design.mat' +# >>> flameo.inputs.t_con_file = 'design.con' +# >>> flameo.inputs.mask_file = 'mask.nii' +# >>> flameo.inputs.run_mode = 'fe' +# >>> flameo.cmdline +# 'flameo --copefile=cope.nii.gz --covsplitfile=cov_split.mat --designfile=design.mat --ld=stats --maskfile=mask.nii --runmode=fe --tcontrastsfile=design.con --varcopefile=varcope.nii.gz' +# +# +task_name: FLAMEO +nipype_name: FLAMEO +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + cope_file: medimage/nifti-gz + # type=file|default=: cope regressor data file + var_cope_file: medimage/nifti-gz + # type=file|default=: varcope weightings data file + dof_var_cope_file: generic/file + # type=file|default=: dof data file for varcope data + mask_file: medimage/nifti1 + # type=file|default=: mask file + design_file: datascience/text-matrix + # type=file|default=: design matrix file + t_con_file: medimage-fsl/con + # type=file|default=: ascii matrix specifying t-contrasts + f_con_file: generic/file + # type=file|default=: ascii matrix specifying f-contrasts + cov_split_file: datascience/text-matrix + # type=file|default=: ascii matrix specifying the groups the covariance is split into + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + cope_file: + # type=file|default=: cope regressor data file + var_cope_file: + # type=file|default=: varcope weightings data file + dof_var_cope_file: + # type=file|default=: dof data file for varcope data + mask_file: + # type=file|default=: mask file + design_file: + # type=file|default=: design matrix file + t_con_file: + # type=file|default=: ascii matrix specifying t-contrasts + f_con_file: + # type=file|default=: ascii matrix specifying f-contrasts + cov_split_file: + # type=file|default=: ascii matrix specifying the groups the covariance is split into + run_mode: + # type=enum|default='fe'|allowed['fe','flame1','flame12','ols']: inference to perform + n_jumps: + # type=int|default=0: number of jumps made by mcmc + burnin: + # type=int|default=0: number of jumps at start of mcmc to be discarded + sample_every: + # type=int|default=0: number of jumps for each sample + fix_mean: + # type=bool|default=False: fix mean for tfit + infer_outliers: + # type=bool|default=False: infer outliers - not for fe + no_pe_outputs: + # type=bool|default=False: do not output pe files + sigma_dofs: + # type=int|default=0: sigma (in mm) to use for Gaussian smoothing the DOFs in FLAME 2. Default is 1mm, -1 indicates no smoothing + outlier_iter: + # type=int|default=0: Number of max iterations to use when inferring outliers. Default is 12. + log_dir: + # type=directory|default='stats': + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + cope_file: + # type=file|default=: cope regressor data file + var_cope_file: + # type=file|default=: varcope weightings data file + cov_split_file: + # type=file|default=: ascii matrix specifying the groups the covariance is split into + design_file: + # type=file|default=: design matrix file + t_con_file: + # type=file|default=: ascii matrix specifying t-contrasts + mask_file: + # type=file|default=: mask file + run_mode: '"fe"' + # type=enum|default='fe'|allowed['fe','flame1','flame12','ols']: inference to perform + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: flameo --copefile=cope.nii.gz --covsplitfile=cov_split.mat --designfile=design.mat --ld=stats --maskfile=mask.nii --runmode=fe --tcontrastsfile=design.con --varcopefile=varcope.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + cope_file: + # type=file|default=: cope regressor data file + var_cope_file: + # type=file|default=: varcope weightings data file + cov_split_file: + # type=file|default=: ascii matrix specifying the groups the covariance is split into + design_file: + # type=file|default=: design matrix file + t_con_file: + # type=file|default=: ascii matrix specifying t-contrasts + mask_file: + # type=file|default=: mask file + run_mode: '"fe"' + # type=enum|default='fe'|allowed['fe','flame1','flame12','ols']: inference to perform + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/flameo_callables.py b/nipype-auto-conv/specs/flameo_callables.py new file mode 100644 index 0000000..d01dd85 --- /dev/null +++ b/nipype-auto-conv/specs/flameo_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FLAMEO.yaml""" diff --git a/nipype-auto-conv/specs/flirt.yaml b/nipype-auto-conv/specs/flirt.yaml new file mode 100644 index 0000000..c70491e --- /dev/null +++ b/nipype-auto-conv/specs/flirt.yaml @@ -0,0 +1,277 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.FLIRT' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL FLIRT wrapper for coregistration +# +# For complete details, see the `FLIRT Documentation. +# `_ +# +# To print out the command line help, use: +# fsl.FLIRT().inputs_help() +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import example_data +# >>> flt = fsl.FLIRT(bins=640, cost_func='mutualinfo') +# >>> flt.inputs.in_file = 'structural.nii' +# >>> flt.inputs.reference = 'mni.nii' +# >>> flt.inputs.output_type = "NIFTI_GZ" +# >>> flt.cmdline # doctest: +ELLIPSIS +# 'flirt -in structural.nii -ref mni.nii -out structural_flirt.nii.gz -omat structural_flirt.mat -bins 640 -searchcost mutualinfo' +# >>> res = flt.run() #doctest: +SKIP +# +# +task_name: FLIRT +nipype_name: FLIRT +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: input file + reference: medimage/nifti1 + # type=file|default=: reference file + out_file: generic/file + # type=file: path/name of registered file (if generated) + # type=file|default=: registered output file + out_matrix_file: generic/file + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format + out_log: generic/file + # type=file: path/name of output log (if generated) + # type=file|default=: output log + in_matrix_file: generic/file + # type=file|default=: input 4x4 affine matrix + schedule: generic/file + # type=file|default=: replaces default schedule + ref_weight: generic/file + # type=file|default=: File for reference weighting volume + in_weight: generic/file + # type=file|default=: File for input weighting volume + wm_seg: generic/file + # type=file|default=: white matter segmentation volume needed by BBR cost function + wmcoords: generic/file + # type=file|default=: white matter boundary coordinates for BBR cost function + wmnorms: generic/file + # type=file|default=: white matter boundary normals for BBR cost function + fieldmap: generic/file + # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image + fieldmapmask: generic/file + # type=file|default=: mask for fieldmap image + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: path/name of registered file (if generated) + # type=file|default=: registered output file + out_matrix_file: generic/file + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format + out_log: generic/file + # type=file: path/name of output log (if generated) + # type=file|default=: output log + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file + reference: + # type=file|default=: reference file + out_file: + # type=file: path/name of registered file (if generated) + # type=file|default=: registered output file + out_matrix_file: + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format + out_log: + # type=file: path/name of output log (if generated) + # type=file|default=: output log + in_matrix_file: + # type=file|default=: input 4x4 affine matrix + apply_xfm: + # type=bool|default=False: apply transformation supplied by in_matrix_file or uses_qform to use the affine matrix stored in the reference header + apply_isoxfm: + # type=float|default=0.0: as applyxfm but forces isotropic resampling + datatype: + # type=enum|default='char'|allowed['char','double','float','int','short']: force output data type + cost: + # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function + cost_func: + # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function + uses_qform: + # type=bool|default=False: initialize using sform or qform + display_init: + # type=bool|default=False: display initial matrix + angle_rep: + # type=enum|default='quaternion'|allowed['euler','quaternion']: representation of rotation angles + interp: + # type=enum|default='trilinear'|allowed['nearestneighbour','sinc','spline','trilinear']: final interpolation method used in reslicing + sinc_width: + # type=int|default=0: full-width in voxels + sinc_window: + # type=enum|default='rectangular'|allowed['blackman','hanning','rectangular']: sinc window + bins: + # type=int|default=0: number of histogram bins + dof: + # type=int|default=0: number of transform degrees of freedom + no_resample: + # type=bool|default=False: do not change input sampling + force_scaling: + # type=bool|default=False: force rescaling even for low-res images + min_sampling: + # type=float|default=0.0: set minimum voxel dimension for sampling + padding_size: + # type=int|default=0: for applyxfm: interpolates outside image by size + searchr_x: + # type=list|default=[]: search angles along x-axis, in degrees + searchr_y: + # type=list|default=[]: search angles along y-axis, in degrees + searchr_z: + # type=list|default=[]: search angles along z-axis, in degrees + no_search: + # type=bool|default=False: set all angular searches to ranges 0 to 0 + coarse_search: + # type=int|default=0: coarse search delta angle + fine_search: + # type=int|default=0: fine search delta angle + schedule: + # type=file|default=: replaces default schedule + ref_weight: + # type=file|default=: File for reference weighting volume + in_weight: + # type=file|default=: File for input weighting volume + no_clamp: + # type=bool|default=False: do not use intensity clamping + no_resample_blur: + # type=bool|default=False: do not use blurring on downsampling + rigid2D: + # type=bool|default=False: use 2D rigid body mode - ignores dof + save_log: + # type=bool|default=False: save to log file + verbose: + # type=int|default=0: verbose mode, 0 is least + bgvalue: + # type=float|default=0: use specified background value for points outside FOV + wm_seg: + # type=file|default=: white matter segmentation volume needed by BBR cost function + wmcoords: + # type=file|default=: white matter boundary coordinates for BBR cost function + wmnorms: + # type=file|default=: white matter boundary normals for BBR cost function + fieldmap: + # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image + fieldmapmask: + # type=file|default=: mask for fieldmap image + pedir: + # type=int|default=0: phase encode direction of EPI - 1/2/3=x/y/z & -1/-2/-3=-x/-y/-z + echospacing: + # type=float|default=0.0: value of EPI echo spacing - units of seconds + bbrtype: + # type=enum|default='signed'|allowed['global_abs','local_abs','signed']: type of bbr cost function: signed [default], global_abs, local_abs + bbrslope: + # type=float|default=0.0: value of bbr slope + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file + reference: + # type=file|default=: reference file + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + bins: '640' + # type=int|default=0: number of histogram bins + cost_func: '"mutualinfo"' + # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.testing + name: example_data + alias: + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: flirt -in structural.nii -ref mni.nii -out structural_flirt.nii.gz -omat structural_flirt.mat -bins 640 -searchcost mutualinfo + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input file + reference: + # type=file|default=: reference file + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + bins: '640' + # type=int|default=0: number of histogram bins + cost_func: '"mutualinfo"' + # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/flirt_callables.py b/nipype-auto-conv/specs/flirt_callables.py new file mode 100644 index 0000000..1b4f6bd --- /dev/null +++ b/nipype-auto-conv/specs/flirt_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FLIRT.yaml""" diff --git a/nipype-auto-conv/specs/fnirt.yaml b/nipype-auto-conv/specs/fnirt.yaml new file mode 100644 index 0000000..67b04cc --- /dev/null +++ b/nipype-auto-conv/specs/fnirt.yaml @@ -0,0 +1,264 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.FNIRT' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL FNIRT wrapper for non-linear registration +# +# For complete details, see the `FNIRT Documentation. +# `_ +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import example_data +# >>> fnt = fsl.FNIRT(affine_file=example_data('trans.mat')) +# >>> res = fnt.run(ref_file=example_data('mni.nii', in_file=example_data('structural.nii')) #doctest: +SKIP +# +# T1 -> Mni153 +# +# >>> from nipype.interfaces import fsl +# >>> fnirt_mprage = fsl.FNIRT() +# >>> fnirt_mprage.inputs.in_fwhm = [8, 4, 2, 2] +# >>> fnirt_mprage.inputs.subsampling_scheme = [4, 2, 1, 1] +# +# Specify the resolution of the warps +# +# >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6) +# >>> res = fnirt_mprage.run(in_file='structural.nii', ref_file='mni.nii', warped_file='warped.nii', fieldcoeff_file='fieldcoeff.nii')#doctest: +SKIP +# +# We can check the command line and confirm that it's what we expect. +# +# >>> fnirt_mprage.cmdline #doctest: +SKIP +# 'fnirt --cout=fieldcoeff.nii --in=structural.nii --infwhm=8,4,2,2 --ref=mni.nii --subsamp=4,2,1,1 --warpres=6,6,6 --iout=warped.nii' +# +# +task_name: FNIRT +nipype_name: FNIRT +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + ref_file: generic/file + # type=file|default=: name of reference image + in_file: generic/file + # type=file|default=: name of input image + affine_file: generic/file + # type=file|default=: name of file containing affine transform + inwarp_file: generic/file + # type=file|default=: name of file containing initial non-linear warps + in_intensitymap_file: generic/file+list-of + # type=list|default=[]: name of file/files containing initial intensity mapping usually generated by previous fnirt run + refmask_file: generic/file + # type=file|default=: name of file with mask in reference space + inmask_file: generic/file + # type=file|default=: name of file with mask in input image space + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + fieldcoeff_file: generic/file + # type=file: file with field coefficients + # type=traitcompound|default=None: name of output file with field coefficients or true + warped_file: generic/file + # type=file: warped image + # type=file|default=: name of output image + field_file: generic/file + # type=file: file with warp field + # type=traitcompound|default=None: name of output file with field or true + jacobian_file: generic/file + # type=file: file containing Jacobian of the field + # type=traitcompound|default=None: name of file for writing out the Jacobian of the field (for diagnostic or VBM purposes) + modulatedref_file: generic/file + # type=file: file containing intensity modulated --ref + # type=traitcompound|default=None: name of file for writing out intensity modulated --ref (for diagnostic purposes) + log_file: generic/file + # type=file: Name of log-file + # type=file|default=: Name of log-file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + warped_file: warped_file + # type=file: warped image + # type=file|default=: name of output image + log_file: log_file + # type=file: Name of log-file + # type=file|default=: Name of log-file + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + ref_file: + # type=file|default=: name of reference image + in_file: + # type=file|default=: name of input image + affine_file: + # type=file|default=: name of file containing affine transform + inwarp_file: + # type=file|default=: name of file containing initial non-linear warps + in_intensitymap_file: + # type=list|default=[]: name of file/files containing initial intensity mapping usually generated by previous fnirt run + fieldcoeff_file: + # type=file: file with field coefficients + # type=traitcompound|default=None: name of output file with field coefficients or true + warped_file: + # type=file: warped image + # type=file|default=: name of output image + field_file: + # type=file: file with warp field + # type=traitcompound|default=None: name of output file with field or true + jacobian_file: + # type=file: file containing Jacobian of the field + # type=traitcompound|default=None: name of file for writing out the Jacobian of the field (for diagnostic or VBM purposes) + modulatedref_file: + # type=file: file containing intensity modulated --ref + # type=traitcompound|default=None: name of file for writing out intensity modulated --ref (for diagnostic purposes) + out_intensitymap_file: + # type=list: files containing info pertaining to intensity mapping + # type=traitcompound|default=None: name of files for writing information pertaining to intensity mapping + log_file: + # type=file: Name of log-file + # type=file|default=: Name of log-file + config_file: + # type=traitcompound|default=None: Name of config file specifying command line arguments + refmask_file: + # type=file|default=: name of file with mask in reference space + inmask_file: + # type=file|default=: name of file with mask in input image space + skip_refmask: + # type=bool|default=False: Skip specified refmask if set, default false + skip_inmask: + # type=bool|default=False: skip specified inmask if set, default false + apply_refmask: + # type=list|default=[]: list of iterations to use reference mask on (1 to use, 0 to skip) + apply_inmask: + # type=list|default=[]: list of iterations to use input mask on (1 to use, 0 to skip) + skip_implicit_ref_masking: + # type=bool|default=False: skip implicit masking based on value in --ref image. Default = 0 + skip_implicit_in_masking: + # type=bool|default=False: skip implicit masking based on value in --in image. Default = 0 + refmask_val: + # type=float|default=0.0: Value to mask out in --ref image. Default =0.0 + inmask_val: + # type=float|default=0.0: Value to mask out in --in image. Default =0.0 + max_nonlin_iter: + # type=list|default=[]: Max # of non-linear iterations list, default [5, 5, 5, 5] + subsampling_scheme: + # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] + warp_resolution: + # type=tuple|default=(0, 0, 0): (approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10 + spline_order: + # type=int|default=0: Order of spline, 2->Qadratic spline, 3->Cubic spline. Default=3 + in_fwhm: + # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] + ref_fwhm: + # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for ref volume, default [4, 2, 0, 0] + regularization_model: + # type=enum|default='membrane_energy'|allowed['bending_energy','membrane_energy']: Model for regularisation of warp-field [membrane_energy bending_energy], default bending_energy + regularization_lambda: + # type=list|default=[]: Weight of regularisation, default depending on --ssqlambda and --regmod switches. See user documentation. + skip_lambda_ssq: + # type=bool|default=False: If true, lambda is not weighted by current ssq, default false + jacobian_range: + # type=tuple|default=(0.0, 0.0): Allowed range of Jacobian determinants, default 0.01, 100.0 + derive_from_ref: + # type=bool|default=False: If true, ref image is used to calculate derivatives. Default false + intensity_mapping_model: + # type=enum|default='none'|allowed['global_linear','global_non_linear','global_non_linear_with_bias','local_linear','local_non_linear','none']: Model for intensity-mapping + intensity_mapping_order: + # type=int|default=0: Order of poynomial for mapping intensities, default 5 + biasfield_resolution: + # type=tuple|default=(0, 0, 0): Resolution (in mm) of bias-field modelling local intensities, default 50, 50, 50 + bias_regularization_lambda: + # type=float|default=0.0: Weight of regularisation for bias-field, default 10000 + skip_intensity_mapping: + # type=bool|default=False: Skip estimate intensity-mapping default false + apply_intensity_mapping: + # type=list|default=[]: List of subsampling levels to apply intensity mapping for (0 to skip, 1 to apply) + hessian_precision: + # type=enum|default='double'|allowed['double','float']: Precision for representing Hessian, double or float. Default double + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_fwhm: '[8, 4, 2, 2]' + # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] + subsampling_scheme: '[4, 2, 1, 1] Specify the resolution of the warps >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6)' + # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.testing + name: example_data + alias: + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_fwhm: '[8, 4, 2, 2]' + # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] + subsampling_scheme: '[4, 2, 1, 1] Specify the resolution of the warps >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6)' + # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fnirt_callables.py b/nipype-auto-conv/specs/fnirt_callables.py new file mode 100644 index 0000000..6739d9d --- /dev/null +++ b/nipype-auto-conv/specs/fnirt_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FNIRT.yaml""" diff --git a/nipype-auto-conv/specs/fslx_command.yaml b/nipype-auto-conv/specs/fslx_command.yaml new file mode 100644 index 0000000..9670198 --- /dev/null +++ b/nipype-auto-conv/specs/fslx_command.yaml @@ -0,0 +1,130 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.FSLXCommand' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Base support for ``xfibres`` and ``bedpostx`` +# +task_name: FSLXCommand +nipype_name: FSLXCommand +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + dwi: generic/file + # type=file|default=: diffusion weighted image data file + mask: generic/file + # type=file|default=: brain binary mask file (i.e. from BET) + bvecs: generic/file + # type=file|default=: b vectors file + bvals: generic/file + # type=file|default=: b values file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mean_dsamples: generic/file + # type=file: Mean of distribution on diffusivity d + mean_S0samples: generic/file + # type=file: Mean of distribution on T2wbaseline signal intensity S0 + mean_tausamples: generic/file + # type=file: Mean of distribution on tau samples (only with rician noise) + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: brain binary mask file (i.e. from BET) + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + logdir: + # type=directory|default='.': + n_fibres: + # type=range|default=2: Maximum number of fibres to fit in each voxel + model: + # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model + fudge: + # type=int|default=0: ARD fudge factor + n_jumps: + # type=int|default=5000: Num of jumps to be made by MCMC + burn_in: + # type=range|default=0: Total num of jumps at start of MCMC to be discarded + burn_in_no_ard: + # type=range|default=0: num of burnin jumps before the ard is imposed + sample_every: + # type=range|default=1: Num of jumps for each sample (MCMC) + update_proposal_every: + # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) + seed: + # type=int|default=0: seed for pseudo random number generator + no_ard: + # type=bool|default=False: Turn ARD off on all fibres + all_ard: + # type=bool|default=False: Turn ARD on on all fibres + no_spat: + # type=bool|default=False: Initialise with tensor, not spatially + non_linear: + # type=bool|default=False: Initialise with nonlinear fitting + cnlinear: + # type=bool|default=False: Initialise with constrained nonlinear fitting + rician: + # type=bool|default=False: use Rician noise modeling + f0_noard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + f0_ard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + force_dir: + # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/fslx_command_callables.py b/nipype-auto-conv/specs/fslx_command_callables.py new file mode 100644 index 0000000..048758a --- /dev/null +++ b/nipype-auto-conv/specs/fslx_command_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FSLXCommand.yaml""" diff --git a/nipype-auto-conv/specs/fugue.yaml b/nipype-auto-conv/specs/fugue.yaml new file mode 100644 index 0000000..bb13f87 --- /dev/null +++ b/nipype-auto-conv/specs/fugue.yaml @@ -0,0 +1,387 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.FUGUE' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL FUGUE set of tools for EPI distortion correction +# +# `FUGUE `_ is, most generally, +# a set of tools for EPI distortion correction. +# +# Distortions may be corrected for +# 1. improving registration with non-distorted images (e.g. structurals), +# or +# 2. dealing with motion-dependent changes. +# +# FUGUE is designed to deal only with the first case - +# improving registration. +# +# +# Examples +# -------- +# +# +# Unwarping an input image (shift map is known): +# +# >>> from nipype.interfaces.fsl.preprocess import FUGUE +# >>> fugue = FUGUE() +# >>> fugue.inputs.in_file = 'epi.nii' +# >>> fugue.inputs.mask_file = 'epi_mask.nii' +# >>> fugue.inputs.shift_in_file = 'vsm.nii' # Previously computed with fugue as well +# >>> fugue.inputs.unwarp_direction = 'y' +# >>> fugue.inputs.output_type = "NIFTI_GZ" +# >>> fugue.cmdline # doctest: +ELLIPSIS +# 'fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --unwarp=epi_unwarped.nii.gz' +# >>> fugue.run() #doctest: +SKIP +# +# +# Warping an input image (shift map is known): +# +# >>> from nipype.interfaces.fsl.preprocess import FUGUE +# >>> fugue = FUGUE() +# >>> fugue.inputs.in_file = 'epi.nii' +# >>> fugue.inputs.forward_warping = True +# >>> fugue.inputs.mask_file = 'epi_mask.nii' +# >>> fugue.inputs.shift_in_file = 'vsm.nii' # Previously computed with fugue as well +# >>> fugue.inputs.unwarp_direction = 'y' +# >>> fugue.inputs.output_type = "NIFTI_GZ" +# >>> fugue.cmdline # doctest: +ELLIPSIS +# 'fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --warp=epi_warped.nii.gz' +# >>> fugue.run() #doctest: +SKIP +# +# +# Computing the vsm (unwrapped phase map is known): +# +# >>> from nipype.interfaces.fsl.preprocess import FUGUE +# >>> fugue = FUGUE() +# >>> fugue.inputs.phasemap_in_file = 'epi_phasediff.nii' +# >>> fugue.inputs.mask_file = 'epi_mask.nii' +# >>> fugue.inputs.dwell_to_asym_ratio = (0.77e-3 * 3) / 2.46e-3 +# >>> fugue.inputs.unwarp_direction = 'y' +# >>> fugue.inputs.save_shift = True +# >>> fugue.inputs.output_type = "NIFTI_GZ" +# >>> fugue.cmdline # doctest: +ELLIPSIS +# 'fugue --dwelltoasym=0.9390243902 --mask=epi_mask.nii --phasemap=epi_phasediff.nii --saveshift=epi_phasediff_vsm.nii.gz --unwarpdir=y' +# >>> fugue.run() #doctest: +SKIP +# +# +# +task_name: FUGUE +nipype_name: FUGUE +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: filename of input volume + shift_in_file: medimage/nifti1 + # type=file|default=: filename for reading pixel shift volume + phasemap_in_file: medimage/nifti1 + # type=file|default=: filename for input phase image + fmap_in_file: generic/file + # type=file|default=: filename for loading fieldmap (rad/s) + unwarped_file: generic/file + # type=file: unwarped file + # type=file|default=: apply unwarping and save as filename + warped_file: generic/file + # type=file: forward warped file + # type=file|default=: apply forward warping and save as filename + mask_file: medimage/nifti1 + # type=file|default=: filename for loading valid mask + shift_out_file: generic/file + # type=file: voxel shift map file + # type=file|default=: filename for saving pixel shift volume + fmap_out_file: generic/file + # type=file: fieldmap file + # type=file|default=: filename for saving fieldmap (rad/s) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + unwarped_file: generic/file + # type=file: unwarped file + # type=file|default=: apply unwarping and save as filename + warped_file: generic/file + # type=file: forward warped file + # type=file|default=: apply forward warping and save as filename + shift_out_file: generic/file + # type=file: voxel shift map file + # type=file|default=: filename for saving pixel shift volume + fmap_out_file: generic/file + # type=file: fieldmap file + # type=file|default=: filename for saving fieldmap (rad/s) + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input volume + shift_in_file: + # type=file|default=: filename for reading pixel shift volume + phasemap_in_file: + # type=file|default=: filename for input phase image + fmap_in_file: + # type=file|default=: filename for loading fieldmap (rad/s) + unwarped_file: + # type=file: unwarped file + # type=file|default=: apply unwarping and save as filename + warped_file: + # type=file: forward warped file + # type=file|default=: apply forward warping and save as filename + forward_warping: + # type=bool|default=False: apply forward warping instead of unwarping + dwell_to_asym_ratio: + # type=float|default=0.0: set the dwell to asym time ratio + dwell_time: + # type=float|default=0.0: set the EPI dwell time per phase-encode line - same as echo spacing - (sec) + asym_se_time: + # type=float|default=0.0: set the fieldmap asymmetric spin echo time (sec) + median_2dfilter: + # type=bool|default=False: apply 2D median filtering + despike_2dfilter: + # type=bool|default=False: apply a 2D de-spiking filter + no_gap_fill: + # type=bool|default=False: do not apply gap-filling measure to the fieldmap + no_extend: + # type=bool|default=False: do not apply rigid-body extrapolation to the fieldmap + smooth2d: + # type=float|default=0.0: apply 2D Gaussian smoothing of sigma N (in mm) + smooth3d: + # type=float|default=0.0: apply 3D Gaussian smoothing of sigma N (in mm) + poly_order: + # type=int|default=0: apply polynomial fitting of order N + fourier_order: + # type=int|default=0: apply Fourier (sinusoidal) fitting of order N + pava: + # type=bool|default=False: apply monotonic enforcement via PAVA + despike_threshold: + # type=float|default=0.0: specify the threshold for de-spiking (default=3.0) + unwarp_direction: + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + phase_conjugate: + # type=bool|default=False: apply phase conjugate method of unwarping + icorr: + # type=bool|default=False: apply intensity correction to unwarping (pixel shift method only) + icorr_only: + # type=bool|default=False: apply intensity correction only + mask_file: + # type=file|default=: filename for loading valid mask + nokspace: + # type=bool|default=False: do not use k-space forward warping + save_shift: + # type=bool|default=False: write pixel shift volume + shift_out_file: + # type=file: voxel shift map file + # type=file|default=: filename for saving pixel shift volume + save_unmasked_shift: + # type=bool|default=False: saves the unmasked shiftmap when using --saveshift + save_fmap: + # type=bool|default=False: write field map volume + fmap_out_file: + # type=file: fieldmap file + # type=file|default=: filename for saving fieldmap (rad/s) + save_unmasked_fmap: + # type=bool|default=False: saves the unmasked fieldmap when using --savefmap + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input volume + mask_file: + # type=file|default=: filename for loading valid mask + shift_in_file: + # type=file|default=: filename for reading pixel shift volume + unwarp_direction: '"y"' + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input volume + forward_warping: 'True' + # type=bool|default=False: apply forward warping instead of unwarping + mask_file: + # type=file|default=: filename for loading valid mask + shift_in_file: + # type=file|default=: filename for reading pixel shift volume + unwarp_direction: '"y"' + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + phasemap_in_file: + # type=file|default=: filename for input phase image + mask_file: + # type=file|default=: filename for loading valid mask + dwell_to_asym_ratio: (0.77e-3 * 3) / 2.46e-3 + # type=float|default=0.0: set the dwell to asym time ratio + unwarp_direction: '"y"' + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + save_shift: 'True' + # type=bool|default=False: write pixel shift volume + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --unwarp=epi_unwarped.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: filename of input volume + mask_file: + # type=file|default=: filename for loading valid mask + shift_in_file: + # type=file|default=: filename for reading pixel shift volume + unwarp_direction: '"y"' + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS +- cmdline: fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --warp=epi_warped.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: filename of input volume + forward_warping: 'True' + # type=bool|default=False: apply forward warping instead of unwarping + mask_file: + # type=file|default=: filename for loading valid mask + shift_in_file: + # type=file|default=: filename for reading pixel shift volume + unwarp_direction: '"y"' + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS +- cmdline: fugue --dwelltoasym=0.9390243902 --mask=epi_mask.nii --phasemap=epi_phasediff.nii --saveshift=epi_phasediff_vsm.nii.gz --unwarpdir=y + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + phasemap_in_file: + # type=file|default=: filename for input phase image + mask_file: + # type=file|default=: filename for loading valid mask + dwell_to_asym_ratio: (0.77e-3 * 3) / 2.46e-3 + # type=float|default=0.0: set the dwell to asym time ratio + unwarp_direction: '"y"' + # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) + save_shift: 'True' + # type=bool|default=False: write pixel shift volume + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fugue_callables.py b/nipype-auto-conv/specs/fugue_callables.py new file mode 100644 index 0000000..3d58eb5 --- /dev/null +++ b/nipype-auto-conv/specs/fugue_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in FUGUE.yaml""" diff --git a/nipype-auto-conv/specs/glm.yaml b/nipype-auto-conv/specs/glm.yaml new file mode 100644 index 0000000..480043f --- /dev/null +++ b/nipype-auto-conv/specs/glm.yaml @@ -0,0 +1,201 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.GLM' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# FSL GLM: +# +# Example +# ------- +# >>> import nipype.interfaces.fsl as fsl +# >>> glm = fsl.GLM(in_file='functional.nii', design='maps.nii', output_type='NIFTI') +# >>> glm.cmdline +# 'fsl_glm -i functional.nii -d maps.nii -o functional_glm.nii' +# +# +task_name: GLM +nipype_name: GLM +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: input file name (text matrix or 3D/4D image file) + out_file: generic/file + # type=file: file name of GLM parameters (if generated) + # type=file|default=: filename for GLM parameter estimates (GLM betas) + design: medimage/nifti1 + # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) + contrasts: generic/file + # type=file|default=: matrix of t-statics contrasts + mask: generic/file + # type=file|default=: mask image file name if input is image + out_cope: generic/file + # type=outputmultiobject: output file name for COPEs (either as text file or image) + # type=file|default=: output file name for COPE (either as txt or image + out_z_name: generic/file + # type=file|default=: output file name for Z-stats (either as txt or image + out_t_name: generic/file + # type=file|default=: output file name for t-stats (either as txt or image + out_p_name: generic/file + # type=file|default=: output file name for p-values of Z-stats (either as text file or image) + out_f_name: generic/file + # type=file|default=: output file name for F-value of full model fit + out_pf_name: generic/file + # type=file|default=: output file name for p-value for full model fit + out_res_name: generic/file + # type=file|default=: output file name for residuals + out_varcb_name: generic/file + # type=file|default=: output file name for variance of COPEs + out_sigsq_name: generic/file + # type=file|default=: output file name for residual noise variance sigma-square + out_data_name: generic/file + # type=file|default=: output file name for pre-processed data + out_vnscales_name: generic/file + # type=file|default=: output file name for scaling factors for variance normalisation + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: file name of GLM parameters (if generated) + # type=file|default=: filename for GLM parameter estimates (GLM betas) + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file name (text matrix or 3D/4D image file) + out_file: + # type=file: file name of GLM parameters (if generated) + # type=file|default=: filename for GLM parameter estimates (GLM betas) + design: + # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) + contrasts: + # type=file|default=: matrix of t-statics contrasts + mask: + # type=file|default=: mask image file name if input is image + dof: + # type=int|default=0: set degrees of freedom explicitly + des_norm: + # type=bool|default=False: switch on normalization of the design matrix columns to unit std deviation + dat_norm: + # type=bool|default=False: switch on normalization of the data time series to unit std deviation + var_norm: + # type=bool|default=False: perform MELODIC variance-normalisation on data + demean: + # type=bool|default=False: switch on demeaining of design and data + out_cope: + # type=outputmultiobject: output file name for COPEs (either as text file or image) + # type=file|default=: output file name for COPE (either as txt or image + out_z_name: + # type=file|default=: output file name for Z-stats (either as txt or image + out_t_name: + # type=file|default=: output file name for t-stats (either as txt or image + out_p_name: + # type=file|default=: output file name for p-values of Z-stats (either as text file or image) + out_f_name: + # type=file|default=: output file name for F-value of full model fit + out_pf_name: + # type=file|default=: output file name for p-value for full model fit + out_res_name: + # type=file|default=: output file name for residuals + out_varcb_name: + # type=file|default=: output file name for variance of COPEs + out_sigsq_name: + # type=file|default=: output file name for residual noise variance sigma-square + out_data_name: + # type=file|default=: output file name for pre-processed data + out_vnscales_name: + # type=file|default=: output file name for scaling factors for variance normalisation + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file name (text matrix or 3D/4D image file) + design: + # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) + output_type: '"NIFTI"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.interfaces.fsl as fsl + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fsl_glm -i functional.nii -d maps.nii -o functional_glm.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input file name (text matrix or 3D/4D image file) + design: + # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) + output_type: '"NIFTI"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/glm_callables.py b/nipype-auto-conv/specs/glm_callables.py new file mode 100644 index 0000000..e54bc44 --- /dev/null +++ b/nipype-auto-conv/specs/glm_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in GLM.yaml""" diff --git a/nipype-auto-conv/specs/ica__aroma.yaml b/nipype-auto-conv/specs/ica__aroma.yaml new file mode 100644 index 0000000..a88cfbe --- /dev/null +++ b/nipype-auto-conv/specs/ica__aroma.yaml @@ -0,0 +1,191 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.aroma.ICA_AROMA' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Interface for the ICA_AROMA.py script. +# +# ICA-AROMA (i.e. 'ICA-based Automatic Removal Of Motion Artifacts') concerns +# a data-driven method to identify and remove motion-related independent +# components from fMRI data. To that end it exploits a small, but robust +# set of theoretically motivated features, preventing the need for classifier +# re-training and therefore providing direct and easy applicability. +# +# See link for further documentation: https://github.com/rhr-pruim/ICA-AROMA +# +# Example +# ------- +# +# >>> from nipype.interfaces.fsl import ICA_AROMA +# >>> from nipype.testing import example_data +# >>> AROMA_obj = ICA_AROMA() +# >>> AROMA_obj.inputs.in_file = 'functional.nii' +# >>> AROMA_obj.inputs.mat_file = 'func_to_struct.mat' +# >>> AROMA_obj.inputs.fnirt_warp_file = 'warpfield.nii' +# >>> AROMA_obj.inputs.motion_parameters = 'fsl_mcflirt_movpar.txt' +# >>> AROMA_obj.inputs.mask = 'mask.nii.gz' +# >>> AROMA_obj.inputs.denoise_type = 'both' +# >>> AROMA_obj.inputs.out_dir = 'ICA_testout' +# >>> AROMA_obj.cmdline # doctest: +ELLIPSIS +# 'ICA_AROMA.py -den both -warp warpfield.nii -i functional.nii -m mask.nii.gz -affmat func_to_struct.mat -mc fsl_mcflirt_movpar.txt -o .../ICA_testout' +# +task_name: ICA_AROMA +nipype_name: ICA_AROMA +nipype_module: nipype.interfaces.fsl.aroma +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: volume to be denoised + mask: medimage/nifti-gz + # type=file|default=: path/name volume mask + mat_file: datascience/text-matrix + # type=file|default=: path/name of the mat-file describing the affine registration (e.g. FSL FLIRT) of the functional data to structural space (.mat file) + fnirt_warp_file: medimage/nifti1 + # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) + motion_parameters: text/text-file + # type=file|default=: motion parameters file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + aggr_denoised_file: generic/file + # type=file: if generated: aggressively denoised volume + nonaggr_denoised_file: generic/file + # type=file: if generated: non aggressively denoised volume + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + feat_dir: + # type=directory|default=: If a feat directory exists and temporal filtering has not been run yet, ICA_AROMA can use the files in this directory. + in_file: + # type=file|default=: volume to be denoised + out_dir: + # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) + # type=directory|default='out': output directory + mask: + # type=file|default=: path/name volume mask + dim: + # type=int|default=0: Dimensionality reduction when running MELODIC (default is automatic estimation) + TR: + # type=float|default=0.0: TR in seconds. If this is not specified the TR will be extracted from the header of the fMRI nifti file. + melodic_dir: + # type=directory|default=: path to MELODIC directory if MELODIC has already been run + mat_file: + # type=file|default=: path/name of the mat-file describing the affine registration (e.g. FSL FLIRT) of the functional data to structural space (.mat file) + fnirt_warp_file: + # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) + motion_parameters: + # type=file|default=: motion parameters file + denoise_type: + # type=enum|default='nonaggr'|allowed['aggr','both','no','nonaggr']: Type of denoising strategy: -no: only classification, no denoising -nonaggr (default): non-aggresssive denoising, i.e. partial component regression -aggr: aggressive denoising, i.e. full component regression -both: both aggressive and non-aggressive denoising (two outputs) + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: volume to be denoised + mat_file: + # type=file|default=: path/name of the mat-file describing the affine registration (e.g. FSL FLIRT) of the functional data to structural space (.mat file) + fnirt_warp_file: + # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) + motion_parameters: + # type=file|default=: motion parameters file + mask: + # type=file|default=: path/name volume mask + denoise_type: '"both"' + # type=enum|default='nonaggr'|allowed['aggr','both','no','nonaggr']: Type of denoising strategy: -no: only classification, no denoising -nonaggr (default): non-aggresssive denoising, i.e. partial component regression -aggr: aggressive denoising, i.e. full component regression -both: both aggressive and non-aggressive denoising (two outputs) + out_dir: '"ICA_testout"' + # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) + # type=directory|default='out': output directory + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.testing + name: example_data + alias: + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: ICA_AROMA.py -den both -warp warpfield.nii -i functional.nii -m mask.nii.gz -affmat func_to_struct.mat -mc fsl_mcflirt_movpar.txt -o .../ICA_testout + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: volume to be denoised + mat_file: + # type=file|default=: path/name of the mat-file describing the affine registration (e.g. FSL FLIRT) of the functional data to structural space (.mat file) + fnirt_warp_file: + # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) + motion_parameters: + # type=file|default=: motion parameters file + mask: + # type=file|default=: path/name volume mask + denoise_type: '"both"' + # type=enum|default='nonaggr'|allowed['aggr','both','no','nonaggr']: Type of denoising strategy: -no: only classification, no denoising -nonaggr (default): non-aggresssive denoising, i.e. partial component regression -aggr: aggressive denoising, i.e. full component regression -both: both aggressive and non-aggressive denoising (two outputs) + out_dir: '"ICA_testout"' + # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) + # type=directory|default='out': output directory + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/ica__aroma_callables.py b/nipype-auto-conv/specs/ica__aroma_callables.py new file mode 100644 index 0000000..ebc5c58 --- /dev/null +++ b/nipype-auto-conv/specs/ica__aroma_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ICA_AROMA.yaml""" diff --git a/nipype-auto-conv/specs/image_maths.yaml b/nipype-auto-conv/specs/image_maths.yaml new file mode 100644 index 0000000..ac462f2 --- /dev/null +++ b/nipype-auto-conv/specs/image_maths.yaml @@ -0,0 +1,156 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.ImageMaths' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL fslmaths command to allow mathematical manipulation of images +# `FSL info `_ +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import anatfile +# >>> maths = fsl.ImageMaths(in_file=anatfile, op_string= '-add 5', +# ... out_file='foo_maths.nii') +# >>> maths.cmdline == 'fslmaths %s -add 5 foo_maths.nii' % anatfile +# True +# +# +# +task_name: ImageMaths +nipype_name: ImageMaths +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: + in_file2: generic/file + # type=file|default=: + mask_file: generic/file + # type=file|default=: use (following image>0) to mask current image + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: medimage/nifti1 + # type=file: + # type=file|default=: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"foo_maths.nii"' + # type=file: + # type=file|default=: + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: + in_file2: + # type=file|default=: + mask_file: + # type=file|default=: use (following image>0) to mask current image + out_file: + # type=file: + # type=file|default=: + op_string: + # type=str|default='': string defining the operation, i. e. -add + suffix: + # type=str|default='': out_file suffix + out_data_type: + # type=enum|default='char'|allowed['char','double','float','input','int','short']: output datatype, one of (char, short, int, float, double, input) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: + op_string: '"-add 5"' + # type=str|default='': string defining the operation, i. e. -add + out_file: '"foo_maths.nii"' + # type=file: + # type=file|default=: + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.testing + name: anatfile + alias: + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: + op_string: '"-add 5"' + # type=str|default='': string defining the operation, i. e. -add + out_file: '"foo_maths.nii"' + # type=file: + # type=file|default=: + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/image_maths_callables.py b/nipype-auto-conv/specs/image_maths_callables.py new file mode 100644 index 0000000..af88ca1 --- /dev/null +++ b/nipype-auto-conv/specs/image_maths_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ImageMaths.yaml""" diff --git a/nipype-auto-conv/specs/image_meants.yaml b/nipype-auto-conv/specs/image_meants.yaml new file mode 100644 index 0000000..2ce06fd --- /dev/null +++ b/nipype-auto-conv/specs/image_meants.yaml @@ -0,0 +1,103 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.ImageMeants' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmeants for printing the average timeseries (intensities) to +# the screen (or saves to a file). The average is taken over all voxels +# in the mask (or all voxels in the image if no mask is specified) +# +# +task_name: ImageMeants +nipype_name: ImageMeants +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input file for computing the average timeseries + mask: generic/file + # type=file|default=: input 3D mask + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: path/name of output text matrix + # type=file|default=: name of output text matrix + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: path/name of output text matrix + # type=file|default=: name of output text matrix + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file for computing the average timeseries + out_file: + # type=file: path/name of output text matrix + # type=file|default=: name of output text matrix + mask: + # type=file|default=: input 3D mask + spatial_coord: + # type=list|default=[]: requested spatial coordinate (instead of mask) + use_mm: + # type=bool|default=False: use mm instead of voxel coordinates (for -c option) + show_all: + # type=bool|default=False: show all voxel time series (within mask) instead of averaging + eig: + # type=bool|default=False: calculate Eigenvariate(s) instead of mean (output will have 0 mean) + order: + # type=int|default=1: select number of Eigenvariates + nobin: + # type=bool|default=False: do not binarise the mask for calculation of Eigenvariates + transpose: + # type=bool|default=False: output results in transpose format (one row per voxel/mean) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/image_meants_callables.py b/nipype-auto-conv/specs/image_meants_callables.py new file mode 100644 index 0000000..0e60de8 --- /dev/null +++ b/nipype-auto-conv/specs/image_meants_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ImageMeants.yaml""" diff --git a/nipype-auto-conv/specs/image_stats.yaml b/nipype-auto-conv/specs/image_stats.yaml new file mode 100644 index 0000000..2ca5523 --- /dev/null +++ b/nipype-auto-conv/specs/image_stats.yaml @@ -0,0 +1,139 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.ImageStats' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL fslstats command to calculate stats from images +# `FSL info +# `_ +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import ImageStats +# >>> from nipype.testing import funcfile +# >>> stats = ImageStats(in_file=funcfile, op_string= '-M') +# >>> stats.cmdline == 'fslstats %s -M'%funcfile +# True +# +# +# +task_name: ImageStats +nipype_name: ImageStats +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input file to generate stats of + mask_file: generic/file + # type=file|default=: mask file used for option -k %s + index_mask_file: generic/file + # type=file|default=: generate separate n submasks from indexMask, for indexvalues 1..n where n is the maximum index value in indexMask, and generate statistics for each submask + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + split_4d: + # type=bool|default=False: give a separate output line for each 3D volume of a 4D timeseries + in_file: + # type=file|default=: input file to generate stats of + op_string: + # type=str|default='': string defining the operation, options are applied in order, e.g. -M -l 10 -M will report the non-zero mean, apply a threshold and then report the new nonzero mean + mask_file: + # type=file|default=: mask file used for option -k %s + index_mask_file: + # type=file|default=: generate separate n submasks from indexMask, for indexvalues 1..n where n is the maximum index value in indexMask, and generate statistics for each submask + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input file to generate stats of + op_string: '"-M"' + # type=str|default='': string defining the operation, options are applied in order, e.g. -M -l 10 -M will report the non-zero mean, apply a threshold and then report the new nonzero mean + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.testing + name: funcfile + alias: + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input file to generate stats of + op_string: '"-M"' + # type=str|default='': string defining the operation, options are applied in order, e.g. -M -l 10 -M will report the non-zero mean, apply a threshold and then report the new nonzero mean + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/image_stats_callables.py b/nipype-auto-conv/specs/image_stats_callables.py new file mode 100644 index 0000000..1a14596 --- /dev/null +++ b/nipype-auto-conv/specs/image_stats_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ImageStats.yaml""" diff --git a/nipype-auto-conv/specs/inv_warp.yaml b/nipype-auto-conv/specs/inv_warp.yaml new file mode 100644 index 0000000..6b4c1f5 --- /dev/null +++ b/nipype-auto-conv/specs/inv_warp.yaml @@ -0,0 +1,157 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.InvWarp' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL Invwarp to invert a FNIRT warp +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import InvWarp +# >>> invwarp = InvWarp() +# >>> invwarp.inputs.warp = "struct2mni.nii" +# >>> invwarp.inputs.reference = "anatomical.nii" +# >>> invwarp.inputs.output_type = "NIFTI_GZ" +# >>> invwarp.cmdline +# 'invwarp --out=struct2mni_inverse.nii.gz --ref=anatomical.nii --warp=struct2mni.nii' +# >>> res = invwarp.run() # doctest: +SKIP +# +# +# +task_name: InvWarp +nipype_name: InvWarp +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + warp: medimage/nifti1 + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: medimage/nifti1 + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + inverse_warp: generic/file + # type=file: Name of output file, containing warps that are the "reverse" of those in --warp. + # type=file|default=: Name of output file, containing warps that are the "reverse" of those in --warp. This will be a field-file (rather than a file of spline coefficients), and it will have any affine component included as part of the displacements. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + inverse_warp: generic/file + # type=file: Name of output file, containing warps that are the "reverse" of those in --warp. + # type=file|default=: Name of output file, containing warps that are the "reverse" of those in --warp. This will be a field-file (rather than a file of spline coefficients), and it will have any affine component included as part of the displacements. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + warp: + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + inverse_warp: + # type=file: Name of output file, containing warps that are the "reverse" of those in --warp. + # type=file|default=: Name of output file, containing warps that are the "reverse" of those in --warp. This will be a field-file (rather than a file of spline coefficients), and it will have any affine component included as part of the displacements. + absolute: + # type=bool|default=False: If set it indicates that the warps in --warp should be interpreted as absolute, provided that it is not created by fnirt (which always uses relative warps). If set it also indicates that the output --out should be absolute. + relative: + # type=bool|default=False: If set it indicates that the warps in --warp should be interpreted as relative. I.e. the values in --warp are displacements from the coordinates in the --ref space. If set it also indicates that the output --out should be relative. + niter: + # type=int|default=0: Determines how many iterations of the gradient-descent search that should be run. + regularise: + # type=float|default=0.0: Regularization strength (default=1.0). + noconstraint: + # type=bool|default=False: Do not apply Jacobian constraint + jacobian_min: + # type=float|default=0.0: Minimum acceptable Jacobian value for constraint (default 0.01) + jacobian_max: + # type=float|default=0.0: Maximum acceptable Jacobian value for constraint (default 100.0) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + warp: + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: invwarp --out=struct2mni_inverse.nii.gz --ref=anatomical.nii --warp=struct2mni.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + warp: + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/inv_warp_callables.py b/nipype-auto-conv/specs/inv_warp_callables.py new file mode 100644 index 0000000..3df23d8 --- /dev/null +++ b/nipype-auto-conv/specs/inv_warp_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in InvWarp.yaml""" diff --git a/nipype-auto-conv/specs/isotropic_smooth.yaml b/nipype-auto-conv/specs/isotropic_smooth.yaml new file mode 100644 index 0000000..0d358ea --- /dev/null +++ b/nipype-auto-conv/specs/isotropic_smooth.yaml @@ -0,0 +1,91 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.IsotropicSmooth' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to spatially smooth an image with a gaussian kernel. +task_name: IsotropicSmooth +nipype_name: IsotropicSmooth +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + fwhm: + # type=float|default=0.0: fwhm of smoothing kernel [mm] + sigma: + # type=float|default=0.0: sigma of smoothing kernel [mm] + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/isotropic_smooth_callables.py b/nipype-auto-conv/specs/isotropic_smooth_callables.py new file mode 100644 index 0000000..cb3b0b0 --- /dev/null +++ b/nipype-auto-conv/specs/isotropic_smooth_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in IsotropicSmooth.yaml""" diff --git a/nipype-auto-conv/specs/l2_model.yaml b/nipype-auto-conv/specs/l2_model.yaml new file mode 100644 index 0000000..17c0d9c --- /dev/null +++ b/nipype-auto-conv/specs/l2_model.yaml @@ -0,0 +1,78 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.L2Model' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Generate subject specific second level model +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import L2Model +# >>> model = L2Model(num_copes=3) # 3 sessions +# +# +task_name: L2Model +nipype_name: L2Model +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + design_mat: generic/file + # type=file: design matrix file + design_con: generic/file + # type=file: design contrast file + design_grp: generic/file + # type=file: design group file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + num_copes: + # type=range|default=1: number of copes to be combined + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/l2_model_callables.py b/nipype-auto-conv/specs/l2_model_callables.py new file mode 100644 index 0000000..05b7a8c --- /dev/null +++ b/nipype-auto-conv/specs/l2_model_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in L2Model.yaml""" diff --git a/nipype-auto-conv/specs/level_1_design.yaml b/nipype-auto-conv/specs/level_1_design.yaml new file mode 100644 index 0000000..227d174 --- /dev/null +++ b/nipype-auto-conv/specs/level_1_design.yaml @@ -0,0 +1,85 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.Level1Design' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Generate FEAT specific files +# +# Examples +# -------- +# +# >>> level1design = Level1Design() +# >>> level1design.inputs.interscan_interval = 2.5 +# >>> level1design.inputs.bases = {'dgamma':{'derivs': False}} +# >>> level1design.inputs.session_info = 'session_info.npz' +# >>> level1design.run() # doctest: +SKIP +# +# +task_name: Level1Design +nipype_name: Level1Design +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + interscan_interval: + # type=float|default=0.0: Interscan interval (in secs) + session_info: + # type=any|default=None: Session specific information generated by ``modelgen.SpecifyModel`` + bases: + # type=traitcompound|default=None: name of basis function and options e.g., {'dgamma': {'derivs': True}} + orthogonalization: + # type=dict|default={}: which regressors to make orthogonal e.g., {1: {0:0,1:0,2:0}, 2: {0:1,1:1,2:0}} to make the second regressor in a 2-regressor model orthogonal to the first. + model_serial_correlations: + # type=bool|default=False: Option to model serial correlations using an autoregressive estimator (order 1). Setting this option is only useful in the context of the fsf file. If you set this to False, you need to repeat this option for FILMGLS by setting autocorr_noestimate to True + contrasts: + # type=list|default=[]: List of contrasts with each contrast being a list of the form - [('name', 'stat', [condition list], [weight list], [session list])]. if session list is None or not provided, all sessions are used. For F contrasts, the condition list should contain previously defined T-contrasts. + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/level_1_design_callables.py b/nipype-auto-conv/specs/level_1_design_callables.py new file mode 100644 index 0000000..0558037 --- /dev/null +++ b/nipype-auto-conv/specs/level_1_design_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Level1Design.yaml""" diff --git a/nipype-auto-conv/specs/make_dyadic_vectors.yaml b/nipype-auto-conv/specs/make_dyadic_vectors.yaml new file mode 100644 index 0000000..55d445a --- /dev/null +++ b/nipype-auto-conv/specs/make_dyadic_vectors.yaml @@ -0,0 +1,91 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.MakeDyadicVectors' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Create vector volume representing mean principal diffusion direction +# and its uncertainty (dispersion) +task_name: MakeDyadicVectors +nipype_name: MakeDyadicVectors +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + theta_vol: generic/file + # type=file|default=: + phi_vol: generic/file + # type=file|default=: + mask: generic/file + # type=file|default=: + output: generic/file + # type=file|default='dyads': + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + dyads: generic/file + # type=file: + dispersion: generic/file + # type=file: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + theta_vol: + # type=file|default=: + phi_vol: + # type=file|default=: + mask: + # type=file|default=: + output: + # type=file|default='dyads': + perc: + # type=float|default=0.0: the {perc}% angle of the output cone of uncertainty (output will be in degrees) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/make_dyadic_vectors_callables.py b/nipype-auto-conv/specs/make_dyadic_vectors_callables.py new file mode 100644 index 0000000..3864dbd --- /dev/null +++ b/nipype-auto-conv/specs/make_dyadic_vectors_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MakeDyadicVectors.yaml""" diff --git a/nipype-auto-conv/specs/maths_command.yaml b/nipype-auto-conv/specs/maths_command.yaml new file mode 100644 index 0000000..1f5eae6 --- /dev/null +++ b/nipype-auto-conv/specs/maths_command.yaml @@ -0,0 +1,87 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MathsCommand' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +task_name: MathsCommand +nipype_name: MathsCommand +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/maths_command_callables.py b/nipype-auto-conv/specs/maths_command_callables.py new file mode 100644 index 0000000..84e0f13 --- /dev/null +++ b/nipype-auto-conv/specs/maths_command_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MathsCommand.yaml""" diff --git a/nipype-auto-conv/specs/max_image.yaml b/nipype-auto-conv/specs/max_image.yaml new file mode 100644 index 0000000..127dbca --- /dev/null +++ b/nipype-auto-conv/specs/max_image.yaml @@ -0,0 +1,133 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MaxImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate a max image across a given dimension. +# +# Examples +# -------- +# >>> from nipype.interfaces.fsl.maths import MaxImage +# >>> maxer = MaxImage() +# >>> maxer.inputs.in_file = "functional.nii" # doctest: +SKIP +# >>> maxer.dimension = "T" +# >>> maxer.cmdline # doctest: +SKIP +# 'fslmaths functional.nii -Tmax functional_max.nii' +# +# +task_name: MaxImage +nipype_name: MaxImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to max across + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to operate on + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fslmaths functional.nii -Tmax functional_max.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: image to operate on + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/max_image_callables.py b/nipype-auto-conv/specs/max_image_callables.py new file mode 100644 index 0000000..940bd9a --- /dev/null +++ b/nipype-auto-conv/specs/max_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MaxImage.yaml""" diff --git a/nipype-auto-conv/specs/maxn_image.yaml b/nipype-auto-conv/specs/maxn_image.yaml new file mode 100644 index 0000000..00a05a4 --- /dev/null +++ b/nipype-auto-conv/specs/maxn_image.yaml @@ -0,0 +1,92 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MaxnImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate an image of index of max across +# a given dimension. +# +# +task_name: MaxnImage +nipype_name: MaxnImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to index max across + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/maxn_image_callables.py b/nipype-auto-conv/specs/maxn_image_callables.py new file mode 100644 index 0000000..31eb42f --- /dev/null +++ b/nipype-auto-conv/specs/maxn_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MaxnImage.yaml""" diff --git a/nipype-auto-conv/specs/mcflirt.yaml b/nipype-auto-conv/specs/mcflirt.yaml new file mode 100644 index 0000000..81d3b1f --- /dev/null +++ b/nipype-auto-conv/specs/mcflirt.yaml @@ -0,0 +1,188 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.MCFLIRT' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL MCFLIRT wrapper for within-modality motion correction +# +# For complete details, see the `MCFLIRT Documentation. +# `_ +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> mcflt = fsl.MCFLIRT() +# >>> mcflt.inputs.in_file = 'functional.nii' +# >>> mcflt.inputs.cost = 'mutualinfo' +# >>> mcflt.inputs.out_file = 'moco.nii' +# >>> mcflt.cmdline +# 'mcflirt -in functional.nii -cost mutualinfo -out moco.nii' +# >>> res = mcflt.run() # doctest: +SKIP +# +# +task_name: MCFLIRT +nipype_name: MCFLIRT +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: timeseries to motion-correct + init: generic/file + # type=file|default=: initial transformation matrix + ref_file: generic/file + # type=file|default=: target image for motion correction + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: medimage/nifti1 + # type=file: motion-corrected timeseries + # type=file|default=: file to write + variance_img: generic/file + # type=file: variance image + std_img: generic/file + # type=file: standard deviation image + mean_img: generic/file + # type=file: mean timeseries image (if mean_vol=True) + par_file: generic/file + # type=file: text-file with motion parameters + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"moco.nii"' + # type=file: motion-corrected timeseries + # type=file|default=: file to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: timeseries to motion-correct + out_file: + # type=file: motion-corrected timeseries + # type=file|default=: file to write + cost: + # type=enum|default='mutualinfo'|allowed['corratio','leastsquares','mutualinfo','normcorr','normmi','woods']: cost function to optimize + bins: + # type=int|default=0: number of histogram bins + dof: + # type=int|default=0: degrees of freedom for the transformation + ref_vol: + # type=int|default=0: volume to align frames to + scaling: + # type=float|default=0.0: scaling factor to use + smooth: + # type=float|default=0.0: smoothing factor for the cost function + rotation: + # type=int|default=0: scaling factor for rotation tolerances + stages: + # type=int|default=0: stages (if 4, perform final search with sinc interpolation + init: + # type=file|default=: initial transformation matrix + interpolation: + # type=enum|default='spline'|allowed['nn','sinc','spline']: interpolation method for transformation + use_gradient: + # type=bool|default=False: run search on gradient images + use_contour: + # type=bool|default=False: run search on contour images + mean_vol: + # type=bool|default=False: register to mean volume + stats_imgs: + # type=bool|default=False: produce variance and std. dev. images + save_mats: + # type=bool|default=False: save transformation matrices + save_plots: + # type=bool|default=False: save transformation parameters + save_rms: + # type=bool|default=False: save rms displacement parameters + ref_file: + # type=file|default=: target image for motion correction + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: timeseries to motion-correct + cost: '"mutualinfo"' + # type=enum|default='mutualinfo'|allowed['corratio','leastsquares','mutualinfo','normcorr','normmi','woods']: cost function to optimize + out_file: '"moco.nii"' + # type=file: motion-corrected timeseries + # type=file|default=: file to write + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: mcflirt -in functional.nii -cost mutualinfo -out moco.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: timeseries to motion-correct + cost: '"mutualinfo"' + # type=enum|default='mutualinfo'|allowed['corratio','leastsquares','mutualinfo','normcorr','normmi','woods']: cost function to optimize + out_file: '"moco.nii"' + # type=file: motion-corrected timeseries + # type=file|default=: file to write + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/mcflirt_callables.py b/nipype-auto-conv/specs/mcflirt_callables.py new file mode 100644 index 0000000..7fb6bc8 --- /dev/null +++ b/nipype-auto-conv/specs/mcflirt_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MCFLIRT.yaml""" diff --git a/nipype-auto-conv/specs/mean_image.yaml b/nipype-auto-conv/specs/mean_image.yaml new file mode 100644 index 0000000..6f15b26 --- /dev/null +++ b/nipype-auto-conv/specs/mean_image.yaml @@ -0,0 +1,89 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MeanImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate a mean image across a given dimension. +task_name: MeanImage +nipype_name: MeanImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to mean across + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/mean_image_callables.py b/nipype-auto-conv/specs/mean_image_callables.py new file mode 100644 index 0000000..1d3333c --- /dev/null +++ b/nipype-auto-conv/specs/mean_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MeanImage.yaml""" diff --git a/nipype-auto-conv/specs/median_image.yaml b/nipype-auto-conv/specs/median_image.yaml new file mode 100644 index 0000000..ee4f848 --- /dev/null +++ b/nipype-auto-conv/specs/median_image.yaml @@ -0,0 +1,89 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MedianImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate a median image across a given dimension. +task_name: MedianImage +nipype_name: MedianImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to median across + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/median_image_callables.py b/nipype-auto-conv/specs/median_image_callables.py new file mode 100644 index 0000000..d4df040 --- /dev/null +++ b/nipype-auto-conv/specs/median_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MedianImage.yaml""" diff --git a/nipype-auto-conv/specs/melodic.yaml b/nipype-auto-conv/specs/melodic.yaml new file mode 100644 index 0000000..fb02987 --- /dev/null +++ b/nipype-auto-conv/specs/melodic.yaml @@ -0,0 +1,291 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.MELODIC' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Multivariate Exploratory Linear Optimised Decomposition into Independent +# Components +# +# Examples +# -------- +# +# >>> melodic_setup = MELODIC() +# >>> melodic_setup.inputs.approach = 'tica' +# >>> melodic_setup.inputs.in_files = ['functional.nii', 'functional2.nii', 'functional3.nii'] +# >>> melodic_setup.inputs.no_bet = True +# >>> melodic_setup.inputs.bg_threshold = 10 +# >>> melodic_setup.inputs.tr_sec = 1.5 +# >>> melodic_setup.inputs.mm_thresh = 0.5 +# >>> melodic_setup.inputs.out_stats = True +# >>> melodic_setup.inputs.t_des = 'timeDesign.mat' +# >>> melodic_setup.inputs.t_con = 'timeDesign.con' +# >>> melodic_setup.inputs.s_des = 'subjectDesign.mat' +# >>> melodic_setup.inputs.s_con = 'subjectDesign.con' +# >>> melodic_setup.inputs.out_dir = 'groupICA.out' +# >>> melodic_setup.cmdline +# 'melodic -i functional.nii,functional2.nii,functional3.nii -a tica --bgthreshold=10.000000 --mmthresh=0.500000 --nobet -o groupICA.out --Ostats --Scon=subjectDesign.con --Sdes=subjectDesign.mat --Tcon=timeDesign.con --Tdes=timeDesign.mat --tr=1.500000' +# >>> melodic_setup.run() # doctest: +SKIP +# +# +# +task_name: MELODIC +nipype_name: MELODIC +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: input file names (either single file name or a list) + mask: generic/file + # type=file|default=: file name of mask for thresholding + ICs: generic/file + # type=file|default=: filename of the IC components file for mixture modelling + mix: generic/file + # type=file|default=: mixing matrix for mixture modelling / filtering + smode: generic/file + # type=file|default=: matrix of session modes for report generation + bg_image: generic/file + # type=file|default=: specify background image for report (default: mean image) + t_des: datascience/text-matrix + # type=file|default=: design matrix across time-domain + t_con: medimage-fsl/con + # type=file|default=: t-contrast matrix across time-domain + s_des: datascience/text-matrix + # type=file|default=: design matrix across subject-domain + s_con: medimage-fsl/con + # type=file|default=: t-contrast matrix across subject-domain + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_dir: '"groupICA.out"' + # type=directory: + # type=directory|default=: output directory name + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=inputmultiobject|default=[]: input file names (either single file name or a list) + out_dir: + # type=directory: + # type=directory|default=: output directory name + mask: + # type=file|default=: file name of mask for thresholding + no_mask: + # type=bool|default=False: switch off masking + update_mask: + # type=bool|default=False: switch off mask updating + no_bet: + # type=bool|default=False: switch off BET + bg_threshold: + # type=float|default=0.0: brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected) + dim: + # type=int|default=0: dimensionality reduction into #num dimensions (default: automatic estimation) + dim_est: + # type=str|default='': use specific dim. estimation technique: lap, bic, mdl, aic, mean (default: lap) + sep_whiten: + # type=bool|default=False: switch on separate whitening + sep_vn: + # type=bool|default=False: switch off joined variance normalization + migp: + # type=bool|default=False: switch on MIGP data reduction + migpN: + # type=int|default=0: number of internal Eigenmaps + migp_shuffle: + # type=bool|default=False: randomise MIGP file order (default: TRUE) + migp_factor: + # type=int|default=0: Internal Factor of mem-threshold relative to number of Eigenmaps (default: 2) + num_ICs: + # type=int|default=0: number of IC's to extract (for deflation approach) + approach: + # type=str|default='': approach for decomposition, 2D: defl, symm (default), 3D: tica (default), concat + non_linearity: + # type=str|default='': nonlinearity: gauss, tanh, pow3, pow4 + var_norm: + # type=bool|default=False: switch off variance normalization + pbsc: + # type=bool|default=False: switch off conversion to percent BOLD signal change + cov_weight: + # type=float|default=0.0: voxel-wise weights for the covariance matrix (e.g. segmentation information) + epsilon: + # type=float|default=0.0: minimum error change + epsilonS: + # type=float|default=0.0: minimum error change for rank-1 approximation in TICA + maxit: + # type=int|default=0: maximum number of iterations before restart + max_restart: + # type=int|default=0: maximum number of restarts + mm_thresh: + # type=float|default=0.0: threshold for Mixture Model based inference + no_mm: + # type=bool|default=False: switch off mixture modelling on IC maps + ICs: + # type=file|default=: filename of the IC components file for mixture modelling + mix: + # type=file|default=: mixing matrix for mixture modelling / filtering + smode: + # type=file|default=: matrix of session modes for report generation + rem_cmp: + # type=list|default=[]: component numbers to remove + report: + # type=bool|default=False: generate Melodic web report + bg_image: + # type=file|default=: specify background image for report (default: mean image) + tr_sec: + # type=float|default=0.0: TR in seconds + log_power: + # type=bool|default=False: calculate log of power for frequency spectrum + t_des: + # type=file|default=: design matrix across time-domain + t_con: + # type=file|default=: t-contrast matrix across time-domain + s_des: + # type=file|default=: design matrix across subject-domain + s_con: + # type=file|default=: t-contrast matrix across subject-domain + out_all: + # type=bool|default=False: output everything + out_unmix: + # type=bool|default=False: output unmixing matrix + out_stats: + # type=bool|default=False: output thresholded maps and probability maps + out_pca: + # type=bool|default=False: output PCA results + out_white: + # type=bool|default=False: output whitening/dewhitening matrices + out_orig: + # type=bool|default=False: output the original ICs + out_mean: + # type=bool|default=False: output mean volume + report_maps: + # type=str|default='': control string for spatial map images (see slicer) + remove_deriv: + # type=bool|default=False: removes every second entry in paradigm file (EV derivatives) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + approach: '"tica"' + # type=str|default='': approach for decomposition, 2D: defl, symm (default), 3D: tica (default), concat + in_files: + # type=inputmultiobject|default=[]: input file names (either single file name or a list) + no_bet: 'True' + # type=bool|default=False: switch off BET + bg_threshold: '10' + # type=float|default=0.0: brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected) + tr_sec: '1.5' + # type=float|default=0.0: TR in seconds + mm_thresh: '0.5' + # type=float|default=0.0: threshold for Mixture Model based inference + out_stats: 'True' + # type=bool|default=False: output thresholded maps and probability maps + t_des: + # type=file|default=: design matrix across time-domain + t_con: + # type=file|default=: t-contrast matrix across time-domain + s_des: + # type=file|default=: design matrix across subject-domain + s_con: + # type=file|default=: t-contrast matrix across subject-domain + out_dir: '"groupICA.out"' + # type=directory: + # type=directory|default=: output directory name + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: melodic -i functional.nii,functional2.nii,functional3.nii -a tica --bgthreshold=10.000000 --mmthresh=0.500000 --nobet -o groupICA.out --Ostats --Scon=subjectDesign.con --Sdes=subjectDesign.mat --Tcon=timeDesign.con --Tdes=timeDesign.mat --tr=1.500000 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + approach: '"tica"' + # type=str|default='': approach for decomposition, 2D: defl, symm (default), 3D: tica (default), concat + in_files: + # type=inputmultiobject|default=[]: input file names (either single file name or a list) + no_bet: 'True' + # type=bool|default=False: switch off BET + bg_threshold: '10' + # type=float|default=0.0: brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected) + tr_sec: '1.5' + # type=float|default=0.0: TR in seconds + mm_thresh: '0.5' + # type=float|default=0.0: threshold for Mixture Model based inference + out_stats: 'True' + # type=bool|default=False: output thresholded maps and probability maps + t_des: + # type=file|default=: design matrix across time-domain + t_con: + # type=file|default=: t-contrast matrix across time-domain + s_des: + # type=file|default=: design matrix across subject-domain + s_con: + # type=file|default=: t-contrast matrix across subject-domain + out_dir: '"groupICA.out"' + # type=directory: + # type=directory|default=: output directory name + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/melodic_callables.py b/nipype-auto-conv/specs/melodic_callables.py new file mode 100644 index 0000000..b6075b9 --- /dev/null +++ b/nipype-auto-conv/specs/melodic_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MELODIC.yaml""" diff --git a/nipype-auto-conv/specs/merge.yaml b/nipype-auto-conv/specs/merge.yaml new file mode 100644 index 0000000..8f5e750 --- /dev/null +++ b/nipype-auto-conv/specs/merge.yaml @@ -0,0 +1,154 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Merge' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmerge to concatenate images +# +# Images can be concatenated across time, x, y, or z dimensions. Across the +# time (t) dimension the TR is set by default to 1 sec. +# +# Note: to set the TR to a different value, specify 't' for dimension and +# specify the TR value in seconds for the tr input. The dimension will be +# automatically updated to 'tr'. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import Merge +# >>> merger = Merge() +# >>> merger.inputs.in_files = ['functional2.nii', 'functional3.nii'] +# >>> merger.inputs.dimension = 't' +# >>> merger.inputs.output_type = 'NIFTI_GZ' +# >>> merger.cmdline +# 'fslmerge -t functional2_merged.nii.gz functional2.nii functional3.nii' +# >>> merger.inputs.tr = 2.25 +# >>> merger.cmdline +# 'fslmerge -tr functional2_merged.nii.gz functional2.nii functional3.nii 2.25' +# +# +# +task_name: Merge +nipype_name: Merge +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: medimage/nifti1+list-of + # type=list|default=[]: + merged_file: generic/file + # type=file: + # type=file|default=: + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + merged_file: generic/file + # type=file: + # type=file|default=: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=list|default=[]: + dimension: + # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t + tr: + # type=float|default=0.0: use to specify TR in seconds (default is 1.00 sec), overrides dimension and sets it to tr + merged_file: + # type=file: + # type=file|default=: + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=list|default=[]: + dimension: '"t"' + # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + tr: '2.25' + # type=float|default=0.0: use to specify TR in seconds (default is 1.00 sec), overrides dimension and sets it to tr + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fslmerge -tr functional2_merged.nii.gz functional2.nii functional3.nii 2.25 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_files: + # type=list|default=[]: + dimension: '"t"' + # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + tr: '2.25' + # type=float|default=0.0: use to specify TR in seconds (default is 1.00 sec), overrides dimension and sets it to tr + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/merge_callables.py b/nipype-auto-conv/specs/merge_callables.py new file mode 100644 index 0000000..1950a89 --- /dev/null +++ b/nipype-auto-conv/specs/merge_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Merge.yaml""" diff --git a/nipype-auto-conv/specs/min_image.yaml b/nipype-auto-conv/specs/min_image.yaml new file mode 100644 index 0000000..5f56747 --- /dev/null +++ b/nipype-auto-conv/specs/min_image.yaml @@ -0,0 +1,89 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MinImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate a minimum image across a given dimension. +task_name: MinImage +nipype_name: MinImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to min across + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/min_image_callables.py b/nipype-auto-conv/specs/min_image_callables.py new file mode 100644 index 0000000..be3a24b --- /dev/null +++ b/nipype-auto-conv/specs/min_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MinImage.yaml""" diff --git a/nipype-auto-conv/specs/motion_outliers.yaml b/nipype-auto-conv/specs/motion_outliers.yaml new file mode 100644 index 0000000..7bcceac --- /dev/null +++ b/nipype-auto-conv/specs/motion_outliers.yaml @@ -0,0 +1,154 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.MotionOutliers' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL fsl_motion_outliers`http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLMotionOutliers`_ to find outliers in timeseries (4d) data. +# Examples +# -------- +# >>> from nipype.interfaces.fsl import MotionOutliers +# >>> mo = MotionOutliers() +# >>> mo.inputs.in_file = "epi.nii" +# >>> mo.cmdline # doctest: +ELLIPSIS +# 'fsl_motion_outliers -i epi.nii -o epi_outliers.txt -p epi_metrics.png -s epi_metrics.txt' +# >>> res = mo.run() # doctest: +SKIP +# +task_name: MotionOutliers +nipype_name: MotionOutliers +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: unfiltered 4D image + out_file: generic/file + # type=file: + # type=file|default=: output outlier file name + mask: generic/file + # type=file|default=: mask image for calculating metric + out_metric_values: generic/file + # type=file: + # type=file|default=: output metric values (DVARS etc.) file name + out_metric_plot: generic/file + # type=file: + # type=file|default=: output metric values plot (DVARS etc.) file name + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: + # type=file|default=: output outlier file name + out_metric_values: generic/file + # type=file: + # type=file|default=: output metric values (DVARS etc.) file name + out_metric_plot: generic/file + # type=file: + # type=file|default=: output metric values plot (DVARS etc.) file name + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: unfiltered 4D image + out_file: + # type=file: + # type=file|default=: output outlier file name + mask: + # type=file|default=: mask image for calculating metric + metric: + # type=enum|default='refrms'|allowed['dvars','fd','fdrms','refmse','refrms']: metrics: refrms - RMS intensity difference to reference volume as metric [default metric], refmse - Mean Square Error version of refrms (used in original version of fsl_motion_outliers), dvars - DVARS, fd - frame displacement, fdrms - FD with RMS matrix calculation + threshold: + # type=float|default=0.0: specify absolute threshold value (otherwise use box-plot cutoff = P75 + 1.5*IQR) + no_motion_correction: + # type=bool|default=False: do not run motion correction (assumed already done) + dummy: + # type=int|default=0: number of dummy scans to delete (before running anything and creating EVs) + out_metric_values: + # type=file: + # type=file|default=: output metric values (DVARS etc.) file name + out_metric_plot: + # type=file: + # type=file|default=: output metric values plot (DVARS etc.) file name + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: unfiltered 4D image + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fsl_motion_outliers -i epi.nii -o epi_outliers.txt -p epi_metrics.png -s epi_metrics.txt + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: unfiltered 4D image + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/motion_outliers_callables.py b/nipype-auto-conv/specs/motion_outliers_callables.py new file mode 100644 index 0000000..811e819 --- /dev/null +++ b/nipype-auto-conv/specs/motion_outliers_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MotionOutliers.yaml""" diff --git a/nipype-auto-conv/specs/multi_image_maths.yaml b/nipype-auto-conv/specs/multi_image_maths.yaml new file mode 100644 index 0000000..1f4a890 --- /dev/null +++ b/nipype-auto-conv/specs/multi_image_maths.yaml @@ -0,0 +1,153 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.MultiImageMaths' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to perform a sequence of mathematical operations. +# +# Examples +# -------- +# >>> from nipype.interfaces.fsl import MultiImageMaths +# >>> maths = MultiImageMaths() +# >>> maths.inputs.in_file = "functional.nii" +# >>> maths.inputs.op_string = "-add %s -mul -1 -div %s" +# >>> maths.inputs.operand_files = ["functional2.nii", "functional3.nii"] +# >>> maths.inputs.out_file = "functional4.nii" +# >>> maths.cmdline +# 'fslmaths functional.nii -add functional2.nii -mul -1 -div functional3.nii functional4.nii' +# +# +task_name: MultiImageMaths +nipype_name: MultiImageMaths +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + operand_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: list of file names to plug into op string + in_file: medimage/nifti1 + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: medimage/nifti1 + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"functional4.nii"' + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + op_string: + # type=string|default='': python formatted string of operations to perform + operand_files: + # type=inputmultiobject|default=[]: list of file names to plug into op string + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to operate on + op_string: '"-add %s -mul -1 -div %s"' + # type=string|default='': python formatted string of operations to perform + operand_files: + # type=inputmultiobject|default=[]: list of file names to plug into op string + out_file: '"functional4.nii"' + # type=file: image written after calculations + # type=file|default=: image to write + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fslmaths functional.nii -add functional2.nii -mul -1 -div functional3.nii functional4.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: image to operate on + op_string: '"-add %s -mul -1 -div %s"' + # type=string|default='': python formatted string of operations to perform + operand_files: + # type=inputmultiobject|default=[]: list of file names to plug into op string + out_file: '"functional4.nii"' + # type=file: image written after calculations + # type=file|default=: image to write + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/multi_image_maths_callables.py b/nipype-auto-conv/specs/multi_image_maths_callables.py new file mode 100644 index 0000000..af619ea --- /dev/null +++ b/nipype-auto-conv/specs/multi_image_maths_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MultiImageMaths.yaml""" diff --git a/nipype-auto-conv/specs/multiple_regress_design.yaml b/nipype-auto-conv/specs/multiple_regress_design.yaml new file mode 100644 index 0000000..987f401 --- /dev/null +++ b/nipype-auto-conv/specs/multiple_regress_design.yaml @@ -0,0 +1,94 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.MultipleRegressDesign' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Generate multiple regression design +# +# .. note:: +# FSL does not demean columns for higher level analysis. +# +# Please see `FSL documentation +# `_ +# for more details on model specification for higher level analysis. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import MultipleRegressDesign +# >>> model = MultipleRegressDesign() +# >>> model.inputs.contrasts = [['group mean', 'T',['reg1'],[1]]] +# >>> model.inputs.regressors = dict(reg1=[1, 1, 1], reg2=[2.,-4, 3]) +# >>> model.run() # doctest: +SKIP +# +# +task_name: MultipleRegressDesign +nipype_name: MultipleRegressDesign +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + design_mat: generic/file + # type=file: design matrix file + design_con: generic/file + # type=file: design t-contrast file + design_fts: generic/file + # type=file: design f-contrast file + design_grp: generic/file + # type=file: design group file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + contrasts: + # type=list|default=[]: List of contrasts with each contrast being a list of the form - [('name', 'stat', [condition list], [weight list])]. if session list is None or not provided, all sessions are used. For F contrasts, the condition list should contain previously defined T-contrasts without any weight list. + regressors: + # type=dict|default={}: dictionary containing named lists of regressors + groups: + # type=list|default=[]: list of group identifiers (defaults to single group) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/multiple_regress_design_callables.py b/nipype-auto-conv/specs/multiple_regress_design_callables.py new file mode 100644 index 0000000..d429231 --- /dev/null +++ b/nipype-auto-conv/specs/multiple_regress_design_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in MultipleRegressDesign.yaml""" diff --git a/nipype-auto-conv/specs/overlay.yaml b/nipype-auto-conv/specs/overlay.yaml new file mode 100644 index 0000000..7a5ea42 --- /dev/null +++ b/nipype-auto-conv/specs/overlay.yaml @@ -0,0 +1,124 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Overlay' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL's overlay command to combine background and statistical images +# into one volume +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> combine = fsl.Overlay() +# >>> combine.inputs.background_image = 'mean_func.nii.gz' +# >>> combine.inputs.auto_thresh_bg = True +# >>> combine.inputs.stat_image = 'zstat1.nii.gz' +# >>> combine.inputs.stat_thresh = (3.5, 10) +# >>> combine.inputs.show_negative_stats = True +# >>> res = combine.run() #doctest: +SKIP +# +# +# +task_name: Overlay +nipype_name: Overlay +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + background_image: generic/file + # type=file|default=: image to use as background + stat_image: generic/file + # type=file|default=: statistical image to overlay in color + stat_image2: generic/file + # type=file|default=: second statistical image to overlay in color + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: combined image volume + # type=file|default=: combined image volume + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: combined image volume + # type=file|default=: combined image volume + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + transparency: + # type=bool|default=True: make overlay colors semi-transparent + out_type: + # type=enum|default='float'|allowed['float','int']: write output with float or int + use_checkerboard: + # type=bool|default=False: use checkerboard mask for overlay + background_image: + # type=file|default=: image to use as background + auto_thresh_bg: + # type=bool|default=False: automatically threshold the background image + full_bg_range: + # type=bool|default=False: use full range of background image + bg_thresh: + # type=tuple|default=(0.0, 0.0): min and max values for background intensity + stat_image: + # type=file|default=: statistical image to overlay in color + stat_thresh: + # type=tuple|default=(0.0, 0.0): min and max values for the statistical overlay + show_negative_stats: + # type=bool|default=False: display negative statistics in overlay + stat_image2: + # type=file|default=: second statistical image to overlay in color + stat_thresh2: + # type=tuple|default=(0.0, 0.0): min and max values for second statistical overlay + out_file: + # type=file: combined image volume + # type=file|default=: combined image volume + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/overlay_callables.py b/nipype-auto-conv/specs/overlay_callables.py new file mode 100644 index 0000000..dc82668 --- /dev/null +++ b/nipype-auto-conv/specs/overlay_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Overlay.yaml""" diff --git a/nipype-auto-conv/specs/percentile_image.yaml b/nipype-auto-conv/specs/percentile_image.yaml new file mode 100644 index 0000000..fa52a47 --- /dev/null +++ b/nipype-auto-conv/specs/percentile_image.yaml @@ -0,0 +1,136 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.PercentileImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate a percentile image across a given dimension. +# +# Examples +# -------- +# >>> from nipype.interfaces.fsl.maths import MaxImage +# >>> percer = PercentileImage() +# >>> percer.inputs.in_file = "functional.nii" # doctest: +SKIP +# >>> percer.dimension = "T" +# >>> percer.perc = 90 +# >>> percer.cmdline # doctest: +SKIP +# 'fslmaths functional.nii -Tperc 90 functional_perc.nii' +# +# +task_name: PercentileImage +nipype_name: PercentileImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to percentile across + perc: + # type=range|default=0: nth percentile (0-100) of FULL RANGE across dimension + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to operate on + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fslmaths functional.nii -Tperc 90 functional_perc.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: image to operate on + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/percentile_image_callables.py b/nipype-auto-conv/specs/percentile_image_callables.py new file mode 100644 index 0000000..3ab3b26 --- /dev/null +++ b/nipype-auto-conv/specs/percentile_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in PercentileImage.yaml""" diff --git a/nipype-auto-conv/specs/plot_motion_params.yaml b/nipype-auto-conv/specs/plot_motion_params.yaml new file mode 100644 index 0000000..2accc6c --- /dev/null +++ b/nipype-auto-conv/specs/plot_motion_params.yaml @@ -0,0 +1,110 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.PlotMotionParams' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fsl_tsplot to plot the estimated motion parameters from a +# realignment program. +# +# +# Examples +# -------- +# +# >>> import nipype.interfaces.fsl as fsl +# >>> plotter = fsl.PlotMotionParams() +# >>> plotter.inputs.in_file = 'functional.par' +# >>> plotter.inputs.in_source = 'fsl' +# >>> plotter.inputs.plot_type = 'rotations' +# >>> res = plotter.run() #doctest: +SKIP +# +# +# Notes +# ----- +# +# The 'in_source' attribute determines the order of columns that are expected +# in the source file. FSL prints motion parameters in the order rotations, +# translations, while SPM prints them in the opposite order. This interface +# should be able to plot timecourses of motion parameters generated from +# other sources as long as they fall under one of these two patterns. For +# more flexibility, see the :class:`fsl.PlotTimeSeries` interface. +# +# +task_name: PlotMotionParams +nipype_name: PlotMotionParams +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image to write + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image to write + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=traitcompound|default=None: file with motion parameters + in_source: + # type=enum|default='spm'|allowed['fsl','spm']: which program generated the motion parameter file - fsl, spm + plot_type: + # type=enum|default='rotations'|allowed['displacement','rotations','translations']: which motion type to plot - rotations, translations, displacement + plot_size: + # type=tuple|default=(0, 0): plot image height and width + out_file: + # type=file: image to write + # type=file|default=: image to write + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/plot_motion_params_callables.py b/nipype-auto-conv/specs/plot_motion_params_callables.py new file mode 100644 index 0000000..cb9a47a --- /dev/null +++ b/nipype-auto-conv/specs/plot_motion_params_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in PlotMotionParams.yaml""" diff --git a/nipype-auto-conv/specs/plot_time_series.yaml b/nipype-auto-conv/specs/plot_time_series.yaml new file mode 100644 index 0000000..20a0e1a --- /dev/null +++ b/nipype-auto-conv/specs/plot_time_series.yaml @@ -0,0 +1,120 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.PlotTimeSeries' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fsl_tsplot to create images of time course plots. +# +# Examples +# -------- +# +# >>> import nipype.interfaces.fsl as fsl +# >>> plotter = fsl.PlotTimeSeries() +# >>> plotter.inputs.in_file = 'functional.par' +# >>> plotter.inputs.title = 'Functional timeseries' +# >>> plotter.inputs.labels = ['run1', 'run2'] +# >>> plotter.run() #doctest: +SKIP +# +# +# +task_name: PlotTimeSeries +nipype_name: PlotTimeSeries +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + legend_file: generic/file + # type=file|default=: legend file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image to write + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image to write + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=traitcompound|default=None: file or list of files with columns of timecourse information + plot_start: + # type=int|default=0: first column from in-file to plot + plot_finish: + # type=int|default=0: final column from in-file to plot + plot_range: + # type=tuple|default=(0, 0): first and last columns from the in-file to plot + title: + # type=str|default='': plot title + legend_file: + # type=file|default=: legend file + labels: + # type=traitcompound|default=None: label or list of labels + y_min: + # type=float|default=0.0: minimum y value + y_max: + # type=float|default=0.0: maximum y value + y_range: + # type=tuple|default=(0.0, 0.0): min and max y axis values + x_units: + # type=int|default=1: scaling units for x-axis (between 1 and length of in file) + plot_size: + # type=tuple|default=(0, 0): plot image height and width + x_precision: + # type=int|default=0: precision of x-axis labels + sci_notation: + # type=bool|default=False: switch on scientific notation + out_file: + # type=file: image to write + # type=file|default=: image to write + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/plot_time_series_callables.py b/nipype-auto-conv/specs/plot_time_series_callables.py new file mode 100644 index 0000000..a741da7 --- /dev/null +++ b/nipype-auto-conv/specs/plot_time_series_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in PlotTimeSeries.yaml""" diff --git a/nipype-auto-conv/specs/power_spectrum.yaml b/nipype-auto-conv/specs/power_spectrum.yaml new file mode 100644 index 0000000..b239a10 --- /dev/null +++ b/nipype-auto-conv/specs/power_spectrum.yaml @@ -0,0 +1,92 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.PowerSpectrum' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL PowerSpectrum command for power spectrum estimation. +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> pspec = fsl.PowerSpectrum() +# >>> pspec.inputs.in_file = 'functional.nii' +# >>> res = pspec.run() # doctest: +SKIP +# +# +# +task_name: PowerSpectrum +nipype_name: PowerSpectrum +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input 4D file to estimate the power spectrum + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: path/name of the output 4D power spectrum file + # type=file|default=: name of output 4D file for power spectrum + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: path/name of the output 4D power spectrum file + # type=file|default=: name of output 4D file for power spectrum + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input 4D file to estimate the power spectrum + out_file: + # type=file: path/name of the output 4D power spectrum file + # type=file|default=: name of output 4D file for power spectrum + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/power_spectrum_callables.py b/nipype-auto-conv/specs/power_spectrum_callables.py new file mode 100644 index 0000000..9973085 --- /dev/null +++ b/nipype-auto-conv/specs/power_spectrum_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in PowerSpectrum.yaml""" diff --git a/nipype-auto-conv/specs/prelude.yaml b/nipype-auto-conv/specs/prelude.yaml new file mode 100644 index 0000000..3ecd6fe --- /dev/null +++ b/nipype-auto-conv/specs/prelude.yaml @@ -0,0 +1,128 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.PRELUDE' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL prelude wrapper for phase unwrapping +# +# Examples +# -------- +# +# Please insert examples for use of this command +# +# +task_name: PRELUDE +nipype_name: PRELUDE +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + complex_phase_file: generic/file + # type=file|default=: complex phase input volume + magnitude_file: generic/file + # type=file|default=: file containing magnitude image + phase_file: generic/file + # type=file|default=: raw phase file + mask_file: generic/file + # type=file|default=: filename of mask input volume + savemask_file: generic/file + # type=file|default=: saving the mask volume + rawphase_file: generic/file + # type=file|default=: saving the raw phase output + label_file: generic/file + # type=file|default=: saving the area labels output + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + unwrapped_phase_file: generic/file + # type=file: unwrapped phase file + # type=file|default=: file containing unwrapepd phase + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + unwrapped_phase_file: unwrapped_phase_file + # type=file: unwrapped phase file + # type=file|default=: file containing unwrapepd phase + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + complex_phase_file: + # type=file|default=: complex phase input volume + magnitude_file: + # type=file|default=: file containing magnitude image + phase_file: + # type=file|default=: raw phase file + unwrapped_phase_file: + # type=file: unwrapped phase file + # type=file|default=: file containing unwrapepd phase + num_partitions: + # type=int|default=0: number of phase partitions to use + labelprocess2d: + # type=bool|default=False: does label processing in 2D (slice at a time) + process2d: + # type=bool|default=False: does all processing in 2D (slice at a time) + process3d: + # type=bool|default=False: forces all processing to be full 3D + threshold: + # type=float|default=0.0: intensity threshold for masking + mask_file: + # type=file|default=: filename of mask input volume + start: + # type=int|default=0: first image number to process (default 0) + end: + # type=int|default=0: final image number to process (default Inf) + savemask_file: + # type=file|default=: saving the mask volume + rawphase_file: + # type=file|default=: saving the raw phase output + label_file: + # type=file|default=: saving the area labels output + removeramps: + # type=bool|default=False: remove phase ramps during unwrapping + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/prelude_callables.py b/nipype-auto-conv/specs/prelude_callables.py new file mode 100644 index 0000000..af11ab9 --- /dev/null +++ b/nipype-auto-conv/specs/prelude_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in PRELUDE.yaml""" diff --git a/nipype-auto-conv/specs/prepare_fieldmap.yaml b/nipype-auto-conv/specs/prepare_fieldmap.yaml new file mode 100644 index 0000000..5c52c02 --- /dev/null +++ b/nipype-auto-conv/specs/prepare_fieldmap.yaml @@ -0,0 +1,153 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.PrepareFieldmap' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Interface for the fsl_prepare_fieldmap script (FSL 5.0) +# +# Prepares a fieldmap suitable for FEAT from SIEMENS data - saves output in +# rad/s format (e.g. ```fsl_prepare_fieldmap SIEMENS +# images_3_gre_field_mapping images_4_gre_field_mapping fmap_rads 2.65```). +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import PrepareFieldmap +# >>> prepare = PrepareFieldmap() +# >>> prepare.inputs.in_phase = "phase.nii" +# >>> prepare.inputs.in_magnitude = "magnitude.nii" +# >>> prepare.inputs.output_type = "NIFTI_GZ" +# >>> prepare.cmdline # doctest: +ELLIPSIS +# 'fsl_prepare_fieldmap SIEMENS phase.nii magnitude.nii .../phase_fslprepared.nii.gz 2.460000' +# >>> res = prepare.run() # doctest: +SKIP +# +# +# +task_name: PrepareFieldmap +nipype_name: PrepareFieldmap +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_phase: medimage/nifti1 + # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) + in_magnitude: medimage/nifti1 + # type=file|default=: Magnitude difference map, brain extracted + out_fieldmap: generic/file + # type=file: output name for prepared fieldmap + # type=file|default=: output name for prepared fieldmap + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_fieldmap: generic/file + # type=file: output name for prepared fieldmap + # type=file|default=: output name for prepared fieldmap + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + scanner: + # type=string|default='SIEMENS': must be SIEMENS + in_phase: + # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) + in_magnitude: + # type=file|default=: Magnitude difference map, brain extracted + delta_TE: + # type=float|default=2.46: echo time difference of the fieldmap sequence in ms. (usually 2.46ms in Siemens) + nocheck: + # type=bool|default=False: do not perform sanity checks for image size/range/dimensions + out_fieldmap: + # type=file: output name for prepared fieldmap + # type=file|default=: output name for prepared fieldmap + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_phase: + # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) + in_magnitude: + # type=file|default=: Magnitude difference map, brain extracted + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fsl_prepare_fieldmap SIEMENS phase.nii magnitude.nii .../phase_fslprepared.nii.gz 2.460000 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_phase: + # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) + in_magnitude: + # type=file|default=: Magnitude difference map, brain extracted + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/prepare_fieldmap_callables.py b/nipype-auto-conv/specs/prepare_fieldmap_callables.py new file mode 100644 index 0000000..55273d7 --- /dev/null +++ b/nipype-auto-conv/specs/prepare_fieldmap_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in PrepareFieldmap.yaml""" diff --git a/nipype-auto-conv/specs/prob_track_x.yaml b/nipype-auto-conv/specs/prob_track_x.yaml new file mode 100644 index 0000000..4e677d8 --- /dev/null +++ b/nipype-auto-conv/specs/prob_track_x.yaml @@ -0,0 +1,273 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.ProbTrackX' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL probtrackx for tractography on bedpostx results +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> pbx = fsl.ProbTrackX(samples_base_name='merged', mask='mask.nii', seed='MASK_average_thal_right.nii', mode='seedmask', xfm='trans.mat', n_samples=3, n_steps=10, force_dir=True, opd=True, os2t=True, target_masks = ['targets_MASK1.nii', 'targets_MASK2.nii'], thsamples='merged_thsamples.nii', fsamples='merged_fsamples.nii', phsamples='merged_phsamples.nii', out_dir='.') +# >>> pbx.cmdline +# 'probtrackx --forcedir -m mask.nii --mode=seedmask --nsamples=3 --nsteps=10 --opd --os2t --dir=. --samples=merged --seed=MASK_average_thal_right.nii --targetmasks=targets.txt --xfm=trans.mat' +# +# +task_name: ProbTrackX +nipype_name: ProbTrackX +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mask2: generic/file + # type=file|default=: second bet binary mask (in diffusion space) in twomask_symm mode + mesh: generic/file + # type=file|default=: Freesurfer-type surface descriptor (in ascii format) + thsamples: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: + phsamples: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: + fsamples: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: + mask: medimage/nifti1 + # type=file|default=: bet binary mask file in diffusion space + target_masks: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + waypoints: generic/file + # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks + seed_ref: generic/file + # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent + avoid_mp: generic/file + # type=file|default=: reject pathways passing through locations given by this mask + stop_mask: generic/file + # type=file|default=: stop tracking at locations given by this mask file + xfm: datascience/text-matrix + # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity + inv_xfm: generic/file + # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + log: generic/file + # type=file: path/name of a text record of the command that was run + way_total: generic/file + # type=file: path/name of a text file containing a single number corresponding to the total number of generated tracts that have not been rejected by inclusion/exclusion mask criteria + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + mode: '"seedmask"' + # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) + out_dir: '"."' + # type=directory|default=: directory to put the final volumes in + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mode: + # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) + mask2: + # type=file|default=: second bet binary mask (in diffusion space) in twomask_symm mode + mesh: + # type=file|default=: Freesurfer-type surface descriptor (in ascii format) + thsamples: + # type=inputmultiobject|default=[]: + phsamples: + # type=inputmultiobject|default=[]: + fsamples: + # type=inputmultiobject|default=[]: + samples_base_name: + # type=str|default='merged': the rootname/base_name for samples files + mask: + # type=file|default=: bet binary mask file in diffusion space + seed: + # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file + target_masks: + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + waypoints: + # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks + network: + # type=bool|default=False: activate network mode - only keep paths going through at least one seed mask (required if multiple seed masks) + seed_ref: + # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent + out_dir: + # type=directory|default=: directory to put the final volumes in + force_dir: + # type=bool|default=True: use the actual directory name given - i.e. do not add + to make a new directory + opd: + # type=bool|default=True: outputs path distributions + correct_path_distribution: + # type=bool|default=False: correct path distribution for the length of the pathways + os2t: + # type=bool|default=False: Outputs seeds to targets + avoid_mp: + # type=file|default=: reject pathways passing through locations given by this mask + stop_mask: + # type=file|default=: stop tracking at locations given by this mask file + xfm: + # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity + inv_xfm: + # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + n_samples: + # type=int|default=5000: number of samples - default=5000 + n_steps: + # type=int|default=0: number of steps per sample - default=2000 + dist_thresh: + # type=float|default=0.0: discards samples shorter than this threshold (in mm - default=0) + c_thresh: + # type=float|default=0.0: curvature threshold - default=0.2 + sample_random_points: + # type=bool|default=False: sample random points within seed voxels + step_length: + # type=float|default=0.0: step_length in mm - default=0.5 + loop_check: + # type=bool|default=False: perform loop_checks on paths - slower, but allows lower curvature threshold + use_anisotropy: + # type=bool|default=False: use anisotropy to constrain tracking + rand_fib: + # type=enum|default=0|allowed[0,1,2,3]: options: 0 - default, 1 - to randomly sample initial fibres (with f > fibthresh), 2 - to sample in proportion fibres (with f>fibthresh) to f, 3 - to sample ALL populations at random (even if f: bet binary mask file in diffusion space + seed: '"MASK_average_thal_right.nii"' + # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file + mode: '"seedmask"' + # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) + xfm: + # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity + n_samples: '3' + # type=int|default=5000: number of samples - default=5000 + n_steps: '10' + # type=int|default=0: number of steps per sample - default=2000 + force_dir: 'True' + # type=bool|default=True: use the actual directory name given - i.e. do not add + to make a new directory + opd: 'True' + # type=bool|default=True: outputs path distributions + os2t: 'True' + # type=bool|default=False: Outputs seeds to targets + target_masks: + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + thsamples: + # type=inputmultiobject|default=[]: + fsamples: + # type=inputmultiobject|default=[]: + phsamples: + # type=inputmultiobject|default=[]: + out_dir: '"."' + # type=directory|default=: directory to put the final volumes in + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: probtrackx --forcedir -m mask.nii --mode=seedmask --nsamples=3 --nsteps=10 --opd --os2t --dir=. --samples=merged --seed=MASK_average_thal_right.nii --targetmasks=targets.txt --xfm=trans.mat + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + samples_base_name: '"merged"' + # type=str|default='merged': the rootname/base_name for samples files + mask: + # type=file|default=: bet binary mask file in diffusion space + seed: '"MASK_average_thal_right.nii"' + # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file + mode: '"seedmask"' + # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) + xfm: + # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity + n_samples: '3' + # type=int|default=5000: number of samples - default=5000 + n_steps: '10' + # type=int|default=0: number of steps per sample - default=2000 + force_dir: 'True' + # type=bool|default=True: use the actual directory name given - i.e. do not add + to make a new directory + opd: 'True' + # type=bool|default=True: outputs path distributions + os2t: 'True' + # type=bool|default=False: Outputs seeds to targets + target_masks: + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + thsamples: + # type=inputmultiobject|default=[]: + fsamples: + # type=inputmultiobject|default=[]: + phsamples: + # type=inputmultiobject|default=[]: + out_dir: '"."' + # type=directory|default=: directory to put the final volumes in + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/prob_track_x2.yaml b/nipype-auto-conv/specs/prob_track_x2.yaml new file mode 100644 index 0000000..045fc23 --- /dev/null +++ b/nipype-auto-conv/specs/prob_track_x2.yaml @@ -0,0 +1,296 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.ProbTrackX2' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL probtrackx2 for tractography on bedpostx results +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> pbx2 = fsl.ProbTrackX2() +# >>> pbx2.inputs.seed = 'seed_source.nii.gz' +# >>> pbx2.inputs.thsamples = 'merged_th1samples.nii.gz' +# >>> pbx2.inputs.fsamples = 'merged_f1samples.nii.gz' +# >>> pbx2.inputs.phsamples = 'merged_ph1samples.nii.gz' +# >>> pbx2.inputs.mask = 'nodif_brain_mask.nii.gz' +# >>> pbx2.inputs.out_dir = '.' +# >>> pbx2.inputs.n_samples = 3 +# >>> pbx2.inputs.n_steps = 10 +# >>> pbx2.cmdline +# 'probtrackx2 --forcedir -m nodif_brain_mask.nii.gz --nsamples=3 --nsteps=10 --opd --dir=. --samples=merged --seed=seed_source.nii.gz' +# +task_name: ProbTrackX2 +nipype_name: ProbTrackX2 +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + fopd: generic/file + # type=file|default=: Other mask for binning tract distribution + target2: generic/file + # type=file|default=: Low resolution binary brain mask for storing connectivity distribution in matrix2 mode + target3: generic/file + # type=file|default=: Mask used for NxN connectivity matrix (or Nxn if lrtarget3 is set) + lrtarget3: generic/file + # type=file|default=: Column-space mask used for Nxn connectivity matrix + colmask4: generic/file + # type=file|default=: Mask for columns of matrix4 (default=seed mask) + target4: generic/file + # type=file|default=: Brain mask in DTI space + thsamples: medimage/nifti-gz+list-of + # type=inputmultiobject|default=[]: + phsamples: medimage/nifti-gz+list-of + # type=inputmultiobject|default=[]: + fsamples: medimage/nifti-gz+list-of + # type=inputmultiobject|default=[]: + mask: medimage/nifti-gz + # type=file|default=: bet binary mask file in diffusion space + target_masks: generic/file+list-of + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + waypoints: generic/file + # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks + seed_ref: generic/file + # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent + avoid_mp: generic/file + # type=file|default=: reject pathways passing through locations given by this mask + stop_mask: generic/file + # type=file|default=: stop tracking at locations given by this mask file + xfm: generic/file + # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity + inv_xfm: generic/file + # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + network_matrix: generic/file + # type=file: the network matrix generated by --omatrix1 option + matrix1_dot: generic/file + # type=file: Output matrix1.dot - SeedToSeed Connectivity + lookup_tractspace: generic/file + # type=file: lookup_tractspace generated by --omatrix2 option + matrix2_dot: generic/file + # type=file: Output matrix2.dot - SeedToLowResMask + matrix3_dot: generic/file + # type=file: Output matrix3 - NxN connectivity matrix + log: generic/file + # type=file: path/name of a text record of the command that was run + way_total: generic/file + # type=file: path/name of a text file containing a single number corresponding to the total number of generated tracts that have not been rejected by inclusion/exclusion mask criteria + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_dir: '"."' + # type=directory|default=: directory to put the final volumes in + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + simple: + # type=bool|default=False: rack from a list of voxels (seed must be a ASCII list of coordinates) + fopd: + # type=file|default=: Other mask for binning tract distribution + waycond: + # type=enum|default='OR'|allowed['AND','OR']: Waypoint condition. Either "AND" (default) or "OR" + wayorder: + # type=bool|default=False: Reject streamlines that do not hit waypoints in given order. Only valid if waycond=AND + onewaycondition: + # type=bool|default=False: Apply waypoint conditions to each half tract separately + omatrix1: + # type=bool|default=False: Output matrix1 - SeedToSeed Connectivity + distthresh1: + # type=float|default=0.0: Discards samples (in matrix1) shorter than this threshold (in mm - default=0) + omatrix2: + # type=bool|default=False: Output matrix2 - SeedToLowResMask + target2: + # type=file|default=: Low resolution binary brain mask for storing connectivity distribution in matrix2 mode + omatrix3: + # type=bool|default=False: Output matrix3 (NxN connectivity matrix) + target3: + # type=file|default=: Mask used for NxN connectivity matrix (or Nxn if lrtarget3 is set) + lrtarget3: + # type=file|default=: Column-space mask used for Nxn connectivity matrix + distthresh3: + # type=float|default=0.0: Discards samples (in matrix3) shorter than this threshold (in mm - default=0) + omatrix4: + # type=bool|default=False: Output matrix4 - DtiMaskToSeed (special Oxford Sparse Format) + colmask4: + # type=file|default=: Mask for columns of matrix4 (default=seed mask) + target4: + # type=file|default=: Brain mask in DTI space + meshspace: + # type=enum|default='caret'|allowed['caret','first','freesurfer','vox']: Mesh reference space - either "caret" (default) or "freesurfer" or "first" or "vox" + thsamples: + # type=inputmultiobject|default=[]: + phsamples: + # type=inputmultiobject|default=[]: + fsamples: + # type=inputmultiobject|default=[]: + samples_base_name: + # type=str|default='merged': the rootname/base_name for samples files + mask: + # type=file|default=: bet binary mask file in diffusion space + seed: + # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file + target_masks: + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + waypoints: + # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks + network: + # type=bool|default=False: activate network mode - only keep paths going through at least one seed mask (required if multiple seed masks) + seed_ref: + # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent + out_dir: + # type=directory|default=: directory to put the final volumes in + force_dir: + # type=bool|default=True: use the actual directory name given - i.e. do not add + to make a new directory + opd: + # type=bool|default=True: outputs path distributions + correct_path_distribution: + # type=bool|default=False: correct path distribution for the length of the pathways + os2t: + # type=bool|default=False: Outputs seeds to targets + avoid_mp: + # type=file|default=: reject pathways passing through locations given by this mask + stop_mask: + # type=file|default=: stop tracking at locations given by this mask file + xfm: + # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity + inv_xfm: + # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + n_samples: + # type=int|default=5000: number of samples - default=5000 + n_steps: + # type=int|default=0: number of steps per sample - default=2000 + dist_thresh: + # type=float|default=0.0: discards samples shorter than this threshold (in mm - default=0) + c_thresh: + # type=float|default=0.0: curvature threshold - default=0.2 + sample_random_points: + # type=bool|default=False: sample random points within seed voxels + step_length: + # type=float|default=0.0: step_length in mm - default=0.5 + loop_check: + # type=bool|default=False: perform loop_checks on paths - slower, but allows lower curvature threshold + use_anisotropy: + # type=bool|default=False: use anisotropy to constrain tracking + rand_fib: + # type=enum|default=0|allowed[0,1,2,3]: options: 0 - default, 1 - to randomly sample initial fibres (with f > fibthresh), 2 - to sample in proportion fibres (with f>fibthresh) to f, 3 - to sample ALL populations at random (even if f: bet binary mask file in diffusion space + out_dir: '"."' + # type=directory|default=: directory to put the final volumes in + n_samples: '3' + # type=int|default=5000: number of samples - default=5000 + n_steps: '10' + # type=int|default=0: number of steps per sample - default=2000 + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: probtrackx2 --forcedir -m nodif_brain_mask.nii.gz --nsamples=3 --nsteps=10 --opd --dir=. --samples=merged --seed=seed_source.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + seed: '"seed_source.nii.gz"' + # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file + thsamples: + # type=inputmultiobject|default=[]: + fsamples: + # type=inputmultiobject|default=[]: + phsamples: + # type=inputmultiobject|default=[]: + mask: + # type=file|default=: bet binary mask file in diffusion space + out_dir: '"."' + # type=directory|default=: directory to put the final volumes in + n_samples: '3' + # type=int|default=5000: number of samples - default=5000 + n_steps: '10' + # type=int|default=0: number of steps per sample - default=2000 + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/prob_track_x2_callables.py b/nipype-auto-conv/specs/prob_track_x2_callables.py new file mode 100644 index 0000000..bf9e220 --- /dev/null +++ b/nipype-auto-conv/specs/prob_track_x2_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ProbTrackX2.yaml""" diff --git a/nipype-auto-conv/specs/prob_track_x_callables.py b/nipype-auto-conv/specs/prob_track_x_callables.py new file mode 100644 index 0000000..9bac868 --- /dev/null +++ b/nipype-auto-conv/specs/prob_track_x_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ProbTrackX.yaml""" diff --git a/nipype-auto-conv/specs/proj_thresh.yaml b/nipype-auto-conv/specs/proj_thresh.yaml new file mode 100644 index 0000000..93fecf8 --- /dev/null +++ b/nipype-auto-conv/specs/proj_thresh.yaml @@ -0,0 +1,124 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.ProjThresh' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL proj_thresh for thresholding some outputs of probtrack +# For complete details, see the FDT Documentation +# +# +# Example +# ------- +# +# >>> from nipype.interfaces import fsl +# >>> ldir = ['seeds_to_M1.nii', 'seeds_to_M2.nii'] +# >>> pThresh = fsl.ProjThresh(in_files=ldir, threshold=3) +# >>> pThresh.cmdline +# 'proj_thresh seeds_to_M1.nii seeds_to_M2.nii 3' +# +# +task_name: ProjThresh +nipype_name: ProjThresh +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_files: generic/file+list-of + # type=list|default=[]: a list of input volumes + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=list|default=[]: a list of input volumes + threshold: + # type=int|default=0: threshold indicating minimum number of seed voxels entering this mask region + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_files: + # type=list|default=[]: a list of input volumes + threshold: '3' + # type=int|default=0: threshold indicating minimum number of seed voxels entering this mask region + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: proj_thresh seeds_to_M1.nii seeds_to_M2.nii 3 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_files: + # type=list|default=[]: a list of input volumes + threshold: '3' + # type=int|default=0: threshold indicating minimum number of seed voxels entering this mask region + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/proj_thresh_callables.py b/nipype-auto-conv/specs/proj_thresh_callables.py new file mode 100644 index 0000000..3089925 --- /dev/null +++ b/nipype-auto-conv/specs/proj_thresh_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in ProjThresh.yaml""" diff --git a/nipype-auto-conv/specs/randomise.yaml b/nipype-auto-conv/specs/randomise.yaml new file mode 100644 index 0000000..8467d35 --- /dev/null +++ b/nipype-auto-conv/specs/randomise.yaml @@ -0,0 +1,191 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.Randomise' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL Randomise: feeds the 4D projected FA data into GLM +# modelling and thresholding +# in order to find voxels which correlate with your model +# +# Example +# ------- +# >>> import nipype.interfaces.fsl as fsl +# >>> rand = fsl.Randomise(in_file='allFA.nii', mask = 'mask.nii', tcon='design.con', design_mat='design.mat') +# >>> rand.cmdline +# 'randomise -i allFA.nii -o "randomise" -d design.mat -t design.con -m mask.nii' +# +# +task_name: Randomise +nipype_name: Randomise +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: 4D input file + design_mat: datascience/text-matrix + # type=file|default=: design matrix file + tcon: medimage-fsl/con + # type=file|default=: t contrasts file + fcon: generic/file + # type=file|default=: f contrasts file + mask: medimage/nifti1 + # type=file|default=: mask image + x_block_labels: generic/file + # type=file|default=: exchangeability block labels file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: 4D input file + base_name: + # type=str|default='randomise': the rootname that all generated files will have + design_mat: + # type=file|default=: design matrix file + tcon: + # type=file|default=: t contrasts file + fcon: + # type=file|default=: f contrasts file + mask: + # type=file|default=: mask image + x_block_labels: + # type=file|default=: exchangeability block labels file + demean: + # type=bool|default=False: demean data temporally before model fitting + one_sample_group_mean: + # type=bool|default=False: perform 1-sample group-mean test instead of generic permutation test + show_total_perms: + # type=bool|default=False: print out how many unique permutations would be generated and exit + show_info_parallel_mode: + # type=bool|default=False: print out information required for parallel mode and exit + vox_p_values: + # type=bool|default=False: output voxelwise (corrected and uncorrected) p-value images + tfce: + # type=bool|default=False: carry out Threshold-Free Cluster Enhancement + tfce2D: + # type=bool|default=False: carry out Threshold-Free Cluster Enhancement with 2D optimisation + f_only: + # type=bool|default=False: calculate f-statistics only + raw_stats_imgs: + # type=bool|default=False: output raw ( unpermuted ) statistic images + p_vec_n_dist_files: + # type=bool|default=False: output permutation vector and null distribution text files + num_perm: + # type=int|default=0: number of permutations (default 5000, set to 0 for exhaustive) + seed: + # type=int|default=0: specific integer seed for random number generator + var_smooth: + # type=int|default=0: use variance smoothing (std is in mm) + c_thresh: + # type=float|default=0.0: carry out cluster-based thresholding + cm_thresh: + # type=float|default=0.0: carry out cluster-mass-based thresholding + f_c_thresh: + # type=float|default=0.0: carry out f cluster thresholding + f_cm_thresh: + # type=float|default=0.0: carry out f cluster-mass thresholding + tfce_H: + # type=float|default=0.0: TFCE height parameter (default=2) + tfce_E: + # type=float|default=0.0: TFCE extent parameter (default=0.5) + tfce_C: + # type=float|default=0.0: TFCE connectivity (6 or 26; default=6) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: 4D input file + mask: + # type=file|default=: mask image + tcon: + # type=file|default=: t contrasts file + design_mat: + # type=file|default=: design matrix file + imports: &id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + - module: nipype.interfaces.fsl as fsl + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: randomise -i allFA.nii -o "randomise" -d design.mat -t design.con -m mask.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: 4D input file + mask: + # type=file|default=: mask image + tcon: + # type=file|default=: t contrasts file + design_mat: + # type=file|default=: design matrix file + imports: *id001 + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/randomise_callables.py b/nipype-auto-conv/specs/randomise_callables.py new file mode 100644 index 0000000..3f63d05 --- /dev/null +++ b/nipype-auto-conv/specs/randomise_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Randomise.yaml""" diff --git a/nipype-auto-conv/specs/reorient_2_std.yaml b/nipype-auto-conv/specs/reorient_2_std.yaml new file mode 100644 index 0000000..3e813d1 --- /dev/null +++ b/nipype-auto-conv/specs/reorient_2_std.yaml @@ -0,0 +1,93 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Reorient2Std' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# fslreorient2std is a tool for reorienting the image to match the +# approximate orientation of the standard template images (MNI152). +# +# +# Examples +# -------- +# +# >>> reorient = Reorient2Std() +# >>> reorient.inputs.in_file = "functional.nii" +# >>> res = reorient.run() # doctest: +SKIP +# +# +# +task_name: Reorient2Std +nipype_name: Reorient2Std +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: + # type=file|default=: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: + # type=file|default=: + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: + out_file: + # type=file: + # type=file|default=: + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/reorient_2_std_callables.py b/nipype-auto-conv/specs/reorient_2_std_callables.py new file mode 100644 index 0000000..7e424ba --- /dev/null +++ b/nipype-auto-conv/specs/reorient_2_std_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Reorient2Std.yaml""" diff --git a/nipype-auto-conv/specs/robust_fov.yaml b/nipype-auto-conv/specs/robust_fov.yaml new file mode 100644 index 0000000..945b91d --- /dev/null +++ b/nipype-auto-conv/specs/robust_fov.yaml @@ -0,0 +1,96 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.RobustFOV' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Automatically crops an image removing lower head and neck. +# +# Interface is stable 5.0.0 to 5.0.9, but default brainsize changed from +# 150mm to 170mm. +# +task_name: RobustFOV +nipype_name: RobustFOV +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input filename + out_roi: generic/file + # type=file: ROI volume output name + # type=file|default=: ROI volume output name + out_transform: generic/file + # type=file: Transformation matrix in_file to out_roi output name + # type=file|default=: Transformation matrix in_file to out_roi output name + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_roi: generic/file + # type=file: ROI volume output name + # type=file|default=: ROI volume output name + out_transform: generic/file + # type=file: Transformation matrix in_file to out_roi output name + # type=file|default=: Transformation matrix in_file to out_roi output name + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input filename + out_roi: + # type=file: ROI volume output name + # type=file|default=: ROI volume output name + brainsize: + # type=int|default=0: size of brain in z-dimension (default 170mm/150mm) + out_transform: + # type=file: Transformation matrix in_file to out_roi output name + # type=file|default=: Transformation matrix in_file to out_roi output name + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/robust_fov_callables.py b/nipype-auto-conv/specs/robust_fov_callables.py new file mode 100644 index 0000000..4b540c7 --- /dev/null +++ b/nipype-auto-conv/specs/robust_fov_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in RobustFOV.yaml""" diff --git a/nipype-auto-conv/specs/sig_loss.yaml b/nipype-auto-conv/specs/sig_loss.yaml new file mode 100644 index 0000000..47be512 --- /dev/null +++ b/nipype-auto-conv/specs/sig_loss.yaml @@ -0,0 +1,100 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.SigLoss' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Estimates signal loss from a field map (in rad/s) +# +# Examples +# -------- +# +# >>> sigloss = SigLoss() +# >>> sigloss.inputs.in_file = "phase.nii" +# >>> sigloss.inputs.echo_time = 0.03 +# >>> res = sigloss.run() # doctest: +SKIP +# +# +# +task_name: SigLoss +nipype_name: SigLoss +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: b0 fieldmap file + mask_file: generic/file + # type=file|default=: brain mask file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: signal loss estimate file + # type=file|default=: output signal loss estimate file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: signal loss estimate file + # type=file|default=: output signal loss estimate file + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: b0 fieldmap file + out_file: + # type=file: signal loss estimate file + # type=file|default=: output signal loss estimate file + mask_file: + # type=file|default=: brain mask file + echo_time: + # type=float|default=0.0: echo time in seconds + slice_direction: + # type=enum|default='x'|allowed['x','y','z']: slicing direction + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/sig_loss_callables.py b/nipype-auto-conv/specs/sig_loss_callables.py new file mode 100644 index 0000000..05400d7 --- /dev/null +++ b/nipype-auto-conv/specs/sig_loss_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SigLoss.yaml""" diff --git a/nipype-auto-conv/specs/slice.yaml b/nipype-auto-conv/specs/slice.yaml new file mode 100644 index 0000000..fe6ac07 --- /dev/null +++ b/nipype-auto-conv/specs/slice.yaml @@ -0,0 +1,125 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Slice' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslslice to split a 3D file into lots of 2D files (along z-axis). +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import Slice +# >>> slice = Slice() +# >>> slice.inputs.in_file = 'functional.nii' +# >>> slice.inputs.out_base_name = 'sl' +# >>> slice.cmdline +# 'fslslice functional.nii sl' +# +# +# +task_name: Slice +nipype_name: Slice +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: input filename + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input filename + out_base_name: + # type=str|default='': outputs prefix + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input filename + out_base_name: '"sl"' + # type=str|default='': outputs prefix + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fslslice functional.nii sl + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: input filename + out_base_name: '"sl"' + # type=str|default='': outputs prefix + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/slice_callables.py b/nipype-auto-conv/specs/slice_callables.py new file mode 100644 index 0000000..d53846e --- /dev/null +++ b/nipype-auto-conv/specs/slice_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Slice.yaml""" diff --git a/nipype-auto-conv/specs/slice_timer.yaml b/nipype-auto-conv/specs/slice_timer.yaml new file mode 100644 index 0000000..8fb5e06 --- /dev/null +++ b/nipype-auto-conv/specs/slice_timer.yaml @@ -0,0 +1,107 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.SliceTimer' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL slicetimer wrapper to perform slice timing correction +# +# Examples +# -------- +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import example_data +# >>> st = fsl.SliceTimer() +# >>> st.inputs.in_file = example_data('functional.nii') +# >>> st.inputs.interleaved = True +# >>> result = st.run() #doctest: +SKIP +# +# +task_name: SliceTimer +nipype_name: SliceTimer +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: filename of input timeseries + custom_timings: generic/file + # type=file|default=: slice timings, in fractions of TR, range 0:1 (default is 0.5 = no shift) + custom_order: generic/file + # type=file|default=: filename of single-column custom interleave order file (first slice is referred to as 1 not 0) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + slice_time_corrected_file: generic/file + # type=file: slice time corrected file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file|default=: filename of output timeseries + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input timeseries + out_file: + # type=file|default=: filename of output timeseries + index_dir: + # type=bool|default=False: slice indexing from top to bottom + time_repetition: + # type=float|default=0.0: Specify TR of data - default is 3s + slice_direction: + # type=enum|default=1|allowed[1,2,3]: direction of slice acquisition (x=1, y=2, z=3) - default is z + interleaved: + # type=bool|default=False: use interleaved acquisition + custom_timings: + # type=file|default=: slice timings, in fractions of TR, range 0:1 (default is 0.5 = no shift) + global_shift: + # type=float|default=0.0: shift in fraction of TR, range 0:1 (default is 0.5 = no shift) + custom_order: + # type=file|default=: filename of single-column custom interleave order file (first slice is referred to as 1 not 0) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/slice_timer_callables.py b/nipype-auto-conv/specs/slice_timer_callables.py new file mode 100644 index 0000000..ecae156 --- /dev/null +++ b/nipype-auto-conv/specs/slice_timer_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SliceTimer.yaml""" diff --git a/nipype-auto-conv/specs/slicer.yaml b/nipype-auto-conv/specs/slicer.yaml new file mode 100644 index 0000000..866a1f4 --- /dev/null +++ b/nipype-auto-conv/specs/slicer.yaml @@ -0,0 +1,130 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Slicer' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL's slicer command to output a png image from a volume. +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import example_data +# >>> slice = fsl.Slicer() +# >>> slice.inputs.in_file = example_data('functional.nii') +# >>> slice.inputs.all_axial = True +# >>> slice.inputs.image_width = 750 +# >>> res = slice.run() #doctest: +SKIP +# +# +# +task_name: Slicer +nipype_name: Slicer +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input volume + image_edges: generic/file + # type=file|default=: volume to display edge overlay for (useful for checking registration + colour_map: generic/file + # type=file|default=: use different colour map from that stored in nifti header + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: picture to write + # type=file|default=: picture to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: picture to write + # type=file|default=: picture to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input volume + image_edges: + # type=file|default=: volume to display edge overlay for (useful for checking registration + label_slices: + # type=bool|default=True: display slice number + colour_map: + # type=file|default=: use different colour map from that stored in nifti header + intensity_range: + # type=tuple|default=(0.0, 0.0): min and max intensities to display + threshold_edges: + # type=float|default=0.0: use threshold for edges + dither_edges: + # type=bool|default=False: produce semi-transparent (dithered) edges + nearest_neighbour: + # type=bool|default=False: use nearest neighbor interpolation for output + show_orientation: + # type=bool|default=True: label left-right orientation + single_slice: + # type=enum|default='x'|allowed['x','y','z']: output picture of single slice in the x, y, or z plane + slice_number: + # type=int|default=0: slice number to save in picture + middle_slices: + # type=bool|default=False: output picture of mid-sagittal, axial, and coronal slices + all_axial: + # type=bool|default=False: output all axial slices into one picture + sample_axial: + # type=int|default=0: output every n axial slices into one picture + image_width: + # type=int|default=0: max picture width + out_file: + # type=file: picture to write + # type=file|default=: picture to write + scaling: + # type=float|default=0.0: image scale + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/slicer_callables.py b/nipype-auto-conv/specs/slicer_callables.py new file mode 100644 index 0000000..88b4316 --- /dev/null +++ b/nipype-auto-conv/specs/slicer_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Slicer.yaml""" diff --git a/nipype-auto-conv/specs/smm.yaml b/nipype-auto-conv/specs/smm.yaml new file mode 100644 index 0000000..f1d229b --- /dev/null +++ b/nipype-auto-conv/specs/smm.yaml @@ -0,0 +1,88 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.SMM' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Spatial Mixture Modelling. For more detail on the spatial mixture modelling +# see Mixture Models with Adaptive Spatial Regularisation for Segmentation +# with an Application to FMRI Data; Woolrich, M., Behrens, T., Beckmann, C., +# and Smith, S.; IEEE Trans. Medical Imaging, 24(1):1-11, 2005. +# +task_name: SMM +nipype_name: SMM +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + spatial_data_file: generic/file + # type=file|default=: statistics spatial map + mask: generic/file + # type=file|default=: mask file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + _p_map: generic/file + activation_p_map: generic/file + # type=file: + deactivation_p_map: generic/file + # type=file: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + spatial_data_file: + # type=file|default=: statistics spatial map + mask: + # type=file|default=: mask file + no_deactivation_class: + # type=bool|default=False: enforces no deactivation class + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/smm_callables.py b/nipype-auto-conv/specs/smm_callables.py new file mode 100644 index 0000000..a6c2729 --- /dev/null +++ b/nipype-auto-conv/specs/smm_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SMM.yaml""" diff --git a/nipype-auto-conv/specs/smooth.yaml b/nipype-auto-conv/specs/smooth.yaml new file mode 100644 index 0000000..3a6a29d --- /dev/null +++ b/nipype-auto-conv/specs/smooth.yaml @@ -0,0 +1,239 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Smooth' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use fslmaths to smooth the image +# +# Examples +# -------- +# +# Setting the kernel width using sigma: +# +# >>> sm = Smooth() +# >>> sm.inputs.output_type = 'NIFTI_GZ' +# >>> sm.inputs.in_file = 'functional2.nii' +# >>> sm.inputs.sigma = 8.0 +# >>> sm.cmdline # doctest: +ELLIPSIS +# 'fslmaths functional2.nii -kernel gauss 8.000 -fmean functional2_smooth.nii.gz' +# +# Setting the kernel width using fwhm: +# +# >>> sm = Smooth() +# >>> sm.inputs.output_type = 'NIFTI_GZ' +# >>> sm.inputs.in_file = 'functional2.nii' +# >>> sm.inputs.fwhm = 8.0 +# >>> sm.cmdline # doctest: +ELLIPSIS +# 'fslmaths functional2.nii -kernel gauss 3.397 -fmean functional2_smooth.nii.gz' +# +# One of sigma or fwhm must be set: +# +# >>> from nipype.interfaces.fsl import Smooth +# >>> sm = Smooth() +# >>> sm.inputs.output_type = 'NIFTI_GZ' +# >>> sm.inputs.in_file = 'functional2.nii' +# >>> sm.cmdline #doctest: +ELLIPSIS +# Traceback (most recent call last): +# ... +# ValueError: Smooth requires a value for one of the inputs ... +# +# +task_name: Smooth +nipype_name: Smooth +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: + smoothed_file: generic/file + # type=file: + # type=file|default=: + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + smoothed_file: generic/file + # type=file: + # type=file|default=: + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: + sigma: + # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) + fwhm: + # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) + smoothed_file: + # type=file: + # type=file|default=: + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + in_file: + # type=file|default=: + sigma: '8.0' + # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + in_file: + # type=file|default=: + fwhm: '8.0' + # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + in_file: + # type=file|default=: + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fslmaths functional2.nii -kernel gauss 8.000 -fmean functional2_smooth.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + in_file: + # type=file|default=: + sigma: '8.0' + # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS +- cmdline: fslmaths functional2.nii -kernel gauss 3.397 -fmean functional2_smooth.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + in_file: + # type=file|default=: + fwhm: '8.0' + # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS +- cmdline: + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + in_file: + # type=file|default=: + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/smooth_callables.py b/nipype-auto-conv/specs/smooth_callables.py new file mode 100644 index 0000000..5dbe8c1 --- /dev/null +++ b/nipype-auto-conv/specs/smooth_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Smooth.yaml""" diff --git a/nipype-auto-conv/specs/smooth_estimate.yaml b/nipype-auto-conv/specs/smooth_estimate.yaml new file mode 100644 index 0000000..26412a1 --- /dev/null +++ b/nipype-auto-conv/specs/smooth_estimate.yaml @@ -0,0 +1,130 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.model.SmoothEstimate' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Estimates the smoothness of an image +# +# Examples +# -------- +# +# >>> est = SmoothEstimate() +# >>> est.inputs.zstat_file = 'zstat1.nii.gz' +# >>> est.inputs.mask_file = 'mask.nii' +# >>> est.cmdline +# 'smoothest --mask=mask.nii --zstat=zstat1.nii.gz' +# +# +task_name: SmoothEstimate +nipype_name: SmoothEstimate +nipype_module: nipype.interfaces.fsl.model +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mask_file: medimage/nifti1 + # type=file|default=: brain mask volume + residual_fit_file: generic/file + # type=file|default=: residual-fit image file + zstat_file: medimage/nifti-gz + # type=file|default=: zstat image file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dof: + # type=int|default=0: number of degrees of freedom + mask_file: + # type=file|default=: brain mask volume + residual_fit_file: + # type=file|default=: residual-fit image file + zstat_file: + # type=file|default=: zstat image file + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + zstat_file: + # type=file|default=: zstat image file + mask_file: + # type=file|default=: brain mask volume + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: smoothest --mask=mask.nii --zstat=zstat1.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + zstat_file: + # type=file|default=: zstat image file + mask_file: + # type=file|default=: brain mask volume + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/smooth_estimate_callables.py b/nipype-auto-conv/specs/smooth_estimate_callables.py new file mode 100644 index 0000000..bac9d45 --- /dev/null +++ b/nipype-auto-conv/specs/smooth_estimate_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SmoothEstimate.yaml""" diff --git a/nipype-auto-conv/specs/spatial_filter.yaml b/nipype-auto-conv/specs/spatial_filter.yaml new file mode 100644 index 0000000..3e0ad22 --- /dev/null +++ b/nipype-auto-conv/specs/spatial_filter.yaml @@ -0,0 +1,97 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.SpatialFilter' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to spatially filter an image. +task_name: SpatialFilter +nipype_name: SpatialFilter +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + kernel_file: generic/file + # type=file|default=: use external file for kernel + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + operation: + # type=enum|default='mean'|allowed['mean','meanu','median']: operation to filter with + kernel_shape: + # type=enum|default='3D'|allowed['2D','3D','box','boxv','file','gauss','sphere']: kernel shape to use + kernel_size: + # type=float|default=0.0: kernel size - voxels for box/boxv, mm for sphere, mm sigma for gauss + kernel_file: + # type=file|default=: use external file for kernel + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/spatial_filter_callables.py b/nipype-auto-conv/specs/spatial_filter_callables.py new file mode 100644 index 0000000..3a39375 --- /dev/null +++ b/nipype-auto-conv/specs/spatial_filter_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SpatialFilter.yaml""" diff --git a/nipype-auto-conv/specs/split.yaml b/nipype-auto-conv/specs/split.yaml new file mode 100644 index 0000000..37fbd92 --- /dev/null +++ b/nipype-auto-conv/specs/split.yaml @@ -0,0 +1,78 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Split' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Uses FSL Fslsplit command to separate a volume into images in +# time, x, y or z dimension. +# +task_name: Split +nipype_name: Split +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input filename + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input filename + out_base_name: + # type=str|default='': outputs prefix + dimension: + # type=enum|default='t'|allowed['t','x','y','z']: dimension along which the file will be split + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/split_callables.py b/nipype-auto-conv/specs/split_callables.py new file mode 100644 index 0000000..bdbf3d7 --- /dev/null +++ b/nipype-auto-conv/specs/split_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Split.yaml""" diff --git a/nipype-auto-conv/specs/std_image.yaml b/nipype-auto-conv/specs/std_image.yaml new file mode 100644 index 0000000..f4fabba --- /dev/null +++ b/nipype-auto-conv/specs/std_image.yaml @@ -0,0 +1,91 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.StdImage' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to generate a standard deviation in an image across a given +# dimension. +# +task_name: StdImage +nipype_name: StdImage +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dimension: + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to standard deviate across + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/std_image_callables.py b/nipype-auto-conv/specs/std_image_callables.py new file mode 100644 index 0000000..4670a79 --- /dev/null +++ b/nipype-auto-conv/specs/std_image_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in StdImage.yaml""" diff --git a/nipype-auto-conv/specs/susan.yaml b/nipype-auto-conv/specs/susan.yaml new file mode 100644 index 0000000..32474f2 --- /dev/null +++ b/nipype-auto-conv/specs/susan.yaml @@ -0,0 +1,105 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.preprocess.SUSAN' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# FSL SUSAN wrapper to perform smoothing +# +# For complete details, see the `SUSAN Documentation. +# `_ +# +# Examples +# -------- +# +# >>> from nipype.interfaces import fsl +# >>> from nipype.testing import example_data +# >>> anatfile # doctest: +SKIP +# anatomical.nii # doctest: +SKIP +# >>> sus = fsl.SUSAN() +# >>> sus.inputs.in_file = example_data('structural.nii') +# >>> sus.inputs.brightness_threshold = 2000.0 +# >>> sus.inputs.fwhm = 8.0 +# >>> result = sus.run() # doctest: +SKIP +# +task_name: SUSAN +nipype_name: SUSAN +nipype_module: nipype.interfaces.fsl.preprocess +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: filename of input timeseries + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + smoothed_file: generic/file + # type=file: smoothed output file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file|default=: output file name + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename of input timeseries + brightness_threshold: + # type=float|default=0.0: brightness threshold and should be greater than noise level and less than contrast of edges to be preserved. + fwhm: + # type=float|default=0.0: fwhm of smoothing, in mm, gets converted using sqrt(8*log(2)) + dimension: + # type=enum|default=3|allowed[2,3]: within-plane (2) or fully 3D (3) + use_median: + # type=enum|default=1|allowed[0,1]: whether to use a local median filter in the cases where single-point noise is detected + usans: + # type=list|default=[]: determines whether the smoothing area (USAN) is to be found from secondary images (0, 1 or 2). A negative value for any brightness threshold will auto-set the threshold at 10% of the robust range + out_file: + # type=file|default=: output file name + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/susan_callables.py b/nipype-auto-conv/specs/susan_callables.py new file mode 100644 index 0000000..505eade --- /dev/null +++ b/nipype-auto-conv/specs/susan_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SUSAN.yaml""" diff --git a/nipype-auto-conv/specs/swap_dimensions.yaml b/nipype-auto-conv/specs/swap_dimensions.yaml new file mode 100644 index 0000000..cae1420 --- /dev/null +++ b/nipype-auto-conv/specs/swap_dimensions.yaml @@ -0,0 +1,90 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.SwapDimensions' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslswapdim to alter the orientation of an image. +# +# This interface accepts a three-tuple corresponding to the new +# orientation. You may either provide dimension ids in the form of +# (-)x, (-)y, or (-z), or nifti-syle dimension codes +# (RL, LR, AP, PA, IS, SI). +# +# +task_name: SwapDimensions +nipype_name: SwapDimensions +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input image + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image with new dimensions + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image with new dimensions + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input image + new_dims: + # type=tuple|default=('x', 'x', 'x'): 3-tuple of new dimension order + out_file: + # type=file: image with new dimensions + # type=file|default=: image to write + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/swap_dimensions_callables.py b/nipype-auto-conv/specs/swap_dimensions_callables.py new file mode 100644 index 0000000..74ec8ec --- /dev/null +++ b/nipype-auto-conv/specs/swap_dimensions_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in SwapDimensions.yaml""" diff --git a/nipype-auto-conv/specs/temporal_filter.yaml b/nipype-auto-conv/specs/temporal_filter.yaml new file mode 100644 index 0000000..a9f713c --- /dev/null +++ b/nipype-auto-conv/specs/temporal_filter.yaml @@ -0,0 +1,94 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.TemporalFilter' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to apply a low, high, or bandpass temporal filter to a +# timeseries. +# +# +task_name: TemporalFilter +nipype_name: TemporalFilter +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + lowpass_sigma: + # type=float|default=-1: lowpass filter sigma (in volumes) + highpass_sigma: + # type=float|default=-1: highpass filter sigma (in volumes) + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/temporal_filter_callables.py b/nipype-auto-conv/specs/temporal_filter_callables.py new file mode 100644 index 0000000..3ec888f --- /dev/null +++ b/nipype-auto-conv/specs/temporal_filter_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in TemporalFilter.yaml""" diff --git a/nipype-auto-conv/specs/text_2_vest.yaml b/nipype-auto-conv/specs/text_2_vest.yaml new file mode 100644 index 0000000..6dab282 --- /dev/null +++ b/nipype-auto-conv/specs/text_2_vest.yaml @@ -0,0 +1,133 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Text2Vest' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL Text2Vest`https://web.mit.edu/fsl_v5.0.10/fsl/doc/wiki/GLM(2f)CreatingDesignMatricesByHand.html`_ +# to convert your plain text design matrix data into the format used by the FSL tools. +# +# Examples +# -------- +# >>> from nipype.interfaces.fsl import Text2Vest +# >>> t2v = Text2Vest() +# >>> t2v.inputs.in_file = "design.txt" +# >>> t2v.inputs.out_file = "design.mat" +# >>> t2v.cmdline +# 'Text2Vest design.txt design.mat' +# >>> res = t2v.run() # doctest: +SKIP +# +task_name: Text2Vest +nipype_name: Text2Vest +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: text/text-file + # type=file|default=: plain text file representing your design, contrast, or f-test matrix + out_file: datascience/text-matrix + # type=file: matrix data in the format used by FSL tools + # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: datascience/text-matrix + # type=file: matrix data in the format used by FSL tools + # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: plain text file representing your design, contrast, or f-test matrix + out_file: + # type=file: matrix data in the format used by FSL tools + # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: plain text file representing your design, contrast, or f-test matrix + out_file: + # type=file: matrix data in the format used by FSL tools + # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: Text2Vest design.txt design.mat + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: plain text file representing your design, contrast, or f-test matrix + out_file: + # type=file: matrix data in the format used by FSL tools + # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/text_2_vest_callables.py b/nipype-auto-conv/specs/text_2_vest_callables.py new file mode 100644 index 0000000..1fdad81 --- /dev/null +++ b/nipype-auto-conv/specs/text_2_vest_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Text2Vest.yaml""" diff --git a/nipype-auto-conv/specs/threshold.yaml b/nipype-auto-conv/specs/threshold.yaml new file mode 100644 index 0000000..7dcb37d --- /dev/null +++ b/nipype-auto-conv/specs/threshold.yaml @@ -0,0 +1,95 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.Threshold' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to apply a threshold to an image in a variety of ways. +task_name: Threshold +nipype_name: Threshold +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + thresh: + # type=float|default=0.0: threshold value + direction: + # type=enum|default='below'|allowed['above','below']: zero-out either below or above thresh value + use_robust_range: + # type=bool|default=False: interpret thresh as percentage (0-100) of robust range + use_nonzero_voxels: + # type=bool|default=False: use nonzero voxels to calculate robust range + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/threshold_callables.py b/nipype-auto-conv/specs/threshold_callables.py new file mode 100644 index 0000000..a542f78 --- /dev/null +++ b/nipype-auto-conv/specs/threshold_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Threshold.yaml""" diff --git a/nipype-auto-conv/specs/topup.yaml b/nipype-auto-conv/specs/topup.yaml new file mode 100644 index 0000000..d4c21ec --- /dev/null +++ b/nipype-auto-conv/specs/topup.yaml @@ -0,0 +1,217 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.epi.TOPUP' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Interface for FSL topup, a tool for estimating and correcting +# susceptibility induced distortions. See FSL documentation for +# `reference `_, +# `usage examples +# `_, +# and `exemplary config files +# `_. +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import TOPUP +# >>> topup = TOPUP() +# >>> topup.inputs.in_file = "b0_b0rev.nii" +# >>> topup.inputs.encoding_file = "topup_encoding.txt" +# >>> topup.inputs.output_type = "NIFTI_GZ" +# >>> topup.cmdline # doctest: +ELLIPSIS +# 'topup --config=b02b0.cnf --datain=topup_encoding.txt --imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz --fout=b0_b0rev_field.nii.gz --jacout=jac --logout=b0_b0rev_topup.log --rbmout=xfm --dfout=warpfield' +# >>> res = topup.run() # doctest: +SKIP +# +# +task_name: TOPUP +nipype_name: TOPUP +nipype_module: nipype.interfaces.fsl.epi +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: name of 4D file with images + encoding_file: text/text-file + # type=file|default=: name of text file with PE directions/times + readout_times: generic/file+list-of + # type=inputmultiobject|default=[]: readout times (dwell times by # phase-encode steps minus 1) + out_base: generic/file + # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) + out_field: generic/file + # type=file: name of image file with field (Hz) + # type=file|default=: name of image file with field (Hz) + out_corrected: generic/file + # type=file: name of 4D image file with unwarped images + # type=file|default=: name of 4D image file with unwarped images + out_logfile: generic/file + # type=file: name of log-file + # type=file|default=: name of log-file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_fieldcoef: generic/file + # type=file: file containing the field coefficients + out_movpar: generic/file + # type=file: movpar.txt output file + out_enc_file: generic/file + # type=file: encoding directions file output for applytopup + out_field: generic/file + # type=file: name of image file with field (Hz) + # type=file|default=: name of image file with field (Hz) + out_corrected: generic/file + # type=file: name of 4D image file with unwarped images + # type=file|default=: name of 4D image file with unwarped images + out_logfile: generic/file + # type=file: name of log-file + # type=file|default=: name of log-file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: name of 4D file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + encoding_direction: + # type=list|default=[]: encoding direction for automatic generation of encoding_file + readout_times: + # type=inputmultiobject|default=[]: readout times (dwell times by # phase-encode steps minus 1) + out_base: + # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) + out_field: + # type=file: name of image file with field (Hz) + # type=file|default=: name of image file with field (Hz) + out_warp_prefix: + # type=str|default='warpfield': prefix for the warpfield images (in mm) + out_mat_prefix: + # type=str|default='xfm': prefix for the realignment matrices + out_jac_prefix: + # type=str|default='jac': prefix for the warpfield images + out_corrected: + # type=file: name of 4D image file with unwarped images + # type=file|default=: name of 4D image file with unwarped images + out_logfile: + # type=file: name of log-file + # type=file|default=: name of log-file + warp_res: + # type=float|default=0.0: (approximate) resolution (in mm) of warp basis for the different sub-sampling levels + subsamp: + # type=int|default=0: sub-sampling scheme + fwhm: + # type=float|default=0.0: FWHM (in mm) of gaussian smoothing kernel + config: + # type=string|default='b02b0.cnf': Name of config file specifying command line arguments + max_iter: + # type=int|default=0: max # of non-linear iterations + reg_lambda: + # type=float|default=0.0: Weight of regularisation, default depending on --ssqlambda and --regmod switches. + ssqlambda: + # type=enum|default=1|allowed[0,1]: Weight lambda by the current value of the ssd. If used (=1), the effective weight of regularisation term becomes higher for the initial iterations, therefore initial steps are a little smoother than they would without weighting. This reduces the risk of finding a local minimum. + regmod: + # type=enum|default='bending_energy'|allowed['bending_energy','membrane_energy']: Regularisation term implementation. Defaults to bending_energy. Note that the two functions have vastly different scales. The membrane energy is based on the first derivatives and the bending energy on the second derivatives. The second derivatives will typically be much smaller than the first derivatives, so input lambda will have to be larger for bending_energy to yield approximately the same level of regularisation. + estmov: + # type=enum|default=1|allowed[0,1]: estimate movements if set + minmet: + # type=enum|default=0|allowed[0,1]: Minimisation method 0=Levenberg-Marquardt, 1=Scaled Conjugate Gradient + splineorder: + # type=int|default=0: order of spline, 2->Qadratic spline, 3->Cubic spline + numprec: + # type=enum|default='double'|allowed['double','float']: Precision for representing Hessian, double or float. + interp: + # type=enum|default='spline'|allowed['linear','spline']: Image interpolation model, linear or spline. + scale: + # type=enum|default=0|allowed[0,1]: If set (=1), the images are individually scaled to a common mean + regrid: + # type=enum|default=1|allowed[0,1]: If set (=1), the calculations are done in a different grid + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: name of 4D file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: topup --config=b02b0.cnf --datain=topup_encoding.txt --imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz --fout=b0_b0rev_field.nii.gz --jacout=jac --logout=b0_b0rev_topup.log --rbmout=xfm --dfout=warpfield + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: name of 4D file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/topup_callables.py b/nipype-auto-conv/specs/topup_callables.py new file mode 100644 index 0000000..3069076 --- /dev/null +++ b/nipype-auto-conv/specs/topup_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in TOPUP.yaml""" diff --git a/nipype-auto-conv/specs/tract_skeleton.yaml b/nipype-auto-conv/specs/tract_skeleton.yaml new file mode 100644 index 0000000..5f96e8c --- /dev/null +++ b/nipype-auto-conv/specs/tract_skeleton.yaml @@ -0,0 +1,135 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.TractSkeleton' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL's tbss_skeleton to skeletonise an FA image or project arbitrary +# values onto a skeleton. +# +# There are two ways to use this interface. To create a skeleton from an FA +# image, just supply the ``in_file`` and set ``skeleton_file`` to True (or +# specify a skeleton filename. To project values onto a skeleton, you must +# set ``project_data`` to True, and then also supply values for +# ``threshold``, ``distance_map``, and ``data_file``. The +# ``search_mask_file`` and ``use_cingulum_mask`` inputs are also used in data +# projection, but ``use_cingulum_mask`` is set to True by default. This mask +# controls where the projection algorithm searches within a circular space +# around a tract, rather than in a single perpendicular direction. +# +# Example +# ------- +# +# >>> import nipype.interfaces.fsl as fsl +# >>> skeletor = fsl.TractSkeleton() +# >>> skeletor.inputs.in_file = "all_FA.nii.gz" +# >>> skeletor.inputs.skeleton_file = True +# >>> skeletor.run() # doctest: +SKIP +# +# +task_name: TractSkeleton +nipype_name: TractSkeleton +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: input image (typically mean FA volume) + distance_map: generic/file + # type=file|default=: distance map image + search_mask_file: generic/file + # type=file|default=: mask in which to use alternate search rule + data_file: generic/file + # type=file|default=: 4D data to project onto skeleton (usually FA) + alt_data_file: generic/file + # type=file|default=: 4D non-FA data to project onto skeleton + alt_skeleton: generic/file + # type=file|default=: alternate skeleton to use + projected_data: generic/file + # type=file: input data projected onto skeleton + # type=file|default=: input data projected onto skeleton + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + projected_data: generic/file + # type=file: input data projected onto skeleton + # type=file|default=: input data projected onto skeleton + skeleton_file: generic/file + # type=file: tract skeleton image + # type=traitcompound|default=None: write out skeleton image + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input image (typically mean FA volume) + project_data: + # type=bool|default=False: project data onto skeleton + threshold: + # type=float|default=0.0: skeleton threshold value + distance_map: + # type=file|default=: distance map image + search_mask_file: + # type=file|default=: mask in which to use alternate search rule + use_cingulum_mask: + # type=bool|default=True: perform alternate search using built-in cingulum mask + data_file: + # type=file|default=: 4D data to project onto skeleton (usually FA) + alt_data_file: + # type=file|default=: 4D non-FA data to project onto skeleton + alt_skeleton: + # type=file|default=: alternate skeleton to use + projected_data: + # type=file: input data projected onto skeleton + # type=file|default=: input data projected onto skeleton + skeleton_file: + # type=file: tract skeleton image + # type=traitcompound|default=None: write out skeleton image + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/tract_skeleton_callables.py b/nipype-auto-conv/specs/tract_skeleton_callables.py new file mode 100644 index 0000000..92b6fc4 --- /dev/null +++ b/nipype-auto-conv/specs/tract_skeleton_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in TractSkeleton.yaml""" diff --git a/nipype-auto-conv/specs/training.yaml b/nipype-auto-conv/specs/training.yaml new file mode 100644 index 0000000..91531b1 --- /dev/null +++ b/nipype-auto-conv/specs/training.yaml @@ -0,0 +1,78 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.fix.Training' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Train the classifier based on your own FEAT/MELODIC output directory. +# +task_name: Training +nipype_name: Training +nipype_module: nipype.interfaces.fsl.fix +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mel_icas: generic/file+list-of + # type=inputmultiobject|default=[]: Melodic output directories + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + trained_wts_file: generic/file + # type=file: Trained-weights file + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mel_icas: + # type=inputmultiobject|default=[]: Melodic output directories + trained_wts_filestem: + # type=str|default='': trained-weights filestem, used for trained_wts_file and output directories + loo: + # type=bool|default=False: full leave-one-out test with classifier training + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/training_callables.py b/nipype-auto-conv/specs/training_callables.py new file mode 100644 index 0000000..7be534e --- /dev/null +++ b/nipype-auto-conv/specs/training_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Training.yaml""" diff --git a/nipype-auto-conv/specs/training_set_creator.yaml b/nipype-auto-conv/specs/training_set_creator.yaml new file mode 100644 index 0000000..04f170d --- /dev/null +++ b/nipype-auto-conv/specs/training_set_creator.yaml @@ -0,0 +1,73 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.fix.TrainingSetCreator' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Goes through set of provided melodic output directories, to find all +# the ones that have a hand_labels_noise.txt file in them. +# +# This is outsourced as a separate class, so that the pipeline is +# rerun every time a handlabeled file has been changed, or a new one +# created. +# +# +task_name: TrainingSetCreator +nipype_name: TrainingSetCreator +nipype_module: nipype.interfaces.fsl.fix +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mel_icas_in: generic/file+list-of + # type=inputmultiobject|default=[]: Melodic output directories + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mel_icas_in: + # type=inputmultiobject|default=[]: Melodic output directories + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/training_set_creator_callables.py b/nipype-auto-conv/specs/training_set_creator_callables.py new file mode 100644 index 0000000..b585309 --- /dev/null +++ b/nipype-auto-conv/specs/training_set_creator_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in TrainingSetCreator.yaml""" diff --git a/nipype-auto-conv/specs/unary_maths.yaml b/nipype-auto-conv/specs/unary_maths.yaml new file mode 100644 index 0000000..7cb6818 --- /dev/null +++ b/nipype-auto-conv/specs/unary_maths.yaml @@ -0,0 +1,89 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.maths.UnaryMaths' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use fslmaths to perorm a variety of mathematical operations on an image. +task_name: UnaryMaths +nipype_name: UnaryMaths +nipype_module: nipype.interfaces.fsl.maths +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: generic/file + # type=file|default=: image to operate on + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: image written after calculations + # type=file|default=: image to write + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file + # type=file: image written after calculations + # type=file|default=: image to write + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + operation: + # type=enum|default='exp'|allowed['abs','acos','asin','atan','bin','binv','cos','edge','exp','fillh','fillh26','index','log','nan','nanm','rand','randn','range','recip','sin','sqr','sqrt','tan']: operation to perform + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/unary_maths_callables.py b/nipype-auto-conv/specs/unary_maths_callables.py new file mode 100644 index 0000000..ae1ae26 --- /dev/null +++ b/nipype-auto-conv/specs/unary_maths_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in UnaryMaths.yaml""" diff --git a/nipype-auto-conv/specs/vec_reg.yaml b/nipype-auto-conv/specs/vec_reg.yaml new file mode 100644 index 0000000..3c8aa5a --- /dev/null +++ b/nipype-auto-conv/specs/vec_reg.yaml @@ -0,0 +1,170 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.VecReg' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL vecreg for registering vector data +# For complete details, see the FDT Documentation +# +# +# Example +# ------- +# +# >>> from nipype.interfaces import fsl +# >>> vreg = fsl.VecReg(in_file='diffusion.nii', affine_mat='trans.mat', ref_vol='mni.nii', out_file='diffusion_vreg.nii') +# >>> vreg.cmdline +# 'vecreg -t trans.mat -i diffusion.nii -o diffusion_vreg.nii -r mni.nii' +# +# +task_name: VecReg +nipype_name: VecReg +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: filename for input vector or tensor field + ref_vol: medimage/nifti1 + # type=file|default=: filename for reference (target) volume + affine_mat: datascience/text-matrix + # type=file|default=: filename for affine transformation matrix + warp_field: generic/file + # type=file|default=: filename for 4D warp field for nonlinear registration + rotation_mat: generic/file + # type=file|default=: filename for secondary affine matrix if set, this will be used for the rotation of the vector/tensor field + rotation_warp: generic/file + # type=file|default=: filename for secondary warp field if set, this will be used for the rotation of the vector/tensor field + mask: generic/file + # type=file|default=: brain mask in input space + ref_mask: generic/file + # type=file|default=: brain mask in output space (useful for speed up of nonlinear reg) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: medimage/nifti1 + # type=file: path/name of filename for the registered vector or tensor field + # type=file|default=: filename for output registered vector or tensor field + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: '"diffusion_vreg.nii"' + # type=file: path/name of filename for the registered vector or tensor field + # type=file|default=: filename for output registered vector or tensor field + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename for input vector or tensor field + out_file: + # type=file: path/name of filename for the registered vector or tensor field + # type=file|default=: filename for output registered vector or tensor field + ref_vol: + # type=file|default=: filename for reference (target) volume + affine_mat: + # type=file|default=: filename for affine transformation matrix + warp_field: + # type=file|default=: filename for 4D warp field for nonlinear registration + rotation_mat: + # type=file|default=: filename for secondary affine matrix if set, this will be used for the rotation of the vector/tensor field + rotation_warp: + # type=file|default=: filename for secondary warp field if set, this will be used for the rotation of the vector/tensor field + interpolation: + # type=enum|default='nearestneighbour'|allowed['nearestneighbour','sinc','spline','trilinear']: interpolation method : nearestneighbour, trilinear (default), sinc or spline + mask: + # type=file|default=: brain mask in input space + ref_mask: + # type=file|default=: brain mask in output space (useful for speed up of nonlinear reg) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: filename for input vector or tensor field + affine_mat: + # type=file|default=: filename for affine transformation matrix + ref_vol: + # type=file|default=: filename for reference (target) volume + out_file: '"diffusion_vreg.nii"' + # type=file: path/name of filename for the registered vector or tensor field + # type=file|default=: filename for output registered vector or tensor field + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: vecreg -t trans.mat -i diffusion.nii -o diffusion_vreg.nii -r mni.nii + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: filename for input vector or tensor field + affine_mat: + # type=file|default=: filename for affine transformation matrix + ref_vol: + # type=file|default=: filename for reference (target) volume + out_file: '"diffusion_vreg.nii"' + # type=file: path/name of filename for the registered vector or tensor field + # type=file|default=: filename for output registered vector or tensor field + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/vec_reg_callables.py b/nipype-auto-conv/specs/vec_reg_callables.py new file mode 100644 index 0000000..e1d8453 --- /dev/null +++ b/nipype-auto-conv/specs/vec_reg_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in VecReg.yaml""" diff --git a/nipype-auto-conv/specs/vest_2_text.yaml b/nipype-auto-conv/specs/vest_2_text.yaml new file mode 100644 index 0000000..0a0e392 --- /dev/null +++ b/nipype-auto-conv/specs/vest_2_text.yaml @@ -0,0 +1,126 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.Vest2Text' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL Vest2Text`https://web.mit.edu/fsl_v5.0.10/fsl/doc/wiki/GLM(2f)CreatingDesignMatricesByHand.html`_ +# to convert your design.mat design.con and design.fts files into plain text. +# +# Examples +# -------- +# >>> from nipype.interfaces.fsl import Vest2Text +# >>> v2t = Vest2Text() +# >>> v2t.inputs.in_file = "design.mat" +# >>> v2t.cmdline +# 'Vest2Text design.mat design.txt' +# >>> res = v2t.run() # doctest: +SKIP +# +task_name: Vest2Text +nipype_name: Vest2Text +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: datascience/text-matrix + # type=file|default=: matrix data stored in the format used by FSL tools + out_file: generic/file + # type=file: plain text representation of FSL matrix + # type=file|default='design.txt': file name to store text output from matrix + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: plain text representation of FSL matrix + # type=file|default='design.txt': file name to store text output from matrix + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: matrix data stored in the format used by FSL tools + out_file: + # type=file: plain text representation of FSL matrix + # type=file|default='design.txt': file name to store text output from matrix + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: matrix data stored in the format used by FSL tools + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: Vest2Text design.mat design.txt + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: matrix data stored in the format used by FSL tools + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/vest_2_text_callables.py b/nipype-auto-conv/specs/vest_2_text_callables.py new file mode 100644 index 0000000..905b226 --- /dev/null +++ b/nipype-auto-conv/specs/vest_2_text_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in Vest2Text.yaml""" diff --git a/nipype-auto-conv/specs/warp_points.yaml b/nipype-auto-conv/specs/warp_points.yaml new file mode 100644 index 0000000..0c55db1 --- /dev/null +++ b/nipype-auto-conv/specs/warp_points.yaml @@ -0,0 +1,169 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.WarpPoints' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL `img2imgcoord `_ +# to transform point sets. Accepts plain text files and vtk files. +# +# .. Note:: transformation of TrackVis trk files is not yet implemented +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import WarpPoints +# >>> warppoints = WarpPoints() +# >>> warppoints.inputs.in_coords = 'surf.txt' +# >>> warppoints.inputs.src_file = 'epi.nii' +# >>> warppoints.inputs.dest_file = 'T1.nii' +# >>> warppoints.inputs.warp_file = 'warpfield.nii' +# >>> warppoints.inputs.coord_mm = True +# >>> warppoints.cmdline # doctest: +ELLIPSIS +# 'img2imgcoord -mm -dest T1.nii -src epi.nii -warp warpfield.nii surf.txt' +# >>> res = warppoints.run() # doctest: +SKIP +# +# +# +task_name: WarpPoints +nipype_name: WarpPoints +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + src_file: medimage/nifti1 + # type=file|default=: filename of source image + dest_file: medimage/nifti1 + # type=file|default=: filename of destination image + in_coords: text/text-file + # type=file|default=: filename of file containing coordinates + xfm_file: generic/file + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + warp_file: medimage/nifti1 + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: output file name + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: output file name + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + src_file: + # type=file|default=: filename of source image + dest_file: + # type=file|default=: filename of destination image + in_coords: + # type=file|default=: filename of file containing coordinates + xfm_file: + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_vox: + # type=bool|default=True: all coordinates in voxels - default + coord_mm: + # type=bool|default=False: all coordinates in mm + out_file: + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: output file name + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_coords: + # type=file|default=: filename of file containing coordinates + src_file: + # type=file|default=: filename of source image + dest_file: + # type=file|default=: filename of destination image + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_mm: 'True' + # type=bool|default=False: all coordinates in mm + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: img2imgcoord -mm -dest T1.nii -src epi.nii -warp warpfield.nii surf.txt + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_coords: + # type=file|default=: filename of file containing coordinates + src_file: + # type=file|default=: filename of source image + dest_file: + # type=file|default=: filename of destination image + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_mm: 'True' + # type=bool|default=False: all coordinates in mm + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_points_callables.py b/nipype-auto-conv/specs/warp_points_callables.py new file mode 100644 index 0000000..b868a2c --- /dev/null +++ b/nipype-auto-conv/specs/warp_points_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in WarpPoints.yaml""" diff --git a/nipype-auto-conv/specs/warp_points_from_std.yaml b/nipype-auto-conv/specs/warp_points_from_std.yaml new file mode 100644 index 0000000..2c28ddf --- /dev/null +++ b/nipype-auto-conv/specs/warp_points_from_std.yaml @@ -0,0 +1,162 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.WarpPointsFromStd' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL `std2imgcoord `_ +# to transform point sets to standard space coordinates. Accepts plain text coordinates +# files. +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import WarpPointsFromStd +# >>> warppoints = WarpPointsFromStd() +# >>> warppoints.inputs.in_coords = 'surf.txt' +# >>> warppoints.inputs.img_file = 'T1.nii' +# >>> warppoints.inputs.std_file = 'mni.nii' +# >>> warppoints.inputs.warp_file = 'warpfield.nii' +# >>> warppoints.inputs.coord_mm = True +# >>> warppoints.cmdline # doctest: +ELLIPSIS +# 'std2imgcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt' +# >>> res = warppoints.run() # doctest: +SKIP +# +# +# +task_name: WarpPointsFromStd +nipype_name: WarpPointsFromStd +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + img_file: medimage/nifti1 + # type=file|default=: filename of a destination image + std_file: medimage/nifti1 + # type=file|default=: filename of the image in standard space + in_coords: text/text-file + # type=file|default=: filename of file containing coordinates + xfm_file: generic/file + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + warp_file: medimage/nifti1 + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + img_file: + # type=file|default=: filename of a destination image + std_file: + # type=file|default=: filename of the image in standard space + in_coords: + # type=file|default=: filename of file containing coordinates + xfm_file: + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_vox: + # type=bool|default=True: all coordinates in voxels - default + coord_mm: + # type=bool|default=False: all coordinates in mm + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_coords: + # type=file|default=: filename of file containing coordinates + img_file: + # type=file|default=: filename of a destination image + std_file: + # type=file|default=: filename of the image in standard space + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_mm: 'True' + # type=bool|default=False: all coordinates in mm + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: std2imgcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_coords: + # type=file|default=: filename of file containing coordinates + img_file: + # type=file|default=: filename of a destination image + std_file: + # type=file|default=: filename of the image in standard space + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_mm: 'True' + # type=bool|default=False: all coordinates in mm + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_points_from_std_callables.py b/nipype-auto-conv/specs/warp_points_from_std_callables.py new file mode 100644 index 0000000..e587abf --- /dev/null +++ b/nipype-auto-conv/specs/warp_points_from_std_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in WarpPointsFromStd.yaml""" diff --git a/nipype-auto-conv/specs/warp_points_to_std.yaml b/nipype-auto-conv/specs/warp_points_to_std.yaml new file mode 100644 index 0000000..20ddb69 --- /dev/null +++ b/nipype-auto-conv/specs/warp_points_to_std.yaml @@ -0,0 +1,175 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.WarpPointsToStd' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Use FSL `img2stdcoord `_ +# to transform point sets to standard space coordinates. Accepts plain text +# files and vtk files. +# +# .. Note:: transformation of TrackVis trk files is not yet implemented +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import WarpPointsToStd +# >>> warppoints = WarpPointsToStd() +# >>> warppoints.inputs.in_coords = 'surf.txt' +# >>> warppoints.inputs.img_file = 'T1.nii' +# >>> warppoints.inputs.std_file = 'mni.nii' +# >>> warppoints.inputs.warp_file = 'warpfield.nii' +# >>> warppoints.inputs.coord_mm = True +# >>> warppoints.cmdline # doctest: +ELLIPSIS +# 'img2stdcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt' +# >>> res = warppoints.run() # doctest: +SKIP +# +# +# +task_name: WarpPointsToStd +nipype_name: WarpPointsToStd +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + img_file: medimage/nifti1 + # type=file|default=: filename of input image + std_file: medimage/nifti1 + # type=file|default=: filename of destination image + premat_file: generic/file + # type=file|default=: filename of pre-warp affine transform (e.g. example_func2highres.mat) + in_coords: text/text-file + # type=file|default=: filename of file containing coordinates + xfm_file: generic/file + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + warp_file: medimage/nifti1 + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: output file name + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: output file name + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + img_file: + # type=file|default=: filename of input image + std_file: + # type=file|default=: filename of destination image + premat_file: + # type=file|default=: filename of pre-warp affine transform (e.g. example_func2highres.mat) + in_coords: + # type=file|default=: filename of file containing coordinates + xfm_file: + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_vox: + # type=bool|default=True: all coordinates in voxels - default + coord_mm: + # type=bool|default=False: all coordinates in mm + out_file: + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: output file name + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_coords: + # type=file|default=: filename of file containing coordinates + img_file: + # type=file|default=: filename of input image + std_file: + # type=file|default=: filename of destination image + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_mm: 'True' + # type=bool|default=False: all coordinates in mm + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: img2stdcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_coords: + # type=file|default=: filename of file containing coordinates + img_file: + # type=file|default=: filename of input image + std_file: + # type=file|default=: filename of destination image + warp_file: + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + coord_mm: 'True' + # type=bool|default=False: all coordinates in mm + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_points_to_std_callables.py b/nipype-auto-conv/specs/warp_points_to_std_callables.py new file mode 100644 index 0000000..3c70651 --- /dev/null +++ b/nipype-auto-conv/specs/warp_points_to_std_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in WarpPointsToStd.yaml""" diff --git a/nipype-auto-conv/specs/warp_utils.yaml b/nipype-auto-conv/specs/warp_utils.yaml new file mode 100644 index 0000000..360fd75 --- /dev/null +++ b/nipype-auto-conv/specs/warp_utils.yaml @@ -0,0 +1,172 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.utils.WarpUtils' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# Use FSL `fnirtfileutils `_ +# to convert field->coefficients, coefficients->field, coefficients->other_coefficients etc +# +# +# Examples +# -------- +# +# >>> from nipype.interfaces.fsl import WarpUtils +# >>> warputils = WarpUtils() +# >>> warputils.inputs.in_file = "warpfield.nii" +# >>> warputils.inputs.reference = "T1.nii" +# >>> warputils.inputs.out_format = 'spline' +# >>> warputils.inputs.warp_resolution = (10,10,10) +# >>> warputils.inputs.output_type = "NIFTI_GZ" +# >>> warputils.cmdline # doctest: +ELLIPSIS +# 'fnirtfileutils --in=warpfield.nii --outformat=spline --ref=T1.nii --warpres=10.0000,10.0000,10.0000 --out=warpfield_coeffs.nii.gz' +# >>> res = invwarp.run() # doctest: +SKIP +# +# +# +task_name: WarpUtils +nipype_name: WarpUtils +nipype_module: nipype.interfaces.fsl.utils +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti1 + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: medimage/nifti1 + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: Name of output file. The format of the output depends on what other parameters are set. The default format is a (4D) field-file. If the --outformat is set to spline the format will be a (4D) file of spline coefficients. + out_jacobian: generic/file + # type=file: Name of output file, containing the map of the determinant of the Jacobian + # type=file|default=: Specifies that a (3D) file of Jacobian determinants corresponding to --in should be produced and written to filename. + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: generic/file + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: Name of output file. The format of the output depends on what other parameters are set. The default format is a (4D) field-file. If the --outformat is set to spline the format will be a (4D) file of spline coefficients. + out_jacobian: generic/file + # type=file: Name of output file, containing the map of the determinant of the Jacobian + # type=file|default=: Specifies that a (3D) file of Jacobian determinants corresponding to --in should be produced and written to filename. + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + out_format: + # type=enum|default='spline'|allowed['field','spline']: Specifies the output format. If set to field (default) the output will be a (4D) field-file. If set to spline the format will be a (4D) file of spline coefficients. + warp_resolution: + # type=tuple|default=(0.0, 0.0, 0.0): Specifies the resolution/knot-spacing of the splines pertaining to the coefficients in the --out file. This parameter is only relevant if --outformat is set to spline. It should be noted that if the --in file has a higher resolution, the resulting coefficients will pertain to the closest (in a least-squares sense) file in the space of fields with the --warpres resolution. It should also be noted that the resolution will always be an integer multiple of the voxel size. + knot_space: + # type=tuple|default=(0, 0, 0): Alternative (to --warpres) specification of the resolution of the output spline-field. + out_file: + # type=file: Name of output file, containing the warp as field or coefficients. + # type=file|default=: Name of output file. The format of the output depends on what other parameters are set. The default format is a (4D) field-file. If the --outformat is set to spline the format will be a (4D) file of spline coefficients. + write_jacobian: + # type=bool|default=False: Switch on --jac flag with automatically generated filename + out_jacobian: + # type=file: Name of output file, containing the map of the determinant of the Jacobian + # type=file|default=: Specifies that a (3D) file of Jacobian determinants corresponding to --in should be produced and written to filename. + with_affine: + # type=bool|default=False: Specifies that the affine transform (i.e. that which was specified for the --aff parameter in fnirt) should be included as displacements in the --out file. That can be useful for interfacing with software that cannot decode FSL/fnirt coefficient-files (where the affine transform is stored separately from the displacements). + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + out_format: '"spline"' + # type=enum|default='spline'|allowed['field','spline']: Specifies the output format. If set to field (default) the output will be a (4D) field-file. If set to spline the format will be a (4D) file of spline coefficients. + warp_resolution: (10,10,10) + # type=tuple|default=(0.0, 0.0, 0.0): Specifies the resolution/knot-spacing of the splines pertaining to the coefficients in the --out file. This parameter is only relevant if --outformat is set to spline. It should be noted that if the --in file has a higher resolution, the resulting coefficients will pertain to the closest (in a least-squares sense) file in the space of fields with the --warpres resolution. It should also be noted that the resolution will always be an integer multiple of the voxel size. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: +- cmdline: fnirtfileutils --in=warpfield.nii --outformat=spline --ref=T1.nii --warpres=10.0000,10.0000,10.0000 --out=warpfield_coeffs.nii.gz + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + reference: + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + out_format: '"spline"' + # type=enum|default='spline'|allowed['field','spline']: Specifies the output format. If set to field (default) the output will be a (4D) field-file. If set to spline the format will be a (4D) file of spline coefficients. + warp_resolution: (10,10,10) + # type=tuple|default=(0.0, 0.0, 0.0): Specifies the resolution/knot-spacing of the splines pertaining to the coefficients in the --out file. This parameter is only relevant if --outformat is set to spline. It should be noted that if the --in file has a higher resolution, the resulting coefficients will pertain to the closest (in a least-squares sense) file in the space of fields with the --warpres resolution. It should also be noted that the resolution will always be an integer multiple of the voxel size. + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_utils_callables.py b/nipype-auto-conv/specs/warp_utils_callables.py new file mode 100644 index 0000000..f8cee64 --- /dev/null +++ b/nipype-auto-conv/specs/warp_utils_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in WarpUtils.yaml""" diff --git a/nipype-auto-conv/specs/x_fibres_5.yaml b/nipype-auto-conv/specs/x_fibres_5.yaml new file mode 100644 index 0000000..7756753 --- /dev/null +++ b/nipype-auto-conv/specs/x_fibres_5.yaml @@ -0,0 +1,135 @@ +# This file is used to manually specify the semi-automatic conversion of +# 'nipype.interfaces.fsl.dti.XFibres5' from Nipype to Pydra. +# +# Please fill-in/edit the fields below where appropriate +# +# Docs +# ---- +# +# Perform model parameters estimation for local (voxelwise) diffusion +# parameters +# +task_name: XFibres5 +nipype_name: XFibres5 +nipype_module: nipype.interfaces.fsl.dti +inputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + gradnonlin: generic/file + # type=file|default=: gradient file corresponding to slice + dwi: generic/file + # type=file|default=: diffusion weighted image data file + mask: generic/file + # type=file|default=: brain binary mask file (i.e. from BET) + bvecs: generic/file + # type=file|default=: b vectors file + bvals: generic/file + # type=file|default=: b values file + metadata: + # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) +outputs: + omit: + # list[str] - fields to omit from the Pydra interface + rename: + # dict[str, str] - fields to rename in the Pydra interface + types: + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mean_dsamples: generic/file + # type=file: Mean of distribution on diffusivity d + mean_S0samples: generic/file + # type=file: Mean of distribution on T2wbaseline signal intensity S0 + mean_tausamples: generic/file + # type=file: Mean of distribution on tau samples (only with rician noise) + callables: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set to the `callable` attribute of output fields + templates: + # dict[str, str] - `output_file_template` values to be provided to output fields + requirements: + # dict[str, list[str]] - input fields that are required to be provided for the output field to be present +tests: +- inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + gradnonlin: + # type=file|default=: gradient file corresponding to slice + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: brain binary mask file (i.e. from BET) + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + logdir: + # type=directory|default='.': + n_fibres: + # type=range|default=2: Maximum number of fibres to fit in each voxel + model: + # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model + fudge: + # type=int|default=0: ARD fudge factor + n_jumps: + # type=int|default=5000: Num of jumps to be made by MCMC + burn_in: + # type=range|default=0: Total num of jumps at start of MCMC to be discarded + burn_in_no_ard: + # type=range|default=0: num of burnin jumps before the ard is imposed + sample_every: + # type=range|default=1: Num of jumps for each sample (MCMC) + update_proposal_every: + # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) + seed: + # type=int|default=0: seed for pseudo random number generator + no_ard: + # type=bool|default=False: Turn ARD off on all fibres + all_ard: + # type=bool|default=False: Turn ARD on on all fibres + no_spat: + # type=bool|default=False: Initialise with tensor, not spatially + non_linear: + # type=bool|default=False: Initialise with nonlinear fitting + cnlinear: + # type=bool|default=False: Initialise with constrained nonlinear fitting + rician: + # type=bool|default=False: use Rician noise modeling + f0_noard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + f0_ard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + force_dir: + # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file +doctests: [] diff --git a/nipype-auto-conv/specs/x_fibres_5_callables.py b/nipype-auto-conv/specs/x_fibres_5_callables.py new file mode 100644 index 0000000..0f22a32 --- /dev/null +++ b/nipype-auto-conv/specs/x_fibres_5_callables.py @@ -0,0 +1 @@ +"""Module to put any functions that are referred to in XFibres5.yaml""" diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index ad1ccb6..de9520f 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -1,12 +1,37 @@ """ -To use the tasks in this package, import from ``pydra.tasks.fsl``:: - - >>> import pydra.engine - >>> import pydra.tasks.fsl +This is a basic doctest demonstrating that the package and pydra can both be successfully +imported. +>>> import pydra.engine +>>> import pydra.tasks.fsl """ +from warnings import warn +from pathlib import Path + +pkg_path = Path(__file__).parent.parent try: from ._version import __version__ except ImportError: - pass + raise RuntimeError( + "pydra-fsl has not been properly installed, please run " + f"`pip install -e {str(pkg_path)}` to install a development version" + ) +if "nipype" not in __version__: + try: + from .auto._version import nipype_version, nipype2pydra_version + except ImportError: + warn( + "Nipype interfaces haven't been automatically converted from their specs in " + f"`nipype-auto-conv`. Please run `{str(pkg_path / 'nipype-auto-conv' / 'generate')}` " + "to generated the converted Nipype interfaces in pydra.tasks.fsl.auto" + ) + else: + n_ver = nipype_version.replace(".", "_") + n2p_ver = nipype2pydra_version.replace(".", "_") + __version__ += ( + "_" if "+" in __version__ else "+" + ) + f"nipype{n_ver}_nipype2pydra{n2p_ver}" + + +__all__ = ["__version__"] diff --git a/pydra/tasks/fsl/latest.py b/pydra/tasks/fsl/latest.py new file mode 100644 index 0000000..f41e057 --- /dev/null +++ b/pydra/tasks/fsl/latest.py @@ -0,0 +1,3 @@ +PACKAGE_VERSION = "v1" + +from .v1 import * # noqa diff --git a/pydra/tasks/fsl/v1/__init__.py b/pydra/tasks/fsl/v1/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/pyproject.toml b/pyproject.toml index 3a0ead8..01ce137 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,38 +1,37 @@ [build-system] -requires = ["flit_scm"] -build-backend = "flit_scm:buildapi" +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" [project] name = "pydra-fsl" -description = "FSL tasks for the Pydra dataflow engine" -readme = "README.md" -requires-python = ">=3.7" -dependencies = ["pydra >=0.14.1"] +description = "Pydra tasks package for fsl" +readme = "README.rst" +requires-python = ">=3.8" +dependencies = [ + "pydra >=0.22", + "fileformats >=0.8.3", + "fileformats-datascience >=0.1", + "fileformats-medimage >=0.4.1", + "fileformats-medimage-fsl" +] license = {file = "LICENSE"} authors = [{name = "Nipype developers", email = "neuroimaging@python.org"}] -keywords = ["pydra", "fsl"] +maintainers = [{name = "Nipype developers", email = "neuroimaging@python.org"}] +keywords = ["pydra"] classifiers = [ - "Development Status :: 3 - Alpha", + "Development Status :: 2 - Pre-Alpha", "Environment :: Console", "Intended Audience :: Science/Research", "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", - "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3", "Topic :: Scientific/Engineering", ] dynamic = ["version"] [project.optional-dependencies] -all = [ - "pydra-fsl[dev]", - "pydra-fsl[doc]", -] dev = [ - "pydra-fsl[test]", - "nipype", - "pyyaml", "black", "pre-commit", ] @@ -44,32 +43,41 @@ doc = [ "sphinxcontrib-napoleon", "sphinxcontrib-versioning", ] -docs = [ - "pydra-fsl[doc]", -] test = [ - "pytest >=4.4.0", + "pytest >= 4.4.0", "pytest-cov", "pytest-env", "pytest-xdist", "pytest-rerunfailures", "codecov", -] -tests = [ - "pydra-fsl[test]", + "fileformats-extras", + "fileformats-datascience-extras", + "fileformats-medimage-extras", + "fileformats-medimage-fsl-extras" ] -[project.urls] -repository = "https://github.com/nipype/pydra-fsl" +[tool.hatch.version] +source = "vcs" -[tool.flit.module] -name = "pydra.tasks.fsl" +[tool.hatch.build.hooks.vcs] +version-file = "pydra/tasks/fsl/_version.py" -[tool.setuptools_scm] -write_to = "pydra/tasks/fsl/_version.py" +[tool.hatch.build.targets.wheel] +packages = ["pydra"] +include-only = ["pydra/tasks/fsl"] [tool.black] -line-length = 99 -target-version = ['py37'] -skip-string-normalization = true -extend-exclude = '_version.py|versioneer.py' +target-version = ["py38"] +exclude = "_version.py" + +[tool.codespell] +ignore-words = ".codespell-ignorewords" + +[tool.flake8] +doctests = true +per-file-ignores = [ + "__init__.py:F401,F403" +] +max-line-length = 88 +select = "C,E,F,W,B,B950" +extend-ignore = ['E203', 'E501', 'E129', 'W503'] diff --git a/related-packages/conftest.py b/related-packages/conftest.py new file mode 100644 index 0000000..2a703c0 --- /dev/null +++ b/related-packages/conftest.py @@ -0,0 +1,37 @@ +import os +import logging +from pathlib import Path +import tempfile +import pytest + +# Set DEBUG logging for unittests + +log_level = logging.WARNING + +logger = logging.getLogger("fileformats") +logger.setLevel(log_level) + +sch = logging.StreamHandler() +sch.setLevel(log_level) +formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s") +sch.setFormatter(formatter) +logger.addHandler(sch) + + +# For debugging in IDE's don't catch raised exceptions and let the IDE +# break at it +if os.getenv("_PYTEST_RAISE", "0") != "0": + + @pytest.hookimpl(tryfirst=True) + def pytest_exception_interact(call): + raise call.excinfo.value + + @pytest.hookimpl(tryfirst=True) + def pytest_internalerror(excinfo): + raise excinfo.value + + +@pytest.fixture +def work_dir(): + work_dir = tempfile.mkdtemp() + return Path(work_dir) diff --git a/related-packages/fileformats-extras/LICENSE b/related-packages/fileformats-extras/LICENSE new file mode 100644 index 0000000..e00bcb3 --- /dev/null +++ b/related-packages/fileformats-extras/LICENSE @@ -0,0 +1,13 @@ + Copyright 2021 Nipype developers + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/related-packages/fileformats-extras/README.rst b/related-packages/fileformats-extras/README.rst new file mode 100644 index 0000000..56cb579 --- /dev/null +++ b/related-packages/fileformats-extras/README.rst @@ -0,0 +1,29 @@ +FileFormats-fsl Extras +====================================== +.. image:: https://github.com/nipype/pydra-freesurfer/actions/workflows/ci-cd.yaml/badge.svg + :target: https://github.com/nipype/pydra-freesurfer/actions/workflows/ci-cd.yaml + + +This is a extras module for the `fileformats-fsl `__ +fileformats extension package, which provides additional functionality to format classes (i.e. aside +from basic identification and validation), such as conversion tools, metadata parsers, test data generators, etc... + + +Quick Installation +------------------ + +This extension can be installed for Python 3 using *pip*:: + + $ pip3 install fileformats-fsl-extras + +This will install the core package and any other dependencies + +License +------- + +This work is licensed under a +`Creative Commons Attribution 4.0 International License `_ + +.. image:: https://i.creativecommons.org/l/by/4.0/88x31.png + :target: http://creativecommons.org/licenses/by/4.0/ + :alt: Creative Commons Attribution 4.0 International License diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py new file mode 100644 index 0000000..5ee470b --- /dev/null +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py @@ -0,0 +1,13 @@ +from pathlib import Path +import typing as ty +from random import Random +from fileformats.core import FileSet +from fileformats.medimage_fsl import ( + Con, +) + + + +@FileSet.generate_sample_data.register +def gen_sample_con_data(con: Con, dest_dir: Path, seed: ty.Union[int, Random], stem: ty.Optional[str]): + raise NotImplementedError diff --git a/related-packages/fileformats-extras/pyproject.toml b/related-packages/fileformats-extras/pyproject.toml new file mode 100644 index 0000000..d35d999 --- /dev/null +++ b/related-packages/fileformats-extras/pyproject.toml @@ -0,0 +1,87 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "fileformats-medimage-fsl-extras" +description = "Extensions to add functionality to tool-specific *fileformats* classes" +readme = "README.rst" +requires-python = ">=3.8" +dependencies = [ + "fileformats >= 0.7", + "fileformats-medimage-fsl", + "pydra >= 0.22.0" +] +license = {file = "LICENSE"} +authors = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +maintainers = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +keywords = [ + "file formats", + "data", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", +] +dynamic = ["version"] + +[project.optional-dependencies] +dev = [ + "black", + "pre-commit", + "codespell", + "flake8", + "flake8-pyproject", +] +test = [ + "pytest >=6.2.5", + "pytest-env>=0.6.2", + "pytest-cov>=2.12.1", + "codecov", +] + +converters = [ +] + +[project.urls] +repository = "https://github.com/nipype/pydra-fsl" + +[tool.hatch.version] +source = "vcs" +raw-options = { root = "../.." } + +[tool.hatch.build.hooks.vcs] +version-file = "fileformats/extras/medimage_fsl/_version.py" + +[tool.hatch.build.targets.wheel] +packages = ["fileformats"] + +[tool.black] +target-version = ['py38'] +exclude = "fileformats/extras/medimage_fsl/_version.py" + +[tool.codespell] +ignore-words = ".codespell-ignorewords" + +[tool.flake8] +doctests = true +per-file-ignores = [ + "__init__.py:F401" +] +max-line-length = 88 +select = "C,E,F,W,B,B950" +extend-ignore = ['E203', 'E501', 'E129'] diff --git a/related-packages/fileformats/LICENSE b/related-packages/fileformats/LICENSE new file mode 100644 index 0000000..e00bcb3 --- /dev/null +++ b/related-packages/fileformats/LICENSE @@ -0,0 +1,13 @@ + Copyright 2021 Nipype developers + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/related-packages/fileformats/README.rst b/related-packages/fileformats/README.rst new file mode 100644 index 0000000..99ef16e --- /dev/null +++ b/related-packages/fileformats/README.rst @@ -0,0 +1,39 @@ +How to customise this template +============================== + +#. Rename the `related-packages/fileformats/fsl` directory to the name of the fileformats subpackage (e.g. `medimage_fsl`) +#. Search and replace "fsl" with the name of the fileformats subpackage the extras are to be added +#. Replace name + email placeholders in `pyproject.toml` for developers and maintainers +#. Add the extension file-format classes +#. Ensure that all the extension file-format classes are imported into the extras package root, i.e. `fileformats/fsl` +#. Delete these instructions + +... + +FileFormats Extension - fsl +==================================== +.. image:: https://github.com/nipype/pydra-fsl/actions/workflows/ci-cd.yml/badge.svg + :target: https://github.com/nipype/pydra-fsl/actions/workflows/ci-cd.yml + +This is the "fsl" extension module for the +`fileformats `__ package + + +Quick Installation +------------------ + +This extension can be installed for Python 3 using *pip*:: + + $ pip3 install fileformats-fsl + +This will install the core package and any other dependencies + +License +------- + +This work is licensed under a +`Creative Commons Attribution 4.0 International License `_ + +.. image:: https://i.creativecommons.org/l/by/4.0/88x31.png + :target: http://creativecommons.org/licenses/by/4.0/ + :alt: Creative Commons Attribution 4.0 International License diff --git a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py new file mode 100644 index 0000000..d6ea01b --- /dev/null +++ b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py @@ -0,0 +1,5 @@ +from fileformats.generic import File + +class Con(File): + ext = ".con" + binary = True diff --git a/related-packages/fileformats/pyproject.toml b/related-packages/fileformats/pyproject.toml new file mode 100644 index 0000000..13156ca --- /dev/null +++ b/related-packages/fileformats/pyproject.toml @@ -0,0 +1,84 @@ +[build-system] +requires = ["hatchling", "hatch-vcs"] +build-backend = "hatchling.build" + +[project] +name = "fileformats-medimage-fsl" +description = "Classes for representing different file formats in Python classes for use in type hinting in data workflows" +readme = "README.rst" +requires-python = ">=3.8" +dependencies = [ + "fileformats >= 0.4", + "fileformats-medimage > = 0.2" +] +license = {file = "LICENSE"} +authors = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +maintainers = [ + {name = "Thomas G. Close", email = "tom.g.close@gmail.com"}, +] +keywords = [ + "file formats", + "data", +] +classifiers = [ + "Development Status :: 3 - Alpha", + "Environment :: Console", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: MacOS :: MacOS X", + "Operating System :: Microsoft :: Windows", + "Operating System :: POSIX :: Linux", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", +] +dynamic = ["version"] + +[project.optional-dependencies] +dev = [ + "black", + "pre-commit", + "codespell", + "flake8", + "flake8-pyproject", +] +test = [ + "pytest >=6.2.5", + "pytest-env>=0.6.2", + "pytest-cov>=2.12.1", + "codecov", + "fileformats-medimage-CHANGME-extras", +] + +[project.urls] +repository = "https://github.com/nipype/pydra-fsl" + +[tool.hatch.version] +source = "vcs" +raw-options = { root = "../.." } + +[tool.hatch.build.hooks.vcs] +version-file = "fileformats/medimage_fsl/_version.py" + +[tool.hatch.build.targets.wheel] +packages = ["fileformats"] + +[tool.black] +target-version = ['py38'] +exclude = "fileformats/medimage_fsl/_version.py" + +[tool.codespell] +ignore-words = ".codespell-ignorewords" + +[tool.flake8] +doctests = true +per-file-ignores = [ + "__init__.py:F401" +] +max-line-length = 88 +select = "C,E,F,W,B,B950" +extend-ignore = ['E203', 'E501', 'E129'] From f7c4f262168c4dcf2bbd73625deff56e3933df03 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Wed, 22 Nov 2023 17:23:57 +1100 Subject: [PATCH 002/224] cleaned up yaml files --- nipype-auto-conv/specs/fnirt.yaml | 3 ++- nipype-auto-conv/specs/smm.yaml | 2 +- .../fileformats/extras/medimage_fsl/_version.py | 16 ++++++++++++++++ .../fileformats/medimage_fsl/_version.py | 16 ++++++++++++++++ related-packages/fileformats/pyproject.toml | 2 +- 5 files changed, 36 insertions(+), 3 deletions(-) create mode 100644 related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py create mode 100644 related-packages/fileformats/fileformats/medimage_fsl/_version.py diff --git a/nipype-auto-conv/specs/fnirt.yaml b/nipype-auto-conv/specs/fnirt.yaml index 67b04cc..cca2254 100644 --- a/nipype-auto-conv/specs/fnirt.yaml +++ b/nipype-auto-conv/specs/fnirt.yaml @@ -226,7 +226,8 @@ tests: # (if not specified, will try to choose a sensible value) in_fwhm: '[8, 4, 2, 2]' # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] - subsampling_scheme: '[4, 2, 1, 1] Specify the resolution of the warps >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6)' + subsampling_scheme: '[4, 2, 1, 1]' + warp_resolution: '(6, 6, 6)' # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] imports: &id001 # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item diff --git a/nipype-auto-conv/specs/smm.yaml b/nipype-auto-conv/specs/smm.yaml index f1d229b..1f19c69 100644 --- a/nipype-auto-conv/specs/smm.yaml +++ b/nipype-auto-conv/specs/smm.yaml @@ -42,7 +42,7 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - _p_map: generic/file + _p_map: generic/file activation_p_map: generic/file # type=file: deactivation_p_map: generic/file diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py new file mode 100644 index 0000000..accac60 --- /dev/null +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py @@ -0,0 +1,16 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '0.1.dev228+g48cd321.d20231122' +__version_tuple__ = version_tuple = (0, 1, 'dev228', 'g48cd321.d20231122') diff --git a/related-packages/fileformats/fileformats/medimage_fsl/_version.py b/related-packages/fileformats/fileformats/medimage_fsl/_version.py new file mode 100644 index 0000000..accac60 --- /dev/null +++ b/related-packages/fileformats/fileformats/medimage_fsl/_version.py @@ -0,0 +1,16 @@ +# file generated by setuptools_scm +# don't change, don't track in version control +TYPE_CHECKING = False +if TYPE_CHECKING: + from typing import Tuple, Union + VERSION_TUPLE = Tuple[Union[int, str], ...] +else: + VERSION_TUPLE = object + +version: str +__version__: str +__version_tuple__: VERSION_TUPLE +version_tuple: VERSION_TUPLE + +__version__ = version = '0.1.dev228+g48cd321.d20231122' +__version_tuple__ = version_tuple = (0, 1, 'dev228', 'g48cd321.d20231122') diff --git a/related-packages/fileformats/pyproject.toml b/related-packages/fileformats/pyproject.toml index 13156ca..b36b6b6 100644 --- a/related-packages/fileformats/pyproject.toml +++ b/related-packages/fileformats/pyproject.toml @@ -9,7 +9,7 @@ readme = "README.rst" requires-python = ">=3.8" dependencies = [ "fileformats >= 0.4", - "fileformats-medimage > = 0.2" + "fileformats-medimage >= 0.2" ] license = {file = "LICENSE"} authors = [ From ce5a3e32c17a1f15659f7e3765f7f5ec3ea8b62d Mon Sep 17 00:00:00 2001 From: Tom Close Date: Wed, 20 Dec 2023 17:37:49 +1100 Subject: [PATCH 003/224] cleaned up fileformats extras --- .../extras/medimage_fsl/__init__.py | 2 +- tools/__init__.py | 0 tools/converter.py | 607 ------------------ tools/data_tests/test.nii.gz | 3 - tools/tests/test_converter.py | 92 --- 5 files changed, 1 insertion(+), 703 deletions(-) delete mode 100644 tools/__init__.py delete mode 100644 tools/converter.py delete mode 100644 tools/data_tests/test.nii.gz delete mode 100644 tools/tests/test_converter.py diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py index 5ee470b..d96e129 100644 --- a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py @@ -9,5 +9,5 @@ @FileSet.generate_sample_data.register -def gen_sample_con_data(con: Con, dest_dir: Path, seed: ty.Union[int, Random], stem: ty.Optional[str]): +def gen_sample_con_data(con: Con, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None) -> ty.Iterable[Path]: raise NotImplementedError diff --git a/tools/__init__.py b/tools/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tools/converter.py b/tools/converter.py deleted file mode 100644 index eca5cc1..0000000 --- a/tools/converter.py +++ /dev/null @@ -1,607 +0,0 @@ -from attr import has -from ast import literal_eval -from nipype.interfaces import fsl -from nipype.interfaces.base import traits_extension -from pydra.engine import specs -from pydra.engine.helpers import ensure_list - -import os, sys, yaml, black, imp -import traits -from pathlib import Path -import typing as ty -import inspect -import click -import warnings -import functools - -sys.path.append(str(Path(__file__).resolve().parent.parent / 'specs')) -import callables - - -class FSLConverter: - INPUT_KEYS = [ - "allowed_values", - "argstr", - "container_path", - "copyfile", - "desc", - "mandatory", - "position", - "requires", - "sep", - "xor", - ] - OUTPUT_KEYS = ["desc"] - NAME_MAPPING = {"desc": "help_string"} - - TRAITS_IRREL = [ - 'output_type', - 'args', - 'environ', - 'environ_items', - '__all__', - 'trait_added', - 'trait_modified', - ] - - TYPE_REPLACE = [ - ("\'File\'", "specs.File"), - ("\'bool\'", "bool"), - ("\'str\'", "str"), - ("\'Any\'", "ty.Any"), - ("\'int\'", "int"), - ("\'float\'", "float"), - ("\'list\'", "list"), - ("\'dict\'", "dict"), - ("\'MultiInputObj\'", "specs.MultiInputObj"), - ("\'MultiOutputObj\'", "specs.MultiOutputObj"), - ("\'MultiInputFile\'", "specs.MultiInputFile"), - ("\'MultiOutputFile\'", "specs.MultiOutputFile"), - ] - - def __init__(self, interface_name, interface_spec_file): - self.interface_name = interface_name - with interface_spec_file.open() as f: - self.interface_spec = yaml.safe_load(f)[self.interface_name] - if self.interface_spec.get("output_requirements") is None: - self.interface_spec["output_requirements"] = [] - if self.interface_spec.get("inputs_metadata") is None: - self.interface_spec["inputs_metadata"] = {} - if self.interface_spec.get("inputs_drop") is None: - self.interface_spec["inputs_drop"] = [] - if self.interface_spec.get("output_templates") is None: - self.interface_spec["output_templates"] = {} - if self.interface_spec.get("output_callables") is None: - self.interface_spec["output_callables"] = {} - if ( - not self.interface_spec["output_callables"] - .keys() - .isdisjoint(self.interface_spec["output_templates"].keys()) - ): - raise Exception("output_callables and output_templates have the same keys") - if self.interface_spec.get("doctest") is None: - self.interface_spec["doctest"] = {} - - # getting input/output spec from nipype - nipype_interface = getattr(fsl, self.interface_name) - self.cmd = nipype_interface._cmd - self.nipype_input_spec = nipype_interface.input_spec() - self.nipype_output_spec = nipype_interface.output_spec() - - def pydra_specs(self, write=False, dirname=None): - """creating pydra input/output spec from nipype specs - if write is True, a pydra Task class will be written to the file together with tests - """ - input_fields_pdr, inp_templates = self.convert_input_fields() - output_fields_pdr = self.convert_output_spec(fields_from_template=inp_templates) - - input_spec_pydra = specs.SpecInfo( - name="Input", fields=input_fields_pdr, bases=(specs.ShellSpec,) - ) - output_spec_pydra = specs.SpecInfo( - name="Output", fields=output_fields_pdr, bases=(specs.ShellOutSpec,) - ) - - if write: - if dirname is None: - raise Exception("dirname has to be provided if write is True") - self.write_pydra_files( - dirname=dirname, - pydra_input_spec=input_fields_pdr, - pydra_output_spec=output_fields_pdr, - ) - return input_spec_pydra, output_spec_pydra - - def write_pydra_files(self, dirname, pydra_input_spec, pydra_output_spec): - """writing pydra task and tests to the files""" - testdir = dirname / "tests" - testdir.mkdir(parents=True, exist_ok=True) - Path.touch(dirname / "__init__.py") - Path.touch(testdir / "__init__.py") - filename = dirname / f"{self.interface_name.lower()}.py" - filename_test = testdir / f"test_spec_{filename.name}" - filename_test_run = testdir / f"test_run_{filename.name}" - - print("\n FILENAME", filename) - self.write_task(filename, pydra_input_spec, pydra_output_spec) - - self.write_test(filename_test=filename_test) - self.write_test(filename_test=filename_test_run, run=True) - - def write_task(self, filename, input_fields, output_fields): - """writing pydra task to the dile based on the input and output spec""" - - def types_to_names(spec_fields): - spec_fields_str = [] - for el in spec_fields: - el = list(el) - try: - el[1] = el[1].__name__ - except AttributeError: - el[1] = el[1]._name - spec_fields_str.append(tuple(el)) - return spec_fields_str - - input_fields_str = types_to_names(spec_fields=input_fields) - output_fields_str = types_to_names(spec_fields=output_fields) - functions_str = self.function_callables() - spec_str = "from pydra.engine import specs \nfrom pydra import ShellCommandTask \n" - spec_str += f"import typing as ty\n" - spec_str += functions_str - spec_str += f"input_fields = {input_fields_str}\n" - spec_str += f"{self.interface_name}_input_spec = specs.SpecInfo(name='Input', fields=input_fields, bases=(specs.ShellSpec,))\n\n" - spec_str += f"output_fields = {output_fields_str}\n" - spec_str += f"{self.interface_name}_output_spec = specs.SpecInfo(name='Output', fields=output_fields, bases=(specs.ShellOutSpec,))\n\n" - - spec_str += f"class {self.interface_name}(ShellCommandTask):\n" - if self.interface_spec["doctest"]: - spec_str += self.create_doctest() - spec_str += f" input_spec = {self.interface_name}_input_spec\n" - spec_str += f" output_spec = {self.interface_name}_output_spec\n" - spec_str += f" executable='{self.cmd}'\n" - - for tp_repl in self.TYPE_REPLACE: - spec_str = spec_str.replace(*tp_repl) - - spec_str_black = black.format_file_contents(spec_str, fast=False, mode=black.FileMode()) - - with open(filename, "w") as f: - f.write(spec_str_black) - - def write_test(self, filename_test, run=False): - """writing tests for the specific interface based on the test spec (from interface_spec) - if run is True the test contains task run, - if run is False only the spec is check by the test - """ - tests_inputs = self.interface_spec["tests_inputs"] - tests_outputs = self.interface_spec["tests_outputs"] - if len(tests_inputs) != len(tests_outputs): - raise Exception("tests and tests_outputs should have the same length") - - tests_inp_outp = [] - tests_inp_error = [] - for i, out in enumerate(tests_outputs): - if isinstance(out, list): - tests_inp_outp.append((tests_inputs[i], out)) - elif out is None: - tests_inp_outp.append((tests_inputs[i], [])) - # allowing for incomplete or incorrect inputs that should raise an exception - elif out not in ["AttributeError", "Exception"]: - tests_inp_outp.append((tests_inputs[i], [out])) - else: - tests_inp_error.append((tests_inputs[i], out)) - - spec_str = f"import re, os, shutil, pytest \nfrom pathlib import Path\n" - spec_str += f"from ..{self.interface_name.lower()} import {self.interface_name} \n\n" - if run: - spec_str += ( - "@pytest.mark.xfail('FSLDIR' not in os.environ, reason='no FSL found', " - "raises=FileNotFoundError)\n" - ) - spec_str += f"@pytest.mark.parametrize('inputs, outputs', {tests_inp_outp})\n" - spec_str += f"def test_{self.interface_name}(test_data, inputs, outputs):\n" - spec_str += f" if inputs is None:\n" - spec_str += f" in_file = Path(test_data) / 'test.nii.gz'\n" - spec_str += f" task = {self.interface_name}(in_file=in_file)\n" - spec_str += f" else:\n" - spec_str += f" for key, val in inputs.items():\n" - spec_str += f" try: \n" - spec_str += f" pattern = r'\.[a-zA-Z]*'\n" - spec_str += f" if isinstance(val, str):\n" - spec_str += f" if re.findall(pattern, val) != []:\n" - spec_str += f" inputs[key] = Path(test_data) / val\n" - spec_str += f" elif '_dir' in key:\n" - spec_str += f" dirpath = Path(test_data) / val\n" - spec_str += f" if dirpath.exists() and dirpath.is_dir():\n" - spec_str += f" shutil.rmtree(dirpath)\n" - spec_str += f" inputs[key] = Path(test_data) / val\n" - spec_str += f" else: inputs[key] = eval(val)\n" - spec_str += f" elif isinstance(val, list):\n" - spec_str += f" if all (re.findall(pattern, _) != [] for _ in val):\n" - spec_str += f" inputs[key] = [Path(test_data)/_ for _ in val] \n" - spec_str += f" else: inputs[key] = eval(val)\n" - spec_str += f" except: pass\n" - spec_str += f" task = {self.interface_name}(**inputs)\n" - spec_str += ( - f" assert set(task.generated_output_names) == " - f"set(['return_code', 'stdout', 'stderr'] + outputs)\n" - ) - - if run: - spec_str += f" res = task()\n" - spec_str += f" print('RESULT: ', res)\n" - spec_str += f" for out_nm in outputs:\n" - spec_str += f" if isinstance(getattr(res.output, out_nm), list): assert [os.path.exists(x) for x in getattr(res.output, out_nm)]\n" - spec_str += f" else: assert os.path.exists(getattr(res.output, out_nm))\n" - - # if test_inp_error is not empty, than additional test function will be created - if tests_inp_error: - spec_str += self.write_test_error(input_error=tests_inp_error) - - spec_str_black = black.format_file_contents(spec_str, fast=False, mode=black.FileMode()) - - with open(filename_test, "w") as f: - f.write(spec_str_black) - - def write_test_error(self, input_error): - """creating a tests for incorrect or incomplete inputs - checking if the exceptions are raised - """ - spec_str = "\n\n" - spec_str += f"@pytest.mark.parametrize('inputs, error', {input_error})\n" - spec_str += f"def test_{self.interface_name}_exception(test_data, inputs, error):\n" - spec_str += f" if inputs is None:\n" - spec_str += f" in_file = Path(test_data) / 'test.nii.gz'\n" - spec_str += f" task = {self.interface_name}(in_file=in_file)\n" - spec_str += f" else:\n" - spec_str += f" for key, val in inputs.items():\n" - spec_str += f" try: \n" - spec_str += f" pattern = r'\.[a-zA-Z]*'\n" - spec_str += f" if isinstance(val, str):\n" - spec_str += f" if re.findall(pattern, val) != []:\n" - spec_str += f" inputs[key] = Path(test_data) / val\n" - spec_str += f" elif '_dir' in key:\n" - spec_str += f" dirpath = Path(test_data) / val\n" - spec_str += f" if dirpath.exists() and dirpath.is_dir():\n" - spec_str += f" shutil.rmtree(dirpath)\n" - spec_str += f" inputs[key] = Path(test_data) / val\n" - spec_str += f" else: inputs[key] = eval(val)\n" - spec_str += f" elif isinstance(val, list):\n" - spec_str += f" if all (re.findall(pattern, _) != [] for _ in val):\n" - spec_str += f" inputs[key] = [Path(test_data)/_ for _ in val] \n" - spec_str += f" else: inputs[key] = eval(val)\n" - spec_str += f" except: pass\n" - spec_str += f" task = {self.interface_name}(**inputs)\n" - spec_str += f" with pytest.raises(eval(error)):\n" - spec_str += f" task.generated_output_names\n" - - return spec_str - - def create_doctest(self): - """adding doctests to the interfaces""" - cmdline = self.interface_spec["doctest"].pop("cmdline") - doctest = ' """\n Example\n -------\n' - doctest += f' >>> task = {self.interface_name}()\n' - for key, val in self.interface_spec["doctest"].items(): - if type(val) is str: - doctest += f' >>> task.inputs.{key} = "{val}"\n' - else: - doctest += f' >>> task.inputs.{key} = {val}\n' - doctest += ' >>> task.cmdline\n' - doctest += f" '{cmdline}'" - doctest += '\n """\n' - return doctest - - def convert_input_fields(self): - """creating fields list for pydra input spec""" - fields_pdr_dict = {} - position_dict = {} - has_template = [] - for name, fld in self.nipype_input_spec.traits().items(): - if name in self.TRAITS_IRREL: - continue - if name in self.interface_spec["inputs_drop"]: - continue - fld_pdr, pos = self.pydra_fld_input(fld, name) - meta_pdr = fld_pdr[-1] - if "output_file_template" in meta_pdr: - has_template.append(name) - fields_pdr_dict[name] = (name,) + fld_pdr - if pos is not None: - position_dict[name] = pos - - fields_pdr_l = list(fields_pdr_dict.values()) - return fields_pdr_l, has_template - - def pydra_fld_input(self, field, nm): - """converting a single nipype field to one element of fields for pydra input_spec""" - tp_pdr = self.pydra_type_converter(field, spec_type="input", name=nm) - if nm in self.interface_spec["inputs_metadata"]: - metadata_extra_spec = self.interface_spec["inputs_metadata"][nm] - else: - metadata_extra_spec = {} - - if "default" in metadata_extra_spec: - default_pdr = metadata_extra_spec.pop("default") - elif getattr(field, "usedefault") and field.default is not traits.ctrait.Undefined: - default_pdr = field.default - else: - default_pdr = None - - metadata_pdr = {"help_string": ""} - for key in self.INPUT_KEYS: - key_nm_pdr = self.NAME_MAPPING.get(key, key) - val = getattr(field, key) - if val is not None: - if key == "argstr" and "%" in val: - val = self.string_formats(argstr=val, name=nm) - metadata_pdr[key_nm_pdr] = val - - if getattr(field, "name_template"): - template = getattr(field, "name_template") - name_source = ensure_list(getattr(field, "name_source")) - - metadata_pdr["output_file_template"] = self.string_formats( - argstr=template, name=name_source[0] - ) - if tp_pdr in [specs.File, specs.Directory]: - tp_pdr = str - elif getattr(field, "genfile"): - if nm in self.interface_spec["output_templates"]: - if isinstance(self.interface_spec["output_templates"][nm], list): - metadata_pdr["output_file_template"] = self.interface_spec["output_templates"][ - nm - ][0] - else: - metadata_pdr["output_file_template"] = self.interface_spec["output_templates"][ - nm - ] - if tp_pdr in [ - specs.File, - specs.Directory, - ]: # since this is a template, the file doesn't exist - tp_pdr = str - elif nm not in self.interface_spec["output_callables"]: - raise Exception( - f"the filed {nm} has genfile=True, but no output template or callables provided" - ) - - metadata_pdr.update(metadata_extra_spec) - - pos = metadata_pdr.get("position", None) - - if default_pdr is not None and not metadata_pdr.get("mandatory", None): - return (tp_pdr, default_pdr, metadata_pdr), pos - else: - return (tp_pdr, metadata_pdr), pos - - def convert_output_spec(self, fields_from_template): - """creating fields list for pydra output spec""" - fields_pdr_l = [] - for name, fld in self.nipype_output_spec.traits().items(): - if ( - name in self.interface_spec["output_requirements"] - and name not in fields_from_template - ): - fld_pdr = self.pydra_fld_output(fld, name) - fields_pdr_l.append((name,) + fld_pdr) - return fields_pdr_l - - def pydra_fld_output(self, field, nm): - """converting a single nipype field to one element of fields for pydra output_spec""" - tp_pdr = self.pydra_type_converter(field, spec_type="output", name=nm) - - metadata_pdr = {} - for key in self.OUTPUT_KEYS: - key_nm_pdr = self.NAME_MAPPING.get(key, key) - val = getattr(field, key) - if val: - metadata_pdr[key_nm_pdr] = val - - if self.interface_spec["output_requirements"][nm]: - if all( - [isinstance(el, list) for el in self.interface_spec["output_requirements"][nm]] - ): - requires_l = self.interface_spec["output_requirements"][nm] - nested_flag = True - elif all( - [ - isinstance(el, (str, dict)) - for el in self.interface_spec["output_requirements"][nm] - ] - ): - requires_l = [self.interface_spec["output_requirements"][nm]] - nested_flag = False - else: - Exception("has to be either list of list or list of str/dict") - - metadata_pdr["requires"] = [] - for requires in requires_l: - requires_mod = [] - for el in requires: - if isinstance(el, str): - requires_mod.append(el) - elif isinstance(el, dict): - requires_mod += list(el.items()) - metadata_pdr["requires"].append(requires_mod) - if nested_flag is False: - metadata_pdr["requires"] = metadata_pdr["requires"][0] - - if nm in self.interface_spec["output_templates"]: - if isinstance(self.interface_spec["output_templates"][nm], list): - metadata_pdr["output_file_template"] = self.interface_spec["output_templates"][nm][ - 0 - ] - else: - metadata_pdr["output_file_template"] = self.interface_spec["output_templates"][nm] - elif nm in self.interface_spec["output_callables"]: - metadata_pdr["callable"] = self.interface_spec["output_callables"][nm] - return (tp_pdr, metadata_pdr) - - def function_callables(self): - fun_names = [] - if not self.interface_spec["output_callables"]: - if self.interface_spec["output_templates"]: - tmpls = list(self.interface_spec["output_templates"].values()) - for tmpl in tmpls: - if isinstance(tmpl, list): - fun_names.append(tmpl[0]) - if len(fun_names) < 1: - pass - python_functions_spec = Path(os.path.dirname(__file__)) / "../specs/callables.py" - if not python_functions_spec.exists(): - raise Exception( - "specs/callables.py file is needed if functions are used in the spec files" - ) - - fun_names.extend(list(set(self.interface_spec["output_callables"].values()))) - fun_names.sort() - fun_str = "" - for fun_nm in fun_names: - fun = getattr(callables, fun_nm) - fun_str += inspect.getsource(fun) + "\n" - return fun_str - - def pydra_type_converter(self, field, spec_type, name): - """converting types to types used in pydra""" - if spec_type not in ["input", "output"]: - raise Exception(f"spec_type has to be input or output, but {spec_type} provided") - tp = field.trait_type - if isinstance(tp, traits.trait_types.Int): - tp_pdr = int - elif isinstance(tp, traits.trait_types.Float): - tp_pdr = float - elif isinstance(tp, traits.trait_types.Str): - tp_pdr = str - elif isinstance(tp, traits.trait_types.Bool): - tp_pdr = bool - elif isinstance(tp, traits.trait_types.Dict): - tp_pdr = dict - elif isinstance(tp, traits_extension.InputMultiObject): - if isinstance(field.inner_traits[0].trait_type, traits_extension.File): - tp_pdr = specs.MultiInputFile - else: - tp_pdr = specs.MultiInputObj - elif isinstance(tp, traits_extension.OutputMultiObject): - if isinstance(field.inner_traits[0].trait_type, traits_extension.File): - tp_pdr = specs.MultiOutputFile - else: - tp_pdr = specs.MultiOutputObj - elif isinstance(tp, traits_extension.InputMultiPath): - if isinstance(field.inner_traits[0].trait_type, traits_extension.File): - tp_pdr = specs.MultiInputFile - else: - tp_pdr = specs.MultiInputObj - elif isinstance(tp, traits_extension.OutputMultiPath): - if isinstance(field.inner_traits[0].trait_type, traits_extension.File): - tp_pdr = specs.MultiOutputFile - else: - tp_pdr = specs.MultiOutputObj - elif isinstance(tp, traits.trait_types.List): - if isinstance(field.inner_traits[0].trait_type, traits_extension.File): - if spec_type == "input": - tp_pdr = specs.MultiInputFile - else: - tp_pdr = specs.MultiOutputFile - else: - tp_pdr = list - elif isinstance(tp, traits_extension.File): - if ( - spec_type == "output" or tp.exists is True - ): # TODO check the hash_file metadata in nipype - tp_pdr = specs.File - else: - tp_pdr = str - else: - tp_pdr = ty.Any - return tp_pdr - - def string_formats(self, argstr, name): - import re - - if "%s" in argstr: - argstr_new = argstr.replace("%s", f"{{{name}}}") - elif "%d" in argstr: - argstr_new = argstr.replace("%d", f"{{{name}}}") - elif "%f" in argstr: - argstr_new = argstr.replace("%f", f"{{{name}}}") - elif "%g" in argstr: - argstr_new = argstr.replace("%g", f"{{{name}}}") - elif len(re.findall("%[0-9.]+f", argstr)) == 1: - old_format = re.findall("%[0-9.]+f", argstr)[0] - argstr_new = argstr.replace(old_format, f"{{{name}:{old_format[1:]}}}") - else: - raise Exception(f"format from {argstr} is not supported TODO") - return argstr_new - - -FSL_MODULES = ['aroma', 'dti', 'epi', 'fix', 'maths', 'model', 'possum', 'preprocess', 'utils'] - - -@click.command() -@click.option( - "-i", - "--interface_name", - required=True, - default="all", - help="name of the interface (name used in Nipype, e.g. BET) or all (default)" - "if all is used all interfaces from the spec file will be created", -) -@click.option( - "-m", "--module_name", required=True, help=f"name of the module from the list {FSL_MODULES}" -) -def create_pydra_spec(interface_name, module_name): - if module_name not in FSL_MODULES: - raise Exception( - f"module name {module_name} not available;" f"should be from the list {FSL_MODULES}" - ) - - spec_file = Path(os.path.dirname(__file__)) / f"../specs/fsl_{module_name}_param.yml" - if not spec_file.exists(): - raise Exception( - f"the specification file doesn't exist for the module {module_name}," - f"create the specification file in {spec_file.parent}" - ) - - @functools.lru_cache() - def all_interfaces(module): - nipype_module = getattr(fsl, module) - all_specs = [el for el in dir(nipype_module) if "InputSpec" in el] - all_interf = [el.replace("InputSpec", "") for el in all_specs] - - # interfaces in the spec file - with open(spec_file) as f: - spec_interf = yaml.safe_load(f).keys() - - if set(all_interf) - set(spec_interf): - warnings.warn( - f"some interfaces are not in the spec file: " - f"{set(all_interf) - set(spec_interf)}, " - f"and pydra interfaces will not be created for them" - ) - return spec_interf - - if interface_name == "all": - interface_list = all_interfaces(module_name) - elif interface_name in all_interfaces(module_name): - interface_list = [interface_name] - else: - raise Exception( - f"interface_name has to be 'all' " - f"or a name from the list {all_interfaces(module_name)}" - ) - - dirname_interf = Path(__file__).parent.parent / f"pydra/tasks/fsl/{module_name}" - dirname_interf.mkdir(exist_ok=True) - - for interface_el in interface_list: - converter = FSLConverter( - interface_name=interface_el, - interface_spec_file=Path(__file__).parent.parent - / f"specs/fsl_{module_name}_param.yml", - ) - converter.pydra_specs(write=True, dirname=dirname_interf) - - -if __name__ == '__main__': - create_pydra_spec() diff --git a/tools/data_tests/test.nii.gz b/tools/data_tests/test.nii.gz deleted file mode 100644 index 3424c44..0000000 --- a/tools/data_tests/test.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ffd0a1a4abf91c63edb64a7add1978e1d990a8bf2fbc057fd93d2367f335c9d4 -size 10379696 diff --git a/tools/tests/test_converter.py b/tools/tests/test_converter.py deleted file mode 100644 index 0444726..0000000 --- a/tools/tests/test_converter.py +++ /dev/null @@ -1,92 +0,0 @@ -import pytest -import pydra -import os, imp -from pathlib import Path - -from ..converter import FSLConverter - -# TODO: rethink teh tests - - -@pytest.mark.skip() -def test_spec(tmpdir): - interface_name = "BET" - converter = FSLConverter(interface_name=interface_name) - input_spec_pydra, output_spec_pydra = converter.pydra_specs() - - in_file = Path(os.path.dirname(__file__)) / "data_tests/test.nii.gz" - out_file = Path(os.path.dirname(__file__)) / "data_tests/test_brain.nii.gz" - cmd = "bet" - - shelly = pydra.ShellCommandTask( - name="bet_task", executable=cmd, input_spec=input_spec_pydra, output_spec=output_spec_pydra - ) - shelly.inputs.in_file = in_file - assert shelly.inputs.executable == "bet" - assert shelly.cmdline == f"bet {in_file} {str(shelly.output_dir / 'test_brain.nii.gz')}" - res = shelly() - assert res.output.out_file.exists() - print("\n Result: ", res) - - shelly_mask = pydra.ShellCommandTask( - name="bet_task", executable=cmd, input_spec=input_spec_pydra, output_spec=output_spec_pydra - ) - shelly_mask.inputs.in_file = in_file - shelly_mask.inputs.mask = True - assert ( - shelly_mask.cmdline - == f"bet {in_file} {str(shelly_mask.output_dir / 'test_brain.nii.gz')} -m" - ) - res = shelly_mask() - assert res.output.out_file.exists() - assert res.output.mask_file.exists() - print("\n Result: ", res) - - -@pytest.mark.skip() -def test_spec_from_file(tmpdir): - interface_name = "BET" - converter = FSLConverter(interface_name=interface_name) - - dirname_spec = Path(tmpdir) - (dirname_spec / "tests").mkdir() - - _, _ = converter.pydra_specs(write=True, dirname=dirname_spec) - - imp.load_source("bet_module", str(dirname_spec / "bet.py")) - import bet_module as bm - - in_file = Path(os.path.dirname(__file__)) / "data_tests/test.nii.gz" - - shelly = bm.BET(name="my_bet") - shelly.inputs.in_file = in_file - assert shelly.inputs.executable == "bet" - assert shelly.cmdline == f"bet {in_file} {str(shelly.output_dir / 'test_brain.nii.gz')}" - res = shelly() - assert res.output.out_file.exists() - print("\n Result: ", res) - - shelly_mask = bm.BET(name="my_bet") - shelly_mask.inputs.in_file = in_file - shelly_mask.inputs.mask = True - assert ( - shelly_mask.cmdline - == f"bet {in_file} {str(shelly_mask.output_dir / 'test_brain.nii.gz')} -m" - ) - res = shelly_mask() - assert res.output.out_file.exists() - assert res.output.mask_file.exists() - print("\n Result: ", res) - - shelly_surf = bm.BET(name="my_bet") - shelly_surf.inputs.in_file = in_file - shelly_surf.inputs.surfaces = True - assert ( - shelly_surf.cmdline - == f"bet {in_file} {str(shelly_surf.output_dir / 'test_brain.nii.gz')} -A" - ) - res = shelly_surf() - assert res.output.out_file.exists() - assert res.output.inskull_mask_file.exists() - assert res.output.skull_mask_file.exists() - print("\n Result: ", res) From fe79dd0c155e2e4113e3f1897d35946e0d1e2080 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Wed, 10 Jan 2024 16:17:17 +1100 Subject: [PATCH 004/224] updated with latest generation of auto-gen yaml files --- nipype-auto-conv/specs/accuracy_tester.yaml | 10 ++- nipype-auto-conv/specs/bedpostx5.yaml | 4 + nipype-auto-conv/specs/classifier.yaml | 2 + nipype-auto-conv/specs/dual_regression.yaml | 3 + nipype-auto-conv/specs/feat.yaml | 2 + nipype-auto-conv/specs/feat_register.yaml | 74 ------------------- .../specs/feat_register_callables.py | 1 - nipype-auto-conv/specs/feature_extractor.yaml | 6 ++ nipype-auto-conv/specs/filmgls.yaml | 6 ++ nipype-auto-conv/specs/flameo.yaml | 4 + nipype-auto-conv/specs/fnirt.yaml | 7 +- nipype-auto-conv/specs/fslx_command.yaml | 2 + nipype-auto-conv/specs/ica__aroma.yaml | 10 +++ nipype-auto-conv/specs/melodic.yaml | 5 ++ nipype-auto-conv/specs/topup.yaml | 2 - nipype-auto-conv/specs/training.yaml | 2 +- .../specs/training_set_creator.yaml | 2 +- nipype-auto-conv/specs/x_fibres_5.yaml | 2 + 18 files changed, 61 insertions(+), 83 deletions(-) delete mode 100644 nipype-auto-conv/specs/feat_register.yaml delete mode 100644 nipype-auto-conv/specs/feat_register_callables.py diff --git a/nipype-auto-conv/specs/accuracy_tester.yaml b/nipype-auto-conv/specs/accuracy_tester.yaml index fb17bf4..a900f0c 100644 --- a/nipype-auto-conv/specs/accuracy_tester.yaml +++ b/nipype-auto-conv/specs/accuracy_tester.yaml @@ -23,10 +23,13 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mel_icas: generic/file+list-of - # type=inputmultiobject|default=[]: Melodic output directories trained_wts_file: generic/file # type=file|default=: trained-weights file + mel_icas: generic/directory+list-of + # type=inputmultiobject|default=[]: Melodic output directories + output_directory: generic/directory + # type=directory: Path to folder in which to store the results of the accuracy test. + # type=directory|default=: Path to folder in which to store the results of the accuracy test. metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -40,6 +43,9 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + output_directory: generic/directory + # type=directory: Path to folder in which to store the results of the accuracy test. + # type=directory|default=: Path to folder in which to store the results of the accuracy test. callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/bedpostx5.yaml b/nipype-auto-conv/specs/bedpostx5.yaml index 92e9c8b..b25f1b6 100644 --- a/nipype-auto-conv/specs/bedpostx5.yaml +++ b/nipype-auto-conv/specs/bedpostx5.yaml @@ -53,6 +53,10 @@ inputs: # type=file|default=: b values file grad_dev: generic/file # type=file|default=: grad_dev file, if gradnonlin, -g is True + logdir: generic/directory + # type=directory|default=: + out_dir: generic/directory + # type=directory|default='bedpostx': output directory metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: diff --git a/nipype-auto-conv/specs/classifier.yaml b/nipype-auto-conv/specs/classifier.yaml index 3f29445..358635c 100644 --- a/nipype-auto-conv/specs/classifier.yaml +++ b/nipype-auto-conv/specs/classifier.yaml @@ -27,6 +27,8 @@ inputs: artifacts_list_file: generic/file # type=file: Text file listing which ICs are artifacts; can be the output from classification or can be created manually # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually + mel_ica: generic/directory + # type=directory|default=: Melodic output directory or directories metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: diff --git a/nipype-auto-conv/specs/dual_regression.yaml b/nipype-auto-conv/specs/dual_regression.yaml index 6b873a8..3630a78 100644 --- a/nipype-auto-conv/specs/dual_regression.yaml +++ b/nipype-auto-conv/specs/dual_regression.yaml @@ -57,6 +57,9 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_dir: generic/directory + # type=directory: + # type=directory|default='output': This directory will be created to hold all output and logfiles callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/feat.yaml b/nipype-auto-conv/specs/feat.yaml index 94af3ad..3862605 100644 --- a/nipype-auto-conv/specs/feat.yaml +++ b/nipype-auto-conv/specs/feat.yaml @@ -35,6 +35,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + feat_dir: generic/directory + # type=directory: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/feat_register.yaml b/nipype-auto-conv/specs/feat_register.yaml deleted file mode 100644 index fadda16..0000000 --- a/nipype-auto-conv/specs/feat_register.yaml +++ /dev/null @@ -1,74 +0,0 @@ -# This file is used to manually specify the semi-automatic conversion of -# 'nipype.interfaces.fsl.model.FEATRegister' from Nipype to Pydra. -# -# Please fill-in/edit the fields below where appropriate -# -# Docs -# ---- -# Register feat directories to a specific standard -task_name: FEATRegister -nipype_name: FEATRegister -nipype_module: nipype.interfaces.fsl.model -inputs: - omit: - # list[str] - fields to omit from the Pydra interface - rename: - # dict[str, str] - fields to rename in the Pydra interface - types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - feat_dirs: generic/file+list-of - # type=inputmultiobject|default=[]: Lower level feat dirs - reg_image: generic/file - # type=file|default=: image to register to (will be treated as standard) - metadata: - # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) -outputs: - omit: - # list[str] - fields to omit from the Pydra interface - rename: - # dict[str, str] - fields to rename in the Pydra interface - types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - fsf_file: generic/file - # type=file: FSL feat specification file - callables: - # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` - # to set to the `callable` attribute of output fields - templates: - # dict[str, str] - `output_file_template` values to be provided to output fields - requirements: - # dict[str, list[str]] - input fields that are required to be provided for the output field to be present -tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - feat_dirs: - # type=inputmultiobject|default=[]: Lower level feat dirs - reg_image: - # type=file|default=: image to register to (will be treated as standard) - reg_dof: - # type=int|default=12: registration degrees of freedom - imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -doctests: [] diff --git a/nipype-auto-conv/specs/feat_register_callables.py b/nipype-auto-conv/specs/feat_register_callables.py deleted file mode 100644 index 8271252..0000000 --- a/nipype-auto-conv/specs/feat_register_callables.py +++ /dev/null @@ -1 +0,0 @@ -"""Module to put any functions that are referred to in FEATRegister.yaml""" diff --git a/nipype-auto-conv/specs/feature_extractor.yaml b/nipype-auto-conv/specs/feature_extractor.yaml index 0e017da..2b83416 100644 --- a/nipype-auto-conv/specs/feature_extractor.yaml +++ b/nipype-auto-conv/specs/feature_extractor.yaml @@ -22,6 +22,9 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + mel_ica: generic/directory + # type=directory: Melodic output directory or directories + # type=directory|default=: Melodic output directory or directories metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -35,6 +38,9 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + mel_ica: generic/directory + # type=directory: Melodic output directory or directories + # type=directory|default=: Melodic output directory or directories callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/filmgls.yaml b/nipype-auto-conv/specs/filmgls.yaml index 2df9dc4..155c8a7 100644 --- a/nipype-auto-conv/specs/filmgls.yaml +++ b/nipype-auto-conv/specs/filmgls.yaml @@ -55,6 +55,9 @@ inputs: # type=file|default=: input data file design_file: generic/file # type=file|default=: design matrix file + results_dir: generic/directory + # type=directory: directory storing model estimation output + # type=directory|default='results': directory to store results in metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -78,6 +81,9 @@ outputs: # type=file: The FILM autocorrelation parameters logfile: generic/file # type=file: FILM run logfile + results_dir: generic/directory + # type=directory: directory storing model estimation output + # type=directory|default='results': directory to store results in callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/flameo.yaml b/nipype-auto-conv/specs/flameo.yaml index b3d3c8d..c7b2cf2 100644 --- a/nipype-auto-conv/specs/flameo.yaml +++ b/nipype-auto-conv/specs/flameo.yaml @@ -55,6 +55,8 @@ inputs: # type=file|default=: ascii matrix specifying f-contrasts cov_split_file: datascience/text-matrix # type=file|default=: ascii matrix specifying the groups the covariance is split into + log_dir: generic/directory + # type=directory|default='stats': metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -68,6 +70,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + stats_dir: generic/directory + # type=directory: directory storing model estimation output callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/fnirt.yaml b/nipype-auto-conv/specs/fnirt.yaml index cca2254..506b06f 100644 --- a/nipype-auto-conv/specs/fnirt.yaml +++ b/nipype-auto-conv/specs/fnirt.yaml @@ -227,8 +227,9 @@ tests: in_fwhm: '[8, 4, 2, 2]' # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] subsampling_scheme: '[4, 2, 1, 1]' - warp_resolution: '(6, 6, 6)' # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] + warp_resolution: (6, 6, 6) + # type=tuple|default=(0, 0, 0): (approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10 imports: &id001 # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys @@ -256,8 +257,10 @@ doctests: # '.mock()' method of the corresponding class is used instead. in_fwhm: '[8, 4, 2, 2]' # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] - subsampling_scheme: '[4, 2, 1, 1] Specify the resolution of the warps >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6)' + subsampling_scheme: '[4, 2, 1, 1]' # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] + warp_resolution: (6, 6, 6) + # type=tuple|default=(0, 0, 0): (approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10 imports: *id001 # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys diff --git a/nipype-auto-conv/specs/fslx_command.yaml b/nipype-auto-conv/specs/fslx_command.yaml index 9670198..866e863 100644 --- a/nipype-auto-conv/specs/fslx_command.yaml +++ b/nipype-auto-conv/specs/fslx_command.yaml @@ -30,6 +30,8 @@ inputs: # type=file|default=: b vectors file bvals: generic/file # type=file|default=: b values file + logdir: generic/directory + # type=directory|default='.': metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: diff --git a/nipype-auto-conv/specs/ica__aroma.yaml b/nipype-auto-conv/specs/ica__aroma.yaml index a88cfbe..a637cc3 100644 --- a/nipype-auto-conv/specs/ica__aroma.yaml +++ b/nipype-auto-conv/specs/ica__aroma.yaml @@ -56,6 +56,13 @@ inputs: # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) motion_parameters: text/text-file # type=file|default=: motion parameters file + feat_dir: generic/directory + # type=directory|default=: If a feat directory exists and temporal filtering has not been run yet, ICA_AROMA can use the files in this directory. + out_dir: generic/directory + # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) + # type=directory|default='out': output directory + melodic_dir: generic/directory + # type=directory|default=: path to MELODIC directory if MELODIC has already been run metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -73,6 +80,9 @@ outputs: # type=file: if generated: aggressively denoised volume nonaggr_denoised_file: generic/file # type=file: if generated: non aggressively denoised volume + out_dir: generic/directory + # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) + # type=directory|default='out': output directory callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/melodic.yaml b/nipype-auto-conv/specs/melodic.yaml index fb02987..9e355f6 100644 --- a/nipype-auto-conv/specs/melodic.yaml +++ b/nipype-auto-conv/specs/melodic.yaml @@ -77,6 +77,11 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_dir: generic/directory + # type=directory: + # type=directory|default=: output directory name + report_dir: generic/directory + # type=directory: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/topup.yaml b/nipype-auto-conv/specs/topup.yaml index d4c21ec..bfb37c4 100644 --- a/nipype-auto-conv/specs/topup.yaml +++ b/nipype-auto-conv/specs/topup.yaml @@ -45,8 +45,6 @@ inputs: # type=file|default=: name of 4D file with images encoding_file: text/text-file # type=file|default=: name of text file with PE directions/times - readout_times: generic/file+list-of - # type=inputmultiobject|default=[]: readout times (dwell times by # phase-encode steps minus 1) out_base: generic/file # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) out_field: generic/file diff --git a/nipype-auto-conv/specs/training.yaml b/nipype-auto-conv/specs/training.yaml index 91531b1..6491ff2 100644 --- a/nipype-auto-conv/specs/training.yaml +++ b/nipype-auto-conv/specs/training.yaml @@ -22,7 +22,7 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mel_icas: generic/file+list-of + mel_icas: generic/directory+list-of # type=inputmultiobject|default=[]: Melodic output directories metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) diff --git a/nipype-auto-conv/specs/training_set_creator.yaml b/nipype-auto-conv/specs/training_set_creator.yaml index 04f170d..d9bb524 100644 --- a/nipype-auto-conv/specs/training_set_creator.yaml +++ b/nipype-auto-conv/specs/training_set_creator.yaml @@ -27,7 +27,7 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mel_icas_in: generic/file+list-of + mel_icas_in: generic/directory+list-of # type=inputmultiobject|default=[]: Melodic output directories metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) diff --git a/nipype-auto-conv/specs/x_fibres_5.yaml b/nipype-auto-conv/specs/x_fibres_5.yaml index 7756753..1cbf74a 100644 --- a/nipype-auto-conv/specs/x_fibres_5.yaml +++ b/nipype-auto-conv/specs/x_fibres_5.yaml @@ -33,6 +33,8 @@ inputs: # type=file|default=: b vectors file bvals: generic/file # type=file|default=: b values file + logdir: generic/directory + # type=directory|default='.': metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: From 47ff295d4c6df40f382a49bbe6c8ed806bcc7b4f Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 15:14:58 +1100 Subject: [PATCH 005/224] updated package with latest auto-generation --- .gitignore | 7 + NOTICE | 6 + README.md | 215 - README.rst | 25 +- nipype-auto-conv/generate | 15 +- nipype-auto-conv/requirements.txt | 1 + nipype-auto-conv/specs/accuracy_tester.yaml | 11 +- .../specs/accuracy_tester_callables.py | 29 +- nipype-auto-conv/specs/apply_mask.yaml | 12 +- .../specs/apply_mask_callables.py | 330 +- nipype-auto-conv/specs/apply_topup.yaml | 23 +- .../specs/apply_topup_callables.py | 339 +- nipype-auto-conv/specs/apply_warp.yaml | 24 +- .../specs/apply_warp_callables.py | 330 +- nipype-auto-conv/specs/apply_xfm.yaml | 45 +- nipype-auto-conv/specs/apply_xfm_callables.py | 353 +- nipype-auto-conv/specs/ar1_image.yaml | 8 +- nipype-auto-conv/specs/ar1_image_callables.py | 330 +- nipype-auto-conv/specs/av_scale.yaml | 11 +- nipype-auto-conv/specs/av_scale_callables.py | 82 +- nipype-auto-conv/specs/b0_calc.yaml | 13 +- nipype-auto-conv/specs/b0_calc_callables.py | 339 +- nipype-auto-conv/specs/bedpostx5.yaml | 49 +- nipype-auto-conv/specs/bedpostx5_callables.py | 482 +- nipype-auto-conv/specs/bet.yaml | 42 +- nipype-auto-conv/specs/bet_callables.py | 525 +- nipype-auto-conv/specs/binary_maths.yaml | 12 +- .../specs/binary_maths_callables.py | 330 +- nipype-auto-conv/specs/change_data_type.yaml | 8 +- .../specs/change_data_type_callables.py | 330 +- nipype-auto-conv/specs/classifier.yaml | 11 +- .../specs/classifier_callables.py | 43 +- nipype-auto-conv/specs/cleaner.yaml | 5 +- nipype-auto-conv/specs/cleaner_callables.py | 43 +- nipype-auto-conv/specs/cluster.yaml | 27 +- nipype-auto-conv/specs/cluster_callables.py | 380 +- nipype-auto-conv/specs/complex.yaml | 38 +- nipype-auto-conv/specs/complex_callables.py | 465 +- nipype-auto-conv/specs/contrast_mgr.yaml | 31 +- .../specs/contrast_mgr_callables.py | 469 +- nipype-auto-conv/specs/convert_warp.yaml | 31 +- .../specs/convert_warp_callables.py | 339 +- nipype-auto-conv/specs/convert_xfm.yaml | 14 +- .../specs/convert_xfm_callables.py | 148 +- nipype-auto-conv/specs/copy_geom.yaml | 9 +- nipype-auto-conv/specs/copy_geom_callables.py | 339 +- nipype-auto-conv/specs/dilate_image.yaml | 12 +- .../specs/dilate_image_callables.py | 330 +- nipype-auto-conv/specs/distance_map.yaml | 8 +- .../specs/distance_map_callables.py | 148 +- nipype-auto-conv/specs/dti_fit.yaml | 49 +- nipype-auto-conv/specs/dti_fit_callables.py | 408 +- nipype-auto-conv/specs/dual_regression.yaml | 28 +- .../specs/dual_regression_callables.py | 38 +- nipype-auto-conv/specs/eddy.yaml | 91 +- nipype-auto-conv/specs/eddy_callables.py | 186 +- nipype-auto-conv/specs/eddy_correct.yaml | 17 +- .../specs/eddy_correct_callables.py | 339 +- nipype-auto-conv/specs/eddy_quad.yaml | 37 +- nipype-auto-conv/specs/eddy_quad_callables.py | 112 +- nipype-auto-conv/specs/epi_de_warp.yaml | 41 +- .../specs/epi_de_warp_callables.py | 425 +- nipype-auto-conv/specs/epi_reg.yaml | 65 +- nipype-auto-conv/specs/epi_reg_callables.py | 148 +- nipype-auto-conv/specs/erode_image.yaml | 12 +- .../specs/erode_image_callables.py | 330 +- nipype-auto-conv/specs/extract_roi.yaml | 14 +- .../specs/extract_roi_callables.py | 346 +- nipype-auto-conv/specs/fast.yaml | 38 +- nipype-auto-conv/specs/fast_callables.py | 497 +- nipype-auto-conv/specs/feat.yaml | 5 +- nipype-auto-conv/specs/feat_callables.py | 43 +- nipype-auto-conv/specs/feat_model.yaml | 17 +- .../specs/feat_model_callables.py | 92 +- nipype-auto-conv/specs/feature_extractor.yaml | 7 +- .../specs/feature_extractor_callables.py | 21 +- nipype-auto-conv/specs/filmgls.yaml | 45 +- nipype-auto-conv/specs/filmgls_callables.py | 576 +- nipype-auto-conv/specs/filter_regressor.yaml | 12 +- .../specs/filter_regressor_callables.py | 330 +- nipype-auto-conv/specs/find_the_biggest.yaml | 14 +- .../specs/find_the_biggest_callables.py | 331 +- nipype-auto-conv/specs/first.yaml | 15 +- nipype-auto-conv/specs/first_callables.py | 188 +- nipype-auto-conv/specs/flameo.yaml | 63 +- nipype-auto-conv/specs/flameo_callables.py | 168 +- nipype-auto-conv/specs/flirt.yaml | 53 +- nipype-auto-conv/specs/flirt_callables.py | 353 +- nipype-auto-conv/specs/fnirt.yaml | 58 +- nipype-auto-conv/specs/fnirt_callables.py | 421 +- nipype-auto-conv/specs/fslx_command.yaml | 132 - .../specs/fslx_command_callables.py | 1 - nipype-auto-conv/specs/fugue.yaml | 73 +- nipype-auto-conv/specs/fugue_callables.py | 360 +- nipype-auto-conv/specs/glm.yaml | 82 +- nipype-auto-conv/specs/glm_callables.py | 458 +- nipype-auto-conv/specs/ica__aroma.yaml | 33 +- .../specs/ica__aroma_callables.py | 47 +- nipype-auto-conv/specs/image_maths.yaml | 14 +- .../specs/image_maths_callables.py | 333 +- nipype-auto-conv/specs/image_meants.yaml | 8 +- .../specs/image_meants_callables.py | 332 +- nipype-auto-conv/specs/image_stats.yaml | 17 +- .../specs/image_stats_callables.py | 339 +- nipype-auto-conv/specs/inv_warp.yaml | 23 +- nipype-auto-conv/specs/inv_warp_callables.py | 339 +- nipype-auto-conv/specs/isotropic_smooth.yaml | 8 +- .../specs/isotropic_smooth_callables.py | 330 +- nipype-auto-conv/specs/l2_model.yaml | 9 +- nipype-auto-conv/specs/l2_model_callables.py | 33 +- nipype-auto-conv/specs/level_1_design.yaml | 7 +- .../specs/level_1_design_callables.py | 64 +- .../specs/make_dyadic_vectors.yaml | 17 +- .../specs/make_dyadic_vectors_callables.py | 333 +- nipype-auto-conv/specs/maths_command.yaml | 8 +- .../specs/maths_command_callables.py | 330 +- nipype-auto-conv/specs/max_image.yaml | 14 +- nipype-auto-conv/specs/max_image_callables.py | 330 +- nipype-auto-conv/specs/maxn_image.yaml | 8 +- .../specs/maxn_image_callables.py | 330 +- nipype-auto-conv/specs/mcflirt.yaml | 30 +- nipype-auto-conv/specs/mcflirt_callables.py | 467 +- nipype-auto-conv/specs/mean_image.yaml | 8 +- .../specs/mean_image_callables.py | 330 +- nipype-auto-conv/specs/median_image.yaml | 8 +- .../specs/median_image_callables.py | 330 +- nipype-auto-conv/specs/melodic.yaml | 42 +- nipype-auto-conv/specs/melodic_callables.py | 47 +- nipype-auto-conv/specs/merge.yaml | 13 +- nipype-auto-conv/specs/merge_callables.py | 339 +- nipype-auto-conv/specs/min_image.yaml | 8 +- nipype-auto-conv/specs/min_image_callables.py | 330 +- nipype-auto-conv/specs/motion_outliers.yaml | 29 +- .../specs/motion_outliers_callables.py | 353 +- nipype-auto-conv/specs/multi_image_maths.yaml | 20 +- .../specs/multi_image_maths_callables.py | 330 +- .../specs/multiple_regress_design.yaml | 9 +- .../multiple_regress_design_callables.py | 43 +- nipype-auto-conv/specs/overlay.yaml | 8 +- nipype-auto-conv/specs/overlay_callables.py | 340 +- nipype-auto-conv/specs/percentile_image.yaml | 14 +- .../specs/percentile_image_callables.py | 330 +- .../specs/plot_motion_params.yaml | 8 +- .../specs/plot_motion_params_callables.py | 136 +- nipype-auto-conv/specs/plot_time_series.yaml | 8 +- .../specs/plot_time_series_callables.py | 334 +- nipype-auto-conv/specs/power_spectrum.yaml | 8 +- .../specs/power_spectrum_callables.py | 339 +- nipype-auto-conv/specs/prelude.yaml | 20 +- nipype-auto-conv/specs/prelude_callables.py | 340 +- nipype-auto-conv/specs/prepare_fieldmap.yaml | 19 +- .../specs/prepare_fieldmap_callables.py | 21 +- nipype-auto-conv/specs/prob_track_x.yaml | 65 +- nipype-auto-conv/specs/prob_track_x2.yaml | 81 +- .../specs/prob_track_x2_callables.py | 486 +- .../specs/prob_track_x_callables.py | 419 +- nipype-auto-conv/specs/proj_thresh.yaml | 13 +- .../specs/proj_thresh_callables.py | 324 +- nipype-auto-conv/specs/randomise.yaml | 37 +- nipype-auto-conv/specs/randomise_callables.py | 410 +- nipype-auto-conv/specs/reorient_2_std.yaml | 8 +- .../specs/reorient_2_std_callables.py | 334 +- nipype-auto-conv/specs/robust_fov.yaml | 9 +- .../specs/robust_fov_callables.py | 346 +- nipype-auto-conv/specs/sig_loss.yaml | 8 +- nipype-auto-conv/specs/sig_loss_callables.py | 329 +- nipype-auto-conv/specs/slice.yaml | 13 +- nipype-auto-conv/specs/slice_callables.py | 279 +- nipype-auto-conv/specs/slice_timer.yaml | 19 +- .../specs/slice_timer_callables.py | 330 +- nipype-auto-conv/specs/slicer.yaml | 16 +- nipype-auto-conv/specs/slicer_callables.py | 330 +- nipype-auto-conv/specs/smm.yaml | 12 +- nipype-auto-conv/specs/smm_callables.py | 353 +- nipype-auto-conv/specs/smooth.yaml | 25 +- nipype-auto-conv/specs/smooth_callables.py | 339 +- nipype-auto-conv/specs/smooth_estimate.yaml | 19 +- .../specs/smooth_estimate_callables.py | 353 +- nipype-auto-conv/specs/spatial_filter.yaml | 12 +- .../specs/spatial_filter_callables.py | 330 +- nipype-auto-conv/specs/split.yaml | 7 +- nipype-auto-conv/specs/split_callables.py | 179 +- nipype-auto-conv/specs/std_image.yaml | 8 +- nipype-auto-conv/specs/std_image_callables.py | 330 +- nipype-auto-conv/specs/susan.yaml | 11 +- nipype-auto-conv/specs/susan_callables.py | 330 +- nipype-auto-conv/specs/swap_dimensions.yaml | 8 +- .../specs/swap_dimensions_callables.py | 330 +- nipype-auto-conv/specs/temporal_filter.yaml | 8 +- .../specs/temporal_filter_callables.py | 330 +- nipype-auto-conv/specs/text_2_vest.yaml | 17 +- .../specs/text_2_vest_callables.py | 339 +- nipype-auto-conv/specs/threshold.yaml | 8 +- nipype-auto-conv/specs/threshold_callables.py | 330 +- nipype-auto-conv/specs/topup.yaml | 49 +- nipype-auto-conv/specs/topup_callables.py | 566 +- nipype-auto-conv/specs/tract_skeleton.yaml | 23 +- .../specs/tract_skeleton_callables.py | 142 +- nipype-auto-conv/specs/training.yaml | 5 +- nipype-auto-conv/specs/training_callables.py | 29 +- .../specs/training_set_creator.yaml | 7 +- .../specs/training_set_creator_callables.py | 22 +- nipype-auto-conv/specs/unary_maths.yaml | 8 +- .../specs/unary_maths_callables.py | 338 +- nipype-auto-conv/specs/vec_reg.yaml | 34 +- nipype-auto-conv/specs/vec_reg_callables.py | 333 +- nipype-auto-conv/specs/vest_2_text.yaml | 13 +- .../specs/vest_2_text_callables.py | 339 +- nipype-auto-conv/specs/warp_points.yaml | 31 +- .../specs/warp_points_callables.py | 205 +- .../specs/warp_points_from_std.yaml | 25 +- .../specs/warp_points_from_std_callables.py | 23 +- .../specs/warp_points_to_std.yaml | 35 +- .../specs/warp_points_to_std_callables.py | 205 +- nipype-auto-conv/specs/warp_utils.yaml | 21 +- .../specs/warp_utils_callables.py | 346 +- nipype-auto-conv/specs/x_fibres_5.yaml | 35 +- .../specs/x_fibres_5_callables.py | 447 +- pydra/tasks/fsl/_version.py | 4 - pydra/tasks/fsl/conftest.py | 48 - pydra/tasks/fsl/model/cluster.py | 242 - pydra/tasks/fsl/model/feat.py | 62 - pydra/tasks/fsl/model/featmodel.py | 119 - pydra/tasks/fsl/model/filmgls.py | 396 - pydra/tasks/fsl/model/flameo.py | 336 - pydra/tasks/fsl/model/glm.py | 194 - pydra/tasks/fsl/model/melodic.py | 356 - pydra/tasks/fsl/model/tests/__init__.py | 0 .../tasks/fsl/model/tests/test_run_cluster.py | 64 - pydra/tasks/fsl/model/tests/test_run_feat.py | 72 - .../fsl/model/tests/test_run_featmodel.py | 72 - .../tasks/fsl/model/tests/test_run_filmgls.py | 62 - .../tasks/fsl/model/tests/test_run_flameo.py | 69 - pydra/tasks/fsl/model/tests/test_run_glm.py | 44 - .../tasks/fsl/model/tests/test_run_melodic.py | 72 - .../fsl/model/tests/test_spec_cluster.py | 51 - pydra/tasks/fsl/model/tests/test_spec_feat.py | 64 - .../fsl/model/tests/test_spec_featmodel.py | 64 - .../fsl/model/tests/test_spec_filmgls.py | 54 - .../tasks/fsl/model/tests/test_spec_flameo.py | 61 - pydra/tasks/fsl/model/tests/test_spec_glm.py | 36 - .../fsl/model/tests/test_spec_melodic.py | 64 - pydra/tasks/fsl/preprocess/__init__.py | 0 pydra/tasks/fsl/preprocess/applywarp.py | 129 - pydra/tasks/fsl/preprocess/bet.py | 306 - pydra/tasks/fsl/preprocess/fast.py | 280 - pydra/tasks/fsl/preprocess/first.py | 138 - pydra/tasks/fsl/preprocess/flirt.py | 348 - pydra/tasks/fsl/preprocess/fnirt.py | 363 - pydra/tasks/fsl/preprocess/mcflirt.py | 185 - pydra/tasks/fsl/preprocess/prelude.py | 155 - pydra/tasks/fsl/preprocess/slicetimer.py | 97 - pydra/tasks/fsl/preprocess/susan.py | 114 - pydra/tasks/fsl/preprocess/tests/__init__.py | 0 .../preprocess/tests/test_run_applywarp.py | 22 - .../fsl/preprocess/tests/test_run_bet.py | 42 - .../fsl/preprocess/tests/test_run_fast.py | 37 - .../fsl/preprocess/tests/test_run_first.py | 37 - .../fsl/preprocess/tests/test_run_flirt.py | 37 - .../fsl/preprocess/tests/test_run_fnirt.py | 52 - .../fsl/preprocess/tests/test_run_mcflirt.py | 22 - .../fsl/preprocess/tests/test_run_prelude.py | 37 - .../preprocess/tests/test_run_slicetimer.py | 25 - .../fsl/preprocess/tests/test_run_susan.py | 40 - .../preprocess/tests/test_spec_applywarp.py | 17 - .../fsl/preprocess/tests/test_spec_bet.py | 37 - .../fsl/preprocess/tests/test_spec_fast.py | 32 - .../fsl/preprocess/tests/test_spec_first.py | 32 - .../fsl/preprocess/tests/test_spec_flirt.py | 32 - .../fsl/preprocess/tests/test_spec_fnirt.py | 47 - .../fsl/preprocess/tests/test_spec_mcflirt.py | 17 - .../fsl/preprocess/tests/test_spec_prelude.py | 32 - .../preprocess/tests/test_spec_slicetimer.py | 20 - .../fsl/preprocess/tests/test_spec_susan.py | 35 - pydra/tasks/fsl/tests/data/anatomical.nii | 0 .../fsl/tests/data/confounds_regressors.tsv | 527 - pydra/tasks/fsl/tests/data/cope_merged.nii.gz | 3 - pydra/tasks/fsl/tests/data/design | 0 pydra/tasks/fsl/tests/data/design.con | 8 - pydra/tasks/fsl/tests/data/design.grp | 30 - pydra/tasks/fsl/tests/data/design.mat | 31 - .../tasks/fsl/tests/data/design_film_gls.mat | 151 - pydra/tasks/fsl/tests/data/dest.nii.gz | 0 pydra/tasks/fsl/tests/data/ev_1.txt | 12 - pydra/tasks/fsl/tests/data/ev_2.txt | 12 - pydra/tasks/fsl/tests/data/flirt.mat | 4 - pydra/tasks/fsl/tests/data/flirt_inv.mat | 4 - pydra/tasks/fsl/tests/data/mask.nii.gz | 3 - pydra/tasks/fsl/tests/data/struct2mni.nii | 0 pydra/tasks/fsl/tests/data/subjectDesign.con | 0 pydra/tasks/fsl/tests/data/subjectDesign.mat | 0 pydra/tasks/fsl/tests/data/test.fsf | 11836 ---------------- pydra/tasks/fsl/tests/data/test.nii.gz | 3 - pydra/tasks/fsl/tests/data/test2.nii | 0 pydra/tasks/fsl/tests/data/test3.nii | 0 .../tasks/fsl/tests/data/test_film_gls.nii.gz | 3 - .../tasks/fsl/tests/data/test_warpcoef.nii.gz | 3 - pydra/tasks/fsl/tests/data/timeDesign.con | 0 pydra/tasks/fsl/tests/data/timeDesign.mat | 0 .../fsl/tests/data/varcope_merged.nii.gz | 3 - pydra/tasks/fsl/tests/data/warpfield.nii | 0 pydra/tasks/fsl/tests/data/warpfield.nii.gz | 3 - pydra/tasks/fsl/tests/data/zstat1.nii.gz | 3 - pydra/tasks/fsl/utils/__init__.py | 0 pydra/tasks/fsl/utils/complex.py | 267 - pydra/tasks/fsl/utils/convertwarp.py | 169 - pydra/tasks/fsl/utils/convertxfm.py | 110 - pydra/tasks/fsl/utils/copygeom.py | 69 - pydra/tasks/fsl/utils/extractroi.py | 58 - pydra/tasks/fsl/utils/filterregressor.py | 91 - pydra/tasks/fsl/utils/imagemaths.py | 75 - pydra/tasks/fsl/utils/imagemeants.py | 105 - pydra/tasks/fsl/utils/imagestats.py | 77 - pydra/tasks/fsl/utils/invwarp.py | 111 - pydra/tasks/fsl/utils/slice.py | 44 - pydra/tasks/fsl/utils/smooth.py | 55 - pydra/tasks/fsl/utils/split.py | 72 - pydra/tasks/fsl/utils/swapdimensions.py | 48 - pydra/tasks/fsl/utils/tests/__init__.py | 0 .../tasks/fsl/utils/tests/test_run_complex.py | 72 - .../fsl/utils/tests/test_run_convertwarp.py | 72 - .../fsl/utils/tests/test_run_convertxfm.py | 43 - .../fsl/utils/tests/test_run_copygeom.py | 72 - .../fsl/utils/tests/test_run_extractroi.py | 44 - .../utils/tests/test_run_filterregressor.py | 72 - .../fsl/utils/tests/test_run_imagemaths.py | 41 - .../fsl/utils/tests/test_run_imagemeants.py | 41 - .../fsl/utils/tests/test_run_imagestats.py | 72 - .../tasks/fsl/utils/tests/test_run_invwarp.py | 72 - pydra/tasks/fsl/utils/tests/test_run_slice.py | 22 - .../tasks/fsl/utils/tests/test_run_smooth.py | 43 - pydra/tasks/fsl/utils/tests/test_run_split.py | 53 - .../utils/tests/test_run_swapdimensions.py | 72 - .../fsl/utils/tests/test_spec_complex.py | 64 - .../fsl/utils/tests/test_spec_convertwarp.py | 64 - .../fsl/utils/tests/test_spec_convertxfm.py | 35 - .../fsl/utils/tests/test_spec_copygeom.py | 64 - .../fsl/utils/tests/test_spec_extractroi.py | 36 - .../utils/tests/test_spec_filterregressor.py | 64 - .../fsl/utils/tests/test_spec_imagemaths.py | 33 - .../fsl/utils/tests/test_spec_imagemeants.py | 33 - .../fsl/utils/tests/test_spec_imagestats.py | 64 - .../fsl/utils/tests/test_spec_invwarp.py | 64 - .../tasks/fsl/utils/tests/test_spec_slice.py | 17 - .../tasks/fsl/utils/tests/test_spec_smooth.py | 35 - .../tasks/fsl/utils/tests/test_spec_split.py | 45 - .../utils/tests/test_spec_swapdimensions.py | 64 - pydra/tasks/fsl/v1/__init__.py | 0 pydra/tasks/fsl/{model => v1_0}/__init__.py | 0 pyproject.toml | 1 + .../fileformats-extras/README.rst | 15 +- .../extras/medimage_fsl/__init__.py | 5 +- .../extras/medimage_fsl/_version.py | 16 - .../tests/test_generate_sample_data.py | 10 + .../fileformats-extras/pyproject.toml | 4 +- related-packages/fileformats/README.rst | 23 +- .../fileformats/medimage_fsl/__init__.py | 1 + .../fileformats/medimage_fsl/_version.py | 16 - related-packages/fileformats/pyproject.toml | 4 +- report_progress.py | 31 + specs/callables.py | 411 - specs/fsl_aroma_param.yml | 8 - specs/fsl_dti_param.yml | 125 - specs/fsl_epi_param.yml | 80 - specs/fsl_fix_param.yml | 44 - specs/fsl_maths_param.yml | 170 - specs/fsl_model_param.yml | 349 - specs/fsl_possum_param.yml | 11 - specs/fsl_preprocess_param.yml | 231 - specs/fsl_utils_param.yml | 401 - tools/increment_tool_version.py | 69 + tools/rename_template.py | 46 + tools/requirements.txt | 3 + 373 files changed, 31988 insertions(+), 24059 deletions(-) create mode 100644 NOTICE delete mode 100644 README.md delete mode 100644 nipype-auto-conv/specs/fslx_command.yaml delete mode 100644 nipype-auto-conv/specs/fslx_command_callables.py delete mode 100644 pydra/tasks/fsl/_version.py delete mode 100644 pydra/tasks/fsl/conftest.py delete mode 100644 pydra/tasks/fsl/model/cluster.py delete mode 100644 pydra/tasks/fsl/model/feat.py delete mode 100644 pydra/tasks/fsl/model/featmodel.py delete mode 100644 pydra/tasks/fsl/model/filmgls.py delete mode 100644 pydra/tasks/fsl/model/flameo.py delete mode 100644 pydra/tasks/fsl/model/glm.py delete mode 100644 pydra/tasks/fsl/model/melodic.py delete mode 100644 pydra/tasks/fsl/model/tests/__init__.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_cluster.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_feat.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_featmodel.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_filmgls.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_flameo.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_glm.py delete mode 100644 pydra/tasks/fsl/model/tests/test_run_melodic.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_cluster.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_feat.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_featmodel.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_filmgls.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_flameo.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_glm.py delete mode 100644 pydra/tasks/fsl/model/tests/test_spec_melodic.py delete mode 100644 pydra/tasks/fsl/preprocess/__init__.py delete mode 100644 pydra/tasks/fsl/preprocess/applywarp.py delete mode 100644 pydra/tasks/fsl/preprocess/bet.py delete mode 100644 pydra/tasks/fsl/preprocess/fast.py delete mode 100644 pydra/tasks/fsl/preprocess/first.py delete mode 100644 pydra/tasks/fsl/preprocess/flirt.py delete mode 100644 pydra/tasks/fsl/preprocess/fnirt.py delete mode 100644 pydra/tasks/fsl/preprocess/mcflirt.py delete mode 100644 pydra/tasks/fsl/preprocess/prelude.py delete mode 100644 pydra/tasks/fsl/preprocess/slicetimer.py delete mode 100644 pydra/tasks/fsl/preprocess/susan.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/__init__.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_applywarp.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_bet.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_fast.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_first.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_flirt.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_fnirt.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_mcflirt.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_prelude.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_slicetimer.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_run_susan.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_applywarp.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_bet.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_fast.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_first.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_flirt.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_fnirt.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_mcflirt.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_prelude.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_slicetimer.py delete mode 100644 pydra/tasks/fsl/preprocess/tests/test_spec_susan.py delete mode 100644 pydra/tasks/fsl/tests/data/anatomical.nii delete mode 100644 pydra/tasks/fsl/tests/data/confounds_regressors.tsv delete mode 100644 pydra/tasks/fsl/tests/data/cope_merged.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/design delete mode 100644 pydra/tasks/fsl/tests/data/design.con delete mode 100644 pydra/tasks/fsl/tests/data/design.grp delete mode 100644 pydra/tasks/fsl/tests/data/design.mat delete mode 100644 pydra/tasks/fsl/tests/data/design_film_gls.mat delete mode 100644 pydra/tasks/fsl/tests/data/dest.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/ev_1.txt delete mode 100644 pydra/tasks/fsl/tests/data/ev_2.txt delete mode 100644 pydra/tasks/fsl/tests/data/flirt.mat delete mode 100644 pydra/tasks/fsl/tests/data/flirt_inv.mat delete mode 100644 pydra/tasks/fsl/tests/data/mask.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/struct2mni.nii delete mode 100644 pydra/tasks/fsl/tests/data/subjectDesign.con delete mode 100644 pydra/tasks/fsl/tests/data/subjectDesign.mat delete mode 100644 pydra/tasks/fsl/tests/data/test.fsf delete mode 100644 pydra/tasks/fsl/tests/data/test.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/test2.nii delete mode 100644 pydra/tasks/fsl/tests/data/test3.nii delete mode 100644 pydra/tasks/fsl/tests/data/test_film_gls.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/test_warpcoef.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/timeDesign.con delete mode 100644 pydra/tasks/fsl/tests/data/timeDesign.mat delete mode 100644 pydra/tasks/fsl/tests/data/varcope_merged.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/warpfield.nii delete mode 100644 pydra/tasks/fsl/tests/data/warpfield.nii.gz delete mode 100644 pydra/tasks/fsl/tests/data/zstat1.nii.gz delete mode 100644 pydra/tasks/fsl/utils/__init__.py delete mode 100644 pydra/tasks/fsl/utils/complex.py delete mode 100644 pydra/tasks/fsl/utils/convertwarp.py delete mode 100644 pydra/tasks/fsl/utils/convertxfm.py delete mode 100644 pydra/tasks/fsl/utils/copygeom.py delete mode 100644 pydra/tasks/fsl/utils/extractroi.py delete mode 100644 pydra/tasks/fsl/utils/filterregressor.py delete mode 100644 pydra/tasks/fsl/utils/imagemaths.py delete mode 100644 pydra/tasks/fsl/utils/imagemeants.py delete mode 100644 pydra/tasks/fsl/utils/imagestats.py delete mode 100644 pydra/tasks/fsl/utils/invwarp.py delete mode 100644 pydra/tasks/fsl/utils/slice.py delete mode 100644 pydra/tasks/fsl/utils/smooth.py delete mode 100644 pydra/tasks/fsl/utils/split.py delete mode 100644 pydra/tasks/fsl/utils/swapdimensions.py delete mode 100644 pydra/tasks/fsl/utils/tests/__init__.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_complex.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_convertwarp.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_convertxfm.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_copygeom.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_extractroi.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_filterregressor.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_imagemaths.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_imagemeants.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_imagestats.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_invwarp.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_slice.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_smooth.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_split.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_run_swapdimensions.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_complex.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_convertwarp.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_convertxfm.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_copygeom.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_extractroi.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_filterregressor.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_imagemaths.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_imagemeants.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_imagestats.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_invwarp.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_slice.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_smooth.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_split.py delete mode 100644 pydra/tasks/fsl/utils/tests/test_spec_swapdimensions.py delete mode 100644 pydra/tasks/fsl/v1/__init__.py rename pydra/tasks/fsl/{model => v1_0}/__init__.py (100%) delete mode 100644 related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py create mode 100644 related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py delete mode 100644 related-packages/fileformats/fileformats/medimage_fsl/_version.py create mode 100644 report_progress.py delete mode 100644 specs/callables.py delete mode 100644 specs/fsl_aroma_param.yml delete mode 100644 specs/fsl_dti_param.yml delete mode 100644 specs/fsl_epi_param.yml delete mode 100644 specs/fsl_fix_param.yml delete mode 100644 specs/fsl_maths_param.yml delete mode 100644 specs/fsl_model_param.yml delete mode 100644 specs/fsl_possum_param.yml delete mode 100644 specs/fsl_preprocess_param.yml delete mode 100644 specs/fsl_utils_param.yml create mode 100755 tools/increment_tool_version.py create mode 100755 tools/rename_template.py create mode 100644 tools/requirements.txt diff --git a/.gitignore b/.gitignore index 600b434..a6fcb00 100644 --- a/.gitignore +++ b/.gitignore @@ -131,11 +131,18 @@ dmypy.json # Pycharm .idea +# Vim +.*.sw[op] + # VS Code .vscode # Mac garbarge .DS_store +# Generated files +/pydra/tasks/fsl/_version.py +/related-packages/fileformats/fileformats/medimage_fsl/_version.py +/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py /pydra/tasks/fsl/auto /pydra/tasks/fsl/_version.py diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..aee9927 --- /dev/null +++ b/NOTICE @@ -0,0 +1,6 @@ +Pydra-fsl +Copyright 2024 Pydra Development Team + +The bases for the task interfaces defined in this package were semi-automatically converted +from Nipype interfaces (https://github.com/nipy/nipype) using the Nipype2Pydra tool +(https://github.com/nipype/nipype2pydra). diff --git a/README.md b/README.md deleted file mode 100644 index 77962ed..0000000 --- a/README.md +++ /dev/null @@ -1,215 +0,0 @@ -# Pydra FSL Tasks - -This repository aims to be the canonical set of Pydra tasks for incorporating -[FSL](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/) tools into a Pydra workflow. - -Part of this effort is to establish a (mostly) declarative language for describing tasks that -potentially have intricate rules for determining the availability and names from the choice of -inputs. See [Converter](#Converter) for this aspect of the repository. - -## Installation -``` -pip install /path/to/pydra-fsl/ -``` - -### Installation for developers -``` -pip install -e /path/to/pydra-fsl/[dev] -``` - - -## Converter - -`FSLConverter` class (from `tools/converter.py`) requires three parts of information: - -- Nipype spec: converter loads nipype interface and reads `_cmd`, `input_spec` and `output_spec` -- yml file with additional spec: `specs/fsl_{module_name}_params.yml` contains additional spec that are written based -on additional functions from nipype (including `list_outputs`), each interface can have the following fields: - - inputs_metadata: additional metadata for fields from input_spec - (it will be included in `metadata` in pydra spec), - e.g., used in `specs/fsl_preprocess_params.yml` for `FAST` to set default value for `number_classes` - (it's not part of nipype's spec, but it's set in `list_output`, see [here](https://github.com/nipy/nipype/blob/f4343d6ddaee814aa16b197cc729a10d437990bf/nipype/interfaces/fsl/preprocess.py#L403)) - - - output_requirements: providing required fields for the output to be created, - taken from `list_output` structure (e.g. requirements for tissue_class_files [here](https://github.com/nipy/nipype/blob/f4343d6ddaee814aa16b197cc729a10d437990bf/nipype/interfaces/fsl/preprocess.py#L418)); - it's a part of the `requires` field in metadata in pydra spec (e.g. [here](https://github.com/nipype/pydra-fsl/blob/ceae758f76bde81465e86cff029b40e334a7939a/pydra/tasks/fsl/preprocess/fast.py#L237)) - - - output_templates: providing template to create the output file name, - taken from `list_output` structure (e.g., [here](https://github.com/nipy/nipype/blob/f4343d6ddaee814aa16b197cc729a10d437990bf/nipype/interfaces/fsl/preprocess.py#L205)); - it is set as `output_file_template` in metadata (e.g. [here](https://github.com/nipype/pydra-fsl/blob/ceae758f76bde81465e86cff029b40e334a7939a/pydra/tasks/fsl/preprocess/bet.py#L204)) - - - output_callables: providing function name that should be used to gather output, - based on the `list_output` structure and used only for `FAST`; - it is set as `callable` in metadata (e.g. [here](https://github.com/nipype/pydra-fsl/blob/ceae758f76bde81465e86cff029b40e334a7939a/pydra/tasks/fsl/preprocess/fast.py#L237)) - - - tests_inputs, tests_outputs: specification for tests, - the fields should have the same length and each element should contain - the input fields values and list of the expected output fields names - - - doctests: specification for doctest, - should include values for input fields and the expected `cmdline` - -- python file with functions used as callables to gather the outputs: -`specs/callables.py` should contain all the functions from `output_callables`; -the source code of the functions is read and written again in the pydra interface file - - -### How to use the convert - -The converter can be used by running: - - python tools/converter.py --interface_name --module_name - -The pydra task will be created and saved in `pydra/tasks/fsl/{module_name}/{interface_name}.py`. -Note, that the spec file has to be present for the specific module name in order to run the converter. -If no `interface_name` is provided, the default value `all` will be used - and the converter will be run for all interfaces from the spec file. - -Tests are written based on the fields from the yml file: -`tests_inputs` and `tests_outputs` (the lengths should be the same). -One test, `test_specs_*` checks only the correctness of the spec based -on the `test_inputs/outputs` pairs, i.e. predicts which output fields -should be created based on the list of the input fields. -The second test, `test_run_*` should run the interfaces -(TODO: this is temporary, should be removed from the final repo). -Tests can be run using `pytest`: - - pytest -vs pydra/tasks/fsl/{module_name}/tests - -## Interface progress - -Below is a list of all planned interfaces, with completed interfaces checked. The list was copied from the nipype documentation at https://nipype.readthedocs.io/en/latest/api/generated/nipype.interfaces.fsl.html. - -### Preprocess - -- [x] ApplyWarp (`applywarp`) -- [ ] ApplyXFM (`flirt`) -- [x] BET (`bet`) -- [x] FAST (`fast`) -- [x] FIRST (`first`) -- [x] FLIRT (`flirt`) -- [x] FNIRT (`fnirt`) -- [ ] FUGUE (`fugue`) -- [x] MCFLIRT (`mcflirt`) -- [x] PRELUDE (`prelude`) -- [x] SUSAN (`susan`) -- [x] SliceTimer (`slicetimer`) - -### AROMA - -- [ ] ICA_AROMA (`ICA_AROMA.py`) - -### DTI - -- [ ] BEDPOSTX / BEDPOSTX5 (`bedpostx`) -- [ ] DTIFit (`dtifit`) -- [ ] DistanceMap (`distancemap`) -- [ ] FSLXCommand (`xfibres` and `bedpost`) -- [ ] FindTheBiggest (`find_the_biggest`) -- [ ] MakeDyadicVectors (`make_dyadic_vectors`) -- [ ] ProbTrackX (`probtrackx`) -- [ ] ProbTrackX2 (`probtrackx2`) -- [ ] ProjThresh (`proj_thresh`) -- [ ] TractSkeleton (`tbss_skeleton`) -- [ ] VecReg (`vecreg`) -- [ ] XFibres / XFibres5 (`xfibres`) - -## EPI - -- [ ] ApplyTOPUP (`applytopup`) -- [ ] EPIDeWarp (`epidewarp.fsl`; depreciated) -- [ ] Eddy (`eddy_openmp`) -- [ ] EddyCorrect (`eddy_correct`; depreciated) -- [ ] EddyQuad (`eddy_quad`) -- [ ] EpiReg (`epi_reg`) -- [ ] PrepareFieldmap (`fsl_prepare_fieldmap`) -- [ ] SigLoss (`sigloss`) -- [ ] TOPUP (`topup`) - -## FIX - -- [ ] Classifier (`fix -c`) -- [ ] Cleaner (`fix -a`) -- [ ] FeatureExtractor (`fix -f`) -- [ ] Training (`fix -t`) -- [ ] TrainingSetCreator - -## Utils - -- [ ] AvScale (`avscale`) -- [ ] Complex (`fslcomplex`) -- [ ] ConvertWarp (`convertwarp`) -- [ ] ConvertXFM (`convert_xfm`) -- [ ] CopyGeom (`fslcpgeom`) -- [ ] ExtractROI (`fslroi`) -- [ ] FilterRegressor (`fsl_regfilt`) -- [ ] ImageMaths (`fslmaths`) -- [ ] ImageMeants (`fslmeants`) -- [ ] ImageStats (`fslstats`) -- [ ] InvWarp (`invwarp`) -- [ ] Merge (`fslmerge`) -- [ ] MotionOutliers (`fsl_motion_outliers`) -- [ ] Overlay (`overlay`) -- [ ] PlotMotionParams (`fsl_tsplot`) -- [ ] PlotTimeSeries (`fsl_tsplot`) -- [ ] PowerSpectrum (`fslpspec`) -- [ ] Reorient2Std (`fslreorient2std`) -- [ ] RobustFOV (`robustfov`) -- [ ] SigLoss (`sigloss`) -- [ ] Slice (`fslslice`) -- [ ] Slicer (`slicer`) -- [ ] Smooth (`fslmaths`) -- [ ] Split (`fslsplit`) -- [ ] SwapDimensions (`fslswapdim`) -- [ ] Text2Vest (`text2vest`) -- [ ] Vest2Text (`vest2text`) -- [ ] WarpPoints (`img2imgcoord`) -- [ ] WarpPointsFromStd (`std2imgcoord`) -- [ ] WarpPointsToStd (`img2stdcoord`) -- [ ] WarpUtils (`fnirtfileutils`) - -### POSSUM - -- [ ] B0Calc (`b0calc`) - -### Model - -- [ ] Cluster (`cluster`) -- [ ] ContrastMgr (`contrast_mgr`) -- [ ] DualRegression (`dual_regression`) -- [ ] FEAT (`feat`) -- [ ] FEATModel (`feat_model`) -- [ ] FEATRegister -- [ ] FILMGLS (`film_gls`) -- [ ] FLAMEO (`flameo`) -- [ ] GLM (`fsl_glm`) -- [ ] L2Model -- [ ] Level1Design -- [ ] MELODIC (`melodic`) -- [ ] MultipleRegressDesign -- [ ] Randomise (`randomise`) -- [ ] SMM (`mm --ld=logdir`) -- [ ] SmoothEstimate (`smoothest`) - -### Maths - -- [ ] AR1Image (`fslmaths`) -- [ ] ApplyMask (`fslmaths`) -- [ ] BinaryMaths (`fslmaths`) -- [ ] ChangeDataType (`fslmaths`) -- [ ] DilateImage (`fslmaths`) -- [ ] ErodeImage (`fslmaths`) -- [ ] IsotropicSmooth (`fslmaths`) -- [ ] MathsCommand (`fslmaths`) -- [ ] MaxImage (`fslmaths`) -- [ ] MaxnImage (`fslmaths`) -- [ ] MeanImage (`fslmaths`) -- [ ] MedianImage (`fslmaths`) -- [ ] MinImage (`fslmaths`) -- [ ] MultiImageMaths (`fslmaths`) -- [ ] PercentileImage (`fslmaths`) -- [ ] SpatialFilter (`fslmaths`) -- [ ] StdImage (`fslmaths`) -- [ ] TemporalFilter (`fslmaths`) -- [ ] Threshold (`fslmaths`) -- [ ] UnaryMaths (`fslmaths`) diff --git a/README.rst b/README.rst index c78a403..c2e2bc2 100644 --- a/README.rst +++ b/README.rst @@ -1,11 +1,11 @@ -=============================== +========================== Pydra task package for fsl -=============================== +========================== -.. image:: https://github.com/nipype/pydra-fsl/actions/workflows/pythonpackage.yaml/badge.svg - :target: https://github.com/nipype/pydra-fsl/actions/workflows/pythonpackage.yaml -.. .. image:: https://codecov.io/gh/nipype/pydra-fsl/branch/main/graph/badge.svg?token=UIS0OGPST7 -.. :target: https://codecov.io/gh/nipype/pydra-fsl +.. image:: https://github.com/nipype/pydra-fsl/actions/workflows/ci-cd.yaml/badge.svg + :target: https://github.com/nipype/pydra-fsl/actions/workflows/ci-cd.yaml +.. image:: https://codecov.io/gh/nipype/pydra-fsl/branch/main/graph/badge.svg?token=UIS0OGPST7 + :target: https://codecov.io/gh/nipype/pydra-fsl .. image:: https://img.shields.io/pypi/pyversions/pydra-fsl.svg :target: https://pypi.python.org/pypi/pydra-fsl/ :alt: Supported Python versions @@ -71,6 +71,14 @@ Contributing to this package Developer installation ~~~~~~~~~~~~~~~~~~~~~~ +Install the `fileformats `__ packages +corresponding to AFNI specific file formats + + +.. code-block:: + + $ pip install -e ./related-packages/fileformats[dev] + $ pip install -e ./related-packages/fileformats-extras[dev] Install repo in developer mode from the source directory and install pre-commit to ensure consistent code-style and quality. @@ -78,7 +86,7 @@ ensure consistent code-style and quality. .. code-block:: $ pip install -e .[test,dev] -$ pre-commit install + $ pre-commit install Next install the requirements for running the auto-conversion script and generate the Pydra task interfaces from their Nipype counterparts @@ -93,7 +101,8 @@ The run the conversion script to convert Nipype interfaces to Pydra $ nipype-auto-conv/generate -## Methodology +Methodology +~~~~~~~~~~~ The development of this package is expected to have two phases diff --git a/nipype-auto-conv/generate b/nipype-auto-conv/generate index e77ca16..5265da9 100755 --- a/nipype-auto-conv/generate +++ b/nipype-auto-conv/generate @@ -6,9 +6,10 @@ from pathlib import Path import shutil from importlib import import_module import yaml +from tqdm import tqdm import nipype import nipype2pydra.utils -from nipype2pydra.task import TaskConverter +from nipype2pydra.task import get_converter SPECS_DIR = Path(__file__).parent / "specs" @@ -35,7 +36,10 @@ auto_dir = PKG_ROOT / "pydra" / "tasks" / PKG_NAME / "auto" if auto_dir.exists(): shutil.rmtree(auto_dir) -for fspath in sorted(SPECS_DIR.glob("**/*.yaml")): +all_interfaces = [] +for fspath in tqdm( + sorted(SPECS_DIR.glob("**/*.yaml")), "converting interfaces from Nipype to Pydra" +): with open(fspath) as f: spec = yaml.load(f, Loader=yaml.SafeLoader) @@ -49,13 +53,14 @@ for fspath in sorted(SPECS_DIR.glob("**/*.yaml")): module_name = nipype2pydra.utils.to_snake_case(spec["task_name"]) - converter = TaskConverter( + converter = get_converter( output_module=f"pydra.tasks.{PKG_NAME}.auto.{module_name}", callables_module=callables, # type: ignore **spec, ) converter.generate(PKG_ROOT) auto_init += f"from .{module_name} import {converter.task_name}\n" + all_interfaces.append(converter.task_name) with open(PKG_ROOT / "pydra" / "tasks" / PKG_NAME / "auto" / "_version.py", "w") as f: @@ -68,5 +73,9 @@ post_release = (nipype_version + nipype2pydra_version).replace(".", "") """ ) +auto_init += ( + "\n\n__all__ = [\n" + "\n".join(f' "{i}",' for i in all_interfaces) + "\n]\n" +) + with open(PKG_ROOT / "pydra" / "tasks" / PKG_NAME / "auto" / "__init__.py", "w") as f: f.write(auto_init) diff --git a/nipype-auto-conv/requirements.txt b/nipype-auto-conv/requirements.txt index fccc3a6..9858b15 100644 --- a/nipype-auto-conv/requirements.txt +++ b/nipype-auto-conv/requirements.txt @@ -1,6 +1,7 @@ black attrs>=22.1.0 nipype +tqdm pydra PyYAML>=6.0 fileformats >=0.8 diff --git a/nipype-auto-conv/specs/accuracy_tester.yaml b/nipype-auto-conv/specs/accuracy_tester.yaml index a900f0c..54388d1 100644 --- a/nipype-auto-conv/specs/accuracy_tester.yaml +++ b/nipype-auto-conv/specs/accuracy_tester.yaml @@ -23,13 +23,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - trained_wts_file: generic/file - # type=file|default=: trained-weights file mel_icas: generic/directory+list-of # type=inputmultiobject|default=[]: Melodic output directories - output_directory: generic/directory + output_directory: Path # type=directory: Path to folder in which to store the results of the accuracy test. # type=directory|default=: Path to folder in which to store the results of the accuracy test. + trained_wts_file: generic/file + # type=file|default=: trained-weights file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -69,7 +72,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/accuracy_tester_callables.py b/nipype-auto-conv/specs/accuracy_tester_callables.py index 5c3eb00..d6e4893 100644 --- a/nipype-auto-conv/specs/accuracy_tester_callables.py +++ b/nipype-auto-conv/specs/accuracy_tester_callables.py @@ -1 +1,28 @@ -"""Module to put any functions that are referred to in AccuracyTester.yaml""" +"""Module to put any functions that are referred to in the "callables" section of AccuracyTester.yaml""" + +import attrs +from fileformats.generic import Directory + + +def output_directory_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["output_directory"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L251 of /interfaces/fsl/fix.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.output_directory is not attrs.NOTHING: + outputs["output_directory"] = Directory( + exists=False, value=inputs.output_directory + ) + else: + outputs["output_directory"] = Directory(exists=False, value="accuracy_test") + return outputs diff --git a/nipype-auto-conv/specs/apply_mask.yaml b/nipype-auto-conv/specs/apply_mask.yaml index 617a7b3..53f7d01 100644 --- a/nipype-auto-conv/specs/apply_mask.yaml +++ b/nipype-auto-conv/specs/apply_mask.yaml @@ -20,10 +20,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mask_file: generic/file - # type=file|default=: binary image defining mask space in_file: generic/file # type=file|default=: image to operate on + mask_file: generic/file + # type=file|default=: binary image defining mask space + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -74,7 +80,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/apply_mask_callables.py b/nipype-auto-conv/specs/apply_mask_callables.py index ce0e94d..fcd5f27 100644 --- a/nipype-auto-conv/specs/apply_mask_callables.py +++ b/nipype-auto-conv/specs/apply_mask_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in ApplyMask.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ApplyMask.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/apply_topup.yaml b/nipype-auto-conv/specs/apply_topup.yaml index 29127fb..07ed94f 100644 --- a/nipype-auto-conv/specs/apply_topup.yaml +++ b/nipype-auto-conv/specs/apply_topup.yaml @@ -43,17 +43,20 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_files: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: name of file with images encoding_file: text/text-file # type=file|default=: name of text file with PE directions/times + in_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: name of file with images in_topup_fieldcoef: medimage/nifti-gz # type=file|default=: topup file containing the field coefficients in_topup_movpar: text/text-file # type=file|default=: topup movpar.txt file - out_corrected: generic/file + out_corrected: Path # type=file: name of 4D image file with unwarped images # type=file|default=: output (warped) image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -107,7 +110,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -135,7 +138,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -156,18 +159,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_files: + in_files: '["epi.nii", "epi_rev.nii"]' # type=inputmultiobject|default=[]: name of file with images - encoding_file: + encoding_file: '"topup_encoding.txt"' # type=file|default=: name of text file with PE directions/times - in_topup_fieldcoef: + in_topup_fieldcoef: '"topup_fieldcoef.nii.gz"' # type=file|default=: topup file containing the field coefficients - in_topup_movpar: + in_topup_movpar: '"topup_movpar.txt"' # type=file|default=: topup movpar.txt file output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/apply_topup_callables.py b/nipype-auto-conv/specs/apply_topup_callables.py index 62f411a..6ae5fc5 100644 --- a/nipype-auto-conv/specs/apply_topup_callables.py +++ b/nipype-auto-conv/specs/apply_topup_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in ApplyTOPUP.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ApplyTOPUP.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_corrected_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_corrected"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/apply_warp.yaml b/nipype-auto-conv/specs/apply_warp.yaml index 348c504..08f921e 100644 --- a/nipype-auto-conv/specs/apply_warp.yaml +++ b/nipype-auto-conv/specs/apply_warp.yaml @@ -33,18 +33,24 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: image to be warped - ref_file: generic/file - # type=file|default=: reference image field_file: generic/file # type=file|default=: file containing warp field - premat: generic/file - # type=file|default=: filename for pre-transform (affine matrix) - postmat: generic/file - # type=file|default=: filename for post-transform (affine matrix) + in_file: generic/file + # type=file|default=: image to be warped mask_file: generic/file # type=file|default=: filename for mask image (in reference space) + out_file: Path + # type=file: Warped output file + # type=file|default=: output filename + postmat: generic/file + # type=file|default=: filename for post-transform (affine matrix) + premat: generic/file + # type=file|default=: filename for pre-transform (affine matrix) + ref_file: generic/file + # type=file|default=: reference image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -109,7 +115,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/apply_warp_callables.py b/nipype-auto-conv/specs/apply_warp_callables.py index 827cf9f..6d2586d 100644 --- a/nipype-auto-conv/specs/apply_warp_callables.py +++ b/nipype-auto-conv/specs/apply_warp_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in ApplyWarp.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ApplyWarp.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1494 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "applywarp" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1486 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix="_warp", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs["out_file"] = os.path.abspath(inputs.out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/apply_xfm.yaml b/nipype-auto-conv/specs/apply_xfm.yaml index fa55e07..ae9ca24 100644 --- a/nipype-auto-conv/specs/apply_xfm.yaml +++ b/nipype-auto-conv/specs/apply_xfm.yaml @@ -39,37 +39,40 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + fieldmap: generic/file + # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image + fieldmapmask: generic/file + # type=file|default=: mask for fieldmap image in_file: generic/file # type=file|default=: input file - reference: generic/file - # type=file|default=: reference file - out_file: generic/file + in_matrix_file: generic/file + # type=file|default=: input 4x4 affine matrix + in_weight: generic/file + # type=file|default=: File for input weighting volume + out_file: Path # type=file: path/name of registered file (if generated) # type=file|default=: registered output file - out_matrix_file: generic/file - # type=file: path/name of calculated affine transform (if generated) - # type=file|default=: output affine matrix in 4x4 asciii format - out_log: generic/file + out_log: Path # type=file: path/name of output log (if generated) # type=file|default=: output log - in_matrix_file: generic/file - # type=file|default=: input 4x4 affine matrix - schedule: generic/file - # type=file|default=: replaces default schedule + out_matrix_file: Path + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format ref_weight: generic/file # type=file|default=: File for reference weighting volume - in_weight: generic/file - # type=file|default=: File for input weighting volume + reference: generic/file + # type=file|default=: reference file + schedule: generic/file + # type=file|default=: replaces default schedule wm_seg: generic/file # type=file|default=: white matter segmentation volume needed by BBR cost function wmcoords: generic/file # type=file|default=: white matter boundary coordinates for BBR cost function wmnorms: generic/file # type=file|default=: white matter boundary normals for BBR cost function - fieldmap: generic/file - # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image - fieldmapmask: generic/file - # type=file|default=: mask for fieldmap image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -86,12 +89,12 @@ outputs: out_file: generic/file # type=file: path/name of registered file (if generated) # type=file|default=: registered output file - out_matrix_file: generic/file - # type=file: path/name of calculated affine transform (if generated) - # type=file|default=: output affine matrix in 4x4 asciii format out_log: generic/file # type=file: path/name of output log (if generated) # type=file|default=: output log + out_matrix_file: generic/file + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -207,7 +210,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/apply_xfm_callables.py b/nipype-auto-conv/specs/apply_xfm_callables.py index 3b6054b..6b019b9 100644 --- a/nipype-auto-conv/specs/apply_xfm_callables.py +++ b/nipype-auto-conv/specs/apply_xfm_callables.py @@ -1 +1,352 @@ -"""Module to put any functions that are referred to in ApplyXFM.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ApplyXFM.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def out_log_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_log"] + + +def out_matrix_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_matrix_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/ar1_image.yaml b/nipype-auto-conv/specs/ar1_image.yaml index ac9b296..722dc9a 100644 --- a/nipype-auto-conv/specs/ar1_image.yaml +++ b/nipype-auto-conv/specs/ar1_image.yaml @@ -25,6 +25,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -75,7 +81,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/ar1_image_callables.py b/nipype-auto-conv/specs/ar1_image_callables.py index 7bd8155..aee1108 100644 --- a/nipype-auto-conv/specs/ar1_image_callables.py +++ b/nipype-auto-conv/specs/ar1_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in AR1Image.yaml""" +"""Module to put any functions that are referred to in the "callables" section of AR1Image.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/av_scale.yaml b/nipype-auto-conv/specs/av_scale.yaml index cc334ff..ca20362 100644 --- a/nipype-auto-conv/specs/av_scale.yaml +++ b/nipype-auto-conv/specs/av_scale.yaml @@ -34,6 +34,9 @@ inputs: # type=file|default=: mat file to read ref_file: generic/file # type=file|default=: reference file to get center of rotation + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -50,6 +53,12 @@ outputs: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields + average_scaling: average_scaling_callable + # type=float: Average Scaling + determinant: determinant_callable + # type=float: Determinant + left_right_orientation_preserved: left_right_orientation_preserved_callable + # type=bool: True if LR orientation preserved templates: # dict[str, str] - `output_file_template` values to be provided to output fields requirements: @@ -69,7 +78,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/av_scale_callables.py b/nipype-auto-conv/specs/av_scale_callables.py index 236bd30..a26202f 100644 --- a/nipype-auto-conv/specs/av_scale_callables.py +++ b/nipype-auto-conv/specs/av_scale_callables.py @@ -1 +1,81 @@ -"""Module to put any functions that are referred to in AvScale.yaml""" +"""Module to put any functions that are referred to in the "callables" section of AvScale.yaml""" + + +def average_scaling_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["average_scaling"] + + +def backward_half_transform_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["backward_half_transform"] + + +def determinant_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["determinant"] + + +def forward_half_transform_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["forward_half_transform"] + + +def left_right_orientation_preserved_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["left_right_orientation_preserved"] + + +def rot_angles_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["rot_angles"] + + +def rotation_translation_matrix_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["rotation_translation_matrix"] + + +def scales_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["scales"] + + +def skews_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["skews"] + + +def translations_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["translations"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L935 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + return _results diff --git a/nipype-auto-conv/specs/b0_calc.yaml b/nipype-auto-conv/specs/b0_calc.yaml index 103b9c1..a277b11 100644 --- a/nipype-auto-conv/specs/b0_calc.yaml +++ b/nipype-auto-conv/specs/b0_calc.yaml @@ -39,9 +39,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: filename of input image (usually a tissue/air segmentation) - out_file: generic/file + out_file: Path # type=file: filename of B0 output volume # type=file|default=: filename of B0 output volume + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -105,7 +108,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -129,7 +132,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -150,14 +153,14 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"tissue+air_map.nii"' # type=file|default=: filename of input image (usually a tissue/air segmentation) z_b0: '3.0' # type=float|default=1.0: Value for zeroth-order b0 field (z-component), in Tesla output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/b0_calc_callables.py b/nipype-auto-conv/specs/b0_calc_callables.py index 4c30d1f..1a08f4f 100644 --- a/nipype-auto-conv/specs/b0_calc_callables.py +++ b/nipype-auto-conv/specs/b0_calc_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in B0Calc.yaml""" +"""Module to put any functions that are referred to in the "callables" section of B0Calc.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/bedpostx5.yaml b/nipype-auto-conv/specs/bedpostx5.yaml index b25f1b6..8708280 100644 --- a/nipype-auto-conv/specs/bedpostx5.yaml +++ b/nipype-auto-conv/specs/bedpostx5.yaml @@ -43,20 +43,23 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - dwi: medimage/nifti1 - # type=file|default=: diffusion weighted image data file - mask: medimage/nifti1 - # type=file|default=: bet binary mask file - bvecs: medimage/bvec - # type=file|default=: b vectors file bvals: medimage/bval # type=file|default=: b values file + bvecs: medimage/bvec + # type=file|default=: b vectors file + dwi: medimage/nifti1 + # type=file|default=: diffusion weighted image data file grad_dev: generic/file # type=file|default=: grad_dev file, if gradnonlin, -g is True logdir: generic/directory # type=directory|default=: + mask: medimage/nifti1 + # type=file|default=: bet binary mask file out_dir: generic/directory # type=directory|default='bedpostx': output directory + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,10 +73,26 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mean_dsamples: generic/file - # type=file: Mean of distribution on diffusivity d + dyads: generic/file+list-of + # type=outputmultiobject: Mean of PDD distribution in vector form. + dyads_dispersion: generic/file+list-of + # type=outputmultiobject: Dispersion mean_S0samples: generic/file # type=file: Mean of distribution on T2wbaseline signal intensity S0 + mean_dsamples: generic/file + # type=file: Mean of distribution on diffusivity d + mean_fsamples: generic/file+list-of + # type=outputmultiobject: Mean of distribution on f anisotropy + mean_phsamples: generic/file+list-of + # type=outputmultiobject: Mean of distribution on phi + mean_thsamples: generic/file+list-of + # type=outputmultiobject: Mean of distribution on theta + merged_fsamples: generic/file+list-of + # type=outputmultiobject: Samples from the distribution on anisotropic volume fraction + merged_phsamples: generic/file+list-of + # type=outputmultiobject: Samples from the distribution on phi + merged_thsamples: generic/file+list-of + # type=outputmultiobject: Samples from the distribution on theta callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -146,7 +165,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -174,7 +193,7 @@ tests: n_fibres: '1' # type=range|default=2: Maximum number of fibres to fit in each voxel imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -195,18 +214,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - bvecs: + bvecs: '"bvecs"' # type=file|default=: b vectors file - bvals: + bvals: '"bvals"' # type=file|default=: b values file - dwi: + dwi: '"diffusion.nii"' # type=file|default=: diffusion weighted image data file - mask: + mask: '"mask.nii"' # type=file|default=: bet binary mask file n_fibres: '1' # type=range|default=2: Maximum number of fibres to fit in each voxel imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/bedpostx5_callables.py b/nipype-auto-conv/specs/bedpostx5_callables.py index 3f67f67..8525bc4 100644 --- a/nipype-auto-conv/specs/bedpostx5_callables.py +++ b/nipype-auto-conv/specs/bedpostx5_callables.py @@ -1 +1,481 @@ -"""Module to put any functions that are referred to in BEDPOSTX5.yaml""" +"""Module to put any functions that are referred to in the "callables" section of BEDPOSTX5.yaml""" + +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def dyads_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dyads"] + + +def dyads_dispersion_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dyads_dispersion"] + + +def mean_S0samples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_S0samples"] + + +def mean_dsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_dsamples"] + + +def mean_fsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_fsamples"] + + +def mean_phsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_phsamples"] + + +def mean_thsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_thsamples"] + + +def merged_fsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["merged_fsamples"] + + +def merged_phsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["merged_phsamples"] + + +def merged_thsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["merged_thsamples"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "bedpostx" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L483 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + n_fibres = inputs.n_fibres + + multi_out = [ + "merged_thsamples", + "merged_fsamples", + "merged_phsamples", + "mean_phsamples", + "mean_thsamples", + "mean_fsamples", + "dyads_dispersion", + "dyads", + ] + + single_out = ["mean_dsamples", "mean_S0samples"] + + for k in single_out: + outputs[k] = _gen_fname( + k, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + for k in multi_out: + outputs[k] = [] + + for i in range(1, n_fibres + 1): + outputs["merged_thsamples"].append( + _gen_fname( + "merged_th%dsamples" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["merged_fsamples"].append( + _gen_fname( + "merged_f%dsamples" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["merged_phsamples"].append( + _gen_fname( + "merged_ph%dsamples" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["mean_thsamples"].append( + _gen_fname( + "mean_th%dsamples" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["mean_phsamples"].append( + _gen_fname( + "mean_ph%dsamples" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["mean_fsamples"].append( + _gen_fname( + "mean_f%dsamples" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["dyads"].append( + _gen_fname( + "dyads%d" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["dyads_dispersion"].append( + _gen_fname( + "dyads%d_dispersion" % i, + cwd=_out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/bet.yaml b/nipype-auto-conv/specs/bet.yaml index e754808..9067cd2 100644 --- a/nipype-auto-conv/specs/bet.yaml +++ b/nipype-auto-conv/specs/bet.yaml @@ -38,8 +38,14 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: input file to skull strip + out_file: Path + # type=file: path/name of skullstripped file (if generated) + # type=file|default=: name of output skull stripped image t2_guided: generic/file # type=file|default=: as with creating surfaces, when also feeding in non-brain-extracted T2 (includes registrations) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -53,31 +59,31 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + inskull_mask_file: generic/file + # type=file: path/name of inskull mask (if generated) + inskull_mesh_file: generic/file + # type=file: path/name of inskull mesh outline (if generated) + mask_file: generic/file + # type=file: path/name of binary brain mask (if generated) + meshfile: generic/file + # type=file: path/name of vtk mesh file (if generated) out_file: medimage/nifti1 # type=file: path/name of skullstripped file (if generated) # type=file|default=: name of output skull stripped image - mask_file: generic/file - # type=file: path/name of binary brain mask (if generated) outline_file: generic/file # type=file: path/name of outline file (if generated) - meshfile: generic/file - # type=file: path/name of vtk mesh file (if generated) - inskull_mask_file: generic/file - # type=file: path/name of inskull mask (if generated) - inskull_mesh_file: generic/file - # type=file: path/name of inskull mesh outline (if generated) - outskull_mask_file: generic/file - # type=file: path/name of outskull mask (if generated) - outskull_mesh_file: generic/file - # type=file: path/name of outskull mesh outline (if generated) outskin_mask_file: generic/file # type=file: path/name of outskin mask (if generated) outskin_mesh_file: generic/file # type=file: path/name of outskin mesh outline (if generated) - skull_mask_file: generic/file - # type=file: path/name of skull mask (if generated) + outskull_mask_file: generic/file + # type=file: path/name of outskull mask (if generated) + outskull_mesh_file: generic/file + # type=file: path/name of outskull mesh outline (if generated) skull_file: generic/file # type=file: path/name of skull file (if generated) + skull_mask_file: generic/file + # type=file: path/name of skull mask (if generated) callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -138,7 +144,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -163,7 +169,7 @@ tests: # type=file: path/name of skullstripped file (if generated) # type=file|default=: name of output skull stripped image imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -184,7 +190,7 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"structural.nii"' # type=file|default=: input file to skull strip frac: '0.7' # type=float|default=0.0: fractional intensity threshold @@ -192,7 +198,7 @@ doctests: # type=file: path/name of skullstripped file (if generated) # type=file|default=: name of output skull stripped image imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/bet_callables.py b/nipype-auto-conv/specs/bet_callables.py index 8b4d7f5..6163733 100644 --- a/nipype-auto-conv/specs/bet_callables.py +++ b/nipype-auto-conv/specs/bet_callables.py @@ -1 +1,524 @@ -"""Module to put any functions that are referred to in BET.yaml""" +"""Module to put any functions that are referred to in the "callables" section of BET.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def inskull_mask_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["inskull_mask_file"] + + +def inskull_mesh_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["inskull_mesh_file"] + + +def mask_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mask_file"] + + +def meshfile_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["meshfile"] + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def outline_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["outline_file"] + + +def outskin_mask_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["outskin_mask_file"] + + +def outskin_mesh_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["outskin_mesh_file"] + + +def outskull_mask_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["outskull_mask_file"] + + +def outskull_mesh_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["outskull_mesh_file"] + + +def skull_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["skull_file"] + + +def skull_mask_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["skull_mask_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L232 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _gen_outfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "bet" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L176 of /interfaces/fsl/preprocess.py +def _gen_outfilename(inputs=None, stdout=None, stderr=None, output_dir=None): + out_file = inputs.out_file + # Generate default output filename if non specified. + if (out_file is attrs.NOTHING) and (inputs.in_file is not attrs.NOTHING): + out_file = _gen_fname( + inputs.in_file, + suffix="_brain", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + # Convert to relative path to prevent BET failure + # with long paths. + return op.relpath(out_file, start=output_dir) + return out_file + + +# Original source at L186 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = os.path.abspath( + _gen_outfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + ) + + basename = os.path.basename(outputs["out_file"]) + cwd = os.path.dirname(outputs["out_file"]) + kwargs = {"basename": basename, "cwd": cwd} + + if ((inputs.mesh is not attrs.NOTHING) and inputs.mesh) or ( + (inputs.surfaces is not attrs.NOTHING) and inputs.surfaces + ): + outputs["meshfile"] = _gen_fname( + suffix="_mesh.vtk", + change_ext=False, + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if ((inputs.mask is not attrs.NOTHING) and inputs.mask) or ( + (inputs.reduce_bias is not attrs.NOTHING) and inputs.reduce_bias + ): + outputs["mask_file"] = _gen_fname( + suffix="_mask", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if (inputs.outline is not attrs.NOTHING) and inputs.outline: + outputs["outline_file"] = _gen_fname( + suffix="_overlay", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if (inputs.surfaces is not attrs.NOTHING) and inputs.surfaces: + outputs["inskull_mask_file"] = _gen_fname( + suffix="_inskull_mask", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["inskull_mesh_file"] = _gen_fname( + suffix="_inskull_mesh", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["outskull_mask_file"] = _gen_fname( + suffix="_outskull_mask", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["outskull_mesh_file"] = _gen_fname( + suffix="_outskull_mesh", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["outskin_mask_file"] = _gen_fname( + suffix="_outskin_mask", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["outskin_mesh_file"] = _gen_fname( + suffix="_outskin_mesh", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["skull_mask_file"] = _gen_fname( + suffix="_skull_mask", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if (inputs.skull is not attrs.NOTHING) and inputs.skull: + outputs["skull_file"] = _gen_fname( + suffix="_skull", + **kwargs, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if (inputs.no_output is not attrs.NOTHING) and inputs.no_output: + outputs["out_file"] = attrs.NOTHING + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/binary_maths.yaml b/nipype-auto-conv/specs/binary_maths.yaml index 2ea42f0..bd135d3 100644 --- a/nipype-auto-conv/specs/binary_maths.yaml +++ b/nipype-auto-conv/specs/binary_maths.yaml @@ -23,10 +23,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - operand_file: generic/file - # type=file|default=: second image to perform operation with in_file: generic/file # type=file|default=: image to operate on + operand_file: generic/file + # type=file|default=: second image to perform operation with + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -81,7 +87,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/binary_maths_callables.py b/nipype-auto-conv/specs/binary_maths_callables.py index 68e6b72..ac159de 100644 --- a/nipype-auto-conv/specs/binary_maths_callables.py +++ b/nipype-auto-conv/specs/binary_maths_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in BinaryMaths.yaml""" +"""Module to put any functions that are referred to in the "callables" section of BinaryMaths.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/change_data_type.yaml b/nipype-auto-conv/specs/change_data_type.yaml index 07f91a5..e1c6460 100644 --- a/nipype-auto-conv/specs/change_data_type.yaml +++ b/nipype-auto-conv/specs/change_data_type.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,7 +76,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/change_data_type_callables.py b/nipype-auto-conv/specs/change_data_type_callables.py index 2eb3367..3af76c1 100644 --- a/nipype-auto-conv/specs/change_data_type_callables.py +++ b/nipype-auto-conv/specs/change_data_type_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in ChangeDataType.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ChangeDataType.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/classifier.yaml b/nipype-auto-conv/specs/classifier.yaml index 358635c..2b42cb0 100644 --- a/nipype-auto-conv/specs/classifier.yaml +++ b/nipype-auto-conv/specs/classifier.yaml @@ -22,13 +22,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - trained_wts_file: generic/file - # type=file|default=: trained-weights file - artifacts_list_file: generic/file + artifacts_list_file: Path # type=file: Text file listing which ICs are artifacts; can be the output from classification or can be created manually # type=file|default=: Text file listing which ICs are artifacts; can be the output from classification or can be created manually mel_ica: generic/directory # type=directory|default=: Melodic output directory or directories + trained_wts_file: generic/file + # type=file|default=: trained-weights file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,7 +73,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/classifier_callables.py b/nipype-auto-conv/specs/classifier_callables.py index 4f49e90..49a89d3 100644 --- a/nipype-auto-conv/specs/classifier_callables.py +++ b/nipype-auto-conv/specs/classifier_callables.py @@ -1 +1,42 @@ -"""Module to put any functions that are referred to in Classifier.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Classifier.yaml""" + +import os + + +def artifacts_list_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["artifacts_list_file"] + + +# Original source at L304 of /interfaces/fsl/fix.py +def _gen_artifacts_list_file( + mel_ica, thresh, inputs=None, stdout=None, stderr=None, output_dir=None +): + _, trained_wts_file = os.path.split(inputs.trained_wts_file) + trained_wts_filestem = trained_wts_file.split(".")[0] + filestem = "fix4melview_" + trained_wts_filestem + "_thr" + + fname = os.path.join(mel_ica, filestem + str(thresh) + ".txt") + return fname + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L312 of /interfaces/fsl/fix.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["artifacts_list_file"] = _gen_artifacts_list_file( + inputs.mel_ica, + inputs.thresh, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + return outputs diff --git a/nipype-auto-conv/specs/cleaner.yaml b/nipype-auto-conv/specs/cleaner.yaml index 8f1d242..6be0935 100644 --- a/nipype-auto-conv/specs/cleaner.yaml +++ b/nipype-auto-conv/specs/cleaner.yaml @@ -30,6 +30,9 @@ inputs: # type=file|default=: Include additional confound file. confound_file_2: generic/file # type=file|default=: Include additional confound file. + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -75,7 +78,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/cleaner_callables.py b/nipype-auto-conv/specs/cleaner_callables.py index 625e2af..8a8692c 100644 --- a/nipype-auto-conv/specs/cleaner_callables.py +++ b/nipype-auto-conv/specs/cleaner_callables.py @@ -1 +1,42 @@ -"""Module to put any functions that are referred to in Cleaner.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Cleaner.yaml""" + +import os + + +def cleaned_functional_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["cleaned_functional_file"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L376 of /interfaces/fsl/fix.py +def _get_cleaned_functional_filename( + artifacts_list_filename, inputs=None, stdout=None, stderr=None, output_dir=None +): + """extract the proper filename from the first line of the artifacts file""" + artifacts_list_file = open(artifacts_list_filename, "r") + functional_filename, extension = artifacts_list_file.readline().split(".") + artifacts_list_file_path, artifacts_list_filename = os.path.split( + artifacts_list_filename + ) + + return os.path.join(artifacts_list_file_path, functional_filename + "_clean.nii.gz") + + +# Original source at L388 of /interfaces/fsl/fix.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["cleaned_functional_file"] = _get_cleaned_functional_filename( + inputs.artifacts_list_file, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs diff --git a/nipype-auto-conv/specs/cluster.yaml b/nipype-auto-conv/specs/cluster.yaml index 82f5aad..0a2b28a 100644 --- a/nipype-auto-conv/specs/cluster.yaml +++ b/nipype-auto-conv/specs/cluster.yaml @@ -33,16 +33,19 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: medimage/nifti-gz - # type=file|default=: input volume cope_file: generic/file # type=file|default=: cope volume - xfm_file: generic/file - # type=file|default=: filename for Linear: input->standard-space transform. Non-linear: input->highres transform + in_file: medimage/nifti-gz + # type=file|default=: input volume std_space_file: generic/file # type=file|default=: filename for standard-space volume warpfield_file: generic/file # type=file|default=: file contining warpfield + xfm_file: generic/file + # type=file|default=: filename for Linear: input->standard-space transform. Non-linear: input->highres transform + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -58,20 +61,20 @@ outputs: # passed to the field in the automatically generated unittests. index_file: generic/file # type=file: output of cluster index (in size order) - threshold_file: generic/file - # type=file: thresholded image localmax_txt_file: generic/file # type=file: local maxima text file localmax_vol_file: generic/file # type=file: output of local maxima volume - size_file: generic/file - # type=file: filename for output of size image max_file: generic/file # type=file: filename for output of max image mean_file: generic/file # type=file: filename for output of mean image pval_file: generic/file # type=file: filename for image output of log pvals + size_file: generic/file + # type=file: filename for output of size image + threshold_file: generic/file + # type=file: thresholded image callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -140,7 +143,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -166,7 +169,7 @@ tests: use_mm: 'True' # type=bool|default=False: use mm, not voxel, coordinates imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -189,14 +192,14 @@ doctests: # '.mock()' method of the corresponding class is used instead. threshold: '2.3' # type=float|default=0.0: threshold for input volume - in_file: + in_file: '"zstat1.nii.gz"' # type=file|default=: input volume out_localmax_txt_file: '"stats.txt"' # type=traitcompound|default=None: local maxima text file use_mm: 'True' # type=bool|default=False: use mm, not voxel, coordinates imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/cluster_callables.py b/nipype-auto-conv/specs/cluster_callables.py index bca8cde..c6a7247 100644 --- a/nipype-auto-conv/specs/cluster_callables.py +++ b/nipype-auto-conv/specs/cluster_callables.py @@ -1 +1,379 @@ -"""Module to put any functions that are referred to in Cluster.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Cluster.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def index_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["index_file"] + + +def localmax_txt_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["localmax_txt_file"] + + +def localmax_vol_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["localmax_vol_file"] + + +def max_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["max_file"] + + +def mean_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_file"] + + +def pval_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["pval_file"] + + +def size_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["size_file"] + + +def threshold_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["threshold_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "cluster" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L2074 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + for key, suffix in list(filemap.items()): + outkey = key[4:] + inval = getattr(inputs, key) + if inval is not attrs.NOTHING: + if isinstance(inval, bool): + if inval: + change_ext = True + if suffix.endswith(".txt"): + change_ext = False + outputs[outkey] = _gen_fname( + inputs.in_file, + suffix="_" + suffix, + change_ext=change_ext, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs[outkey] = os.path.abspath(inval) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/complex.yaml b/nipype-auto-conv/specs/complex.yaml index cc22fea..1910446 100644 --- a/nipype-auto-conv/specs/complex.yaml +++ b/nipype-auto-conv/specs/complex.yaml @@ -35,14 +35,32 @@ inputs: # type=file|default=: complex_in_file2: generic/file # type=file|default=: - real_in_file: generic/file + complex_out_file: Path + # type=file: # type=file|default=: imaginary_in_file: generic/file # type=file|default=: + imaginary_out_file: Path + # type=file: + # type=file|default=: magnitude_in_file: generic/file # type=file|default=: + magnitude_out_file: Path + # type=file: + # type=file|default=: phase_in_file: generic/file # type=file|default=: + phase_out_file: Path + # type=file: + # type=file|default=: + real_in_file: generic/file + # type=file|default=: + real_out_file: Path + # type=file: + # type=file|default=: + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -56,19 +74,19 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - magnitude_out_file: generic/file + complex_out_file: generic/file # type=file: # type=file|default=: - phase_out_file: generic/file + imaginary_out_file: generic/file # type=file: # type=file|default=: - real_out_file: generic/file + magnitude_out_file: generic/file # type=file: # type=file|default=: - imaginary_out_file: generic/file + phase_out_file: generic/file # type=file: # type=file|default=: - complex_out_file: generic/file + real_out_file: generic/file # type=file: # type=file|default=: callables: @@ -79,6 +97,9 @@ outputs: complex_out_file: complex_out_file # type=file: # type=file|default=: + imaginary_out_file: imaginary_out_file + # type=file: + # type=file|default=: magnitude_out_file: magnitude_out_file # type=file: # type=file|default=: @@ -88,9 +109,6 @@ outputs: real_out_file: real_out_file # type=file: # type=file|default=: - imaginary_out_file: imaginary_out_file - # type=file: - # type=file|default=: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -147,7 +165,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/complex_callables.py b/nipype-auto-conv/specs/complex_callables.py index 566f01d..b8a505b 100644 --- a/nipype-auto-conv/specs/complex_callables.py +++ b/nipype-auto-conv/specs/complex_callables.py @@ -1 +1,464 @@ -"""Module to put any functions that are referred to in Complex.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Complex.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def complex_out_file_default(inputs): + return _gen_filename("complex_out_file", inputs=inputs) + + +def imaginary_out_file_default(inputs): + return _gen_filename("imaginary_out_file", inputs=inputs) + + +def magnitude_out_file_default(inputs): + return _gen_filename("magnitude_out_file", inputs=inputs) + + +def phase_out_file_default(inputs): + return _gen_filename("phase_out_file", inputs=inputs) + + +def real_out_file_default(inputs): + return _gen_filename("real_out_file", inputs=inputs) + + +def complex_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["complex_out_file"] + + +def imaginary_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["imaginary_out_file"] + + +def magnitude_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["magnitude_out_file"] + + +def phase_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["phase_out_file"] + + +def real_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["real_out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L2031 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "complex_out_file": + if inputs.complex_cartesian: + in_file = inputs.real_in_file + elif inputs.complex_polar: + in_file = inputs.magnitude_in_file + elif inputs.complex_split or inputs.complex_merge: + in_file = inputs.complex_in_file + else: + return None + return _gen_fname( + in_file, + suffix="_cplx", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif name == "magnitude_out_file": + return _gen_fname( + inputs.complex_in_file, + suffix="_mag", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif name == "phase_out_file": + return _gen_fname( + inputs.complex_in_file, + suffix="_phase", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif name == "real_out_file": + return _gen_fname( + inputs.complex_in_file, + suffix="_real", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif name == "imaginary_out_file": + return _gen_fname( + inputs.complex_in_file, + suffix="_imag", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslcomplex" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L2052 of /interfaces/fsl/utils.py +def _get_output(name, inputs=None, stdout=None, stderr=None, output_dir=None): + output = getattr(inputs, name) + if output is attrs.NOTHING: + output = _gen_filename( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + return os.path.abspath(output) + + +# Original source at L2058 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if ( + inputs.complex_cartesian + or inputs.complex_polar + or inputs.complex_split + or inputs.complex_merge + ): + outputs["complex_out_file"] = _get_output( + "complex_out_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif inputs.real_cartesian: + outputs["real_out_file"] = _get_output( + "real_out_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["imaginary_out_file"] = _get_output( + "imaginary_out_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif inputs.real_polar: + outputs["magnitude_out_file"] = _get_output( + "magnitude_out_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["phase_out_file"] = _get_output( + "phase_out_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/contrast_mgr.yaml b/nipype-auto-conv/specs/contrast_mgr.yaml index 18f8961..a3f5071 100644 --- a/nipype-auto-conv/specs/contrast_mgr.yaml +++ b/nipype-auto-conv/specs/contrast_mgr.yaml @@ -25,18 +25,21 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - tcon_file: generic/file - # type=file|default=: contrast file containing T-contrasts - fcon_file: generic/file - # type=file|default=: contrast file containing F-contrasts - param_estimates: generic/file+list-of - # type=inputmultiobject|default=[]: Parameter estimates for each column of the design matrix corrections: generic/file # type=file|default=: statistical corrections used within FILM modelling dof_file: generic/file # type=file|default=: degrees of freedom + fcon_file: generic/file + # type=file|default=: contrast file containing F-contrasts + param_estimates: generic/file+list-of + # type=inputmultiobject|default=[]: Parameter estimates for each column of the design matrix sigmasquareds: generic/file # type=file|default=: summary of residuals, See Woolrich, et. al., 2001 + tcon_file: generic/file + # type=file|default=: contrast file containing T-contrasts + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -50,6 +53,20 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + copes: generic/file+list-of + # type=outputmultiobject: Contrast estimates for each contrast + fstats: generic/file+list-of + # type=outputmultiobject: f-stat file for each contrast + neffs: generic/file+list-of + # type=outputmultiobject: neff file ?? for each contrast + tstats: generic/file+list-of + # type=outputmultiobject: t-stat file for each contrast + varcopes: generic/file+list-of + # type=outputmultiobject: Variance estimates for each contrast + zfstats: generic/file+list-of + # type=outputmultiobject: z-stat file for each F contrast + zstats: generic/file+list-of + # type=outputmultiobject: z-stat file for each contrast callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -84,7 +101,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/contrast_mgr_callables.py b/nipype-auto-conv/specs/contrast_mgr_callables.py index ff62f09..a2849d0 100644 --- a/nipype-auto-conv/specs/contrast_mgr_callables.py +++ b/nipype-auto-conv/specs/contrast_mgr_callables.py @@ -1 +1,468 @@ -"""Module to put any functions that are referred to in ContrastMgr.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ContrastMgr.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def copes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["copes"] + + +def fstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fstats"] + + +def neffs_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["neffs"] + + +def tstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tstats"] + + +def varcopes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["varcopes"] + + +def zfstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["zfstats"] + + +def zstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["zstats"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "contrast_mgr" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1301 of /interfaces/fsl/model.py +def _get_numcons(inputs=None, stdout=None, stderr=None, output_dir=None): + numtcons = 0 + numfcons = 0 + if inputs.tcon_file is not attrs.NOTHING: + fp = open(inputs.tcon_file, "rt") + for line in fp.readlines(): + if line.startswith("/NumContrasts"): + numtcons = int(line.split()[-1]) + break + fp.close() + if inputs.fcon_file is not attrs.NOTHING: + fp = open(inputs.fcon_file, "rt") + for line in fp.readlines(): + if line.startswith("/NumContrasts"): + numfcons = int(line.split()[-1]) + break + fp.close() + return numtcons, numfcons + + +# Original source at L1320 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + pth, _ = os.path.split(inputs.sigmasquareds) + numtcons, numfcons = _get_numcons( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + base_contrast = 1 + if inputs.contrast_num is not attrs.NOTHING: + base_contrast = inputs.contrast_num + copes = [] + varcopes = [] + zstats = [] + tstats = [] + neffs = [] + for i in range(numtcons): + copes.append( + _gen_fname( + "cope%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + varcopes.append( + _gen_fname( + "varcope%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + zstats.append( + _gen_fname( + "zstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + tstats.append( + _gen_fname( + "tstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + neffs.append( + _gen_fname( + "neff%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + if copes: + outputs["copes"] = copes + outputs["varcopes"] = varcopes + outputs["zstats"] = zstats + outputs["tstats"] = tstats + outputs["neffs"] = neffs + fstats = [] + zfstats = [] + for i in range(numfcons): + fstats.append( + _gen_fname( + "fstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + zfstats.append( + _gen_fname( + "zfstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + if fstats: + outputs["fstats"] = fstats + outputs["zfstats"] = zfstats + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/convert_warp.yaml b/nipype-auto-conv/specs/convert_warp.yaml index 498e441..e4d553f 100644 --- a/nipype-auto-conv/specs/convert_warp.yaml +++ b/nipype-auto-conv/specs/convert_warp.yaml @@ -38,23 +38,26 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - reference: medimage/nifti1 - # type=file|default=: Name of a file in target space of the full transform. - out_file: generic/file + midmat: generic/file + # type=file|default=: Name of file containing mid-warp-affine transform + out_file: Path # type=file: Name of output file, containing the warp as field or coefficients. # type=file|default=: Name of output file, containing warps that are the combination of all those given as arguments. The format of this will be a field-file (rather than spline coefficients) with any affine components included. + postmat: generic/file + # type=file|default=: Name of file containing an affine transform (applied last). It could e.g. be an affine transform that maps the MNI152-space into a better approximation to the Talairach-space (if indeed there is one). premat: generic/file # type=file|default=: filename for pre-transform (affine matrix) + reference: medimage/nifti1 + # type=file|default=: Name of a file in target space of the full transform. + shift_in_file: generic/file + # type=file|default=: Name of file containing a "shiftmap", a non-linear transform with displacements only in one direction (applied first, before premat). This would typically be a fieldmap that has been pre-processed using fugue that maps a subjects functional (EPI) data onto an undistorted space (i.e. a space that corresponds to his/her true anatomy). warp1: medimage/nifti1 # type=file|default=: Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects. - midmat: generic/file - # type=file|default=: Name of file containing mid-warp-affine transform warp2: generic/file # type=file|default=: Name of file containing secondary warp-fields/coefficients (after warp1/midmat but before postmat). This could e.g. be a fnirt-transform from the average of a group of subjects to some standard space (e.g. MNI152). - postmat: generic/file - # type=file|default=: Name of file containing an affine transform (applied last). It could e.g. be an affine transform that maps the MNI152-space into a better approximation to the Talairach-space (if indeed there is one). - shift_in_file: generic/file - # type=file|default=: Name of file containing a "shiftmap", a non-linear transform with displacements only in one direction (applied first, before premat). This would typically be a fieldmap that has been pre-processed using fugue that maps a subjects functional (EPI) data onto an undistorted space (i.e. a space that corresponds to his/her true anatomy). + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -122,7 +125,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -148,7 +151,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -169,16 +172,16 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - warp1: + warp1: '"warpfield.nii"' # type=file|default=: Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects. - reference: + reference: '"T1.nii"' # type=file|default=: Name of a file in target space of the full transform. relwarp: 'True' # type=bool|default=False: If set it indicates that the warps in --warp1/2 should be interpreted as relative. I.e. the values in --warp1/2 are displacements from the coordinates in the next space. output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/convert_warp_callables.py b/nipype-auto-conv/specs/convert_warp_callables.py index b6a046c..bb15f5b 100644 --- a/nipype-auto-conv/specs/convert_warp_callables.py +++ b/nipype-auto-conv/specs/convert_warp_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in ConvertWarp.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ConvertWarp.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/convert_xfm.yaml b/nipype-auto-conv/specs/convert_xfm.yaml index 19f5a17..6cc22d8 100644 --- a/nipype-auto-conv/specs/convert_xfm.yaml +++ b/nipype-auto-conv/specs/convert_xfm.yaml @@ -38,6 +38,12 @@ inputs: # type=file|default=: input transformation matrix in_file2: generic/file # type=file|default=: second input matrix (for use with fix_scale_skew or concat_xfm) + out_file: Path + # type=file: output transformation matrix + # type=file|default=: final transformation matrix + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -88,7 +94,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -113,7 +119,7 @@ tests: # type=file: output transformation matrix # type=file|default=: final transformation matrix imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.interfaces.fsl as fsl expected_outputs: @@ -135,7 +141,7 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"flirt.mat"' # type=file|default=: input transformation matrix invert_xfm: 'True' # type=bool|default=False: invert input transformation @@ -143,7 +149,7 @@ doctests: # type=file: output transformation matrix # type=file|default=: final transformation matrix imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/convert_xfm_callables.py b/nipype-auto-conv/specs/convert_xfm_callables.py index c81ca18..374e76f 100644 --- a/nipype-auto-conv/specs/convert_xfm_callables.py +++ b/nipype-auto-conv/specs/convert_xfm_callables.py @@ -1 +1,147 @@ -"""Module to put any functions that are referred to in ConvertXFM.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ConvertXFM.yaml""" + +import attrs +import os +import os.path as op +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +# Original source at L1592 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L1567 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outfile = inputs.out_file + if outfile is attrs.NOTHING: + _, infile1, _ = split_filename(inputs.in_file) + if inputs.invert_xfm: + outfile = fname_presuffix( + infile1, suffix="_inv.mat", newpath=output_dir, use_ext=False + ) + else: + if inputs.concat_xfm: + _, infile2, _ = split_filename(inputs.in_file2) + outfile = fname_presuffix( + "%s_%s" % (infile1, infile2), + suffix=".mat", + newpath=output_dir, + use_ext=False, + ) + else: + outfile = fname_presuffix( + infile1, suffix="_fix.mat", newpath=output_dir, use_ext=False + ) + outputs["out_file"] = os.path.abspath(outfile) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext diff --git a/nipype-auto-conv/specs/copy_geom.yaml b/nipype-auto-conv/specs/copy_geom.yaml index e5714c6..677859c 100644 --- a/nipype-auto-conv/specs/copy_geom.yaml +++ b/nipype-auto-conv/specs/copy_geom.yaml @@ -27,10 +27,13 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: source image dest_file: generic/file # type=file|default=: destination image + in_file: generic/file + # type=file|default=: source image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,7 +73,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/copy_geom_callables.py b/nipype-auto-conv/specs/copy_geom_callables.py index 384cdef..f1ae1c9 100644 --- a/nipype-auto-conv/specs/copy_geom_callables.py +++ b/nipype-auto-conv/specs/copy_geom_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in CopyGeom.yaml""" +"""Module to put any functions that are referred to in the "callables" section of CopyGeom.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/dilate_image.yaml b/nipype-auto-conv/specs/dilate_image.yaml index 1bf03b5..5f29bf3 100644 --- a/nipype-auto-conv/specs/dilate_image.yaml +++ b/nipype-auto-conv/specs/dilate_image.yaml @@ -20,10 +20,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - kernel_file: generic/file - # type=file|default=: use external file for kernel in_file: generic/file # type=file|default=: image to operate on + kernel_file: generic/file + # type=file|default=: use external file for kernel + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -80,7 +86,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/dilate_image_callables.py b/nipype-auto-conv/specs/dilate_image_callables.py index a27b1b0..db0f502 100644 --- a/nipype-auto-conv/specs/dilate_image_callables.py +++ b/nipype-auto-conv/specs/dilate_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in DilateImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of DilateImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/distance_map.yaml b/nipype-auto-conv/specs/distance_map.yaml index b2486ad..d027bbd 100644 --- a/nipype-auto-conv/specs/distance_map.yaml +++ b/nipype-auto-conv/specs/distance_map.yaml @@ -31,10 +31,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + distance_map: Path + # type=file: value is distance to nearest nonzero voxels + # type=file|default=: distance map to write in_file: generic/file # type=file|default=: image to calculate distance values for mask_file: generic/file # type=file|default=: binary mask to constrain calculations + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -87,7 +93,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/distance_map_callables.py b/nipype-auto-conv/specs/distance_map_callables.py index e8ef0b5..f12fbb6 100644 --- a/nipype-auto-conv/specs/distance_map_callables.py +++ b/nipype-auto-conv/specs/distance_map_callables.py @@ -1 +1,147 @@ -"""Module to put any functions that are referred to in DistanceMap.yaml""" +"""Module to put any functions that are referred to in the "callables" section of DistanceMap.yaml""" + +import attrs +import os +import os.path as op +from pathlib import Path + + +def distance_map_default(inputs): + return _gen_filename("distance_map", inputs=inputs) + + +def distance_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["distance_map"] + + +def local_max_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["local_max_file"] + + +# Original source at L1537 of /interfaces/fsl/dti.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "distance_map": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["distance_map"] + return None + + +# Original source at L1519 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + _si = inputs + outputs["distance_map"] = _si.distance_map + if _si.distance_map is attrs.NOTHING: + outputs["distance_map"] = fname_presuffix( + _si.in_file, suffix="_dstmap", use_ext=True, newpath=output_dir + ) + outputs["distance_map"] = os.path.abspath(outputs["distance_map"]) + if _si.local_max_file is not attrs.NOTHING: + outputs["local_max_file"] = _si.local_max_file + if isinstance(_si.local_max_file, bool): + outputs["local_max_file"] = fname_presuffix( + _si.in_file, suffix="_lclmax", use_ext=True, newpath=output_dir + ) + outputs["local_max_file"] = os.path.abspath(outputs["local_max_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext diff --git a/nipype-auto-conv/specs/dti_fit.yaml b/nipype-auto-conv/specs/dti_fit.yaml index 9ace4d9..19a0a2e 100644 --- a/nipype-auto-conv/specs/dti_fit.yaml +++ b/nipype-auto-conv/specs/dti_fit.yaml @@ -36,18 +36,21 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - dwi: medimage/nifti1 - # type=file|default=: diffusion weighted image data file - mask: medimage/nifti1 - # type=file|default=: bet binary mask file - bvecs: medimage/bvec - # type=file|default=: b vectors file bvals: medimage/bval # type=file|default=: b values file + bvecs: medimage/bvec + # type=file|default=: b vectors file cni: generic/file # type=file|default=: input counfound regressors + dwi: medimage/nifti1 + # type=file|default=: diffusion weighted image data file gradnonlin: generic/file # type=file|default=: gradient non linearities + mask: medimage/nifti1 + # type=file|default=: bet binary mask file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -61,12 +64,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - V1: generic/file - # type=file: path/name of file with the 1st eigenvector - V2: generic/file - # type=file: path/name of file with the 2nd eigenvector - V3: generic/file - # type=file: path/name of file with the 3rd eigenvector + FA: generic/file + # type=file: path/name of file with the fractional anisotropy L1: generic/file # type=file: path/name of file with the 1st eigenvalue L2: generic/file @@ -75,17 +74,21 @@ outputs: # type=file: path/name of file with the 3rd eigenvalue MD: generic/file # type=file: path/name of file with the mean diffusivity - FA: generic/file - # type=file: path/name of file with the fractional anisotropy MO: generic/file # type=file: path/name of file with the mode of anisotropy S0: generic/file # type=file: path/name of file with the raw T2 signal with no diffusion weighting - tensor: generic/file - # type=file: path/name of file with the 4D tensor volume + V1: generic/file + # type=file: path/name of file with the 1st eigenvector + V2: generic/file + # type=file: path/name of file with the 2nd eigenvector + V3: generic/file + # type=file: path/name of file with the 3rd eigenvector sse: generic/file # type=file: path/name of file with the summed squared error # type=bool|default=False: output sum of squared errors + tensor: generic/file + # type=file: path/name of file with the 4D tensor volume callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -137,7 +140,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -165,7 +168,7 @@ tests: mask: # type=file|default=: bet binary mask file imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -186,18 +189,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - dwi: + dwi: '"diffusion.nii"' # type=file|default=: diffusion weighted image data file - bvecs: + bvecs: '"bvecs"' # type=file|default=: b vectors file - bvals: + bvals: '"bvals"' # type=file|default=: b values file base_name: '"TP"' # type=str|default='dtifit_': base_name that all output files will start with - mask: + mask: '"mask.nii"' # type=file|default=: bet binary mask file imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/dti_fit_callables.py b/nipype-auto-conv/specs/dti_fit_callables.py index 5d71e93..7037322 100644 --- a/nipype-auto-conv/specs/dti_fit_callables.py +++ b/nipype-auto-conv/specs/dti_fit_callables.py @@ -1 +1,407 @@ -"""Module to put any functions that are referred to in DTIFit.yaml""" +"""Module to put any functions that are referred to in the "callables" section of DTIFit.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def FA_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["FA"] + + +def L1_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["L1"] + + +def L2_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["L2"] + + +def L3_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["L3"] + + +def MD_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["MD"] + + +def MO_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["MO"] + + +def S0_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["S0"] + + +def V1_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["V1"] + + +def V2_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["V2"] + + +def V3_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["V3"] + + +def sse_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["sse"] + + +def tensor_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tensor"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "dtifit" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L114 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + keys_to_ignore = {"outputtype", "environ", "args"} + # Optional output: Map output name to input flag + opt_output = {"tensor": inputs.save_tensor, "sse": inputs.sse} + # Ignore optional output, whose corresponding input-flag is not defined + # or set to False + for output, input_flag in opt_output.items(): + if (input_flag is not attrs.NOTHING) and input_flag: + # this is wanted output, do not ignore + continue + keys_to_ignore.add(output) + + outputs = {} + for k in set(outputs.keys()) - keys_to_ignore: + outputs[k] = _gen_fname( + inputs.base_name, + suffix="_" + k, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/dual_regression.yaml b/nipype-auto-conv/specs/dual_regression.yaml index 3630a78..06b866e 100644 --- a/nipype-auto-conv/specs/dual_regression.yaml +++ b/nipype-auto-conv/specs/dual_regression.yaml @@ -36,14 +36,20 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_files: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets - group_IC_maps_4D: medimage/nifti1 - # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis - design_file: generic/file - # type=file|default=: Design matrix for final cross-subject modelling with randomise con_file: generic/file # type=file|default=: Design contrasts for final cross-subject modelling with randomise + design_file: generic/file + # type=file|default=: Design matrix for final cross-subject modelling with randomise + group_IC_maps_4D: medimage/nifti1 + # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis + in_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets + out_dir: Path + # type=directory: + # type=directory|default='output': This directory will be created to hold all output and logfiles + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -98,7 +104,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -129,7 +135,7 @@ tests: # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -150,9 +156,9 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_files: + in_files: '["functional.nii", "functional2.nii", "functional3.nii"]' # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets - group_IC_maps_4D: + group_IC_maps_4D: '"allFA.nii"' # type=file|default=: 4D image containing spatial IC maps (melodic_IC) from the whole-group ICA analysis des_norm: 'False' # type=bool|default=True: Whether to variance-normalise the timecourses used as the stage-2 regressors; True is default and recommended @@ -164,7 +170,7 @@ doctests: # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/dual_regression_callables.py b/nipype-auto-conv/specs/dual_regression_callables.py index 1e6cc35..55ed558 100644 --- a/nipype-auto-conv/specs/dual_regression_callables.py +++ b/nipype-auto-conv/specs/dual_regression_callables.py @@ -1 +1,37 @@ -"""Module to put any functions that are referred to in DualRegression.yaml""" +"""Module to put any functions that are referred to in the "callables" section of DualRegression.yaml""" + +import attrs +import os + + +def out_dir_default(inputs): + return _gen_filename("out_dir", inputs=inputs) + + +def out_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_dir"] + + +# Original source at L2198 of /interfaces/fsl/model.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_dir": + return output_dir + + +# Original source at L2190 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.out_dir is not attrs.NOTHING: + outputs["out_dir"] = os.path.abspath(inputs.out_dir) + else: + outputs["out_dir"] = _gen_filename( + "out_dir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs diff --git a/nipype-auto-conv/specs/eddy.yaml b/nipype-auto-conv/specs/eddy.yaml index 7ae120f..368ad6b 100644 --- a/nipype-auto-conv/specs/eddy.yaml +++ b/nipype-auto-conv/specs/eddy.yaml @@ -58,32 +58,35 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: medimage/nifti1 - # type=file|default=: File containing all the images to estimate distortions for - in_mask: generic/file - # type=file|default=: Mask to indicate brain - in_index: text/text-file - # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + field: generic/file + # type=file|default=: Non-topup derived fieldmap scaled in Hz + field_mat: generic/file + # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain in_acqp: generic/file # type=file|default=: File containing acquisition parameters - in_bvec: generic/file - # type=file|default=: File containing the b-vectors for all volumes in --imain in_bval: generic/file # type=file|default=: File containing the b-values for all volumes in --imain - session: generic/file - # type=file|default=: File containing session indices for all volumes in --imain + in_bvec: generic/file + # type=file|default=: File containing the b-vectors for all volumes in --imain + in_file: medimage/nifti1 + # type=file|default=: File containing all the images to estimate distortions for + in_index: text/text-file + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + in_mask: generic/file + # type=file|default=: Mask to indicate brain in_topup_fieldcoef: generic/file # type=file|default=: Topup results file containing the field coefficients in_topup_movpar: generic/file # type=file|default=: Topup results file containing the movement parameters (movpar.txt) - field: generic/file - # type=file|default=: Non-topup derived fieldmap scaled in Hz - field_mat: generic/file - # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain - slice_order: text/text-file - # type=file|default='': Name of text file completely specifying slice/group acquisition json: generic/file # type=file|default='': Name of .json text file with information about slice timing + session: generic/file + # type=file|default=: File containing session indices for all volumes in --imain + slice_order: text/text-file + # type=file|default='': Name of text file completely specifying slice/group acquisition + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -97,36 +100,36 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_cnr_maps: generic/file + # type=file: path/name of file with the cnr_maps out_corrected: generic/file # type=file: 4D image file containing all the corrected volumes - out_parameter: generic/file - # type=file: Text file with parameters defining the field and movement for each scan - out_rotated_bvecs: generic/file - # type=file: File containing rotated b-values for all volumes + out_movement_over_time: generic/file + # type=file: Text file containing translations (mm) and rotations (radians) for each excitation out_movement_rms: generic/file # type=file: Summary of the 'total movement' in each volume - out_restricted_movement_rms: generic/file - # type=file: Summary of the 'total movement' in each volume disregarding translation in the PE direction - out_shell_alignment_parameters: generic/file - # type=file: Text file containing rigid body movement parameters between the different shells as estimated by a post-hoc mutual information based registration - out_shell_pe_translation_parameters: generic/file - # type=file: Text file containing translation along the PE-direction between the different shells as estimated by a post-hoc mutual information based registration + out_outlier_free: generic/file + # type=file: 4D image file not corrected for susceptibility or eddy-current distortions or subject movement but with outlier slices replaced out_outlier_map: generic/file # type=file: Matrix where rows represent volumes and columns represent slices. "0" indicates that scan-slice is not an outlier and "1" indicates that it is - out_outlier_n_stdev_map: generic/file - # type=file: Matrix where rows represent volumes and columns represent slices. Values indicate number of standard deviations off the mean difference between observation and prediction is out_outlier_n_sqr_stdev_map: generic/file # type=file: Matrix where rows represent volumes and columns represent slices. Values indicate number of standard deivations off the square root of the mean squared difference between observation and prediction is + out_outlier_n_stdev_map: generic/file + # type=file: Matrix where rows represent volumes and columns represent slices. Values indicate number of standard deviations off the mean difference between observation and prediction is out_outlier_report: generic/file # type=file: Text file with a plain language report on what outlier slices eddy has found - out_outlier_free: generic/file - # type=file: 4D image file not corrected for susceptibility or eddy-current distortions or subject movement but with outlier slices replaced - out_movement_over_time: generic/file - # type=file: Text file containing translations (mm) and rotations (radians) for each excitation - out_cnr_maps: generic/file - # type=file: path/name of file with the cnr_maps + out_parameter: generic/file + # type=file: Text file with parameters defining the field and movement for each scan out_residuals: generic/file # type=file: path/name of file with the residuals + out_restricted_movement_rms: generic/file + # type=file: Summary of the 'total movement' in each volume disregarding translation in the PE direction + out_rotated_bvecs: generic/file + # type=file: File containing rotated b-values for all volumes + out_shell_alignment_parameters: generic/file + # type=file: Text file containing rigid body movement parameters between the different shells as estimated by a post-hoc mutual information based registration + out_shell_pe_translation_parameters: generic/file + # type=file: Text file containing translation along the PE-direction between the different shells as estimated by a post-hoc mutual information based registration callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -239,7 +242,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -261,7 +264,7 @@ tests: in_index: # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -281,7 +284,7 @@ tests: use_cuda: 'True' # type=bool|default=False: Run eddy using cuda gpu imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -309,7 +312,7 @@ tests: slice_order: # type=file|default='': Name of text file completely specifying slice/group acquisition imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -330,12 +333,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"epi.nii"' # type=file|default=: File containing all the images to estimate distortions for - in_index: + in_index: '"epi_index.txt"' # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS @@ -348,7 +351,7 @@ doctests: use_cuda: 'True' # type=bool|default=False: Run eddy using cuda gpu imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS @@ -366,10 +369,10 @@ doctests: # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) slice2vol_interp: '"trilinear"' # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step - slice_order: + slice_order: '"epi_slspec.txt"' # type=file|default='': Name of text file completely specifying slice/group acquisition imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_callables.py b/nipype-auto-conv/specs/eddy_callables.py index 8b90e54..1fc233f 100644 --- a/nipype-auto-conv/specs/eddy_callables.py +++ b/nipype-auto-conv/specs/eddy_callables.py @@ -1 +1,185 @@ -"""Module to put any functions that are referred to in Eddy.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Eddy.yaml""" + +import attrs +import os + + +def out_cnr_maps_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_cnr_maps"] + + +def out_corrected_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_corrected"] + + +def out_movement_over_time_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_movement_over_time"] + + +def out_movement_rms_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_movement_rms"] + + +def out_outlier_free_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_outlier_free"] + + +def out_outlier_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_outlier_map"] + + +def out_outlier_n_sqr_stdev_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_outlier_n_sqr_stdev_map"] + + +def out_outlier_n_stdev_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_outlier_n_stdev_map"] + + +def out_outlier_report_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_outlier_report"] + + +def out_parameter_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_parameter"] + + +def out_residuals_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_residuals"] + + +def out_restricted_movement_rms_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_restricted_movement_rms"] + + +def out_rotated_bvecs_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_rotated_bvecs"] + + +def out_shell_alignment_parameters_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_shell_alignment_parameters"] + + +def out_shell_pe_translation_parameters_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_shell_pe_translation_parameters"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L1008 of /interfaces/fsl/epi.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_corrected"] = os.path.abspath("%s.nii.gz" % inputs.out_base) + outputs["out_parameter"] = os.path.abspath("%s.eddy_parameters" % inputs.out_base) + + # File generation might depend on the version of EDDY + out_rotated_bvecs = os.path.abspath("%s.eddy_rotated_bvecs" % inputs.out_base) + out_movement_rms = os.path.abspath("%s.eddy_movement_rms" % inputs.out_base) + out_restricted_movement_rms = os.path.abspath( + "%s.eddy_restricted_movement_rms" % inputs.out_base + ) + out_shell_alignment_parameters = os.path.abspath( + "%s.eddy_post_eddy_shell_alignment_parameters" % inputs.out_base + ) + out_shell_pe_translation_parameters = os.path.abspath( + "%s.eddy_post_eddy_shell_PE_translation_parameters" % inputs.out_base + ) + out_outlier_map = os.path.abspath("%s.eddy_outlier_map" % inputs.out_base) + out_outlier_n_stdev_map = os.path.abspath( + "%s.eddy_outlier_n_stdev_map" % inputs.out_base + ) + out_outlier_n_sqr_stdev_map = os.path.abspath( + "%s.eddy_outlier_n_sqr_stdev_map" % inputs.out_base + ) + out_outlier_report = os.path.abspath("%s.eddy_outlier_report" % inputs.out_base) + if (inputs.repol is not attrs.NOTHING) and inputs.repol: + out_outlier_free = os.path.abspath( + "%s.eddy_outlier_free_data" % inputs.out_base + ) + if os.path.exists(out_outlier_free): + outputs["out_outlier_free"] = out_outlier_free + if (inputs.mporder is not attrs.NOTHING) and inputs.mporder > 0: + out_movement_over_time = os.path.abspath( + "%s.eddy_movement_over_time" % inputs.out_base + ) + if os.path.exists(out_movement_over_time): + outputs["out_movement_over_time"] = out_movement_over_time + if (inputs.cnr_maps is not attrs.NOTHING) and inputs.cnr_maps: + out_cnr_maps = os.path.abspath("%s.eddy_cnr_maps.nii.gz" % inputs.out_base) + if os.path.exists(out_cnr_maps): + outputs["out_cnr_maps"] = out_cnr_maps + if (inputs.residuals is not attrs.NOTHING) and inputs.residuals: + out_residuals = os.path.abspath("%s.eddy_residuals.nii.gz" % inputs.out_base) + if os.path.exists(out_residuals): + outputs["out_residuals"] = out_residuals + + if os.path.exists(out_rotated_bvecs): + outputs["out_rotated_bvecs"] = out_rotated_bvecs + if os.path.exists(out_movement_rms): + outputs["out_movement_rms"] = out_movement_rms + if os.path.exists(out_restricted_movement_rms): + outputs["out_restricted_movement_rms"] = out_restricted_movement_rms + if os.path.exists(out_shell_alignment_parameters): + outputs["out_shell_alignment_parameters"] = out_shell_alignment_parameters + if os.path.exists(out_shell_pe_translation_parameters): + outputs["out_shell_pe_translation_parameters"] = ( + out_shell_pe_translation_parameters + ) + if os.path.exists(out_outlier_map): + outputs["out_outlier_map"] = out_outlier_map + if os.path.exists(out_outlier_n_stdev_map): + outputs["out_outlier_n_stdev_map"] = out_outlier_n_stdev_map + if os.path.exists(out_outlier_n_sqr_stdev_map): + outputs["out_outlier_n_sqr_stdev_map"] = out_outlier_n_sqr_stdev_map + if os.path.exists(out_outlier_report): + outputs["out_outlier_report"] = out_outlier_report + + return outputs diff --git a/nipype-auto-conv/specs/eddy_correct.yaml b/nipype-auto-conv/specs/eddy_correct.yaml index a3bde33..6094f53 100644 --- a/nipype-auto-conv/specs/eddy_correct.yaml +++ b/nipype-auto-conv/specs/eddy_correct.yaml @@ -36,8 +36,11 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: 4D input file - out_file: medimage/nifti1 + out_file: Path # type=file|default=: 4D output file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -77,7 +80,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -96,12 +99,12 @@ tests: # (if not specified, will try to choose a sensible value) in_file: # type=file|default=: 4D input file - out_file: + out_file: '"diffusion_edc.nii"' # type=file|default=: 4D output file ref_num: '0' # type=int|default=0: reference number imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -122,14 +125,14 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"diffusion.nii"' # type=file|default=: 4D input file - out_file: + out_file: '"diffusion_edc.nii"' # type=file|default=: 4D output file ref_num: '0' # type=int|default=0: reference number imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_correct_callables.py b/nipype-auto-conv/specs/eddy_correct_callables.py index dfb3b96..209f413 100644 --- a/nipype-auto-conv/specs/eddy_correct_callables.py +++ b/nipype-auto-conv/specs/eddy_correct_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in EddyCorrect.yaml""" +"""Module to put any functions that are referred to in the "callables" section of EddyCorrect.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def eddy_corrected_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["eddy_corrected"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/eddy_quad.yaml b/nipype-auto-conv/specs/eddy_quad.yaml index 833fa37..916b9fd 100644 --- a/nipype-auto-conv/specs/eddy_quad.yaml +++ b/nipype-auto-conv/specs/eddy_quad.yaml @@ -43,20 +43,23 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - idx_file: generic/file - # type=file|default=: File containing indices for all volumes into acquisition parameters - param_file: text/text-file - # type=file|default=: File containing acquisition parameters - mask_file: generic/file - # type=file|default=: Binary mask file bval_file: generic/file # type=file|default=: b-values file bvec_file: generic/file # type=file|default=: b-vectors file - only used when .eddy_residuals file is present field: generic/file # type=file|default=: TOPUP estimated field (in Hz) + idx_file: generic/file + # type=file|default=: File containing indices for all volumes into acquisition parameters + mask_file: generic/file + # type=file|default=: Binary mask file + param_file: text/text-file + # type=file|default=: File containing acquisition parameters slice_spec: generic/file # type=file|default=: Text file specifying slice/group acquisition + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,16 +73,22 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + avg_b0_pe_png: generic/file+list-of + # type=list: Image showing mid-sagittal, -coronal and -axial slices of each averaged pe-direction b0 volume. Generated when using the -f option. + avg_b_png: generic/file+list-of + # type=list: Image showing mid-sagittal, -coronal and -axial slices of each averaged b-shell volume. + clean_volumes: generic/file + # type=file: Text file containing a list of clean volumes, based on the eddy squared residuals. To generate a version of the pre-processed dataset without outlier volumes, use: `fslselectvols -i -o eddy_corrected_data_clean --vols=vols_no_outliers.txt` + cnr_png: generic/file+list-of + # type=list: Image showing mid-sagittal, -coronal and -axial slices of each b-shell CNR volume. Generated when CNR maps are available. qc_json: generic/file # type=file: Single subject database containing quality metrics and data info. qc_pdf: generic/file # type=file: Single subject QC report. - vdm_png: generic/file - # type=file: Image showing mid-sagittal, -coronal and -axial slices of the voxel displacement map. Generated when using the -f option. residuals: generic/file # type=file: Text file containing the volume-wise mask-averaged squared residuals. Generated when residual maps are available. - clean_volumes: generic/file - # type=file: Text file containing a list of clean volumes, based on the eddy squared residuals. To generate a version of the pre-processed dataset without outlier volumes, use: `fslselectvols -i -o eddy_corrected_data_clean --vols=vols_no_outliers.txt` + vdm_png: generic/file + # type=file: Image showing mid-sagittal, -coronal and -axial slices of the voxel displacement map. Generated when using the -f option. callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -118,7 +127,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -140,7 +149,7 @@ tests: output_dir: '"eddy_corrected.qc"' # type=str|default='': Output directory - default = '.qc' imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -161,12 +170,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - param_file: + param_file: '"epi_acqp.txt"' # type=file|default=: File containing acquisition parameters output_dir: '"eddy_corrected.qc"' # type=str|default='': Output directory - default = '.qc' imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_quad_callables.py b/nipype-auto-conv/specs/eddy_quad_callables.py index 1720ae1..daf563b 100644 --- a/nipype-auto-conv/specs/eddy_quad_callables.py +++ b/nipype-auto-conv/specs/eddy_quad_callables.py @@ -1 +1,111 @@ -"""Module to put any functions that are referred to in EddyQuad.yaml""" +"""Module to put any functions that are referred to in the "callables" section of EddyQuad.yaml""" + +import attrs +import os +from glob import glob + + +def avg_b0_pe_png_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["avg_b0_pe_png"] + + +def avg_b_png_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["avg_b_png"] + + +def clean_volumes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["clean_volumes"] + + +def cnr_png_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["cnr_png"] + + +def qc_json_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["qc_json"] + + +def qc_pdf_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["qc_pdf"] + + +def residuals_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["residuals"] + + +def vdm_png_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["vdm_png"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L1673 of /interfaces/fsl/epi.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + from glob import glob + + outputs = {} + + # If the output directory isn't defined, the interface seems to use + # the default but not set its value in `inputs.output_dir` + if inputs.output_dir is attrs.NOTHING: + out_dir = os.path.abspath(os.path.basename(inputs.base_name) + ".qc") + else: + out_dir = os.path.abspath(inputs.output_dir) + + outputs["qc_json"] = os.path.join(out_dir, "qc.json") + outputs["qc_pdf"] = os.path.join(out_dir, "qc.pdf") + + # Grab all b* files here. This will also grab the b0_pe* files + # as well, but only if the field input was provided. So we'll remove + # them later in the next conditional. + outputs["avg_b_png"] = sorted(glob(os.path.join(out_dir, "avg_b*.png"))) + + if inputs.field is not attrs.NOTHING: + outputs["avg_b0_pe_png"] = sorted(glob(os.path.join(out_dir, "avg_b0_pe*.png"))) + + # The previous glob for `avg_b_png` also grabbed the + # `avg_b0_pe_png` files so we have to remove them + # from `avg_b_png`. + for fname in outputs["avg_b0_pe_png"]: + outputs["avg_b_png"].remove(fname) + + outputs["vdm_png"] = os.path.join(out_dir, "vdm.png") + + outputs["cnr_png"] = sorted(glob(os.path.join(out_dir, "cnr*.png"))) + + residuals = os.path.join(out_dir, "eddy_msr.txt") + if os.path.isfile(residuals): + outputs["residuals"] = residuals + + clean_volumes = os.path.join(out_dir, "vols_no_outliers.txt") + if os.path.isfile(clean_volumes): + outputs["clean_volumes"] = clean_volumes + + return outputs diff --git a/nipype-auto-conv/specs/epi_de_warp.yaml b/nipype-auto-conv/specs/epi_de_warp.yaml index 69baeb1..fd2d31c 100644 --- a/nipype-auto-conv/specs/epi_de_warp.yaml +++ b/nipype-auto-conv/specs/epi_de_warp.yaml @@ -41,14 +41,21 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mag_file: medimage/nifti1 - # type=file|default=: Magnitude file dph_file: medimage/nifti1 # type=file|default=: Phase file assumed to be scaled from 0 to 4095 - exf_file: generic/file - # type=file|default=: example func volume (or use epi) epi_file: medimage/nifti1 # type=file|default=: EPI volume to unwarp + exf_file: generic/file + # type=file|default=: example func volume (or use epi) + mag_file: medimage/nifti1 + # type=file|default=: Magnitude file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields + tmpdir: tmpdir_default + # type=string|default='': tmpdir + vsm: vsm_default + # type=string|default='': voxel shift map metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -62,27 +69,23 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + exf_mask: generic/file + # type=file: Mask from example functional volume + exfdw: generic/file + # type=file: dewarped functional volume example + # type=string|default='': dewarped example func volume unwarped_file: generic/file # type=file: unwarped epi file vsm_file: generic/file # type=file: voxel shift map - exfdw: generic/file - # type=file: dewarped functional volume example - # type=string|default='': dewarped example func volume - exf_mask: generic/file - # type=file: Mask from example functional volume callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields - vsm: vsm - # type=string|default='': voxel shift map exfdw: exfdw # type=file: dewarped functional volume example # type=string|default='': dewarped example func volume - tmpdir: tmpdir - # type=string|default='': tmpdir requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -123,7 +126,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -149,7 +152,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -170,16 +173,16 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - epi_file: + epi_file: '"functional.nii"' # type=file|default=: EPI volume to unwarp - mag_file: + mag_file: '"magnitude.nii"' # type=file|default=: Magnitude file - dph_file: + dph_file: '"phase.nii"' # type=file|default=: Phase file assumed to be scaled from 0 to 4095 output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/epi_de_warp_callables.py b/nipype-auto-conv/specs/epi_de_warp_callables.py index 33f2aea..b121f9b 100644 --- a/nipype-auto-conv/specs/epi_de_warp_callables.py +++ b/nipype-auto-conv/specs/epi_de_warp_callables.py @@ -1 +1,424 @@ -"""Module to put any functions that are referred to in EPIDeWarp.yaml""" +"""Module to put any functions that are referred to in the "callables" section of EPIDeWarp.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def exfdw_default(inputs): + return _gen_filename("exfdw", inputs=inputs) + + +def tmpdir_default(inputs): + return _gen_filename("tmpdir", inputs=inputs) + + +def vsm_default(inputs): + return _gen_filename("vsm", inputs=inputs) + + +def exf_mask_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["exf_mask"] + + +def exfdw_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["exfdw"] + + +def unwarped_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["unwarped_file"] + + +def vsm_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["vsm_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1428 of /interfaces/fsl/epi.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "exfdw": + if inputs.exf_file is not attrs.NOTHING: + return _gen_fname( + inputs.exf_file, + suffix="_exfdw", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + return _gen_fname( + "exfdw", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if name == "epidw": + if inputs.epi_file is not attrs.NOTHING: + return _gen_fname( + inputs.epi_file, + suffix="_epidw", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if name == "vsm": + return _gen_fname( + "vsm", inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if name == "tmpdir": + return os.path.join(output_dir, "temp") + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "epidewarp.fsl" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1443 of /interfaces/fsl/epi.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.exfdw is attrs.NOTHING: + outputs["exfdw"] = _gen_filename( + "exfdw", inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + else: + outputs["exfdw"] = inputs.exfdw + if inputs.epi_file is not attrs.NOTHING: + if inputs.epidw is not attrs.NOTHING: + outputs["unwarped_file"] = inputs.epidw + else: + outputs["unwarped_file"] = _gen_filename( + "epidw", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if inputs.vsm is attrs.NOTHING: + outputs["vsm_file"] = _gen_filename( + "vsm", inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + else: + outputs["vsm_file"] = _gen_fname( + inputs.vsm, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if inputs.tmpdir is attrs.NOTHING: + outputs["exf_mask"] = _gen_fname( + cwd=_gen_filename("tmpdir"), + basename="maskexf", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs["exf_mask"] = _gen_fname( + cwd=inputs.tmpdir, + basename="maskexf", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/epi_reg.yaml b/nipype-auto-conv/specs/epi_reg.yaml index c5e5dad..c187a6a 100644 --- a/nipype-auto-conv/specs/epi_reg.yaml +++ b/nipype-auto-conv/specs/epi_reg.yaml @@ -45,21 +45,24 @@ inputs: # passed to the field in the automatically generated unittests. epi: medimage/nifti1 # type=file|default=: EPI image - t1_head: medimage/nifti1 - # type=file|default=: wholehead T1 image - t1_brain: medimage/nifti1 - # type=file|default=: brain extracted T1 image fmap: medimage/nifti1 # type=file|default=: fieldmap image (in rad/s) fmapmag: medimage/nifti1 # type=file|default=: fieldmap magnitude image - wholehead fmapmagbrain: medimage/nifti1 # type=file|default=: fieldmap magnitude image - brain extracted - wmseg: generic/file - # type=file: white matter segmentation used in flirt bbr - # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg + t1_brain: medimage/nifti1 + # type=file|default=: brain extracted T1 image + t1_head: medimage/nifti1 + # type=file|default=: wholehead T1 image weight_image: generic/file # type=file|default=: weighting image (in T1 space) + wmseg: Path + # type=file: white matter segmentation used in flirt bbr + # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -73,35 +76,35 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - out_file: generic/file - # type=file: unwarped and coregistered epi input - out_1vol: generic/file - # type=file: unwarped and coregistered single volume - fmap2str_mat: generic/file - # type=file: rigid fieldmap-to-structural transform + epi2str_inv: generic/file + # type=file: rigid structural-to-epi transform + epi2str_mat: generic/file + # type=file: rigid epi-to-structural transform fmap2epi_mat: generic/file # type=file: rigid fieldmap-to-epi transform + fmap2str_mat: generic/file + # type=file: rigid fieldmap-to-structural transform fmap_epi: generic/file # type=file: fieldmap in epi space fmap_str: generic/file # type=file: fieldmap in structural space fmapmag_str: generic/file # type=file: fieldmap magnitude image in structural space - epi2str_inv: generic/file - # type=file: rigid structural-to-epi transform - epi2str_mat: generic/file - # type=file: rigid epi-to-structural transform - shiftmap: generic/file - # type=file: shiftmap in epi space fullwarp: generic/file # type=file: warpfield to unwarp epi and transform into structural space - wmseg: generic/file - # type=file: white matter segmentation used in flirt bbr - # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg + out_1vol: generic/file + # type=file: unwarped and coregistered single volume + out_file: generic/file + # type=file: unwarped and coregistered epi input seg: generic/file # type=file: white matter, gray matter, csf segmentation + shiftmap: generic/file + # type=file: shiftmap in epi space wmedge: generic/file # type=file: white matter edges for visualization + wmseg: generic/file + # type=file: white matter segmentation used in flirt bbr + # type=file|default=: white matter segmentation of T1 image, has to be named like the t1brain and end on _wmseg callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -147,7 +150,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -183,7 +186,7 @@ tests: pedir: '"y"' # type=enum|default='x'|allowed['-x','-y','-z','x','y','z']: phase encoding direction, dir = x/y/z/-x/-y/-z imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -204,26 +207,26 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - epi: + epi: '"epi.nii"' # type=file|default=: EPI image - t1_head: + t1_head: '"T1.nii"' # type=file|default=: wholehead T1 image - t1_brain: + t1_brain: '"T1_brain.nii"' # type=file|default=: brain extracted T1 image out_base: '"epi2struct"' # type=string|default='epi2struct': output base name - fmap: + fmap: '"fieldmap_phase_fslprepared.nii"' # type=file|default=: fieldmap image (in rad/s) - fmapmag: + fmapmag: '"fieldmap_mag.nii"' # type=file|default=: fieldmap magnitude image - wholehead - fmapmagbrain: + fmapmagbrain: '"fieldmap_mag_brain.nii"' # type=file|default=: fieldmap magnitude image - brain extracted echospacing: '0.00067' # type=float|default=0.0: Effective EPI echo spacing (sometimes called dwell time) - in seconds pedir: '"y"' # type=enum|default='x'|allowed['-x','-y','-z','x','y','z']: phase encoding direction, dir = x/y/z/-x/-y/-z imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/epi_reg_callables.py b/nipype-auto-conv/specs/epi_reg_callables.py index 06d672a..9acf06e 100644 --- a/nipype-auto-conv/specs/epi_reg_callables.py +++ b/nipype-auto-conv/specs/epi_reg_callables.py @@ -1 +1,147 @@ -"""Module to put any functions that are referred to in EpiReg.yaml""" +"""Module to put any functions that are referred to in the "callables" section of EpiReg.yaml""" + +import attrs +import os + + +def epi2str_inv_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["epi2str_inv"] + + +def epi2str_mat_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["epi2str_mat"] + + +def fmap2epi_mat_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fmap2epi_mat"] + + +def fmap2str_mat_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fmap2str_mat"] + + +def fmap_epi_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fmap_epi"] + + +def fmap_str_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fmap_str"] + + +def fmapmag_str_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fmapmag_str"] + + +def fullwarp_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fullwarp"] + + +def out_1vol_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_1vol"] + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def seg_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["seg"] + + +def shiftmap_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["shiftmap"] + + +def wmedge_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["wmedge"] + + +def wmseg_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["wmseg"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L1271 of /interfaces/fsl/epi.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = os.path.join(output_dir, inputs.out_base + ".nii.gz") + if not ((inputs.no_fmapreg is not attrs.NOTHING) and inputs.no_fmapreg) and ( + inputs.fmap is not attrs.NOTHING + ): + outputs["out_1vol"] = os.path.join(output_dir, inputs.out_base + "_1vol.nii.gz") + outputs["fmap2str_mat"] = os.path.join( + output_dir, inputs.out_base + "_fieldmap2str.mat" + ) + outputs["fmap2epi_mat"] = os.path.join( + output_dir, inputs.out_base + "_fieldmaprads2epi.mat" + ) + outputs["fmap_epi"] = os.path.join( + output_dir, inputs.out_base + "_fieldmaprads2epi.nii.gz" + ) + outputs["fmap_str"] = os.path.join( + output_dir, inputs.out_base + "_fieldmaprads2str.nii.gz" + ) + outputs["fmapmag_str"] = os.path.join( + output_dir, inputs.out_base + "_fieldmap2str.nii.gz" + ) + outputs["shiftmap"] = os.path.join( + output_dir, inputs.out_base + "_fieldmaprads2epi_shift.nii.gz" + ) + outputs["fullwarp"] = os.path.join(output_dir, inputs.out_base + "_warp.nii.gz") + outputs["epi2str_inv"] = os.path.join(output_dir, inputs.out_base + "_inv.mat") + if inputs.wmseg is attrs.NOTHING: + outputs["wmedge"] = os.path.join( + output_dir, inputs.out_base + "_fast_wmedge.nii.gz" + ) + outputs["wmseg"] = os.path.join( + output_dir, inputs.out_base + "_fast_wmseg.nii.gz" + ) + outputs["seg"] = os.path.join(output_dir, inputs.out_base + "_fast_seg.nii.gz") + outputs["epi2str_mat"] = os.path.join(output_dir, inputs.out_base + ".mat") + return outputs diff --git a/nipype-auto-conv/specs/erode_image.yaml b/nipype-auto-conv/specs/erode_image.yaml index 948c0e1..9bcb725 100644 --- a/nipype-auto-conv/specs/erode_image.yaml +++ b/nipype-auto-conv/specs/erode_image.yaml @@ -20,10 +20,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - kernel_file: generic/file - # type=file|default=: use external file for kernel in_file: generic/file # type=file|default=: image to operate on + kernel_file: generic/file + # type=file|default=: use external file for kernel + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -80,7 +86,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/erode_image_callables.py b/nipype-auto-conv/specs/erode_image_callables.py index 545fa4d..da319d0 100644 --- a/nipype-auto-conv/specs/erode_image_callables.py +++ b/nipype-auto-conv/specs/erode_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in ErodeImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ErodeImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/extract_roi.yaml b/nipype-auto-conv/specs/extract_roi.yaml index d0db703..a58d740 100644 --- a/nipype-auto-conv/specs/extract_roi.yaml +++ b/nipype-auto-conv/specs/extract_roi.yaml @@ -45,6 +45,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: input file + roi_file: Path + # type=file: + # type=file|default=: output file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -105,7 +111,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -132,7 +138,7 @@ tests: t_size: '1' # type=int|default=0: imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.testing name: anatfile @@ -156,7 +162,7 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: anatfile # type=file|default=: input file roi_file: '"bar.nii"' # type=file: @@ -166,7 +172,7 @@ doctests: t_size: '1' # type=int|default=0: imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/extract_roi_callables.py b/nipype-auto-conv/specs/extract_roi_callables.py index 9292403..7ca660e 100644 --- a/nipype-auto-conv/specs/extract_roi_callables.py +++ b/nipype-auto-conv/specs/extract_roi_callables.py @@ -1 +1,345 @@ -"""Module to put any functions that are referred to in ExtractROI.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ExtractROI.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def roi_file_default(inputs): + return _gen_filename("roi_file", inputs=inputs) + + +def roi_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["roi_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L513 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "roi_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslroi" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L489 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + """Create a Bunch which contains all possible files generated + by running the interface. Some files are always generated, others + depending on which ``inputs`` options are set. + + + Returns + ------- + + outputs : Bunch object + Bunch object containing all possible files generated by + interface object. + + If None, file was not generated + Else, contains path, filename of generated outputfile + + """ + outputs = {} + outputs["roi_file"] = inputs.roi_file + if outputs["roi_file"] is attrs.NOTHING: + outputs["roi_file"] = _gen_fname( + inputs.in_file, + suffix="_roi", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["roi_file"] = os.path.abspath(outputs["roi_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/fast.yaml b/nipype-auto-conv/specs/fast.yaml index 2ffd753..007930a 100644 --- a/nipype-auto-conv/specs/fast.yaml +++ b/nipype-auto-conv/specs/fast.yaml @@ -37,14 +37,17 @@ inputs: # passed to the field in the automatically generated unittests. in_files: medimage/nifti1+list-of # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented - out_basename: generic/file - # type=file|default=: base name of output files init_transform: generic/file # type=file|default=: initialise using priors - other_priors: generic/file+list-of - # type=inputmultiobject|default=[]: alternative prior images manual_seg: generic/file # type=file|default=: Filename containing intensities + other_priors: generic/file+list-of + # type=inputmultiobject|default=[]: alternative prior images + out_basename: Path + # type=file|default=: base name of output files + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -58,12 +61,23 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - tissue_class_map: generic/file - # type=file: path/name of binary segmented volume file one val for each class _seg + bias_field: generic/file+list-of + # type=outputmultiobject: mixeltype: generic/file # type=file: path/name of mixeltype volume file _mixeltype + partial_volume_files: generic/file+list-of + # type=outputmultiobject: partial_volume_map: generic/file # type=file: path/name of partial volume file _pveseg + probability_maps: generic/file+list-of + # type=outputmultiobject: + # type=bool|default=False: outputs individual probability maps + restored_image: generic/file+list-of + # type=outputmultiobject: + tissue_class_files: generic/file+list-of + # type=outputmultiobject: + tissue_class_map: generic/file + # type=file: path/name of binary segmented volume file one val for each class _seg callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -127,7 +141,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -146,10 +160,10 @@ tests: # (if not specified, will try to choose a sensible value) in_files: # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented - out_basename: + out_basename: '"fast_"' # type=file|default=: base name of output files imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -170,12 +184,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_files: + in_files: '"structural.nii"' # type=inputmultiobject|default=[]: image, or multi-channel set of images, to be segmented - out_basename: + out_basename: '"fast_"' # type=file|default=: base name of output files imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fast_callables.py b/nipype-auto-conv/specs/fast_callables.py index 4e29548..b83ee37 100644 --- a/nipype-auto-conv/specs/fast_callables.py +++ b/nipype-auto-conv/specs/fast_callables.py @@ -1 +1,496 @@ -"""Module to put any functions that are referred to in FAST.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FAST.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def bias_field_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["bias_field"] + + +def mixeltype_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mixeltype"] + + +def partial_volume_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["partial_volume_files"] + + +def partial_volume_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["partial_volume_map"] + + +def probability_maps_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["probability_maps"] + + +def restored_image_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["restored_image"] + + +def tissue_class_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tissue_class_files"] + + +def tissue_class_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tissue_class_map"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fast" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L401 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.number_classes is attrs.NOTHING: + nclasses = 3 + else: + nclasses = inputs.number_classes + # when using multichannel, results basename is based on last + # input filename + _gen_fname_opts = {} + if inputs.out_basename is not attrs.NOTHING: + _gen_fname_opts["basename"] = inputs.out_basename + _gen_fname_opts["cwd"] = output_dir + else: + _gen_fname_opts["basename"] = inputs.in_files[-1] + _gen_fname_opts["cwd"], _, _ = split_filename(_gen_fname_opts["basename"]) + + outputs["tissue_class_map"] = _gen_fname( + suffix="_seg", + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if inputs.segments: + outputs["tissue_class_files"] = [] + for i in range(nclasses): + outputs["tissue_class_files"].append( + _gen_fname( + suffix="_seg_%d" % i, + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + if inputs.output_biascorrected is not attrs.NOTHING: + outputs["restored_image"] = [] + if len(inputs.in_files) > 1: + # for multi-image segmentation there is one corrected image + # per input + for val, f in enumerate(inputs.in_files): + # image numbering is 1-based + outputs["restored_image"].append( + _gen_fname( + suffix="_restore_%d" % (val + 1), + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + else: + # single image segmentation has unnumbered output image + outputs["restored_image"].append( + _gen_fname( + suffix="_restore", + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + + outputs["mixeltype"] = _gen_fname( + suffix="_mixeltype", + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + if not inputs.no_pve: + outputs["partial_volume_map"] = _gen_fname( + suffix="_pveseg", + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + outputs["partial_volume_files"] = [] + for i in range(nclasses): + outputs["partial_volume_files"].append( + _gen_fname( + suffix="_pve_%d" % i, + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + if inputs.output_biasfield: + outputs["bias_field"] = [] + if len(inputs.in_files) > 1: + # for multi-image segmentation there is one bias field image + # per input + for val, f in enumerate(inputs.in_files): + # image numbering is 1-based + outputs["bias_field"].append( + _gen_fname( + suffix="_bias_%d" % (val + 1), + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + else: + # single image segmentation has unnumbered output image + outputs["bias_field"].append( + _gen_fname( + suffix="_bias", + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + + if inputs.probability_maps: + outputs["probability_maps"] = [] + for i in range(nclasses): + outputs["probability_maps"].append( + _gen_fname( + suffix="_prob_%d" % i, + **_gen_fname_opts, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir + ) + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/feat.yaml b/nipype-auto-conv/specs/feat.yaml index 3862605..9bde358 100644 --- a/nipype-auto-conv/specs/feat.yaml +++ b/nipype-auto-conv/specs/feat.yaml @@ -22,6 +22,9 @@ inputs: # passed to the field in the automatically generated unittests. fsf_file: generic/file # type=file|default=: File specifying the feat design spec file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -57,7 +60,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/feat_callables.py b/nipype-auto-conv/specs/feat_callables.py index ac5b32f..a28955e 100644 --- a/nipype-auto-conv/specs/feat_callables.py +++ b/nipype-auto-conv/specs/feat_callables.py @@ -1 +1,42 @@ -"""Module to put any functions that are referred to in FEAT.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FEAT.yaml""" + +import os +from glob import glob + + +def feat_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["feat_dir"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L465 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + is_ica = False + outputs["feat_dir"] = None + with open(inputs.fsf_file, "rt") as fp: + text = fp.read() + if "set fmri(inmelodic) 1" in text: + is_ica = True + for line in text.split("\n"): + if line.find("set fmri(outputdir)") > -1: + try: + outputdir_spec = line.split('"')[-2] + if os.path.exists(outputdir_spec): + outputs["feat_dir"] = outputdir_spec + + except: + pass + if not outputs["feat_dir"]: + if is_ica: + outputs["feat_dir"] = glob(os.path.join(output_dir, "*ica"))[0] + else: + outputs["feat_dir"] = glob(os.path.join(output_dir, "*feat"))[0] + return outputs diff --git a/nipype-auto-conv/specs/feat_model.yaml b/nipype-auto-conv/specs/feat_model.yaml index 6594e63..430e8ce 100644 --- a/nipype-auto-conv/specs/feat_model.yaml +++ b/nipype-auto-conv/specs/feat_model.yaml @@ -20,10 +20,13 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - fsf_file: generic/file - # type=file|default=: File specifying the feat design spec file ev_files: generic/file+list-of # type=list|default=[]: Event spec files generated by level1design + fsf_file: generic/file + # type=file|default=: File specifying the feat design spec file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -37,14 +40,14 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + con_file: generic/file + # type=file: Contrast file containing contrast vectors + design_cov: generic/file + # type=file: Graphical representation of design covariance design_file: generic/file # type=file: Mat file containing ascii matrix for design design_image: generic/file # type=file: Graphical representation of design matrix - design_cov: generic/file - # type=file: Graphical representation of design covariance - con_file: generic/file - # type=file: Contrast file containing contrast vectors fcon_file: generic/file # type=file: Contrast file containing contrast vectors callables: @@ -69,7 +72,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/feat_model_callables.py b/nipype-auto-conv/specs/feat_model_callables.py index ddb4019..bb0a4aa 100644 --- a/nipype-auto-conv/specs/feat_model_callables.py +++ b/nipype-auto-conv/specs/feat_model_callables.py @@ -1 +1,91 @@ -"""Module to put any functions that are referred to in FEATModel.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FEATModel.yaml""" + +import os +from glob import glob + + +def con_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["con_file"] + + +def design_cov_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_cov"] + + +def design_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_file"] + + +def design_image_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_image"] + + +def fcon_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fcon_file"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L534 of /interfaces/fsl/model.py +def _get_design_root(infile, inputs=None, stdout=None, stderr=None, output_dir=None): + _, fname = os.path.split(infile) + return fname.split(".")[0] + + +# Original source at L538 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + # TODO: figure out file names and get rid off the globs + outputs = {} + root = _get_design_root( + simplify_list(inputs.fsf_file), + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + design_file = glob(os.path.join(output_dir, "%s*.mat" % root)) + assert len(design_file) == 1, "No mat file generated by FEAT Model" + outputs["design_file"] = design_file[0] + design_image = glob(os.path.join(output_dir, "%s.png" % root)) + assert len(design_image) == 1, "No design image generated by FEAT Model" + outputs["design_image"] = design_image[0] + design_cov = glob(os.path.join(output_dir, "%s_cov.png" % root)) + assert len(design_cov) == 1, "No covariance image generated by FEAT Model" + outputs["design_cov"] = design_cov[0] + con_file = glob(os.path.join(output_dir, "%s*.con" % root)) + assert len(con_file) == 1, "No con file generated by FEAT Model" + outputs["con_file"] = con_file[0] + fcon_file = glob(os.path.join(output_dir, "%s*.fts" % root)) + if fcon_file: + assert len(fcon_file) == 1, "No fts file generated by FEAT Model" + outputs["fcon_file"] = fcon_file[0] + return outputs + + +# Original source at L530 of /utils/filemanip.py +def simplify_list(filelist): + """Returns a list if filelist is a list of length greater than 1, + otherwise returns the first element + """ + if len(filelist) > 1: + return filelist + else: + return filelist[0] diff --git a/nipype-auto-conv/specs/feature_extractor.yaml b/nipype-auto-conv/specs/feature_extractor.yaml index 2b83416..fdd69d3 100644 --- a/nipype-auto-conv/specs/feature_extractor.yaml +++ b/nipype-auto-conv/specs/feature_extractor.yaml @@ -22,9 +22,12 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mel_ica: generic/directory + mel_ica: Path # type=directory: Melodic output directory or directories # type=directory|default=: Melodic output directory or directories + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -60,7 +63,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/feature_extractor_callables.py b/nipype-auto-conv/specs/feature_extractor_callables.py index 1bcc7da..9a93d53 100644 --- a/nipype-auto-conv/specs/feature_extractor_callables.py +++ b/nipype-auto-conv/specs/feature_extractor_callables.py @@ -1 +1,20 @@ -"""Module to put any functions that are referred to in FeatureExtractor.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FeatureExtractor.yaml""" + + +def mel_ica_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mel_ica"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L161 of /interfaces/fsl/fix.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["mel_ica"] = inputs.mel_ica + return outputs diff --git a/nipype-auto-conv/specs/filmgls.yaml b/nipype-auto-conv/specs/filmgls.yaml index 155c8a7..2e15e91 100644 --- a/nipype-auto-conv/specs/filmgls.yaml +++ b/nipype-auto-conv/specs/filmgls.yaml @@ -45,19 +45,22 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - tcon_file: generic/file - # type=file|default=: contrast file containing T-contrasts + design_file: generic/file + # type=file|default=: design matrix file fcon_file: generic/file # type=file|default=: contrast file containing F-contrasts - surface: generic/file - # type=file|default=: input surface for autocorr smoothing in surface-based analyses in_file: generic/file # type=file|default=: input data file - design_file: generic/file - # type=file|default=: design matrix file - results_dir: generic/directory + results_dir: Path # type=directory: directory storing model estimation output # type=directory|default='results': directory to store results in + surface: generic/file + # type=file|default=: input surface for autocorr smoothing in surface-based analyses + tcon_file: generic/file + # type=file|default=: contrast file containing T-contrasts + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -71,19 +74,33 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - residual4d: generic/file - # type=file: Model fit residual mean-squared error for each time point + copes: generic/file+list-of + # type=outputmultiobject: Contrast estimates for each contrast dof_file: generic/file # type=file: degrees of freedom - sigmasquareds: generic/file - # type=file: summary of residuals, See Woolrich, et. al., 2001 - thresholdac: generic/file - # type=file: The FILM autocorrelation parameters + fstats: generic/file+list-of + # type=outputmultiobject: f-stat file for each contrast logfile: generic/file # type=file: FILM run logfile + param_estimates: generic/file+list-of + # type=outputmultiobject: Parameter estimates for each column of the design matrix + residual4d: generic/file + # type=file: Model fit residual mean-squared error for each time point results_dir: generic/directory # type=directory: directory storing model estimation output # type=directory|default='results': directory to store results in + sigmasquareds: generic/file + # type=file: summary of residuals, See Woolrich, et. al., 2001 + thresholdac: generic/file + # type=file: The FILM autocorrelation parameters + tstats: generic/file+list-of + # type=outputmultiobject: t-stat file for each contrast + varcopes: generic/file+list-of + # type=outputmultiobject: Variance estimates for each contrast + zfstats: generic/file+list-of + # type=outputmultiobject: z-stat file for each F contrast + zstats: generic/file+list-of + # type=outputmultiobject: z-stat file for each contrast callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -141,7 +158,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/filmgls_callables.py b/nipype-auto-conv/specs/filmgls_callables.py index 2911e6a..7d41802 100644 --- a/nipype-auto-conv/specs/filmgls_callables.py +++ b/nipype-auto-conv/specs/filmgls_callables.py @@ -1 +1,575 @@ -"""Module to put any functions that are referred to in FILMGLS.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FILMGLS.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from looseversion import LooseVersion +from pathlib import Path + + +def copes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["copes"] + + +def dof_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dof_file"] + + +def fstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fstats"] + + +def logfile_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["logfile"] + + +def param_estimates_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["param_estimates"] + + +def residual4d_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["residual4d"] + + +def results_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["results_dir"] + + +def sigmasquareds_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["sigmasquareds"] + + +def thresholdac_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["thresholdac"] + + +def tstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tstats"] + + +def varcopes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["varcopes"] + + +def zfstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["zfstats"] + + +def zstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["zstats"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "film_gls" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L841 of /interfaces/fsl/model.py +def _get_numcons(inputs=None, stdout=None, stderr=None, output_dir=None): + numtcons = 0 + numfcons = 0 + if inputs.tcon_file is not attrs.NOTHING: + fp = open(inputs.tcon_file, "rt") + for line in fp.readlines(): + if line.startswith("/NumContrasts"): + numtcons = int(line.split()[-1]) + break + fp.close() + if inputs.fcon_file is not attrs.NOTHING: + fp = open(inputs.fcon_file, "rt") + for line in fp.readlines(): + if line.startswith("/NumContrasts"): + numfcons = int(line.split()[-1]) + break + fp.close() + return numtcons, numfcons + + +# Original source at L827 of /interfaces/fsl/model.py +def _get_pe_files(cwd, inputs=None, stdout=None, stderr=None, output_dir=None): + files = None + if inputs.design_file is not attrs.NOTHING: + fp = open(inputs.design_file, "rt") + for line in fp.readlines(): + if line.startswith("/NumWaves"): + numpes = int(line.split()[-1]) + files = [] + for i in range(numpes): + files.append( + _gen_fname( + "pe%d.nii" % (i + 1), + cwd=cwd, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + break + fp.close() + return files + + +# Original source at L860 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + cwd = output_dir + results_dir = os.path.join(cwd, inputs.results_dir) + outputs["results_dir"] = results_dir + pe_files = _get_pe_files( + results_dir, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if pe_files: + outputs["param_estimates"] = pe_files + outputs["residual4d"] = _gen_fname( + "res4d.nii", + cwd=results_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["dof_file"] = os.path.join(results_dir, "dof") + outputs["sigmasquareds"] = _gen_fname( + "sigmasquareds.nii", + cwd=results_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["thresholdac"] = _gen_fname( + "threshac1.nii", + cwd=results_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if Info.version() and LooseVersion(Info.version()) < LooseVersion("5.0.7"): + outputs["corrections"] = _gen_fname( + "corrections.nii", + cwd=results_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["logfile"] = _gen_fname( + "logfile", + change_ext=False, + cwd=results_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + if Info.version() and LooseVersion(Info.version()) > LooseVersion("5.0.6"): + pth = results_dir + numtcons, numfcons = _get_numcons( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + base_contrast = 1 + copes = [] + varcopes = [] + zstats = [] + tstats = [] + for i in range(numtcons): + copes.append( + _gen_fname( + "cope%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + varcopes.append( + _gen_fname( + "varcope%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + zstats.append( + _gen_fname( + "zstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + tstats.append( + _gen_fname( + "tstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + if copes: + outputs["copes"] = copes + outputs["varcopes"] = varcopes + outputs["zstats"] = zstats + outputs["tstats"] = tstats + fstats = [] + zfstats = [] + for i in range(numfcons): + fstats.append( + _gen_fname( + "fstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + zfstats.append( + _gen_fname( + "zfstat%d.nii" % (base_contrast + i), + cwd=pth, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + if fstats: + outputs["fstats"] = fstats + outputs["zfstats"] = zfstats + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/filter_regressor.yaml b/nipype-auto-conv/specs/filter_regressor.yaml index 68f738f..f3af84b 100644 --- a/nipype-auto-conv/specs/filter_regressor.yaml +++ b/nipype-auto-conv/specs/filter_regressor.yaml @@ -23,12 +23,18 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: input file name (4D image) design_file: generic/file # type=file|default=: name of the matrix with time courses (e.g. GLM design or MELODIC mixing matrix) + in_file: generic/file + # type=file|default=: input file name (4D image) mask: generic/file # type=file|default=: mask image file name + out_file: Path + # type=file: output file name for the filtered data + # type=file|default=: output file name for the filtered data + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -83,7 +89,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/filter_regressor_callables.py b/nipype-auto-conv/specs/filter_regressor_callables.py index 9e1cd02..15ef6f2 100644 --- a/nipype-auto-conv/specs/filter_regressor_callables.py +++ b/nipype-auto-conv/specs/filter_regressor_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in FilterRegressor.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FilterRegressor.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L731 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fsl_regfilt" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L721 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if outputs["out_file"] is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix="_regfilt", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/find_the_biggest.yaml b/nipype-auto-conv/specs/find_the_biggest.yaml index d44c932..5955dcb 100644 --- a/nipype-auto-conv/specs/find_the_biggest.yaml +++ b/nipype-auto-conv/specs/find_the_biggest.yaml @@ -37,6 +37,12 @@ inputs: # passed to the field in the automatically generated unittests. in_files: generic/file+list-of # type=list|default=[]: a list of input volumes or a singleMatrixFile + out_file: Path + # type=file: output file indexed in order of input files + # type=file|default=: file with the resulting segmentation + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -79,7 +85,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -102,7 +108,7 @@ tests: # type=file: output file indexed in order of input files # type=file|default=: file with the resulting segmentation imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -123,13 +129,13 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_files: + in_files: ldir # type=list|default=[]: a list of input volumes or a singleMatrixFile out_file: '"biggestSegmentation"' # type=file: output file indexed in order of input files # type=file|default=: file with the resulting segmentation imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/find_the_biggest_callables.py b/nipype-auto-conv/specs/find_the_biggest_callables.py index a666e9d..4bc9cf0 100644 --- a/nipype-auto-conv/specs/find_the_biggest_callables.py +++ b/nipype-auto-conv/specs/find_the_biggest_callables.py @@ -1 +1,330 @@ -"""Module to put any functions that are referred to in FindTheBiggest.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FindTheBiggest.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1341 of /interfaces/fsl/dti.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + else: + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "find_the_biggest" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1333 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if outputs["out_file"] is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + "biggestSegmentation", + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/first.yaml b/nipype-auto-conv/specs/first.yaml index b19e26e..bb3e430 100644 --- a/nipype-auto-conv/specs/first.yaml +++ b/nipype-auto-conv/specs/first.yaml @@ -33,12 +33,15 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + affine_file: generic/file + # type=file|default=: Affine matrix to use (e.g. img2std.mat) (does not re-run registration) in_file: generic/file # type=file|default=: input data file - out_file: generic/file + out_file: Path # type=file|default='segmented': output data file - affine_file: generic/file - # type=file|default=: Affine matrix to use (e.g. img2std.mat) (does not re-run registration) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -52,10 +55,14 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + bvars: generic/file+list-of + # type=outputmultiobject: bvars for each subcortical region original_segmentations: generic/file # type=file: 3D image file containing the segmented regions as integer values. Uses CMA labelling segmentation_file: generic/file # type=file: 4D image file containing a single volume per segmented region + vtk_surfaces: generic/file+list-of + # type=outputmultiobject: VTK format meshes for each subcortical region callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -92,7 +99,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/first_callables.py b/nipype-auto-conv/specs/first_callables.py index 08786d5..9f168a3 100644 --- a/nipype-auto-conv/specs/first_callables.py +++ b/nipype-auto-conv/specs/first_callables.py @@ -1 +1,187 @@ -"""Module to put any functions that are referred to in FIRST.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FIRST.yaml""" + +import attrs +import os.path as op + + +def bvars_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["bvars"] + + +def original_segmentations_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["original_segmentations"] + + +def segmentation_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["segmentation_file"] + + +def vtk_surfaces_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["vtk_surfaces"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L2259 of /interfaces/fsl/preprocess.py +def _gen_fname(basename, inputs=None, stdout=None, stderr=None, output_dir=None): + path, outname, ext = split_filename(inputs.out_file) + + method = "none" + if (inputs.method is not attrs.NOTHING) and inputs.method != "none": + method = "fast" + if inputs.list_of_specific_structures and inputs.method == "auto": + method = "none" + + if inputs.method_as_numerical_threshold is not attrs.NOTHING: + thres = "%.4f" % inputs.method_as_numerical_threshold + method = thres.replace(".", "") + + if basename == "original_segmentations": + return op.abspath("%s_all_%s_origsegs.nii.gz" % (outname, method)) + if basename == "segmentation_file": + return op.abspath("%s_all_%s_firstseg.nii.gz" % (outname, method)) + + return None + + +# Original source at L2279 of /interfaces/fsl/preprocess.py +def _gen_mesh_names( + name, structures, inputs=None, stdout=None, stderr=None, output_dir=None +): + path, prefix, ext = split_filename(inputs.out_file) + if name == "vtk_surfaces": + vtks = list() + for struct in structures: + vtk = prefix + "-" + struct + "_first.vtk" + vtks.append(op.abspath(vtk)) + return vtks + if name == "bvars": + bvars = list() + for struct in structures: + bvar = prefix + "-" + struct + "_first.bvars" + bvars.append(op.abspath(bvar)) + return bvars + return None + + +# Original source at L2230 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + + if inputs.list_of_specific_structures is not attrs.NOTHING: + structures = inputs.list_of_specific_structures + else: + structures = [ + "L_Hipp", + "R_Hipp", + "L_Accu", + "R_Accu", + "L_Amyg", + "R_Amyg", + "L_Caud", + "R_Caud", + "L_Pall", + "R_Pall", + "L_Puta", + "R_Puta", + "L_Thal", + "R_Thal", + "BrStem", + ] + outputs["original_segmentations"] = _gen_fname( + "original_segmentations", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["segmentation_file"] = _gen_fname( + "segmentation_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["vtk_surfaces"] = _gen_mesh_names( + "vtk_surfaces", + structures, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["bvars"] = _gen_mesh_names( + "bvars", + structures, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext diff --git a/nipype-auto-conv/specs/flameo.yaml b/nipype-auto-conv/specs/flameo.yaml index c7b2cf2..2b735aa 100644 --- a/nipype-auto-conv/specs/flameo.yaml +++ b/nipype-auto-conv/specs/flameo.yaml @@ -41,22 +41,25 @@ inputs: # passed to the field in the automatically generated unittests. cope_file: medimage/nifti-gz # type=file|default=: cope regressor data file - var_cope_file: medimage/nifti-gz - # type=file|default=: varcope weightings data file - dof_var_cope_file: generic/file - # type=file|default=: dof data file for varcope data - mask_file: medimage/nifti1 - # type=file|default=: mask file + cov_split_file: datascience/text-matrix + # type=file|default=: ascii matrix specifying the groups the covariance is split into design_file: datascience/text-matrix # type=file|default=: design matrix file - t_con_file: medimage-fsl/con - # type=file|default=: ascii matrix specifying t-contrasts + dof_var_cope_file: generic/file + # type=file|default=: dof data file for varcope data f_con_file: generic/file # type=file|default=: ascii matrix specifying f-contrasts - cov_split_file: datascience/text-matrix - # type=file|default=: ascii matrix specifying the groups the covariance is split into log_dir: generic/directory # type=directory|default='stats': + mask_file: medimage/nifti1 + # type=file|default=: mask file + t_con_file: medimage-fsl/con + # type=file|default=: ascii matrix specifying t-contrasts + var_cope_file: medimage/nifti-gz + # type=file|default=: varcope weightings data file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,8 +73,30 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + copes: generic/file+list-of + # type=outputmultiobject: Contrast estimates for each contrast + fstats: generic/file+list-of + # type=outputmultiobject: f-stat file for each contrast + mrefvars: generic/file+list-of + # type=outputmultiobject: mean random effect variances for each contrast + pes: generic/file+list-of + # type=outputmultiobject: Parameter estimates for each column of the design matrix for each voxel + res4d: generic/file+list-of + # type=outputmultiobject: Model fit residual mean-squared error for each time point stats_dir: generic/directory # type=directory: directory storing model estimation output + tdof: generic/file+list-of + # type=outputmultiobject: temporal dof file for each contrast + tstats: generic/file+list-of + # type=outputmultiobject: t-stat file for each contrast + var_copes: generic/file+list-of + # type=outputmultiobject: Variance estimates for each contrast + weights: generic/file+list-of + # type=outputmultiobject: weights file for each contrast + zfstats: generic/file+list-of + # type=outputmultiobject: z stat file for each f contrast + zstats: generic/file+list-of + # type=outputmultiobject: z-stat file for each contrast callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -126,7 +151,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -158,7 +183,7 @@ tests: run_mode: '"fe"' # type=enum|default='fe'|allowed['fe','flame1','flame12','ols']: inference to perform imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -179,22 +204,22 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - cope_file: + cope_file: '"cope.nii.gz"' # type=file|default=: cope regressor data file - var_cope_file: + var_cope_file: '"varcope.nii.gz"' # type=file|default=: varcope weightings data file - cov_split_file: + cov_split_file: '"cov_split.mat"' # type=file|default=: ascii matrix specifying the groups the covariance is split into - design_file: + design_file: '"design.mat"' # type=file|default=: design matrix file - t_con_file: + t_con_file: '"design.con"' # type=file|default=: ascii matrix specifying t-contrasts - mask_file: + mask_file: '"mask.nii"' # type=file|default=: mask file run_mode: '"fe"' # type=enum|default='fe'|allowed['fe','flame1','flame12','ols']: inference to perform imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/flameo_callables.py b/nipype-auto-conv/specs/flameo_callables.py index d01dd85..734d1ea 100644 --- a/nipype-auto-conv/specs/flameo_callables.py +++ b/nipype-auto-conv/specs/flameo_callables.py @@ -1 +1,167 @@ -"""Module to put any functions that are referred to in FLAMEO.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FLAMEO.yaml""" + +import attrs +import os +import re +from glob import glob + + +def copes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["copes"] + + +def fstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fstats"] + + +def mrefvars_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mrefvars"] + + +def pes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["pes"] + + +def res4d_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["res4d"] + + +def stats_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["stats_dir"] + + +def tdof_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tdof"] + + +def tstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tstats"] + + +def var_copes_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["var_copes"] + + +def weights_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["weights"] + + +def zfstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["zfstats"] + + +def zstats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["zstats"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L1143 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + pth = os.path.join(output_dir, inputs.log_dir) + + pes = human_order_sorted(glob(os.path.join(pth, "pe[0-9]*.*"))) + assert len(pes) >= 1, "No pe volumes generated by FSL Estimate" + outputs["pes"] = pes + + res4d = human_order_sorted(glob(os.path.join(pth, "res4d.*"))) + assert len(res4d) == 1, "No residual volume generated by FSL Estimate" + outputs["res4d"] = res4d[0] + + copes = human_order_sorted(glob(os.path.join(pth, "cope[0-9]*.*"))) + assert len(copes) >= 1, "No cope volumes generated by FSL CEstimate" + outputs["copes"] = copes + + var_copes = human_order_sorted(glob(os.path.join(pth, "varcope[0-9]*.*"))) + assert len(var_copes) >= 1, "No varcope volumes generated by FSL CEstimate" + outputs["var_copes"] = var_copes + + zstats = human_order_sorted(glob(os.path.join(pth, "zstat[0-9]*.*"))) + assert len(zstats) >= 1, "No zstat volumes generated by FSL CEstimate" + outputs["zstats"] = zstats + + if inputs.f_con_file is not attrs.NOTHING: + zfstats = human_order_sorted(glob(os.path.join(pth, "zfstat[0-9]*.*"))) + assert len(zfstats) >= 1, "No zfstat volumes generated by FSL CEstimate" + outputs["zfstats"] = zfstats + + fstats = human_order_sorted(glob(os.path.join(pth, "fstat[0-9]*.*"))) + assert len(fstats) >= 1, "No fstat volumes generated by FSL CEstimate" + outputs["fstats"] = fstats + + tstats = human_order_sorted(glob(os.path.join(pth, "tstat[0-9]*.*"))) + assert len(tstats) >= 1, "No tstat volumes generated by FSL CEstimate" + outputs["tstats"] = tstats + + mrefs = human_order_sorted( + glob(os.path.join(pth, "mean_random_effects_var[0-9]*.*")) + ) + assert len(mrefs) >= 1, "No mean random effects volumes generated by FLAMEO" + outputs["mrefvars"] = mrefs + + tdof = human_order_sorted(glob(os.path.join(pth, "tdof_t[0-9]*.*"))) + assert len(tdof) >= 1, "No T dof volumes generated by FLAMEO" + outputs["tdof"] = tdof + + weights = human_order_sorted(glob(os.path.join(pth, "weights[0-9]*.*"))) + assert len(weights) >= 1, "No weight volumes generated by FLAMEO" + outputs["weights"] = weights + + outputs["stats_dir"] = pth + + return outputs + + +# Original source at L19 of /utils/misc.py +def human_order_sorted(l): + """Sorts string in human order (i.e. 'stat10' will go after 'stat2')""" + + def atoi(text): + return int(text) if text.isdigit() else text + + def natural_keys(text): + if isinstance(text, tuple): + text = text[0] + return [atoi(c) for c in re.split(r"(\d+)", text)] + + return sorted(l, key=natural_keys) diff --git a/nipype-auto-conv/specs/flirt.yaml b/nipype-auto-conv/specs/flirt.yaml index c70491e..5e39a3a 100644 --- a/nipype-auto-conv/specs/flirt.yaml +++ b/nipype-auto-conv/specs/flirt.yaml @@ -40,37 +40,40 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + fieldmap: generic/file + # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image + fieldmapmask: generic/file + # type=file|default=: mask for fieldmap image in_file: medimage/nifti1 # type=file|default=: input file - reference: medimage/nifti1 - # type=file|default=: reference file - out_file: generic/file + in_matrix_file: generic/file + # type=file|default=: input 4x4 affine matrix + in_weight: generic/file + # type=file|default=: File for input weighting volume + out_file: Path # type=file: path/name of registered file (if generated) # type=file|default=: registered output file - out_matrix_file: generic/file - # type=file: path/name of calculated affine transform (if generated) - # type=file|default=: output affine matrix in 4x4 asciii format - out_log: generic/file + out_log: Path # type=file: path/name of output log (if generated) # type=file|default=: output log - in_matrix_file: generic/file - # type=file|default=: input 4x4 affine matrix - schedule: generic/file - # type=file|default=: replaces default schedule + out_matrix_file: Path + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format ref_weight: generic/file # type=file|default=: File for reference weighting volume - in_weight: generic/file - # type=file|default=: File for input weighting volume + reference: medimage/nifti1 + # type=file|default=: reference file + schedule: generic/file + # type=file|default=: replaces default schedule wm_seg: generic/file # type=file|default=: white matter segmentation volume needed by BBR cost function wmcoords: generic/file # type=file|default=: white matter boundary coordinates for BBR cost function wmnorms: generic/file # type=file|default=: white matter boundary normals for BBR cost function - fieldmap: generic/file - # type=file|default=: fieldmap image in rads/s - must be already registered to the reference image - fieldmapmask: generic/file - # type=file|default=: mask for fieldmap image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -87,12 +90,12 @@ outputs: out_file: generic/file # type=file: path/name of registered file (if generated) # type=file|default=: registered output file - out_matrix_file: generic/file - # type=file: path/name of calculated affine transform (if generated) - # type=file|default=: output affine matrix in 4x4 asciii format out_log: generic/file # type=file: path/name of output log (if generated) # type=file|default=: output log + out_matrix_file: generic/file + # type=file: path/name of calculated affine transform (if generated) + # type=file|default=: output affine matrix in 4x4 asciii format callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -208,7 +211,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -236,7 +239,7 @@ tests: cost_func: '"mutualinfo"' # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.testing name: example_data @@ -260,9 +263,9 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"structural.nii"' # type=file|default=: input file - reference: + reference: '"mni.nii"' # type=file|default=: reference file output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type @@ -271,7 +274,7 @@ doctests: cost_func: '"mutualinfo"' # type=enum|default='mutualinfo'|allowed['bbr','corratio','labeldiff','leastsq','mutualinfo','normcorr','normmi']: cost function imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/flirt_callables.py b/nipype-auto-conv/specs/flirt_callables.py index 1b4f6bd..cf6386c 100644 --- a/nipype-auto-conv/specs/flirt_callables.py +++ b/nipype-auto-conv/specs/flirt_callables.py @@ -1 +1,352 @@ -"""Module to put any functions that are referred to in FLIRT.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FLIRT.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def out_log_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_log"] + + +def out_matrix_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_matrix_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/fnirt.yaml b/nipype-auto-conv/specs/fnirt.yaml index 506b06f..84d3b6d 100644 --- a/nipype-auto-conv/specs/fnirt.yaml +++ b/nipype-auto-conv/specs/fnirt.yaml @@ -49,20 +49,29 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - ref_file: generic/file - # type=file|default=: name of reference image - in_file: generic/file - # type=file|default=: name of input image affine_file: generic/file # type=file|default=: name of file containing affine transform - inwarp_file: generic/file - # type=file|default=: name of file containing initial non-linear warps + in_file: generic/file + # type=file|default=: name of input image in_intensitymap_file: generic/file+list-of # type=list|default=[]: name of file/files containing initial intensity mapping usually generated by previous fnirt run - refmask_file: generic/file - # type=file|default=: name of file with mask in reference space inmask_file: generic/file # type=file|default=: name of file with mask in input image space + inwarp_file: generic/file + # type=file|default=: name of file containing initial non-linear warps + log_file: Path + # type=file: Name of log-file + # type=file|default=: Name of log-file + ref_file: generic/file + # type=file|default=: name of reference image + refmask_file: generic/file + # type=file|default=: name of file with mask in reference space + warped_file: Path + # type=file: warped image + # type=file|default=: name of output image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -76,35 +85,38 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - fieldcoeff_file: generic/file - # type=file: file with field coefficients - # type=traitcompound|default=None: name of output file with field coefficients or true - warped_file: generic/file - # type=file: warped image - # type=file|default=: name of output image field_file: generic/file # type=file: file with warp field # type=traitcompound|default=None: name of output file with field or true + fieldcoeff_file: generic/file + # type=file: file with field coefficients + # type=traitcompound|default=None: name of output file with field coefficients or true jacobian_file: generic/file # type=file: file containing Jacobian of the field # type=traitcompound|default=None: name of file for writing out the Jacobian of the field (for diagnostic or VBM purposes) - modulatedref_file: generic/file - # type=file: file containing intensity modulated --ref - # type=traitcompound|default=None: name of file for writing out intensity modulated --ref (for diagnostic purposes) log_file: generic/file # type=file: Name of log-file # type=file|default=: Name of log-file + modulatedref_file: generic/file + # type=file: file containing intensity modulated --ref + # type=traitcompound|default=None: name of file for writing out intensity modulated --ref (for diagnostic purposes) + out_intensitymap_file: generic/file+list-of + # type=list: files containing info pertaining to intensity mapping + # type=traitcompound|default=None: name of files for writing information pertaining to intensity mapping + warped_file: generic/file + # type=file: warped image + # type=file|default=: name of output image callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields - warped_file: warped_file - # type=file: warped image - # type=file|default=: name of output image log_file: log_file # type=file: Name of log-file # type=file|default=: Name of log-file + warped_file: warped_file + # type=file: warped image + # type=file|default=: name of output image requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -207,7 +219,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -231,7 +243,7 @@ tests: warp_resolution: (6, 6, 6) # type=tuple|default=(0, 0, 0): (approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10 imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.testing name: example_data @@ -262,7 +274,7 @@ doctests: warp_resolution: (6, 6, 6) # type=tuple|default=(0, 0, 0): (approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10 imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fnirt_callables.py b/nipype-auto-conv/specs/fnirt_callables.py index 6739d9d..3d121a2 100644 --- a/nipype-auto-conv/specs/fnirt_callables.py +++ b/nipype-auto-conv/specs/fnirt_callables.py @@ -1 +1,420 @@ -"""Module to put any functions that are referred to in FNIRT.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FNIRT.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def log_file_default(inputs): + return _gen_filename("log_file", inputs=inputs) + + +def warped_file_default(inputs): + return _gen_filename("warped_file", inputs=inputs) + + +def field_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["field_file"] + + +def fieldcoeff_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fieldcoeff_file"] + + +def jacobian_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["jacobian_file"] + + +def log_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["log_file"] + + +def modulatedref_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["modulatedref_file"] + + +def out_intensitymap_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_intensitymap_file"] + + +def warped_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["warped_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1341 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name in ["warped_file", "log_file"]: + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fnirt" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1298 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + for key, suffix in list(filemap.items()): + inval = getattr(inputs, key) + change_ext = True + if key in ["warped_file", "log_file"]: + if suffix.endswith(".txt"): + change_ext = False + if inval is not attrs.NOTHING: + outputs[key] = os.path.abspath(inval) + else: + outputs[key] = _gen_fname( + inputs.in_file, + suffix="_" + suffix, + change_ext=change_ext, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif inval is not attrs.NOTHING: + if isinstance(inval, bool): + if inval: + outputs[key] = _gen_fname( + inputs.in_file, + suffix="_" + suffix, + change_ext=change_ext, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs[key] = os.path.abspath(inval) + + if key == "out_intensitymap_file" and (outputs[key] is not attrs.NOTHING): + basename = intensitymap_file_basename( + outputs[key], + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs[key] = [outputs[key], "%s.txt" % basename] + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L1364 of /interfaces/fsl/preprocess.py +def intensitymap_file_basename( + f, inputs=None, stdout=None, stderr=None, output_dir=None +): + """Removes valid intensitymap extensions from `f`, returning a basename + that can refer to both intensitymap files. + """ + for ext in list(Info.ftypes.values()) + [".txt"]: + if f.endswith(ext): + return f[: -len(ext)] + # TODO consider warning for this case + return f + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/fslx_command.yaml b/nipype-auto-conv/specs/fslx_command.yaml deleted file mode 100644 index 866e863..0000000 --- a/nipype-auto-conv/specs/fslx_command.yaml +++ /dev/null @@ -1,132 +0,0 @@ -# This file is used to manually specify the semi-automatic conversion of -# 'nipype.interfaces.fsl.dti.FSLXCommand' from Nipype to Pydra. -# -# Please fill-in/edit the fields below where appropriate -# -# Docs -# ---- -# -# Base support for ``xfibres`` and ``bedpostx`` -# -task_name: FSLXCommand -nipype_name: FSLXCommand -nipype_module: nipype.interfaces.fsl.dti -inputs: - omit: - # list[str] - fields to omit from the Pydra interface - rename: - # dict[str, str] - fields to rename in the Pydra interface - types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - dwi: generic/file - # type=file|default=: diffusion weighted image data file - mask: generic/file - # type=file|default=: brain binary mask file (i.e. from BET) - bvecs: generic/file - # type=file|default=: b vectors file - bvals: generic/file - # type=file|default=: b values file - logdir: generic/directory - # type=directory|default='.': - metadata: - # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) -outputs: - omit: - # list[str] - fields to omit from the Pydra interface - rename: - # dict[str, str] - fields to rename in the Pydra interface - types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - mean_dsamples: generic/file - # type=file: Mean of distribution on diffusivity d - mean_S0samples: generic/file - # type=file: Mean of distribution on T2wbaseline signal intensity S0 - mean_tausamples: generic/file - # type=file: Mean of distribution on tau samples (only with rician noise) - callables: - # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` - # to set to the `callable` attribute of output fields - templates: - # dict[str, str] - `output_file_template` values to be provided to output fields - requirements: - # dict[str, list[str]] - input fields that are required to be provided for the output field to be present -tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - dwi: - # type=file|default=: diffusion weighted image data file - mask: - # type=file|default=: brain binary mask file (i.e. from BET) - bvecs: - # type=file|default=: b vectors file - bvals: - # type=file|default=: b values file - logdir: - # type=directory|default='.': - n_fibres: - # type=range|default=2: Maximum number of fibres to fit in each voxel - model: - # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model - fudge: - # type=int|default=0: ARD fudge factor - n_jumps: - # type=int|default=5000: Num of jumps to be made by MCMC - burn_in: - # type=range|default=0: Total num of jumps at start of MCMC to be discarded - burn_in_no_ard: - # type=range|default=0: num of burnin jumps before the ard is imposed - sample_every: - # type=range|default=1: Num of jumps for each sample (MCMC) - update_proposal_every: - # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) - seed: - # type=int|default=0: seed for pseudo random number generator - no_ard: - # type=bool|default=False: Turn ARD off on all fibres - all_ard: - # type=bool|default=False: Turn ARD on on all fibres - no_spat: - # type=bool|default=False: Initialise with tensor, not spatially - non_linear: - # type=bool|default=False: Initialise with nonlinear fitting - cnlinear: - # type=bool|default=False: Initialise with constrained nonlinear fitting - rician: - # type=bool|default=False: use Rician noise modeling - f0_noard: - # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 - f0_ard: - # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 - force_dir: - # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -doctests: [] diff --git a/nipype-auto-conv/specs/fslx_command_callables.py b/nipype-auto-conv/specs/fslx_command_callables.py deleted file mode 100644 index 048758a..0000000 --- a/nipype-auto-conv/specs/fslx_command_callables.py +++ /dev/null @@ -1 +0,0 @@ -"""Module to put any functions that are referred to in FSLXCommand.yaml""" diff --git a/nipype-auto-conv/specs/fugue.yaml b/nipype-auto-conv/specs/fugue.yaml index bb13f87..20d9554 100644 --- a/nipype-auto-conv/specs/fugue.yaml +++ b/nipype-auto-conv/specs/fugue.yaml @@ -82,28 +82,31 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + fmap_in_file: generic/file + # type=file|default=: filename for loading fieldmap (rad/s) + fmap_out_file: Path + # type=file: fieldmap file + # type=file|default=: filename for saving fieldmap (rad/s) in_file: medimage/nifti1 # type=file|default=: filename of input volume - shift_in_file: medimage/nifti1 - # type=file|default=: filename for reading pixel shift volume + mask_file: medimage/nifti1 + # type=file|default=: filename for loading valid mask phasemap_in_file: medimage/nifti1 # type=file|default=: filename for input phase image - fmap_in_file: generic/file - # type=file|default=: filename for loading fieldmap (rad/s) - unwarped_file: generic/file + shift_in_file: medimage/nifti1 + # type=file|default=: filename for reading pixel shift volume + shift_out_file: Path + # type=file: voxel shift map file + # type=file|default=: filename for saving pixel shift volume + unwarped_file: Path # type=file: unwarped file # type=file|default=: apply unwarping and save as filename - warped_file: generic/file + warped_file: Path # type=file: forward warped file # type=file|default=: apply forward warping and save as filename - mask_file: medimage/nifti1 - # type=file|default=: filename for loading valid mask - shift_out_file: generic/file - # type=file: voxel shift map file - # type=file|default=: filename for saving pixel shift volume - fmap_out_file: generic/file - # type=file: fieldmap file - # type=file|default=: filename for saving fieldmap (rad/s) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -117,18 +120,18 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + fmap_out_file: generic/file + # type=file: fieldmap file + # type=file|default=: filename for saving fieldmap (rad/s) + shift_out_file: generic/file + # type=file: voxel shift map file + # type=file|default=: filename for saving pixel shift volume unwarped_file: generic/file # type=file: unwarped file # type=file|default=: apply unwarping and save as filename warped_file: generic/file # type=file: forward warped file # type=file|default=: apply forward warping and save as filename - shift_out_file: generic/file - # type=file: voxel shift map file - # type=file|default=: filename for saving pixel shift volume - fmap_out_file: generic/file - # type=file: fieldmap file - # type=file|default=: filename for saving fieldmap (rad/s) callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -215,7 +218,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -243,7 +246,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -273,7 +276,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -303,7 +306,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -324,18 +327,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"epi.nii"' # type=file|default=: filename of input volume - mask_file: + mask_file: '"epi_mask.nii"' # type=file|default=: filename for loading valid mask - shift_in_file: + shift_in_file: '"vsm.nii" # Previously computed with fugue as well' # type=file|default=: filename for reading pixel shift volume unwarp_direction: '"y"' # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS @@ -345,20 +348,20 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"epi.nii"' # type=file|default=: filename of input volume forward_warping: 'True' # type=bool|default=False: apply forward warping instead of unwarping - mask_file: + mask_file: '"epi_mask.nii"' # type=file|default=: filename for loading valid mask - shift_in_file: + shift_in_file: '"vsm.nii" # Previously computed with fugue as well' # type=file|default=: filename for reading pixel shift volume unwarp_direction: '"y"' # type=enum|default='x'|allowed['x','x-','y','y-','z','z-']: specifies direction of warping (default y) output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS @@ -368,9 +371,9 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - phasemap_in_file: + phasemap_in_file: '"epi_phasediff.nii"' # type=file|default=: filename for input phase image - mask_file: + mask_file: '"epi_mask.nii"' # type=file|default=: filename for loading valid mask dwell_to_asym_ratio: (0.77e-3 * 3) / 2.46e-3 # type=float|default=0.0: set the dwell to asym time ratio @@ -381,7 +384,7 @@ doctests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fugue_callables.py b/nipype-auto-conv/specs/fugue_callables.py index 3d58eb5..befea95 100644 --- a/nipype-auto-conv/specs/fugue_callables.py +++ b/nipype-auto-conv/specs/fugue_callables.py @@ -1 +1,359 @@ -"""Module to put any functions that are referred to in FUGUE.yaml""" +"""Module to put any functions that are referred to in the "callables" section of FUGUE.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def fmap_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fmap_out_file"] + + +def shift_out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["shift_out_file"] + + +def unwarped_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["unwarped_file"] + + +def warped_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["warped_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/glm.yaml b/nipype-auto-conv/specs/glm.yaml index 480043f..532b6d8 100644 --- a/nipype-auto-conv/specs/glm.yaml +++ b/nipype-auto-conv/specs/glm.yaml @@ -30,40 +30,43 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: medimage/nifti1 - # type=file|default=: input file name (text matrix or 3D/4D image file) - out_file: generic/file - # type=file: file name of GLM parameters (if generated) - # type=file|default=: filename for GLM parameter estimates (GLM betas) - design: medimage/nifti1 - # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) contrasts: generic/file # type=file|default=: matrix of t-statics contrasts + design: medimage/nifti1 + # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) + in_file: medimage/nifti1 + # type=file|default=: input file name (text matrix or 3D/4D image file) mask: generic/file # type=file|default=: mask image file name if input is image - out_cope: generic/file + out_cope: Path # type=outputmultiobject: output file name for COPEs (either as text file or image) # type=file|default=: output file name for COPE (either as txt or image - out_z_name: generic/file - # type=file|default=: output file name for Z-stats (either as txt or image - out_t_name: generic/file - # type=file|default=: output file name for t-stats (either as txt or image - out_p_name: generic/file - # type=file|default=: output file name for p-values of Z-stats (either as text file or image) - out_f_name: generic/file + out_data_name: Path + # type=file|default=: output file name for pre-processed data + out_f_name: Path # type=file|default=: output file name for F-value of full model fit - out_pf_name: generic/file + out_file: Path + # type=file: file name of GLM parameters (if generated) + # type=file|default=: filename for GLM parameter estimates (GLM betas) + out_p_name: Path + # type=file|default=: output file name for p-values of Z-stats (either as text file or image) + out_pf_name: Path # type=file|default=: output file name for p-value for full model fit - out_res_name: generic/file + out_res_name: Path # type=file|default=: output file name for residuals - out_varcb_name: generic/file - # type=file|default=: output file name for variance of COPEs - out_sigsq_name: generic/file + out_sigsq_name: Path # type=file|default=: output file name for residual noise variance sigma-square - out_data_name: generic/file - # type=file|default=: output file name for pre-processed data - out_vnscales_name: generic/file + out_t_name: Path + # type=file|default=: output file name for t-stats (either as txt or image + out_varcb_name: Path + # type=file|default=: output file name for variance of COPEs + out_vnscales_name: Path # type=file|default=: output file name for scaling factors for variance normalisation + out_z_name: Path + # type=file|default=: output file name for Z-stats (either as txt or image + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -77,9 +80,32 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_cope: generic/file+list-of + # type=outputmultiobject: output file name for COPEs (either as text file or image) + # type=file|default=: output file name for COPE (either as txt or image + out_data: generic/file+list-of + # type=outputmultiobject: output file for preprocessed data + out_f: generic/file+list-of + # type=outputmultiobject: output file name for F-value of full model fit out_file: generic/file # type=file: file name of GLM parameters (if generated) # type=file|default=: filename for GLM parameter estimates (GLM betas) + out_p: generic/file+list-of + # type=outputmultiobject: output file name for p-values of Z-stats (either as text file or image) + out_pf: generic/file+list-of + # type=outputmultiobject: output file name for p-value for full model fit + out_res: generic/file+list-of + # type=outputmultiobject: output file name for residuals + out_sigsq: generic/file+list-of + # type=outputmultiobject: output file name for residual noise variance sigma-square + out_t: generic/file+list-of + # type=outputmultiobject: output file name for t-stats (either as text file or image) + out_varcb: generic/file+list-of + # type=outputmultiobject: output file name for variance of COPEs + out_vnscales: generic/file+list-of + # type=outputmultiobject: output file name for scaling factors for variance normalisation + out_z: generic/file+list-of + # type=outputmultiobject: output file name for COPEs (either as text file or image) callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -142,7 +168,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -166,7 +192,7 @@ tests: output_type: '"NIFTI"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.interfaces.fsl as fsl expected_outputs: @@ -188,14 +214,14 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii"' # type=file|default=: input file name (text matrix or 3D/4D image file) - design: + design: '"maps.nii"' # type=file|default=: file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression) output_type: '"NIFTI"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/glm_callables.py b/nipype-auto-conv/specs/glm_callables.py index e54bc44..3f35c49 100644 --- a/nipype-auto-conv/specs/glm_callables.py +++ b/nipype-auto-conv/specs/glm_callables.py @@ -1 +1,457 @@ -"""Module to put any functions that are referred to in GLM.yaml""" +"""Module to put any functions that are referred to in the "callables" section of GLM.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_cope_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_cope"] + + +def out_data_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_data"] + + +def out_f_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_f"] + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def out_p_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_p"] + + +def out_pf_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_pf"] + + +def out_res_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_res"] + + +def out_sigsq_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_sigsq"] + + +def out_t_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_t"] + + +def out_varcb_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_varcb"] + + +def out_vnscales_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_vnscales"] + + +def out_z_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_z"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L2511 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = nipype_interfaces_fsl__FSLCommand___list_outputs() + + if inputs.out_cope is not attrs.NOTHING: + outputs["out_cope"] = os.path.abspath(inputs.out_cope) + + if inputs.out_z_name is not attrs.NOTHING: + outputs["out_z"] = os.path.abspath(inputs.out_z_name) + + if inputs.out_t_name is not attrs.NOTHING: + outputs["out_t"] = os.path.abspath(inputs.out_t_name) + + if inputs.out_p_name is not attrs.NOTHING: + outputs["out_p"] = os.path.abspath(inputs.out_p_name) + + if inputs.out_f_name is not attrs.NOTHING: + outputs["out_f"] = os.path.abspath(inputs.out_f_name) + + if inputs.out_pf_name is not attrs.NOTHING: + outputs["out_pf"] = os.path.abspath(inputs.out_pf_name) + + if inputs.out_res_name is not attrs.NOTHING: + outputs["out_res"] = os.path.abspath(inputs.out_res_name) + + if inputs.out_varcb_name is not attrs.NOTHING: + outputs["out_varcb"] = os.path.abspath(inputs.out_varcb_name) + + if inputs.out_sigsq_name is not attrs.NOTHING: + outputs["out_sigsq"] = os.path.abspath(inputs.out_sigsq_name) + + if inputs.out_data_name is not attrs.NOTHING: + outputs["out_data"] = os.path.abspath(inputs.out_data_name) + + if inputs.out_vnscales_name is not attrs.NOTHING: + outputs["out_vnscales"] = os.path.abspath(inputs.out_vnscales_name) + + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L891 of /interfaces/base/core.py +def nipype_interfaces_fsl__FSLCommand___list_outputs( + inputs=None, stdout=None, stderr=None, output_dir=None +): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/ica__aroma.yaml b/nipype-auto-conv/specs/ica__aroma.yaml index a637cc3..2a98008 100644 --- a/nipype-auto-conv/specs/ica__aroma.yaml +++ b/nipype-auto-conv/specs/ica__aroma.yaml @@ -46,23 +46,26 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + feat_dir: generic/directory + # type=directory|default=: If a feat directory exists and temporal filtering has not been run yet, ICA_AROMA can use the files in this directory. + fnirt_warp_file: medimage/nifti1 + # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) in_file: medimage/nifti1 # type=file|default=: volume to be denoised mask: medimage/nifti-gz # type=file|default=: path/name volume mask mat_file: datascience/text-matrix # type=file|default=: path/name of the mat-file describing the affine registration (e.g. FSL FLIRT) of the functional data to structural space (.mat file) - fnirt_warp_file: medimage/nifti1 - # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) + melodic_dir: generic/directory + # type=directory|default=: path to MELODIC directory if MELODIC has already been run motion_parameters: text/text-file # type=file|default=: motion parameters file - feat_dir: generic/directory - # type=directory|default=: If a feat directory exists and temporal filtering has not been run yet, ICA_AROMA can use the files in this directory. - out_dir: generic/directory + out_dir: Path # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) # type=directory|default='out': output directory - melodic_dir: generic/directory - # type=directory|default=: path to MELODIC directory if MELODIC has already been run + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -122,7 +125,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -155,7 +158,7 @@ tests: # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) # type=directory|default='out': output directory imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.testing name: example_data @@ -179,15 +182,15 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii"' # type=file|default=: volume to be denoised - mat_file: + mat_file: '"func_to_struct.mat"' # type=file|default=: path/name of the mat-file describing the affine registration (e.g. FSL FLIRT) of the functional data to structural space (.mat file) - fnirt_warp_file: + fnirt_warp_file: '"warpfield.nii"' # type=file|default=: File name of the warp-file describing the non-linear registration (e.g. FSL FNIRT) of the structural data to MNI152 space (.nii.gz) - motion_parameters: + motion_parameters: '"fsl_mcflirt_movpar.txt"' # type=file|default=: motion parameters file - mask: + mask: '"mask.nii.gz"' # type=file|default=: path/name volume mask denoise_type: '"both"' # type=enum|default='nonaggr'|allowed['aggr','both','no','nonaggr']: Type of denoising strategy: -no: only classification, no denoising -nonaggr (default): non-aggresssive denoising, i.e. partial component regression -aggr: aggressive denoising, i.e. full component regression -both: both aggressive and non-aggressive denoising (two outputs) @@ -195,7 +198,7 @@ doctests: # type=directory: directory contains (in addition to the denoised files): melodic.ica + classified_motion_components + classification_overview + feature_scores + melodic_ic_mni) # type=directory|default='out': output directory imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/ica__aroma_callables.py b/nipype-auto-conv/specs/ica__aroma_callables.py index ebc5c58..2c25633 100644 --- a/nipype-auto-conv/specs/ica__aroma_callables.py +++ b/nipype-auto-conv/specs/ica__aroma_callables.py @@ -1 +1,46 @@ -"""Module to put any functions that are referred to in ICA_AROMA.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ICA_AROMA.yaml""" + +import os + + +def aggr_denoised_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["aggr_denoised_file"] + + +def nonaggr_denoised_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["nonaggr_denoised_file"] + + +def out_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_dir"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L151 of /interfaces/fsl/aroma.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_dir"] = os.path.abspath(inputs.out_dir) + out_dir = outputs["out_dir"] + + if inputs.denoise_type in ("aggr", "both"): + outputs["aggr_denoised_file"] = os.path.join( + out_dir, "denoised_func_data_aggr.nii.gz" + ) + if inputs.denoise_type in ("nonaggr", "both"): + outputs["nonaggr_denoised_file"] = os.path.join( + out_dir, "denoised_func_data_nonaggr.nii.gz" + ) + return outputs diff --git a/nipype-auto-conv/specs/image_maths.yaml b/nipype-auto-conv/specs/image_maths.yaml index ac462f2..f156853 100644 --- a/nipype-auto-conv/specs/image_maths.yaml +++ b/nipype-auto-conv/specs/image_maths.yaml @@ -41,6 +41,12 @@ inputs: # type=file|default=: mask_file: generic/file # type=file|default=: use (following image>0) to mask current image + out_file: Path + # type=file: + # type=file|default=: + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -93,7 +99,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -118,7 +124,7 @@ tests: # type=file: # type=file|default=: imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.testing name: anatfile @@ -142,7 +148,7 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: anatfile # type=file|default=: op_string: '"-add 5"' # type=str|default='': string defining the operation, i. e. -add @@ -150,7 +156,7 @@ doctests: # type=file: # type=file|default=: imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/image_maths_callables.py b/nipype-auto-conv/specs/image_maths_callables.py index af88ca1..0689a1c 100644 --- a/nipype-auto-conv/specs/image_maths_callables.py +++ b/nipype-auto-conv/specs/image_maths_callables.py @@ -1 +1,332 @@ -"""Module to put any functions that are referred to in ImageMaths.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ImageMaths.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L627 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L635 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + suffix = "_maths" # ohinds: build suffix + if inputs.suffix is not attrs.NOTHING: + suffix = inputs.suffix + outputs = {} + outputs["out_file"] = inputs.out_file + if outputs["out_file"] is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/image_meants.yaml b/nipype-auto-conv/specs/image_meants.yaml index 2ce06fd..37df853 100644 --- a/nipype-auto-conv/specs/image_meants.yaml +++ b/nipype-auto-conv/specs/image_meants.yaml @@ -28,6 +28,12 @@ inputs: # type=file|default=: input file for computing the average timeseries mask: generic/file # type=file|default=: input 3D mask + out_file: Path + # type=file: path/name of output text matrix + # type=file|default=: name of output text matrix + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -86,7 +92,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/image_meants_callables.py b/nipype-auto-conv/specs/image_meants_callables.py index 0e60de8..b7eb8a5 100644 --- a/nipype-auto-conv/specs/image_meants_callables.py +++ b/nipype-auto-conv/specs/image_meants_callables.py @@ -1 +1,331 @@ -"""Module to put any functions that are referred to in ImageMeants.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ImageMeants.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L184 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmeants" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L174 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if outputs["out_file"] is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix="_ts", + ext=".txt", + change_ext=True, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/image_stats.yaml b/nipype-auto-conv/specs/image_stats.yaml index 2ca5523..8c2f3fc 100644 --- a/nipype-auto-conv/specs/image_stats.yaml +++ b/nipype-auto-conv/specs/image_stats.yaml @@ -37,10 +37,13 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: input file to generate stats of - mask_file: generic/file - # type=file|default=: mask file used for option -k %s index_mask_file: generic/file # type=file|default=: generate separate n submasks from indexMask, for indexvalues 1..n where n is the maximum index value in indexMask, and generate statistics for each submask + mask_file: generic/file + # type=file|default=: mask file used for option -k %s + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -57,6 +60,8 @@ outputs: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields + out_stat: out_stat_callable + # type=any: stats output templates: # dict[str, str] - `output_file_template` values to be provided to output fields requirements: @@ -82,7 +87,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -104,7 +109,7 @@ tests: op_string: '"-M"' # type=str|default='': string defining the operation, options are applied in order, e.g. -M -l 10 -M will report the non-zero mean, apply a threshold and then report the new nonzero mean imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.testing name: funcfile @@ -128,12 +133,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: funcfile # type=file|default=: input file to generate stats of op_string: '"-M"' # type=str|default='': string defining the operation, options are applied in order, e.g. -M -l 10 -M will report the non-zero mean, apply a threshold and then report the new nonzero mean imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/image_stats_callables.py b/nipype-auto-conv/specs/image_stats_callables.py index 1a14596..691ce5b 100644 --- a/nipype-auto-conv/specs/image_stats_callables.py +++ b/nipype-auto-conv/specs/image_stats_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in ImageStats.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ImageStats.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_stat_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_stat"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/inv_warp.yaml b/nipype-auto-conv/specs/inv_warp.yaml index 6b4c1f5..9151af0 100644 --- a/nipype-auto-conv/specs/inv_warp.yaml +++ b/nipype-auto-conv/specs/inv_warp.yaml @@ -37,13 +37,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - warp: medimage/nifti1 - # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). - reference: medimage/nifti1 - # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. - inverse_warp: generic/file + inverse_warp: Path # type=file: Name of output file, containing warps that are the "reverse" of those in --warp. # type=file|default=: Name of output file, containing warps that are the "reverse" of those in --warp. This will be a field-file (rather than a file of spline coefficients), and it will have any affine component included as part of the displacements. + reference: medimage/nifti1 + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + warp: medimage/nifti1 + # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -99,7 +102,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -123,7 +126,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -144,14 +147,14 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - warp: + warp: '"struct2mni.nii"' # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). - reference: + reference: '"anatomical.nii"' # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/inv_warp_callables.py b/nipype-auto-conv/specs/inv_warp_callables.py index 3df23d8..f9af045 100644 --- a/nipype-auto-conv/specs/inv_warp_callables.py +++ b/nipype-auto-conv/specs/inv_warp_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in InvWarp.yaml""" +"""Module to put any functions that are referred to in the "callables" section of InvWarp.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def inverse_warp_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["inverse_warp"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/isotropic_smooth.yaml b/nipype-auto-conv/specs/isotropic_smooth.yaml index 0d358ea..6ffdabd 100644 --- a/nipype-auto-conv/specs/isotropic_smooth.yaml +++ b/nipype-auto-conv/specs/isotropic_smooth.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -74,7 +80,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/isotropic_smooth_callables.py b/nipype-auto-conv/specs/isotropic_smooth_callables.py index cb3b0b0..214d374 100644 --- a/nipype-auto-conv/specs/isotropic_smooth_callables.py +++ b/nipype-auto-conv/specs/isotropic_smooth_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in IsotropicSmooth.yaml""" +"""Module to put any functions that are referred to in the "callables" section of IsotropicSmooth.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/l2_model.yaml b/nipype-auto-conv/specs/l2_model.yaml index 17c0d9c..fb142c5 100644 --- a/nipype-auto-conv/specs/l2_model.yaml +++ b/nipype-auto-conv/specs/l2_model.yaml @@ -28,6 +28,9 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -41,12 +44,12 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - design_mat: generic/file - # type=file: design matrix file design_con: generic/file # type=file: design contrast file design_grp: generic/file # type=file: design group file + design_mat: generic/file + # type=file: design matrix file callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -61,7 +64,7 @@ tests: num_copes: # type=range|default=1: number of copes to be combined imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/l2_model_callables.py b/nipype-auto-conv/specs/l2_model_callables.py index 05b7a8c..faac4e1 100644 --- a/nipype-auto-conv/specs/l2_model_callables.py +++ b/nipype-auto-conv/specs/l2_model_callables.py @@ -1 +1,32 @@ -"""Module to put any functions that are referred to in L2Model.yaml""" +"""Module to put any functions that are referred to in the "callables" section of L2Model.yaml""" + +import os + + +def design_con_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_con"] + + +def design_grp_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_grp"] + + +def design_mat_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_mat"] + + +# Original source at L1431 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + for field in list(outputs.keys()): + outputs[field] = os.path.join(output_dir, field.replace("_", ".")) + return outputs diff --git a/nipype-auto-conv/specs/level_1_design.yaml b/nipype-auto-conv/specs/level_1_design.yaml index 227d174..a85f6a9 100644 --- a/nipype-auto-conv/specs/level_1_design.yaml +++ b/nipype-auto-conv/specs/level_1_design.yaml @@ -31,6 +31,9 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -44,6 +47,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + fsf_files: generic/file+list-of + # type=outputmultiobject: FSL feat specification files callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -68,7 +73,7 @@ tests: contrasts: # type=list|default=[]: List of contrasts with each contrast being a list of the form - [('name', 'stat', [condition list], [weight list], [session list])]. if session list is None or not provided, all sessions are used. For F contrasts, the condition list should contain previously defined T-contrasts. imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/level_1_design_callables.py b/nipype-auto-conv/specs/level_1_design_callables.py index 0558037..ed9f720 100644 --- a/nipype-auto-conv/specs/level_1_design_callables.py +++ b/nipype-auto-conv/specs/level_1_design_callables.py @@ -1 +1,63 @@ -"""Module to put any functions that are referred to in Level1Design.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Level1Design.yaml""" + +import os + + +def ev_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["ev_files"] + + +def fsf_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fsf_files"] + + +# Original source at L343 of /interfaces/fsl/model.py +def _format_session_info( + session_info, inputs=None, stdout=None, stderr=None, output_dir=None +): + if isinstance(session_info, dict): + session_info = [session_info] + return session_info + + +# Original source at L414 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + cwd = output_dir + outputs["fsf_files"] = [] + outputs["ev_files"] = [] + basis_key = list(inputs.bases.keys())[0] + ev_parameters = dict(inputs.bases[basis_key]) + for runno, runinfo in enumerate( + _format_session_info( + inputs.session_info, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ): + outputs["fsf_files"].append(os.path.join(cwd, "run%d.fsf" % runno)) + outputs["ev_files"].insert(runno, []) + evname = [] + for field in ["cond", "regress"]: + for i, cond in enumerate(runinfo[field]): + name = cond["name"] + evname.append(name) + evfname = os.path.join( + cwd, "ev_%s_%d_%d.txt" % (name, runno, len(evname)) + ) + if field == "cond": + ev_parameters["temporalderiv"] = int( + bool(ev_parameters.get("derivs", False)) + ) + if ev_parameters["temporalderiv"]: + evname.append(name + "TD") + outputs["ev_files"][runno].append(os.path.join(cwd, evfname)) + return outputs diff --git a/nipype-auto-conv/specs/make_dyadic_vectors.yaml b/nipype-auto-conv/specs/make_dyadic_vectors.yaml index 55d445a..e41d3cd 100644 --- a/nipype-auto-conv/specs/make_dyadic_vectors.yaml +++ b/nipype-auto-conv/specs/make_dyadic_vectors.yaml @@ -21,14 +21,17 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - theta_vol: generic/file - # type=file|default=: - phi_vol: generic/file - # type=file|default=: mask: generic/file # type=file|default=: output: generic/file # type=file|default='dyads': + phi_vol: generic/file + # type=file|default=: + theta_vol: generic/file + # type=file|default=: + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -42,10 +45,10 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - dyads: generic/file - # type=file: dispersion: generic/file # type=file: + dyads: generic/file + # type=file: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -74,7 +77,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/make_dyadic_vectors_callables.py b/nipype-auto-conv/specs/make_dyadic_vectors_callables.py index 3864dbd..8851bde 100644 --- a/nipype-auto-conv/specs/make_dyadic_vectors_callables.py +++ b/nipype-auto-conv/specs/make_dyadic_vectors_callables.py @@ -1 +1,332 @@ -"""Module to put any functions that are referred to in MakeDyadicVectors.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MakeDyadicVectors.yaml""" + +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def dispersion_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dispersion"] + + +def dyads_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dyads"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "make_dyadic_vectors" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1571 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["dyads"] = _gen_fname( + inputs.output, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["dispersion"] = _gen_fname( + inputs.output, + suffix="_dispersion", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/maths_command.yaml b/nipype-auto-conv/specs/maths_command.yaml index 1f5eae6..e9acb76 100644 --- a/nipype-auto-conv/specs/maths_command.yaml +++ b/nipype-auto-conv/specs/maths_command.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -70,7 +76,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/maths_command_callables.py b/nipype-auto-conv/specs/maths_command_callables.py index 84e0f13..c11baf2 100644 --- a/nipype-auto-conv/specs/maths_command_callables.py +++ b/nipype-auto-conv/specs/maths_command_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MathsCommand.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MathsCommand.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/max_image.yaml b/nipype-auto-conv/specs/max_image.yaml index 127dbca..1d0e2d0 100644 --- a/nipype-auto-conv/specs/max_image.yaml +++ b/nipype-auto-conv/specs/max_image.yaml @@ -33,6 +33,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -83,7 +89,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -103,7 +109,7 @@ tests: in_file: # type=file|default=: image to operate on imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -124,10 +130,10 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii" # doctest: +SKIP' # type=file|default=: image to operate on imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/max_image_callables.py b/nipype-auto-conv/specs/max_image_callables.py index 940bd9a..61b6ae6 100644 --- a/nipype-auto-conv/specs/max_image_callables.py +++ b/nipype-auto-conv/specs/max_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MaxImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MaxImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/maxn_image.yaml b/nipype-auto-conv/specs/maxn_image.yaml index 00a05a4..ac326f3 100644 --- a/nipype-auto-conv/specs/maxn_image.yaml +++ b/nipype-auto-conv/specs/maxn_image.yaml @@ -25,6 +25,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -75,7 +81,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/maxn_image_callables.py b/nipype-auto-conv/specs/maxn_image_callables.py index 31eb42f..87f0b52 100644 --- a/nipype-auto-conv/specs/maxn_image_callables.py +++ b/nipype-auto-conv/specs/maxn_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MaxnImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MaxnImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/mcflirt.yaml b/nipype-auto-conv/specs/mcflirt.yaml index 81d3b1f..f1ea002 100644 --- a/nipype-auto-conv/specs/mcflirt.yaml +++ b/nipype-auto-conv/specs/mcflirt.yaml @@ -40,8 +40,14 @@ inputs: # type=file|default=: timeseries to motion-correct init: generic/file # type=file|default=: initial transformation matrix + out_file: Path + # type=file: motion-corrected timeseries + # type=file|default=: file to write ref_file: generic/file # type=file|default=: target image for motion correction + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -55,17 +61,21 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + mat_file: generic/file+list-of + # type=outputmultiobject: transformation matrices + mean_img: generic/file + # type=file: mean timeseries image (if mean_vol=True) out_file: medimage/nifti1 # type=file: motion-corrected timeseries # type=file|default=: file to write - variance_img: generic/file - # type=file: variance image - std_img: generic/file - # type=file: standard deviation image - mean_img: generic/file - # type=file: mean timeseries image (if mean_vol=True) par_file: generic/file # type=file: text-file with motion parameters + rms_files: generic/file+list-of + # type=outputmultiobject: absolute and relative displacement parameters + std_img: generic/file + # type=file: standard deviation image + variance_img: generic/file + # type=file: variance image callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -128,7 +138,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -153,7 +163,7 @@ tests: # type=file: motion-corrected timeseries # type=file|default=: file to write imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -174,7 +184,7 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii"' # type=file|default=: timeseries to motion-correct cost: '"mutualinfo"' # type=enum|default='mutualinfo'|allowed['corratio','leastsquares','mutualinfo','normcorr','normmi','woods']: cost function to optimize @@ -182,7 +192,7 @@ doctests: # type=file: motion-corrected timeseries # type=file|default=: file to write imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/mcflirt_callables.py b/nipype-auto-conv/specs/mcflirt_callables.py index 7fb6bc8..d6bc0a6 100644 --- a/nipype-auto-conv/specs/mcflirt_callables.py +++ b/nipype-auto-conv/specs/mcflirt_callables.py @@ -1 +1,466 @@ -"""Module to put any functions that are referred to in MCFLIRT.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MCFLIRT.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from looseversion import LooseVersion +from nibabel import load +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def mat_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mat_file"] + + +def mean_img_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_img"] + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def par_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["par_file"] + + +def rms_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["rms_files"] + + +def std_img_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["std_img"] + + +def variance_img_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["variance_img"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L962 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _gen_outfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "mcflirt" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L967 of /interfaces/fsl/preprocess.py +def _gen_outfilename(inputs=None, stdout=None, stderr=None, output_dir=None): + out_file = inputs.out_file + if out_file is not attrs.NOTHING: + out_file = os.path.realpath(out_file) + if (out_file is attrs.NOTHING) and (inputs.in_file is not attrs.NOTHING): + out_file = _gen_fname( + inputs.in_file, + suffix="_mcf", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return os.path.abspath(out_file) + + +# Original source at L906 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + + outputs["out_file"] = _gen_outfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + output_dir = os.path.dirname(outputs["out_file"]) + + if (inputs.stats_imgs is not attrs.NOTHING) and inputs.stats_imgs: + if LooseVersion(Info.version()) < LooseVersion("6.0.0"): + # FSL <6.0 outputs have .nii.gz_variance.nii.gz as extension + outputs["variance_img"] = _gen_fname( + outputs["out_file"] + "_variance.ext", + cwd=output_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["std_img"] = _gen_fname( + outputs["out_file"] + "_sigma.ext", + cwd=output_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs["variance_img"] = _gen_fname( + outputs["out_file"], + suffix="_variance", + cwd=output_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["std_img"] = _gen_fname( + outputs["out_file"], + suffix="_sigma", + cwd=output_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + # The mean image created if -stats option is specified ('meanvol') + # is missing the top and bottom slices. Therefore we only expose the + # mean image created by -meanvol option ('mean_reg') which isn't + # corrupted. + # Note that the same problem holds for the std and variance image. + + if (inputs.mean_vol is not attrs.NOTHING) and inputs.mean_vol: + if LooseVersion(Info.version()) < LooseVersion("6.0.0"): + # FSL <6.0 outputs have .nii.gz_mean_img.nii.gz as extension + outputs["mean_img"] = _gen_fname( + outputs["out_file"] + "_mean_reg.ext", + cwd=output_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs["mean_img"] = _gen_fname( + outputs["out_file"], + suffix="_mean_reg", + cwd=output_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + if (inputs.save_mats is not attrs.NOTHING) and inputs.save_mats: + _, filename = os.path.split(outputs["out_file"]) + matpathname = os.path.join(output_dir, filename + ".mat") + _, _, _, timepoints = load(inputs.in_file).shape + outputs["mat_file"] = [] + for t in range(timepoints): + outputs["mat_file"].append(os.path.join(matpathname, "MAT_%04d" % t)) + if (inputs.save_plots is not attrs.NOTHING) and inputs.save_plots: + # Note - if e.g. out_file has .nii.gz, you get .nii.gz.par, + # which is what mcflirt does! + outputs["par_file"] = outputs["out_file"] + ".par" + if (inputs.save_rms is not attrs.NOTHING) and inputs.save_rms: + outfile = outputs["out_file"] + outputs["rms_files"] = [outfile + "_abs.rms", outfile + "_rel.rms"] + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/mean_image.yaml b/nipype-auto-conv/specs/mean_image.yaml index 6f15b26..c30b541 100644 --- a/nipype-auto-conv/specs/mean_image.yaml +++ b/nipype-auto-conv/specs/mean_image.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -72,7 +78,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/mean_image_callables.py b/nipype-auto-conv/specs/mean_image_callables.py index 1d3333c..5943cf3 100644 --- a/nipype-auto-conv/specs/mean_image_callables.py +++ b/nipype-auto-conv/specs/mean_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MeanImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MeanImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/median_image.yaml b/nipype-auto-conv/specs/median_image.yaml index ee4f848..9b40b41 100644 --- a/nipype-auto-conv/specs/median_image.yaml +++ b/nipype-auto-conv/specs/median_image.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -72,7 +78,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/median_image_callables.py b/nipype-auto-conv/specs/median_image_callables.py index d4df040..ac60356 100644 --- a/nipype-auto-conv/specs/median_image_callables.py +++ b/nipype-auto-conv/specs/median_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MedianImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MedianImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/melodic.yaml b/nipype-auto-conv/specs/melodic.yaml index 9e355f6..05f40e8 100644 --- a/nipype-auto-conv/specs/melodic.yaml +++ b/nipype-auto-conv/specs/melodic.yaml @@ -44,26 +44,32 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + ICs: generic/file + # type=file|default=: filename of the IC components file for mixture modelling + bg_image: generic/file + # type=file|default=: specify background image for report (default: mean image) in_files: medimage/nifti1+list-of # type=inputmultiobject|default=[]: input file names (either single file name or a list) mask: generic/file # type=file|default=: file name of mask for thresholding - ICs: generic/file - # type=file|default=: filename of the IC components file for mixture modelling mix: generic/file # type=file|default=: mixing matrix for mixture modelling / filtering + out_dir: Path + # type=directory: + # type=directory|default=: output directory name + s_con: medimage-fsl/con + # type=file|default=: t-contrast matrix across subject-domain + s_des: datascience/text-matrix + # type=file|default=: design matrix across subject-domain smode: generic/file # type=file|default=: matrix of session modes for report generation - bg_image: generic/file - # type=file|default=: specify background image for report (default: mean image) - t_des: datascience/text-matrix - # type=file|default=: design matrix across time-domain t_con: medimage-fsl/con # type=file|default=: t-contrast matrix across time-domain - s_des: datascience/text-matrix - # type=file|default=: design matrix across subject-domain - s_con: medimage-fsl/con - # type=file|default=: t-contrast matrix across subject-domain + t_des: datascience/text-matrix + # type=file|default=: design matrix across time-domain + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -200,7 +206,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -243,7 +249,7 @@ tests: # type=directory: # type=directory|default=: output directory name imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -266,7 +272,7 @@ doctests: # '.mock()' method of the corresponding class is used instead. approach: '"tica"' # type=str|default='': approach for decomposition, 2D: defl, symm (default), 3D: tica (default), concat - in_files: + in_files: '["functional.nii", "functional2.nii", "functional3.nii"]' # type=inputmultiobject|default=[]: input file names (either single file name or a list) no_bet: 'True' # type=bool|default=False: switch off BET @@ -278,19 +284,19 @@ doctests: # type=float|default=0.0: threshold for Mixture Model based inference out_stats: 'True' # type=bool|default=False: output thresholded maps and probability maps - t_des: + t_des: '"timeDesign.mat"' # type=file|default=: design matrix across time-domain - t_con: + t_con: '"timeDesign.con"' # type=file|default=: t-contrast matrix across time-domain - s_des: + s_des: '"subjectDesign.mat"' # type=file|default=: design matrix across subject-domain - s_con: + s_con: '"subjectDesign.con"' # type=file|default=: t-contrast matrix across subject-domain out_dir: '"groupICA.out"' # type=directory: # type=directory|default=: output directory name imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/melodic_callables.py b/nipype-auto-conv/specs/melodic_callables.py index b6075b9..9ab73a8 100644 --- a/nipype-auto-conv/specs/melodic_callables.py +++ b/nipype-auto-conv/specs/melodic_callables.py @@ -1 +1,46 @@ -"""Module to put any functions that are referred to in MELODIC.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MELODIC.yaml""" + +import attrs +import os + + +def out_dir_default(inputs): + return _gen_filename("out_dir", inputs=inputs) + + +def out_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_dir"] + + +def report_dir_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["report_dir"] + + +# Original source at L1858 of /interfaces/fsl/model.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_dir": + return output_dir + + +# Original source at L1848 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.out_dir is not attrs.NOTHING: + outputs["out_dir"] = os.path.abspath(inputs.out_dir) + else: + outputs["out_dir"] = _gen_filename( + "out_dir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if (inputs.report is not attrs.NOTHING) and inputs.report: + outputs["report_dir"] = os.path.join(outputs["out_dir"], "report") + return outputs diff --git a/nipype-auto-conv/specs/merge.yaml b/nipype-auto-conv/specs/merge.yaml index 8f5e750..dcf8551 100644 --- a/nipype-auto-conv/specs/merge.yaml +++ b/nipype-auto-conv/specs/merge.yaml @@ -46,9 +46,12 @@ inputs: # passed to the field in the automatically generated unittests. in_files: medimage/nifti1+list-of # type=list|default=[]: - merged_file: generic/file + merged_file: Path # type=file: # type=file|default=: + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -92,7 +95,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -118,7 +121,7 @@ tests: tr: '2.25' # type=float|default=0.0: use to specify TR in seconds (default is 1.00 sec), overrides dimension and sets it to tr imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -139,7 +142,7 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_files: + in_files: '["functional2.nii", "functional3.nii"]' # type=list|default=[]: dimension: '"t"' # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t @@ -148,7 +151,7 @@ doctests: tr: '2.25' # type=float|default=0.0: use to specify TR in seconds (default is 1.00 sec), overrides dimension and sets it to tr imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/merge_callables.py b/nipype-auto-conv/specs/merge_callables.py index 1950a89..efab957 100644 --- a/nipype-auto-conv/specs/merge_callables.py +++ b/nipype-auto-conv/specs/merge_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in Merge.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Merge.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def merged_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["merged_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/min_image.yaml b/nipype-auto-conv/specs/min_image.yaml index 5f56747..d6c0721 100644 --- a/nipype-auto-conv/specs/min_image.yaml +++ b/nipype-auto-conv/specs/min_image.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -72,7 +78,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/min_image_callables.py b/nipype-auto-conv/specs/min_image_callables.py index be3a24b..9cde1b9 100644 --- a/nipype-auto-conv/specs/min_image_callables.py +++ b/nipype-auto-conv/specs/min_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MinImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MinImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/motion_outliers.yaml b/nipype-auto-conv/specs/motion_outliers.yaml index 7bcceac..cca7ee4 100644 --- a/nipype-auto-conv/specs/motion_outliers.yaml +++ b/nipype-auto-conv/specs/motion_outliers.yaml @@ -32,17 +32,20 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: unfiltered 4D image - out_file: generic/file - # type=file: - # type=file|default=: output outlier file name mask: generic/file # type=file|default=: mask image for calculating metric - out_metric_values: generic/file + out_file: Path # type=file: - # type=file|default=: output metric values (DVARS etc.) file name - out_metric_plot: generic/file + # type=file|default=: output outlier file name + out_metric_plot: Path # type=file: # type=file|default=: output metric values plot (DVARS etc.) file name + out_metric_values: Path + # type=file: + # type=file|default=: output metric values (DVARS etc.) file name + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -59,12 +62,12 @@ outputs: out_file: generic/file # type=file: # type=file|default=: output outlier file name - out_metric_values: generic/file - # type=file: - # type=file|default=: output metric values (DVARS etc.) file name out_metric_plot: generic/file # type=file: # type=file|default=: output metric values plot (DVARS etc.) file name + out_metric_values: generic/file + # type=file: + # type=file|default=: output metric values (DVARS etc.) file name callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -104,7 +107,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -124,7 +127,7 @@ tests: in_file: # type=file|default=: unfiltered 4D image imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -145,10 +148,10 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"epi.nii"' # type=file|default=: unfiltered 4D image imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/motion_outliers_callables.py b/nipype-auto-conv/specs/motion_outliers_callables.py index 811e819..09bc820 100644 --- a/nipype-auto-conv/specs/motion_outliers_callables.py +++ b/nipype-auto-conv/specs/motion_outliers_callables.py @@ -1 +1,352 @@ -"""Module to put any functions that are referred to in MotionOutliers.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MotionOutliers.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def out_metric_plot_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_metric_plot"] + + +def out_metric_values_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_metric_values"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/multi_image_maths.yaml b/nipype-auto-conv/specs/multi_image_maths.yaml index 1f4a890..72a24c1 100644 --- a/nipype-auto-conv/specs/multi_image_maths.yaml +++ b/nipype-auto-conv/specs/multi_image_maths.yaml @@ -33,10 +33,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - operand_files: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: list of file names to plug into op string in_file: medimage/nifti1 # type=file|default=: image to operate on + operand_files: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: list of file names to plug into op string + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -89,7 +95,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -116,7 +122,7 @@ tests: # type=file: image written after calculations # type=file|default=: image to write imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -137,17 +143,17 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii"' # type=file|default=: image to operate on op_string: '"-add %s -mul -1 -div %s"' # type=string|default='': python formatted string of operations to perform - operand_files: + operand_files: '["functional2.nii", "functional3.nii"]' # type=inputmultiobject|default=[]: list of file names to plug into op string out_file: '"functional4.nii"' # type=file: image written after calculations # type=file|default=: image to write imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/multi_image_maths_callables.py b/nipype-auto-conv/specs/multi_image_maths_callables.py index af619ea..9b5eedb 100644 --- a/nipype-auto-conv/specs/multi_image_maths_callables.py +++ b/nipype-auto-conv/specs/multi_image_maths_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in MultiImageMaths.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MultiImageMaths.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/multiple_regress_design.yaml b/nipype-auto-conv/specs/multiple_regress_design.yaml index 987f401..bd39d05 100644 --- a/nipype-auto-conv/specs/multiple_regress_design.yaml +++ b/nipype-auto-conv/specs/multiple_regress_design.yaml @@ -38,6 +38,9 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -51,14 +54,14 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - design_mat: generic/file - # type=file: design matrix file design_con: generic/file # type=file: design t-contrast file design_fts: generic/file # type=file: design f-contrast file design_grp: generic/file # type=file: design group file + design_mat: generic/file + # type=file: design matrix file callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -77,7 +80,7 @@ tests: groups: # type=list|default=[]: list of group identifiers (defaults to single group) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/multiple_regress_design_callables.py b/nipype-auto-conv/specs/multiple_regress_design_callables.py index d429231..a295709 100644 --- a/nipype-auto-conv/specs/multiple_regress_design_callables.py +++ b/nipype-auto-conv/specs/multiple_regress_design_callables.py @@ -1 +1,42 @@ -"""Module to put any functions that are referred to in MultipleRegressDesign.yaml""" +"""Module to put any functions that are referred to in the "callables" section of MultipleRegressDesign.yaml""" + +import os + + +def design_con_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_con"] + + +def design_fts_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_fts"] + + +def design_grp_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_grp"] + + +def design_mat_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["design_mat"] + + +# Original source at L1600 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + nfcons = sum([1 for con in inputs.contrasts if con[1] == "F"]) + for field in list(outputs.keys()): + if ("fts" in field) and (nfcons == 0): + continue + outputs[field] = os.path.join(output_dir, field.replace("_", ".")) + return outputs diff --git a/nipype-auto-conv/specs/overlay.yaml b/nipype-auto-conv/specs/overlay.yaml index 7a5ea42..155e80a 100644 --- a/nipype-auto-conv/specs/overlay.yaml +++ b/nipype-auto-conv/specs/overlay.yaml @@ -39,10 +39,16 @@ inputs: # passed to the field in the automatically generated unittests. background_image: generic/file # type=file|default=: image to use as background + out_file: Path + # type=file: combined image volume + # type=file|default=: combined image volume stat_image: generic/file # type=file|default=: statistical image to overlay in color stat_image2: generic/file # type=file|default=: second statistical image to overlay in color + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -107,7 +113,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/overlay_callables.py b/nipype-auto-conv/specs/overlay_callables.py index dc82668..a56187c 100644 --- a/nipype-auto-conv/specs/overlay_callables.py +++ b/nipype-auto-conv/specs/overlay_callables.py @@ -1 +1,339 @@ -"""Module to put any functions that are referred to in Overlay.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Overlay.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1098 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "overlay" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1080 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.out_file + if out_file is attrs.NOTHING: + if (inputs.stat_image2 is not attrs.NOTHING) and ( + (inputs.show_negative_stats is attrs.NOTHING) + or not inputs.show_negative_stats + ): + stem = "%s_and_%s" % ( + split_filename(inputs.stat_image)[1], + split_filename(inputs.stat_image2)[1], + ) + else: + stem = split_filename(inputs.stat_image)[1] + out_file = _gen_fname( + stem, + suffix="_overlay", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/percentile_image.yaml b/nipype-auto-conv/specs/percentile_image.yaml index fa52a47..01a5156 100644 --- a/nipype-auto-conv/specs/percentile_image.yaml +++ b/nipype-auto-conv/specs/percentile_image.yaml @@ -34,6 +34,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -86,7 +92,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -106,7 +112,7 @@ tests: in_file: # type=file|default=: image to operate on imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -127,10 +133,10 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii" # doctest: +SKIP' # type=file|default=: image to operate on imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/percentile_image_callables.py b/nipype-auto-conv/specs/percentile_image_callables.py index 3ab3b26..a86a925 100644 --- a/nipype-auto-conv/specs/percentile_image_callables.py +++ b/nipype-auto-conv/specs/percentile_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in PercentileImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of PercentileImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/plot_motion_params.yaml b/nipype-auto-conv/specs/plot_motion_params.yaml index 2accc6c..997f47b 100644 --- a/nipype-auto-conv/specs/plot_motion_params.yaml +++ b/nipype-auto-conv/specs/plot_motion_params.yaml @@ -45,6 +45,12 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_file: Path + # type=file: image to write + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -93,7 +99,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/plot_motion_params_callables.py b/nipype-auto-conv/specs/plot_motion_params_callables.py index cb9a47a..d632bf6 100644 --- a/nipype-auto-conv/specs/plot_motion_params_callables.py +++ b/nipype-auto-conv/specs/plot_motion_params_callables.py @@ -1 +1,135 @@ -"""Module to put any functions that are referred to in PlotMotionParams.yaml""" +"""Module to put any functions that are referred to in the "callables" section of PlotMotionParams.yaml""" + +import attrs +import os +import os.path as op +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +# Original source at L1495 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L1478 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.out_file + if out_file is attrs.NOTHING: + if isinstance(inputs.in_file, list): + infile = inputs.in_file[0] + else: + infile = inputs.in_file + plttype = dict(rot="rot", tra="trans", dis="disp")[inputs.plot_type[:3]] + out_file = fname_presuffix(infile, suffix="_%s.png" % plttype, use_ext=False) + outputs["out_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext diff --git a/nipype-auto-conv/specs/plot_time_series.yaml b/nipype-auto-conv/specs/plot_time_series.yaml index 20a0e1a..8d0c3cd 100644 --- a/nipype-auto-conv/specs/plot_time_series.yaml +++ b/nipype-auto-conv/specs/plot_time_series.yaml @@ -35,6 +35,12 @@ inputs: # passed to the field in the automatically generated unittests. legend_file: generic/file # type=file|default=: legend file + out_file: Path + # type=file: image to write + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -103,7 +109,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/plot_time_series_callables.py b/nipype-auto-conv/specs/plot_time_series_callables.py index a741da7..bd4ce1e 100644 --- a/nipype-auto-conv/specs/plot_time_series_callables.py +++ b/nipype-auto-conv/specs/plot_time_series_callables.py @@ -1 +1,333 @@ -"""Module to put any functions that are referred to in PlotTimeSeries.yaml""" +"""Module to put any functions that are referred to in the "callables" section of PlotTimeSeries.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1367 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fsl_tsplot" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1355 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.out_file + if out_file is attrs.NOTHING: + if isinstance(inputs.in_file, list): + infile = inputs.in_file[0] + else: + infile = inputs.in_file + out_file = _gen_fname( + infile, + ext=".png", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/power_spectrum.yaml b/nipype-auto-conv/specs/power_spectrum.yaml index b239a10..770bf1d 100644 --- a/nipype-auto-conv/specs/power_spectrum.yaml +++ b/nipype-auto-conv/specs/power_spectrum.yaml @@ -33,6 +33,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: input 4D file to estimate the power spectrum + out_file: Path + # type=file: path/name of the output 4D power spectrum file + # type=file|default=: name of output 4D file for power spectrum + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -75,7 +81,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/power_spectrum_callables.py b/nipype-auto-conv/specs/power_spectrum_callables.py index 9973085..126f6e6 100644 --- a/nipype-auto-conv/specs/power_spectrum_callables.py +++ b/nipype-auto-conv/specs/power_spectrum_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in PowerSpectrum.yaml""" +"""Module to put any functions that are referred to in the "callables" section of PowerSpectrum.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1700 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _gen_outfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslpspec" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1689 of /interfaces/fsl/utils.py +def _gen_outfilename(inputs=None, stdout=None, stderr=None, output_dir=None): + out_file = inputs.out_file + if (out_file is attrs.NOTHING) and (inputs.in_file is not attrs.NOTHING): + out_file = _gen_fname( + inputs.in_file, + suffix="_ps", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return out_file + + +# Original source at L1695 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = os.path.abspath( + _gen_outfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/prelude.yaml b/nipype-auto-conv/specs/prelude.yaml index 3ecd6fe..ac6a82c 100644 --- a/nipype-auto-conv/specs/prelude.yaml +++ b/nipype-auto-conv/specs/prelude.yaml @@ -29,18 +29,24 @@ inputs: # passed to the field in the automatically generated unittests. complex_phase_file: generic/file # type=file|default=: complex phase input volume + label_file: generic/file + # type=file|default=: saving the area labels output magnitude_file: generic/file # type=file|default=: file containing magnitude image - phase_file: generic/file - # type=file|default=: raw phase file mask_file: generic/file # type=file|default=: filename of mask input volume - savemask_file: generic/file - # type=file|default=: saving the mask volume + phase_file: generic/file + # type=file|default=: raw phase file rawphase_file: generic/file # type=file|default=: saving the raw phase output - label_file: generic/file - # type=file|default=: saving the area labels output + savemask_file: generic/file + # type=file|default=: saving the mask volume + unwrapped_phase_file: Path + # type=file: unwrapped phase file + # type=file|default=: file containing unwrapepd phase + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -111,7 +117,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/prelude_callables.py b/nipype-auto-conv/specs/prelude_callables.py index af11ab9..3104d4a 100644 --- a/nipype-auto-conv/specs/prelude_callables.py +++ b/nipype-auto-conv/specs/prelude_callables.py @@ -1 +1,339 @@ -"""Module to put any functions that are referred to in PRELUDE.yaml""" +"""Module to put any functions that are referred to in the "callables" section of PRELUDE.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def unwrapped_phase_file_default(inputs): + return _gen_filename("unwrapped_phase_file", inputs=inputs) + + +def unwrapped_phase_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["unwrapped_phase_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L2115 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "unwrapped_phase_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["unwrapped_phase_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "prelude" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L2102 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.unwrapped_phase_file + if out_file is attrs.NOTHING: + if inputs.phase_file is not attrs.NOTHING: + out_file = _gen_fname( + inputs.phase_file, + suffix="_unwrapped", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + elif inputs.complex_phase_file is not attrs.NOTHING: + out_file = _gen_fname( + inputs.complex_phase_file, + suffix="_phase_unwrapped", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["unwrapped_phase_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/prepare_fieldmap.yaml b/nipype-auto-conv/specs/prepare_fieldmap.yaml index 5c52c02..90a0e12 100644 --- a/nipype-auto-conv/specs/prepare_fieldmap.yaml +++ b/nipype-auto-conv/specs/prepare_fieldmap.yaml @@ -41,13 +41,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_phase: medimage/nifti1 - # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) in_magnitude: medimage/nifti1 # type=file|default=: Magnitude difference map, brain extracted - out_fieldmap: generic/file + in_phase: medimage/nifti1 + # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) + out_fieldmap: Path # type=file: output name for prepared fieldmap # type=file|default=: output name for prepared fieldmap + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -95,7 +98,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -119,7 +122,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -140,14 +143,14 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_phase: + in_phase: '"phase.nii"' # type=file|default=: Phase difference map, in SIEMENS format range from 0-4096 or 0-8192) - in_magnitude: + in_magnitude: '"magnitude.nii"' # type=file|default=: Magnitude difference map, brain extracted output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/prepare_fieldmap_callables.py b/nipype-auto-conv/specs/prepare_fieldmap_callables.py index 55273d7..9b4e146 100644 --- a/nipype-auto-conv/specs/prepare_fieldmap_callables.py +++ b/nipype-auto-conv/specs/prepare_fieldmap_callables.py @@ -1 +1,20 @@ -"""Module to put any functions that are referred to in PrepareFieldmap.yaml""" +"""Module to put any functions that are referred to in the "callables" section of PrepareFieldmap.yaml""" + + +def out_fieldmap_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_fieldmap"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L110 of /interfaces/fsl/epi.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_fieldmap"] = inputs.out_fieldmap + return outputs diff --git a/nipype-auto-conv/specs/prob_track_x.yaml b/nipype-auto-conv/specs/prob_track_x.yaml index 4e677d8..03071e9 100644 --- a/nipype-auto-conv/specs/prob_track_x.yaml +++ b/nipype-auto-conv/specs/prob_track_x.yaml @@ -30,32 +30,41 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + avoid_mp: generic/file + # type=file|default=: reject pathways passing through locations given by this mask + fsamples: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: + inv_xfm: generic/file + # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + mask: medimage/nifti1 + # type=file|default=: bet binary mask file in diffusion space mask2: generic/file # type=file|default=: second bet binary mask (in diffusion space) in twomask_symm mode mesh: generic/file # type=file|default=: Freesurfer-type surface descriptor (in ascii format) - thsamples: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: + out_dir: Path + # type=directory|default=: directory to put the final volumes in phsamples: medimage/nifti1+list-of # type=inputmultiobject|default=[]: - fsamples: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: - mask: medimage/nifti1 - # type=file|default=: bet binary mask file in diffusion space - target_masks: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification - waypoints: generic/file - # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks seed_ref: generic/file # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent - avoid_mp: generic/file - # type=file|default=: reject pathways passing through locations given by this mask stop_mask: generic/file # type=file|default=: stop tracking at locations given by this mask file + target_masks: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + thsamples: medimage/nifti1+list-of + # type=inputmultiobject|default=[]: + waypoints: generic/file + # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks xfm: datascience/text-matrix # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity - inv_xfm: generic/file - # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields + mode: mode_default + # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) + out_dir: out_dir_default + # type=directory|default=: directory to put the final volumes in metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -69,8 +78,14 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + fdt_paths: generic/file+list-of + # type=outputmultiobject: path/name of a 3D image file containing the output connectivity distribution to the seed mask log: generic/file # type=file: path/name of a text record of the command that was run + particle_files: generic/file+list-of + # type=list: Files describing all of the tract samples. Generated only if verbose is set to 2 + targets: generic/file+list-of + # type=list: a list with all generated seeds_to_target files way_total: generic/file # type=file: path/name of a text file containing a single number corresponding to the total number of generated tracts that have not been rejected by inclusion/exclusion mask criteria callables: @@ -78,10 +93,6 @@ outputs: # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields - mode: '"seedmask"' - # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) - out_dir: '"."' - # type=directory|default=: directory to put the final volumes in requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -167,7 +178,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -215,7 +226,7 @@ tests: out_dir: '"."' # type=directory|default=: directory to put the final volumes in imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -238,13 +249,13 @@ doctests: # '.mock()' method of the corresponding class is used instead. samples_base_name: '"merged"' # type=str|default='merged': the rootname/base_name for samples files - mask: + mask: '"mask.nii"' # type=file|default=: bet binary mask file in diffusion space seed: '"MASK_average_thal_right.nii"' # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file mode: '"seedmask"' # type=enum|default='simple'|allowed['seedmask','simple','two_mask_symm']: options: simple (single seed voxel), seedmask (mask of seed voxels), twomask_symm (two bet binary masks) - xfm: + xfm: '"trans.mat"' # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity n_samples: '3' # type=int|default=5000: number of samples - default=5000 @@ -256,18 +267,18 @@ doctests: # type=bool|default=True: outputs path distributions os2t: 'True' # type=bool|default=False: Outputs seeds to targets - target_masks: + target_masks: '["targets_MASK1.nii", "targets_MASK2.nii"]' # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification - thsamples: + thsamples: '"merged_thsamples.nii"' # type=inputmultiobject|default=[]: - fsamples: + fsamples: '"merged_fsamples.nii"' # type=inputmultiobject|default=[]: - phsamples: + phsamples: '"merged_phsamples.nii"' # type=inputmultiobject|default=[]: out_dir: '"."' # type=directory|default=: directory to put the final volumes in imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/prob_track_x2.yaml b/nipype-auto-conv/specs/prob_track_x2.yaml index 045fc23..5b8140d 100644 --- a/nipype-auto-conv/specs/prob_track_x2.yaml +++ b/nipype-auto-conv/specs/prob_track_x2.yaml @@ -37,40 +37,47 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + avoid_mp: generic/file + # type=file|default=: reject pathways passing through locations given by this mask + colmask4: generic/file + # type=file|default=: Mask for columns of matrix4 (default=seed mask) fopd: generic/file # type=file|default=: Other mask for binning tract distribution + fsamples: medimage/nifti-gz+list-of + # type=inputmultiobject|default=[]: + inv_xfm: generic/file + # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + lrtarget3: generic/file + # type=file|default=: Column-space mask used for Nxn connectivity matrix + mask: medimage/nifti-gz + # type=file|default=: bet binary mask file in diffusion space + out_dir: Path + # type=directory|default=: directory to put the final volumes in + phsamples: medimage/nifti-gz+list-of + # type=inputmultiobject|default=[]: + seed_ref: generic/file + # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent + stop_mask: generic/file + # type=file|default=: stop tracking at locations given by this mask file target2: generic/file # type=file|default=: Low resolution binary brain mask for storing connectivity distribution in matrix2 mode target3: generic/file # type=file|default=: Mask used for NxN connectivity matrix (or Nxn if lrtarget3 is set) - lrtarget3: generic/file - # type=file|default=: Column-space mask used for Nxn connectivity matrix - colmask4: generic/file - # type=file|default=: Mask for columns of matrix4 (default=seed mask) target4: generic/file # type=file|default=: Brain mask in DTI space - thsamples: medimage/nifti-gz+list-of - # type=inputmultiobject|default=[]: - phsamples: medimage/nifti-gz+list-of - # type=inputmultiobject|default=[]: - fsamples: medimage/nifti-gz+list-of - # type=inputmultiobject|default=[]: - mask: medimage/nifti-gz - # type=file|default=: bet binary mask file in diffusion space target_masks: generic/file+list-of # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification + thsamples: medimage/nifti-gz+list-of + # type=inputmultiobject|default=[]: waypoints: generic/file # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks - seed_ref: generic/file - # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent - avoid_mp: generic/file - # type=file|default=: reject pathways passing through locations given by this mask - stop_mask: generic/file - # type=file|default=: stop tracking at locations given by this mask file xfm: generic/file # type=file|default=: transformation matrix taking seed space to DTI space (either FLIRT matrix or FNIRT warp_field) - default is identity - inv_xfm: generic/file - # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields + out_dir: out_dir_default + # type=directory|default=: directory to put the final volumes in metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -84,18 +91,24 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - network_matrix: generic/file - # type=file: the network matrix generated by --omatrix1 option - matrix1_dot: generic/file - # type=file: Output matrix1.dot - SeedToSeed Connectivity + fdt_paths: generic/file+list-of + # type=outputmultiobject: path/name of a 3D image file containing the output connectivity distribution to the seed mask + log: generic/file + # type=file: path/name of a text record of the command that was run lookup_tractspace: generic/file # type=file: lookup_tractspace generated by --omatrix2 option + matrix1_dot: generic/file + # type=file: Output matrix1.dot - SeedToSeed Connectivity matrix2_dot: generic/file # type=file: Output matrix2.dot - SeedToLowResMask matrix3_dot: generic/file # type=file: Output matrix3 - NxN connectivity matrix - log: generic/file - # type=file: path/name of a text record of the command that was run + network_matrix: generic/file + # type=file: the network matrix generated by --omatrix1 option + particle_files: generic/file+list-of + # type=list: Files describing all of the tract samples. Generated only if verbose is set to 2 + targets: generic/file+list-of + # type=list: a list with all generated seeds_to_target files way_total: generic/file # type=file: path/name of a text file containing a single number corresponding to the total number of generated tracts that have not been rejected by inclusion/exclusion mask criteria callables: @@ -103,8 +116,6 @@ outputs: # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields - out_dir: '"."' - # type=directory|default=: directory to put the final volumes in requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -218,7 +229,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -252,7 +263,7 @@ tests: n_steps: '10' # type=int|default=0: number of steps per sample - default=2000 imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -275,13 +286,13 @@ doctests: # '.mock()' method of the corresponding class is used instead. seed: '"seed_source.nii.gz"' # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file - thsamples: + thsamples: '"merged_th1samples.nii.gz"' # type=inputmultiobject|default=[]: - fsamples: + fsamples: '"merged_f1samples.nii.gz"' # type=inputmultiobject|default=[]: - phsamples: + phsamples: '"merged_ph1samples.nii.gz"' # type=inputmultiobject|default=[]: - mask: + mask: '"nodif_brain_mask.nii.gz"' # type=file|default=: bet binary mask file in diffusion space out_dir: '"."' # type=directory|default=: directory to put the final volumes in @@ -290,7 +301,7 @@ doctests: n_steps: '10' # type=int|default=0: number of steps per sample - default=2000 imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/prob_track_x2_callables.py b/nipype-auto-conv/specs/prob_track_x2_callables.py index bf9e220..8d008b4 100644 --- a/nipype-auto-conv/specs/prob_track_x2_callables.py +++ b/nipype-auto-conv/specs/prob_track_x2_callables.py @@ -1 +1,485 @@ -"""Module to put any functions that are referred to in ProbTrackX2.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ProbTrackX2.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_dir_default(inputs): + return _gen_filename("out_dir", inputs=inputs) + + +def fdt_paths_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fdt_paths"] + + +def log_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["log"] + + +def lookup_tractspace_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["lookup_tractspace"] + + +def matrix1_dot_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["matrix1_dot"] + + +def matrix2_dot_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["matrix2_dot"] + + +def matrix3_dot_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["matrix3_dot"] + + +def network_matrix_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["network_matrix"] + + +def particle_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["particle_files"] + + +def targets_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["targets"] + + +def way_total_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["way_total"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L921 of /interfaces/fsl/dti.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_dir": + return output_dir + elif name == "mode": + if isinstance(inputs.seed, list) and isinstance(inputs.seed[0], list): + return "simple" + else: + return "seedmask" + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "probtrackx2" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1070 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = nipype_interfaces_fsl_dti__ProbTrackX___list_outputs() + + if inputs.out_dir is attrs.NOTHING: + out_dir = output_dir + else: + out_dir = inputs.out_dir + + outputs["way_total"] = os.path.abspath(os.path.join(out_dir, "waytotal")) + + if inputs.omatrix1 is not attrs.NOTHING: + outputs["network_matrix"] = os.path.abspath( + os.path.join(out_dir, "matrix_seeds_to_all_targets") + ) + outputs["matrix1_dot"] = os.path.abspath( + os.path.join(out_dir, "fdt_matrix1.dot") + ) + + if inputs.omatrix2 is not attrs.NOTHING: + outputs["lookup_tractspace"] = os.path.abspath( + os.path.join(out_dir, "lookup_tractspace_fdt_matrix2.nii.gz") + ) + outputs["matrix2_dot"] = os.path.abspath( + os.path.join(out_dir, "fdt_matrix2.dot") + ) + + if inputs.omatrix3 is not attrs.NOTHING: + outputs["matrix3_dot"] = os.path.abspath( + os.path.join(out_dir, "fdt_matrix3.dot") + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L871 of /interfaces/fsl/dti.py +def nipype_interfaces_fsl_dti__ProbTrackX___list_outputs( + inputs=None, stdout=None, stderr=None, output_dir=None +): + outputs = {} + if inputs.out_dir is attrs.NOTHING: + out_dir = _gen_filename( + "out_dir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + out_dir = inputs.out_dir + + outputs["log"] = os.path.abspath(os.path.join(out_dir, "probtrackx.log")) + # outputs['way_total'] = os.path.abspath(os.path.join(out_dir, + # 'waytotal')) + if inputs.opd is True is not attrs.NOTHING: + if isinstance(inputs.seed, list) and isinstance(inputs.seed[0], list): + outputs["fdt_paths"] = [] + for seed in inputs.seed: + outputs["fdt_paths"].append( + os.path.abspath( + _gen_fname( + ("fdt_paths_%s" % ("_".join([str(s) for s in seed]))), + cwd=out_dir, + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + ) + else: + outputs["fdt_paths"] = os.path.abspath( + _gen_fname( + "fdt_paths", + cwd=out_dir, + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + + # handle seeds-to-target output files + if inputs.target_masks is not attrs.NOTHING: + outputs["targets"] = [] + for target in inputs.target_masks: + outputs["targets"].append( + os.path.abspath( + _gen_fname( + "seeds_to_" + os.path.split(target)[1], + cwd=out_dir, + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + ) + if (inputs.verbose is not attrs.NOTHING) and inputs.verbose == 2: + outputs["particle_files"] = [ + os.path.abspath(os.path.join(out_dir, "particle%d" % i)) + for i in range(inputs.n_samples) + ] + return outputs + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/prob_track_x_callables.py b/nipype-auto-conv/specs/prob_track_x_callables.py index 9bac868..7c8c61f 100644 --- a/nipype-auto-conv/specs/prob_track_x_callables.py +++ b/nipype-auto-conv/specs/prob_track_x_callables.py @@ -1 +1,418 @@ -"""Module to put any functions that are referred to in ProbTrackX.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ProbTrackX.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def mode_default(inputs): + return _gen_filename("mode", inputs=inputs) + + +def out_dir_default(inputs): + return _gen_filename("out_dir", inputs=inputs) + + +def fdt_paths_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fdt_paths"] + + +def log_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["log"] + + +def particle_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["particle_files"] + + +def targets_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["targets"] + + +def way_total_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["way_total"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L921 of /interfaces/fsl/dti.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_dir": + return output_dir + elif name == "mode": + if isinstance(inputs.seed, list) and isinstance(inputs.seed[0], list): + return "simple" + else: + return "seedmask" + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "probtrackx" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L871 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.out_dir is attrs.NOTHING: + out_dir = _gen_filename( + "out_dir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + out_dir = inputs.out_dir + + outputs["log"] = os.path.abspath(os.path.join(out_dir, "probtrackx.log")) + # outputs['way_total'] = os.path.abspath(os.path.join(out_dir, + # 'waytotal')) + if inputs.opd is True is not attrs.NOTHING: + if isinstance(inputs.seed, list) and isinstance(inputs.seed[0], list): + outputs["fdt_paths"] = [] + for seed in inputs.seed: + outputs["fdt_paths"].append( + os.path.abspath( + _gen_fname( + ("fdt_paths_%s" % ("_".join([str(s) for s in seed]))), + cwd=out_dir, + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + ) + else: + outputs["fdt_paths"] = os.path.abspath( + _gen_fname( + "fdt_paths", + cwd=out_dir, + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + + # handle seeds-to-target output files + if inputs.target_masks is not attrs.NOTHING: + outputs["targets"] = [] + for target in inputs.target_masks: + outputs["targets"].append( + os.path.abspath( + _gen_fname( + "seeds_to_" + os.path.split(target)[1], + cwd=out_dir, + suffix="", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + ) + if (inputs.verbose is not attrs.NOTHING) and inputs.verbose == 2: + outputs["particle_files"] = [ + os.path.abspath(os.path.join(out_dir, "particle%d" % i)) + for i in range(inputs.n_samples) + ] + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/proj_thresh.yaml b/nipype-auto-conv/specs/proj_thresh.yaml index 93fecf8..5ad5502 100644 --- a/nipype-auto-conv/specs/proj_thresh.yaml +++ b/nipype-auto-conv/specs/proj_thresh.yaml @@ -35,6 +35,9 @@ inputs: # passed to the field in the automatically generated unittests. in_files: generic/file+list-of # type=list|default=[]: a list of input volumes + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -48,6 +51,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_files: generic/file+list-of + # type=list: path/name of output volume after thresholding callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -70,7 +75,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -92,7 +97,7 @@ tests: threshold: '3' # type=int|default=0: threshold indicating minimum number of seed voxels entering this mask region imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -113,12 +118,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_files: + in_files: ldir # type=list|default=[]: a list of input volumes threshold: '3' # type=int|default=0: threshold indicating minimum number of seed voxels entering this mask region imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/proj_thresh_callables.py b/nipype-auto-conv/specs/proj_thresh_callables.py index 3089925..40ea989 100644 --- a/nipype-auto-conv/specs/proj_thresh_callables.py +++ b/nipype-auto-conv/specs/proj_thresh_callables.py @@ -1 +1,323 @@ -"""Module to put any functions that are referred to in ProjThresh.yaml""" +"""Module to put any functions that are referred to in the "callables" section of ProjThresh.yaml""" + +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_files"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "proj_thresh" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1268 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_files"] = [] + for name in inputs.in_files: + cwd, base_name = os.path.split(name) + outputs["out_files"].append( + _gen_fname( + base_name, + cwd=cwd, + suffix="_proj_seg_thr_{}".format(inputs.threshold), + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/randomise.yaml b/nipype-auto-conv/specs/randomise.yaml index 8467d35..6b7ee93 100644 --- a/nipype-auto-conv/specs/randomise.yaml +++ b/nipype-auto-conv/specs/randomise.yaml @@ -31,18 +31,21 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: medimage/nifti1 - # type=file|default=: 4D input file design_mat: datascience/text-matrix # type=file|default=: design matrix file - tcon: medimage-fsl/con - # type=file|default=: t contrasts file fcon: generic/file # type=file|default=: f contrasts file + in_file: medimage/nifti1 + # type=file|default=: 4D input file mask: medimage/nifti1 # type=file|default=: mask image + tcon: medimage-fsl/con + # type=file|default=: t contrasts file x_block_labels: generic/file # type=file|default=: exchangeability block labels file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -56,6 +59,18 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + f_corrected_p_files: generic/file+list-of + # type=list: f contrast FWE (Family-wise error) corrected p values files + f_p_files: generic/file+list-of + # type=list: f contrast uncorrected p values files + fstat_files: generic/file+list-of + # type=list: f contrast raw statistic + t_corrected_p_files: generic/file+list-of + # type=list: t contrast FWE (Family-wise error) corrected p values files + t_p_files: generic/file+list-of + # type=list: f contrast uncorrected p values files + tstat_files: generic/file+list-of + # type=list: t contrast raw statistic callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -128,7 +143,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -154,7 +169,7 @@ tests: design_mat: # type=file|default=: design matrix file imports: &id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys - module: nipype.interfaces.fsl as fsl expected_outputs: @@ -176,16 +191,16 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"allFA.nii"' # type=file|default=: 4D input file - mask: + mask: '"mask.nii"' # type=file|default=: mask image - tcon: + tcon: '"design.con"' # type=file|default=: t contrasts file - design_mat: + design_mat: '"design.mat"' # type=file|default=: design matrix file imports: *id001 - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/randomise_callables.py b/nipype-auto-conv/specs/randomise_callables.py index 3f63d05..635bd2c 100644 --- a/nipype-auto-conv/specs/randomise_callables.py +++ b/nipype-auto-conv/specs/randomise_callables.py @@ -1 +1,409 @@ -"""Module to put any functions that are referred to in Randomise.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Randomise.yaml""" + +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def f_corrected_p_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["f_corrected_p_files"] + + +def f_p_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["f_p_files"] + + +def fstat_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fstat_files"] + + +def t_corrected_p_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["t_corrected_p_files"] + + +def t_p_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["t_p_files"] + + +def tstat_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["tstat_files"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "randomise" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L2322 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["tstat_files"] = glob( + _gen_fname( + "%s_tstat*.nii" % inputs.base_name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["fstat_files"] = glob( + _gen_fname( + "%s_fstat*.nii" % inputs.base_name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + prefix = False + if inputs.tfce or inputs.tfce2D: + prefix = "tfce" + elif inputs.vox_p_values: + prefix = "vox" + elif inputs.c_thresh or inputs.f_c_thresh: + prefix = "clustere" + elif inputs.cm_thresh or inputs.f_cm_thresh: + prefix = "clusterm" + if prefix: + outputs["t_p_files"] = glob( + _gen_fname( + "%s_%s_p_tstat*" % (inputs.base_name, prefix), + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["t_corrected_p_files"] = glob( + _gen_fname( + "%s_%s_corrp_tstat*.nii" % (inputs.base_name, prefix), + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + + outputs["f_p_files"] = glob( + _gen_fname( + "%s_%s_p_fstat*.nii" % (inputs.base_name, prefix), + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["f_corrected_p_files"] = glob( + _gen_fname( + "%s_%s_corrp_fstat*.nii" % (inputs.base_name, prefix), + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/reorient_2_std.yaml b/nipype-auto-conv/specs/reorient_2_std.yaml index 3e813d1..17ce6e8 100644 --- a/nipype-auto-conv/specs/reorient_2_std.yaml +++ b/nipype-auto-conv/specs/reorient_2_std.yaml @@ -34,6 +34,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: + out_file: Path + # type=file: + # type=file|default=: + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -76,7 +82,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/reorient_2_std_callables.py b/nipype-auto-conv/specs/reorient_2_std_callables.py index 7e424ba..dcfa528 100644 --- a/nipype-auto-conv/specs/reorient_2_std_callables.py +++ b/nipype-auto-conv/specs/reorient_2_std_callables.py @@ -1 +1,333 @@ -"""Module to put any functions that are referred to in Reorient2Std.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Reorient2Std.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1784 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _gen_fname( + inputs.in_file, + suffix="_reoriented", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslreorient2std" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1789 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_filename( + "out_file", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + else: + outputs["out_file"] = os.path.abspath(inputs.out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/robust_fov.yaml b/nipype-auto-conv/specs/robust_fov.yaml index 945b91d..151fb65 100644 --- a/nipype-auto-conv/specs/robust_fov.yaml +++ b/nipype-auto-conv/specs/robust_fov.yaml @@ -26,12 +26,15 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: input filename - out_roi: generic/file + out_roi: Path # type=file: ROI volume output name # type=file|default=: ROI volume output name - out_transform: generic/file + out_transform: Path # type=file: Transformation matrix in_file to out_roi output name # type=file|default=: Transformation matrix in_file to out_roi output name + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -79,7 +82,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/robust_fov_callables.py b/nipype-auto-conv/specs/robust_fov_callables.py index 4b540c7..f9cce33 100644 --- a/nipype-auto-conv/specs/robust_fov_callables.py +++ b/nipype-auto-conv/specs/robust_fov_callables.py @@ -1 +1,345 @@ -"""Module to put any functions that are referred to in RobustFOV.yaml""" +"""Module to put any functions that are referred to in the "callables" section of RobustFOV.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_roi_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_roi"] + + +def out_transform_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_transform"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/sig_loss.yaml b/nipype-auto-conv/specs/sig_loss.yaml index 47be512..67dcec9 100644 --- a/nipype-auto-conv/specs/sig_loss.yaml +++ b/nipype-auto-conv/specs/sig_loss.yaml @@ -35,6 +35,12 @@ inputs: # type=file|default=: b0 fieldmap file mask_file: generic/file # type=file|default=: brain mask file + out_file: Path + # type=file: signal loss estimate file + # type=file|default=: output signal loss estimate file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -83,7 +89,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/sig_loss_callables.py b/nipype-auto-conv/specs/sig_loss_callables.py index 05400d7..18d0a40 100644 --- a/nipype-auto-conv/specs/sig_loss_callables.py +++ b/nipype-auto-conv/specs/sig_loss_callables.py @@ -1 +1,328 @@ -"""Module to put any functions that are referred to in SigLoss.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SigLoss.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1750 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "sigloss" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1741 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if (outputs["out_file"] is attrs.NOTHING) and (inputs.in_file is not attrs.NOTHING): + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix="_sigloss", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/slice.yaml b/nipype-auto-conv/specs/slice.yaml index fe6ac07..92408dd 100644 --- a/nipype-auto-conv/specs/slice.yaml +++ b/nipype-auto-conv/specs/slice.yaml @@ -36,6 +36,9 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: input filename + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -49,6 +52,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_files: generic/file+list-of + # type=outputmultiobject: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -71,7 +76,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -93,7 +98,7 @@ tests: out_base_name: '"sl"' # type=str|default='': outputs prefix imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -114,12 +119,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"functional.nii"' # type=file|default=: input filename out_base_name: '"sl"' # type=str|default='': outputs prefix imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/slice_callables.py b/nipype-auto-conv/specs/slice_callables.py index d53846e..d6fc97a 100644 --- a/nipype-auto-conv/specs/slice_callables.py +++ b/nipype-auto-conv/specs/slice_callables.py @@ -1 +1,278 @@ -"""Module to put any functions that are referred to in Slice.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Slice.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_files"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L305 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + """Create a Bunch which contains all possible files generated + by running the interface. Some files are always generated, others + depending on which ``inputs`` options are set. + + Returns + ------- + + outputs : Bunch object + Bunch object containing all possible files generated by + interface object. + + If None, file was not generated + Else, contains path, filename of generated outputfile + + """ + outputs = {} + ext = Info.output_type_to_ext(inputs.output_type) + suffix = "_slice_*" + ext + if inputs.out_base_name is not attrs.NOTHING: + fname_template = os.path.abspath(inputs.out_base_name + suffix) + else: + fname_template = fname_presuffix(inputs.in_file, suffix=suffix, use_ext=False) + + outputs["out_files"] = sorted(glob(fname_template)) + + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/slice_timer.yaml b/nipype-auto-conv/specs/slice_timer.yaml index 8fb5e06..dff7e08 100644 --- a/nipype-auto-conv/specs/slice_timer.yaml +++ b/nipype-auto-conv/specs/slice_timer.yaml @@ -31,12 +31,19 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: filename of input timeseries - custom_timings: generic/file - # type=file|default=: slice timings, in fractions of TR, range 0:1 (default is 0.5 = no shift) custom_order: generic/file # type=file|default=: filename of single-column custom interleave order file (first slice is referred to as 1 not 0) + custom_timings: generic/file + # type=file|default=: slice timings, in fractions of TR, range 0:1 (default is 0.5 = no shift) + in_file: generic/file + # type=file|default=: filename of input timeseries + out_file: Path + # type=file|default=: filename of output timeseries + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields + out_file: out_file_default + # type=file|default=: filename of output timeseries metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -57,8 +64,6 @@ outputs: # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields - out_file: out_file - # type=file|default=: filename of output timeseries requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -90,7 +95,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/slice_timer_callables.py b/nipype-auto-conv/specs/slice_timer_callables.py index ecae156..4e3d44c 100644 --- a/nipype-auto-conv/specs/slice_timer_callables.py +++ b/nipype-auto-conv/specs/slice_timer_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in SliceTimer.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SliceTimer.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def slice_time_corrected_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["slice_time_corrected_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1578 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["slice_time_corrected_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "slicetimer" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1570 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.out_file + if out_file is attrs.NOTHING: + out_file = _gen_fname( + inputs.in_file, + suffix="_st", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["slice_time_corrected_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/slicer.yaml b/nipype-auto-conv/specs/slicer.yaml index 866a1f4..da04f77 100644 --- a/nipype-auto-conv/specs/slicer.yaml +++ b/nipype-auto-conv/specs/slicer.yaml @@ -35,12 +35,18 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: input volume - image_edges: generic/file - # type=file|default=: volume to display edge overlay for (useful for checking registration colour_map: generic/file # type=file|default=: use different colour map from that stored in nifti header + image_edges: generic/file + # type=file|default=: volume to display edge overlay for (useful for checking registration + in_file: generic/file + # type=file|default=: input volume + out_file: Path + # type=file: picture to write + # type=file|default=: picture to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -113,7 +119,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/slicer_callables.py b/nipype-auto-conv/specs/slicer_callables.py index 88b4316..f7ee3c2 100644 --- a/nipype-auto-conv/specs/slicer_callables.py +++ b/nipype-auto-conv/specs/slicer_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in Slicer.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Slicer.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1246 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "slicer" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1238 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.out_file + if out_file is attrs.NOTHING: + out_file = _gen_fname( + inputs.in_file, + ext=".png", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/smm.yaml b/nipype-auto-conv/specs/smm.yaml index 1f19c69..04aad0b 100644 --- a/nipype-auto-conv/specs/smm.yaml +++ b/nipype-auto-conv/specs/smm.yaml @@ -25,10 +25,13 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - spatial_data_file: generic/file - # type=file|default=: statistics spatial map mask: generic/file # type=file|default=: mask file + spatial_data_file: generic/file + # type=file|default=: statistics spatial map + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -42,11 +45,12 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - _p_map: generic/file activation_p_map: generic/file # type=file: deactivation_p_map: generic/file # type=file: + null_p_map: generic/file + # type=file: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -71,7 +75,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/smm_callables.py b/nipype-auto-conv/specs/smm_callables.py index a6c2729..c3df01d 100644 --- a/nipype-auto-conv/specs/smm_callables.py +++ b/nipype-auto-conv/specs/smm_callables.py @@ -1 +1,352 @@ -"""Module to put any functions that are referred to in SMM.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SMM.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def activation_p_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["activation_p_map"] + + +def deactivation_p_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["deactivation_p_map"] + + +def null_p_map_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["null_p_map"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "mm --ld=logdir" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1650 of /interfaces/fsl/model.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + # TODO get the true logdir from the stdout + outputs["null_p_map"] = _gen_fname( + basename="w1_mean", + cwd="logdir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["activation_p_map"] = _gen_fname( + basename="w2_mean", + cwd="logdir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if ( + inputs.no_deactivation_class is attrs.NOTHING + ) or not inputs.no_deactivation_class: + outputs["deactivation_p_map"] = _gen_fname( + basename="w3_mean", + cwd="logdir", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/smooth.yaml b/nipype-auto-conv/specs/smooth.yaml index 3a6a29d..fd618db 100644 --- a/nipype-auto-conv/specs/smooth.yaml +++ b/nipype-auto-conv/specs/smooth.yaml @@ -57,9 +57,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: - smoothed_file: generic/file + smoothed_file: Path # type=file: # type=file|default=: + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -103,7 +106,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -127,7 +130,7 @@ tests: sigma: '8.0' # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -151,7 +154,7 @@ tests: fwhm: '8.0' # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -173,7 +176,7 @@ tests: in_file: # type=file|default=: imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -196,12 +199,12 @@ doctests: # '.mock()' method of the corresponding class is used instead. output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - in_file: + in_file: '"functional2.nii"' # type=file|default=: sigma: '8.0' # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS @@ -213,12 +216,12 @@ doctests: # '.mock()' method of the corresponding class is used instead. output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - in_file: + in_file: '"functional2.nii"' # type=file|default=: fwhm: '8.0' # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS @@ -230,10 +233,10 @@ doctests: # '.mock()' method of the corresponding class is used instead. output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - in_file: + in_file: '"functional2.nii"' # type=file|default=: imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/smooth_callables.py b/nipype-auto-conv/specs/smooth_callables.py index 5dbe8c1..6854c24 100644 --- a/nipype-auto-conv/specs/smooth_callables.py +++ b/nipype-auto-conv/specs/smooth_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in Smooth.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Smooth.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def smoothed_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["smoothed_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/smooth_estimate.yaml b/nipype-auto-conv/specs/smooth_estimate.yaml index 26412a1..fdea86a 100644 --- a/nipype-auto-conv/specs/smooth_estimate.yaml +++ b/nipype-auto-conv/specs/smooth_estimate.yaml @@ -37,6 +37,9 @@ inputs: # type=file|default=: residual-fit image file zstat_file: medimage/nifti-gz # type=file|default=: zstat image file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -53,6 +56,12 @@ outputs: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields + dlh: dlh_callable + # type=float: smoothness estimate sqrt(det(Lambda)) + resels: resels_callable + # type=float: volume of resel, in voxels, defined as FWHM_x * FWHM_y * FWHM_z + volume: volume_callable + # type=int: number of voxels in mask templates: # dict[str, str] - `output_file_template` values to be provided to output fields requirements: @@ -76,7 +85,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -98,7 +107,7 @@ tests: mask_file: # type=file|default=: brain mask volume imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -119,12 +128,12 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - zstat_file: + zstat_file: '"zstat1.nii.gz"' # type=file|default=: zstat image file - mask_file: + mask_file: '"mask.nii"' # type=file|default=: brain mask volume imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/smooth_estimate_callables.py b/nipype-auto-conv/specs/smooth_estimate_callables.py index bac9d45..967d160 100644 --- a/nipype-auto-conv/specs/smooth_estimate_callables.py +++ b/nipype-auto-conv/specs/smooth_estimate_callables.py @@ -1 +1,352 @@ -"""Module to put any functions that are referred to in SmoothEstimate.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SmoothEstimate.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def dlh_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dlh"] + + +def resels_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["resels"] + + +def volume_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["volume"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/spatial_filter.yaml b/nipype-auto-conv/specs/spatial_filter.yaml index 3e0ad22..2f09a21 100644 --- a/nipype-auto-conv/specs/spatial_filter.yaml +++ b/nipype-auto-conv/specs/spatial_filter.yaml @@ -20,10 +20,16 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - kernel_file: generic/file - # type=file|default=: use external file for kernel in_file: generic/file # type=file|default=: image to operate on + kernel_file: generic/file + # type=file|default=: use external file for kernel + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -80,7 +86,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/spatial_filter_callables.py b/nipype-auto-conv/specs/spatial_filter_callables.py index 3a39375..8799501 100644 --- a/nipype-auto-conv/specs/spatial_filter_callables.py +++ b/nipype-auto-conv/specs/spatial_filter_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in SpatialFilter.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SpatialFilter.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/split.yaml b/nipype-auto-conv/specs/split.yaml index 37fbd92..afa9aea 100644 --- a/nipype-auto-conv/specs/split.yaml +++ b/nipype-auto-conv/specs/split.yaml @@ -24,6 +24,9 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: input filename + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -37,6 +40,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + out_files: generic/file+list-of + # type=outputmultiobject: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -61,7 +66,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/split_callables.py b/nipype-auto-conv/specs/split_callables.py index bdbf3d7..28b9397 100644 --- a/nipype-auto-conv/specs/split_callables.py +++ b/nipype-auto-conv/specs/split_callables.py @@ -1 +1,178 @@ -"""Module to put any functions that are referred to in Split.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Split.yaml""" + +import attrs +import logging +import os +from glob import glob + + +def out_files_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_files"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L549 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + """Create a Bunch which contains all possible files generated + by running the interface. Some files are always generated, others + depending on which ``inputs`` options are set. + + Returns + ------- + + outputs : Bunch object + Bunch object containing all possible files generated by + interface object. + + If None, file was not generated + Else, contains path, filename of generated outputfile + + """ + outputs = {} + ext = Info.output_type_to_ext(inputs.output_type) + outbase = "vol[0-9]*" + if inputs.out_base_name is not attrs.NOTHING: + outbase = "%s[0-9]*" % inputs.out_base_name + outputs["out_files"] = sorted(glob(os.path.join(output_dir, outbase + ext))) + return outputs + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/std_image.yaml b/nipype-auto-conv/specs/std_image.yaml index f4fabba..7e77e98 100644 --- a/nipype-auto-conv/specs/std_image.yaml +++ b/nipype-auto-conv/specs/std_image.yaml @@ -24,6 +24,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -74,7 +80,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/std_image_callables.py b/nipype-auto-conv/specs/std_image_callables.py index 4670a79..d9e0072 100644 --- a/nipype-auto-conv/specs/std_image_callables.py +++ b/nipype-auto-conv/specs/std_image_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in StdImage.yaml""" +"""Module to put any functions that are referred to in the "callables" section of StdImage.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/susan.yaml b/nipype-auto-conv/specs/susan.yaml index 32474f2..527da30 100644 --- a/nipype-auto-conv/specs/susan.yaml +++ b/nipype-auto-conv/specs/susan.yaml @@ -39,6 +39,13 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: filename of input timeseries + out_file: Path + # type=file|default=: output file name + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields + out_file: out_file_default + # type=file|default=: output file name metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -59,8 +66,6 @@ outputs: # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields - out_file: out_file - # type=file|default=: output file name requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -88,7 +93,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/susan_callables.py b/nipype-auto-conv/specs/susan_callables.py index 505eade..859ed75 100644 --- a/nipype-auto-conv/specs/susan_callables.py +++ b/nipype-auto-conv/specs/susan_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in SUSAN.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SUSAN.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def smoothed_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["smoothed_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1694 of /interfaces/fsl/preprocess.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["smoothed_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "susan" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1686 of /interfaces/fsl/preprocess.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + out_file = inputs.out_file + if out_file is attrs.NOTHING: + out_file = _gen_fname( + inputs.in_file, + suffix="_smooth", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["smoothed_file"] = os.path.abspath(out_file) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/swap_dimensions.yaml b/nipype-auto-conv/specs/swap_dimensions.yaml index cae1420..f0be367 100644 --- a/nipype-auto-conv/specs/swap_dimensions.yaml +++ b/nipype-auto-conv/specs/swap_dimensions.yaml @@ -29,6 +29,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: input image + out_file: Path + # type=file: image with new dimensions + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -73,7 +79,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/swap_dimensions_callables.py b/nipype-auto-conv/specs/swap_dimensions_callables.py index 74ec8ec..055aff1 100644 --- a/nipype-auto-conv/specs/swap_dimensions_callables.py +++ b/nipype-auto-conv/specs/swap_dimensions_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in SwapDimensions.yaml""" +"""Module to put any functions that are referred to in the "callables" section of SwapDimensions.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1642 of /interfaces/fsl/utils.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslswapdim" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1632 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix="_newdims", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/temporal_filter.yaml b/nipype-auto-conv/specs/temporal_filter.yaml index a9f713c..0534a5b 100644 --- a/nipype-auto-conv/specs/temporal_filter.yaml +++ b/nipype-auto-conv/specs/temporal_filter.yaml @@ -25,6 +25,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -77,7 +83,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/temporal_filter_callables.py b/nipype-auto-conv/specs/temporal_filter_callables.py index 3ec888f..8da590f 100644 --- a/nipype-auto-conv/specs/temporal_filter_callables.py +++ b/nipype-auto-conv/specs/temporal_filter_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in TemporalFilter.yaml""" +"""Module to put any functions that are referred to in the "callables" section of TemporalFilter.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/text_2_vest.yaml b/nipype-auto-conv/specs/text_2_vest.yaml index 6dab282..0507307 100644 --- a/nipype-auto-conv/specs/text_2_vest.yaml +++ b/nipype-auto-conv/specs/text_2_vest.yaml @@ -35,9 +35,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: text/text-file # type=file|default=: plain text file representing your design, contrast, or f-test matrix - out_file: datascience/text-matrix + out_file: Path # type=file: matrix data in the format used by FSL tools # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -77,7 +80,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -96,11 +99,11 @@ tests: # (if not specified, will try to choose a sensible value) in_file: # type=file|default=: plain text file representing your design, contrast, or f-test matrix - out_file: + out_file: '"design.mat"' # type=file: matrix data in the format used by FSL tools # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -121,13 +124,13 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"design.txt"' # type=file|default=: plain text file representing your design, contrast, or f-test matrix - out_file: + out_file: '"design.mat"' # type=file: matrix data in the format used by FSL tools # type=file|default=: file name to store matrix data in the format used by FSL tools (e.g., design.mat, design.con design.fts) imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/text_2_vest_callables.py b/nipype-auto-conv/specs/text_2_vest_callables.py index 1fdad81..f8c73e2 100644 --- a/nipype-auto-conv/specs/text_2_vest_callables.py +++ b/nipype-auto-conv/specs/text_2_vest_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in Text2Vest.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Text2Vest.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/threshold.yaml b/nipype-auto-conv/specs/threshold.yaml index 7dcb37d..a9c7d62 100644 --- a/nipype-auto-conv/specs/threshold.yaml +++ b/nipype-auto-conv/specs/threshold.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -78,7 +84,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/threshold_callables.py b/nipype-auto-conv/specs/threshold_callables.py index a542f78..5f6a848 100644 --- a/nipype-auto-conv/specs/threshold_callables.py +++ b/nipype-auto-conv/specs/threshold_callables.py @@ -1 +1,329 @@ -"""Module to put any functions that are referred to in Threshold.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Threshold.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L51 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/topup.yaml b/nipype-auto-conv/specs/topup.yaml index bfb37c4..128a753 100644 --- a/nipype-auto-conv/specs/topup.yaml +++ b/nipype-auto-conv/specs/topup.yaml @@ -41,21 +41,24 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: medimage/nifti1 - # type=file|default=: name of 4D file with images encoding_file: text/text-file # type=file|default=: name of text file with PE directions/times - out_base: generic/file + in_file: medimage/nifti1 + # type=file|default=: name of 4D file with images + out_base: Path # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) - out_field: generic/file - # type=file: name of image file with field (Hz) - # type=file|default=: name of image file with field (Hz) - out_corrected: generic/file + out_corrected: Path # type=file: name of 4D image file with unwarped images # type=file|default=: name of 4D image file with unwarped images - out_logfile: generic/file + out_field: Path + # type=file: name of image file with field (Hz) + # type=file|default=: name of image file with field (Hz) + out_logfile: Path # type=file: name of log-file # type=file|default=: name of log-file + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -69,21 +72,27 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - out_fieldcoef: generic/file - # type=file: file containing the field coefficients - out_movpar: generic/file - # type=file: movpar.txt output file + out_corrected: generic/file + # type=file: name of 4D image file with unwarped images + # type=file|default=: name of 4D image file with unwarped images out_enc_file: generic/file # type=file: encoding directions file output for applytopup out_field: generic/file # type=file: name of image file with field (Hz) # type=file|default=: name of image file with field (Hz) - out_corrected: generic/file - # type=file: name of 4D image file with unwarped images - # type=file|default=: name of 4D image file with unwarped images + out_fieldcoef: generic/file + # type=file: file containing the field coefficients + out_jacs: generic/file+list-of + # type=list: Jacobian images out_logfile: generic/file # type=file: name of log-file # type=file|default=: name of log-file + out_mats: generic/file+list-of + # type=list: realignment matrices + out_movpar: generic/file + # type=file: movpar.txt output file + out_warps: generic/file+list-of + # type=list: warpfield images callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -157,7 +166,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -181,7 +190,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -202,14 +211,14 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"b0_b0rev.nii"' # type=file|default=: name of 4D file with images - encoding_file: + encoding_file: '"topup_encoding.txt"' # type=file|default=: name of text file with PE directions/times output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/topup_callables.py b/nipype-auto-conv/specs/topup_callables.py index 3069076..93a2073 100644 --- a/nipype-auto-conv/specs/topup_callables.py +++ b/nipype-auto-conv/specs/topup_callables.py @@ -1 +1,565 @@ -"""Module to put any functions that are referred to in TOPUP.yaml""" +"""Module to put any functions that are referred to in the "callables" section of TOPUP.yaml""" + +import attrs +import logging +import nibabel as nb +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_corrected_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_corrected"] + + +def out_enc_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_enc_file"] + + +def out_field_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_field"] + + +def out_fieldcoef_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_fieldcoef"] + + +def out_jacs_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_jacs"] + + +def out_logfile_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_logfile"] + + +def out_mats_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_mats"] + + +def out_movpar_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_movpar"] + + +def out_warps_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_warps"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = nipype_interfaces_fsl__FSLCommand___overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "topup" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L398 of /interfaces/fsl/epi.py +def _get_encfilename(inputs=None, stdout=None, stderr=None, output_dir=None): + out_file = os.path.join( + output_dir, ("%s_encfile.txt" % split_filename(inputs.in_file)[1]) + ) + return out_file + + +# Original source at L361 of /interfaces/fsl/epi.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = nipype_interfaces_fsl__FSLCommand___list_outputs() + del outputs["out_base"] + base_path = None + if inputs.out_base is not attrs.NOTHING: + base_path, base, _ = split_filename(inputs.out_base) + if base_path == "": + base_path = None + else: + base = split_filename(inputs.in_file)[1] + "_base" + outputs["out_fieldcoef"] = _gen_fname( + base, + suffix="_fieldcoef", + cwd=base_path, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_movpar"] = _gen_fname( + base, + suffix="_movpar", + ext=".txt", + cwd=base_path, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + n_vols = nb.load(inputs.in_file).shape[-1] + ext = Info.output_type_to_ext(inputs.output_type) + fmt = os.path.abspath("{prefix}_{i:02d}{ext}").format + outputs["out_warps"] = [ + fmt(prefix=inputs.out_warp_prefix, i=i, ext=ext) for i in range(1, n_vols + 1) + ] + outputs["out_jacs"] = [ + fmt(prefix=inputs.out_jac_prefix, i=i, ext=ext) for i in range(1, n_vols + 1) + ] + outputs["out_mats"] = [ + fmt(prefix=inputs.out_mat_prefix, i=i, ext=".mat") for i in range(1, n_vols + 1) + ] + + if inputs.encoding_direction is not attrs.NOTHING: + outputs["out_enc_file"] = _get_encfilename( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + return outputs + + +# Original source at L430 of /interfaces/fsl/epi.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if name == "out_base": + return value + return nipype_interfaces_fsl__FSLCommand___overload_extension(value, name) + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L891 of /interfaces/base/core.py +def nipype_interfaces_fsl__FSLCommand___list_outputs( + inputs=None, stdout=None, stderr=None, output_dir=None +): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def nipype_interfaces_fsl__FSLCommand___overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/tract_skeleton.yaml b/nipype-auto-conv/specs/tract_skeleton.yaml index 5f96e8c..0533538 100644 --- a/nipype-auto-conv/specs/tract_skeleton.yaml +++ b/nipype-auto-conv/specs/tract_skeleton.yaml @@ -42,21 +42,24 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: input image (typically mean FA volume) - distance_map: generic/file - # type=file|default=: distance map image - search_mask_file: generic/file - # type=file|default=: mask in which to use alternate search rule - data_file: generic/file - # type=file|default=: 4D data to project onto skeleton (usually FA) alt_data_file: generic/file # type=file|default=: 4D non-FA data to project onto skeleton alt_skeleton: generic/file # type=file|default=: alternate skeleton to use - projected_data: generic/file + data_file: generic/file + # type=file|default=: 4D data to project onto skeleton (usually FA) + distance_map: generic/file + # type=file|default=: distance map image + in_file: generic/file + # type=file|default=: input image (typically mean FA volume) + projected_data: Path # type=file: input data projected onto skeleton # type=file|default=: input data projected onto skeleton + search_mask_file: generic/file + # type=file|default=: mask in which to use alternate search rule + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -118,7 +121,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/tract_skeleton_callables.py b/nipype-auto-conv/specs/tract_skeleton_callables.py index 92b6fc4..9833726 100644 --- a/nipype-auto-conv/specs/tract_skeleton_callables.py +++ b/nipype-auto-conv/specs/tract_skeleton_callables.py @@ -1 +1,141 @@ -"""Module to put any functions that are referred to in TractSkeleton.yaml""" +"""Module to put any functions that are referred to in the "callables" section of TractSkeleton.yaml""" + +import attrs +import os.path as op +from pathlib import Path + + +def projected_data_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["projected_data"] + + +def skeleton_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["skeleton_file"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L1445 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + _si = inputs + if (_si.project_data is not attrs.NOTHING) and _si.project_data: + proj_data = _si.projected_data + outputs["projected_data"] = proj_data + if proj_data is attrs.NOTHING: + stem = _si.data_file + if _si.alt_data_file is not attrs.NOTHING: + stem = _si.alt_data_file + outputs["projected_data"] = fname_presuffix( + stem, suffix="_skeletonised", newpath=output_dir, use_ext=True + ) + if (_si.skeleton_file is not attrs.NOTHING) and _si.skeleton_file: + outputs["skeleton_file"] = _si.skeleton_file + if isinstance(_si.skeleton_file, bool): + outputs["skeleton_file"] = fname_presuffix( + _si.in_file, suffix="_skeleton", newpath=output_dir, use_ext=True + ) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext diff --git a/nipype-auto-conv/specs/training.yaml b/nipype-auto-conv/specs/training.yaml index 6491ff2..52ac302 100644 --- a/nipype-auto-conv/specs/training.yaml +++ b/nipype-auto-conv/specs/training.yaml @@ -24,6 +24,9 @@ inputs: # passed to the field in the automatically generated unittests. mel_icas: generic/directory+list-of # type=inputmultiobject|default=[]: Melodic output directories + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -61,7 +64,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/training_callables.py b/nipype-auto-conv/specs/training_callables.py index 7be534e..b162530 100644 --- a/nipype-auto-conv/specs/training_callables.py +++ b/nipype-auto-conv/specs/training_callables.py @@ -1 +1,28 @@ -"""Module to put any functions that are referred to in Training.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Training.yaml""" + +import attrs +import os + + +def trained_wts_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["trained_wts_file"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L200 of /interfaces/fsl/fix.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + if inputs.trained_wts_filestem is not attrs.NOTHING: + outputs["trained_wts_file"] = os.path.abspath( + inputs.trained_wts_filestem + ".RData" + ) + else: + outputs["trained_wts_file"] = os.path.abspath("trained_wts_file.RData") + return outputs diff --git a/nipype-auto-conv/specs/training_set_creator.yaml b/nipype-auto-conv/specs/training_set_creator.yaml index d9bb524..af7716c 100644 --- a/nipype-auto-conv/specs/training_set_creator.yaml +++ b/nipype-auto-conv/specs/training_set_creator.yaml @@ -29,6 +29,9 @@ inputs: # passed to the field in the automatically generated unittests. mel_icas_in: generic/directory+list-of # type=inputmultiobject|default=[]: Melodic output directories + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -42,6 +45,8 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + mel_icas_out: generic/directory+list-of + # type=outputmultiobject: Hand labels for noise vs signal callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -56,7 +61,7 @@ tests: mel_icas_in: # type=inputmultiobject|default=[]: Melodic output directories imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/training_set_creator_callables.py b/nipype-auto-conv/specs/training_set_creator_callables.py index b585309..02bfada 100644 --- a/nipype-auto-conv/specs/training_set_creator_callables.py +++ b/nipype-auto-conv/specs/training_set_creator_callables.py @@ -1 +1,21 @@ -"""Module to put any functions that are referred to in TrainingSetCreator.yaml""" +"""Module to put any functions that are referred to in the "callables" section of TrainingSetCreator.yaml""" + +import os + + +def mel_icas_out_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mel_icas_out"] + + +# Original source at L122 of /interfaces/fsl/fix.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + mel_icas = [] + for item in inputs.mel_icas_in: + if os.path.exists(os.path.join(item, "hand_labels_noise.txt")): + mel_icas.append(item) + outputs = {} + outputs["mel_icas_out"] = mel_icas + return outputs diff --git a/nipype-auto-conv/specs/unary_maths.yaml b/nipype-auto-conv/specs/unary_maths.yaml index 7cb6818..2c0829b 100644 --- a/nipype-auto-conv/specs/unary_maths.yaml +++ b/nipype-auto-conv/specs/unary_maths.yaml @@ -22,6 +22,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: generic/file # type=file|default=: image to operate on + out_file: Path + # type=file: image written after calculations + # type=file|default=: image to write + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -72,7 +78,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/unary_maths_callables.py b/nipype-auto-conv/specs/unary_maths_callables.py index ae1ae26..62b82c1 100644 --- a/nipype-auto-conv/specs/unary_maths_callables.py +++ b/nipype-auto-conv/specs/unary_maths_callables.py @@ -1 +1,337 @@ -"""Module to put any functions that are referred to in UnaryMaths.yaml""" +"""Module to put any functions that are referred to in the "callables" section of UnaryMaths.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L61 of /interfaces/fsl/maths.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return nipype_interfaces_fsl_maths__MathsCommand___list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )["out_file"] + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "fslmaths" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L502 of /interfaces/fsl/maths.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + _suffix = "_" + inputs.operation + return nipype_interfaces_fsl_maths__MathsCommand___list_outputs() + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L51 of /interfaces/fsl/maths.py +def nipype_interfaces_fsl_maths__MathsCommand___list_outputs( + inputs=None, stdout=None, stderr=None, output_dir=None +): + outputs = {} + outputs["out_file"] = inputs.out_file + if inputs.out_file is attrs.NOTHING: + outputs["out_file"] = _gen_fname( + inputs.in_file, + suffix=_suffix, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/vec_reg.yaml b/nipype-auto-conv/specs/vec_reg.yaml index 3c8aa5a..58dd74e 100644 --- a/nipype-auto-conv/specs/vec_reg.yaml +++ b/nipype-auto-conv/specs/vec_reg.yaml @@ -32,22 +32,28 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. + affine_mat: datascience/text-matrix + # type=file|default=: filename for affine transformation matrix in_file: medimage/nifti1 # type=file|default=: filename for input vector or tensor field + mask: generic/file + # type=file|default=: brain mask in input space + out_file: Path + # type=file: path/name of filename for the registered vector or tensor field + # type=file|default=: filename for output registered vector or tensor field + ref_mask: generic/file + # type=file|default=: brain mask in output space (useful for speed up of nonlinear reg) ref_vol: medimage/nifti1 # type=file|default=: filename for reference (target) volume - affine_mat: datascience/text-matrix - # type=file|default=: filename for affine transformation matrix - warp_field: generic/file - # type=file|default=: filename for 4D warp field for nonlinear registration rotation_mat: generic/file # type=file|default=: filename for secondary affine matrix if set, this will be used for the rotation of the vector/tensor field rotation_warp: generic/file # type=file|default=: filename for secondary warp field if set, this will be used for the rotation of the vector/tensor field - mask: generic/file - # type=file|default=: brain mask in input space - ref_mask: generic/file - # type=file|default=: brain mask in output space (useful for speed up of nonlinear reg) + warp_field: generic/file + # type=file|default=: filename for 4D warp field for nonlinear registration + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -106,7 +112,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -133,7 +139,7 @@ tests: # type=file: path/name of filename for the registered vector or tensor field # type=file|default=: filename for output registered vector or tensor field imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -154,17 +160,17 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"diffusion.nii"' # type=file|default=: filename for input vector or tensor field - affine_mat: + affine_mat: '"trans.mat"' # type=file|default=: filename for affine transformation matrix - ref_vol: + ref_vol: '"mni.nii"' # type=file|default=: filename for reference (target) volume out_file: '"diffusion_vreg.nii"' # type=file: path/name of filename for the registered vector or tensor field # type=file|default=: filename for output registered vector or tensor field imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/vec_reg_callables.py b/nipype-auto-conv/specs/vec_reg_callables.py index e1d8453..1a7b200 100644 --- a/nipype-auto-conv/specs/vec_reg_callables.py +++ b/nipype-auto-conv/specs/vec_reg_callables.py @@ -1 +1,332 @@ -"""Module to put any functions that are referred to in VecReg.yaml""" +"""Module to put any functions that are referred to in the "callables" section of VecReg.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def out_file_default(inputs): + return _gen_filename("out_file", inputs=inputs) + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L1216 of /interfaces/fsl/dti.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + if name == "out_file": + return _list_outputs( + inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + )[name] + else: + return None + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "vecreg" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L1205 of /interfaces/fsl/dti.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = inputs.out_file + if (outputs["out_file"] is attrs.NOTHING) and (inputs.in_file is not attrs.NOTHING): + pth, base_name = os.path.split(inputs.in_file) + outputs["out_file"] = _gen_fname( + base_name, + cwd=os.path.abspath(pth), + suffix="_vreg", + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + outputs["out_file"] = os.path.abspath(outputs["out_file"]) + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/nipype-auto-conv/specs/vest_2_text.yaml b/nipype-auto-conv/specs/vest_2_text.yaml index 0a0e392..599cedc 100644 --- a/nipype-auto-conv/specs/vest_2_text.yaml +++ b/nipype-auto-conv/specs/vest_2_text.yaml @@ -34,9 +34,12 @@ inputs: # passed to the field in the automatically generated unittests. in_file: datascience/text-matrix # type=file|default=: matrix data stored in the format used by FSL tools - out_file: generic/file + out_file: Path # type=file: plain text representation of FSL matrix # type=file|default='design.txt': file name to store text output from matrix + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -76,7 +79,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -96,7 +99,7 @@ tests: in_file: # type=file|default=: matrix data stored in the format used by FSL tools imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -117,10 +120,10 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"design.mat"' # type=file|default=: matrix data stored in the format used by FSL tools imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/vest_2_text_callables.py b/nipype-auto-conv/specs/vest_2_text_callables.py index 905b226..2b60243 100644 --- a/nipype-auto-conv/specs/vest_2_text_callables.py +++ b/nipype-auto-conv/specs/vest_2_text_callables.py @@ -1 +1,338 @@ -"""Module to put any functions that are referred to in Vest2Text.yaml""" +"""Module to put any functions that are referred to in the "callables" section of Vest2Text.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/warp_points.yaml b/nipype-auto-conv/specs/warp_points.yaml index 0c55db1..2bb497c 100644 --- a/nipype-auto-conv/specs/warp_points.yaml +++ b/nipype-auto-conv/specs/warp_points.yaml @@ -41,19 +41,22 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - src_file: medimage/nifti1 - # type=file|default=: filename of source image dest_file: medimage/nifti1 # type=file|default=: filename of destination image in_coords: text/text-file # type=file|default=: filename of file containing coordinates - xfm_file: generic/file - # type=file|default=: filename of affine transform (e.g. source2dest.mat) - warp_file: medimage/nifti1 - # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) - out_file: generic/file + out_file: Path # type=file: Name of output file, containing the warp as field or coefficients. # type=file|default=: output file name + src_file: medimage/nifti1 + # type=file|default=: filename of source image + warp_file: medimage/nifti1 + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + xfm_file: generic/file + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -103,7 +106,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -131,7 +134,7 @@ tests: coord_mm: 'True' # type=bool|default=False: all coordinates in mm imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -152,18 +155,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_coords: + in_coords: '"surf.txt"' # type=file|default=: filename of file containing coordinates - src_file: + src_file: '"epi.nii"' # type=file|default=: filename of source image - dest_file: + dest_file: '"T1.nii"' # type=file|default=: filename of destination image - warp_file: + warp_file: '"warpfield.nii"' # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) coord_mm: 'True' # type=bool|default=False: all coordinates in mm imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_points_callables.py b/nipype-auto-conv/specs/warp_points_callables.py index b868a2c..1962865 100644 --- a/nipype-auto-conv/specs/warp_points_callables.py +++ b/nipype-auto-conv/specs/warp_points_callables.py @@ -1 +1,204 @@ -"""Module to put any functions that are referred to in WarpPoints.yaml""" +"""Module to put any functions that are referred to in the "callables" section of WarpPoints.yaml""" + +import attrs +import logging +import os +import os.path as op + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L2585 of /interfaces/fsl/utils.py +def _overload_extension( + value, name, inputs=None, stdout=None, stderr=None, output_dir=None +): + if name == "out_file": + return "%s.%s" % (value, getattr(self, "_outformat")) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/warp_points_from_std.yaml b/nipype-auto-conv/specs/warp_points_from_std.yaml index 2c28ddf..fbf7d17 100644 --- a/nipype-auto-conv/specs/warp_points_from_std.yaml +++ b/nipype-auto-conv/specs/warp_points_from_std.yaml @@ -43,14 +43,17 @@ inputs: # passed to the field in the automatically generated unittests. img_file: medimage/nifti1 # type=file|default=: filename of a destination image - std_file: medimage/nifti1 - # type=file|default=: filename of the image in standard space in_coords: text/text-file # type=file|default=: filename of file containing coordinates - xfm_file: generic/file - # type=file|default=: filename of affine transform (e.g. source2dest.mat) + std_file: medimage/nifti1 + # type=file|default=: filename of the image in standard space warp_file: medimage/nifti1 # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + xfm_file: generic/file + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -96,7 +99,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -124,7 +127,7 @@ tests: coord_mm: 'True' # type=bool|default=False: all coordinates in mm imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -145,18 +148,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_coords: + in_coords: '"surf.txt"' # type=file|default=: filename of file containing coordinates - img_file: + img_file: '"T1.nii"' # type=file|default=: filename of a destination image - std_file: + std_file: '"mni.nii"' # type=file|default=: filename of the image in standard space - warp_file: + warp_file: '"warpfield.nii"' # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) coord_mm: 'True' # type=bool|default=False: all coordinates in mm imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_points_from_std_callables.py b/nipype-auto-conv/specs/warp_points_from_std_callables.py index e587abf..0bd158b 100644 --- a/nipype-auto-conv/specs/warp_points_from_std_callables.py +++ b/nipype-auto-conv/specs/warp_points_from_std_callables.py @@ -1 +1,22 @@ -"""Module to put any functions that are referred to in WarpPointsFromStd.yaml""" +"""Module to put any functions that are referred to in the "callables" section of WarpPointsFromStd.yaml""" + +import os.path as op + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L2744 of /interfaces/fsl/utils.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + outputs["out_file"] = op.abspath("stdout.nipype") + return outputs diff --git a/nipype-auto-conv/specs/warp_points_to_std.yaml b/nipype-auto-conv/specs/warp_points_to_std.yaml index 20ddb69..395843c 100644 --- a/nipype-auto-conv/specs/warp_points_to_std.yaml +++ b/nipype-auto-conv/specs/warp_points_to_std.yaml @@ -45,19 +45,22 @@ inputs: # passed to the field in the automatically generated unittests. img_file: medimage/nifti1 # type=file|default=: filename of input image - std_file: medimage/nifti1 - # type=file|default=: filename of destination image - premat_file: generic/file - # type=file|default=: filename of pre-warp affine transform (e.g. example_func2highres.mat) in_coords: text/text-file # type=file|default=: filename of file containing coordinates - xfm_file: generic/file - # type=file|default=: filename of affine transform (e.g. source2dest.mat) - warp_file: medimage/nifti1 - # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) - out_file: generic/file + out_file: Path # type=file: Name of output file, containing the warp as field or coefficients. # type=file|default=: output file name + premat_file: generic/file + # type=file|default=: filename of pre-warp affine transform (e.g. example_func2highres.mat) + std_file: medimage/nifti1 + # type=file|default=: filename of destination image + warp_file: medimage/nifti1 + # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) + xfm_file: generic/file + # type=file|default=: filename of affine transform (e.g. source2dest.mat) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -109,7 +112,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -137,7 +140,7 @@ tests: coord_mm: 'True' # type=bool|default=False: all coordinates in mm imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -158,18 +161,18 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_coords: + in_coords: '"surf.txt"' # type=file|default=: filename of file containing coordinates - img_file: + img_file: '"T1.nii"' # type=file|default=: filename of input image - std_file: + std_file: '"mni.nii"' # type=file|default=: filename of destination image - warp_file: + warp_file: '"warpfield.nii"' # type=file|default=: filename of warpfield (e.g. intermediate2dest_warp.nii.gz) coord_mm: 'True' # type=bool|default=False: all coordinates in mm imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_points_to_std_callables.py b/nipype-auto-conv/specs/warp_points_to_std_callables.py index 3c70651..078867b 100644 --- a/nipype-auto-conv/specs/warp_points_to_std_callables.py +++ b/nipype-auto-conv/specs/warp_points_to_std_callables.py @@ -1 +1,204 @@ -"""Module to put any functions that are referred to in WarpPointsToStd.yaml""" +"""Module to put any functions that are referred to in the "callables" section of WarpPointsToStd.yaml""" + +import attrs +import logging +import os +import os.path as op + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L2585 of /interfaces/fsl/utils.py +def _overload_extension( + value, name, inputs=None, stdout=None, stderr=None, output_dir=None +): + if name == "out_file": + return "%s.%s" % (value, getattr(self, "_outformat")) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/warp_utils.yaml b/nipype-auto-conv/specs/warp_utils.yaml index 360fd75..3132d25 100644 --- a/nipype-auto-conv/specs/warp_utils.yaml +++ b/nipype-auto-conv/specs/warp_utils.yaml @@ -41,14 +41,17 @@ inputs: # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). - reference: medimage/nifti1 - # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. - out_file: generic/file + out_file: Path # type=file: Name of output file, containing the warp as field or coefficients. # type=file|default=: Name of output file. The format of the output depends on what other parameters are set. The default format is a (4D) field-file. If the --outformat is set to spline the format will be a (4D) file of spline coefficients. - out_jacobian: generic/file + out_jacobian: Path # type=file: Name of output file, containing the map of the determinant of the Jacobian # type=file|default=: Specifies that a (3D) file of Jacobian determinants corresponding to --in should be produced and written to filename. + reference: medimage/nifti1 + # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -106,7 +109,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -134,7 +137,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically @@ -155,9 +158,9 @@ doctests: # dict[str, str] - name-value pairs for inputs to be provided to the doctest. # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. - in_file: + in_file: '"warpfield.nii"' # type=file|default=: Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout). - reference: + reference: '"T1.nii"' # type=file|default=: Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt. out_format: '"spline"' # type=enum|default='spline'|allowed['field','spline']: Specifies the output format. If set to field (default) the output will be a (4D) field-file. If set to spline the format will be a (4D) file of spline coefficients. @@ -166,7 +169,7 @@ doctests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys directive: # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/warp_utils_callables.py b/nipype-auto-conv/specs/warp_utils_callables.py index f8cee64..25df087 100644 --- a/nipype-auto-conv/specs/warp_utils_callables.py +++ b/nipype-auto-conv/specs/warp_utils_callables.py @@ -1 +1,345 @@ -"""Module to put any functions that are referred to in WarpUtils.yaml""" +"""Module to put any functions that are referred to in the "callables" section of WarpUtils.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob + + +def out_file_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_file"] + + +def out_jacobian_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["out_jacobian"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +iflogger = logging.getLogger("nipype.interface") + + +# Original source at L809 of /interfaces/base/core.py +def _filename_from_source( + name, chain=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + if chain is None: + chain = [] + + trait_spec = inputs.trait(name) + retval = getattr(inputs, name) + source_ext = None + if (retval is attrs.NOTHING) or "%s" in retval: + if not trait_spec.name_source: + return retval + + # Do not generate filename when excluded by other inputs + if any( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.xor or () + ): + return retval + + # Do not generate filename when required fields are missing + if not all( + (getattr(inputs, field) is not attrs.NOTHING) + for field in trait_spec.requires or () + ): + return retval + + if (retval is not attrs.NOTHING) and "%s" in retval: + name_template = retval + else: + name_template = trait_spec.name_template + if not name_template: + name_template = "%s_generated" + + ns = trait_spec.name_source + while isinstance(ns, (list, tuple)): + if len(ns) > 1: + iflogger.warning("Only one name_source per trait is allowed") + ns = ns[0] + + if not isinstance(ns, (str, bytes)): + raise ValueError( + "name_source of '{}' trait should be an input trait " + "name, but a type {} object was found".format(name, type(ns)) + ) + + if getattr(inputs, ns) is not attrs.NOTHING: + name_source = ns + source = getattr(inputs, name_source) + while isinstance(source, list): + source = source[0] + + # special treatment for files + try: + _, base, source_ext = split_filename(source) + except (AttributeError, TypeError): + base = source + else: + if name in chain: + raise NipypeInterfaceError("Mutually pointing name_sources") + + chain.append(name) + base = _filename_from_source( + ns, + chain, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + if base is not attrs.NOTHING: + _, _, source_ext = split_filename(base) + else: + # Do not generate filename when required fields are missing + return retval + + chain = None + retval = name_template % base + _, _, ext = split_filename(retval) + if trait_spec.keep_extension and (ext or source_ext): + if (ext is None or not ext) and source_ext: + retval = retval + source_ext + else: + retval = _overload_extension( + retval, + name, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + return retval + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L891 of /interfaces/base/core.py +def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): + metadata = dict(name_source=lambda t: t is not None) + traits = inputs.traits(**metadata) + if traits: + outputs = {} + for name, trait_spec in list(traits.items()): + out_name = name + if trait_spec.output_name is not None: + out_name = trait_spec.output_name + fname = _filename_from_source( + name, inputs=inputs, stdout=stdout, stderr=stderr, output_dir=output_dir + ) + if fname is not attrs.NOTHING: + outputs[out_name] = os.path.abspath(fname) + return outputs + + +# Original source at L249 of /interfaces/fsl/base.py +def _overload_extension( + value, name=None, inputs=None, stdout=None, stderr=None, output_dir=None +): + return value + Info.output_type_to_ext(inputs.output_type) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) + + +# Original source at L125 of /interfaces/base/support.py +class NipypeInterfaceError(Exception): + """Custom error for interfaces""" + + def __init__(self, value): + self.value = value + + def __str__(self): + return "{}".format(self.value) diff --git a/nipype-auto-conv/specs/x_fibres_5.yaml b/nipype-auto-conv/specs/x_fibres_5.yaml index 1cbf74a..9ea798f 100644 --- a/nipype-auto-conv/specs/x_fibres_5.yaml +++ b/nipype-auto-conv/specs/x_fibres_5.yaml @@ -23,18 +23,21 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - gradnonlin: generic/file - # type=file|default=: gradient file corresponding to slice - dwi: generic/file - # type=file|default=: diffusion weighted image data file - mask: generic/file - # type=file|default=: brain binary mask file (i.e. from BET) - bvecs: generic/file - # type=file|default=: b vectors file bvals: generic/file # type=file|default=: b values file + bvecs: generic/file + # type=file|default=: b vectors file + dwi: generic/file + # type=file|default=: diffusion weighted image data file + gradnonlin: generic/file + # type=file|default=: gradient file corresponding to slice logdir: generic/directory # type=directory|default='.': + mask: generic/file + # type=file|default=: brain binary mask file (i.e. from BET) + callable_defaults: + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: @@ -48,12 +51,22 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mean_dsamples: generic/file - # type=file: Mean of distribution on diffusivity d + dyads: generic/file+list-of + # type=outputmultiobject: Mean of PDD distribution in vector form. + fsamples: generic/file+list-of + # type=outputmultiobject: Samples from the distribution on f anisotropy mean_S0samples: generic/file # type=file: Mean of distribution on T2wbaseline signal intensity S0 + mean_dsamples: generic/file + # type=file: Mean of distribution on diffusivity d + mean_fsamples: generic/file+list-of + # type=outputmultiobject: Mean of distribution on f anisotropy mean_tausamples: generic/file # type=file: Mean of distribution on tau samples (only with rician noise) + phsamples: generic/file+list-of + # type=outputmultiobject: phi samples, per fiber + thsamples: generic/file+list-of + # type=outputmultiobject: theta samples, per fiber callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -120,7 +133,7 @@ tests: environ: # type=dict|default={}: Environment variables imports: - # list[nipype2pydra.task.importstatement] - list import statements required by the test, with each list item + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys expected_outputs: # dict[str, str] - expected values for selected outputs, noting that tests will typically diff --git a/nipype-auto-conv/specs/x_fibres_5_callables.py b/nipype-auto-conv/specs/x_fibres_5_callables.py index 0f22a32..8b82c68 100644 --- a/nipype-auto-conv/specs/x_fibres_5_callables.py +++ b/nipype-auto-conv/specs/x_fibres_5_callables.py @@ -1 +1,446 @@ -"""Module to put any functions that are referred to in XFibres5.yaml""" +"""Module to put any functions that are referred to in the "callables" section of XFibres5.yaml""" + +import attrs +import logging +import os +import os.path as op +from glob import glob +from pathlib import Path + + +def dyads_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["dyads"] + + +def fsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["fsamples"] + + +def mean_S0samples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_S0samples"] + + +def mean_dsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_dsamples"] + + +def mean_fsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_fsamples"] + + +def mean_tausamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["mean_tausamples"] + + +def phsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["phsamples"] + + +def thsamples_callable(output_dir, inputs, stdout, stderr): + outputs = _list_outputs( + output_dir=output_dir, inputs=inputs, stdout=stdout, stderr=stderr + ) + return outputs["thsamples"] + + +IFLOGGER = logging.getLogger("nipype.interface") + + +# Original source at L885 of /interfaces/base/core.py +def _gen_filename(name, inputs=None, stdout=None, stderr=None, output_dir=None): + raise NotImplementedError + + +# Original source at L205 of /interfaces/fsl/base.py +def _gen_fname( + basename, + cwd=None, + suffix=None, + change_ext=True, + ext=None, + inputs=None, + stdout=None, + stderr=None, + output_dir=None, +): + """Generate a filename based on the given parameters. + + The filename will take the form: cwd/basename. + If change_ext is True, it will use the extensions specified in + inputs.output_type. + + Parameters + ---------- + basename : str + Filename to base the new filename on. + cwd : str + Path to prefix to the new filename. (default is output_dir) + suffix : str + Suffix to add to the `basename`. (defaults is '' ) + change_ext : bool + Flag to change the filename extension to the FSL output type. + (default True) + + Returns + ------- + fname : str + New filename based on given parameters. + + """ + + if basename == "": + msg = "Unable to generate filename for command %s. " % "xfibres" + msg += "basename is not set!" + raise ValueError(msg) + if cwd is None: + cwd = output_dir + if ext is None: + ext = Info.output_type_to_ext(inputs.output_type) + if change_ext: + if suffix: + suffix = "".join((suffix, ext)) + else: + suffix = ext + if suffix is None: + suffix = "" + fname = fname_presuffix(basename, suffix=suffix, use_ext=False, newpath=cwd) + return fname + + +# Original source at L298 of /interfaces/fsl/dti.py +def _list_outputs(out_dir=None, inputs=None, stdout=None, stderr=None, output_dir=None): + outputs = {} + n_fibres = inputs.n_fibres + if not out_dir: + if inputs.logdir is not attrs.NOTHING: + out_dir = os.path.abspath(inputs.logdir) + else: + out_dir = os.path.abspath("logdir") + + multi_out = ["dyads", "fsamples", "mean_fsamples", "phsamples", "thsamples"] + single_out = ["mean_dsamples", "mean_S0samples"] + + for k in single_out: + outputs[k] = _gen_fname( + k, + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + if (inputs.rician is not attrs.NOTHING) and inputs.rician: + outputs["mean_tausamples"] = _gen_fname( + "mean_tausamples", + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + + for k in multi_out: + outputs[k] = [] + + for i in range(1, n_fibres + 1): + outputs["fsamples"].append( + _gen_fname( + "f%dsamples" % i, + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["mean_fsamples"].append( + _gen_fname( + "mean_f%dsamples" % i, + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + + for i in range(1, n_fibres + 1): + outputs["dyads"].append( + _gen_fname( + "dyads%d" % i, + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["phsamples"].append( + _gen_fname( + "ph%dsamples" % i, + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + outputs["thsamples"].append( + _gen_fname( + "th%dsamples" % i, + cwd=out_dir, + inputs=inputs, + stdout=stdout, + stderr=stderr, + output_dir=output_dir, + ) + ) + + return outputs + + +# Original source at L108 of /utils/filemanip.py +def fname_presuffix(fname, prefix="", suffix="", newpath=None, use_ext=True): + """Manipulates path and name of input filename + + Parameters + ---------- + fname : string + A filename (may or may not include path) + prefix : string + Characters to prepend to the filename + suffix : string + Characters to append to the filename + newpath : string + Path to replace the path of the input fname + use_ext : boolean + If True (default), appends the extension of the original file + to the output name. + + Returns + ------- + Absolute path of the modified filename + + >>> from nipype.utils.filemanip import fname_presuffix + >>> fname = 'foo.nii.gz' + >>> fname_presuffix(fname,'pre','post','/tmp') + '/tmp/prefoopost.nii.gz' + + >>> from nipype.interfaces.base import attrs.NOTHING + >>> fname_presuffix(fname, 'pre', 'post', attrs.NOTHING) == \ + fname_presuffix(fname, 'pre', 'post') + True + + """ + pth, fname, ext = split_filename(fname) + if not use_ext: + ext = "" + + # No need for : bool(attrs.NOTHING is not attrs.NOTHING) evaluates to False + if newpath: + pth = op.abspath(newpath) + return op.join(pth, prefix + fname + suffix + ext) + + +# Original source at L58 of /utils/filemanip.py +def split_filename(fname): + """Split a filename into parts: path, base filename and extension. + + Parameters + ---------- + fname : str + file or path name + + Returns + ------- + pth : str + base path from fname + fname : str + filename from fname, without extension + ext : str + file extension from fname + + Examples + -------- + >>> from nipype.utils.filemanip import split_filename + >>> pth, fname, ext = split_filename('/home/data/subject.nii.gz') + >>> pth + '/home/data' + + >>> fname + 'subject' + + >>> ext + '.nii.gz' + + """ + + special_extensions = [".nii.gz", ".tar.gz", ".niml.dset"] + + pth = op.dirname(fname) + fname = op.basename(fname) + + ext = None + for special_ext in special_extensions: + ext_len = len(special_ext) + if (len(fname) > ext_len) and (fname[-ext_len:].lower() == special_ext.lower()): + ext = fname[-ext_len:] + fname = fname[:-ext_len] + break + if not ext: + fname, ext = op.splitext(fname) + + return pth, fname, ext + + +# Original source at L1069 of /interfaces/base/core.py +class PackageInfo(object): + _version = None + version_cmd = None + version_file = None + + @classmethod + def version(klass): + if klass._version is None: + if klass.version_cmd is not None: + try: + clout = CommandLine( + command=klass.version_cmd, + resource_monitor=False, + terminal_output="allatonce", + ).run() + except IOError: + return None + + raw_info = clout.runtime.stdout + elif klass.version_file is not None: + try: + with open(klass.version_file, "rt") as fobj: + raw_info = fobj.read() + except OSError: + return None + else: + return None + + klass._version = klass.parse_version(raw_info) + + return klass._version + + @staticmethod + def parse_version(raw_info): + raise NotImplementedError + + +# Original source at L40 of /interfaces/fsl/base.py +class Info(PackageInfo): + """ + Handle FSL ``output_type`` and version information. + + output type refers to the type of file fsl defaults to writing + eg, NIFTI, NIFTI_GZ + + Examples + -------- + + >>> from nipype.interfaces.fsl import Info + >>> Info.version() # doctest: +SKIP + >>> Info.output_type() # doctest: +SKIP + + """ + + ftypes = { + "NIFTI": ".nii", + "NIFTI_PAIR": ".img", + "NIFTI_GZ": ".nii.gz", + "NIFTI_PAIR_GZ": ".img.gz", + } + + if os.getenv("FSLDIR"): + version_file = os.path.join(os.getenv("FSLDIR"), "etc", "fslversion") + + @staticmethod + def parse_version(raw_info): + return raw_info.splitlines()[0] + + @classmethod + def output_type_to_ext(cls, output_type): + """Get the file extension for the given output type. + + Parameters + ---------- + output_type : {'NIFTI', 'NIFTI_GZ', 'NIFTI_PAIR', 'NIFTI_PAIR_GZ'} + String specifying the output type. + + Returns + ------- + extension : str + The file extension for the output type. + """ + + try: + return cls.ftypes[output_type] + except KeyError: + msg = "Invalid FSLOUTPUTTYPE: ", output_type + raise KeyError(msg) + + @classmethod + def output_type(cls): + """Get the global FSL output file type FSLOUTPUTTYPE. + + This returns the value of the environment variable + FSLOUTPUTTYPE. An exception is raised if it is not defined. + + Returns + ------- + fsl_ftype : string + Represents the current environment setting of FSLOUTPUTTYPE + """ + try: + return os.environ["FSLOUTPUTTYPE"] + except KeyError: + IFLOGGER.warning( + "FSLOUTPUTTYPE environment variable is not set. " + "Setting FSLOUTPUTTYPE=NIFTI" + ) + return "NIFTI" + + @staticmethod + def standard_image(img_name=None): + """Grab an image from the standard location. + + Returns a list of standard images if called without arguments. + + Could be made more fancy to allow for more relocatability""" + try: + fsldir = os.environ["FSLDIR"] + except KeyError: + raise Exception("FSL environment variables not set") + stdpath = os.path.join(fsldir, "data", "standard") + if img_name is None: + return [ + filename.replace(stdpath + "/", "") + for filename in glob(os.path.join(stdpath, "*nii*")) + ] + return os.path.join(stdpath, img_name) diff --git a/pydra/tasks/fsl/_version.py b/pydra/tasks/fsl/_version.py deleted file mode 100644 index c519089..0000000 --- a/pydra/tasks/fsl/_version.py +++ /dev/null @@ -1,4 +0,0 @@ -# file generated by setuptools_scm -# don't change, don't track in version control -__version__ = version = '0.1.dev123+gd6b46a1.d20230502' -__version_tuple__ = version_tuple = (0, 1, 'dev123', 'gd6b46a1.d20230502') diff --git a/pydra/tasks/fsl/conftest.py b/pydra/tasks/fsl/conftest.py deleted file mode 100644 index ba9f4d8..0000000 --- a/pydra/tasks/fsl/conftest.py +++ /dev/null @@ -1,48 +0,0 @@ -import os -import shutil -from tempfile import mkdtemp -import pytest - -# import numpy -import py.path as pp - -NIPYPE_DATADIR = os.path.realpath(os.path.join(os.path.dirname(__file__), "tests/data")) -temp_folder = mkdtemp() -data_dir = os.path.join(temp_folder, "data") -shutil.copytree(NIPYPE_DATADIR, data_dir) - - -@pytest.fixture(autouse=True) -def add_np(doctest_namespace): - # doctest_namespace["np"] = numpy - doctest_namespace["os"] = os - doctest_namespace["pytest"] = pytest - doctest_namespace["datadir"] = data_dir - - -@pytest.fixture(autouse=True) -def _docdir(request): - """Grabbed from https://stackoverflow.com/a/46991331""" - # Trigger ONLY for the doctests. - doctest_plugin = request.config.pluginmanager.getplugin("doctest") - if isinstance(request.node, doctest_plugin.DoctestItem): - # Get the fixture dynamically by its name. - tmpdir = pp.local(data_dir) - - # Chdir only for the duration of the test. - with tmpdir.as_cwd(): - yield - - else: - # For normal tests, we have to yield, since this is a yield-fixture. - yield - - -@pytest.fixture() -def test_data(): - return NIPYPE_DATADIR - - -def pytest_unconfigure(config): - # Delete temp folder after session is finished - shutil.rmtree(temp_folder) diff --git a/pydra/tasks/fsl/model/cluster.py b/pydra/tasks/fsl/model/cluster.py deleted file mode 100644 index e45f144..0000000 --- a/pydra/tasks/fsl/model/cluster.py +++ /dev/null @@ -1,242 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def Cluster_output(inputs): - import os, attr - from pydra.engine.helpers_file import split_filename - - in_file = inputs.in_file - pth, fname, ext = split_filename(in_file) - - return os.path.join(pth, f"{fname}_localmax.txt") - - -input_fields = [ - ( - "in_file", - specs.File, - {"help_string": "input volume", "argstr": "--in={in_file}", "mandatory": True}, - ), - ( - "threshold", - float, - { - "help_string": "threshold for input volume", - "argstr": "--thresh={threshold:.10f}", - "mandatory": True, - }, - ), - ( - "out_index_file", - ty.Union[bool, str], - False, - { - "help_string": "output of cluster index (in size order)", - "argstr": "--oindex={out_index_file}", - "output_file_template": "{in_file}_index", - }, - ), - ( - "out_threshold_file", - ty.Union[bool, str], - False, - { - "help_string": "thresholded image", - "argstr": "--othresh={out_threshold_file}", - "output_file_template": "{in_file}_threshold", - }, - ), - ( - "out_localmax_txt_file", - ty.Union[bool, str], - False, - { - "help_string": "local maxima text file", - "argstr": "--olmax={out_localmax_txt_file}", - "output_file_template": Cluster_output, - }, - ), - ( - "out_localmax_vol_file", - ty.Union[bool, str], - False, - { - "help_string": "output of local maxima volume", - "argstr": "--olmaxim={out_localmax_vol_file}", - "output_file_template": "{in_file}_localmax", - }, - ), - ( - "out_size_file", - ty.Union[bool, str], - False, - { - "help_string": "filename for output of size image", - "argstr": "--osize={out_size_file}", - "output_file_template": "{in_file}_size", - }, - ), - ( - "out_max_file", - ty.Union[bool, str], - False, - { - "help_string": "filename for output of max image", - "argstr": "--omax={out_max_file}", - "output_file_template": "{in_file}_max", - }, - ), - ( - "out_mean_file", - ty.Union[bool, str], - False, - { - "help_string": "filename for output of mean image", - "argstr": "--omean={out_mean_file}", - "output_file_template": "{in_file}_mean", - }, - ), - ( - "out_pval_file", - ty.Union[bool, str], - False, - { - "help_string": "filename for image output of log pvals", - "argstr": "--opvals={out_pval_file}", - "output_file_template": "{in_file}_pval", - }, - ), - ( - "pthreshold", - float, - { - "help_string": "p-threshold for clusters", - "argstr": "--pthresh={pthreshold:.10f}", - "requires": ["dlh", "volume"], - }, - ), - ( - "peak_distance", - float, - { - "help_string": "minimum distance between local maxima/minima, in mm (default 0)", - "argstr": "--peakdist={peak_distance:.10f}", - }, - ), - ("cope_file", str, {"help_string": "cope volume", "argstr": "--cope={cope_file}"}), - ( - "volume", - int, - {"help_string": "number of voxels in the mask", "argstr": "--volume={volume}"}, - ), - ( - "dlh", - float, - { - "help_string": "smoothness estimate = sqrt(det(Lambda))", - "argstr": "--dlh={dlh:.10f}", - }, - ), - ( - "fractional", - bool, - False, - { - "help_string": "interprets the threshold as a fraction of the robust range", - "argstr": "--fractional", - }, - ), - ( - "connectivity", - int, - { - "help_string": "the connectivity of voxels (default 26)", - "argstr": "--connectivity={connectivity}", - }, - ), - ( - "use_mm", - bool, - False, - {"help_string": "use mm, not voxel, coordinates", "argstr": "--mm"}, - ), - ( - "find_min", - bool, - False, - {"help_string": "find minima instead of maxima", "argstr": "--min"}, - ), - ( - "no_table", - bool, - False, - { - "help_string": "suppresses printing of the table info", - "argstr": "--no_table", - }, - ), - ( - "minclustersize", - bool, - False, - { - "help_string": "prints out minimum significant cluster size", - "argstr": "--minclustersize", - }, - ), - ( - "xfm_file", - str, - { - "help_string": "filename for Linear: input->standard-space transform. Non-linear: input->highres transform", - "argstr": "--xfm={xfm_file}", - }, - ), - ( - "std_space_file", - str, - { - "help_string": "filename for standard-space volume", - "argstr": "--stdvol={std_space_file}", - }, - ), - ( - "num_maxima", - int, - {"help_string": "no of local maxima to report", "argstr": "--num={num_maxima}"}, - ), - ( - "warpfield_file", - str, - { - "help_string": "file contining warpfield", - "argstr": "--warpvol={warpfield_file}", - }, - ), -] -Cluster_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -Cluster_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class Cluster(ShellCommandTask): - """ - Example - ------- - >>> task = Cluster() - >>> task.inputs.in_file = "zstat1.nii.gz" - >>> task.inputs.out_localmax_txt_file = True - >>> task.inputs.threshold = 2.3 - >>> task.inputs.use_mm = True - >>> task.cmdline # doctest: +ELLIPSIS - 'cluster --in=zstat1.nii.gz --thresh=2.3000000000 --olmax=.../zstat1_localmax.txt --mm' - """ - - input_spec = Cluster_input_spec - output_spec = Cluster_output_spec - executable = "cluster" diff --git a/pydra/tasks/fsl/model/feat.py b/pydra/tasks/fsl/model/feat.py deleted file mode 100644 index 8f171d3..0000000 --- a/pydra/tasks/fsl/model/feat.py +++ /dev/null @@ -1,62 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def FEAT_output(fsf_file): - is_ica = False - with open(fsf_file, "rt") as fp: - text = fp.read() - if "set fmri(inmelodic) 1" in text: - is_ica = True - for line in text.split("\n"): - if line.find("set fmri(outputdir)") > -1: - try: - outputdir_spec = line.split('"')[-2] - if os.path.exists(outputdir_spec): - outputs = outputdir_spec - except: - pass - - if not outputs: - if is_ica: - outputs = glob(os.path.join(os.getcwd(), "*ica"))[0] - else: - outputs = glob(os.path.join(os.getcwd(), "*feat"))[0] - print("Outputs from FEATmodel:", outputs) - return outputs - - -input_fields = [ - ( - "fsf_file", - specs.File, - { - "help_string": "File specifying the feat design spec file", - "argstr": "{fsf_file}", - "mandatory": True, - "position": 0, - }, - ) -] -FEAT_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ("feat_dir", specs.Directory, {"requires": ["fsf_file"], "callable": FEAT_output}) -] -FEAT_output_spec = specs.SpecInfo(name="Output", fields=output_fields, bases=(specs.ShellOutSpec,)) - - -class FEAT(ShellCommandTask): - """ - Example - ------- - >>> task = FEAT() - >>> task.inputs.fsf_file = "test.fsf" - >>> task.cmdline - 'feat test.fsf' - """ - - input_spec = FEAT_input_spec - output_spec = FEAT_output_spec - executable = "feat" diff --git a/pydra/tasks/fsl/model/featmodel.py b/pydra/tasks/fsl/model/featmodel.py deleted file mode 100644 index 47663c6..0000000 --- a/pydra/tasks/fsl/model/featmodel.py +++ /dev/null @@ -1,119 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def FEATModel_output(field, fsf_file): - import os - - # TODO: figure out file names and get rid off the globs - outputs = {} - _, fname = os.path.split(fsf_file) - root = fname.split(".")[0] - name = field.name - if name == "design_file": - design_file = glob(os.path.join(os.getcwd(), "%s*.mat" % root)) - assert len(design_file) == 1, "No mat file generated by FEAT Model" - outputs = design_file[0] - elif name == "design_image": - design_image = glob(os.path.join(os.getcwd(), "%s.png" % root)) - assert len(design_image) == 1, "No design image generated by FEAT Model" - outputs = design_image[0] - elif name == "design_cov": - design_cov = glob(os.path.join(os.getcwd(), "%s_cov.png" % root)) - assert len(design_cov) == 1, "No covariance image generated by FEAT Model" - outputs = design_cov[0] - elif name == "con_file": - con_file = glob(os.path.join(os.getcwd(), "%s*.con" % root)) - assert len(con_file) == 1, "No con file generated by FEAT Model" - outputs = con_file[0] - elif name == "fcon_file": - fcon_file = glob(os.path.join(os.getcwd(), "%s*.fts" % root)) - if fcon_file: - assert len(fcon_file) == 1, "No fts file generated by FEAT Model" - outputs = fcon_file[0] - else: - raise Exception( - f"this function should be run only for design_file, design_image" - f"design_cov, con_file, or fcon_file, not for {name}" - ) - return outputs - - -input_fields = [ - ( - "fsf_file", - specs.File, - { - "help_string": "File specifying the feat design spec file", - "argstr": "{fsf_file}", - "copyfile": False, - "mandatory": True, - "position": 0, - }, - ), - ( - "ev_files", - specs.MultiInputFile, - { - "help_string": "Event spec files generated by level1design", - "argstr": "{ev_files}", - "copyfile": False, - "mandatory": True, - "position": 1, - }, - ), -] -FEATModel_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "design_file", - specs.File, - { - "help_string": "Mat file containing ascii matrix for design", - "callable": FEATModel_output, - }, - ), - ( - "design_image", - specs.File, - { - "help_string": "Graphical representation of design matrix", - "callable": FEATModel_output, - }, - ), - ( - "design_cov", - specs.File, - { - "help_string": "Graphical representation of design covariance", - "callable": FEATModel_output, - }, - ), - ( - "con_file", - specs.File, - { - "help_string": "Contrast file containing contrast vectors", - "callable": FEATModel_output, - }, - ), - ( - "fcon_file", - specs.File, - { - "help_string": "Contrast file containing contrast vectors", - "callable": FEATModel_output, - }, - ), -] -FEATModel_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class FEATModel(ShellCommandTask): - input_spec = FEATModel_input_spec - output_spec = FEATModel_output_spec - executable = "feat_model" diff --git a/pydra/tasks/fsl/model/filmgls.py b/pydra/tasks/fsl/model/filmgls.py deleted file mode 100644 index 75c0e19..0000000 --- a/pydra/tasks/fsl/model/filmgls.py +++ /dev/null @@ -1,396 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def FILMGLS_output(field, inputs): - import os, attr - - def _get_pe_files(design_file, pth): - files = None - if design_file not in [None, attr.NOTHING]: - fp = open(design_file, "rt") - for line in fp.readlines(): - if line.startswith("/NumWaves"): - numpes = int(line.split()[-1]) - files = [] - for i in range(numpes): - files.append(os.path.join(pth, ("pe%d.nii.gz" % (i + 1)))) - break - fp.close() - return files - - def _get_numcons(inputs): - numtcons = 0 - numfcons = 0 - if inputs.tcon_file not in [None, attr.NOTHING]: - fp = open(inputs.tcon_file, "rt") - for line in fp.readlines(): - if line.startswith("/NumContrasts"): - numtcons = int(line.split()[-1]) - break - fp.close() - if inputs.fcon_file not in [None, attr.NOTHING]: - fp = open(inputs.fcon_file, "rt") - for line in fp.readlines(): - if line.startswith("/NumContrasts"): - numfcons = int(line.split()[-1]) - break - fp.close() - return numtcons, numfcons - - name = field.name - pth = inputs.results_dir - if name == "results_dir": - return pth - elif name == "param_estimates": - design_file = inputs.design_file - pe_files = _get_pe_files(design_file, pth) - if pe_files: - return pe_files - elif name == "residual4d": - return os.path.join(pth, "res4d.nii.gz") - elif name == "dof_file": - return os.path.join(pth, "dof") - elif name == "sigmasquareds": - return os.path.join(pth, "sigmasquareds.nii.gz") - elif name == "thresholdac": - return os.path.join(pth, "threshac1.nii.gz") - elif name == "logfile": - return os.path.join(pth, "logfile") - - numtcons, numfcons = _get_numcons(inputs) - base_contrast = 1 - copes = [] - varcopes = [] - zstats = [] - tstats = [] - for i in range(numtcons): - copes.append(os.path.join(pth, ("cope%d.nii.gz" % (base_contrast + i)))) - varcopes.append(os.path.join(pth, ("varcope%d.nii.gz" % (base_contrast + i)))) - zstats.append(os.path.join(pth, ("zstat%d.nii.gz" % (base_contrast + i)))) - tstats.append(os.path.join(pth, ("tstat%d.nii.gz" % (base_contrast + i)))) - if copes: - if name == "copes": - return copes - elif name == "varcopes": - return varcopes - elif name == "zstats": - return zstats - elif name == "tstats": - return tstats - fstats = [] - zfstats = [] - for i in range(numfcons): - fstats.append(os.path.join(pth, ("fstat%d.nii.gz" % (base_contrast + i)))) - zfstats.append(os.path.join(pth, ("zfstat%d.nii.gz" % (base_contrast + i)))) - if fstats: - if name == "fstats": - return fstats - elif name == "zfstats": - return zfstats - - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input data file", - "argstr": "--in={in_file}", - "mandatory": True, - "position": -3, - }, - ), - ( - "design_file", - specs.File, - { - "help_string": "design matrix file", - "argstr": "--pd={design_file}", - "position": -2, - }, - ), - ( - "threshold", - float, - -1000.0, - {"help_string": "threshold", "argstr": "--thr={threshold}", "position": -1}, - ), - ( - "tcon_file", - specs.File, - { - "help_string": "contrast file containing T-contrasts", - "argstr": "--con={tcon_file}", - }, - ), - ( - "fcon_file", - specs.File, - { - "help_string": "contrast file containing F-contrasts", - "argstr": "--fcon={fcon_file}", - }, - ), - ( - "mode", - ty.Any, - {"help_string": "Type of analysis to be done", "argstr": "--mode={mode}"}, - ), - ( - "surface", - specs.File, - { - "help_string": "input surface for autocorr smoothing in surface-based analyses", - "argstr": "--in2={surface}", - }, - ), - ( - "smooth_autocorr", - bool, - {"help_string": "Smooth auto corr estimates", "argstr": "--sa"}, - ), - ( - "mask_size", - int, - {"help_string": "susan mask size", "argstr": "--ms={mask_size}"}, - ), - ( - "brightness_threshold", - ty.Any, - { - "help_string": "susan brightness threshold, otherwise it is estimated", - "argstr": "--epith={brightness_threshold}", - }, - ), - ("full_data", bool, {"help_string": "output full data", "argstr": "-v"}), - ( - "autocorr_estimate_only", - bool, - { - "help_string": "perform autocorrelation estimation only", - "argstr": "--ac", - "xor": [ - "autocorr_estimate_only", - "fit_armodel", - "tukey_window", - "multitaper_product", - "use_pava", - "autocorr_noestimate", - ], - }, - ), - ( - "fit_armodel", - bool, - { - "help_string": "fits autoregressive model - default is to use tukey with M=sqrt(numvols)", - "argstr": "--ar", - "xor": [ - "autocorr_estimate_only", - "fit_armodel", - "tukey_window", - "multitaper_product", - "use_pava", - "autocorr_noestimate", - ], - }, - ), - ( - "tukey_window", - int, - { - "help_string": "tukey window size to estimate autocorr", - "argstr": "--tukey={tukey_window}", - "xor": [ - "autocorr_estimate_only", - "fit_armodel", - "tukey_window", - "multitaper_product", - "use_pava", - "autocorr_noestimate", - ], - }, - ), - ( - "multitaper_product", - int, - { - "help_string": "multitapering with slepian tapers and num is the time-bandwidth product", - "argstr": "--mt={multitaper_product}", - "xor": [ - "autocorr_estimate_only", - "fit_armodel", - "tukey_window", - "multitaper_product", - "use_pava", - "autocorr_noestimate", - ], - }, - ), - ( - "use_pava", - bool, - {"help_string": "estimates autocorr using PAVA", "argstr": "--pava"}, - ), - ( - "autocorr_noestimate", - bool, - { - "help_string": "do not estimate autocorrs", - "argstr": "--noest", - "xor": [ - "autocorr_estimate_only", - "fit_armodel", - "tukey_window", - "multitaper_product", - "use_pava", - "autocorr_noestimate", - ], - }, - ), - ( - "output_pwdata", - bool, - { - "help_string": "output prewhitened data and average design matrix", - "argstr": "--outputPWdata", - }, - ), - ( - "results_dir", - str, - "results", - {"help_string": "directory to store results in", "argstr": "--rn={results_dir}"}, - ), -] -FILMGLS_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "results_dir", - specs.Directory, - { - "help_string": "Directory storing model estimation output", - "callable": FILMGLS_output, - }, - ), - ( - "param_estimates", - specs.MultiOutputFile, - { - "help_string": "Parameter estimates for each column of the design matrix", - "callable": FILMGLS_output, - }, - ), - ( - "residual4d", - specs.File, - { - "help_string": "Model fit residual mean-squared error for each time point", - "callable": FILMGLS_output, - }, - ), - ( - "dof_file", - specs.File, - {"help_string": "degrees of freedom", "callable": FILMGLS_output}, - ), - ( - "sigmasquareds", - specs.File, - { - "help_string": "summary of residuals, See Woolrich, et. al., 2001", - "callable": FILMGLS_output, - }, - ), - ( - "thresholdac", - specs.File, - { - "help_string": "The FILM autocorrelation parameters", - "callable": FILMGLS_output, - }, - ), - ( - "logfile", - specs.File, - {"help_string": "FILM run logfile", "callable": FILMGLS_output}, - ), - ( - "copes", - specs.MultiOutputFile, - { - "help_string": "Contrast estimates for each contrast", - "requires": ["tcon_file"], - "callable": FILMGLS_output, - }, - ), - ( - "varcopes", - specs.MultiOutputFile, - { - "help_string": "Variance estimates for each contrast", - "requires": ["tcon_file"], - "callable": FILMGLS_output, - }, - ), - ( - "zstats", - specs.MultiOutputFile, - { - "help_string": "z-stat file for each contrast", - "requires": ["tcon_file"], - "callable": FILMGLS_output, - }, - ), - ( - "tstats", - specs.MultiOutputFile, - { - "help_string": "t-stat file for each contrast", - "requires": ["tcon_file"], - "callable": FILMGLS_output, - }, - ), - ( - "fstats", - specs.MultiOutputFile, - { - "help_string": "f-stat file for each contrast", - "requires": ["fcon_file"], - "callable": FILMGLS_output, - }, - ), - ( - "zfstats", - specs.MultiOutputFile, - { - "help_string": "z-stat file for each F contrast", - "requires": ["fcon_file"], - "callable": FILMGLS_output, - }, - ), -] -FILMGLS_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class FILMGLS(ShellCommandTask): - """ - Example - ------- - >>> task = FILMGLS() - >>> task.inputs.in_file = "test_film_gls.nii.gz" - >>> task.inputs.design_file = "design_film_gls.mat" - >>> task.inputs.threshold = 10 - >>> task.inputs.results_dir = "stats" - >>> task.cmdline - 'film_gls --rn=stats --in=test_film_gls.nii.gz --pd=design_film_gls.mat --thr=10' - """ - - input_spec = FILMGLS_input_spec - output_spec = FILMGLS_output_spec - executable = "film_gls" diff --git a/pydra/tasks/fsl/model/flameo.py b/pydra/tasks/fsl/model/flameo.py deleted file mode 100644 index f5bb54d..0000000 --- a/pydra/tasks/fsl/model/flameo.py +++ /dev/null @@ -1,336 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def FLAMEO_output(field, inputs): - import os, glob, attr - - def human_order_sorted(l): - """ - Sorts string in human order (i.e. 'stat10' will go after 'stat2') - """ - - def atoi(text): - return int(text) if text.isdigit() else text - - def natural_keys(text): - import re - - if isinstance(text, tuple): - text = text[0] - return [atoi(c) for c in re.split(r"(\d+)", text)] - - return sorted(l, key=natural_keys) - - pth = inputs.log_dir - name = field.name - - if name == "pes": - pes = human_order_sorted(glob.glob(os.path.join(pth, "pe[0-9]*.*"))) - if len(pes) >= 1: - return pes - elif name == "res4d": - res4d = human_order_sorted(glob.glob(os.path.join(pth, "res4d.*"))) - if len(res4d) == 1: - return res4d[0] - elif name == "copes": - copes = human_order_sorted(glob.glob(os.path.join(pth, "cope[0-9]*.*"))) - if len(copes) >= 1: - return copes - elif name == "var_copes": - var_copes = human_order_sorted(glob.glob(os.path.join(pth, "varcope[0-9]*.*"))) - if len(var_copes) >= 1: - return var_copes - elif name == "zstats": - zstats = human_order_sorted(glob.glob(os.path.join(pth, "zstat[0-9]*.*"))) - if len(zstats) >= 1: - return zstats - elif name == "tstats": - tstats = human_order_sorted(glob.glob(os.path.join(pth, "tstat[0-9]*.*"))) - if len(tstats) >= 1: - return tstats - elif name == "mrefvars": - mrefs = human_order_sorted(glob.glob(os.path.join(pth, "mean_random_effects_var[0-9]*.*"))) - if len(mrefs) >= 1: - return mrefs - elif name == "tdof": - tdof = human_order_sorted(glob.glob(os.path.join(pth, "tdof_t[0-9]*.*"))) - if len(tdof) >= 1: - return tdof - elif name == "weights": - weights = human_order_sorted(glob.glob(os.path.join(pth, "weights[0-9]*.*"))) - if len(weights) >= 1: - return weights - elif name == "stats_dir": - return pth - elif inputs.f_con_file not in [None, attr.NOTHING]: - if name == "zfstats": - zfstats = human_order_sorted(glob.glob(os.path.join(pth, "zfstat[0-9]*.*"))) - if len(zfstats) >= 1: - return zfstats - elif name == "fstats": - fstats = human_order_sorted(glob.glob(os.path.join(pth, "fstat[0-9]*.*"))) - if len(fstats) >= 1: - return fstats - else: - raise Exception( - f"this function should be run only for pes, res4d, copes, var_copes, zfstats," - f"fstats, zstats, tstats, mrefs, tdof, weights, or stats_dir, not for {name}" - ) - - -input_fields = [ - ( - "cope_file", - specs.File, - { - "help_string": "cope regressor data file", - "argstr": "--copefile={cope_file}", - "mandatory": True, - }, - ), - ( - "var_cope_file", - specs.File, - { - "help_string": "varcope weightings data file", - "argstr": "--varcopefile={var_cope_file}", - }, - ), - ( - "dof_var_cope_file", - specs.File, - { - "help_string": "dof data file for varcope data", - "argstr": "--dofvarcopefile={dof_var_cope_file}", - }, - ), - ( - "mask_file", - specs.File, - { - "help_string": "mask file", - "argstr": "--maskfile={mask_file}", - "mandatory": True, - }, - ), - ( - "design_file", - specs.File, - { - "help_string": "design matrix file", - "argstr": "--designfile={design_file}", - "mandatory": True, - }, - ), - ( - "t_con_file", - specs.File, - { - "help_string": "ascii matrix specifying t-contrasts", - "argstr": "--tcontrastsfile={t_con_file}", - "mandatory": True, - }, - ), - ( - "f_con_file", - specs.File, - { - "help_string": "ascii matrix specifying f-contrasts", - "argstr": "--fcontrastsfile={f_con_file}", - }, - ), - ( - "cov_split_file", - specs.File, - { - "help_string": "ascii matrix specifying the groups the covariance is split into", - "argstr": "--covsplitfile={cov_split_file}", - "mandatory": True, - }, - ), - ( - "run_mode", - ty.Any, - { - "help_string": "inference to perform", - "argstr": "--runmode={run_mode}", - "mandatory": True, - }, - ), - ( - "n_jumps", - int, - {"help_string": "number of jumps made by mcmc", "argstr": "--njumps={n_jumps}"}, - ), - ( - "burnin", - int, - { - "help_string": "number of jumps at start of mcmc to be discarded", - "argstr": "--burnin={burnin}", - }, - ), - ( - "sample_every", - int, - { - "help_string": "number of jumps for each sample", - "argstr": "--sampleevery={sample_every}", - }, - ), - ("fix_mean", bool, {"help_string": "fix mean for tfit", "argstr": "--fixmean"}), - ( - "infer_outliers", - bool, - {"help_string": "infer outliers - not for fe", "argstr": "--inferoutliers"}, - ), - ( - "no_pe_outputs", - bool, - {"help_string": "do not output pe files", "argstr": "--nopeoutput"}, - ), - ( - "sigma_dofs", - int, - { - "help_string": "sigma (in mm) to use for Gaussian smoothing the DOFs in FLAME 2. Default is 1mm, -1 indicates no smoothing", - "argstr": "--sigma_dofs={sigma_dofs}", - }, - ), - ( - "outlier_iter", - int, - { - "help_string": "Number of max iterations to use when inferring outliers. Default is 12.", - "argstr": "--ioni={outlier_iter}", - }, - ), - ("log_dir", ty.Any, "stats", {"help_string": "", "argstr": "--ld={log_dir}"}), -] -FLAMEO_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "pes", - specs.MultiOutputFile, - { - "help_string": "Parameter estimates for each column of the design matrix for each voxel", - "callable": FLAMEO_output, - }, - ), - ( - "res4d", - specs.MultiOutputFile, - { - "help_string": "Model fit residual mean-squared error for each time point", - "callable": FLAMEO_output, - }, - ), - ( - "copes", - specs.MultiOutputFile, - { - "help_string": "Contrast estimates for each contrast", - "callable": FLAMEO_output, - }, - ), - ( - "var_copes", - specs.MultiOutputFile, - { - "help_string": "Variance estimates for each contrast", - "callable": FLAMEO_output, - }, - ), - ( - "zstats", - specs.MultiOutputFile, - { - "help_string": "z-stat file for each contrast", - "requires": ["t_con_file"], - "callable": FLAMEO_output, - }, - ), - ( - "tstats", - specs.MultiOutputFile, - { - "help_string": "t-stat file for each contrast", - "requires": ["t_con_file"], - "callable": FLAMEO_output, - }, - ), - ( - "zfstats", - specs.MultiOutputFile, - { - "help_string": "z stat file for each f contrast", - "requires": ["f_con_file"], - "callable": FLAMEO_output, - }, - ), - ( - "fstats", - specs.MultiOutputFile, - { - "help_string": "f-stat file for each contrast", - "requires": ["f_con_file"], - "callable": FLAMEO_output, - }, - ), - ( - "mrefvars", - specs.MultiOutputFile, - { - "help_string": "mean random effect variances for each contrast", - "callable": FLAMEO_output, - }, - ), - ( - "tdof", - specs.MultiOutputFile, - { - "help_string": "temporal dof file for each contrast", - "callable": FLAMEO_output, - }, - ), - ( - "weights", - specs.MultiOutputFile, - {"help_string": "weights file for each contrast", "callable": FLAMEO_output}, - ), - ( - "stats_dir", - specs.Directory, - { - "help_string": "directory storing model estimation output", - "callable": FLAMEO_output, - }, - ), -] -FLAMEO_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class FLAMEO(ShellCommandTask): - """ - Example - ------- - >>> task = FLAMEO() - >>> task.inputs.cope_file = "cope_merged.nii.gz" - >>> task.inputs.var_cope_file = "varcope_merged.nii.gz" - >>> task.inputs.cov_split_file = "design.grp" - >>> task.inputs.design_file = "design.mat" - >>> task.inputs.t_con_file = "design.con" - >>> task.inputs.mask_file = "mask.nii.gz" - >>> task.inputs.run_mode = "fe" - >>> task.cmdline - 'flameo --copefile=cope_merged.nii.gz --varcopefile=varcope_merged.nii.gz --maskfile=mask.nii.gz --designfile=design.mat --tcontrastsfile=design.con --covsplitfile=design.grp --runmode=fe --ld=stats' - """ - - input_spec = FLAMEO_input_spec - output_spec = FLAMEO_output_spec - executable = "flameo" diff --git a/pydra/tasks/fsl/model/glm.py b/pydra/tasks/fsl/model/glm.py deleted file mode 100644 index 7d42391..0000000 --- a/pydra/tasks/fsl/model/glm.py +++ /dev/null @@ -1,194 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input file name (text matrix or 3D/4D image file)", - "argstr": "-i {in_file}", - "mandatory": True, - "position": 1, - }, - ), - ( - "out_file", - str, - { - "help_string": "filename for GLM parameter estimates (GLM betas)", - "argstr": "-o {out_file}", - "position": 3, - "output_file_template": "{in_file}_glm", - }, - ), - ( - "design", - specs.File, - { - "help_string": "file name of the GLM design matrix (text time courses for temporal regression or an image file for spatial regression)", - "argstr": "-d {design}", - "mandatory": True, - "position": 2, - }, - ), - ( - "contrasts", - specs.File, - {"help_string": "matrix of t-statics contrasts", "argstr": "-c {contrasts}"}, - ), - ( - "mask", - specs.File, - { - "help_string": "mask image file name if input is image", - "argstr": "-m {mask}", - }, - ), - ( - "dof", - int, - {"help_string": "set degrees of freedom explicitly", "argstr": "--dof={dof}"}, - ), - ( - "des_norm", - bool, - { - "help_string": "switch on normalization of the design matrix columns to unit std deviation", - "argstr": "--des_norm", - }, - ), - ( - "dat_norm", - bool, - { - "help_string": "switch on normalization of the data time series to unit std deviation", - "argstr": "--dat_norm", - }, - ), - ( - "var_norm", - bool, - { - "help_string": "perform MELODIC variance-normalisation on data", - "argstr": "--vn", - }, - ), - ( - "demean", - bool, - { - "help_string": "switch on demeaining of design and data", - "argstr": "--demean", - }, - ), - ( - "out_cope", - str, - { - "help_string": "output file name for COPE (either as txt or image", - "argstr": "--out_cope={out_cope}", - }, - ), - ( - "out_z_name", - str, - { - "help_string": "output file name for Z-stats (either as txt or image", - "argstr": "--out_z={out_z_name}", - }, - ), - ( - "out_t_name", - str, - { - "help_string": "output file name for t-stats (either as txt or image", - "argstr": "--out_t={out_t_name}", - }, - ), - ( - "out_p_name", - str, - { - "help_string": "output file name for p-values of Z-stats (either as text file or image)", - "argstr": "--out_p={out_p_name}", - }, - ), - ( - "out_f_name", - str, - { - "help_string": "output file name for F-value of full model fit", - "argstr": "--out_f={out_f_name}", - }, - ), - ( - "out_pf_name", - str, - { - "help_string": "output file name for p-value for full model fit", - "argstr": "--out_pf={out_pf_name}", - }, - ), - ( - "out_res_name", - str, - { - "help_string": "output file name for residuals", - "argstr": "--out_res={out_res_name}", - }, - ), - ( - "out_varcb_name", - str, - { - "help_string": "output file name for variance of COPEs", - "argstr": "--out_varcb={out_varcb_name}", - }, - ), - ( - "out_sigsq_name", - str, - { - "help_string": "output file name for residual noise variance sigma-square", - "argstr": "--out_sigsq={out_sigsq_name}", - }, - ), - ( - "out_data_name", - str, - { - "help_string": "output file name for pre-processed data", - "argstr": "--out_data={out_data_name}", - }, - ), - ( - "out_vnscales_name", - str, - { - "help_string": "output file name for scaling factors for variance normalisation", - "argstr": "--out_vnscales={out_vnscales_name}", - }, - ), -] -GLM_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -GLM_output_spec = specs.SpecInfo(name="Output", fields=output_fields, bases=(specs.ShellOutSpec,)) - - -class GLM(ShellCommandTask): - """ - Example - ------- - >>> task = GLM() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.design = "confounds_regressors.tsv" - >>> task.cmdline # doctest: +SKIP - 'fsl_glm -i test.nii.gz -d confounds_regressors.tsv' - """ - - input_spec = GLM_input_spec - output_spec = GLM_output_spec - executable = "fsl_glm" diff --git a/pydra/tasks/fsl/model/melodic.py b/pydra/tasks/fsl/model/melodic.py deleted file mode 100644 index 5cecdb3..0000000 --- a/pydra/tasks/fsl/model/melodic.py +++ /dev/null @@ -1,356 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def MELODIC_output(field, inputs): - import os, attr - - name = field.name - if name == "out_dir": - if inputs.out_dir not in [None, attr.NOTHING]: - outputs = inputs.out_dir - else: - outputs = os.getcwd() - elif name == "report_dir": - if inputs.report not in [None, attr.NOTHING]: - if inputs.out_dir not in [None, attr.NOTHING]: - out_dir = inputs.out_dir - else: - out_dir = os.getcwd() - outputs = os.path.join(out_dir, "report") - return outputs - - -input_fields = [ - ( - "in_files", - specs.MultiInputFile, - { - "help_string": "input file names (either single file name or a list)", - "argstr": "-i {in_files}", - "mandatory": True, - "position": 0, - "sep": ",", - }, - ), - ( - "out_dir", - ty.Any, - {"help_string": "output directory name", "argstr": "-o {out_dir}"}, - ), - ( - "mask", - specs.File, - {"help_string": "file name of mask for thresholding", "argstr": "-m {mask}"}, - ), - ("no_mask", bool, {"help_string": "switch off masking", "argstr": "--nomask"}), - ( - "update_mask", - bool, - {"help_string": "switch off mask updating", "argstr": "--update_mask"}, - ), - ("no_bet", bool, {"help_string": "switch off BET", "argstr": "--nobet"}), - ( - "bg_threshold", - float, - { - "help_string": "brain/non-brain threshold used to mask non-brain voxels, as a percentage (only if --nobet selected)", - "argstr": "--bgthreshold={bg_threshold}", - }, - ), - ( - "dim", - int, - { - "help_string": "dimensionality reduction into #num dimensions (default: automatic estimation)", - "argstr": "-d {dim}", - }, - ), - ( - "dim_est", - str, - { - "help_string": "use specific dim. estimation technique: lap, bic, mdl, aic, mean (default: lap)", - "argstr": "--dimest={dim_est}", - }, - ), - ( - "sep_whiten", - bool, - {"help_string": "switch on separate whitening", "argstr": "--sep_whiten"}, - ), - ( - "sep_vn", - bool, - { - "help_string": "switch off joined variance normalization", - "argstr": "--sep_vn", - }, - ), - ( - "migp", - bool, - {"help_string": "switch on MIGP data reduction", "argstr": "--migp"}, - ), - ( - "migpN", - int, - {"help_string": "number of internal Eigenmaps", "argstr": "--migpN {migpN}"}, - ), - ( - "migp_shuffle", - bool, - { - "help_string": "randomise MIGP file order (default: TRUE)", - "argstr": "--migp_shuffle", - }, - ), - ( - "migp_factor", - int, - { - "help_string": "Internal Factor of mem-threshold relative to number of Eigenmaps (default: 2)", - "argstr": "--migp_factor {migp_factor}", - }, - ), - ( - "num_ICs", - int, - { - "help_string": "number of IC's to extract (for deflation approach)", - "argstr": "-n {num_ICs}", - }, - ), - ( - "approach", - str, - { - "help_string": "approach for decomposition, 2D: defl, symm (default), 3D: tica (default), concat", - "argstr": "-a {approach}", - }, - ), - ( - "non_linearity", - str, - { - "help_string": "nonlinearity: gauss, tanh, pow3, pow4", - "argstr": "--nl={non_linearity}", - }, - ), - ( - "var_norm", - bool, - {"help_string": "switch off variance normalization", "argstr": "--vn"}, - ), - ( - "pbsc", - bool, - { - "help_string": "switch off conversion to percent BOLD signal change", - "argstr": "--pbsc", - }, - ), - ( - "cov_weight", - float, - { - "help_string": "voxel-wise weights for the covariance matrix (e.g. segmentation information)", - "argstr": "--covarweight={cov_weight}", - }, - ), - ( - "epsilon", - float, - {"help_string": "minimum error change", "argstr": "--eps={epsilon}"}, - ), - ( - "epsilonS", - float, - { - "help_string": "minimum error change for rank-1 approximation in TICA", - "argstr": "--epsS={epsilonS}", - }, - ), - ( - "maxit", - int, - { - "help_string": "maximum number of iterations before restart", - "argstr": "--maxit={maxit}", - }, - ), - ( - "max_restart", - int, - { - "help_string": "maximum number of restarts", - "argstr": "--maxrestart={max_restart}", - }, - ), - ( - "mm_thresh", - float, - { - "help_string": "threshold for Mixture Model based inference", - "argstr": "--mmthresh={mm_thresh}", - }, - ), - ( - "no_mm", - bool, - {"help_string": "switch off mixture modelling on IC maps", "argstr": "--no_mm"}, - ), - ( - "ICs", - specs.File, - { - "help_string": "filename of the IC components file for mixture modelling", - "argstr": "--ICs={ICs}", - }, - ), - ( - "mix", - specs.File, - { - "help_string": "mixing matrix for mixture modelling / filtering", - "argstr": "--mix={mix}", - }, - ), - ( - "smode", - specs.File, - { - "help_string": "matrix of session modes for report generation", - "argstr": "--smode={smode}", - }, - ), - ( - "rem_cmp", - list, - {"help_string": "component numbers to remove", "argstr": "-f {rem_cmp}"}, - ), - ( - "report", - bool, - {"help_string": "generate Melodic web report", "argstr": "--report"}, - ), - ( - "bg_image", - specs.File, - { - "help_string": "specify background image for report (default: mean image)", - "argstr": "--bgimage={bg_image}", - }, - ), - ("tr_sec", float, {"help_string": "TR in seconds", "argstr": "--tr={tr_sec}"}), - ( - "log_power", - bool, - { - "help_string": "calculate log of power for frequency spectrum", - "argstr": "--logPower", - }, - ), - ( - "t_des", - specs.File, - {"help_string": "design matrix across time-domain", "argstr": "--Tdes={t_des}"}, - ), - ( - "t_con", - specs.File, - { - "help_string": "t-contrast matrix across time-domain", - "argstr": "--Tcon={t_con}", - }, - ), - ( - "s_des", - specs.File, - { - "help_string": "design matrix across subject-domain", - "argstr": "--Sdes={s_des}", - }, - ), - ( - "s_con", - specs.File, - { - "help_string": "t-contrast matrix across subject-domain", - "argstr": "--Scon={s_con}", - }, - ), - ("out_all", bool, {"help_string": "output everything", "argstr": "--Oall"}), - ( - "out_unmix", - bool, - {"help_string": "output unmixing matrix", "argstr": "--Ounmix"}, - ), - ( - "out_stats", - bool, - { - "help_string": "output thresholded maps and probability maps", - "argstr": "--Ostats", - }, - ), - ("out_pca", bool, {"help_string": "output PCA results", "argstr": "--Opca"}), - ( - "out_white", - bool, - {"help_string": "output whitening/dewhitening matrices", "argstr": "--Owhite"}, - ), - ("out_orig", bool, {"help_string": "output the original ICs", "argstr": "--Oorig"}), - ("out_mean", bool, {"help_string": "output mean volume", "argstr": "--Omean"}), - ( - "report_maps", - str, - { - "help_string": "control string for spatial map images (see slicer)", - "argstr": "--report_maps={report_maps}", - }, - ), - ( - "remove_deriv", - bool, - { - "help_string": "removes every second entry in paradigm file (EV derivatives)", - "argstr": "--remove_deriv", - }, - ), -] -MELODIC_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ("out_dir", specs.Directory, {"callable": MELODIC_output}), - ("report_dir", specs.Directory, {"callable": MELODIC_output}), -] -MELODIC_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class MELODIC(ShellCommandTask): - """ - Example - ------- - >>> task = MELODIC() - >>> task.inputs.approach = "tica" - >>> task.inputs.in_files = ['test.nii', 'test2.nii', 'test3.nii'] - >>> task.inputs.no_bet = True - >>> task.inputs.bg_threshold = 10 - >>> task.inputs.tr_sec = 1.5 - >>> task.inputs.out_stats = True - >>> task.inputs.t_des = "timeDesign.mat" - >>> task.inputs.t_con = "timeDesign.con" - >>> task.inputs.s_des = "subjectDesign.mat" - >>> task.inputs.s_con = "subjectDesign.con" - >>> task.inputs.out_dir = "groupICA.out" - >>> task.cmdline - 'melodic -i test.nii,test2.nii,test3.nii -o groupICA.out --nobet --bgthreshold=10 -a tica --tr=1.5 --Tdes=timeDesign.mat --Tcon=timeDesign.con --Sdes=subjectDesign.mat --Scon=subjectDesign.con --Ostats' - """ - - input_spec = MELODIC_input_spec - output_spec = MELODIC_output_spec - executable = "melodic" diff --git a/pydra/tasks/fsl/model/tests/__init__.py b/pydra/tasks/fsl/model/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/model/tests/test_run_cluster.py b/pydra/tasks/fsl/model/tests/test_run_cluster.py deleted file mode 100644 index 5543fdc..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_cluster.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..cluster import Cluster - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "in_file": "zstat1.nii.gz", - "threshold": 2.3, - "use_mm": True, - "out_index_file": True, - }, - [ - "out_index_file", - "out_localmax_txt_file", - "out_localmax_vol_file", - "out_threshold_file", - "out_max_file", - "out_mean_file", - "out_pval_file", - "out_size_file", - "out_threshold_file", - ], - ) - ], -) -def test_Cluster(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Cluster(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Cluster(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/model/tests/test_run_feat.py b/pydra/tasks/fsl/model/tests/test_run_feat.py deleted file mode 100644 index abcf1e5..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_feat.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..feat import FEAT - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_FEAT(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEAT(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEAT(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FEAT_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEAT(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEAT(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/model/tests/test_run_featmodel.py b/pydra/tasks/fsl/model/tests/test_run_featmodel.py deleted file mode 100644 index 1ec43ca..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_featmodel.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..featmodel import FEATModel - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_FEATModel(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEATModel(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEATModel(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FEATModel_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEATModel(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEATModel(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/model/tests/test_run_filmgls.py b/pydra/tasks/fsl/model/tests/test_run_filmgls.py deleted file mode 100644 index ed5d1ff..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_filmgls.py +++ /dev/null @@ -1,62 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..filmgls import FILMGLS - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "in_file": "test_film_gls.nii.gz", - "design_file": "design_film_gls.mat", - "threshold": 10, - "results_dir": "stats", - }, - [ - "dof_file", - "logfile", - "param_estimates", - "residual4d", - "results_dir", - "sigmasquareds", - "thresholdac", - ], - ) - ], -) -def test_FILMGLS(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FILMGLS(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FILMGLS(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/model/tests/test_run_flameo.py b/pydra/tasks/fsl/model/tests/test_run_flameo.py deleted file mode 100644 index c7e11d9..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_flameo.py +++ /dev/null @@ -1,69 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..flameo import FLAMEO - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "cope_file": "cope_merged.nii.gz", - "var_cope_file": "varcope_merged.nii.gz", - "cov_split_file": "design.grp", - "design_file": "design.mat", - "t_con_file": "design.con", - "mask_file": "mask.nii.gz", - "run_mode": "fe", - "log_dir": "stats", - }, - [ - "copes", - "var_copes", - "mrefvars", - "pes", - "res4d", - "tdof", - "weights", - "tstats", - "zstats", - "stats_dir", - ], - ) - ], -) -def test_FLAMEO(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FLAMEO(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FLAMEO(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/model/tests/test_run_glm.py b/pydra/tasks/fsl/model/tests/test_run_glm.py deleted file mode 100644 index 49b585e..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_glm.py +++ /dev/null @@ -1,44 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..glm import GLM - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [({"in_file": "test.nii.gz", "design": "confounds_regressors.tsv"}, ["out_file"])], -) -def test_GLM(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = GLM(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = GLM(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/model/tests/test_run_melodic.py b/pydra/tasks/fsl/model/tests/test_run_melodic.py deleted file mode 100644 index a5b333c..0000000 --- a/pydra/tasks/fsl/model/tests/test_run_melodic.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..melodic import MELODIC - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_MELODIC(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = MELODIC(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = MELODIC(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_MELODIC_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = MELODIC(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = MELODIC(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/model/tests/test_spec_cluster.py b/pydra/tasks/fsl/model/tests/test_spec_cluster.py deleted file mode 100644 index 2ed7387..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_cluster.py +++ /dev/null @@ -1,51 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..cluster import Cluster - - -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - {"in_file": "zstat1.nii.gz", "threshold": 2.3, "use_mm": True, "out_index_file": True}, - [ - "out_index_file", - "out_localmax_txt_file", - "out_localmax_vol_file", - "out_threshold_file", - "out_max_file", - "out_mean_file", - "out_pval_file", - "out_size_file", - "out_threshold_file", - ], - ) - ], -) -def test_Cluster(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Cluster(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Cluster(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/model/tests/test_spec_feat.py b/pydra/tasks/fsl/model/tests/test_spec_feat.py deleted file mode 100644 index 403f6e2..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_feat.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..feat import FEAT - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_FEAT(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEAT(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEAT(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FEAT_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEAT(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEAT(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/model/tests/test_spec_featmodel.py b/pydra/tasks/fsl/model/tests/test_spec_featmodel.py deleted file mode 100644 index aead2e6..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_featmodel.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..featmodel import FEATModel - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_FEATModel(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEATModel(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEATModel(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FEATModel_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FEATModel(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FEATModel(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/model/tests/test_spec_filmgls.py b/pydra/tasks/fsl/model/tests/test_spec_filmgls.py deleted file mode 100644 index 08f56db..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_filmgls.py +++ /dev/null @@ -1,54 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..filmgls import FILMGLS - - -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "in_file": "test_film_gls.nii.gz", - "design_file": "design_film_gls.mat", - "threshold": 10, - "results_dir": "stats", - }, - [ - "dof_file", - "logfile", - "param_estimates", - "residual4d", - "results_dir", - "sigmasquareds", - "thresholdac", - ], - ) - ], -) -def test_FILMGLS(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FILMGLS(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FILMGLS(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/model/tests/test_spec_flameo.py b/pydra/tasks/fsl/model/tests/test_spec_flameo.py deleted file mode 100644 index 0186889..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_flameo.py +++ /dev/null @@ -1,61 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..flameo import FLAMEO - - -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "cope_file": "cope_merged.nii.gz", - "var_cope_file": "varcope_merged.nii.gz", - "cov_split_file": "design.grp", - "design_file": "design.mat", - "t_con_file": "design.con", - "mask_file": "mask.nii.gz", - "run_mode": "fe", - "log_dir": "stats", - }, - [ - "copes", - "var_copes", - "mrefvars", - "pes", - "res4d", - "tdof", - "weights", - "tstats", - "zstats", - "stats_dir", - ], - ) - ], -) -def test_FLAMEO(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FLAMEO(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FLAMEO(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/model/tests/test_spec_glm.py b/pydra/tasks/fsl/model/tests/test_spec_glm.py deleted file mode 100644 index 6ac9d78..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_glm.py +++ /dev/null @@ -1,36 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..glm import GLM - - -@pytest.mark.parametrize( - "inputs, outputs", - [({"in_file": "test.nii.gz", "design": "confounds_regressors.tsv"}, ["out_file"])], -) -def test_GLM(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = GLM(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = GLM(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/model/tests/test_spec_melodic.py b/pydra/tasks/fsl/model/tests/test_spec_melodic.py deleted file mode 100644 index e6aa73a..0000000 --- a/pydra/tasks/fsl/model/tests/test_spec_melodic.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..melodic import MELODIC - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_MELODIC(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = MELODIC(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = MELODIC(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_MELODIC_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = MELODIC(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = MELODIC(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/__init__.py b/pydra/tasks/fsl/preprocess/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/preprocess/applywarp.py b/pydra/tasks/fsl/preprocess/applywarp.py deleted file mode 100644 index 6480289..0000000 --- a/pydra/tasks/fsl/preprocess/applywarp.py +++ /dev/null @@ -1,129 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "image to be warped", - "argstr": "--in={in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "out_file", - str, - { - "help_string": "output filename", - "argstr": "--out={out_file}", - "position": 2, - "output_file_template": "{in_file}_warp", - }, - ), - ( - "ref_file", - specs.File, - { - "help_string": "reference image", - "argstr": "--ref={ref_file}", - "mandatory": True, - "position": 1, - }, - ), - ( - "field_file", - specs.File, - {"help_string": "file containing warp field", "argstr": "--warp={field_file}"}, - ), - ( - "abswarp", - bool, - { - "help_string": "treat warp field as absolute: x' = w(x)", - "argstr": "--abs", - "xor": ["relwarp"], - }, - ), - ( - "relwarp", - bool, - { - "help_string": "treat warp field as relative: x' = x + w(x)", - "argstr": "--rel", - "position": -1, - "xor": ["abswarp"], - }, - ), - ( - "datatype", - ty.Any, - { - "help_string": "Force output data type [char short int float double].", - "argstr": "--datatype={datatype}", - }, - ), - ( - "supersample", - bool, - { - "help_string": "intermediary supersampling of output, default is off", - "argstr": "--super", - }, - ), - ( - "superlevel", - ty.Any, - { - "help_string": "level of intermediary supersampling, a for 'automatic' or integer level. Default = 2", - "argstr": "--superlevel={superlevel}", - }, - ), - ( - "premat", - specs.File, - { - "help_string": "filename for pre-transform (affine matrix)", - "argstr": "--premat={premat}", - }, - ), - ( - "postmat", - specs.File, - { - "help_string": "filename for post-transform (affine matrix)", - "argstr": "--postmat={postmat}", - }, - ), - ( - "mask_file", - specs.File, - { - "help_string": "filename for mask image (in reference space)", - "argstr": "--mask={mask_file}", - }, - ), - ( - "interp", - ty.Any, - { - "help_string": "interpolation method", - "argstr": "--interp={interp}", - "position": -2, - }, - ), -] -ApplyWarp_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -ApplyWarp_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ApplyWarp(ShellCommandTask): - input_spec = ApplyWarp_input_spec - output_spec = ApplyWarp_output_spec - executable = "applywarp" diff --git a/pydra/tasks/fsl/preprocess/bet.py b/pydra/tasks/fsl/preprocess/bet.py deleted file mode 100644 index 2674cc2..0000000 --- a/pydra/tasks/fsl/preprocess/bet.py +++ /dev/null @@ -1,306 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input file to skull strip", - "argstr": "{in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "out_file", - str, - { - "help_string": "name of output skull stripped image", - "argstr": "{out_file}", - "position": 1, - "output_file_template": "{in_file}_brain", - }, - ), - ("outline", bool, {"help_string": "create surface outline image", "argstr": "-o"}), - ("mask", bool, {"help_string": "create binary mask image", "argstr": "-m"}), - ("skull", bool, {"help_string": "create skull image", "argstr": "-s"}), - ( - "no_output", - bool, - {"help_string": "Don't generate segmented output", "argstr": "-n"}, - ), - ( - "frac", - float, - {"help_string": "fractional intensity threshold", "argstr": "-f {frac:.2f}"}, - ), - ( - "vertical_gradient", - float, - { - "help_string": "vertical gradient in fractional intensity threshold (-1, 1)", - "argstr": "-g {vertical_gradient:.2f}", - }, - ), - ("radius", int, {"help_string": "head radius", "argstr": "-r {radius}"}), - ( - "center", - list, - {"help_string": "center of gravity in voxels", "argstr": "-c {center}"}, - ), - ( - "threshold", - bool, - { - "help_string": "apply thresholding to segmented brain image and mask", - "argstr": "-t", - }, - ), - ( - "mesh", - bool, - {"help_string": "generate a vtk mesh brain surface", "argstr": "-e"}, - ), - ( - "robust", - bool, - { - "help_string": "robust brain centre estimation (iterates BET several times)", - "argstr": "-R", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), - ( - "padding", - bool, - { - "help_string": "improve BET if FOV is very small in Z (by temporarily padding end slices)", - "argstr": "-Z", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), - ( - "remove_eyes", - bool, - { - "help_string": "eye & optic nerve cleanup (can be useful in SIENA)", - "argstr": "-S", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), - ( - "surfaces", - bool, - { - "help_string": "run bet2 and then betsurf to get additional skull and scalp surfaces (includes registrations)", - "argstr": "-A", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), - ( - "t2_guided", - str, - { - "help_string": "as with creating surfaces, when also feeding in non-brain-extracted T2 (includes registrations)", - "argstr": "-A2 {t2_guided}", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), - ( - "functional", - bool, - { - "help_string": "apply to 4D fMRI data", - "argstr": "-F", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), - ( - "reduce_bias", - bool, - { - "help_string": "bias field and neck cleanup", - "argstr": "-B", - "xor": ( - "functional", - "reduce_bias", - "robust", - "padding", - "remove_eyes", - "surfaces", - "t2_guided", - ), - }, - ), -] -BET_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "mask_file", - specs.File, - { - "help_string": "path/name of binary brain mask (if generated)", - "requires": [[("mask", True)], [("reduce_bias", True)]], - "output_file_template": "{out_file}_mask", - }, - ), - ( - "outline_file", - specs.File, - { - "help_string": "path/name of outline file (if generated)", - "requires": [("outline", True)], - "output_file_template": "{out_file}_overlay", - }, - ), - ( - "meshfile", - specs.File, - { - "help_string": "path/name of vtk mesh file (if generated)", - "requires": [[("mesh", True)], [("surfaces", True)]], - "output_file_template": "{out_file}_mesh.vtk", - }, - ), - ( - "inskull_mask_file", - specs.File, - { - "help_string": "path/name of inskull mask (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_inskull_mask", - }, - ), - ( - "inskull_mesh_file", - specs.File, - { - "help_string": "path/name of inskull mesh outline (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_inskull_mesh", - }, - ), - ( - "outskull_mask_file", - specs.File, - { - "help_string": "path/name of outskull mask (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_outskull_mask", - }, - ), - ( - "outskull_mesh_file", - specs.File, - { - "help_string": "path/name of outskull mesh outline (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_outskull_mesh", - }, - ), - ( - "outskin_mask_file", - specs.File, - { - "help_string": "path/name of outskin mask (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_outskin_mask", - }, - ), - ( - "outskin_mesh_file", - specs.File, - { - "help_string": "path/name of outskin mesh outline (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_outskin_mesh", - }, - ), - ( - "skull_mask_file", - specs.File, - { - "help_string": "path/name of skull mask (if generated)", - "requires": [("surfaces", True)], - "output_file_template": "{out_file}_skull_mask", - }, - ), - ( - "skull_file", - specs.File, - { - "help_string": "path/name of skull file (if generated)", - "requires": [("skull", True)], - "output_file_template": "{out_file}_skull", - }, - ), -] -BET_output_spec = specs.SpecInfo(name="Output", fields=output_fields, bases=(specs.ShellOutSpec,)) - - -class BET(ShellCommandTask): - """ - Example - ------- - >>> task = BET() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.out_file = "test_brain.nii.gz" - >>> task.inputs.frac = 0.7 - >>> task.cmdline - 'bet test.nii.gz test_brain.nii.gz -f 0.70' - """ - - input_spec = BET_input_spec - output_spec = BET_output_spec - executable = "bet" diff --git a/pydra/tasks/fsl/preprocess/fast.py b/pydra/tasks/fsl/preprocess/fast.py deleted file mode 100644 index 732fbc2..0000000 --- a/pydra/tasks/fsl/preprocess/fast.py +++ /dev/null @@ -1,280 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def FAST_output(field, in_files, out_basename): - import attr - - if out_basename in [None, attr.NOTHING]: - out_basename = in_files[-1] - name = field.name - if name == "tissue_class_map": - return f"{out_basename}_seg" - elif name == "mixeltype": - return f"{out_basename}_mixeltype" - elif name == "partial_volume_map": - return f"{out_basename}_pveseg" - else: - raise Exception( - f"this function should be run only for issue_class_map, " - f"or mixeltype, not for {name}" - ) - - outputs = [] - if len(in_files) > 1: - # for multi-image segmentation there is one corrected image - # per input - for val, f in enumerate(in_files): - # image numbering is 1-based - outputs.append(f"{out_basename}_restore_{val+1}") - else: - # single image segmentation has unnumbered output image - outputs.append(f"{out_basename}_restore") - return outputs - - -def FAST_output_infile(field, in_files, out_basename): - import attr - - if out_basename in [None, attr.NOTHING]: - out_basename = in_files[-1] - name = field.name - if name == "restored_image": - suffix = "restore" - elif name == "bias_field": - suffix = "bias" - else: - raise Exception( - f"this function should be run only for restored_image, " - f"or bias_field, not for {name}" - ) - - outputs = [] - if len(in_files) > 1: - # for multi-image segmentation there is one corrected image - # per input - for val, f in enumerate(in_files): - # image numbering is 1-based - outputs.append(f"{out_basename}_{suffix}_{val+1}") - else: - # single image segmentation has unnumbered output image - outputs.append(f"{out_basename}_{suffix}") - return outputs - - -def FAST_output_nclass(field, in_files, nclasses, out_basename): - import attr - - if out_basename in [None, attr.NOTHING]: - out_basename = in_files[-1] - name = field.name - - if name == "tissue_class_files": - suffix = "seg" - elif name == "partial_volume_files": - suffix = "pve" - elif name == "probability_maps": - suffix = "prob" - else: - raise Exception( - f"this function should be run only for tissue_class_files, " - f"partial_volume_files or probability_maps, not for {name}" - ) - - outputs = [] - for ii in range(nclasses): - outputs.append(f"{out_basename}_{suffix}_{ii}") - return outputs - - -input_fields = [ - ( - "in_files", - specs.MultiInputFile, - { - "help_string": "image, or multi-channel set of images, to be segmented", - "argstr": "{in_files}", - "copyfile": False, - "mandatory": True, - "position": -1, - }, - ), - ( - "out_basename", - str, - {"help_string": "base name of output files", "argstr": "-o {out_basename}"}, - ), - ( - "number_classes", - ty.Any, - 3, - { - "help_string": "number of tissue-type classes", - "argstr": "-n {number_classes}", - }, - ), - ( - "output_biasfield", - bool, - {"help_string": "output estimated bias field", "argstr": "-b"}, - ), - ( - "output_biascorrected", - bool, - {"help_string": "output restored image (bias-corrected image)", "argstr": "-B"}, - ), - ( - "img_type", - ty.Any, - { - "help_string": "int specifying type of image: (1 = T1, 2 = T2, 3 = PD)", - "argstr": "-t {img_type}", - }, - ), - ( - "bias_iters", - ty.Any, - { - "help_string": "number of main-loop iterations during bias-field removal", - "argstr": "-I {bias_iters}", - }, - ), - ( - "bias_lowpass", - ty.Any, - { - "help_string": "bias field smoothing extent (FWHM) in mm", - "argstr": "-l {bias_lowpass}", - }, - ), - ( - "init_seg_smooth", - ty.Any, - { - "help_string": "initial segmentation spatial smoothness (during bias field estimation)", - "argstr": "-f {init_seg_smooth:.3f}", - }, - ), - ( - "segments", - bool, - { - "help_string": "outputs a separate binary image for each tissue type", - "argstr": "-g", - }, - ), - ( - "init_transform", - specs.File, - { - "help_string": " initialise using priors", - "argstr": "-a {init_transform}", - }, - ), - ( - "other_priors", - specs.MultiInputFile, - {"help_string": "alternative prior images", "argstr": "-A {other_priors}"}, - ), - ( - "no_pve", - bool, - { - "help_string": "turn off PVE (partial volume estimation)", - "argstr": "--nopve", - }, - ), - ("no_bias", bool, {"help_string": "do not remove bias field", "argstr": "-N"}), - ("use_priors", bool, {"help_string": "use priors throughout", "argstr": "-P"}), - ( - "segment_iters", - ty.Any, - { - "help_string": "number of segmentation-initialisation iterations", - "argstr": "-W {segment_iters}", - }, - ), - ( - "mixel_smooth", - ty.Any, - { - "help_string": "spatial smoothness for mixeltype", - "argstr": "-R {mixel_smooth:.2f}", - }, - ), - ( - "iters_afterbias", - ty.Any, - { - "help_string": "number of main-loop iterations after bias-field removal", - "argstr": "-O {iters_afterbias}", - }, - ), - ( - "hyper", - ty.Any, - {"help_string": "segmentation spatial smoothness", "argstr": "-H {hyper:.2f}"}, - ), - ("verbose", bool, {"help_string": "switch on diagnostic messages", "argstr": "-v"}), - ( - "manual_seg", - specs.File, - {"help_string": "Filename containing intensities", "argstr": "-s {manual_seg}"}, - ), - ( - "probability_maps", - bool, - {"help_string": "outputs individual probability maps", "argstr": "-p"}, - ), -] -FAST_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "tissue_class_files", - specs.MultiOutputFile, - {"requires": [("segments", True)], "callable": "FAST_output_nclass"}, - ), - ( - "partial_volume_map", - specs.File, - { - "help_string": "path/name of partial volume file _pveseg", - "requires": [("no_pve", False)], - "callable": "FAST_output", - }, - ), - ( - "partial_volume_files", - specs.MultiOutputFile, - {"requires": [("no_pve", False)], "callable": "FAST_output_nclass"}, - ), - ( - "bias_field", - specs.MultiOutputFile, - {"requires": [("output_biasfield", True)], "callable": "FAST_output_infile"}, - ), - ( - "probability_maps", - specs.MultiOutputFile, - {"requires": [("probability_maps", True)], "callable": "FAST_output_nclass"}, - ), -] -FAST_output_spec = specs.SpecInfo(name="Output", fields=output_fields, bases=(specs.ShellOutSpec,)) - - -class FAST(ShellCommandTask): - """ - Example - ------- - >>> task = FAST() - >>> task.inputs.in_files = "test.nii.gz" - >>> task.inputs.out_basename = "fast_" - >>> task.cmdline - 'fast -o fast_ -n 3 test.nii.gz' - """ - - input_spec = FAST_input_spec - output_spec = FAST_output_spec - executable = "fast" diff --git a/pydra/tasks/fsl/preprocess/first.py b/pydra/tasks/fsl/preprocess/first.py deleted file mode 100644 index 26d824c..0000000 --- a/pydra/tasks/fsl/preprocess/first.py +++ /dev/null @@ -1,138 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input data file", - "argstr": "-i {in_file}", - "copyfile": False, - "mandatory": True, - "position": -2, - }, - ), - ( - "out_file", - str, - { - "help_string": "output data file", - "argstr": "-o {out_file}", - "mandatory": True, - "position": -1, - }, - ), - ( - "verbose", - bool, - {"help_string": "Use verbose logging.", "argstr": "-v", "position": 1}, - ), - ( - "brain_extracted", - bool, - { - "help_string": "Input structural image is already brain-extracted", - "argstr": "-b", - "position": 2, - }, - ), - ( - "no_cleanup", - bool, - { - "help_string": "Input structural image is already brain-extracted", - "argstr": "-d", - "position": 3, - }, - ), - ( - "method", - ty.Any, - "auto", - { - "help_string": "Method must be one of auto, fast, none, or it can be entered using the 'method_as_numerical_threshold' input", - "argstr": "-m {method}", - "position": 4, - "xor": ["method_as_numerical_threshold"], - }, - ), - ( - "method_as_numerical_threshold", - float, - { - "help_string": "Specify a numerical threshold value or use the 'method' input to choose auto, fast, or none", - "argstr": "-m {method_as_numerical_threshold:.4f}", - "position": 4, - }, - ), - ( - "list_of_specific_structures", - list, - { - "help_string": "Runs only on the specified structures (e.g. L_Hipp, R_HippL_Accu, R_Accu, L_Amyg, R_AmygL_Caud, R_Caud, L_Pall, R_PallL_Puta, R_Puta, L_Thal, R_Thal, BrStem", - "argstr": "-s {list_of_specific_structures}", - "position": 5, - "sep": ",", - }, - ), - ( - "affine_file", - specs.File, - { - "help_string": "Affine matrix to use (e.g. img2std.mat) (does not re-run registration)", - "argstr": "-a {affine_file}", - "position": 6, - }, - ), -] -FIRST_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "vtk_surfaces", - specs.MultiOutputFile, - { - "help_string": "VTK format meshes for each subcortical region", - "requires": ["in_file"], - "output_file_template": "{in_file}_vtk_surfaces", - }, - ), - ( - "bvars", - specs.MultiOutputFile, - { - "help_string": "bvars for each subcortical region", - "requires": ["in_file"], - "output_file_template": "{in_file}_bvars", - }, - ), - ( - "original_segmentations", - specs.File, - { - "help_string": "3D image file containing the segmented regions as integer values. Uses CMA labelling", - "requires": ["in_file"], - "output_file_template": "{in_file}_original_segmentations", - }, - ), - ( - "segmentation_file", - specs.File, - { - "help_string": "4D image file containing a single volume per segmented region", - "requires": ["in_file"], - "output_file_template": "{in_file}_segmentation_file", - }, - ), -] -FIRST_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class FIRST(ShellCommandTask): - input_spec = FIRST_input_spec - output_spec = FIRST_output_spec - executable = "run_first_all" diff --git a/pydra/tasks/fsl/preprocess/flirt.py b/pydra/tasks/fsl/preprocess/flirt.py deleted file mode 100644 index 9da52c7..0000000 --- a/pydra/tasks/fsl/preprocess/flirt.py +++ /dev/null @@ -1,348 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input file", - "argstr": "-in {in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "reference", - specs.File, - { - "help_string": "reference file", - "argstr": "-ref {reference}", - "mandatory": True, - "position": 1, - }, - ), - ( - "out_file", - str, - { - "help_string": "registered output file", - "argstr": "-out {out_file}", - "position": 2, - "output_file_template": "{in_file}_flirt", - }, - ), - ( - "out_matrix_file", - str, - { - "help_string": "output affine matrix in 4x4 asciii format", - "argstr": "-omat {out_matrix_file}", - "position": 3, - "output_file_template": "{in_file}_flirt.mat", - }, - ), - ( - "out_log", - str, - { - "help_string": "output log", - "requires": ["save_log"], - "output_file_template": "{in_file}_flirt.log", - }, - ), - ( - "in_matrix_file", - str, - {"help_string": "input 4x4 affine matrix", "argstr": "-init {in_matrix_file}"}, - ), - ( - "apply_xfm", - bool, - { - "help_string": "apply transformation supplied by in_matrix_file or uses_qform to use the affine matrix stored in the reference header", - "argstr": "-applyxfm", - }, - ), - ( - "apply_isoxfm", - float, - { - "help_string": "as applyxfm but forces isotropic resampling", - "argstr": "-applyisoxfm {apply_isoxfm}", - "xor": ["apply_xfm"], - }, - ), - ( - "datatype", - ty.Any, - {"help_string": "force output data type", "argstr": "-datatype {datatype}"}, - ), - ("cost", ty.Any, {"help_string": "cost function", "argstr": "-cost {cost}"}), - ( - "cost_func", - ty.Any, - {"help_string": "cost function", "argstr": "-searchcost {cost_func}"}, - ), - ( - "uses_qform", - bool, - {"help_string": "initialize using sform or qform", "argstr": "-usesqform"}, - ), - ( - "display_init", - bool, - {"help_string": "display initial matrix", "argstr": "-displayinit"}, - ), - ( - "angle_rep", - ty.Any, - { - "help_string": "representation of rotation angles", - "argstr": "-anglerep {angle_rep}", - }, - ), - ( - "interp", - ty.Any, - { - "help_string": "final interpolation method used in reslicing", - "argstr": "-interp {interp}", - }, - ), - ( - "sinc_width", - int, - {"help_string": "full-width in voxels", "argstr": "-sincwidth {sinc_width}"}, - ), - ( - "sinc_window", - ty.Any, - {"help_string": "sinc window", "argstr": "-sincwindow {sinc_window}"}, - ), - ( - "bins", - int, - {"help_string": "number of histogram bins", "argstr": "-bins {bins}"}, - ), - ( - "dof", - int, - { - "help_string": "number of transform degrees of freedom", - "argstr": "-dof {dof}", - }, - ), - ( - "no_resample", - bool, - {"help_string": "do not change input sampling", "argstr": "-noresample"}, - ), - ( - "force_scaling", - bool, - { - "help_string": "force rescaling even for low-res images", - "argstr": "-forcescaling", - }, - ), - ( - "min_sampling", - float, - { - "help_string": "set minimum voxel dimension for sampling", - "argstr": "-minsampling {min_sampling}", - }, - ), - ( - "padding_size", - int, - { - "help_string": "for applyxfm: interpolates outside image by size", - "argstr": "-paddingsize {padding_size}", - }, - ), - ( - "searchr_x", - list, - { - "help_string": "search angles along x-axis, in degrees", - "argstr": "-searchrx {searchr_x}", - }, - ), - ( - "searchr_y", - list, - { - "help_string": "search angles along y-axis, in degrees", - "argstr": "-searchry {searchr_y}", - }, - ), - ( - "searchr_z", - list, - { - "help_string": "search angles along z-axis, in degrees", - "argstr": "-searchrz {searchr_z}", - }, - ), - ( - "no_search", - bool, - { - "help_string": "set all angular searches to ranges 0 to 0", - "argstr": "-nosearch", - }, - ), - ( - "coarse_search", - int, - { - "help_string": "coarse search delta angle", - "argstr": "-coarsesearch {coarse_search}", - }, - ), - ( - "fine_search", - int, - { - "help_string": "fine search delta angle", - "argstr": "-finesearch {fine_search}", - }, - ), - ( - "schedule", - specs.File, - {"help_string": "replaces default schedule", "argstr": "-schedule {schedule}"}, - ), - ( - "ref_weight", - specs.File, - { - "help_string": "File for reference weighting volume", - "argstr": "-refweight {ref_weight}", - }, - ), - ( - "in_weight", - specs.File, - { - "help_string": "File for input weighting volume", - "argstr": "-inweight {in_weight}", - }, - ), - ( - "no_clamp", - bool, - {"help_string": "do not use intensity clamping", "argstr": "-noclamp"}, - ), - ( - "no_resample_blur", - bool, - { - "help_string": "do not use blurring on downsampling", - "argstr": "-noresampblur", - }, - ), - ( - "rigid2D", - bool, - {"help_string": "use 2D rigid body mode - ignores dof", "argstr": "-2D"}, - ), - ("save_log", bool, {"help_string": "save to log file"}), - ( - "verbose", - int, - {"help_string": "verbose mode, 0 is least", "argstr": "-verbose {verbose}"}, - ), - ( - "bgvalue", - float, - { - "help_string": "use specified background value for points outside FOV", - "argstr": "-setbackground {bgvalue}", - }, - ), - ( - "wm_seg", - str, - { - "help_string": "white matter segmentation volume needed by BBR cost function", - "argstr": "-wmseg {wm_seg}", - }, - ), - ( - "wmcoords", - str, - { - "help_string": "white matter boundary coordinates for BBR cost function", - "argstr": "-wmcoords {wmcoords}", - }, - ), - ( - "wmnorms", - str, - { - "help_string": "white matter boundary normals for BBR cost function", - "argstr": "-wmnorms {wmnorms}", - }, - ), - ( - "fieldmap", - str, - { - "help_string": "fieldmap image in rads/s - must be already registered to the reference image", - "argstr": "-fieldmap {fieldmap}", - }, - ), - ( - "fieldmapmask", - str, - { - "help_string": "mask for fieldmap image", - "argstr": "-fieldmapmask {fieldmapmask}", - }, - ), - ( - "pedir", - int, - { - "help_string": "phase encode direction of EPI - 1/2/3=x/y/z & -1/-2/-3=-x/-y/-z", - "argstr": "-pedir {pedir}", - }, - ), - ( - "echospacing", - float, - { - "help_string": "value of EPI echo spacing - units of seconds", - "argstr": "-echospacing {echospacing}", - }, - ), - ( - "bbrtype", - ty.Any, - { - "help_string": "type of bbr cost function: signed [default], global_abs, local_abs", - "argstr": "-bbrtype {bbrtype}", - }, - ), - ( - "bbrslope", - float, - {"help_string": "value of bbr slope", "argstr": "-bbrslope {bbrslope}"}, - ), -] -FLIRT_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -FLIRT_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class FLIRT(ShellCommandTask): - input_spec = FLIRT_input_spec - output_spec = FLIRT_output_spec - executable = "flirt" diff --git a/pydra/tasks/fsl/preprocess/fnirt.py b/pydra/tasks/fsl/preprocess/fnirt.py deleted file mode 100644 index f1a565f..0000000 --- a/pydra/tasks/fsl/preprocess/fnirt.py +++ /dev/null @@ -1,363 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "ref_file", - specs.File, - { - "help_string": "name of reference image", - "argstr": "--ref={ref_file}", - "mandatory": True, - }, - ), - ( - "in_file", - specs.File, - { - "help_string": "name of input image", - "argstr": "--in={in_file}", - "mandatory": True, - }, - ), - ( - "affine_file", - specs.File, - { - "help_string": "name of file containing affine transform", - "argstr": "--aff={affine_file}", - }, - ), - ( - "inwarp_file", - specs.File, - { - "help_string": "name of file containing initial non-linear warps", - "argstr": "--inwarp={inwarp_file}", - }, - ), - ( - "in_intensitymap_file", - specs.MultiInputFile, - { - "help_string": "name of file/files containing initial intensity mapping usually generated by previous fnirt run", - "argstr": "--intin={in_intensitymap_file}", - "copyfile": False, - }, - ), - ( - "fieldcoeff_file", - str, - { - "help_string": "name of output file with field coefficients or true", - "argstr": "--cout={fieldcoeff_file}", - "output_file_template": "{in_file}_fieldwarp", - }, - ), - ( - "warped_file", - str, - { - "help_string": "name of output image", - "argstr": "--iout={warped_file}", - "output_file_template": "{in_file}_warped", - }, - ), - ( - "field_file", - str, - { - "help_string": "name of output file with field or true", - "argstr": "--fout={field_file}", - "output_file_template": "{in_file}_field", - }, - ), - ( - "jacobian_file", - str, - { - "help_string": "name of file for writing out the Jacobian of the field (for diagnostic or VBM purposes)", - "argstr": "--jout={jacobian_file}", - "output_file_template": "{in_file}_field_jacobian", - }, - ), - ( - "modulatedref_file", - str, - { - "help_string": "name of file for writing out intensity modulated --ref (for diagnostic purposes)", - "argstr": "--refout={modulatedref_file}", - "output_file_template": "{in_file}_modulated", - }, - ), - ( - "out_intensitymap_file", - str, - { - "help_string": "name of files for writing information pertaining to intensity mapping", - "argstr": "--intout={out_intensitymap_file}", - }, - ), - ( - "log_file", - str, - { - "help_string": "Name of log-file", - "argstr": "--logout={log_file}", - "output_file_template": "{in_file}_log.txt", - }, - ), - ( - "config_file", - ty.Any, - { - "help_string": "Name of config file specifying command line arguments", - "argstr": "--config={config_file}", - }, - ), - ( - "refmask_file", - specs.File, - { - "help_string": "name of file with mask in reference space", - "argstr": "--refmask={refmask_file}", - }, - ), - ( - "inmask_file", - specs.File, - { - "help_string": "name of file with mask in input image space", - "argstr": "--inmask={inmask_file}", - }, - ), - ( - "skip_refmask", - bool, - { - "help_string": "Skip specified refmask if set, default false", - "argstr": "--applyrefmask=0", - "xor": ["apply_refmask"], - }, - ), - ( - "skip_inmask", - bool, - { - "help_string": "skip specified inmask if set, default false", - "argstr": "--applyinmask=0", - "xor": ["apply_inmask"], - }, - ), - ( - "apply_refmask", - list, - { - "help_string": "list of iterations to use reference mask on (1 to use, 0 to skip)", - "argstr": "--applyrefmask={apply_refmask}", - "sep": ",", - "xor": ["skip_refmask"], - }, - ), - ( - "apply_inmask", - list, - { - "help_string": "list of iterations to use input mask on (1 to use, 0 to skip)", - "argstr": "--applyinmask={apply_inmask}", - "sep": ",", - "xor": ["skip_inmask"], - }, - ), - ( - "skip_implicit_ref_masking", - bool, - { - "help_string": "skip implicit masking based on value in --ref image. Default = 0", - "argstr": "--imprefm=0", - }, - ), - ( - "skip_implicit_in_masking", - bool, - { - "help_string": "skip implicit masking based on value in --in image. Default = 0", - "argstr": "--impinm=0", - }, - ), - ( - "refmask_val", - float, - { - "help_string": "Value to mask out in --ref image. Default =0.0", - "argstr": "--imprefval={refmask_val}", - }, - ), - ( - "inmask_val", - float, - { - "help_string": "Value to mask out in --in image. Default =0.0", - "argstr": "--impinval={inmask_val}", - }, - ), - ( - "max_nonlin_iter", - list, - { - "help_string": "Max # of non-linear iterations list, default [5, 5, 5, 5]", - "argstr": "--miter={max_nonlin_iter}", - "sep": ",", - }, - ), - ( - "subsampling_scheme", - list, - { - "help_string": "sub-sampling scheme, list, default [4, 2, 1, 1]", - "argstr": "--subsamp={subsampling_scheme}", - "sep": ",", - }, - ), - ( - "warp_resolution", - ty.Any, - { - "help_string": "(approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10", - "argstr": "--warpres={warp_resolution},{warp_resolution},{warp_resolution}", - }, - ), - ( - "spline_order", - int, - { - "help_string": "Order of spline, 2->Qadratic spline, 3->Cubic spline. Default=3", - "argstr": "--splineorder={spline_order}", - }, - ), - ( - "in_fwhm", - list, - { - "help_string": "FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2]", - "argstr": "--infwhm={in_fwhm}", - "sep": ",", - }, - ), - ( - "ref_fwhm", - list, - { - "help_string": "FWHM (in mm) of gaussian smoothing kernel for ref volume, default [4, 2, 0, 0]", - "argstr": "--reffwhm={ref_fwhm}", - "sep": ",", - }, - ), - ( - "regularization_model", - ty.Any, - { - "help_string": "Model for regularisation of warp-field [membrane_energy bending_energy], default bending_energy", - "argstr": "--regmod={regularization_model}", - }, - ), - ( - "regularization_lambda", - list, - { - "help_string": "Weight of regularisation, default depending on --ssqlambda and --regmod switches. See user documetation.", - "argstr": "--lambda={regularization_lambda}", - "sep": ",", - }, - ), - ( - "skip_lambda_ssq", - bool, - { - "help_string": "If true, lambda is not weighted by current ssq, default false", - "argstr": "--ssqlambda=0", - }, - ), - ( - "jacobian_range", - ty.Any, - { - "help_string": "Allowed range of Jacobian determinants, default 0.01, 100.0", - "argstr": "--jacrange={jacobian_range},{jacobian_range}", - }, - ), - ( - "derive_from_ref", - bool, - { - "help_string": "If true, ref image is used to calculate derivatives. Default false", - "argstr": "--refderiv", - }, - ), - ( - "intensity_mapping_model", - ty.Any, - { - "help_string": "Model for intensity-mapping", - "argstr": "--intmod={intensity_mapping_model}", - }, - ), - ( - "intensity_mapping_order", - int, - { - "help_string": "Order of poynomial for mapping intensities, default 5", - "argstr": "--intorder={intensity_mapping_order}", - }, - ), - ( - "biasfield_resolution", - ty.Any, - { - "help_string": "Resolution (in mm) of bias-field modelling local intensities, default 50, 50, 50", - "argstr": "--biasres={biasfield_resolution},{biasfield_resolution},{biasfield_resolution}", - }, - ), - ( - "bias_regularization_lambda", - float, - { - "help_string": "Weight of regularisation for bias-field, default 10000", - "argstr": "--biaslambda={bias_regularization_lambda}", - }, - ), - ( - "skip_intensity_mapping", - bool, - { - "help_string": "Skip estimate intensity-mapping default false", - "argstr": "--estint=0", - "xor": ["apply_intensity_mapping"], - }, - ), - ( - "apply_intensity_mapping", - list, - { - "help_string": "List of subsampling levels to apply intensity mapping for (0 to skip, 1 to apply)", - "argstr": "--estint={apply_intensity_mapping}", - "sep": ",", - "xor": ["skip_intensity_mapping"], - }, - ), - ( - "hessian_precision", - ty.Any, - { - "help_string": "Precision for representing Hessian, double or float. Default double", - "argstr": "--numprec={hessian_precision}", - }, - ), -] -FNIRT_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - - -class FNIRT(ShellCommandTask): - input_spec = FNIRT_input_spec - executable = "fnirt" diff --git a/pydra/tasks/fsl/preprocess/mcflirt.py b/pydra/tasks/fsl/preprocess/mcflirt.py deleted file mode 100644 index 136fde7..0000000 --- a/pydra/tasks/fsl/preprocess/mcflirt.py +++ /dev/null @@ -1,185 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "timeseries to motion-correct", - "argstr": "-in {in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "out_file", - str, - { - "help_string": "file to write", - "argstr": "-out {out_file}", - "output_file_template": "{in_file}_mcf", - }, - ), - ( - "cost", - ty.Any, - {"help_string": "cost function to optimize", "argstr": "-cost {cost}"}, - ), - ( - "bins", - int, - {"help_string": "number of histogram bins", "argstr": "-bins {bins}"}, - ), - ( - "dof", - int, - { - "help_string": "degrees of freedom for the transformation", - "argstr": "-dof {dof}", - }, - ), - ( - "ref_vol", - int, - {"help_string": "volume to align frames to", "argstr": "-refvol {ref_vol}"}, - ), - ( - "scaling", - float, - {"help_string": "scaling factor to use", "argstr": "-scaling {scaling:.2f}"}, - ), - ( - "smooth", - float, - { - "help_string": "smoothing factor for the cost function", - "argstr": "-smooth {smooth:.2f}", - }, - ), - ( - "rotation", - int, - { - "help_string": "scaling factor for rotation tolerances", - "argstr": "-rotation {rotation}", - }, - ), - ( - "stages", - int, - { - "help_string": "stages (if 4, perform final search with sinc interpolation", - "argstr": "-stages {stages}", - }, - ), - ( - "init", - specs.File, - {"help_string": "inital transformation matrix", "argstr": "-init {init}"}, - ), - ( - "interpolation", - ty.Any, - { - "help_string": "interpolation method for transformation", - "argstr": "-{interpolation}_final", - }, - ), - ( - "use_gradient", - bool, - {"help_string": "run search on gradient images", "argstr": "-gdt"}, - ), - ( - "use_contour", - bool, - {"help_string": "run search on contour images", "argstr": "-edge"}, - ), - ( - "mean_vol", - bool, - {"help_string": "register to mean volume", "argstr": "-meanvol"}, - ), - ( - "stats_imgs", - bool, - {"help_string": "produce variance and std. dev. images", "argstr": "-stats"}, - ), - ( - "save_mats", - bool, - {"help_string": "save transformation matrices", "argstr": "-mats"}, - ), - ( - "save_plots", - bool, - {"help_string": "save transformation parameters", "argstr": "-plots"}, - ), - ( - "save_rms", - bool, - { - "help_string": "save rms displacement parameters", - "argstr": "-rmsabs -rmsrel", - }, - ), - ( - "ref_file", - specs.File, - { - "help_string": "target image for motion correction", - "argstr": "-reffile {ref_file}", - }, - ), -] -MCFLIRT_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "variance_img", - specs.File, - { - "help_string": "variance image", - "requires": ["in_file", ("stats_imgs", True)], - "output_file_template": "{out_file}_variance.ext", - }, - ), - ( - "std_img", - specs.File, - { - "help_string": "standard deviation image", - "requires": ["in_file", ("stats_imgs", True)], - "output_file_template": "{out_file}_sigma.ext", - }, - ), - ( - "mean_img", - specs.File, - { - "help_string": "mean timeseries image (if mean_vol=True)", - "requires": ["in_file", ("mean_vol", True)], - "output_file_template": "{out_file}_mean_reg.ext", - }, - ), - ( - "par_file", - specs.File, - { - "help_string": "text-file with motion parameters", - "requires": ["save_plots"], - "output_file_template": "{out_file}.par", - }, - ), -] -MCFLIRT_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class MCFLIRT(ShellCommandTask): - input_spec = MCFLIRT_input_spec - output_spec = MCFLIRT_output_spec - executable = "mcflirt" diff --git a/pydra/tasks/fsl/preprocess/prelude.py b/pydra/tasks/fsl/preprocess/prelude.py deleted file mode 100644 index b5b8520..0000000 --- a/pydra/tasks/fsl/preprocess/prelude.py +++ /dev/null @@ -1,155 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "complex_phase_file", - specs.File, - { - "help_string": "complex phase input volume", - "argstr": "--complex={complex_phase_file}", - "mandatory": True, - "xor": ["magnitude_file", "phase_file"], - }, - ), - ( - "magnitude_file", - specs.File, - { - "help_string": "file containing magnitude image", - "argstr": "--abs={magnitude_file}", - "mandatory": True, - "xor": ["complex_phase_file"], - }, - ), - ( - "phase_file", - specs.File, - { - "help_string": "raw phase file", - "argstr": "--phase={phase_file}", - "mandatory": True, - "xor": ["complex_phase_file"], - }, - ), - ( - "unwrapped_phase_file", - str, - { - "help_string": "file containing unwrapepd phase", - "argstr": "--unwrap={unwrapped_phase_file}", - "output_file_template": "{phase_file}_unwrapped", - }, - ), - ( - "num_partitions", - int, - { - "help_string": "number of phase partitions to use", - "argstr": "--numphasesplit={num_partitions}", - }, - ), - ( - "labelprocess2d", - bool, - { - "help_string": "does label processing in 2D (slice at a time)", - "argstr": "--labelslices", - }, - ), - ( - "process2d", - bool, - { - "help_string": "does all processing in 2D (slice at a time)", - "argstr": "--slices", - "xor": ["labelprocess2d"], - }, - ), - ( - "process3d", - bool, - { - "help_string": "forces all processing to be full 3D", - "argstr": "--force3D", - "xor": ["labelprocess2d", "process2d"], - }, - ), - ( - "threshold", - float, - { - "help_string": "intensity threshold for masking", - "argstr": "--thresh={threshold:.10f}", - }, - ), - ( - "mask_file", - specs.File, - { - "help_string": "filename of mask input volume", - "argstr": "--mask={mask_file}", - }, - ), - ( - "start", - int, - { - "help_string": "first image number to process (default 0)", - "argstr": "--start={start}", - }, - ), - ( - "end", - int, - { - "help_string": "final image number to process (default Inf)", - "argstr": "--end={end}", - }, - ), - ( - "savemask_file", - str, - { - "help_string": "saving the mask volume", - "argstr": "--savemask={savemask_file}", - }, - ), - ( - "rawphase_file", - str, - { - "help_string": "saving the raw phase output", - "argstr": "--rawphase={rawphase_file}", - }, - ), - ( - "label_file", - str, - { - "help_string": "saving the area labels output", - "argstr": "--labels={label_file}", - }, - ), - ( - "removeramps", - bool, - { - "help_string": "remove phase ramps during unwrapping", - "argstr": "--removeramps", - }, - ), -] -PRELUDE_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -PRELUDE_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class PRELUDE(ShellCommandTask): - input_spec = PRELUDE_input_spec - output_spec = PRELUDE_output_spec - executable = "prelude" diff --git a/pydra/tasks/fsl/preprocess/slicetimer.py b/pydra/tasks/fsl/preprocess/slicetimer.py deleted file mode 100644 index 28177bb..0000000 --- a/pydra/tasks/fsl/preprocess/slicetimer.py +++ /dev/null @@ -1,97 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "filename of input timeseries", - "argstr": "--in={in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "out_file", - str, - { - "help_string": "filename of output timeseries", - "argstr": "--out={out_file}", - "output_file_template": "{in_file}_st", - }, - ), - ( - "index_dir", - bool, - {"help_string": "slice indexing from top to bottom", "argstr": "--down"}, - ), - ( - "time_repetition", - float, - { - "help_string": "Specify TR of data - default is 3s", - "argstr": "--repeat={time_repetition}", - }, - ), - ( - "slice_direction", - ty.Any, - { - "help_string": "direction of slice acquisition (x=1, y=2, z=3) - default is z", - "argstr": "--direction={slice_direction}", - }, - ), - ( - "interleaved", - bool, - {"help_string": "use interleaved acquisition", "argstr": "--odd"}, - ), - ( - "custom_timings", - specs.File, - { - "help_string": "slice timings, in fractions of TR, range 0:1 (default is 0.5 = no shift)", - "argstr": "--tcustom={custom_timings}", - }, - ), - ( - "global_shift", - float, - { - "help_string": "shift in fraction of TR, range 0:1 (default is 0.5 = no shift)", - "argstr": "--tglobal", - }, - ), - ( - "custom_order", - specs.File, - { - "help_string": "filename of single-column custom interleave order file (first slice is referred to as 1 not 0)", - "argstr": "--ocustom={custom_order}", - }, - ), -] -SliceTimer_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "slice_time_corrected_file", - specs.File, - { - "help_string": "slice time corrected file", - "requires": ["out_file"], - "output_file_template": "{out_file}", - }, - ) -] -SliceTimer_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class SliceTimer(ShellCommandTask): - input_spec = SliceTimer_input_spec - output_spec = SliceTimer_output_spec - executable = "slicetimer" diff --git a/pydra/tasks/fsl/preprocess/susan.py b/pydra/tasks/fsl/preprocess/susan.py deleted file mode 100644 index 53fa617..0000000 --- a/pydra/tasks/fsl/preprocess/susan.py +++ /dev/null @@ -1,114 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def format_usans(field: ty.Sequence[ty.Tuple[str, float]]) -> str: - """Format usans argument to its appropriate argstr. - - Examples - -------- - >>> format_usans([]) - '0' - >>> format_usans([('/path/to/file', 2.5)]) - '1 /path/to/file 2.5' - >>> format_usans([('/path/to/file1', 10.5), ('/path/to/file2', 22.1)]) - '2 /path/to/file1 10.5 /path/to/file2 22.1' - """ - return " ".join([f"{len(field)}"] + [f"{usan} {bt}" for usan, bt in field]) - - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "filename of input timeseries", - "argstr": "{in_file}", - "mandatory": True, - "position": 1, - }, - ), - ( - "brightness_threshold", - float, - { - "help_string": "brightness threshold and should be greater than noise level and less than contrast of edges to be preserved.", - "argstr": "{brightness_threshold:.10f}", - "mandatory": True, - "position": 2, - }, - ), - ( - "fwhm", - float, - { - "help_string": "fwhm of smoothing, in mm, gets converted using sqrt(8*log(2))", - "argstr": "{fwhm:.10f}", - "mandatory": True, - "position": 3, - }, - ), - ( - "dimension", - ty.Any, - 3, - { - "help_string": "within-plane (2) or fully 3D (3)", - "argstr": "{dimension}", - "position": 4, - }, - ), - ( - "use_median", - ty.Any, - 1, - { - "help_string": "whether to use a local median filter in the cases where single-point noise is detected", - "argstr": "{use_median}", - "position": 5, - }, - ), - ( - "usans", - ty.Sequence[ty.Tuple[str, float]], - [], - { - "help_string": "determines whether the smoothing area (USAN) is to be found from secondary images (0, 1 or 2). A negative value for any brightness threshold will auto-set the threshold at 10% of the robust range", - "formatter": format_usans, - "position": 6, - }, - ), - ( - "out_file", - str, - { - "help_string": "output file name", - "argstr": "{out_file}", - "position": -1, - "output_file_template": "{in_file}_smooth", - }, - ), -] -SUSAN_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "smoothed_file", - specs.File, - { - "help_string": "smoothed output file", - "requires": ["out_file"], - "output_file_template": "{out_file}", - }, - ) -] -SUSAN_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class SUSAN(ShellCommandTask): - input_spec = SUSAN_input_spec - output_spec = SUSAN_output_spec - executable = "susan" diff --git a/pydra/tasks/fsl/preprocess/tests/__init__.py b/pydra/tasks/fsl/preprocess/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_applywarp.py b/pydra/tasks/fsl/preprocess/tests/test_run_applywarp.py deleted file mode 100644 index f87ef98..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_applywarp.py +++ /dev/null @@ -1,22 +0,0 @@ -import os, pytest -from pathlib import Path -from ..applywarp import ApplyWarp - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", [({"ref_file": 'f"{in_file}"'}, ["out_file"])]) -def test_ApplyWarp(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = ApplyWarp(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_bet.py b/pydra/tasks/fsl/preprocess/tests/test_run_bet.py deleted file mode 100644 index 5ca0fb6..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_bet.py +++ /dev/null @@ -1,42 +0,0 @@ -import os, pytest -from pathlib import Path -from ..bet import BET - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [ - (None, ["out_file"]), - ({"mask": True}, ["out_file", "mask_file"]), - ( - {"surfaces": True}, - [ - "out_file", - "meshfile", - "inskull_mask_file", - "inskull_mesh_file", - "outskull_mask_file", - "outskull_mesh_file", - "outskin_mask_file", - "outskin_mesh_file", - "skull_mask_file", - ], - ), - ], -) -def test_BET(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = BET(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_fast.py b/pydra/tasks/fsl/preprocess/tests/test_run_fast.py deleted file mode 100644 index 0b25fc9..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_fast.py +++ /dev/null @@ -1,37 +0,0 @@ -import os, pytest -from pathlib import Path -from ..fast import FAST - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_FAST(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FAST(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FAST_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FAST(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_first.py b/pydra/tasks/fsl/preprocess/tests/test_run_first.py deleted file mode 100644 index e8bcab9..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_first.py +++ /dev/null @@ -1,37 +0,0 @@ -import os, pytest -from pathlib import Path -from ..first import FIRST - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_FIRST(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FIRST(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FIRST_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FIRST(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_flirt.py b/pydra/tasks/fsl/preprocess/tests/test_run_flirt.py deleted file mode 100644 index 5c968c0..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_flirt.py +++ /dev/null @@ -1,37 +0,0 @@ -import os, pytest -from pathlib import Path -from ..flirt import FLIRT - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_FLIRT(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FLIRT(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FLIRT_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FLIRT(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_fnirt.py b/pydra/tasks/fsl/preprocess/tests/test_run_fnirt.py deleted file mode 100644 index a706054..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_fnirt.py +++ /dev/null @@ -1,52 +0,0 @@ -import os, pytest -from pathlib import Path -from ..fnirt import FNIRT - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - {"ref_file": 'f"{in_file}"'}, - [ - "warped_file", - "field_file", - "jacobian_file", - "modulatedref_file", - "log_file", - "fieldcoeff_file", - ], - ) - ], -) -def test_FNIRT(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FNIRT(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FNIRT_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FNIRT(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_mcflirt.py b/pydra/tasks/fsl/preprocess/tests/test_run_mcflirt.py deleted file mode 100644 index 13525ff..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_mcflirt.py +++ /dev/null @@ -1,22 +0,0 @@ -import os, pytest -from pathlib import Path -from ..mcflirt import MCFLIRT - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", [(None, ["out_file"])]) -def test_MCFLIRT(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = MCFLIRT(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_prelude.py b/pydra/tasks/fsl/preprocess/tests/test_run_prelude.py deleted file mode 100644 index 9c6b66f..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_prelude.py +++ /dev/null @@ -1,37 +0,0 @@ -import os, pytest -from pathlib import Path -from ..prelude import PRELUDE - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_PRELUDE(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = PRELUDE(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_PRELUDE_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = PRELUDE(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_slicetimer.py b/pydra/tasks/fsl/preprocess/tests/test_run_slicetimer.py deleted file mode 100644 index f03a0c1..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_slicetimer.py +++ /dev/null @@ -1,25 +0,0 @@ -import os, pytest -from pathlib import Path -from ..slicetimer import SliceTimer - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [({"ref_file": 'f"{in_file}"'}, ["out_file", "slice_time_corrected_file"])], -) -def test_SliceTimer(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = SliceTimer(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() diff --git a/pydra/tasks/fsl/preprocess/tests/test_run_susan.py b/pydra/tasks/fsl/preprocess/tests/test_run_susan.py deleted file mode 100644 index bdb8e42..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_run_susan.py +++ /dev/null @@ -1,40 +0,0 @@ -import os, pytest -from pathlib import Path -from ..susan import SUSAN - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [({"brightness_threshold": 0.01, "fwhm": 2}, ["out_file", "smoothed_file"])], -) -def test_SUSAN(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = SUSAN(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_SUSAN_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = SUSAN(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_applywarp.py b/pydra/tasks/fsl/preprocess/tests/test_spec_applywarp.py deleted file mode 100644 index ad2b138..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_applywarp.py +++ /dev/null @@ -1,17 +0,0 @@ -import os, pytest -from pathlib import Path -from ..applywarp import ApplyWarp - - -@pytest.mark.parametrize("inputs, outputs", [({"ref_file": 'f"{in_file}"'}, ["out_file"])]) -def test_ApplyWarp(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = ApplyWarp(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_bet.py b/pydra/tasks/fsl/preprocess/tests/test_spec_bet.py deleted file mode 100644 index 09dd23a..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_bet.py +++ /dev/null @@ -1,37 +0,0 @@ -import os, pytest -from pathlib import Path -from ..bet import BET - - -@pytest.mark.parametrize( - "inputs, outputs", - [ - (None, ["out_file"]), - ({"mask": True}, ["out_file", "mask_file"]), - ( - {"surfaces": True}, - [ - "out_file", - "meshfile", - "inskull_mask_file", - "inskull_mesh_file", - "outskull_mask_file", - "outskull_mesh_file", - "outskin_mask_file", - "outskin_mesh_file", - "skull_mask_file", - ], - ), - ], -) -def test_BET(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = BET(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_fast.py b/pydra/tasks/fsl/preprocess/tests/test_spec_fast.py deleted file mode 100644 index 61ec166..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_fast.py +++ /dev/null @@ -1,32 +0,0 @@ -import os, pytest -from pathlib import Path -from ..fast import FAST - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_FAST(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FAST(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FAST_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FAST(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_first.py b/pydra/tasks/fsl/preprocess/tests/test_spec_first.py deleted file mode 100644 index e48756b..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_first.py +++ /dev/null @@ -1,32 +0,0 @@ -import os, pytest -from pathlib import Path -from ..first import FIRST - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_FIRST(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FIRST(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FIRST_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FIRST(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_flirt.py b/pydra/tasks/fsl/preprocess/tests/test_spec_flirt.py deleted file mode 100644 index e806cf4..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_flirt.py +++ /dev/null @@ -1,32 +0,0 @@ -import os, pytest -from pathlib import Path -from ..flirt import FLIRT - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_FLIRT(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FLIRT(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FLIRT_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FLIRT(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_fnirt.py b/pydra/tasks/fsl/preprocess/tests/test_spec_fnirt.py deleted file mode 100644 index 1097d04..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_fnirt.py +++ /dev/null @@ -1,47 +0,0 @@ -import os, pytest -from pathlib import Path -from ..fnirt import FNIRT - - -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - {"ref_file": 'f"{in_file}"'}, - [ - "warped_file", - "field_file", - "jacobian_file", - "modulatedref_file", - "log_file", - "fieldcoeff_file", - ], - ) - ], -) -def test_FNIRT(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FNIRT(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FNIRT_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = FNIRT(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_mcflirt.py b/pydra/tasks/fsl/preprocess/tests/test_spec_mcflirt.py deleted file mode 100644 index 075cc33..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_mcflirt.py +++ /dev/null @@ -1,17 +0,0 @@ -import os, pytest -from pathlib import Path -from ..mcflirt import MCFLIRT - - -@pytest.mark.parametrize("inputs, outputs", [(None, ["out_file"])]) -def test_MCFLIRT(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = MCFLIRT(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_prelude.py b/pydra/tasks/fsl/preprocess/tests/test_spec_prelude.py deleted file mode 100644 index 7212865..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_prelude.py +++ /dev/null @@ -1,32 +0,0 @@ -import os, pytest -from pathlib import Path -from ..prelude import PRELUDE - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_PRELUDE(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = PRELUDE(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_PRELUDE_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = PRELUDE(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_slicetimer.py b/pydra/tasks/fsl/preprocess/tests/test_spec_slicetimer.py deleted file mode 100644 index 2125884..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_slicetimer.py +++ /dev/null @@ -1,20 +0,0 @@ -import os, pytest -from pathlib import Path -from ..slicetimer import SliceTimer - - -@pytest.mark.parametrize( - "inputs, outputs", - [({"ref_file": 'f"{in_file}"'}, ["out_file", "slice_time_corrected_file"])], -) -def test_SliceTimer(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = SliceTimer(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/preprocess/tests/test_spec_susan.py b/pydra/tasks/fsl/preprocess/tests/test_spec_susan.py deleted file mode 100644 index aca65a1..0000000 --- a/pydra/tasks/fsl/preprocess/tests/test_spec_susan.py +++ /dev/null @@ -1,35 +0,0 @@ -import os, pytest -from pathlib import Path -from ..susan import SUSAN - - -@pytest.mark.parametrize( - "inputs, outputs", - [({"brightness_threshold": 0.01, "fwhm": 2}, ["out_file", "smoothed_file"])], -) -def test_SUSAN(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = SUSAN(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_SUSAN_exception(test_data, inputs, error): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = SUSAN(in_file=in_file, **inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/tests/data/anatomical.nii b/pydra/tasks/fsl/tests/data/anatomical.nii deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/confounds_regressors.tsv b/pydra/tasks/fsl/tests/data/confounds_regressors.tsv deleted file mode 100644 index abb2b36..0000000 --- a/pydra/tasks/fsl/tests/data/confounds_regressors.tsv +++ /dev/null @@ -1,527 +0,0 @@ -csf white_matter global_signal std_dvars dvars framewise_displacement t_comp_cor_00 t_comp_cor_01 t_comp_cor_02 t_comp_cor_03 t_comp_cor_04 t_comp_cor_05 a_comp_cor_00 a_comp_cor_01 a_comp_cor_02 a_comp_cor_03 a_comp_cor_04 a_comp_cor_05 cosine00 cosine01 cosine02 cosine03 cosine04 cosine05 cosine06 trans_x trans_y trans_z rot_x rot_y rot_z -428.8565979003906 352.93707275390625 346.7164611816406 n/a n/a n/a 0.0537686856 -0.0015589024 0.0256904886 -0.055431638600000006 0.0334041688 -0.045645886 -0.0254605165 0.0048484609000000005 -0.040182257799999996 -0.00840419 0.028837367000000003 -0.0429884066 0.061662366600000004 0.0616615418 0.061660167 0.0616582424 0.0616557679 0.061652743499999996 0.061649169299999994 -0.0473566 0.07976039999999998 -0.119026 0.00304888 -0.000650074 0.000562989 -423.5132446289063 352.6452331542969 345.640625 1.039311 62.641384 0.2022724 0.062349405499999996 -0.0022176462 0.0345898154 -0.0170098117 0.028544711099999998 -0.0453725769 -0.018702046200000003 -0.0057048807 -0.044379064100000004 -0.0006186997 0.0348451634 -0.0065644783 0.061660167 0.061652743499999996 0.0616403716 0.0616230524 0.0616007872 0.0615735779 0.0615414265 -0.0394607 0.143454 -0.0792087 0.00159675 -0.000862004 0.000409737 -421.8155822753906 352.5387268066406 345.3033752441406 1.001764 60.378342 0.07977654999999999 0.052621478099999994 -0.024067204300000002 0.023976866800000003 -0.0034115172 0.020885618600000003 -0.0105915573 -0.016908982 -0.0029474502000000004 -0.0496521325 0.016617866499999998 0.0331314209 0.0023508823 0.0616557679 0.0616351482 0.0616007872 0.0615526926 0.061490875 0.0614153483 0.061326129199999996 -0.0474473 0.142576 -0.13041100000000003 0.0013054 -0.0008713459999999998 0.000503238 -421.94580078125 352.53643798828125 345.1815185546875 1.034929 62.377281 0.34043935 0.0546193864 -0.0085628441 0.0251114206 0.0089886654 0.0472215468 -0.0388199627 -0.0151842025 -0.0052130304 -0.0459949178 0.0050819396 0.0482500117 0.0124924463 0.061649169299999994 0.0616087584 0.0615414265 0.06144720309999999 0.061326129199999996 0.061178257800000004 0.061003653600000006 -0.0450416 -0.0219745 -0.10445 0.00348336 -0.000295167 0.000306934 -421.6714782714844 352.55206298828125 345.7688903808594 0.984481 59.336678 0.1350055 0.053351830999999995 -0.0129630161 0.01933137 0.0093967082 0.0199816272 -0.013670688799999999 -0.013729844 -0.005543737900000001 -0.0410041867 -0.0028430989 0.0371352979 0.0232120496 0.0616403716 0.0615735779 0.06146230849999999 0.061306644 0.0611066967 0.060862611100000005 0.060574563399999996 -0.0474075 0.035851 -0.0622828 0.00322295 -0.000635691 0.000358938 -421.7160339355469 353.1280212402344 346.5439453125 1.044161 62.933681 0.30546834999999994 0.0491227798 -0.0347523588 0.0275142878 0.014662727 -0.0021947441000000002 -0.0037473461 -0.0233749851 -0.0001679766 -0.04227085690000001 0.0110727573 0.025359982000000003 0.0325656202 0.061629375099999995 0.0615296116 0.0613634587 0.061131095700000006 0.0608327732 0.060468813200000006 0.0600396084 -0.0350914 0.146502 -0.100252 0.000399393 -0.0005856 0.000375931 -422.0044860839844 352.8157043457031 346.26373291015625 1.043894 62.917583 0.3683706 0.051076075 -0.019145380400000002 0.027904492000000003 0.014245225700000001 0.0139551647 -0.0289754181 -0.0163075221 0.0021952172 -0.057152487 -0.0011384181 0.032963130800000004 0.0175916103 0.061616180199999995 0.0614768659 0.0612449087 0.060920658200000005 0.060504603 0.05999737 0.0593997236 -0.0473819 -0.0489117 -0.116 0.0030016 -0.000321411 0.000343959 -421.9078369140625 353.349609375 346.627197265625 0.984202 59.319859 0.1142548 0.0557874392 -0.0176886541 0.019926881 0.017280086200000003 0.0154755351 -0.0015848789000000002 -0.0187503826 0.0042999105 -0.0514848333 -0.007117820600000001 0.0375336971 0.023369584500000002 0.0616007872 0.0614153483 0.0611066967 0.060675451799999995 0.0601224786 0.0594488867 0.058656027300000003 -0.0445358 0.030952 -0.0907497 0.0030545 -0.000303749 0.000288627 -423.7535095214844 352.76971435546875 347.08319091796875 1.041885 62.796497 0.24610505 0.041001723399999995 -0.0329021056 0.0241082723 0.0280948068 -0.0124210021 -0.00035472870000000003 -0.0156891539 -0.00190658 -0.0453808136 0.0013530182000000002 0.0307899465 0.0246374027 0.061583196900000005 0.0613450675 0.060948867000000004 0.060395616299999996 0.059686740999999995 0.058824067699999996 0.057809819299999995 -0.0439007 0.154855 -0.0935258 0.00132579 -0.000880095 0.000359388 -421.46575927734375 352.84381103515625 346.3697204589844 1.022636 61.63633 0.33807078 0.0339742969 -0.0209763399 0.0080653242 0.031088961499999998 -0.0089892564 0.053482818 -0.0198270894 -0.0039345466999999995 -0.0451115432 -0.0056682597 0.0331161027 0.025915474100000002 0.061563409699999995 0.061266033600000006 0.0607714702 0.0600813114 0.0591977785 0.058123715199999995 0.0568625783 -0.0379304 -0.00866658 -0.11276000000000003 0.00374655 -0.0004332 0.000240149 -420.7928161621094 352.7812805175781 346.3152160644531 1.023381 61.681225 0.19639038 0.0188112805 -0.0385910818 -0.011891090600000001 0.0513098766 -0.015556511 0.0644882221 -0.0165915746 0.0008219536 -0.0450252247 0.00041603230000000004 0.024071836800000003 0.0367681956 0.0615414265 0.061178257800000004 0.060574563399999996 0.0597327166 0.058656027300000003 0.057348728499999994 0.05581596 -0.0473786 0.0879448 -0.0859926 0.00291274 -0.000635691 0.000475116 -421.4585876464844 352.84234619140625 346.48553466796875 0.992451 59.817059 0.150551 0.022704300099999998 -0.0338238752 -0.020676612900000002 0.0361390234 -0.0082521286 0.044257989299999995 -0.0169017771 -0.0029269592 -0.029943540600000002 0.0160998063 0.0158351577 0.0326194083 0.061517248 0.0610817528 0.0603582097 0.0593500308 0.0580619705 0.0565001029 0.0546717934 -0.0428669 0.150998 -0.0954755 0.00147358 -0.000635691 0.000444212 -419.8441162109375 352.70477294921875 346.0199279785156 1.0102 60.886803 0.30138802 0.0121409076 -0.0273844306 -0.020543481699999998 0.038220342000000004 0.0089782532 0.0738032034 -0.016070717800000002 -0.0082920227 -0.042922151500000005 -0.0043682968 0.0195660682 0.023063640899999998 0.061490875 0.060976532199999996 0.0601224786 0.0589334724 0.057416137699999995 0.055578927800000004 0.053432078200000004 -0.0402938 0.00294458 -0.113888 0.00370674 -0.000347448 0.000318635 -419.6357421875 352.89276123046875 346.4696960449219 1.005331 60.593327 0.30593151999999996 0.0080609827 -0.028165880600000002 -0.0428730964 0.039591141499999996 0.006099671700000001 0.0412882162 -0.015807618 -0.006021654 -0.0362715204 0.0058374459 0.006954896800000001 0.0316654202 0.06146230849999999 0.060862611100000005 0.0598674458 0.0584832792 0.056719105 0.0545863863 0.052098980999999996 -0.0378821 0.151582 -0.09914750000000003 0.00126458 -0.000635691 0.0002462 -421.9593811035156 352.7574768066406 346.8318786621094 1.026059 61.842636 0.2979096265 0.0198073138 -0.032301819700000005 -0.026579866400000002 0.030936274700000002 0.0014158785000000001 0.0619500371 -0.0174697914 -0.0059961181 -0.0457277961 0.0021469561 0.0067888101 0.0121129255 0.0614315496 0.0607400057 0.059593193200000005 0.057999708 0.0559714938 0.053523752699999996 0.050674831600000005 -0.0319609 0.0190501 -0.134484 0.00350584 -0.000635691 5.05947e-06 -420.6251831054688 352.7864074707031 346.70928955078125 0.975088 58.770504 0.0701924765 0.0160915406 -0.0354456936 -0.0186905975 0.040895061 0.0005614441000000001 0.0579349405 -0.0131619995 -0.0039251202 -0.047525683 0.0008730146000000001 0.015449289 0.027326357599999997 0.0613985992 0.0606087335 0.0592998088 0.0574830349 0.0551739708 0.052392391600000005 0.0491621191 -0.0319432 0.0404246 -0.107731 0.00342707 -0.000454141 0.000185685 -424.9055480957031 352.82977294921875 347.3736572265625 1.057406 63.73201 0.28658500000000003 0.0118732582 -0.06779053639999999 -0.0240485873 0.0191050782 0.008052877 -0.0295202877 -0.0171288314 -0.0017573574 -0.0483553418 0.0153628106 0.0053415358 0.0209976612 0.0613634587 0.060468813200000006 0.0589873867 0.0569335547 0.054327247300000006 0.0511937557 0.047563487 -0.035625 0.126491 -0.182642 0.00138752 -0.000635691 0.000403101 -423.4905700683594 347.3473205566406 343.6858215332031 1.429247 86.143631 1.01910365 -0.1022827734 -0.0474509013 0.0326234375 -0.013203429499999999 0.0635159984 -0.052519164199999996 0.0519471864 -0.0529280342 -0.0578015326 0.05777697230000001 -0.09890198310000001 -0.0313843345 0.061326129199999996 0.060320264900000004 0.058656027300000003 0.056351581 0.053432078200000004 0.0499293841 0.0458817293 -0.0444593 -0.247091 -0.662699 -0.00127977 -0.00108247 0.000384563 -417.0805358886719 350.4700927734375 344.9083251953125 1.76582 106.429535 1.040049655 -0.013605852600000001 -0.0557343939 -0.0017400832 -0.0058479165000000005 0.0225796371 0.0297208929 0.013912976799999999 -0.0026512423 0.035373041699999996 0.10219857689999999 -0.1773525384 0.0702475355 0.0612866121 0.060163109699999995 0.058305837 0.055737446100000004 0.05248926190000001 0.0486009003 0.0441197852 -0.06377090000000002 0.00637318 -0.222933 -0.00548047 -1.50595e-05 -0.000897484 -415.3163757324219 352.7156982421875 345.59564208984375 1.247697 75.20121799999998 0.401132795 0.0094559329 -0.049341345099999996 -0.010199398 0.0032057815 -0.0009929884 0.0598669591 -0.0051992248999999996 0.007276668199999999 -0.0045212240999999995 0.0392568501 -0.054685968200000004 0.032555336000000004 0.0612449087 0.05999737 0.0579369282 0.0550915004 0.05149963900000001 0.04721001019999999 0.042280734 -0.0550415 0.03651 0.00631375 -0.00372069 -0.000214771 -0.000196579 -419.47216796875 352.7251281738281 346.4576110839844 1.080105 65.100143 0.41858265 0.025813557 -0.0377546422 -0.0011280455 0.0032204269 -0.0089464002 0.0289313254 -0.0164287725 -0.0046135459 -0.0228354537 0.0063972364 0.0021225244 0.010151818 0.061201020700000004 0.0598230695 0.0575494194 0.0544141125 0.050464092099999996 0.0457584997 0.0403677898 -0.0457497 -0.0767672 0.07715769999999998 9.54066e-05 -0.000730162 -2.46726e-05 -421.4810791015625 353.1749267578125 346.563720703125 1.071692 64.593079 0.33040096 0.0077320123 -0.054674985999999995 -0.0065563106 0.0193986012 0.0007480275 7.75396e-05 -0.017688266499999997 0.0017400876000000002 -0.0172017285 0.029327895899999998 -0.0063180142 0.0330795564 0.061154949400000005 0.059640233 0.057143434800000004 0.053705669000000004 0.0493835445 0.0442482328 0.0383842957 -0.0311852 0.103738 0.0519469 -0.0014082700000000003 -0.0012479800000000003 0.000156242 -419.31378173828125 352.78167724609375 345.8904724121094 1.041467 62.771336 0.14350323000000004 -0.0178676366 -0.0449070646 -0.0320796904 0.026965532 -0.0031668111 0.0495382303 -0.0137813548 0.0019540808 -0.016928535800000002 0.0157095403 0.0031698915000000004 0.0307664177 0.0611066967 0.0594488867 0.056719105 0.0529665744 0.0482589599 0.042681148499999995 0.0363337182 -0.0406102 0.0749191 0.0909968 -0.000655001 -0.0008579749999999998 -2.46726e-05 -422.8047790527344 352.604736328125 346.1974792480469 1.055401 63.611164 0.07445132999999998 -0.0142758577 -0.0432600812 -0.0699937293 0.0244232171 0.023965530899999997 -0.0510595659 -0.0125283464 0.0003246777 -0.0117045255 0.017569212600000002 -0.0081520177 0.0179983371 0.0610562642 0.059249057800000005 0.05627656599999999 0.052197250300000005 0.0470913411 0.041059259300000005 0.0342196412 -0.0364433 0.101577 0.111208 -0.000476084 -0.000706535 0.000113277 -420.7060241699219 350.52545166015625 343.35455322265625 1.372377 82.715958 0.5722636000000001 -0.0744274488 -0.0074701433999999995 -0.047068429800000006 -0.0173755697 0.034343122000000004 -0.0376298668 0.0223343425 0.01634942 0.0276490393 0.0556881186 0.044624588 -0.051700614299999996 0.061003653600000006 0.0590407749 0.05581596 0.051398136 0.0458817293 0.039384647599999996 0.032045759300000004 -0.177749 -0.0180122 0.22425 -0.00386358 -0.000500808 -0.000260034 -420.1304016113281 349.28533935546875 341.61187744140625 1.717919 103.542458 1.5768292 -0.1203087953 0.061222523200000004 -0.0103574369 -0.0671542308 -0.1656955096 -0.0248116825 0.08135555629999999 0.1108777782 0.053629350199999995 -0.0648930502 -0.0518459153 -0.040079954 0.060948867000000004 0.058824067699999996 0.0553374348 0.050569687300000006 0.044631203099999996 0.0376594638 0.0298158718 -0.594501 -0.123645 0.549579 -0.0129923 -0.00312881 -0.00308562 -420.0106201171875 350.4721984863281 341.4777526855469 1.189683 71.704628 0.8598327 -0.0766104331 -0.0011321699 -0.0171281904 -0.0842365336 -0.1322071649 -0.0391631577 0.0612840931 0.1153356112 0.062109298099999995 0.0223132797 -0.09018488599999999 -0.045105018899999995 0.0608919062 0.058598967 0.0548411441 0.049712377300000006 0.043340877699999995 0.0358859231 0.0275338758 -0.197552 -0.103441 0.401287 -0.0140042 -0.00469922 0.000219824 -420.8648681640625 352.74041748046875 346.4868469238281 1.175502 70.849884 0.44343045 -0.0590932687 0.0056311127 -0.0242823688 -0.049743768499999994 -0.09130462460000001 -0.047662057300000005 0.0162643853 0.0960500007 0.0839526051 0.0528457576 -0.0678838777 -0.0326066126 0.0608327732 0.0583655051 0.054327247300000006 0.0488266951 0.0420119037 0.034066302799999996 0.0252037594 -0.170904 -0.0789298 0.316497 -0.00920198 -0.00370526 0.000573269 -422.3285827636719 352.9872131347656 346.9273681640625 1.065876 64.242516 0.3102057 -0.044653840099999995 -0.0049897139000000005 -0.0584648942 -0.0314740389 -0.0624348944 -0.0613848693 0.0010178028 0.0667218101 0.0708351471 0.047145317400000004 -0.0626980809 -0.0255755202 0.0607714702 0.058123715199999995 0.0537959092 0.0479131463 0.0406454662 0.0322029395 0.0228295951 -0.159661 -0.0522662 0.225198 -0.00571034 -0.00358018 0.000576551 -423.484375 353.3213195800781 346.7541198730469 0.99789 60.144844 0.15635430999999997 -0.030048197999999998 -0.022438739 -0.0587792625 -0.0717754746 -0.0718904174 -0.0090266302 -0.005497474699999999 0.056706593 0.0572944617 0.0449399609 -0.07251513679999999 -0.0620536454 0.060707999400000004 0.0578736318 0.0532473004 0.0469722521 0.0392427837 0.030298225699999997 0.020415532 -0.157928 0.00961641 0.159951 -0.00591866 -0.00385606 0.000510917 -422.6296691894531 352.5272521972656 346.68585205078125 1.218467 73.439507 0.6499810400000001 0.015572802299999999 0.0038197293 -0.0405419556 -0.0759826957 0.0156560179 0.0629763753 -0.0182669232 -0.021118611699999998 -0.015509651200000002 -0.0067083703000000005 -0.0030548094 -0.1021812774 0.060642363 0.057615290599999994 0.0526815972 0.046004549699999994 0.0378051071 0.0283546073 0.0179657891 -0.130787 0.00327637 -0.0549245 0.00168537 -0.00356012 0.000378397 -421.4149475097656 352.7333984375 346.0684814453125 1.07985 65.084755 0.241332065 0.0209045278 0.0011166150999999999 -0.0104159162 -0.0825885704 0.0221189512 0.063141819 -0.0195401296 -0.0152460197 -0.0075687529000000005 0.0042409039 0.006294318399999999 -0.0916082194 0.060574563399999996 0.057348728499999994 0.052098980999999996 0.0450105913 0.0363337182 0.02637458 0.0154846479 -0.116168 0.0715134 0.011055 2.7343e-06 -0.00340434 0.000389912 -421.584716796875 353.0647888183594 346.3740234375 1.021754 61.583206 0.128318865 0.0325952896 -0.015737330900000002 0.0052867411 -0.0684415757 0.0177161657 0.042312542300000006 -0.0250786205 -0.0131969716 -0.014223595 0.0198133617 -0.0135185928 -0.0799757221 0.060504603 0.0570739836 0.05149963900000001 0.0439909442 0.0348299293 0.024360686200000002 0.0129764445 -0.117702 0.0848395 -0.007221799999999999 -0.00120561 -0.00386425 0.000625297 -420.8820495605469 352.388916015625 346.1412658691406 1.017181 61.307583 0.26043195 0.046300783600000006 -0.0138193137 0.0271737991 -0.064659733 0.0366652871 0.0376056794 -0.023186009100000002 -0.0260975862 -0.023854651600000002 0.0088141475 0.016341030700000002 -0.0686629118 0.0604324842 0.056791094900000005 0.0508837635 0.0429461904 0.0332950814 0.022315511899999998 0.0104455625 -0.127731 -0.0369069 -0.0206677 0.00087025 -0.00367072 0.00066012 -422.7683410644531 352.6333312988281 346.459228515625 1.086044 65.458061 0.24922650000000005 0.054704745 -0.011635776799999999 0.034030816 -0.046617276500000006 0.028861273700000002 -0.0600267943 -0.018493584 -0.0213040354 -0.0346088526 0.00048352059999999997 0.011412013700000001 -0.0220784731 0.0603582097 0.0565001029 0.0502515524 0.041876926 0.031730543 0.0202416832 0.007896425 -0.120646 0.0814662 0.0342868 -0.000492052 -0.00367072 0.000646144 -423.384765625 352.8699951171875 346.6176452636719 1.045051 62.987331 0.1679798 0.0574015149 -0.04572617019999999 0.036392041800000004 -0.018424803700000002 0.0049927445 -0.048185742999999996 -0.0164273839 -0.007311853399999999 -0.0375152985 0.0284772792 0.0045837666 0.0044404464 0.0602817821 0.056201049100000004 0.0496032084 0.0407837614 0.0301377094 0.0181418631 0.005333487099999999 -0.125901 0.0299356 0.024601 -0.00241004 -0.00361808 0.000586604 -422.10693359375 353.3209228515625 346.6868591308594 1.034287 62.338581 0.16245489999999999 0.0469631784 -0.0329227317 0.0281633687 0.0083475625 -0.00048329199999999997 -0.0141796619 -0.0236444559 -0.0034240401 -0.0348991242 0.0281253477 0.00769393 0.011555743200000001 0.0602032042 0.055893976100000006 0.0489389399 0.0396673204 0.0285180009 0.0160187477 0.0027612279999999997 -0.144605 0.0216047 0.0614511 -0.00165331 -0.00255512 0.000434896 -398.93359375 335.9974670410156 327.3197021484375 2.372919 143.02063 1.7024711 -0.1427911374 0.047946572800000004 0.1193466606 0.0544291915 0.1623886163 -0.0263057648 0.221133462 -0.10771889949999999 0.13227521539999998 0.0017588622 -0.0046823567 0.0931726563 0.0601224786 0.055578927800000004 0.0482589599 0.038528240299999995 0.0268728619 0.0138750634 0.0001841432 -0.0850468 0.352415 1.15167 -0.00345532 -0.00132072 0.00183616 -431.0296325683594 351.3997497558594 347.8903503417969 2.497537 150.531601 1.0051556 -0.06591874639999999 0.0765469858 0.0095970056 -0.0178579808 -0.1354692434 -0.0243402297 0.0276067227 0.068102204 0.0898778094 -0.075914126 -0.0438739834 0.006149240500000001 0.0600396084 0.0552559492 0.047563487 0.0373671711 0.0252037594 0.011713562700000001 -0.0023932635000000002 -0.0399239 0.0523428 0.694779 -0.00622349 -0.00199618 0.00245392 -419.92950439453125 352.5096740722656 347.37646484375 1.408989 84.922646 0.6610651000000001 -0.025038992200000002 0.0758815888 -0.0168802328 0.0013054832000000001 -0.0176771591 -0.047734745300000006 -0.0099677826 -0.0081084539 0.0800175586 -0.0452100625 -0.0072860112 0.0076167113 0.059954596500000006 0.0549250863 0.0468527442 0.0361847754 0.023512181899999998 0.0095370211 -0.0049664875 -0.0493701 0.0342794 0.351993 -0.00158095 -0.00193633 0.00134092 -419.6159362792969 352.8754577636719 347.1625671386719 1.087554 65.549065 0.1817865 -0.0222122365 0.081284435 -0.0233879573 -0.0060134726 -0.0247465624 -0.0339021706 -0.0105451511 -0.0037452589000000003 0.0901970535 -0.0379553977 -0.022177183 -0.0048742068 0.0598674458 0.0545863863 0.0461269599 0.0349817282 0.0217996377 0.0073482335 -0.0075310317 -0.0463575 0.126588 0.338763 -0.00236933 -0.00207881 0.0008070739999999999 -422.2381896972656 352.85284423828125 346.58770751953125 1.062381 64.031845 0.11410094999999998 0.0071009763 0.0851601353 -0.0074290737 -0.027577419 -0.0400239131 -0.003893772 -0.0183355596 -0.005928689599999999 0.0739623988 -0.0350165671 0.013235366 -0.044375791100000006 0.0597781596 0.054239897599999996 0.0453863669 0.033758716 0.020067654 0.0051500103000000005 -0.010082414100000001 -0.0492555 0.106455 0.313232 -0.00199062 -0.00265628 0.000452475 -420.8116455078125 352.6007385253906 345.61712646484375 1.011807 60.983639 0.09175215 0.021658197799999997 0.0967694036 0.0164264371 -0.0287854502 -0.0353801541 0.0036693646000000003 -0.015388752 -0.014942166299999999 0.0712594591 -0.0406792588 0.0261162648 -0.035990155499999996 0.059686740999999995 0.053885669500000004 0.044631203099999996 0.0325164369 0.0183177752 0.0029451740999999997 -0.012616175600000001 -0.0393361 0.0916108 0.344488 -0.00175217 -0.00227646 0.000548856 -422.9323120117188 352.4203796386719 345.6949768066406 1.059777 63.874928 0.09987395 0.0260364647 0.09381332869999999 0.025705270099999997 0.0045152457 -0.0281201 -0.0459503911 -0.0141642325 -0.014653931499999998 0.0794819558 -0.0379641987 0.020624369099999998 0.0040923684 0.059593193200000005 0.053523752699999996 0.043861710899999996 0.0312555998 0.0165515619 0.0007365563000000001 -0.0151278882 -0.0392628 0.133787 0.339265 -0.00238847 -0.00250708 0.0007299649999999998 -420.8698425292969 352.14141845703125 344.97369384765625 1.016259 61.251968 0.14305134999999997 0.0403816914 0.08101173589999999 0.0465354984 0.0348371691 -0.0185282176 -0.0314608136 -0.0147986393 -0.0246743783 0.053034382000000005 -0.0381648646 0.0415512989 0.0253855283 0.0594975196 0.053154198799999997 0.0430781374 0.029976924199999998 0.0147705889 -0.0014730073999999998 -0.0176131622 -0.0519379 0.08368119999999998 0.331422 -0.00109394 -0.00257144 0.000640306 -419.6549377441406 352.02508544921875 344.7625732421875 0.980091 59.072094 0.0865202 0.024214802400000002 0.068124497 0.0184677969 0.0677674363 -0.0561211904 0.0364049215 -0.0113373764 -0.0218900068 0.052820999400000006 -0.0478279063 0.0230809311 0.0567904983 0.0593997236 0.0527770605 0.042280734 0.0286811401 0.0129764445 -0.0036806797 -0.020067654 -0.046333 0.112999 0.345634 -0.00145787 -0.0022119 0.000616066 -419.5580139160156 351.7615661621094 344.95654296875 0.977007 58.886185 0.08806160000000002 0.0084624295 0.06577136110000001 -0.0008156749 0.0838519674 -0.0086116087 0.0357125007 -0.011538676000000001 -0.0301710611 0.06352220780000001 -0.0348161446 0.0099240873 0.0590846897 0.0592998088 0.052392391600000005 0.0414697568 0.0273689869 0.011170728500000001 -0.0058836257 -0.022487074 -0.0491731 0.139818 0.33718 -0.00183489 -0.0026047 0.0008452159999999998 -418.5008850097656 351.43280029296875 344.5787658691406 0.974061 58.708618 0.12656724999999996 -0.016421414 0.0651636451 -0.0194463884 0.086367444 -0.0015944016 0.047496738 -0.007705545899999999 -0.0310243167 0.05627512 -0.042952150700000004 0.0371919003 0.053349555300000004 0.0591977785 0.0520002471 0.0406454662 0.026041213599999998 0.0093550512 -0.0080790168 -0.0248671939 -0.0556319 0.099929 0.334977 -0.000686556 -0.00233067 0.000707251 -420.9892578125 351.54791259765625 345.009521484375 1.003108 60.459343 0.07933844999999998 -0.0164994482 0.0617951317 -0.048894435 0.0763371138 0.0193727231 -0.0279058335 -0.0062813855 -0.0340348075 0.0623236254 -0.0297092848 0.0046927951 0.0416852363 0.0590936366 0.0516006827 0.0398081268 0.0246985778 0.0075310317 -0.010264034 -0.027203854 -0.049199 0.137466 0.339039 -0.00115688 -0.0023668 0.000587574 -420.02740478515625 352.0018005371094 345.2995910644531 0.984135 59.315811 0.07033299999999998 -0.0226097346 0.0694879792 -0.0554352651 0.057112466900000006 0.0241277383 0.006725675 -0.0115110718 -0.033804618 0.0619905498 -0.0190197189 0.0063840547 0.0102565166 0.0589873867 0.0511937557 0.0389580073 0.023341845899999998 0.0057002965 -0.012435871599999999 -0.0294929706 -0.0491411 0.132809 0.305769 -0.00142164 -0.0026515 0.000685076 -420.0936584472656 352.0654296875 345.16571044921875 0.957042 57.682842 0.13281205 -0.0285900512 0.0773623299 -0.06706773519999999 0.046439384400000006 0.0308971175 -0.0326689468 -0.0159388611 -0.0339291298 0.0665602976 -0.035628336600000005 0.0218685 0.0085294545 0.0588790326 0.050779524000000006 0.0380953808 0.021971792200000003 0.0038644781 -0.0145917409 -0.031730543 -0.0521226 0.0966436 0.330312 -0.000687571 -0.00211005 0.000578152 -420.8419494628906 351.9255065917969 345.1107177734375 1.074755 64.777657 0.14086359999999998 -0.0194845099 0.08939296029999999 -0.0719224272 0.0217078052 0.0193211646 -0.027653851899999998 -0.004147429 -0.035500839900000004 0.0582776025 -0.0666198221 -0.0075161073 -0.023371317599999997 0.058768578200000005 0.0503580468 0.0372205242 0.020589198700000002 0.0020252136 -0.0167288735 -0.0339126607 -0.056943 0.164878 0.329525 -0.00145408 -0.00230616 0.000200335 -421.6316223144531 352.25726318359375 345.7149963378906 1.050525 63.317265 0.10525315 -0.0108672556 0.07977497759999999 -0.0706419742 -0.0005168124 -0.0023040367 0.008923870300000001 -0.014216630400000001 -0.022347716400000002 0.0827686301 -0.0387851744 -0.0123695003 -0.0396643459 0.058656027300000003 0.0499293841 0.0363337182 0.019194854299999998 0.0001841432 -0.0188445253 -0.036035509900000005 -0.046556 0.173401 0.318929 -0.00230152 -0.00249998 0.000674018 -422.5867004394531 352.7898254394531 345.7652893066406 1.004552 60.54636 0.1451869 -0.0117407584 0.0833498846 -0.0438805796 -0.005164172 0.0397863951 -0.049954360999999996 -0.0183958325 -0.028527547400000002 0.06408507349999999 -0.0336385317 0.005388817299999999 -0.0388999162 0.0585413841 0.049493597199999996 0.0354352477 0.017789555 -0.0016570915 -0.020935979599999998 -0.0380953808 -0.0543704 0.10232500000000001 0.310844 -0.00140163 -0.00223564 0.000674018 -420.9111633300781 352.42889404296875 345.86029052734375 0.99781 60.140015 0.043292800000000006 -0.0149964254 0.089559924 -0.0596858254 0.009553058199999999 0.0212191985 0.012677600700000001 -0.0178423251 -0.0266844646 0.0701058886 -0.04581336900000001 0.0076488453 -0.0333499027 0.058424652599999995 0.0490507482 0.0345254011 0.0163741027 -0.0034968484000000005 -0.023000551 -0.0400886733 -0.0491631 0.100818 0.33726 -0.00131407 -0.00211995 0.000674018 -422.1372680664063 352.82208251953125 346.4076232910156 0.992392 59.813477 0.13316890000000003 -0.0063103494999999996 0.07559037910000001 -0.0564093232 -0.0113529032 -0.0004702771 0.0081464173 -0.0210727 -0.0209745732 0.0761021816 -0.050849091500000006 0.0016676946 -0.042464985 0.058305837 0.0486009003 0.0336044704 0.0149493052 -0.005333487099999999 -0.0250355883 -0.0420119037 -0.051959 0.152228 0.316758 -0.00207414 -0.0025291 0.000674018 -422.01220703125 352.0959167480469 345.8276062011719 0.992604 59.826241 0.14353344999999998 -0.0012500598 0.0938199256 -0.036478351400000004 -0.025344492000000003 0.0098315538 0.0326452235 -0.0204448392 -0.0429510079 0.0639378764 -0.041268719700000005 0.0069091149 -0.07418235150000001 0.058184941500000004 0.048144117699999996 0.0326727513 0.013515975800000002 -0.007165369699999999 -0.0270384785 -0.043861710899999996 -0.059927 0.0966176 0.307193 -0.000981214 -0.00228794 0.000600303 -421.3096923828125 351.9723815917969 345.3363037109375 0.99018 59.680157 0.10080695000000003 0.020632556399999998 0.1107013187 -0.0042676456 -0.028600071600000002 0.0053936869 0.0581724645 -0.015060127 -0.0415001583 0.070320965 -0.0450211627 0.030595126099999998 -0.056845413399999996 0.0580619705 0.0476804656 0.031730543 0.0120749325 -0.0089908627 -0.0290066498 -0.0456348621 -0.049109 0.130359 0.344162 -0.0011809 -0.00240011 0.000674018 -423.3329162597656 352.4549255371094 345.5524597167969 1.036358 62.463375 0.08394100000000003 0.0321221653 0.0821588092 0.0112712098 -0.0241307394 0.0094092558 0.0090994626 -0.0209235269 -0.0335143023 0.0544769421 -0.0458167459 0.022111012599999997 -0.0387157813 0.0579369282 0.04721001019999999 0.0307781479 0.010626997800000001 -0.010808338300000001 -0.0309375749 -0.0473282582 -0.0516745 0.14868 0.324001 -0.00203155 -0.00239289 0.000674018 -421.2816162109375 352.1495666503906 345.1146545410156 0.984695 59.349564 0.13054564999999999 0.049276664299999995 0.098600015 0.045764886500000004 -0.0026007236 0.0297581227 -0.0253809388 -0.0196968869 -0.049635215999999996 0.0475783343 -0.0535346671 0.0425155371 -0.012113746399999998 0.057809819299999995 0.046732818499999995 0.0298158718 0.0091729979 -0.012616175600000001 -0.032828774399999996 -0.0489389399 -0.0562372 0.102166 0.314577 -0.000720861 -0.00230268 0.000674018 -421.7989501953125 352.4520263671875 345.4519958496094 1.01417 61.12606 0.09187944999999997 0.0471833567 0.0775306207 0.0453196231 0.032335164900000005 0.0193860546 -0.0480464934 -0.018753318300000002 -0.0390848721 0.0405697037 -0.040324131 0.0439859162 0.023938551000000002 0.057680648099999995 0.0462489587 0.028844023599999997 0.0077137627000000005 -0.0144127627 -0.0346778198 -0.050464092099999996 -0.0562707 0.131836 0.33684 -0.00148306 -0.00226662 0.000674018 -421.82696533203125 351.92694091796875 345.33880615234375 0.984491 59.337288 0.090953 0.04884894769999999 0.057143655300000006 0.036861062 0.0558083891 0.010391676899999999 -0.0066740566000000005 -0.0153641154 -0.0516928866 0.0332340851 -0.0403141081 0.0337259373 0.0364109779 0.0575494194 0.0457584997 0.0278629153 0.0062501251 -0.0161964974 -0.036482337000000004 -0.0519010494 -0.0585374 0.145674 0.303843 -0.00122302 -0.00264945 0.000479862 -420.4350891113281 351.8567199707031 344.9952392578125 0.970668 58.504154 0.10880215 0.038339435299999995 0.06106300480000001 0.037040957299999996 0.0712971091 0.019802508 0.00498487 -0.0171071933 -0.055865911799999994 0.0221849333 -0.037471685299999995 0.046710996500000004 0.0362973912 0.057416137699999995 0.0452615117 0.0268728619 0.0047829204 -0.0179657891 -0.038240008799999996 -0.0532473004 -0.0562867 0.111549 0.314946 -0.000640772 -0.00216584 0.000319251 -411.7018432617188 343.9233703613281 336.9710388183594 2.315594 139.565567 1.0493242999999999 -0.140014633 0.0263660836 0.1527444433 -0.019366587 0.1276142973 -0.0339685631 0.1477971323 -0.06483377059999999 -0.022276556 0.0825939779 0.2615088252 -0.0525655451 0.0572808079 0.0447580654 0.025874181200000002 0.003312986 -0.0197190601 -0.0399485782 -0.0545004924 -0.34335 0.00579925 0.580768 -0.00451201 -0.000408454 -0.00186591 -406.6715393066406 337.8937072753906 328.2170715332031 3.021919 182.137177 4.63682895 -0.1512857521 -0.0405221311 0.12172312539999999 -0.0424288011 -0.0358941775 -0.0363868485 0.24780462050000002 -0.0267579577 -0.20872831649999998 -0.4869278987 -0.26469541879999997 0.0315440031 0.057143434800000004 0.0442482328 0.0248671939 0.0018411607000000001 -0.0214547469 -0.041605851299999996 -0.055658435199999995 -0.785518 -0.598966 0.124274 -0.0342055 0.0186851 -0.0157469 -426.7735900878906 353.6833801269531 349.4693298339844 2.737723 165.008102 2.5332849 -0.0602188473 -0.06905555070000001 0.0827582711 -0.0346816995 -0.0053623935 -0.0393583732 0.0442475612 0.134109126 -0.0977769148 0.09789014 0.11653050890000001 -0.0254722208 0.0570040233 0.0437320865 0.0238522233 0.0003682847 -0.023171301800000002 -0.04320970019999999 -0.056719105 -0.345343 -0.361124 0.0526061 -0.0186456 0.00785401 -0.00646589 -423.85748291015625 352.9365539550781 346.9892272949219 1.355973 81.72721099999998 1.3039016 -0.010290669 -0.1105192422 0.0698629266 -0.047344492 0.0201073664 0.0140158973 0.0150962047 0.0533928544 -0.0871943519 0.0893268112 -0.0278773912 -0.0027797946 0.0568625783 0.04320970019999999 0.0228295951 -0.0011048015 -0.0248671939 -0.0447580654 -0.057680648099999995 -0.198136 -0.126131 0.0313255 -0.0104505 0.00244788 -0.0020587 -421.3736267089844 351.91943359375 345.1015625 0.986294 59.445927 0.1167808 -0.013490106799999999 -0.0973536541 0.09162838039999999 -0.055564845700000004 0.0044217701 -0.026089552599999996 0.0322233682 0.044706223499999996 -0.0799900065 0.0781528511 -0.011253983 0.0017219964 0.056719105 0.042681148499999995 0.0217996377 -0.0025772572 -0.0265409112 -0.0462489587 -0.0585413841 -0.198155 -0.171326 0.0816158 -0.0105364 0.00278751 -0.0020587 -425.155029296875 352.4478759765625 345.5978698730469 1.075659 64.83215300000002 0.4580656499999999 0.0074858701 -0.1053277941 0.06825491040000001 -0.035462776099999996 -0.0421025007 -0.051882841 0.019173816899999998 0.058738713399999996 -0.0809222911 0.052828784299999994 -0.0391781207 0.026246303500000002 0.0565736083 0.0421465068 0.0207626817 -0.0040482420000000005 -0.0281909609 -0.0476804656 -0.0592998088 -0.144181 -0.0643765 0.182013 -0.0102576 0.000888942 -0.000301169 -422.0338134765625 352.4966125488281 345.1971740722656 1.048604 63.201485 0.09340305000000008 0.0008459817999999999 -0.08343886589999999 0.0710851889 0.0030720336 -0.0366290739 0.004945483 0.0192978559 0.055334574500000004 -0.0657208242 0.0634196843 -0.0165337258 0.0418577167 0.056426093600000005 0.041605851299999996 0.0197190601 -0.0055169164 -0.0298158718 -0.0490507482 -0.059954596500000006 -0.133104 -0.111184 0.171253 -0.0100454 0.000695615 -0.000390813 -422.3327026367188 352.5309753417969 344.9027404785156 0.976954 58.882984 0.1101332 -0.0010449014 -0.11094984779999999 0.0549021776 0.013715550900000002 -0.0335557518 0.0472933558 0.0153818674 0.0501034229 -0.0652949671 0.0659490225 -0.0249431474 0.0566696309 0.05627656599999999 0.041059259300000005 0.0186691079 -0.0069824421 -0.0314141948 -0.0503580468 -0.060504603 -0.138634 -0.0963438 0.148473 -0.00918632 0.000347823 -0.000523601 -423.12579345703125 352.14959716796875 344.9751892089844 0.974718 58.748241 0.09280588499999994 -0.009164399200000001 -0.1193736657 0.0352633273 0.0346495531 -0.007306515600000001 0.015210751100000001 0.010604373600000001 0.040092527200000005 -0.0582455717 0.0617013226 -0.04832178559999999 0.0619843492 0.0561250309 0.0405068086 0.0176131622 -0.0084439827 -0.0329845047 -0.0516006827 -0.060948867000000004 -0.138671 -0.0354011 0.151107 -0.009162890000000002 0.000264909 -4.61013e-05 -420.6154174804688 352.36676025390625 344.5677795410156 0.985531 59.399971 0.191710215 -0.021823414399999998 -0.083125815 0.0096157646 0.0317464067 -0.022184738500000002 0.0598005704 0.012138259299999999 0.034367673599999995 -0.0408439282 0.0531002897 -0.0316605711 0.050811753 0.0559714938 0.0399485782 0.0165515619 -0.0099007042 -0.0345254011 -0.0527770605 -0.0612866121 -0.11513300000000003 -0.0784964 0.210933 -0.00824821 0.000123522 0.00020285 -421.3871765136719 351.6932373046875 344.2662048339844 0.996876 60.083744 0.06981079999999998 -0.0435387141 -0.0896067772 -0.0100391779 0.0382412935 -0.010765718600000002 0.0097776887 0.0190488044 0.0439872049 -0.0336495534 0.0522168985 -0.041098047900000004 0.0626021572 0.05581596 0.039384647599999996 0.0154846479 -0.011351775 -0.036035509900000005 -0.053885669500000004 -0.061517248 -0.11696 -0.0484236 0.227956 -0.00848776 0.000301732 0.00020285 -420.5823669433594 352.1018371582031 344.6817932128906 0.987586 59.523834 0.09902055000000007 -0.0399608287 -0.0987900573 -0.0164352011 0.0291720993 0.029245059500000004 0.0135080397 0.0137511808 0.031064280299999997 -0.046117299199999996 0.0779014383 -0.042572051799999996 0.031308939 0.055658435199999995 0.038815097400000005 0.0144127627 -0.012796367099999999 -0.0375134847 -0.0549250863 -0.0616403716 -0.126945 -0.0452775 0.16998 -0.007987869999999998 0.000243353 0.00020285 -421.11663818359375 352.0289001464844 344.3695983886719 0.988543 59.581467 0.1015212 -0.0519278193 -0.0808235913 -0.0539017575 0.0079110811 0.0360284556 -0.0337369291 0.013846895900000001 0.0326332931 -0.030396788900000003 0.06924780900000001 -0.040652541699999996 0.0058117472 0.0554989249 0.038240008799999996 0.0133362505 -0.014233656 -0.0389580073 -0.055893976100000006 -0.0616557679 -0.122992 -0.092175 0.200805 -0.007710299999999998 0.000362697 0.00020285 -421.8263854980469 352.24920654296875 344.9517517089844 0.993521 59.881538 0.15708899999999998 -0.0513925392 -0.06611677980000001 -0.0697473975 -0.0284605222 0.0141361492 -0.030075356 0.012946848200000001 0.0417068195 -0.012562811100000001 0.054984658 -0.0493826808 -0.0243462438 0.0553374348 0.0376594638 0.012255456699999999 -0.0156628214 -0.0403677898 -0.056791094900000005 -0.061563409699999995 -0.10947 -0.0295423 0.230782 -0.008388879999999998 0.000123522 0.000101459 -412.33538818359375 345.93560791015625 338.9577941894531 1.414911 85.279579 1.30734705 -0.1609145862 -0.0006602997000000001 0.0217906127 -0.0284179267 0.0580589071 0.0200380702 0.1151009034 0.024335341899999998 -0.0016513557999999998 0.020284848 0.0769789823 -0.055700632800000004 0.0551739708 0.037073545299999996 0.011170728500000001 -0.0170830476 -0.0417415748 -0.057615290599999994 -0.0613634587 -0.600279 -0.15884799999999996 0.460186 -0.0119036 0.0011248400000000002 -0.00453907 -422.26361083984375 352.21002197265625 345.0701599121094 1.628014 98.123718 0.8224001 -0.0556032232 0.0076044111 -0.0383490161 -0.042735997000000005 -0.0806892439 -0.0077987622 0.0236245798 0.0701054165 0.012761761299999999 -0.030042388599999997 -0.011574696 -0.027771065299999998 0.055008538600000004 0.036482337000000004 0.010082414100000001 -0.018493524 -0.0430781374 -0.0583655051 -0.0610562642 -0.372361 -0.08851739999999998 0.378429 -0.00901273 -0.00244952 -0.00215641 -419.70654296875 352.1386413574219 344.7178039550781 1.148872 69.244812 0.649793823 -0.0316314017 -0.0059245074 -0.045988676799999996 -0.050562445 -0.0098425192 0.026574572400000003 0.0110040743 0.0329047992 0.0189949095 0.0229840498 -0.0291243716 -0.0489673327 0.0548411441 0.0358859231 0.0089908627 -0.0198934458 -0.044376285700000004 -0.0590407749 -0.060642363 -0.194562 0.000699273 0.287894 -0.00702926 -0.00116084 0.000416303 -421.6029052734375 352.6191101074219 345.4739685058594 1.001007 60.332726 0.16053932299999998 -0.0230571044 0.0040054329 -0.037859123599999996 -0.0595543309 -0.006473151999999999 0.030290801200000002 -0.0019553795000000003 0.0201338049 0.0183163278 0.015452433500000001 -0.026197428 -0.0640191682 0.0546717934 0.0352843888 0.007896425 -0.0212820138 -0.0456348621 -0.059640233 -0.0601224786 -0.166946 -0.017082199999999995 0.2657 -0.0060121 -0.000764249 0.000861509 -421.3460998535156 351.92645263671875 345.3215026855469 0.98042 59.091919 0.05068375000000004 -0.0095626285 0.0107966055 -0.006839978399999999 -0.0710822701 -0.0249390302 0.058705664000000005 0.0041221452 0.0158317552 0.0243756202 0.0139965473 -0.0219018265 -0.054577558899999996 0.0545004924 0.0346778198 0.006799452199999999 -0.022658435600000002 -0.0468527442 -0.060163109699999995 -0.0594975196 -0.162101 -0.0126845 0.289122 -0.00600269 -0.0007449839999999998 0.000529803 -422.08251953125 352.1204833984375 345.5599670410156 1.020867 61.529728 0.094746 0.0111026098 0.0027382465000000003 0.0424968238 -0.062038024500000004 -0.016072580700000002 0.0230514466 0.0017398342 0.0135934221 0.016300346299999997 0.0170587955 -0.014983705 -0.038680295 0.054327247300000006 0.034066302799999996 0.0057002965 -0.0240219257 -0.0480288462 -0.0606087335 -0.058768578200000005 -0.14863 0.0193024 0.286774 -0.00637674 -0.00122803 0.000611509 -423.6099243164063 352.4850769042969 345.4602966308594 1.021817 61.586975 0.09845851999999998 0.0326022333 -0.0018843774 0.054401008 -0.0395938994 0.0063552339 -0.0775646331 -0.0035065216999999997 0.0035503328 -0.0158895316 0.0314019293 -0.0021568734 -0.0127554307 0.0541520642 0.033449925 0.0045993107 -0.0253717058 -0.0491621191 -0.060976532199999996 -0.0579369282 -0.148625 -0.00932372 0.270622 -0.00571006 -0.00130709 0.000939277 -422.0148010253906 352.59234619140625 345.0855712890625 1.025261 61.794582 0.07011804999999999 0.03530306 -0.0052949603 0.0517087126 0.0324944294 -0.0201829015 -0.0139581524 -0.007947328299999999 0.0025202964 -0.026179402400000003 0.0164536396 0.013674565900000001 0.0393571142 0.05397494940000001 0.032828774399999996 0.0034968484000000005 -0.0267070056 -0.0502515524 -0.061266033600000006 -0.0570040233 -0.148652 0.00681013 0.259946 -0.00515821 -0.00116597 0.000766623 -419.9576110839844 352.22589111328125 344.8659362792969 1.017478 61.325474 0.15858056999999998 -0.0066042404 -0.015216674 0.0178103278 0.0667976788 -0.022552459599999998 0.0443864479 0.0051016187 0.0095032546 -0.0082688539 0.0197394979 -0.0029553319 0.0729415628 0.0537959092 0.0322029395 0.0023932635000000002 -0.0280270631 -0.0512961746 -0.0614768659 -0.0559714938 -0.131833 0.0442354 0.319501 -0.00589689 -0.00122803 0.000861509 -419.1692199707031 351.9072570800781 344.8193054199219 0.999974 60.270443 0.17284706999999996 -0.013523736599999999 -0.0316973263 -0.0183360914 0.0655494045 0.0207046488 0.047339624500000003 0.0022922893 0.0008444959 -0.0114018374 0.030239916800000002 -0.0168914584 0.0489900895 0.05361495 0.0315725097 0.0012889102 -0.0293311248 -0.052295054199999996 -0.0616087584 -0.0548411441 -0.14864 -0.00463002 0.26083 -0.00501378 -0.00122803 0.000774546 -422.2080993652344 351.77520751953125 345.0199890136719 1.0209990000000002 61.537674 0.04832348999999999 -0.029674133199999998 -0.0130227646 -0.0652469496 0.024245606099999997 0.036242947000000005 -0.0680246689 -8.74695e-05 -0.007513824200000001 0.002493322 0.0195387395 -0.0176419092 0.0109649026 0.053432078200000004 0.0309375749 0.0001841432 -0.030618446400000002 -0.0532473004 -0.0616615418 -0.05361495 -0.148639 0.00334912 0.273765 -0.00460119 -0.00122803 0.000910123 -421.1476745605469 352.0025634765625 345.3072204589844 1.011521 60.966393 0.13087913000000004 -0.0253533942 -0.0075364622999999995 -0.0520653275 -0.0298595659 -0.0055366024 0.0271307961 -0.0015108367999999998 0.0123181726 0.0081131835 0.0098232076 -0.0330897874 -0.038171439700000004 0.0532473004 0.030298225699999997 -0.000920683 -0.0318882933 -0.0541520642 -0.0616351482 -0.052295054199999996 -0.148659 0.0466931 0.273959 -0.00606827 -0.00111506 0.00074375 -422.443603515625 353.1455383300781 345.93023681640625 1.013024 61.056988 0.11047275 -0.0047724107 -0.004100558 -0.028383765699999997 -0.0331047151 0.0145684476 -0.0096712461 -0.0057066719999999994 0.0231407948 -0.0044196893 0.0176076219 -0.0178620323 -0.034342598700000004 0.053060623200000004 0.0296545534 -0.0020252136 -0.0331399408 -0.055008538600000004 -0.0615296116 -0.0508837635 -0.15298 0.0181712 0.247213 -0.00519017 -0.000976694 0.000744961 -423.72509765625 352.70269775390625 346.3428649902344 1.239178 74.687798 0.63970315 0.0100820409 -0.0100970238 -0.0181514204 -0.009900476 0.047882884400000006 -0.0085173117 -0.0154346176 -0.0387876704 -0.0670135483 -0.026783944700000003 0.026712436800000003 -0.030635157200000002 0.052872053200000005 0.0290066498 -0.0031290940000000002 -0.0343726744 -0.05581596 -0.0613450675 -0.0493835445 -0.255264 -0.0532813 0.155492 -0.000184466 0.000173296 -0.000584258 -424.0235900878906 353.2411804199219 348.4553527832031 1.18508 71.427155 0.4619082 0.0116415245 -0.015717168 -0.0075574978 -0.0008989042 -0.0137517773 0.0390175523 -0.0194846575 -0.0068618892 -0.0346567923 0.003789184 -0.012907359399999999 0.0054819002000000006 0.0526815972 0.0283546073 -0.0042319699 -0.0355857906 -0.0565736083 -0.0610817528 -0.047797019100000004 -0.164493 0.0668166 0.184002 -0.00331075 -0.00024928 0.000317468 -426.7287292480469 353.33331298828125 349.5809631347656 1.067668 64.350525 0.12247159999999997 0.0329395123 -0.0380657972 0.0284983517 -0.002208613 -0.0349453147 -0.044464301399999996 -0.0199671418 -0.0052670569 -0.0497692444 0.0009301260000000001 -0.0112891829 0.013866178 0.05248926190000001 0.027698518999999998 -0.005333487099999999 -0.0367785971 -0.0572808079 -0.0607400057 -0.0461269599 -0.147122 0.0918347 0.184067 -0.00433099 -0.000494035 0.000652823 -425.2648010253906 353.80419921875 349.080078125 1.087379 65.538528 0.1739615 -0.0025439508 -0.0645197586 0.0044449224 0.0196160725 -0.011476529499999999 0.0236914491 -0.029681967599999998 -0.0038229805 -0.050313753899999994 0.0333174243 -0.004880085399999999 0.0304541764 0.052295054199999996 0.0270384785 -0.0064332921 -0.0379504132 -0.0579369282 -0.060320264900000004 -0.044376285700000004 -0.147487 0.0111253 0.178028 -0.00399612 -0.0015237 0.00102525 -424.3199157714844 353.46234130859375 347.88885498046875 1.065323 64.209198 0.11361006 -0.019359129 -0.030299344199999998 -0.0324576533 0.0174173986 0.0207967768 -0.038853588599999996 -0.0228127766 -0.0012870534 -0.030859670099999997 0.0166370144 -0.0055382187 0.0176991012 0.052098980999999996 0.02637458 -0.0075310317 -0.0391005699 -0.0585413841 -0.0598230695 -0.0425480561 -0.144523 0.00122084 0.217871 -0.00346856 -0.00117411 0.000684428 -424.447265625 353.04541015625 347.0809631347656 1.044102 62.930126 0.12319001 -0.007949013000000001 -0.0157325317 -0.0546440931 -0.0284994912 0.0053424232 -0.014564523400000001 -0.0152612384 -0.0047259256 -0.0159998027 0.0038210345000000002 -0.018898113600000002 -0.033176218199999996 0.0519010494 0.025706918199999998 -0.0086263535 -0.0402284109 -0.0590936366 -0.059249057800000005 -0.0406454662 -0.136115 0.0699199 0.227507 -0.00390468 -0.00100735 0.000810487 -423.0267639160156 353.0918273925781 346.9169006347656 1.02029 61.494957 0.07468219999999999 0.0034204138 -0.0082671429 -0.0231595077 -0.049812618499999996 0.0191993818 0.0346481726 -0.0183531311 -0.0015581166 -0.0215650322 0.0173019094 -0.0017136954 -0.0507609716 0.0517012663 0.0250355883 -0.009718906 -0.0413332925 -0.059593193200000005 -0.058598967 -0.038671841299999996 -0.14455 0.0535372 0.206661 -0.00363215 -0.00106519 0.000560487 -420.7662963867188 352.67364501953125 346.5449523925781 1.032509 62.231434 0.11187555 0.0315689345 0.0005005732 0.0090839018 -0.055163859 0.024191062000000003 0.0688759226 -0.0214015533 -0.0260780576 -0.0288583213 0.0045324983 0.0205198012 -0.0564557695 0.05149963900000001 0.024360686200000002 -0.010808338300000001 -0.0424145842 -0.0600396084 -0.0578736318 -0.0366306304 -0.14456 0.0353493 0.191298 -0.0022169 -0.00100735 0.000467284 -423.93927001953125 352.5133056640625 346.2904052734375 1.121366 67.587013 0.13035599999999997 0.04733408769999999 0.0014156239999999999 0.0426647129 -0.0281864587 0.0436816138 -0.055045484400000004 -0.0168542044 -0.0198235189 -0.0301330254 0.0034365110999999998 0.0225717539 -0.007694141999999999 0.0512961746 0.0236823082 -0.0118943007 -0.0434716687 -0.0604324842 -0.0570739836 -0.0345254011 -0.128064 0.0706941 0.223599 -0.00304798 -0.00100735 0.000560488 -422.9907531738281 352.2771301269531 345.9111633300781 1.059446 63.854927 0.06807634999999995 0.0442387282 -0.0284216713 0.025997447200000003 0.0273458532 0.0077598147 0.013992617800000001 -0.0158320237 -0.0179919105 -0.0417256952 0.0108040882 0.0150001183 0.0402561939 0.0510908803 0.023000551 -0.0129764445 -0.0445039428 -0.0607714702 -0.056201049100000004 -0.0323598325 -0.139381 0.0585212 0.218982 -0.00361761 -0.00109559 0.000702007 -419.16290283203125 351.9938659667969 345.31610107421875 1.019405 61.441601 0.05480925 0.0150123446 -0.0270548918 0.0077729106 0.059490626 0.0148409418 0.072820679 -0.0107184326 -0.020377359299999998 -0.0480038273 -0.002207285 0.0071492234 0.052335488 0.0508837635 0.022315511899999998 -0.0140544224 -0.0455108174 -0.0610562642 -0.0552559492 -0.0301377094 -0.145269 0.0476894 0.216105 -0.00314312 -0.00100735 0.000560488 -420.52490234375 351.8774108886719 345.6357727050781 0.999323 60.231236 0.059066500000000015 -0.0107894136 -0.0372027549 -0.0268895183 0.0663575781 0.0234962714 0.030529397799999997 -0.0052345711999999996 -0.014752473600000001 -0.0299254003 0.0086204664 0.0013052941 0.0584147304 0.050674831600000005 0.0216272887 -0.0151278882 -0.046491717800000006 -0.0612866121 -0.054239897599999996 -0.0278629153 -0.135848 0.0685374 0.233604 -0.00336909 -0.00100735 0.000560488 -421.9220886230469 352.42132568359375 346.16473388671875 0.995017 59.971672 0.04684109999999999 -0.0122464302 -0.040987799 -0.0398151606 0.055075004500000004 0.0432028292 0.002654992 -0.011446894099999999 -0.0064407833 -0.013427454699999999 0.0138111577 0.0096921309 0.0349358148 0.050464092099999996 0.020935979599999998 -0.0161964974 -0.0474460842 -0.06146230849999999 -0.053154198799999997 -0.0255394259 -0.133894 0.0640341 0.233579 -0.00408037 -0.00100735 0.000464592 -423.655029296875 352.2032165527344 346.036865234375 1.022664 61.63802 0.10244109999999997 -0.0108924143 -0.0253291679 -0.059484086299999996 0.028498052000000003 0.0525746077 -0.06541205 -0.0124911596 -0.0142341454 -0.0016922448000000001 -0.0060012252 -0.0004682761 0.0039740597 0.0502515524 0.0202416832 -0.0172599069 -0.048373371799999995 -0.061583196900000005 -0.0520002471 -0.023171301800000002 -0.139211 0.0372603 0.233612 -0.00276992 -0.00100735 0.000560488 -422.8269348144531 351.8955078125 345.72015380859375 1.032901 62.255028 0.0628376 0.0031846202 0.0016965867000000002 -0.0647812814 -0.0371533884 0.013863221499999998 0.0237596798 -0.0114849906 -0.0128405735 -0.0009810438 -0.0067530767 -0.0004806187 -0.058595716299999996 0.050037220099999995 0.0195444986 -0.0183177752 -0.049273051500000005 -0.061649169299999994 -0.050779524000000006 -0.0207626817 -0.135747 0.0694379 0.260808 -0.00276992 -0.00100735 0.000560488 -422.3298034667969 352.5283508300781 345.53253173828125 1.020615 61.514542 0.07075455 0.028310892400000003 0.0079770818 -0.009284709300000001 -0.04194572269999999 0.0335758861 0.028091559900000004 -0.0169482192 -0.009203803 -0.0025219066 -0.0036709369 0.008990871899999999 -0.0511325767 0.0498211028 0.0188445253 -0.0193697628 -0.0501446098 -0.061660167 -0.049493597199999996 -0.0183177752 -0.133156 0.0794016 0.233624 -0.00313038 -0.0011925 0.000635195 -421.76397705078125 352.1412658691406 345.0396728515625 1.016233 61.250404 0.09796690000000002 0.0469079034 0.0065316156 0.0302794958 -0.0399010428 0.029765555099999997 -0.0041900644 -0.015813141 -0.0197245233 -0.0148329272 -0.010684626599999998 0.022028690899999998 -0.0380047714 0.0496032084 0.0181418631 -0.020415532 -0.0509875493 -0.061616180199999995 -0.048144117699999996 -0.0158408552 -0.145298 0.0511935 0.233596 -0.00255463 -0.000832047 0.000419622 -421.668212890625 352.4126281738281 345.1544189453125 1.045984 63.043587 0.08495395000000001 0.056014343 0.0065050339 0.042569275 0.0029886021000000004 0.0305112313 -0.0542951683 -0.0190169963 -0.0198410097 -0.023766057900000002 -0.0019867001 0.0425179317 0.0130088221 0.0493835445 0.0174366123 -0.0214547469 -0.0518013888 -0.061517248 -0.046732818499999995 -0.0133362505 -0.12381 0.064013 0.251332 -0.00289667 -0.00100735 0.000560488 -421.45733642578125 352.3363952636719 345.3581848144531 1.029687 62.061314 0.11506919999999997 0.0430590613 -0.017535858600000002 0.0227367471 0.04986738 -0.00021544389999999999 0.036789385200000004 -0.016639526 -0.0161129623 -0.0191894439 -0.0074022048 0.0092403925 0.0589014053 0.0491621191 0.0167288735 -0.022487074 -0.052585664000000004 -0.0613634587 -0.0452615117 -0.010808338300000001 -0.128126 0.0936919 0.233655 -0.00367163 -0.00119648 0.0008643439999999999 -418.5904541015625 352.453125 344.7914733886719 1.01177 60.981419 0.12501580000000004 0.022747450699999998 -0.0227798644 -0.0007045468 0.0713965647 0.0101405214 0.0707293147 -0.015597615700000001 -0.0205560827 -0.0209622727 0.0001307197 0.012972831499999999 0.0712868117 0.0489389399 0.0160187477 -0.023512181899999998 -0.0533399272 -0.061154949400000005 -0.0437320865 -0.008261536600000001 -0.139388 0.0469917 0.23284 -0.00267814 -0.00100735 0.0007221919999999998 -420.1970520019531 352.1481628417969 345.12286376953125 1.0163700000000002 61.258701 0.06638705000000002 -0.0115672437 -0.0187214364 -0.0363913226 0.0772506508 0.0304733467 0.0134410365 -0.0129747108 -0.012850633799999999 -0.014532846399999999 0.0015036911 0.0148998483 0.0623525065 0.048714014900000005 0.015306336299999999 -0.024529741400000003 -0.054063747800000006 -0.0608919062 -0.0421465068 -0.0057002965 -0.129702 0.0639967 0.248669 -0.00283088 -0.000844453 0.000560488 -421.1519470214844 352.2944030761719 345.677490234375 1.028679 62.000572 0.08387764999999998 -0.0191555198 -0.0113687279 -0.0740546282 0.0326278564 0.033587060499999995 -0.04848576809999999 -0.0153904427 -0.0097177639 0.0035198442 -0.0053295571 -0.005014884 0.0145594218 0.0484873523 0.0145917409 -0.0255394259 -0.0547567129 -0.060574563399999996 -0.0405068086 -0.0031290940000000002 -0.128796 0.0916396 0.244544 -0.00330199 -0.00124153 0.000716376 -420.250732421875 351.9621887207031 345.43682861328125 1.021072 61.54208 0.12908690000000003 -0.0100714281 0.0078229543 -0.0756675527 -0.0127729425 0.033883288399999996 0.0120054373 -0.014763998700000001 -0.0144829328 -0.0054237747 -0.0115784902 -0.0006444371 -0.0383104183 0.0482589599 0.0138750634 -0.0265409112 -0.055418427 -0.0602032042 -0.038815097400000005 -0.0005524229 -0.140138 0.048092 0.224358 -0.00233185 -0.0011525900000000002 0.00069523 -420.20587158203125 352.2241516113281 345.4471435546875 1.004652 60.552383 0.06247405000000001 0.0155805453 0.0206955664 -0.037445390099999996 -0.046230978 0.0278935853 0.06871978969999999 -0.016195846599999997 -0.0170747834 0.0057310854000000005 -0.0194562041 0.0012556731 -0.0625127771 0.0480288462 0.0131564061 -0.0275338758 -0.056048512300000006 -0.0597781596 -0.037073545299999996 0.0020252136 -0.131823 0.0750799 0.237256 -0.00247947 -0.00106181 0.000648167 -420.1483459472656 352.3724365234375 345.9701232910156 1.010679 60.915668 0.08034924999999998 0.0428934479 0.0249091123 0.0047707122 -0.0436802046 -0.0006592569 0.0430127964 -0.0195466625 -0.0125282939 0.006737321700000001 -0.011866213600000002 0.010091188000000001 -0.0478874401 0.047797019100000004 0.012435871599999999 -0.0285180009 -0.056646609199999996 -0.0592998088 -0.0352843888 0.0045993107 -0.137174 0.090847 0.241034 -0.00320294 -0.0013864 0.00070917 -422.59063720703125 351.7917175292969 345.74945068359375 1.052734 63.450413 0.12072649999999997 0.0608201066 0.010710332099999999 0.0371698071 -0.030235705800000002 0.0369771852 -0.0638726565 -0.0184212899 -0.0223792846 -0.011411773899999998 -0.0036626540000000004 0.0234727806 -0.016307429499999998 0.047563487 0.011713562700000001 -0.0294929706 -0.0572123765 -0.058768578200000005 -0.033449925 0.007165369699999999 -0.137594 0.0525486 0.224341 -0.00220331 -0.00115182 0.000637078 -421.29986572265625 351.9552917480469 345.8060302734375 1.047556 63.138294 0.10921329999999996 0.0576419067 0.0026029484 0.025511076299999998 0.0335547387 -0.0055348796 -0.0131980484 -0.015406261999999999 -0.0208065425 -0.0107481317 -0.0217062896 0.022369652 0.0380040641 0.0473282582 0.0109895824 -0.0304584719 -0.0577454912 -0.058184941500000004 -0.0315725097 0.009718906 -0.1307 0.0885306 0.247465 -0.0029793 -0.0011392 0.000712734 -420.73577880859375 352.3150634765625 345.733154296875 0.99917 60.222 0.07258354999999997 0.041706262200000004 -0.0184354864 0.0223997494 0.060025749 -0.0183994632 0.054697039100000004 -0.0161431204 -0.014500616000000001 -0.0241901799 -0.0057932007999999995 0.0292429917 0.0519678439 0.0470913411 0.010264034 -0.0314141948 -0.058245649000000004 -0.0575494194 -0.0296545534 0.012255456699999999 -0.133555 0.0733817 0.218638 -0.00256723 -0.00123053 0.0007243869999999998 -420.08306884765625 351.7671203613281 345.2939147949219 1.007793 60.741749 0.05333959999999999 0.0041891768 -0.0198254472 -0.0175932816 0.0756969538 0.0085742553 0.07434574769999999 -0.015336922099999999 -0.021096962200000003 -0.010582414699999999 -0.012598728200000001 0.0238587301 0.0611686637 0.0468527442 0.0095370211 -0.0323598325 -0.0587125645 -0.0568625783 -0.027698518999999998 0.0147705889 -0.131418 0.0657809 0.225155 -0.00207763 -0.00100897 0.000693851 -423.5035095214844 351.83343505859375 345.78704833984375 1.055552 63.620228 0.14582495 -0.0022212572 -0.0221618295 -0.06857367730000001 0.0524280401 0.031936897 -0.08536141960000002 -0.0120981647 -0.0079309727 -0.0012811015 -0.0092078352 -0.0135205056 0.039327342 0.04661247599999999 0.0088086474 -0.0332950814 -0.059145971299999996 -0.0561250309 -0.025706918199999998 0.0172599069 -0.131354 0.113338 0.236542 -0.00307468 -0.0014429899999999997 0.000999118 -420.44146728515625 352.1424255371094 345.2920227050781 1.025828 61.828732 0.15480639999999998 -0.009734274499999999 -0.0033179588 -0.0761535579 -0.0010935507 0.0418810987 -0.012085762199999999 -0.0173074398 -0.0125526141 0.0104438516 -0.0050322672 -0.0010668259 -0.026027195 0.046370545 0.0080790168 -0.0342196412 -0.059545621900000005 -0.0553374348 -0.0236823082 0.0197190601 -0.14636 0.0411022 0.222327 -0.00220048 -0.00130746 0.000941856 -421.156005859375 351.77032470703125 345.34906005859375 0.997059 60.094769 0.05751199999999997 -0.0017915813 0.0222328836 -0.0659835125 -0.0349563418 0.0141904167 0.0483168108 -0.0128353294 -0.0167858246 0.0134502323 -0.014430826599999998 0.014295206699999998 -0.052305559800000005 0.0461269599 0.0073482335 -0.0351332152 -0.059911288300000004 -0.0545004924 -0.0216272887 0.0221437508 -0.141406 0.0622067 0.229839 -0.00214055 -0.00106879 0.0007616259999999998 -419.8749084472656 352.1002502441406 346.0054016113281 0.991145 59.738308 0.1235847 0.0187830046 0.0270941066 -0.048787141799999996 -0.0478364564 0.001308069 0.06684412969999999 -0.0192428624 -0.0078237746 0.018825390600000002 -0.0105304061 -0.0106381323 -0.0510144708 0.0458817293 0.0066164016 -0.036035509900000005 -0.060242761799999996 -0.05361495 -0.0195444986 0.024529741400000003 -0.13136 0.0998262 0.229849 -0.00310297 -0.00138267 0.0010035100000000002 -420.2380676269531 352.2232360839844 345.88690185546875 0.988142 59.557339 0.15901319999999997 0.0352320536 0.0180660672 -0.0206930178 -0.05477329190000001 0.0099443012 0.051767195 -0.020777261 -0.015811713300000002 0.0042228475 -0.011487230900000001 0.0123809277 -0.0636190823 0.0456348621 0.0058836257 -0.0369262359 -0.0605398531 -0.0526815972 -0.0174366123 0.0268728619 -0.144141 0.0623446 0.20504 -0.00206782 -0.00118201 0.000560488 -421.3014831542969 352.3474426269531 346.1163024902344 0.989916 59.664249 0.14210615 0.043538395 0.0317309044 0.0102378228 -0.0487624504 -0.010808993400000001 0.031209129500000002 -0.0197088058 -0.0061556642 0.0148086964 -0.014702346299999999 0.0260625643 -0.0499614533 0.0453863669 0.0051500103000000005 -0.0378051071 -0.0608023928 -0.0517012663 -0.015306336299999999 0.029169017400000004 -0.121592 0.0897106 0.244455 -0.00257634 -0.00138801 0.000901491 -423.5082092285156 352.45684814453125 346.5848388671875 1.007349 60.714935 0.06765149999999999 0.050004422300000004 0.0128519024 0.0184041507 -0.0470810616 -0.0021615157 -0.0185358183 -0.024310150200000002 -0.0097524138 0.0065539677 -0.0097770711 0.0234881856 -0.043787389100000004 0.045136252800000005 0.00441566 -0.038671841299999996 -0.061030231 -0.050674831600000005 -0.0131564061 0.0314141948 -0.129537 0.0878117 0.207519 -0.00225687 -0.0014389200000000004 0.000948543 -421.98175048828125 352.4674377441406 346.48699951171875 0.984024 59.309135 0.07226484999999999 0.0659706736 0.0255153135 0.0346400304 -0.024407384700000003 0.0037840275 -0.04567679980000001 -0.021180083399999997 -0.011121165700000001 -0.012753838 -0.0226552331 0.0406522816 -0.014079683300000001 0.0448845285 0.0036806797 -0.0395261602 -0.061223237699999995 -0.0496032084 -0.0109895824 0.0336044704 -0.139404 0.0709347 0.210039 -0.00190666 -0.00111379 0.000763866 -421.91644287109375 352.5434875488281 347.06170654296875 0.979836 59.056713 0.13207965 0.0511720541 0.0247754577 0.0404636385 -0.0038592081 -0.0043677991999999995 -0.0362591308 -0.020074775700000002 -0.0028774296999999997 -0.0009055799000000001 -0.0180998293 0.0259114375 0.0206788938 0.044631203099999996 0.0029451740999999997 -0.0403677898 -0.061381302699999994 -0.0484873523 -0.0088086474 0.0357360162 -0.125705 0.0913252 0.236421 -0.00290738 -0.0013468000000000004 0.000962299 -424.5956726074219 353.0257873535156 347.49896240234375 0.98071 59.109394 0.13525779999999998 0.0548632208 -0.0032903804 0.0345516735 -0.0106383276 -0.017932566299999998 -0.032322239700000005 -0.0281461233 -0.0090072964 -0.0240157807 -0.006515952199999999 0.0448917342 0.013481965600000001 0.044376285700000004 0.0022092484 -0.0411964596 -0.0615043357 -0.0473282582 -0.0066164016 0.0378051071 -0.136125 0.0632198 0.185429 -0.00213393 -0.00143565 0.000909791 -423.4337158203125 351.0511169433594 346.9137268066406 1.2241050000000002 73.779297 0.75588715 0.053105325 -0.051482634299999996 0.0533746272 -0.0263710535 0.073343466 -0.034570880299999995 -0.0194396851 -0.0767557274 -0.0967289998 0.0204480105 -0.00023613720000000002 -0.014254611499999998 0.0441197852 0.0014730073999999998 -0.0420119037 -0.0615922667 -0.0461269599 -0.00441566 0.0398081268 -0.209025 -0.0640874 -0.180222 0.00115299 -0.00168165 0.00117745 -423.36016845703125 352.31549072265625 347.3530578613281 1.279965 77.146057 0.7079362 0.0488106375 -0.0740092487 0.055478573600000004 -0.0132529394 -0.0077959643 -0.028707068 -0.0234683633 -0.0042026457 -0.054213518200000005 0.0194330744 -0.026318547 0.0205494757 0.043861710899999996 0.0007365563000000001 -0.0428138604 -0.0616450454 -0.0448845285 -0.0022092484 0.0417415748 -0.183722 0.0479202 0.0779605 -0.00383844 -0.00104118 0.000560488 -421.776611328125 353.0386657714844 347.6093444824219 1.115311 67.222038 0.2461377 0.0415283392 -0.024650441800000002 0.0269411138 -0.001303686 0.008462173 0.0012100341 -0.031195321 -0.0106448976 -0.0287546604 0.010190751999999999 0.0249977378 -0.0006807941999999999 0.043602072 0.0 -0.043602072 -0.0616626416 -0.043602072 -0.0 0.043602072 -0.156998 0.0258659 0.154264 -0.0018317 -0.00132201 0.000694036 -422.5987854003906 352.61468505859375 347.6229553222656 1.022264 61.613914 0.13955905 0.0475939041 -0.013389565700000002 0.0287908345 -0.0147380645 -0.0239198597 0.027153790499999997 -0.0257270585 -0.0133116777 -0.0144547541 0.0011449723 0.0154432904 -0.0008908646000000001 0.043340877699999995 -0.0007365563000000001 -0.044376285700000004 -0.0616450454 -0.042280734 0.0022092484 0.0453863669 -0.13451 0.0802086 0.174842 -0.00218975 -0.00159915 0.000901853 -427.1851501464844 352.84423828125 347.3974914550781 1.082326 65.233986 0.05052445000000001 0.0491078215 -0.0157803929 0.015651703200000002 -0.0030897131 -0.021324849 -0.0639854846 -0.0327311224 -0.0151717324 -0.0193028815 -0.00851609 0.0035450101 0.0125782207 0.0430781374 -0.0014730073999999998 -0.045136252800000005 -0.0615922667 -0.0409216928 0.00441566 0.0470913411 -0.13269 0.072536 0.167481 -0.00241841 -0.0018716 0.00107416 -419.48223876953125 347.6390380859375 341.1233215332031 1.44651 87.184082 0.5044752000000001 -0.019203801399999998 0.046765963099999995 0.0594293788 0.0349410231 -0.0192411494 -0.0195017133 0.0452155049 -0.0100364884 0.0166977451 -0.010073003399999999 0.1048758047 -0.0040857441 0.0428138604 -0.0022092484 -0.0458817293 -0.0615043357 -0.0395261602 0.0066164016 0.048714014900000005 -0.228279 0.0697857 0.448684 -0.00413023 -0.00136517 0.000793752 -419.1417236328125 347.2120666503906 337.5389404296875 1.841203 110.97303 1.4824372 -0.05502935900000001 0.0267136498 0.07489594150000001 0.011400609499999999 -0.1360912319 -0.0483217735 0.1098562606 0.12148239949999999 -0.0206135956 -0.11107966710000002 0.0167155558 -0.0092070825 0.0425480561 -0.0029451740999999997 -0.04661247599999999 -0.061381302699999994 -0.0380953808 0.0088086474 0.0502515524 -0.235353 -0.0295037 0.7423889999999999 -0.0213236 -0.00485926 -0.000166164 -420.49713134765625 353.3000793457031 347.6824645996094 1.748108 105.361984 1.12480525 -0.0176827585 0.0361692655 0.0272465083 0.0488607996 -0.11479637529999999 -0.0010444564 -0.0023606739 0.0925013391 0.0619237999 0.015038494199999999 0.0210452825 0.062111926399999996 0.042280734 -0.0036806797 -0.0473282582 -0.061223237699999995 -0.0366306304 0.0109895824 0.0517012663 -0.145046 -0.0305184 0.467571 -0.00907012 -0.00290248 0.000796887 -417.9351501464844 352.1173095703125 345.0296325683594 1.061603 63.984955 0.33119735 -0.0041427598 0.0534190014 0.0158289934 0.0496063208 -0.08463287189999999 -0.0086600734 -0.0005150928 0.0422400353 0.0694249962 -0.0070432314 0.0090077151 0.0635416773 0.0420119037 -0.00441566 -0.0480288462 -0.061030231 -0.0351332152 0.0131564061 0.053060623200000004 -0.133051 0.0166828 0.407861 -0.00555546 -0.00248713 0.0011127 -419.62432861328125 351.81707763671875 345.2821960449219 0.9782090000000002 58.958622 0.20785619999999996 0.010336882 0.034207974700000005 0.013431401200000002 0.06367034690000001 -0.0829388836 0.013018621299999998 -0.0080108489 0.018207352 0.0620223901 -0.0058426155 -0.0031011603000000005 0.0761695229 0.0417415748 -0.0051500103000000005 -0.048714014900000005 -0.0608023928 -0.0336044704 0.015306336299999999 0.054327247300000006 -0.12483 0.103701 0.360968 -0.00447347 -0.00266038 0.00105346 -419.2793884277344 351.5086669921875 344.9368896484375 0.9436270000000002 56.874313 0.10590359999999996 0.0038737775 0.0474468904 0.0113542924 0.0767864601 -0.07373601910000001 0.0147486442 -0.0048971062 0.0135201385 0.06766060730000001 -0.0131480668 -0.0047792035 0.0813065539 0.0414697568 -0.0058836257 -0.0493835445 -0.0605398531 -0.032045759300000004 0.0174366123 0.0554989249 -0.118662 0.0658139 0.365455 -0.00395702 -0.00228322 0.00130708 -422.5331726074219 352.1214904785156 345.411865234375 0.994598 59.946453 0.05805619999999999 -0.0132485511 0.0239049621 -0.027214396000000002 0.07308669450000001 -0.061404889299999994 -0.0409484815 -0.007108525300000001 0.027448917200000002 0.0661398563 -0.0079355572 -0.0100719283 0.0768889316 0.0411964596 -0.0066164016 -0.050037220099999995 -0.060242761799999996 -0.0304584719 0.0195444986 0.0565736083 -0.121603 0.0845931 0.35236 -0.00414747 -0.00250512 0.00135955 -420.5591125488281 352.3153991699219 345.3928527832031 0.989638 59.647511 0.049286099999999985 -0.0261165281 0.0352267331 -0.0518468379 0.052470860599999995 -0.0288522 -0.0425686204 -0.0082149038 0.0361605607 0.07844623440000001 0.0013565006 -0.0241743635 0.048225897999999996 0.0409216928 -0.0073482335 -0.050674831600000005 -0.059911288300000004 -0.028844023599999997 0.0216272887 0.0575494194 -0.117411 0.0910577 0.341351 -0.00457876 -0.00260855 0.00137724 -420.8538818359375 351.761962890625 345.1949157714844 0.990924 59.724972 0.09462979999999997 -0.034232918 0.0641273601 -0.0727171938 0.02582455 -0.032460812400000004 -0.0862393421 -0.006406631800000001 0.026143427 0.09465700710000001 -0.0220991269 -0.011682726599999999 0.0040293177 0.0406454662 -0.0080790168 -0.0512961746 -0.059545621900000005 -0.027203854 0.0236823082 0.058424652599999995 -0.119174 0.0670379 0.36722 -0.00387323 -0.00251508 0.00131668 -421.5807800292969 351.71038818359375 345.1061706542969 0.991945 59.786514 0.08226339999999997 -0.010969500600000001 0.0690144107 -0.0752790087 -0.0239052366 -0.06046973940000001 0.0123430576 -0.0065658648 0.037534899100000005 0.0951308567 -0.0233743665 -0.0214610171 -0.027553254300000003 0.0403677898 -0.0088086474 -0.0519010494 -0.059145971299999996 -0.0255394259 0.025706918199999998 0.0591977785 -0.121249 0.0945728 0.352592 -0.00439605 -0.00260855 0.00117246 -421.98486328125 351.43084716796875 344.9309387207031 0.977981 58.944904 0.05250900000000003 0.0035815448999999997 0.07562464599999999 -0.0279477518 -0.0340343374 -0.0500115701 -0.0133699486 -0.0075526021999999995 0.0208858548 0.0950582344 -0.024865594900000003 -0.0048351959 -0.0407517608 0.0400886733 -0.0095370211 -0.05248926190000001 -0.0587125645 -0.0238522233 0.027698518999999998 0.0598674458 -0.115948 0.07234129999999998 0.345431 -0.00417581 -0.00260855 0.00130853 -419.6445617675781 351.8945007324219 344.824951171875 0.989353 59.630318 0.062248299999999986 0.013701867099999999 0.09863174429999999 -0.0009302833000000001 -0.0329776995 -0.0491290622 0.0264491718 -0.0078268423 0.022080031 0.1006648616 -0.039635962000000004 0.014033177800000001 -0.0217804113 0.0398081268 -0.010264034 -0.053060623200000004 -0.058245649000000004 -0.0221437508 0.0296545534 0.0604324842 -0.120389 0.0642655 0.358305 -0.00376193 -0.00242135 0.00117246 -420.3621520996094 352.1670227050781 345.20892333984375 1.027115 61.906322 0.11939499999999997 0.0198336879 0.0768257307 0.0165001363 -0.034115407599999995 -0.0574503299 -0.0093596371 -0.0103679342 0.0367467085 0.0967823497 -0.0193439899 0.0065000488 -0.0050220867 0.0395261602 -0.0109895824 -0.05361495 -0.0577454912 -0.020415532 0.0315725097 0.0608919062 -0.119368 0.106769 0.364701 -0.00479984 -0.00240695 0.00150964 -421.5797424316406 351.4495849609375 344.98822021484375 0.973075 58.649216 0.09145819999999998 0.037697913199999995 0.0837219441 0.0398759446 0.000930913 -0.046664974500000005 -0.0784680812 -0.0052781029000000005 0.0197200828 0.0841707952 -0.025320864900000004 0.0229921663 0.0212022806 0.0392427837 -0.011713562700000001 -0.0541520642 -0.0572123765 -0.0186691079 0.033449925 0.0612449087 -0.122979 0.0624388 0.364371 -0.00421027 -0.00260855 0.00143707 -420.4116516113281 351.5838928222656 344.9733581542969 0.996178 60.041687 0.06491369999999996 0.043820576900000005 0.0728100706 0.027101428700000003 0.0445694885 -0.0728180773 -0.0374639761 -0.0081432496 0.019124061100000003 0.0852125102 -0.0368273096 0.0331443855 0.0597517625 0.0389580073 -0.012435871599999999 -0.0546717934 -0.056646609199999996 -0.0169060359 0.0352843888 0.061490875 -0.124342 0.08260499999999998 0.353241 -0.00367422 -0.00260855 0.00132803 -421.0395202636719 351.544921875 345.14874267578125 0.987114 59.495369 0.08192300000000002 0.014556900400000001 0.0551584402 3.1248e-05 0.0701555796 -0.0986551407 0.008468997800000001 -0.0036840351 0.027374709 0.07622668860000001 -0.0231944932 0.0049024996000000005 0.0759539063 0.038671841299999996 -0.0131564061 -0.0551739708 -0.056048512300000006 -0.0151278882 0.037073545299999996 0.061629375099999995 -0.126963 0.114593 0.35085 -0.00438206 -0.00260855 0.00151865 -418.25042724609375 351.6273193359375 344.78558349609375 0.980327 59.086285 0.08555980000000002 -0.010328235699999999 0.06565432730000001 -0.0101556374 0.0775104545 -0.07196956 0.0383008322 -0.0073131901 0.0256683023 0.08416575039999999 -0.0230530479 0.0231259491 0.0800698914 0.0383842957 -0.0138750634 -0.055658435199999995 -0.055418427 -0.0133362505 0.038815097400000005 0.061660167 -0.124044 0.0754857 0.356901 -0.00388878 -0.00252128 0.00134955 -419.4575805664063 351.6487731933594 345.09423828125 0.986188 59.439548 0.048152000000000014 -0.0260739149 0.05726497 -0.046342767800000004 0.0840485894 -0.0511862601 -0.012933463899999999 -0.0042413227 0.0223493802 0.0900996702 -0.0278557823 0.005765305 0.0697280064 0.0380953808 -0.0145917409 -0.0561250309 -0.0547567129 -0.0115327203 0.0405068086 0.061583196900000005 -0.114806 0.0873067 0.355092 -0.00351538 -0.00242015 0.0013184 -421.58831787109375 351.7852478027344 345.87432861328125 1.009516 60.845562 0.1262378 -0.0185013774 0.06655887190000001 -0.0779951131 0.0383424573 -0.0527735854 -0.0969095514 -0.0030888267 0.0368584241 0.1101801889 -0.0258630358 -0.0078068795 0.037544356800000005 0.0378051071 -0.015306336299999999 -0.0565736083 -0.054063747800000006 -0.009718906 0.0421465068 0.0613985992 -0.12057 0.121652 0.340379 -0.00450709 -0.00260855 0.0015666 -421.7759399414063 351.9810485839844 345.7310485839844 1.001103 60.338512 0.12806309999999999 -0.0232374117 0.092479576 -0.0837831392 0.00292924 -0.0626836058 -0.022470951099999997 -0.0123324719 0.026087216 0.11246701519999999 -0.0207844968 -0.0130843348 -0.0071272601 0.0375134847 -0.0160187477 -0.0570040233 -0.0533399272 -0.007896425 0.0437320865 0.0611066967 -0.122423 0.0597034 0.334443 -0.00378691 -0.00239843 0.00133039 -421.8748474121094 351.870361328125 345.957275390625 0.995423 59.996162 0.12857530000000003 0.0019898686 0.0948397663 -0.06803665589999999 -0.0304614736 -0.060040231500000006 0.0228883066 -0.0135771648 0.0152939257 0.1041015215 -0.044272621100000006 -0.0082723064 -0.0423675723 0.0372205242 -0.0167288735 -0.057416137699999995 -0.052585664000000004 -0.0060669025 0.0452615117 0.060707999400000004 -0.110223 0.0908212 0.308865 -0.00289224 -0.00225744 0.00117246 -420.8256530761719 352.49835205078125 346.4927673339844 1.105437 66.626953 0.2628535 0.0171351093 0.08457232449999999 -0.015610962800000001 -0.044062884000000004 -0.0849410561 0.026704057200000002 -0.0169552458 0.0338395762 0.07334408049999999 -0.041988968099999996 0.0085082976 -0.0418398454 0.0369262359 -0.0174366123 -0.057809819299999995 -0.0518013888 -0.0042319699 0.046732818499999995 0.0602032042 -0.143256 0.151593 0.26226 -0.0027699 -0.00260855 -0.0008029639999999998 -420.0455322265625 351.53558349609375 345.9622802734375 1.233448 74.34238399999998 0.40248775 0.0349089357 0.0407256221 0.0175790917 -0.0628559366 -0.0349492572 0.0214626033 -0.0027215177000000004 0.0086519935 0.043244582999999996 0.018371331299999998 0.042298605 -0.0561036209 0.0366306304 -0.0181418631 -0.058184941500000004 -0.0509875493 -0.0023932635000000002 0.048144117699999996 0.059593193200000005 -0.112935 0.008415149999999998 0.147193 -0.00340674 -0.00261427 0.000832914 -371.8408203125 319.4721374511719 317.13128662109375 2.695495 162.462921 4.5592784 -0.22982537649999998 0.0660880391 0.20263495969999998 -0.0304630009 0.1203307259 0.034400257000000004 0.4023250324 -0.29489698870000003 0.0102890986 -0.0337780382 -0.3993795026 0.057695294400000006 0.0363337182 -0.0188445253 -0.0585413841 -0.0501446098 -0.0005524229 0.049493597199999996 0.0588790326 -0.242945 -1.05812 -2.26129 -0.0175487 0.00130519 -0.000190671 -388.5560302734375 325.427978515625 323.8311767578125 2.978447 179.51705899999996 1.84074905 -0.2072273094 0.18541149640000001 0.1204360401 0.015630603899999998 0.20550099600000002 0.0627507547 0.3619995774 -0.23847223760000003 0.1085712506 0.1602848676 -0.08238694440000001 -0.10405390630000001 0.036035509900000005 -0.0195444986 -0.0588790326 -0.049273051500000005 0.0012889102 0.050779524000000006 0.0580619705 -0.189946 -0.561132 -1.45172 -0.0224386 -0.0021674 0.00107068 -446.2183837890625 358.96343994140625 356.27215576171875 3.0819 185.752365 2.19632375 -0.0170385669 -0.0969058071 0.0272631398 -0.0788873693 -0.0782021948 0.007906609 -0.060092058200000006 0.1392848764 -0.17949356579999998 0.0045532283 0.0456448692 -0.1357348719 0.0357360162 -0.0202416832 -0.0591977785 -0.048373371799999995 0.0031290940000000002 0.0520002471 0.057143434800000004 -0.077342 -0.17363 -0.432441 -0.0101056 -0.0019108 0.000121505 -426.2521362304688 352.3639221191406 349.082763671875 1.201052 72.38981599999998 0.2936817500000001 -0.034226029 -0.0970712113 0.0415512388 -0.0728341244 -0.0008469578999999999 0.0291118375 0.0048558405 0.0593840928 -0.07714488900000001 0.0621739332 -0.0484108211 -0.0580779885 0.0354352477 -0.020935979599999998 -0.0594975196 -0.0474460842 0.0049664875 0.053154198799999997 0.0561250309 -0.0823867 -0.148694 -0.279671 -0.00972644 -0.00296558 0.000906186 -422.6844482421875 352.3898620605469 347.7001953125 1.022394 61.62175 0.22604705 -0.0201318079 -0.089603122 0.0577608293 -0.0734382729 0.016965808 -0.0036360960999999997 0.0042130504 0.0423293985 -0.065783112 0.0808476196 -0.0272599543 -0.048523075199999995 0.0351332152 -0.0216272887 -0.0597781596 -0.046491717800000006 0.006799452199999999 0.054239897599999996 0.055008538600000004 -0.0835529 -0.179997 -0.222187 -0.00746464 -0.0028402 0.000571489 -424.8573303222656 351.83721923828125 347.0563049316406 1.033289 62.278442 0.12920795 -0.011289496100000001 -0.09116565119999999 0.0607617591 -0.0640008322 0.0122083214 -0.0791823033 0.0030361637 0.0333806716 -0.06789766929999999 0.0764826813 -0.0497500216 -0.0106133487 0.0348299293 -0.022315511899999998 -0.0600396084 -0.0455108174 0.0086263535 0.0552559492 0.0537959092 -0.0918004 -0.121509 -0.255577 -0.007469639999999999 -0.00340796 0.000580378 -424.8421936035156 352.13555908203125 347.1554870605469 1.007909 60.748692 0.12244779999999998 0.0025444573 -0.1019771853 0.049156763799999996 -0.0209229573 0.0061476887 -0.0285107711 -0.006291230500000001 0.0311930517 -0.0686275497 0.0752187262 -0.0397872454 0.012709487 0.0345254011 -0.023000551 -0.0602817821 -0.0445039428 0.0104455625 0.056201049100000004 0.05248926190000001 -0.0952568 -0.144071 -0.212203 -0.00694939 -0.00294291 0.000656186 -422.4728088378906 351.80108642578125 346.5733642578125 0.992611 59.826687 0.1030241 -0.0098025868 -0.0924194057 0.0319791472 -0.0055226976 -0.0019092552 0.0347978328 0.0011449789 0.024866761600000002 -0.0658331163 0.0695249133 -0.0294918819 0.0184346317 0.0342196412 -0.0236823082 -0.060504603 -0.0434716687 0.012255456699999999 0.0570739836 0.0510908803 -0.0953404 -0.12004600000000003 -0.218076 -0.00551143 -0.0029658 0.000656186 -422.5759582519531 351.4847106933594 346.56536865234375 0.984502 59.33794 0.14416359999999992 -0.010765733700000002 -0.1035114103 0.0173941424 0.0088542747 0.007404955699999999 0.0180018879 0.0037366757 0.025295633999999997 -0.0608298275 0.0700055811 -0.0563518125 0.0275643179 0.0339126607 -0.024360686200000002 -0.060707999400000004 -0.0424145842 0.0140544224 0.0578736318 0.0496032084 -0.0931421 -0.08417589999999998 -0.217778 -0.00678802 -0.00347359 0.00098775 -420.9371337890625 351.7113342285156 346.44708251953125 0.9767420000000002 58.870228 0.1839856 -0.01588401 -0.0912572111 0.015906652900000002 0.0032158040999999997 0.0130156692 0.056767869699999994 -0.0020004005 0.0219296762 -0.0617466614 0.0686505949 -0.0338214716 0.0237334751 0.0336044704 -0.0250355883 -0.0608919062 -0.0413332925 0.0158408552 0.058598967 0.0480288462 -0.104994 -0.144422 -0.207731 -0.00547704 -0.002963 0.000772508 -423.8532104492188 351.5809631347656 346.5943298339844 0.992221 59.80315 0.1289245 -0.0275264642 -0.107889165 -0.006779010699999999 0.0086406829 0.0099218627 0.010104832900000001 0.0012167211 0.0250443026 -0.054092663799999996 0.0544819145 -0.052155023099999996 0.0206710153 0.0332950814 -0.025706918199999998 -0.0610562642 -0.0402284109 0.0176131622 0.059249057800000005 0.046370545 -0.10504 -0.0841849 -0.179717 -0.00580597 -0.00331294 0.000906186 -422.5363464355469 351.7102355957031 346.67083740234375 0.983412 59.272236 0.08249860000000002 -0.034388189900000005 -0.0966847596 -0.018507543600000002 0.006575534300000001 0.0388053187 -0.0013669889999999999 -0.0043658928 0.0156729808 -0.04463154230000001 0.0550661487 -0.0430433917 0.015391821299999999 0.0329845047 -0.02637458 -0.061201020700000004 -0.0391005699 0.0193697628 0.0598230695 0.044631203099999996 -0.112126 -0.10412900000000001 -0.199566 -0.00513781 -0.00335717 0.000906186 -424.6297607421875 351.6400451660156 346.61871337890625 1.021613 61.574673 0.07801899999999995 -0.0312695573 -0.0867668339 -0.0518614853 -0.018042229099999998 0.056600449500000004 -0.0980467454 -0.0034487216 0.025869639 -0.0379895092 0.0581101521 -0.0379647537 -0.0199175245 0.0326727513 -0.0270384785 -0.061326129199999996 -0.0379504132 0.0211090908 0.060320264900000004 0.0428138604 -0.105061 -0.113356 -0.1821 -0.00455676 -0.003053 0.000906186 -424.0057067871094 351.641357421875 346.29254150390625 1.014974 61.174534 0.14543669999999992 -0.023366110899999997 -0.0751545073 -0.0481119238 -0.0579066158 0.0233885701 -0.016651642 -0.0038979473 0.021873633599999998 -0.021519916 0.0631843046 -0.0430295685 -0.0475350788 0.0323598325 -0.027698518999999998 -0.0614315496 -0.0367785971 0.0228295951 0.0607400057 0.0409216928 -0.105098 -0.059611 -0.185821 -0.00555472 -0.00339019 0.00132971 -423.8024597167969 351.4261474609375 345.0937194824219 1.173586 70.734413 0.55995755 -0.0134620972 -0.0434374304 -0.0207158982 -0.0646235605 0.044712007000000005 0.015809633400000002 -0.0005134006 0.0117718104 -0.0410361775 0.0232161703 -0.0089896232 -0.060399298399999996 0.032045759300000004 -0.0283546073 -0.061517248 -0.0355857906 0.024529741400000003 0.0610817528 0.0389580073 -0.160006 -0.08683169999999998 -0.310637 -0.000176446 -0.00222378 0.000814137 -423.8966674804688 352.117431640625 346.4755859375 1.265707 76.28675099999998 0.2610007 0.0020204745999999997 -0.0382612394 -0.0210711655 -0.0293188605 0.0558932503 -0.0321826733 -0.0151106858 -0.0021762998000000003 -0.0719529459 -0.002261629 -0.0067719543999999994 -0.0423707641 0.031730543 -0.0290066498 -0.061583196900000005 -0.0343726744 0.0262080137 0.0613450675 0.0369262359 -0.117865 0.0215905 -0.292692 0.000784101 -0.00197592 0.00145558 -424.9112854003906 352.21783447265625 347.5047302246094 1.073799 64.720024 0.25835995 -0.0088369365 -0.056155679800000004 -0.0103845381 -0.044445636399999995 0.0352619975 -0.014107638700000001 -0.0150569544 0.005299499599999999 -0.0432470249 0.005991164 -0.0216692546 -0.0227751879 0.0314141948 -0.0296545534 -0.061629375099999995 -0.0331399408 0.0278629153 0.0615296116 0.0348299293 -0.0978827 0.0264831 -0.265458 -0.0019666 -0.003002 0.00180382 -424.5313720703125 352.70330810546875 348.140625 1.08171 65.196838 0.17423700000000003 0.0096342635 -0.0650172923 0.00072536 -0.017175623799999998 0.0035691578999999998 0.042765554299999994 -0.020828586899999998 0.006742971899999999 -0.0635016733 0.0088991969 -0.0020432216000000002 -0.0161847361 0.031096726 -0.030298225699999997 -0.0616557679 -0.0318882933 0.0294929706 0.0616351482 0.0326727513 -0.100189 -0.0887781 -0.249987 -0.00133538 -0.00291596 0.00169711 -422.3537902832031 352.4111328125 347.2664794921875 1.00957 60.848808 0.11087464999999996 -0.0046294295 -0.0626231593 0.0023633305 0.0192921969 0.0176411146 0.0488911513 -0.0173293094 -0.005222608 -0.0615740913 0.0130575713 -0.0042309635 0.0181647551 0.0307781479 -0.0309375749 -0.061662366600000004 -0.030618446400000002 0.031096726 0.0616615418 0.0304584719 -0.0978289 -0.0979367 -0.229826 -0.000485801 -0.00243164 0.00144711 -425.0855407714844 352.34771728515625 347.18243408203125 1.058717 63.810993 0.39789085 -0.017565411 -0.060799221900000006 -0.0415021535 0.0167501043 0.0240358788 -0.0598611658 -0.0183302354 0.0027364575 -0.0313436832 0.024527518199999997 -0.0194046471 0.0120168996 0.0304584719 -0.0315725097 -0.061649169299999994 -0.0293311248 0.0326727513 0.0616087584 0.0281909609 -0.0893022 0.0409965 -0.173185 -0.00221824 -0.00398043 0.00204168 -421.9892578125 352.3133544921875 346.42840576171875 1.014923 61.17149 0.10958549999999996 -0.019776966200000003 -0.0396059068 -0.044169424900000004 0.0065530132999999996 0.049677442800000006 -0.0071229608 -0.0169455724 -0.0022990865 -0.031145808100000002 0.018515976899999998 -0.0022832476 -0.0202326522 0.0301377094 -0.0322029395 -0.061616180199999995 -0.0280270631 0.0342196412 0.0614768659 0.025874181200000002 -0.0979872 -0.0145015 -0.193463 -0.00179631 -0.00405489 0.00204778 -423.8751831054688 351.60650634765625 346.2781677246094 1.021762 61.583668 0.11621590000000002 -0.0101199052 -0.0372622187 -0.0668542423 -0.0349916222 0.050195645899999995 -0.046445779400000005 -0.0172424859 -0.0093788649 -0.0221878236 -0.002450315 -0.0192703353 -0.0461667125 0.0298158718 -0.032828774399999996 -0.061563409699999995 -0.0267070056 0.0357360162 0.061266033600000006 0.023512181899999998 -0.0979068 -0.0139641 -0.202865 -0.000771808 -0.00303685 0.00212916 -422.0880737304688 351.6440734863281 346.3509216308594 1.00375 60.498028 0.2349168 -0.0077274316 -0.0287179407 -0.04968493190000001 -0.0555592369 0.0315583796 0.0250690143 -0.0164157642 -0.007248081700000001 -0.0182552356 0.0029483324 -0.027057425 -0.051043318600000005 0.0294929706 -0.033449925 -0.061490875 -0.0253717058 0.0372205242 0.060976532199999996 0.0211090908 -0.0937063 0.0513641 -0.16982 -0.00215963 -0.00410835 0.00194162 -422.6476135253906 351.5140380859375 345.9818115234375 0.996538 60.063381 0.18880095 0.0054559386 -0.0131062597 -0.0223561998 -0.060367823 0.05616988480000001 0.0371567604 -0.0155241847 -0.0216681904 -0.0236113308 0.0009333467 -0.0025882881 -0.0678949463 0.029169017400000004 -0.034066302799999996 -0.0613985992 -0.0240219257 0.038671841299999996 0.0606087335 0.0186691079 -0.0935034 -0.00591445 -0.206831 -0.00103637 -0.00363977 0.00223595 -420.2033996582031 351.52252197265625 345.60125732421875 0.997148 60.100101 0.09428277999999997 0.011983648000000001 -0.0011753077 -0.0155850351 -0.056316245 0.0419143613 0.0711083567 -0.014318583000000001 -0.0246130181 -0.023210971299999997 -0.0092365638 -0.0062122674 -0.053827034100000004 0.028844023599999997 -0.0346778198 -0.0612866121 -0.022658435600000002 0.0400886733 0.060163109699999995 0.0161964974 -0.0979138 0.00816503 -0.209357 -0.000285002 -0.0030495 0.00211225 -420.6841735839844 351.7802429199219 346.08441162109375 1.002271 60.408901 0.26820586999999996 0.0209380038 -0.006810462 0.011523040600000001 -0.0536550391 0.0349658143 0.07163965679999999 -0.017780752900000002 -0.0178421674 -0.011088294399999999 0.007430624100000001 0.0138845689 -0.0570843086 0.0285180009 -0.0352843888 -0.061154949400000005 -0.0212820138 0.0414697568 0.059640233 0.013695580700000001 -0.08688089999999998 0.08296109999999998 -0.159058 -0.00171596 -0.00404077 0.00189292 -421.4260559082031 351.34722900390625 345.8697509765625 0.997961 60.149109 0.18633054 0.027952597000000003 -0.013184781699999999 0.0307975507 -0.0532364623 0.051519719900000004 0.0232240819 -0.0098676711 -0.0280273485 -0.030692753399999998 0.0043202779 0.0230849214 -0.0518366738 0.0281909609 -0.0358859231 -0.061003653600000006 -0.0198934458 0.0428138604 0.0590407749 0.011170728500000001 -0.0979368 0.00874246 -0.194395 -0.0010183 -0.00348613 0.001955 -422.3150634765625 351.6091003417969 345.9823303222656 1.011959 60.992813 0.08459588999999999 0.0439283797 -0.0148099047 0.0489802127 -0.0424390049 0.059420296399999996 -0.0565382715 -0.0121507608 -0.022295684700000002 -0.037552105 0.0042611439 0.034019372400000004 -0.0244058482 0.0278629153 -0.036482337000000004 -0.0608327732 -0.018493524 0.0441197852 0.0583655051 0.0086263535 -0.0979379 0.0601683 -0.175272 -0.0008633109999999999 -0.00359749 0.00196957 -422.8018798828125 351.4815673828125 346.05987548828125 1.025106 61.785191 0.07743475000000001 0.044449181500000004 -0.024852973900000002 0.0441605584 -0.012044073999999998 0.0477918442 -0.0548200347 -0.0172399741 -0.023714606000000003 -0.051128777300000004 -0.0100344076 0.0209731267 0.0044276048 0.0275338758 -0.037073545299999996 -0.060642363 -0.0170830476 0.0453863669 0.057615290599999994 0.0060669025 -0.0979781 0.0688394 -0.169723 -0.0015208 -0.00416387 0.00200919 -421.4130859375 351.9045104980469 345.7351989746094 0.990878 59.722214 0.1366389 0.0428110164 -0.0208371795 0.0486993857 0.017308966999999998 0.0405193698 -0.0247940268 -0.0194296388 -0.0226295869 -0.04770863 -0.0146526985 0.0285268514 0.0185153052 0.027203854 -0.0376594638 -0.0604324842 -0.0156628214 0.04661247599999999 0.056791094900000005 0.0034968484000000005 -0.097946 0.016423199999999995 -0.179682 -0.0008448779999999998 -0.00343447 0.0020885 -421.0196228027344 351.72174072265625 346.04754638671875 0.997698 60.133293 0.11708410000000002 0.046634374000000006 -0.018130558600000003 0.0372039938 0.0396095414 0.010542983799999999 0.0272720729 -0.0165808055 -0.027307909900000003 -0.0414866421 -0.016381121000000002 0.0324867895 0.0438015833 0.0268728619 -0.038240008799999996 -0.0602032042 -0.014233656 0.047797019100000004 0.055893976100000006 0.000920683 -0.0979415 0.0670117 -0.141974 -0.00122366 -0.00357062 0.00202777 -421.4193115234375 351.4181823730469 345.9225158691406 1.007482 60.72298 0.10243845 0.0232310957 -0.0360561301 0.0196652834 0.051050268200000005 0.022884451099999998 0.0420647933 -0.012879491699999999 -0.0275002011 -0.041010233199999996 -0.0151841028 0.0168696551 0.0325580484 0.0265409112 -0.038815097400000005 -0.059954596500000006 -0.012796367099999999 0.0489389399 0.0549250863 -0.0016570915 -0.0939676 0.0796652 -0.191883 -0.000572849 -0.00359342 0.00198334 -419.16650390625 351.9150390625 345.5081481933594 0.986818 59.477516 0.13402215 0.0167236996 -0.0165595864 0.004435298 0.048532786200000004 0.0059336078 0.0612036542 -0.014108946499999999 -0.0234068803 -0.0406376717 -0.012138823799999999 0.031367512599999994 0.033083182 0.0262080137 -0.039384647599999996 -0.059686740999999995 -0.011351775 0.050037220099999995 0.053885669500000004 -0.0042319699 -0.0983398 0.0210847 -0.175271 -0.000939398 -0.00314015 0.00225267 -420.06427001953125 351.91522216796875 345.9388732910156 0.974281 58.721912 0.1831128 0.0213552913 -0.0161051913 -0.012788989399999999 0.053905654299999994 0.0045942387 0.0416618223 -0.0175791825 -0.0202333947 -0.0172551651 -0.0044477053 0.019185091100000003 0.037581111800000004 0.025874181200000002 -0.0399485782 -0.0593997236 -0.0099007042 0.0510908803 0.0527770605 -0.006799452199999999 -0.0993679 0.0755338 -0.11843 -0.00156367 -0.00383019 0.00215109 -418.86944580078125 351.7622985839844 346.0969543457031 0.9888650000000002 59.600891 0.1386867 0.006226570799999999 -0.0144626319 -0.004429177 0.057197238399999996 0.0158663996 0.049112549000000005 -0.0135825373 -0.0279540406 -0.0234131004 -0.0156103574 0.027723295499999998 0.040027528799999997 0.0255394259 -0.0405068086 -0.0590936366 -0.0084439827 0.052098980999999996 0.0516006827 -0.0093550512 -0.102261 0.0653096 -0.181053 -0.000725032 -0.00355907 0.00200192 -419.2788391113281 352.1996154785156 346.2226257324219 0.970639 58.502384 0.08818175000000002 0.0040933279 -0.005643300699999999 -0.0119869722 0.052544139000000004 0.0106335412 0.058115428399999995 -0.0187126665 -0.0316683569 -0.0273974818 -0.0240820695 0.023157892200000002 0.036345007400000004 0.0252037594 -0.041059259300000005 -0.058768578200000005 -0.0069824421 0.053060623200000004 0.0503580468 -0.0118943007 -0.101391 0.0225561 -0.172906 -0.000601997 -0.00311965 0.00216769 -422.3112182617188 352.235107421875 346.813720703125 1.003327 60.472576 0.22410545 -0.0039162877 -0.0158253332 -0.039360043 0.0606922411 0.0052133778 -0.0017137435999999998 -0.021749364 -0.0225440815 -0.0118048892 -0.017586881699999998 0.0044711055 0.0407604931 0.0248671939 -0.041605851299999996 -0.058424652599999995 -0.0055169164 0.05397494940000001 0.0490507482 -0.0144127627 -0.0899385 0.0986779 -0.128795 -0.0013519 -0.00416563 0.00211517 -420.5513916015625 352.23455810546875 346.8238220214844 0.983902 59.301788 0.17272380000000004 -0.0078055305 -0.0104412852 -0.029775232999999998 0.0433006666 0.030872658799999998 0.0426146366 -0.0193255684 -0.0302616359 -0.02386947 -0.0100758059 0.0208563193 0.0210815874 0.024529741400000003 -0.0421465068 -0.0580619705 -0.0040482420000000005 0.0548411441 0.0476804656 -0.0169060359 -0.0906523 0.0430298 -0.17394 -0.000667012 -0.00370378 0.00239277 -422.8477478027344 351.93603515625 346.871826171875 0.993878 59.903023 0.09734886499999998 -0.019065979 -0.009418314399999999 -0.0369988694 0.050810347900000004 0.0450666434 -0.021428536499999998 -0.0165772304 -0.027827252900000002 -0.018063672700000002 -0.0029267685 0.0199271688 0.031070478199999998 0.0241914138 -0.042681148499999995 -0.057680648099999995 -0.0025772572 0.055658435199999995 0.0462489587 -0.0193697628 -0.097145 0.0534703 -0.179467 6.92013e-05 -0.00308518 0.00224981 -423.6578369140625 351.89031982421875 347.078125 1.028198 61.971561 0.213494365 -0.0079924236 -0.010467770999999999 -0.043437965599999996 0.0351692472 0.0426682801 -0.06768680690000001 -0.0173991763 -0.0275578017 -0.0059331529000000004 -0.0134814331 0.0060418965 0.011379178500000002 0.0238522233 -0.04320970019999999 -0.0572808079 -0.0011048015 0.056426093600000005 0.0447580654 -0.0217996377 -0.0901059 0.10022 -0.133417 -0.00120738 -0.00399535 0.00216345 -421.5909423828125 352.0312805175781 346.44940185546875 1.010465 60.90279 0.233848502 -0.018988345 0.0075105909 -0.056996379699999995 0.0104285614 0.0707207768 -0.035727597400000005 -0.0181501643 -0.0315426596 0.0027320756 -0.0082031421 0.0238144098 -0.0117490142 0.023512181899999998 -0.0437320865 -0.0568625783 0.0003682847 0.057143434800000004 0.04320970019999999 -0.0241914138 -0.0981038 0.0241496 -0.168326 9.26404e-06 -0.00318944 0.00243832 -422.1461791992188 351.7137451171875 346.37445068359375 1.016089 61.241753 0.193018952 -0.0113091626 0.0212366934 -0.0620492184 -0.0213935994 0.0410174458 0.0127283346 -0.018338563000000002 -0.0314527411 -0.0005377416 -0.012851893400000002 0.0113963927 -0.041663478999999996 0.023171301800000002 -0.0442482328 -0.056426093600000005 0.0018411607000000001 0.057809819299999995 0.041605851299999996 -0.0265409112 -0.0936131 0.0883674 -0.121257 -0.000749305 -0.00368793 0.00215055 -421.1915283203125 352.3005065917969 346.2352600097656 0.991681 59.770592 0.0689275 0.0021453077999999998 0.025261975099999997 -0.0457860187 -0.0355744166 0.0559366899 0.0081743036 -0.024218786000000003 -0.0365534107 -0.0037880759999999996 -0.0219948602 0.008709355 -0.0495849237 0.0228295951 -0.0447580654 -0.0559714938 0.003312986 0.058424652599999995 0.0399485782 -0.028844023599999997 -0.0934163 0.0797497 -0.159274 -0.0009183450000000002 -0.00378511 0.00232625 -421.8989868164063 351.7101135253906 346.1007385253906 0.99133 59.749489 0.10970357499999998 -0.00037756370000000005 0.0280387235 -0.0484059064 -0.0456048841 0.037888938399999995 0.0570989518 -0.0188422279 -0.0359994341 -0.0033002228999999997 -0.038290958300000004 0.0227541677 -0.0695258677 0.022487074 -0.0452615117 -0.0554989249 0.0047829204 0.0589873867 0.038240008799999996 -0.031096726 -0.0933916 0.0395275 -0.159303 -8.590149999999998e-05 -0.00333879 0.00243604 -421.0643310546875 352.281982421875 346.2794494628906 0.99785 60.142418 0.181458875 0.019755148700000003 0.039561813599999995 -0.0222871537 -0.0398664622 0.0423408678 0.072756141 -0.0257199859 -0.0429269284 0.0116810141 -0.035326259900000004 0.0335479931 -0.054743069000000005 0.0221437508 -0.0457584997 -0.055008538600000004 0.0062501251 0.0594975196 0.036482337000000004 -0.0332950814 -0.0894043 0.108057 -0.13228100000000004 -0.0008826129999999998 -0.00399425 0.00224981 -421.2106323242188 351.82904052734375 345.9365539550781 0.993903 59.90453 0.19137607 0.0224605944 0.035569854500000005 7.868e-06 -0.0469302428 0.053187272599999995 0.0553340731 -0.021601498599999998 -0.0448099514 -0.012984470900000001 -0.0349708722 0.035010204100000004 -0.057474907699999994 0.0217996377 -0.0462489587 -0.0545004924 0.0077137627000000005 0.059954596500000006 0.0346778198 -0.0354352477 -0.0934032 0.050352 -0.174009 8.596039999999998e-05 -0.00345394 0.00249981 -422.6008605957031 351.6798095703125 346.0926208496094 1.020569 61.511738 0.11545716999999997 0.0443057905 0.0421902104 0.0273883029 -0.0391200583 0.048825785499999996 0.015916538 -0.0208291249 -0.0475315154 -0.011822358100000001 -0.032614427 0.052265043 -0.039580505099999996 0.0214547469 -0.046732818499999995 -0.05397494940000001 0.0091729979 0.0603582097 0.032828774399999996 -0.0375134847 -0.0934184 0.0912663 -0.1377 -8.951299999999998e-05 -0.00379284 0.00224981 -422.640380859375 351.410888671875 345.8951110839844 1.046788 63.09206 0.09617099999999998 0.0413968392 0.0324033059 0.0345564698 -0.0330001924 0.0624924455 -0.0659391079 -0.0182127504 -0.052187339400000005 -0.005900954599999999 -0.0357695209 0.045933985 -0.0244660064 0.0211090908 -0.04721001019999999 -0.053432078200000004 0.010626997800000001 0.060707999400000004 0.0309375749 -0.0395261602 -0.0934309 0.0993467 -0.118793 -0.000753525 -0.00439106 0.002371 -420.9017028808594 351.4735107421875 345.5483703613281 1.021847 61.588802 0.16460514999999998 0.0573194032 0.026875347 0.046981658200000005 0.0087816004 0.057997775599999996 -0.0425989243 -0.0197826566 -0.0499876892 -0.0170227118 -0.0345115088 0.0578974887 0.0042791229 0.0207626817 -0.0476804656 -0.052872053200000005 0.0120749325 0.061003653600000006 0.0290066498 -0.0414697568 -0.110118 0.0447392 -0.146089 -0.000235854 -0.00370963 0.00224981 -420.91143798828125 351.27850341796875 345.8308410644531 1.0019650000000002 60.39045 0.15107305 0.0547965641 0.0300509383 0.044849274800000005 0.048834196600000004 0.040883339500000004 -0.004001709 -0.0146951942 -0.0550336663 -0.0313041217 -0.0483818906 0.0425699894 0.035760641600000004 0.020415532 -0.048144117699999996 -0.052295054199999996 0.013515975800000002 0.0612449087 0.0270384785 -0.043340877699999995 -0.100232 0.0888884 -0.110721 -0.000959531 -0.00409264 0.00237652 -421.18096923828125 351.7684020996094 345.97088623046875 0.9805910000000002 59.102196 0.06165 0.0459281581 0.0175686366 0.0349558566 0.0642166546 0.029880529399999998 0.0194120419 -0.0178887381 -0.0484858393 -0.034810578599999996 -0.0382573361 0.0522929209 0.0398187996 0.020067654 -0.0486009003 -0.0517012663 0.0149493052 0.0614315496 0.0250355883 -0.045136252800000005 -0.0934274 0.0785719 -0.136119 -0.0007746129999999998 -0.00411645 0.00255041 -420.58203125 351.601318359375 345.96722412109375 0.98439 59.331211 0.1353011 0.0409700965 0.0179135298 0.0213988443 0.0763914057 0.0107000395 0.052761634 -0.0176066402 -0.0563738575 -0.0413642112 -0.0428915557 0.0386115671 0.042052087 0.0197190601 -0.0490507482 -0.0510908803 0.0163741027 0.061563409699999995 0.023000551 -0.0468527442 -0.090569 0.047357 -0.152871 0.000112723 -0.00359613 0.00283227 -417.2941284179688 345.3746337890625 338.2203674316406 1.784158 107.534798 1.20907865 -0.0244726194 0.0093742151 0.035897461 0.07777163200000001 -0.0303684668 0.0071617827 0.1040713297 -0.0240124576 -0.044294756500000004 -0.0333279632 0.16387961339999998 -0.020172699 0.0193697628 -0.049493597199999996 -0.050464092099999996 0.017789555 0.0616403716 0.020935979599999998 -0.0484873523 -0.103549 -0.162898 0.120828 -0.0123284 -0.00331471 0.00131192 -424.7168273925781 351.8787841796875 346.9467468261719 1.899814 114.505653 0.46324965 -0.047295163 4.48162e-05 0.0220492181 0.0365253393 -0.1283501825 0.029243329 0.0414085373 0.1143861293 0.0176700199 -0.012257761200000002 -0.0162649261 0.0550814901 0.0190197746 -0.0499293841 -0.0498211028 0.019194854299999998 0.061662366600000004 0.0188445253 -0.050037220099999995 -0.0773709 -0.244581 0.152006 -0.0182037 -0.0035371 0.000925399 -421.4012756347656 351.4746398925781 345.48040771484375 1.028646 61.998592 0.29885175 -0.051966765899999996 -0.0071256712 -0.0012379977 0.039429626 -0.1028233958 0.0049518201000000005 0.0402705124 0.0905400982 0.0419800318 0.0036049604999999997 -0.0167499971 0.0645163332 0.0186691079 -0.0503580468 -0.0491621191 0.020589198700000002 0.061629375099999995 0.0167288735 -0.05149963900000001 -0.0818451 -0.167259 0.168046 -0.0147047 -0.00317771 0.00108732 -423.1089477539063 351.7129821777344 345.75860595703125 0.968234 58.357426 0.18166439999999998 -0.0471293475 -0.0112730129 -0.0099505788 0.0433757125 -0.0763654375 -0.016315737099999998 0.0298493525 0.0709356074 0.0451183215 0.0178954715 -0.0363432324 0.0646190379 0.0183177752 -0.050779524000000006 -0.0484873523 0.021971792200000003 0.0615414265 0.0145917409 -0.052872053200000005 -0.08502999999999998 -0.121696 0.140409 -0.0130288 -0.00334613 0.00134859 -423.0423889160156 351.5523376464844 345.71624755859375 0.956474 57.648624 0.13263110000000009 -0.0615120205 -0.004930438499999999 -0.0217314196 0.0241467473 -0.0627655343 -0.021971764700000004 0.026169980699999998 0.0660052543 0.048049134800000004 0.023897136800000003 -0.0267778734 0.045540051500000005 0.0179657891 -0.0511937557 -0.047797019100000004 0.023341845899999998 0.0613985992 0.012435871599999999 -0.0541520642 -0.0881566 -0.153154 0.134861 -0.0114513 -0.00316229 0.00143722 -426.3393859863281 351.7640380859375 346.1451416015625 1.020152 61.48661 0.13517539999999997 -0.0403398221 0.0022675158999999998 -0.0636538128 -0.0075901047 -0.0465500789 -0.10176338509999999 0.018648545 0.059232743600000005 0.0651620576 0.019608566100000002 -0.0363461798 0.0066964791000000004 0.0176131622 -0.0516006827 -0.0470913411 0.0246985778 0.061201020700000004 0.010264034 -0.0553374348 -0.08487269999999998 -0.08651799999999998 0.141238 -0.0105728 -0.00329765 0.00160093 -423.4654541015625 351.7749938964844 346.0797119140625 0.993894 59.903992 0.12247720000000002 -0.0341961546 0.0133512097 -0.0421187369 -0.0326078888 -0.0362158423 -0.0275064365 0.011337238999999999 0.0473662702 0.0654131779 0.008802183 -0.0341876644 -0.029068193500000002 0.0172599069 -0.0520002471 -0.046370545 0.026041213599999998 0.060948867000000004 0.0080790168 -0.056426093600000005 -0.0797419 -0.0724393 0.08841079999999998 -0.010183 -0.00370348 0.00181411 -423.8712463378906 352.0328369140625 346.2323913574219 0.994781 59.957493 0.1598977 -0.023220433999999998 0.0286381 -0.040912017599999996 -0.0540266615 -0.0466986219 0.0423915454 0.0070449811 0.0367662968 0.0460822625 0.0052590282 -0.025611222000000003 -0.0543224698 0.0169060359 -0.052392391600000005 -0.0456348621 0.0273689869 0.060642363 0.0058836257 -0.057416137699999995 -0.0876595 -0.115471 0.0786899 -0.008288659999999998 -0.00367054 0.00187138 -421.52813720703125 351.5581359863281 345.9969177246094 0.982469 59.215405 0.1993312 -0.0020146135 0.044557184699999995 -0.0093184571 -0.0630931085 -0.0623296234 0.058509373499999996 0.0088499414 0.033816361499999996 0.0746768547 0.0018906545 -0.034695650099999996 -0.0308188992 0.0165515619 -0.0527770605 -0.0448845285 0.0286811401 0.0602817821 0.0036806797 -0.058305837 -0.0745547 -0.0217697 0.131954 -0.008884559999999998 -0.00376485 0.00196639 -424.36614990234375 351.9421691894531 346.2874450683594 1.0263350000000002 61.859291 0.1964816 0.017362050900000002 0.0327483045 0.025601837599999996 -0.052947338600000005 -0.0112390287 -0.0057812624 -0.0023575676000000003 0.0141540424 0.0444799277 0.0049808671 -0.0019177547 -0.039960696000000004 0.0161964974 -0.053154198799999997 -0.0441197852 0.029976924199999998 0.0598674458 0.0014730073999999998 -0.0590936366 -0.07942019999999998 -0.0681896 0.0692983 -0.007538119999999999 -0.00403607 0.00199954 -423.3648681640625 351.61138916015625 345.8852844238281 0.994223 59.923851 0.09422880000000003 0.0315013476 0.0272749264 0.0462887229 -0.0354235913 -0.0014099557 -0.045145552199999994 0.0005759388 0.0070887046 0.0323585742 -0.0043356243 0.018714535600000002 -0.0120754401 0.0158408552 -0.053523752699999996 -0.043340877699999995 0.0312555998 0.0593997236 -0.0007365563000000001 -0.0597781596 -0.0918848 -0.0602115 0.0591302 -0.00677487 -0.00369122 0.00183528 -423.40228271484375 351.9134826660156 346.06304931640625 1.039104 62.628887 0.194276 0.0328661099 0.029443089500000002 0.0537095122 -0.006629089 -0.0202112416 -0.0723990082 0.0047721402 0.0179099644 0.0384570677 -0.016193028300000002 0.0119897496 0.0277432541 0.0154846479 -0.053885669500000004 -0.0425480561 0.0325164369 0.0588790326 -0.0029451740999999997 -0.0603582097 -0.08445379999999998 -0.01113 0.0964447 -0.008022899999999998 -0.00411934 0.00216811 -423.3897399902344 351.6880798339844 345.78656005859375 0.988752 59.594078 0.15253169999999996 0.045402413600000004 0.025410369500000002 0.0476353602 0.0333954418 -0.0215123975 -0.0335446102 -0.0025440534 0.0014290379 0.0195097245 -0.0018649439 0.014256956000000001 0.0411759325 0.0151278882 -0.054239897599999996 -0.0417415748 0.033758716 0.058305837 -0.0051500103000000005 -0.0608327732 -0.0902044 -0.0719686 0.0699242 -0.00703126 -0.00392905 0.0021616 -422.7668762207031 351.4952392578125 345.99603271484375 0.9755720000000002 58.799713 0.09536039999999997 0.025201566 0.0171973013 0.0280993198 0.0483696895 -0.059364945 0.025616817000000004 0.0026399909000000004 0.0040565251 0.0247700931 -0.0120644462 0.008000493000000001 0.051159029800000005 0.0147705889 -0.0545863863 -0.0409216928 0.0349817282 0.057680648099999995 -0.0073482335 -0.061201020700000004 -0.0917033 -0.0278846 0.0798142 -0.00651845 -0.00375262 0.00227011 -424.080322265625 351.4493713378906 346.17706298828125 0.992622 59.827328 0.11118245 0.014840133 0.0086544572 0.012217308400000002 0.0595060734 -0.0687002662 0.0213362999 0.0024970962 0.0108179537 0.032458341200000004 0.0016845879999999999 0.00104682 0.0484065117 0.0144127627 -0.0549250863 -0.0400886733 0.0361847754 0.0570040233 -0.0095370211 -0.06146230849999999 -0.0919712 -0.00416325 0.0957754 -0.00752283 -0.00411934 0.00221657 -417.5284729003906 348.4391174316406 341.1147155761719 1.580422 95.255257 1.445874345 -0.0790233671 0.0314003006 0.0489106264 0.0443080946 -0.0509156609 0.0189071722 0.0817259511 0.0172028724 0.00035558650000000003 -0.0166687705 0.09875713119999999 0.0370810799 0.0140544224 -0.0552559492 -0.0392427837 0.0373671711 0.05627656599999999 -0.011713562700000001 -0.061616180199999995 -0.438044 -0.247257 0.146285 -0.0128594 9.95139e-05 -0.00435197 -418.19091796875 348.2479248046875 339.64501953125 1.880119 113.318604 0.9360719049999998 -0.1109426106 0.030597105299999997 0.0355856374 0.0367447243 -0.0724148784 0.0169703295 0.10202465039999999 0.0825147918 -0.0582945687 -0.1734329634 -0.073767431 0.0588038653 0.013695580700000001 -0.055578927800000004 -0.0383842957 0.038528240299999995 0.0554989249 -0.0138750634 -0.061662366600000004 -0.390372 -0.326547 0.0556109 -0.0226449 0.00144462 -0.00759008 -424.94091796875 352.2395935058594 347.3620300292969 1.559419 93.989342 1.1128402499999999 -0.0792304399 -0.0242622273 -0.0018140702 0.0257119977 -0.0388553289 -0.0603107957 0.033887173199999995 0.0824656954 -0.0022610285 0.0307639394 0.028266095800000002 0.030548457200000004 0.0133362505 -0.055893976100000006 -0.0375134847 0.0396673204 0.0546717934 -0.0160187477 -0.0616007872 -0.25822 -0.160444 0.0142407 -0.0137564 -0.000676261 -0.00313516 -421.6093444824219 351.98199462890625 346.223388671875 1.024628 61.756397 0.37193627000000007 -0.069063072 -0.0065112223 -0.008524024 0.006548840699999999 -0.0308709598 0.0036452315000000002 0.0166342935 0.0514752556 0.0032358711 0.024863652000000003 0.0022249138 0.011267113799999999 0.0129764445 -0.056201049100000004 -0.0366306304 0.0407837614 0.0537959092 -0.0181418631 -0.0614315496 -0.221457 -0.16666 0.00168588 -0.00982569 -0.00145083 -0.00151239 -422.35382080078125 352.2723388671875 346.2593078613281 0.972845 58.635365 0.17737693000000002 -0.06318649309999999 -0.0069691785 -0.0404669607 -6.15042e-05 -0.0225879446 -0.02120398 0.0162400143 0.04619489 0.0115332741 0.020731117 -0.0210893988 0.0200870344 0.012616175600000001 -0.0565001029 -0.0357360162 0.041876926 0.052872053200000005 -0.0202416832 -0.061154949400000005 -0.189513 -0.12929 0.00700116 -0.00936539 -0.00225015 -0.000717057 -424.7076110839844 352.8108215332031 347.04071044921875 1.03486 62.373127 0.23513748999999995 -0.041279871 -0.0158013198 -0.0345595492 0.010057102 -0.0232909723 -0.04506566730000001 0.0061182703 0.044376871 0.0243955783 0.0209189102 -0.022134108599999997 0.014762108500000001 0.012255456699999999 -0.056791094900000005 -0.0348299293 0.0429461904 0.0519010494 -0.022315511899999998 -0.0607714702 -0.1253 -0.091163 0.0106486 -0.00918997 -0.00336622 0.000574454 -424.1550598144531 352.6535949707031 346.78173828125 0.986096 59.433998 0.14767120000000003 -0.0530107915 0.0014335181 -0.043869512 0.0113073676 -0.0047418153000000005 -0.0639371577 0.0028142119 0.0321738869 0.0219080758 0.0157849263 -0.0174264049 0.0057008584 0.0118943007 -0.0570739836 -0.0339126607 0.0439909442 0.0508837635 -0.024360686200000002 -0.0602817821 -0.139926 -0.115312 0.0373337 -0.008045049999999998 -0.00300062 0.000440752 -424.0668640136719 352.33819580078125 346.44195556640625 1.0070960000000002 60.699738 0.10894034999999996 -0.043764011 0.0095077361 -0.055993126500000004 -0.0389070675 -0.0330319588 -0.0364280065 0.0048033953 0.0328917434 0.036890122000000004 -0.0020304148 -0.030578072799999998 -0.0225901649 0.0115327203 -0.057348728499999994 -0.0329845047 0.0450105913 0.0498211028 -0.02637458 -0.059686740999999995 -0.139912 -0.0597373 0.0451467 -0.008779749999999998 -0.0030263 0.000591145 -424.81427001953125 352.2562255859375 346.2680969238281 1.005395 60.597179 0.1207324 -0.016634396699999998 0.0245449987 -0.0351348135 -0.0551324978 -0.023535043999999998 0.015581861499999999 -0.0029063514000000003 0.019695968 0.030668974300000002 -0.0016384833 -0.0103057548 -0.0517783618 0.011170728500000001 -0.057615290599999994 -0.032045759300000004 0.046004549699999994 0.048714014900000005 -0.0283546073 -0.0589873867 -0.139914 -0.0938236 0.0373613 -0.007752239999999999 -0.00340638 0.000760729 -422.05657958984375 352.1700134277344 345.8394775390625 1.004128 60.520805 0.06196264999999996 -0.0051074901 0.0426428254 0.0029461911 -0.06260347200000001 -0.0107359058 0.0503716549 0.00017778310000000002 0.0208265643 0.031235145 -1.67866e-05 -0.0043443327 -0.059382320999999995 0.010808338300000001 -0.0578736318 -0.031096726 0.0469722521 0.047563487 -0.030298225699999997 -0.058184941500000004 -0.139928 -0.07565439999999998 0.0566884 -0.00765562 -0.00311962 0.0008663959999999999 -422.1356201171875 352.1509704589844 346.02471923828125 1.013172 61.065945 0.09017365 0.0005078042 0.0338096632 0.0255557172 -0.055044300899999996 -0.0191295571 0.035163219 0.0001789774 0.0191552577 0.040011024 -0.0143766945 -0.0017187985999999999 -0.0336436133 0.0104455625 -0.058123715199999995 -0.0301377094 0.0479131463 0.046370545 -0.0322029395 -0.0572808079 -0.139882 -0.0422079 0.0666327 -0.00826958 -0.00333473 0.000760729 -423.0480346679688 352.432861328125 345.9150695800781 0.994727 59.954189 0.12457345 0.0168576369 0.0283689547 0.0458419426 -0.0467421792 0.0173151995 -0.0147536723 -0.0051258326000000005 0.010918133100000001 0.0122718123 0.0040361265 0.0166511349 -0.0331144979 0.010082414100000001 -0.0583655051 -0.029169017400000004 0.0488266951 0.045136252800000005 -0.034066302799999996 -0.05627656599999999 -0.139882 -0.102134 0.0541894 -0.0072255 -0.00333473 0.000760728 -423.0245361328125 351.4356994628906 345.81500244140625 0.981028 59.128548 0.09885295000000002 0.0229049619 0.0275829859 0.0580657096 -0.0309894851 0.0120718393 -0.045163619 0.0036244445000000003 0.0016662813 0.0099794702 0.0003019519 0.0175682356 0.0039418668 0.009718906 -0.058598967 -0.0281909609 0.049712377300000006 0.043861710899999996 -0.0358859231 -0.0551739708 -0.139882 -0.0557233 0.07391209999999998 -0.00787989 -0.00333473 0.000760729 -425.8929443359375 352.049560546875 346.0365295410156 1.022274 61.614555 0.07602049999999991 0.0281748873 0.0019910404 0.0511038937 0.0038703767 -0.0117534851 -0.07182500139999999 -0.0011808922 0.0071077747 -0.0132773886 0.0023438021 0.0109371375 0.0279793742 0.0093550512 -0.058824067699999996 -0.027203854 0.050569687300000006 0.0425480561 -0.0376594638 -0.05397494940000001 -0.146812 -0.0524673 0.0403272 -0.00794319 -0.00373216 0.000944991 -421.2095642089844 351.776611328125 345.5497741699219 0.989831 59.659138 0.12880155 0.0290451071 0.016655511799999998 0.054114432000000004 0.0338961096 -0.0105474724 -0.0007520843 -0.0005066492 -0.0030560644 -0.0003386763 0.006854194 0.0127307835 0.044577704100000004 0.0089908627 -0.0590407749 -0.0262080137 0.051398136 0.0411964596 -0.039384647599999996 -0.0526815972 -0.144347 -0.105569 0.0555291 -0.00702109 -0.00358736 0.00103875 -422.1073303222656 352.2035217285156 345.9828796386719 0.9997990000000002 60.259895 0.14915840000000002 0.0105781406 -8.877e-07 0.032017690099999996 0.0594295998 -0.0419285448 0.0261311088 -0.0036693878000000004 0.0076564526 0.0031731805 -0.0026860795000000002 0.019973951299999997 0.062792141 0.0086263535 -0.059249057800000005 -0.0252037594 0.052197250300000005 0.0398081268 -0.041059259300000005 -0.0512961746 -0.13993 -0.0411533 0.08632779999999998 -0.0074634 -0.00333473 0.00133435 -420.1533203125 351.8241271972656 345.6193542480469 0.985431 59.393944 0.1133233 -0.0036475565000000003 -0.0035924693 0.0195532126 0.0634018384 -0.013870218799999999 0.07490759030000001 -0.0022980046 -0.003375367 0.009495073 -0.0056338174 0.0091184499 0.0612307694 0.008261536600000001 -0.0594488867 -0.0241914138 0.0529665744 0.0383842957 -0.042681148499999995 -0.0498211028 -0.148517 -0.0782892 0.0624944 -0.00695459 -0.00364104 0.00127413 -421.9633483886719 351.81988525390625 345.7237854003906 1.00546 60.601082 0.07361039999999999 -0.0139059176 -0.0073569058 -0.0184929164 0.0696343915 0.0166994205 -0.0107983508 0.0022909904000000003 -0.0022764995 0.0153074193 0.0156275915 -0.0124444305 0.06663919509999999 0.007896425 -0.059640233 -0.023171301800000002 0.053705669000000004 0.0369262359 -0.0442482328 -0.0482589599 -0.15215 -0.0568948 0.0822684 -0.00668472 -0.00333473 0.00127413 -424.2965087890625 351.56085205078125 345.83709716796875 1.003746 60.497784 0.10487530000000003 -0.030254825699999998 -0.0056435636 -0.0431778134 0.040154926699999996 0.0322793283 -0.09062475769999999 0.0037399202000000004 0.0042248381 0.0354233479 0.010486508200000001 -0.0071166361 0.0401991452 0.0075310317 -0.0598230695 -0.0221437508 0.0544141125 0.0354352477 -0.0457584997 -0.04661247599999999 -0.144784 -0.0224411 0.0801703 -0.00790387 -0.00333473 0.00127413 -422.2561340332031 352.03302001953125 345.5464172363281 0.997692 60.132896 0.14641510000000002 -0.0284321891 0.0191379649 -0.0644608032 0.0068671501 0.0397403621 -0.0343684524 -0.0013267062 -0.000839966 0.0221413069 0.0061532712 0.0034484659000000003 -0.0181531915 0.007165369699999999 -0.05999737 -0.0211090908 0.0550915004 0.0339126607 -0.04721001019999999 -0.0448845285 -0.152293 -0.08534859999999998 0.0679727 -0.00662785 -0.00333473 0.00127413 -422.4893798828125 351.54461669921875 345.3058776855469 1.013685 61.096817 0.0530353 -0.0168435102 0.0295242741 -0.055421379800000004 -0.04849598 0.0091537535 0.0379827129 -0.0030656595000000003 -0.0090239335 0.018157121000000002 -0.0101408437 -0.0189606584 -0.0586017456 0.006799452199999999 -0.060163109699999995 -0.020067654 0.055737446100000004 0.0323598325 -0.0486009003 -0.0430781374 -0.14835 -0.067322 0.0504075 -0.006459 -0.00323357 0.00127413 -421.2701416015625 351.62396240234375 345.5201721191406 1.002561 60.426357 0.14919729999999998 0.0071914035 0.0392955731 -0.0064449432 -0.060810755999999994 -0.0009298527 0.0611106487 0.0020865948 0.0030022984999999998 0.0398691345 -0.011479557900000001 -0.014858703999999999 -0.05409250559999999 0.0064332921 -0.060320264900000004 -0.0190197746 0.056351581 0.0307781479 -0.0499293841 -0.0411964596 -0.146068 -0.0287711 0.0972094 -0.007589089999999999 -0.00333473 0.00127413 -423.9424743652344 351.7538146972656 345.59564208984375 1.035838 62.432076 0.11697359999999997 0.0227044779 0.0250585396 0.0252282669 -0.0507769229 0.0253156247 -0.0071299534 -0.0035962576 -0.0072132989 0.014479565500000001 0.0022321204 -0.006930486800000001 -0.045635389400000004 0.0060669025 -0.060468813200000006 -0.0179657891 0.0569335547 0.029169017400000004 -0.0511937557 -0.0392427837 -0.15213 -0.0638625 0.0657622 -0.00708433 -0.00371743 0.00127413 -421.79791259765625 351.64263916015625 345.25250244140625 0.98693 59.484264 0.06247239999999996 0.039199561699999996 0.0251434323 0.0485003339 -0.0241995272 0.0313294155 -0.0457119578 -0.0021932328 -0.0172731525 0.008723049 -0.0052449575 0.0154686873 -0.009607239 0.0057002965 -0.0606087335 -0.0169060359 0.0574830349 0.0275338758 -0.052392391600000005 -0.0372205242 -0.147224 -0.0663918 0.0676908 -0.00640486 -0.00333473 0.00127413 -421.93072509765625 352.1482849121094 345.708740234375 1.026816 61.888298 0.1272926 0.0470898203 0.0207069948 0.0610288358 0.0146292004 0.0031783196000000004 -0.0333325724 -0.0061132941000000005 -0.0073838742 -0.001646058 -0.0054390672 0.023915826299999998 0.0397765263 0.005333487099999999 -0.0607400057 -0.0158408552 0.057999708 0.025874181200000002 -0.053523752699999996 -0.0351332152 -0.152643 -0.0101424 0.0783385 -0.00714534 -0.00369378 0.00127413 -423.099853515625 351.7292785644531 345.8302307128906 0.990612 59.7062 0.1305567 0.0469942033 0.008852149 0.0428985004 0.0405635142 -0.0064250910999999996 0.0076453484999999995 -0.0069496159 -0.017051946499999998 -0.0171191389 -0.0058363784 0.0185908797 0.043179329800000006 0.0049664875 -0.060862611100000005 -0.0147705889 0.0584832792 0.0241914138 -0.0545863863 -0.0329845047 -0.147397 -0.0658508 0.0696422 -0.00614075 -0.00348025 0.00127413 -421.5107421875 352.27752685546875 346.03955078125 0.989419 59.634304 0.0531963 0.020022476 -0.0036083053 0.0310779838 0.0671342506 -0.023294095299999998 0.0523726357 -0.009906657 -0.015509258500000001 -0.0105998873 -0.0183705534 0.0199972097 0.0616241134 0.0045993107 -0.060976532199999996 -0.013695580700000001 0.0589334724 0.022487074 -0.055578927800000004 -0.0307781479 -0.150358 -0.0380616 0.0813828 -0.00611743 -0.0034356 0.00142027 -422.28912353515625 351.97943115234375 346.1861877441406 0.999593 60.247524 0.08907579999999998 0.0032203551000000003 -0.013936120900000001 0.0085176652 0.0704002095 -0.0102516257 0.0275278861 -0.0058939463 -0.0046106728 0.009313088800000001 0.0027355609000000005 -0.0086485306 0.0769878695 0.0042319699 -0.0610817528 -0.012616175600000001 0.0593500308 0.0207626817 -0.0565001029 -0.0285180009 -0.150482 -0.0177823 0.0608183 -0.00675984 -0.00360921 0.00127413 -420.774658203125 351.58770751953125 345.85504150390625 1.003311 60.471558 0.10080179999999998 -0.0196344023 -0.0064488235999999996 -0.0433020962 0.061712373499999994 0.0466474791 -0.0070087343000000005 -0.0012070985000000002 -0.0202283669 0.0011430699000000001 0.0144320524 -5.71065e-05 0.0274773977 0.0038644781 -0.061178257800000004 -0.0115327203 0.0597327166 0.0190197746 -0.057348728499999994 -0.0262080137 -0.153062 -0.0648663 0.054811 -0.00589529 -0.00357115 0.00127413 -422.6864929199219 351.8775634765625 346.20751953125 1.033639 62.299541 0.1168921 -0.026893925899999997 0.0107180713 -0.0731417439 0.017215149199999998 0.022736507599999997 -0.0677866313 -0.0054545991000000005 -0.0071645738 0.027143106099999998 -0.0006317544 -0.0108997546 -0.008140302 0.0034968484000000005 -0.061266033600000006 -0.0104455625 0.0600813114 0.0172599069 -0.058123715199999995 -0.0238522233 -0.146675 -0.0134394 0.0925847 -0.00627281 -0.00352258 0.00127413 -422.8456115722656 352.4344787597656 346.22808837890625 0.994814 59.959465 0.08209830000000001 -0.010621235900000001 0.021378302400000004 -0.052403482300000005 -0.024496937799999997 0.030314101200000002 0.0064703908 -0.0122472211 -0.0053087295 0.0217521445 0.0021283870000000002 -0.0151414997 -0.040866952000000005 0.0031290940000000002 -0.0613450675 -0.0093550512 0.060395616299999996 0.0154846479 -0.058824067699999996 -0.0214547469 -0.150762 -0.0247122 0.0462732 -0.00630376 -0.00390017 0.00127413 -422.9660339355469 352.00299072265625 346.23626708984375 0.9918 59.777802 0.09859279999999998 0.0033584942999999997 0.0287212617 -0.0472375124 -0.048790541900000005 0.0084625901 0.0406435552 -0.0117558295 -0.0152058781 0.0047684817 -0.0067508376 -0.0115114222 -0.06563714820000001 0.0027612279999999997 -0.0614153483 -0.008261536600000001 0.060675451799999995 0.013695580700000001 -0.0594488867 -0.0190197746 -0.150703 -0.0395441 0.0623171 -0.00564199 -0.00337131 0.00143666 -422.44915771484375 351.9327697753906 346.5376281738281 0.989137 59.617283 0.12046626999999997 0.018384969299999998 0.039892994 -0.0054338065 -0.0537514678 -0.001585472 0.06653288019999999 -0.0072107003 -0.0074497122999999995 0.025523831 -0.0028616592 -0.0084084583 -0.0664157242 0.0023932635000000002 -0.0614768659 -0.007165369699999999 0.060920658200000005 0.0118943007 -0.05999737 -0.0165515619 -0.14666499999999996 -0.008350329999999998 0.0906711 -0.00668082 -0.00345629 0.00145046 -423.9931335449219 352.3074951171875 346.7554626464844 1.011729 60.978962 0.10625807 0.024933695 0.021902189300000003 0.0333136702 -0.062121087 0.0106012578 0.0043502983 -0.010044719399999999 -0.011308383799999999 -0.0015908532 -0.0125697599 0.0036901995 -0.057059823200000005 0.0020252136 -0.0615296116 -0.0060669025 0.061131095700000006 0.010082414100000001 -0.060468813200000006 -0.0140544224 -0.152155 -0.032254 0.0564882 -0.0061437 -0.00372816 0.00140582 -423.6745910644531 352.1184387207031 346.8763427734375 0.98844 59.575275 0.07847870000000003 0.0447592452 0.0255725063 0.0537008268 -0.035567461099999996 0.0194432168 -0.0402978534 -0.0107025817 -0.0209731744 0.0010398476 -0.0125732225 0.0182753466 -0.011926136399999999 0.0016570915 -0.0615735779 -0.0049664875 0.061306644 0.008261536600000001 -0.060862611100000005 -0.0115327203 -0.146409 -0.0485833 0.0650126 -0.00566166 -0.00334158 0.00149478 -424.34906005859375 352.42840576171875 347.3380126953125 1.042073 62.807858 0.12424978000000003 0.0488040451 0.0089761566 0.052543589800000005 0.002944869 -0.0199920901 -0.0530406286 -0.0098403771 -0.0092902134 -0.0094402303 -0.0057109295 0.0119313315 0.0186552891 0.0012889102 -0.0616087584 -0.0038644781 0.06144720309999999 0.0064332921 -0.061178257800000004 -0.0089908627 -0.145747 -0.00454162 0.0908037 -0.00644768 -0.00354873 0.00141285 -423.4538269042969 352.07965087890625 347.1715087890625 1.017207 61.309105 0.11093467999999997 0.035279282200000005 -0.0099449915 0.0268605023 0.0468246833 -0.0358520774 0.045555255 -0.0094717593 -0.0177346076 -0.02287013 -0.0052841443999999994 0.0152549147 0.054979404800000006 0.000920683 -0.0616351482 -0.0027612279999999997 0.0615526926 0.0045993107 -0.0614153483 -0.0064332921 -0.145745 -0.0317784 0.0468788 -0.00586563 -0.00374777 0.00139852 -422.6480712890625 352.08612060546875 346.703125 1.014634 61.154064 0.037242899999999995 0.0033816905 -0.0233172889 -0.0066642587 0.0656518367 -0.0027511182 0.032191565299999995 -0.0083457415 -0.0152698077 -0.024685920099999998 0.0022264366000000002 0.0003469703 0.0541358792 0.0005524229 -0.061652743499999996 -0.0016570915 0.0616230524 0.0027612279999999997 -0.0615735779 -0.0038644781 -0.145772 -0.0358861 0.0550545 -0.00595598 -0.00335771 0.00138028 -425.5208740234375 351.64764404296875 347.0054626464844 1.044097 62.929871 0.11216687 -0.0180362575 -0.010253023100000001 -0.055090863600000005 0.027054304100000003 0.0231150246 -0.083615245 -0.00351559 -0.0060941651 0.0094704862 0.0242820773 -0.0166484252 0.0144462064 0.0001841432 -0.0616615418 -0.0005524229 0.0616582424 0.000920683 -0.061652743499999996 -0.0012889102 -0.145743 0.00108797 0.0803908 -0.00650628 -0.00363701 0.00154723 -423.056396484375 351.6148376464844 346.5876770019531 1.034194 62.33297 0.09589186999999998 0.0016956422 0.0032560717 -0.0482294484 -0.0370651803 0.0156615799 0.021735155 -0.007353035799999999 -0.0186052074 0.0129778098 0.010067210600000001 -0.017737501699999998 -0.05009777940000001 -0.0001841432 -0.0616615418 0.0005524229 0.0616582424 -0.000920683 -0.061652743499999996 0.0012889102 -0.145747 -0.042523 0.0563679 -0.00622338 -0.00362793 0.00127413 -423.0142211914063 351.8645935058594 346.55059814453125 1.008234 60.768295 0.08314669999999999 0.0241448692 0.014098157 -0.007604683399999999 -0.056266075199999994 0.015186296100000002 0.0551742581 -0.010641140700000001 -0.016262713 0.0028514632 -0.0076045986999999995 -0.017857669 -0.06778292849999999 -0.0005524229 -0.061652743499999996 0.0016570915 0.0616230524 -0.0027612279999999997 -0.0615735779 0.0038644781 -0.151153 -0.0469808 0.08058329999999998 -0.0056934 -0.00347605 0.00157362 -424.0895385742188 351.9103698730469 346.6689453125 1.091821 65.806252 0.11193832000000005 0.0363140147 0.0180340179 0.0407674153 -0.048622809 0.0153853476 -0.0503740466 -0.0085678722 -0.0116771003 0.0028042871000000004 0.0029113337 -0.0049580244 -0.022957021600000002 -0.000920683 -0.0616351482 0.0027612279999999997 0.0615526926 -0.0045993107 -0.0614153483 0.0064332921 -0.14575 0.00393002 0.0833273 -0.00642673 -0.00367341 0.00170054 -423.2201843261719 351.49432373046875 346.393310546875 1.03575 62.426769 0.12321862000000003 0.0660591741 0.0010317133 0.0523422112 0.0003475424 0.015706557700000002 -0.0607401239 -0.0099515447 -0.029016688500000002 -0.0229334363 -0.0001448073 0.0150579 0.0192092267 -0.0012889102 -0.0616087584 0.0038644781 0.06144720309999999 -0.0064332921 -0.061178257800000004 0.0089908627 -0.153091 -0.0436701 0.06585480000000002 -0.00561298 -0.00360936 0.0015622399999999997 -421.7550659179688 351.44525146484375 346.4691467285156 1.01372 61.098969 0.06358719999999998 0.03991794 -0.0167302547 0.0339420531 0.04879327730000001 -0.0224715214 0.061852524900000004 -0.0079213945 -0.0199438373 -0.0220940869 -0.0049164514 0.0049871574 0.0536179506 -0.0016570915 -0.0615735779 0.0049664875 0.061306644 -0.008261536600000001 -0.060862611100000005 0.0115327203 -0.14577 -0.0255227 0.08472359999999998 -0.00579584 -0.00349337 0.00164839 -421.45635986328125 352.1016845703125 346.6666259765625 0.996851 60.082253 0.09657218 0.0067522789 -0.0163490636 0.0028501807 0.055377361900000005 -0.0185816307 0.034071564900000004 -0.007544854 -0.012234094 -0.0060462588 0.0015124323 -0.0149976616 0.041548512200000005 -0.0020252136 -0.0615296116 0.0060669025 0.061131095700000006 -0.010082414100000001 -0.060468813200000006 0.0140544224 -0.145759 0.00169778 0.0755389 -0.00673733 -0.00367341 0.0015668 -420.78070068359375 352.3178405761719 346.60931396484375 0.9817570000000002 59.172493 0.12888128 -0.0082579993 -0.010545012900000001 -0.0106295156 0.0603809941 0.007689063 0.041915391499999996 -0.012972514499999999 -0.012361843899999999 -0.0053890872999999995 0.0082497868 -0.0118962461 0.05040502400000001 -0.0023932635000000002 -0.0614768659 0.007165369699999999 0.060920658200000005 -0.0118943007 -0.05999737 0.0165515619 -0.151568 -0.0476931 0.0751275 -0.00547346 -0.00359273 0.00168765 -423.9154357910156 352.0771789550781 347.07659912109375 1.039327 62.642365 0.11952255999999997 -0.0216324404 -0.0142949083 -0.0628127964 0.041317104 0.0213775059 -0.060973049800000005 -0.0094777205 -0.0139018346 0.0055140706000000005 0.0120257388 -0.0218017902 0.017972361200000002 -0.0027612279999999997 -0.0614153483 0.008261536600000001 0.060675451799999995 -0.013695580700000001 -0.0594488867 0.0190197746 -0.145759 0.00283246 0.104202 -0.00599235 -0.00367341 0.00177035 -423.5655822753906 351.8409423828125 347.0753479003906 1.024534 61.750759 0.07703055999999998 -0.0176274877 -0.0089197872 -0.0669768304 -0.0164901895 0.011178166699999999 -0.0165854421 -0.010543627 -0.0157270396 0.0072771764 0.000917608 -0.035881979 -0.0304492454 -0.0031290940000000002 -0.0613450675 0.0093550512 0.060395616299999996 -0.0154846479 -0.058824067699999996 0.0214547469 -0.15458 -0.0311391 0.0852925 -0.00574857 -0.00367341 0.0017075599999999997 -423.7508850097656 352.0266418457031 346.920654296875 1.006564 60.667675 0.039044800000000005 -0.0008721005000000001 0.0208999401 -0.0509749696 -0.059626320700000006 -0.0135086782 0.0365194986 -0.0118750665 -0.0143820142 0.0052321532 -0.0062634497 -0.0261125069 -0.0746038392 -0.0034968484000000005 -0.061266033600000006 0.0104455625 0.0600813114 -0.0172599069 -0.058123715199999995 0.0238522233 -0.145751 -0.0440656 0.0882948 -0.00558059 -0.00367341 0.0015898 -422.8259582519531 351.642578125 347.02508544921875 0.9935790000000002 59.885006 0.10655752 0.0090213507 0.0173016 -0.0150729829 -0.0686909738 -0.019873698000000002 0.059805524699999994 -0.0100660838 -0.0120027288 0.0203194708 0.012105850900000001 -0.0262434077 -0.0644347867 -0.0038644781 -0.061178257800000004 0.0115327203 0.0597327166 -0.0190197746 -0.057348728499999994 0.0262080137 -0.145728 -0.00417308 0.0861038 -0.00655807 -0.00384264 0.00144749 -423.8187561035156 352.1510925292969 346.9847106933594 1.023226 61.671879 0.08029502000000001 0.025017043 0.0081184106 0.0288706673 -0.0719204809 0.0095984751 0.0051992176 -0.014214818999999998 -0.0134285701 -0.0034634064 -0.0005935768 -0.0013883398000000002 -0.0679039268 -0.0042319699 -0.0610817528 0.012616175600000001 0.0593500308 -0.0207626817 -0.0565001029 0.0285180009 -0.150071 -0.0415857 0.0826374 -0.00597614 -0.00394541 0.00143073 -423.77154541015625 352.24627685546875 346.7822265625 1.025837 61.8293 0.09809249999999997 0.0462542136 0.0045895963 0.0528750234 -0.0337791264 0.014640639399999999 -0.0826769938 -0.014960761699999998 -0.019683888400000002 -0.0163221432 0.0003089843 0.0162794878 -0.013701072 -0.0045993107 -0.060976532199999996 0.013695580700000001 0.0589334724 -0.022487074 -0.055578927800000004 0.0307781479 -0.155761 -0.0316946 0.0970898 -0.00535261 -0.00354894 0.00177191 -424.74017333984375 351.98748779296875 347.145263671875 1.055362 63.60878 0.15959460000000003 0.038639568199999995 -0.0221509825 0.039015003 0.015586193 -0.0216206435 -0.0067438341 -0.011418741699999999 -0.0076103907 -0.0189863249 0.005863291 -0.007974851 0.023153043999999998 -0.0049664875 -0.060862611100000005 0.0147705889 0.0584832792 -0.0241914138 -0.0545863863 0.0329845047 -0.14574 0.0195532 0.0761805 -0.006566 -0.00385949 0.00174752 -424.1434020996094 352.32257080078125 347.3174743652344 1.009025 60.81599 0.11422493999999997 0.023327357200000003 -0.0472761317 0.0227958246 0.0381810159 -0.0056383471 0.0327575389 -0.0154189558 -0.012063331299999999 -0.0408557636 0.0172012801 -0.0008544442 0.0393667154 -0.005333487099999999 -0.0607400057 0.0158408552 0.057999708 -0.025874181200000002 -0.053523752699999996 0.0351332152 -0.145694 -0.00341794 0.0165542 -0.00675019 -0.00427144 0.00171203 -420.5997924804688 352.46820068359375 346.83648681640625 1.0157600000000002 61.221905 0.23348786 0.0230027377 -0.026321017999999998 0.0073961525 0.0481740687 -0.0258750672 0.0570177761 -0.0190412917 -0.0189156865 -0.0337267949 0.0056392796999999995 -0.0018588097 0.0378277006 -0.0057002965 -0.0606087335 0.0169060359 0.0574830349 -0.0275338758 -0.052392391600000005 0.0372205242 -0.153047 -0.0749817 0.0791918 -0.00538721 -0.00381492 0.00169286 -421.5812683105469 351.8645324707031 347.01214599609375 1.016085 61.241528 0.11568909999999998 -0.0054021876 -0.036047570099999995 -0.0241367298 0.0647287272 0.0027367992 0.025964602799999997 -0.0086185152 -0.017722553500000002 -0.0178451891 0.0159175127 -0.0092236977 0.0483897796 -0.0060669025 -0.060468813200000006 0.0179657891 0.0569335547 -0.029169017400000004 -0.0511937557 0.0392427837 -0.145791 -0.0174313 0.101565 -0.00545372 -0.00331124 0.00169286 -424.6976318359375 352.34686279296875 347.7719421386719 1.046371 63.066868 0.08850182000000002 -0.0169693845 -0.031527144900000005 -0.059322451 0.0237630808 0.019130016200000002 -0.07052876940000001 -0.0116476029 -0.0035495692 -0.0020103394 0.0179923372 -0.036666341 -0.0010285908 -0.0064332921 -0.060320264900000004 0.0190197746 0.056351581 -0.0307781479 -0.0499293841 0.0411964596 -0.145762 0.007672919999999998 0.0871884 -0.00590856 -0.00367341 0.00185569 -424.1856384277344 351.9267272949219 347.33856201171875 1.034116 62.328259 0.10547602000000003 0.0070415302 -0.0138493196 -0.0503529284 -0.0439065488 0.0023470018 0.0031596439 -0.0145304 -0.0149719259 -0.0031095309000000004 0.0014870031 -0.01944538 -0.0637206926 -0.006799452199999999 -0.060163109699999995 0.020067654 0.055737446100000004 -0.0323598325 -0.0486009003 0.0430781374 -0.14575 -0.056337 0.09365250000000003 -0.00537159 -0.00367341 0.00169286 -423.38916015625 351.97882080078125 347.2102966308594 1.023629 61.696205 0.08362345999999996 0.033392038 -0.0016165898000000001 0.0032592431 -0.06263700929999999 0.0018841526999999999 0.0281980177 -0.0080398172 -0.0168520058 -0.0080411059 0.0033164558 -0.0088972508 -0.0556316124 -0.007165369699999999 -0.05999737 0.0211090908 0.0550915004 -0.0339126607 -0.04721001019999999 0.0448845285 -0.14574 -0.00815854 0.109331 -0.00541879 -0.00383285 0.00188135 -424.82818603515625 351.9365234375 347.30462646484375 1.092296 65.834877 0.06538249 0.0476112853 -0.0126601705 0.0404942914 -0.043062602 0.0070755124 -0.0670686508 -0.011319074699999999 -0.010602446599999999 -0.0189241225 0.0133420657 -0.011950173 -0.0162473525 -0.0075310317 -0.0598230695 0.0221437508 0.0544141125 -0.0354352477 -0.0457584997 0.04661247599999999 -0.145762 0.00982145 0.101999 -0.00603963 -0.00367341 0.00190204 -422.53363037109375 352.3207702636719 347.1430969238281 1.039734 62.666893 0.15682205 0.05639283480000001 -0.0157825986 0.044799062699999996 0.0202534014 -0.0176818867 -0.0077057314000000005 -0.0177922968 -0.0252166545 -0.0480801009 0.017273620700000002 0.0020732161999999998 0.024072958300000002 -0.007896425 -0.059640233 0.023171301800000002 0.053705669000000004 -0.0369262359 -0.0442482328 0.0482589599 -0.145734 -0.0605666 0.0746975 -0.00516325 -0.00385766 0.00178058 -422.9571838378906 352.22271728515625 347.1920166015625 1.02439 61.742062 0.09931673999999997 0.010622128 -0.045723022599999996 0.009569438000000001 0.0531784314 -0.0062161276 0.046503306900000006 -0.0138414285 -0.0140305059 -0.0352662386 0.0095441368 -0.0192941482 0.050782990599999994 -0.008261536600000001 -0.0594488867 0.0241914138 0.0529665744 -0.0383842957 -0.042681148499999995 0.0498211028 -0.147987 -0.00296826 0.0985779 -0.00520297 -0.00367341 0.00169285 -424.906982421875 352.1824951171875 347.2353515625 1.038994 62.622253 0.11594815999999998 -0.0051423623 -0.050358807900000004 -0.0350585877 0.0295090925 0.0282228962 -0.0468504982 -0.0146681127 -0.006622089300000001 -0.008694141899999999 0.045584791 -0.0398838542 0.0228892271 -0.0086263535 -0.059249057800000005 0.0252037594 0.052197250300000005 -0.0398081268 -0.041059259300000005 0.0512961746 -0.145689 0.0355939 0.0945914 -0.0059103 -0.00417242 0.00190854 -423.4152526855469 351.8850402832031 346.5765075683594 1.033736 62.305393 0.122037 -0.003448004 -0.0284800076 -0.0632263175 -0.0208423459 0.021239447999999998 -0.029798318900000002 -0.013741626000000002 -0.015185738 -0.0124831997 0.020881561 -0.0246763623 -0.0350786415 -0.0089908627 -0.0590407749 0.0262080137 0.051398136 -0.0411964596 -0.039384647599999996 0.0526815972 -0.145691 -0.0314626 0.08619839999999998 -0.00504354 -0.00417242 0.00184359 -422.3483276367188 351.3887939453125 346.0973205566406 1.016984 61.295673 0.05798449999999999 0.020825352 -0.007977205400000001 -0.041685711 -0.0652662406 0.0204827338 0.04883233730000001 -0.011724732 -0.0250426273 -0.0126569267 0.0159793476 -0.0324552615 -0.07986357820000001 -0.0093550512 -0.058824067699999996 0.027203854 0.050569687300000006 -0.0425480561 -0.0376594638 0.05397494940000001 -0.145718 -0.0167102 0.0934285 -0.00484384 -0.00379368 0.00198465 -422.2748718261719 351.71759033203125 346.2295227050781 1.008756 60.799755 0.11634870000000003 0.0299340027 -0.011695148700000001 0.004381459 -0.0602362714 0.0081581148 0.043900467699999994 -0.0123940505 -0.0165054741 -0.0025180971 0.0244170522 -0.0246205027 -0.0583530781 -0.009718906 -0.058598967 0.0281909609 0.049712377300000006 -0.043861710899999996 -0.0358859231 0.0551739708 -0.145756 0.018509 0.117126 -0.00592362 -0.00376121 0.00202028 -422.718505859375 352.04962158203125 346.31982421875 1.017756 61.342197 0.1144385 0.045343036100000005 -0.0263671653 0.0412184963 -0.058902891299999996 0.021277525699999997 -0.0060841318999999994 -0.017678732 -0.0190525298 -0.0212998712 0.025238842200000004 -0.017160889 -0.047041514900000005 -0.010082414100000001 -0.0583655051 0.029169017400000004 0.0488266951 -0.045136252800000005 -0.034066302799999996 0.05627656599999999 -0.145703 -0.0295023 0.0982763 -0.00530639 -0.00408005 0.00200586 -422.1099243164063 351.9504699707031 346.4938659667969 0.984848 59.35881 0.0433124 0.060287010599999996 -0.0174425404 0.048151882699999995 -0.0274210729 0.018581709199999998 -0.058369866900000004 -0.017142591000000002 -0.0217055929 -0.027296614900000002 0.021584801600000002 -0.0089845655 -0.0106874843 -0.0104455625 -0.058123715199999995 0.0301377094 0.0479131463 -0.046370545 -0.0322029395 0.0572808079 -0.145737 -0.023353 0.0932532 -0.00492651 -0.00386643 0.00195724 -423.7091674804688 352.0915832519531 347.0028076171875 1.032212 62.213509 0.10736609999999996 0.0586275556 -0.0354025879 0.044459265199999994 0.0048383178 -0.011817707 -0.0289568589 -0.017851856399999998 -0.014880365900000001 -0.0279544681 0.0140970602 -0.0045805519 0.0228996648 -0.010808338300000001 -0.0578736318 0.031096726 0.0469722521 -0.047563487 -0.030298225699999997 0.058184941500000004 -0.139365 0.0249503 0.102666 -0.00574148 -0.00387646 0.00191668 -421.5442199707031 352.4117126464844 346.8356628417969 0.989607 59.645592 0.1240591 0.0472242227 -0.0442042697 0.026575413 0.0401719722 -0.0224274486 0.0398233484 -0.0195155471 -0.0214943618 -0.0446623845 0.016171305 -0.0044929325 0.037657791499999996 -0.011170728500000001 -0.057615290599999994 0.032045759300000004 0.046004549699999994 -0.048714014900000005 -0.0283546073 0.0589873867 -0.132264 -0.031324 0.0918057 -0.00509904 -0.00400667 0.00169286 -420.6295776367188 350.8545837402344 345.02227783203125 1.168657 70.437317 0.25510549999999993 0.0148706421 -0.0554163036 0.0235735903 0.0476593143 -0.0366593026 0.0534355809 0.0124539124 -0.0061993434 -0.050260397400000004 0.0500016899 0.0249562616 0.0410605719 -0.0115327203 -0.057348728499999994 0.0329845047 0.0450105913 -0.0498211028 -0.02637458 0.059686740999999995 -0.129556 -0.0837447 0.14995 -0.0076283 -0.00417242 0.0018345 -422.6178588867188 351.5042419433594 345.54022216796875 1.358652 81.88868 0.37498197 -0.0014688322 -0.07695412459999999 -0.004849271 0.039514092599999995 -0.0635779209 0.00039524 0.0062495355 0.0350227281 -0.0251286543 0.0097157511 -0.053903538499999994 0.0503580432 -0.0118943007 -0.0570739836 0.0339126607 0.0439909442 -0.0508837635 -0.024360686200000002 0.0602817821 -0.0654082 0.00338597 0.135923 -0.009860130000000003 -0.00533363 0.00263499 -420.6769714355469 352.3966369628906 346.6168212890625 1.120178 67.515404 0.28085887 -0.0133455466 -0.0488771263 -0.0220569381 0.027313674 -0.0328615391 0.051491877 -0.0094324671 0.017665354299999998 -0.0130409728 0.051504332699999995 -0.0166837217 0.0338754846 -0.012255456699999999 -0.056791094900000005 0.0348299293 0.0429461904 -0.0519010494 -0.022315511899999998 0.0607714702 -0.08371499999999998 -0.07057860000000002 0.140476 -0.00703084 -0.00478372 0.0023335 -422.7582702636719 351.9284362792969 346.5043029785156 0.97896 59.003902 0.10698750000000001 -0.016422506599999998 -0.0549309717 -0.0433468909 0.0284524913 -0.022590903500000002 -0.0022184689000000002 -0.003498682 0.0167817936 0.0027847465999999996 0.0386297067 -0.03575692 0.030469596600000003 -0.012616175600000001 -0.0565001029 0.0357360162 0.041876926 -0.052872053200000005 -0.0202416832 0.061154949400000005 -0.102312 -0.0160031 0.155845 -0.0070238 -0.00448303 0.00227231 -422.84375 352.2189636230469 346.8207702636719 0.964336 58.122475 0.0774803 -0.0145992953 -0.058557927999999995 -0.0424643644 0.015744261699999998 -0.020013881100000002 0.0196514939 -0.014168373 0.0101208601 0.00022264150000000002 0.048837958099999995 -0.0391397556 0.011757996599999999 -0.0129764445 -0.056201049100000004 0.0366306304 0.0407837614 -0.0537959092 -0.0181418631 0.0614315496 -0.110227 -0.0290379 0.143161 -0.00619207 -0.00443783 0.00227231 -423.8365173339844 352.55279541015625 346.9889221191406 1.001551 60.365532 0.08324310000000003 -0.0098700877 -0.0529568599 -0.061541105 0.0200284701 0.017987659 -0.0554965717 -0.0169523745 0.0041132797 -0.0009852164999999999 0.034727085899999996 -0.0500017382 0.0043647567 -0.0133362505 -0.055893976100000006 0.0375134847 0.0396673204 -0.0546717934 -0.0160187477 0.0616007872 -0.105186 -0.032385 0.131572 -0.00511668 -0.0042479 0.00227231 -424.3617248535156 351.87579345703125 346.8218078613281 0.9938920000000002 59.903885 0.1365014 -0.012420121200000002 -0.0452155183 -0.0688329871 -0.0237948699 0.0078060239 -0.0689877966 -0.0145568198 0.0063200292000000005 0.0191307811 0.0390222379 -0.0373914738 -0.022765977799999997 -0.013695580700000001 -0.055578927800000004 0.0383842957 0.038528240299999995 -0.0554989249 -0.0138750634 0.061662366600000004 -0.107132 0.0300154 0.143111 -0.00602979 -0.00454711 0.00227231 -422.29010009765625 352.276123046875 346.68463134765625 0.974888 58.758476 0.1413646 -0.0034901336 -0.0368069848 -0.06949750240000001 -0.0403706286 0.013703283 -0.0226037608 -0.0189569937 -0.0077822803000000005 0.0038286287 0.0336041878 -0.0385197021 -0.0438986892 -0.0140544224 -0.0552559492 0.0392427837 0.0373671711 -0.05627656599999999 -0.011713562700000001 0.061616180199999995 -0.105689 -0.0266737 0.123571 -0.00487044 -0.00449451 0.00233421 -422.5505676269531 351.8749694824219 346.6341552734375 0.9847570000000002 59.353287 0.05286497399999997 -0.002167942 -0.028766027799999996 -0.07607462599999999 -0.062303696 0.0059415323999999995 0.020479888300000002 -0.016628863600000002 -0.0031687068 0.003857267 0.0257887107 -0.0379424954 -0.06564794110000001 -0.0144127627 -0.0549250863 0.0400886733 0.0361847754 -0.0570040233 -0.0095370211 0.06146230849999999 -0.10600200000000001 0.000830274 0.12144 -0.00450004 -0.00446847 0.00227231 -422.6456909179688 352.3600158691406 346.9045715332031 0.9853090000000002 59.386581 0.11083832599999996 0.0077365503000000006 -0.0240850261 -0.056410402400000004 -0.0717334884 0.0042848031 0.0458891525 -0.0208762657 -0.0021544422 -0.0041681425 0.025687652400000004 -0.0497983677 -0.0827506308 -0.0147705889 -0.0545863863 0.0409216928 0.0349817282 -0.057680648099999995 -0.0073482335 0.061201020700000004 -0.0922927 0.0384368 0.11277 -0.00541728 -0.00456828 0.00227231 -423.7093811035156 352.1448669433594 346.72174072265625 1.017677 61.337456 0.1199639 0.02461359 -0.0182305379 -0.032310691600000004 -0.0812785104 0.0141625643 0.0389227234 -0.0192172169 -0.0074533546 -0.019561557 0.029298173900000002 -0.0202829003 -0.0858611032 -0.0151278882 -0.054239897599999996 0.0417415748 0.033758716 -0.058305837 -0.0051500103000000005 0.0608327732 -0.0993306 -0.0326072 0.115636 -0.00466176 -0.00454348 0.00227231 -421.2937316894531 352.0890808105469 346.230712890625 1.078237 64.987511 0.2223304 0.0250452419 -0.0074110574 -0.0082451319 -0.07068775 0.0109136174 0.0609189597 -0.0137984499 -0.018711523100000002 -0.0335353204 -0.0084279776 -0.0411021827 -0.0759983316 -0.0154846479 -0.053885669500000004 0.0425480561 0.0325164369 -0.0588790326 -0.0029451740999999997 0.0603582097 -0.114905 0.0444918 0.135491 -0.00598668 -0.00416994 0.00177473 -421.4561462402344 352.227783203125 346.6115417480469 1.049795 63.273277 0.09400490000000003 0.0385089746 -0.0144814374 -0.0058419611 -0.0687047625 -0.0034088853000000005 0.0615125967 -0.0151748193 0.0045066681 0.0030896777 0.0327425365 -0.0300551802 -0.056591387 -0.0158408552 -0.053523752699999996 0.043340877699999995 0.0312555998 -0.0593997236 -0.0007365563000000001 0.0597781596 -0.105755 0.0445967 0.126141 -0.00544197 -0.00466537 0.00224259 -423.6142578125 351.9715270996094 347.0666809082031 1.013613 61.092537 0.2177588 0.0167637999 -0.0117756175 -0.005412407199999999 -0.0620226625 -0.034436012099999996 0.030865654300000003 -0.0110315416 0.0164970131 0.0204331765 0.0231988043 -0.0505995215 -0.035057669799999996 -0.0161964974 -0.053154198799999997 0.0441197852 0.029976924199999998 -0.0598674458 0.0014730073999999998 0.0590936366 -0.103266 0.110771 0.201107 -0.00669981 -0.00465603 0.002458 -427.740234375 352.4847106933594 347.1923828125 1.05381 63.515274 0.2609612 0.024877446600000002 -0.0559776802 -0.0246304569 -0.0512546847 -0.0171045689 -0.0913772999 -0.018423078 0.0200505984 -0.0079608371 0.0401458068 -0.040262107400000004 -0.0402735102 -0.0165515619 -0.0527770605 0.0448845285 0.0286811401 -0.0602817821 0.0036806797 0.058305837 -0.108416 -0.0269597 0.145813 -0.00613822 -0.00523027 0.0025779 -423.3394775390625 353.0061950683594 346.8187561035156 1.234664 74.41567999999998 0.4004576 0.0063593151 -0.0325957304 -0.025438136899999998 -0.0193870761 0.0069204352 0.0119839502 -0.0264957321 -0.00017609439999999999 -0.0487983171 0.0147207082 -0.0122212533 -0.022759951 -0.0169060359 -0.052392391600000005 0.0456348621 0.0273689869 -0.060642363 0.0058836257 0.057416137699999995 -0.191272 -0.084914 0.0820212 -0.00257154 -0.00552273 0.00251993 -421.97845458984375 349.72161865234375 344.50994873046875 1.496215 90.179893 1.0792577 -0.0012798273 -0.046241961100000006 -0.0029049118 0.0199219524 0.0869564028 0.0356474281 0.0095975031 -0.0723173962 -0.1199444347 -0.0347604158 0.0510009564 -0.028026108799999998 -0.0172599069 -0.0520002471 0.046370545 0.026041213599999998 -0.060948867000000004 0.0080790168 0.056426093600000005 -0.284592 -0.0303675 -0.265353 0.00646376 -0.00289899 0.00249863 -424.1256713867188 353.44305419921875 349.127197265625 1.451313 87.473602 1.0715289 0.0445281501 -0.0699649765 -0.0196453693 -0.0046037047999999995 0.0057414096 0.041156126 -0.0372914667 -0.0168640065 -0.0787979162 0.013916442 -0.0261348623 0.009069177 -0.0176131622 -0.0516006827 0.0470913411 0.0246985778 -0.061201020700000004 0.010264034 0.0553374348 -0.166239 0.0730873 0.0551311 -0.00319971 -0.00264181 0.00183454 -425.1435241699219 353.13153076171875 348.6854553222656 1.051298 63.363842 0.059509599999999975 0.057746738799999996 -0.0718942896 0.013702285 -0.0044518692 0.0293604835 -0.0541616599 -0.032873114700000004 -0.016904306799999998 -0.0636160845 0.0171360495 -0.0216423856 0.011169146999999999 -0.0179657891 -0.0511937557 0.047797019100000004 0.023341845899999998 -0.0613985992 0.012435871599999999 0.0541520642 -0.153895 0.07285719999999998 0.0516151 -0.0033907 -0.00315692 0.00199683 -422.7452697753906 353.29705810546875 347.9543762207031 1.019454 61.444538 0.15587456 0.0420840797 -0.06346851 0.020126138000000002 0.0186987252 -0.0016357363000000001 0.040097863500000004 -0.033330087200000004 -0.013189423999999998 -0.07132720669999999 0.0276283368 -0.0079039478 0.0239118248 -0.0183177752 -0.050779524000000006 0.0484873523 0.021971792200000003 -0.0615414265 0.0145917409 0.052872053200000005 -0.152211 -0.00784506 0.0743409 -0.0024331 -0.00312874 0.0020263 -424.16485595703125 352.35308837890625 346.89385986328125 1.038503 62.592697 0.06613685999999999 0.0149720576 -0.0831111812 -0.0184594144 0.0287169178 0.026716054399999998 0.0087715771 -0.024333394700000004 -0.0232936969 -0.06290824610000001 0.0351210388 -0.0139469091 0.027704867 -0.0186691079 -0.0503580468 0.0491621191 0.020589198700000002 -0.061629375099999995 0.0167288735 0.05149963900000001 -0.152143 0.0313076 0.0769561 -0.0027276 -0.00326344 0.00208312 -381.43780517578125 328.59796142578125 318.6061706542969 3.266707 196.891068 4.998244499999999 -0.27949821329999996 0.0493168888 0.19188755870000002 -0.011588620800000001 0.27473458030000003 0.1383723112 0.3781581853 -0.1450526235 0.084602809 0.2117462949 0.31736477949999997 0.0833617164 -0.0190197746 -0.0499293841 0.0498211028 0.019194854299999998 -0.061662366600000004 0.0188445253 0.050037220099999995 -0.590689 -0.677089 1.46892 -0.0447741 0.00053772 0.00542222 -430.1203918457031 348.6003112792969 337.3504333496094 3.559375 214.530762 1.912353 -0.0821045373 -0.0365527078 0.032241907400000006 -0.0291464888 -0.0476142554 -0.1442313003 0.1142043246 0.1589983794 -0.13013242279999998 -0.2885125416 0.1279321592 -0.0699563358 -0.0193697628 -0.049493597199999996 0.050464092099999996 0.017789555 -0.0616403716 0.020935979599999998 0.0484873523 -0.238862 -0.263924 1.87262 -0.0368451 -0.00245278 0.0014685 -420.9122314453125 350.6184387207031 344.6624755859375 2.237752 134.873871 1.5853179499999999 -0.09660376539999999 0.0274469187 0.0335664597 0.0168789102 -0.0016264710999999998 -0.053468085 0.0829219735 0.145673912 0.0025913276000000002 -0.08234539910000001 0.0639192953 -0.023081462 -0.0197190601 -0.0490507482 0.0510908803 0.0163741027 -0.061563409699999995 0.023000551 0.0468527442 -0.139761 -0.284412 1.02678 -0.0261859 -0.0034299 0.000707041 -416.0423889160156 351.7149658203125 343.8774108886719 1.249672 75.32029 0.63827645 -0.08787958720000001 0.0469013786 0.0482506743 0.029953811 -0.0347097439 -0.0013538407999999999 0.0598150951 0.1241603616 0.0260196187 -0.024213616099999998 0.0354661675 0.029322807700000002 -0.020067654 -0.0486009003 0.0517012663 0.0149493052 -0.0614315496 0.0250355883 0.045136252800000005 -0.136732 -0.122598 0.9196820000000002 -0.0192144 -0.00338039 0.00101274 -416.6216430664063 351.4099426269531 343.5850524902344 1.147374 69.154549 0.7932158 -0.08651585619999999 0.0317053361 0.0278264586 0.0415710305 -0.0969107884 0.022814073100000002 0.0476876128 0.11132616599999999 0.033368533 -0.016538328300000002 -0.0039084546 0.061998104299999995 -0.020415532 -0.048144117699999996 0.052295054199999996 0.013515975800000002 -0.0612449087 0.0270384785 0.043340877699999995 -0.244915 -0.114362 0.665929 -0.0135094 -0.00219469 -0.000557436 -417.2756042480469 351.6089782714844 343.672119140625 1.072087 64.61685900000002 0.3013182 -0.0885339501 0.0393997498 0.0114484199 0.0334181996 -0.0750047499 -0.0174234578 0.04118784 0.1032295738 0.040453483 -0.011552347 0.0047513762 0.05622744440000001 -0.0207626817 -0.0476804656 0.052872053200000005 0.0120749325 -0.061003653600000006 0.0290066498 0.0414697568 -0.296138 -0.059247 0.623405 -0.0121936 -0.00251497 -0.00197048 -412.31427001953125 346.5185852050781 338.6865539550781 1.354589 81.643822 0.8741875 -0.17176138359999998 0.04558414400000001 0.0711636254 0.0179050913 0.060690622199999995 0.0036113513 0.11824592699999999 0.0817420278 0.0444737349 0.0203566862 0.1322736098 -0.0005133234999999999 -0.0211090908 -0.04721001019999999 0.053432078200000004 0.010626997800000001 -0.060707999400000004 0.0309375749 0.0395261602 -0.552367 -0.135477 0.811977 -0.0165198 -0.00423537 -0.00298701 -420.53814697265625 350.3009338378906 341.71527099609375 1.739488 104.842476 1.9515818 -0.1122973687 -0.0031921453999999997 0.0582734507 -0.0132743728 0.0728957074 -0.0660589099 0.0944983474 0.1399426479 -0.0149088518 -0.1169942427 0.1346583501 -0.012123116699999999 -0.0214547469 -0.046732818499999995 0.05397494940000001 0.0091729979 -0.0603582097 0.032828774399999996 0.0375134847 -1.32604 -0.193237 1.45057 -0.0218548 -0.00614497 -0.000600494 -403.7314147949219 345.10888671875 334.2265930175781 1.444173 87.043259 0.5011631999999997 -0.1424296957 0.0381241223 0.0989981752 -0.006750082199999999 0.0690426135 -0.0166578336 0.1531964284 0.0648963615 0.0247377528 -0.0849648059 0.1256678796 0.0080494822 -0.0217996377 -0.0462489587 0.0545004924 0.0077137627000000005 -0.059954596500000006 0.0346778198 0.0354352477 -1.32894 -0.202312 1.28201 -0.0191909 -0.00428106 0.00128426 -418.6464538574219 352.6941223144531 345.50244140625 1.808055 108.975136 2.1226263 -0.1138750332 0.0766725524 0.0600054884 0.0365209154 -0.0458939588 -0.0043352168 0.0320673433 0.0956600428 0.046863561100000006 -0.0370116257 0.052592152999999996 0.038859774900000005 -0.0221437508 -0.0457584997 0.055008538600000004 0.0062501251 -0.0594975196 0.036482337000000004 0.0332950814 -0.469324 -0.08129369999999998 0.789845 -0.0104851 -0.00765017 0.00220589 -415.0279235839844 351.4504699707031 344.04193115234375 0.942763 56.822212 0.30418820000000013 -0.1017150592 0.0786017312 0.048158628499999995 0.0417232721 -0.065068477 0.0112137188 0.0372076766 0.0765185736 0.0643926115 -0.0254301126 0.0104275035 0.0531444855 -0.022487074 -0.0452615117 0.0554989249 0.0047829204 -0.0589873867 0.038240008799999996 0.031096726 -0.390554 -0.028478 0.708189 -0.009544960000000003 -0.0073794 0.00281391 -418.3803405761719 351.62249755859375 344.8193664550781 0.9751050000000002 58.77153 0.3668353 -0.0801844635 0.0554067799 0.027544582 0.0340847507 -0.0657583232 -0.0022876656 0.022626427799999998 0.063638717 0.0638562263 -0.008382901199999999 -0.0042630786 0.058586199400000004 -0.0228295951 -0.0447580654 0.0559714938 0.003312986 -0.058424652599999995 0.0399485782 0.028844023599999997 -0.351145 0.0194848 0.564413 -0.00831807 -0.00629838 0.00321975 -416.8069763183594 351.5849609375 344.3423156738281 1.026259 61.854683 0.3547696000000001 -0.06968792730000001 0.0724468588 0.0043474851 0.046090084 -0.0314205399 -0.0028625911 0.013401146599999999 0.0337760604 0.0732611953 -0.0177494105 0.0061055216 0.0574833162 -0.023171301800000002 -0.0442482328 0.056426093600000005 0.0018411607000000001 -0.057809819299999995 0.041605851299999996 0.0265409112 -0.319167 0.0239209 0.51541 -0.00433552 -0.00536314 0.00275049 -423.1354675292969 352.40936279296875 346.1038513183594 1.244313 74.99726099999998 0.6488629 -0.0149252484 0.0126746327 -0.053155308899999996 0.0386578883 0.056841211100000004 -0.057410986100000005 -0.019337585 -0.018540563700000002 0.0025758523 0.0042235889 -0.0339061309 0.033533104700000003 -0.023512181899999998 -0.0437320865 0.0568625783 0.0003682847 -0.057143434800000004 0.04320970019999999 0.0241914138 -0.273208 0.022326 0.240882 -0.00111602 -0.00265059 0.00214692 -418.4499206542969 352.0712890625 345.3442687988281 1.017885 61.350006 0.17379210000000003 -0.023854337000000003 0.0299966751 -0.0658393642 0.0114561618 0.0209044326 -0.0352460602 -0.018403136100000002 -0.0164089256 0.0342071832 -0.008356224399999999 -0.0194982112 0.0018115726 -0.0238522233 -0.04320970019999999 0.0572808079 -0.0011048015 -0.056426093600000005 0.0447580654 0.0217996377 -0.271391 0.0955996 0.244251 -0.0018335 -0.00337606 0.00261062 -419.1112365722656 352.1437072753906 345.2984619140625 0.976786 58.872883 0.15570490000000003 -0.0119107696 0.0438664187 -0.0724635387 -0.014711053799999999 0.0166800691 0.0004672146 -0.0179805687 -0.012364441100000002 0.0289318161 -0.0248313827 -0.019431400300000002 -0.0382879047 -0.0241914138 -0.042681148499999995 0.057680648099999995 -0.0025772572 -0.055658435199999995 0.0462489587 0.0193697628 -0.273648 0.0363352 0.265147 -0.00107512 -0.00306929 0.00221002 -420.4413146972656 351.6837463378906 345.521240234375 0.9906 59.705498 0.1736448 -0.004422174 0.0680626179 -0.0481275741 -0.045184999299999994 -0.0095133037 0.049516363 -0.0159525451 -0.0157110527 0.0502104292 -0.0308175607 -0.022644120299999997 -0.051410701399999995 -0.024529741400000003 -0.0421465068 0.0580619705 -0.0040482420000000005 -0.0548411441 0.0476804656 0.0169060359 -0.247245 0.103608 0.29487 -0.00135959 -0.00358014 0.00241962 -419.6473388671875 351.62896728515625 345.6497802734375 0.967 58.283031 0.07151610000000004 0.0189618504 0.06766151320000001 -0.022233211099999997 -0.043993692300000005 0.0002666888 0.0357006199 -0.0167969886 -0.015423474 0.0391091991 -0.0257199105 0.0077114674 -0.0536105537 -0.0248671939 -0.041605851299999996 0.058424652599999995 -0.0055169164 -0.05397494940000001 0.0490507482 0.0144127627 -0.23772 0.0786209 0.287076 -0.0010534 -0.00379233 0.00248544 -418.9615478515625 351.8234558105469 345.80267333984375 0.967743 58.327808 0.06568415000000001 0.0301487805 0.0703560798 -0.0069774165 -0.0393003124 0.0061570858999999995 0.057461163499999995 -0.0186964214 -0.0247389319 0.042906738300000004 -0.0369381559 0.0054517433999999995 -0.052482956 -0.0252037594 -0.041059259300000005 0.058768578200000005 -0.0069824421 -0.053060623200000004 0.0503580468 0.0118943007 -0.23909 0.0757087 0.298645 -0.000304101 -0.00358014 0.00252061 -419.6753234863281 351.7593078613281 346.1188659667969 1.009272 60.830894 0.11859274999999997 0.0276107927 0.06866515549999999 0.021092530699999997 -0.028276063799999997 -0.0248488284 0.019408708 -0.0177545523 -0.0201570228 0.0414372242 -0.0329587837 0.0129256875 -0.0314004408 -0.0255394259 -0.0405068086 0.0590936366 -0.0084439827 -0.052098980999999996 0.0516006827 0.0093550512 -0.239019 0.112943 0.316532 -0.00111388 -0.00379241 0.00276657 -422.27276611328125 351.53399658203125 346.1166687011719 0.99742 60.116497 0.09682470000000003 0.044067184599999996 0.066210256 0.0447473251 -0.0193339788 -0.002002235 -0.0551286987 -0.013770552 -0.020730941200000002 0.0386171194 -0.0263255869 0.0169869058 -0.0050380914 -0.025874181200000002 -0.0399485782 0.0593997236 -0.0099007042 -0.0510908803 0.0527770605 0.006799452199999999 -0.239134 0.0751837 0.329917 -0.000782472 -0.00349075 0.00248833 -422.04248046875 351.7495422363281 345.74310302734375 1.009807 60.86314 0.035670499999999994 0.0495643625 0.051569550199999994 0.0411217369 0.0310298427 -0.026947155499999997 -0.0432072606 -0.0180884813 -0.0225546896 0.0136109412 -0.0429351579 0.0267300836 0.0383393096 -0.0262080137 -0.039384647599999996 0.059686740999999995 -0.011351775 -0.050037220099999995 0.053885669500000004 0.0042319699 -0.239099 0.0962352 0.333524 -0.000782472 -0.003588 0.00261062 -421.6839599609375 351.4595642089844 345.8724670410156 0.999159 60.221348 0.1157992 0.017132814099999998 0.027773046000000003 0.027932422999999998 0.063342975 -0.06338024639999999 0.0227716881 -0.013739878799999999 -0.007751890500000001 0.026026464 -0.0215084302 0.0112781667 0.06580490230000001 -0.0265409112 -0.038815097400000005 0.059954596500000006 -0.012796367099999999 -0.0489389399 0.0549250863 0.0016570915 -0.244236 0.118076 0.341341 -0.00191486 -0.00396659 0.00271973 -417.738037109375 351.3692626953125 345.33258056640625 0.96524 58.17696 0.13038679999999997 -0.000270669 0.0312168344 0.0037762311999999998 0.07441905160000001 -0.010850259499999999 0.057639717800000004 -0.014111835500000001 -0.0266302828 0.029569029700000003 -0.0278649781 0.0176900778 0.0656814815 -0.0268728619 -0.038240008799999996 0.0602032042 -0.014233656 -0.047797019100000004 0.055893976100000006 -0.000920683 -0.244722 0.0766613 0.336405 -0.000793038 -0.00352652 0.00261062 -419.8628845214844 351.568359375 345.51226806640625 0.960336 57.881405 0.060819449999999976 -0.01070881 0.0281359439 -0.0244137148 0.0777633915 -0.0091804062 0.0044453755 -0.0130626528 -0.015988826499999997 0.0339401093 -0.0201823184 0.0067077535 0.0732611837 -0.027203854 -0.0376594638 0.0604324842 -0.0156628214 -0.04661247599999999 0.056791094900000005 -0.0034968484000000005 -0.239189 0.0995235 0.327475 -0.0008354929999999998 -0.00326034 0.00244937 -422.4987487792969 351.3699645996094 346.0322570800781 0.994591 59.946003 0.11540434999999998 -0.014313031499999998 0.0185412544 -0.0387777866 0.0580043118 0.011305381000000001 -0.0708969293 -0.0086500406 -0.010106941099999999 0.0399708752 -0.012745536799999999 -0.0166379345 0.0526798053 -0.0275338758 -0.037073545299999996 0.060642363 -0.0170830476 -0.0453863669 0.057615290599999994 -0.0060669025 -0.23901 0.127879 0.336526 -0.00167625 -0.00381471 0.00261062 -419.77490234375 351.44244384765625 345.6802673339844 0.981476 59.155567 0.11940634999999995 -0.028755087599999996 0.0394407414 -0.0603907303 0.0281335252 0.0144500952 -0.0327123158 -0.0123311932 -0.0168627979 0.048842275899999996 -0.0198487369 -0.0171848882 0.010335123199999999 -0.0278629153 -0.036482337000000004 0.0608327732 -0.018493524 -0.0441197852 0.0583655051 -0.0086263535 -0.23906 0.0774393 0.330282 -0.000603147 -0.00363436 0.00261062 -421.48577880859375 351.2916564941406 345.5426940917969 0.990654 59.708748 0.04891735000000005 -0.0190920045 0.0655958814 -0.07128014490000001 -0.023667556 -0.0060796043 0.0079269932 -0.0139786079 -0.0191278401 0.0533322608 -0.0333970323 -0.0140409817 -0.044440648099999994 -0.0281909609 -0.0358859231 0.061003653600000006 -0.0198934458 -0.0428138604 0.0590407749 -0.011170728500000001 -0.239145 0.106642 0.329783 -0.00072408 -0.00337268 0.00261062 -420.5012512207031 351.2781982421875 345.6613464355469 0.969045 58.40633 0.108104 0.0059798062 0.058926953600000005 -0.025717250299999998 -0.04403736230000001 -0.014884317 0.0439250403 -0.0111031498 -0.0108040105 0.0587366876 -0.0263536079 -0.0187305097 -0.045449246299999996 -0.0285180009 -0.0352843888 0.061154949400000005 -0.0212820138 -0.0414697568 0.059640233 -0.013695580700000001 -0.238982 0.131304 0.336535 -0.00171888 -0.00390842 0.00261062 -421.4539794921875 351.36175537109375 345.560791015625 0.960475 57.889786 0.14115905 0.0283283069 0.060085735 0.0006942722 -0.0449613669 -0.0211546235 0.0396752889 -0.014757578200000001 -0.0174069405 0.0444395266 -0.0388275309 0.0044987638 -0.0453782116 -0.028844023599999997 -0.0346778198 0.0612866121 -0.022658435600000002 -0.0400886733 0.060163109699999995 -0.0161964974 -0.239088 0.0888294 0.328379 -0.000377261 -0.0035485 0.00250371 -422.3851623535156 351.499755859375 345.82940673828125 1.029197 62.031773 0.06255749999999997 0.044296603899999995 0.049730095300000006 0.0363155293 -0.0456064928 0.0008636684 -0.0315394366 -0.0146453347 -0.0196351105 0.0274457405 -0.0197615486 0.0100781716 -0.029350047 -0.029169017400000004 -0.034066302799999996 0.0613985992 -0.0240219257 -0.038671841299999996 0.0606087335 -0.0186691079 -0.239108 0.109027 0.319032 -0.000855789 -0.00347408 0.00261062 -422.9940185546875 351.74468994140625 345.89935302734375 1.0179 61.350899 0.058277549999999914 0.044980719599999996 0.0388065309 0.0314733021 0.0102872676 -0.0160080667 -0.07114038240000001 -0.0159623464 -0.0183381406 0.0186001831 -0.01911889 -0.0022809312 0.0241486519 -0.0294929706 -0.033449925 0.061490875 -0.0253717058 -0.0372205242 0.060976532199999996 -0.0211090908 -0.239021 0.1278 0.314715 -0.00124426 -0.00378762 0.00261062 -420.0005493164063 351.4852294921875 345.6397705078125 0.9854520000000002 59.395176 0.11547944999999996 0.049970423 0.0409867702 0.0415755323 0.0446576617 -0.015918626 -0.011482043999999999 -0.0138804619 -0.0230172463 0.0142293099 -0.0217899453 0.0241337044 0.0407006636 -0.0298158718 -0.032828774399999996 0.061563409699999995 -0.0267070056 -0.0357360162 0.061266033600000006 -0.023512181899999998 -0.23909 0.0831601 0.324432 -0.000268039 -0.00354277 0.00261062 -419.77874755859375 351.7409362792969 345.9888000488281 0.9620820000000002 57.986626 0.15881895000000001 0.0257785591 0.030920624700000003 0.036847313300000004 0.0623546788 -0.04241853190000001 0.019138481399999997 -0.0144525498 -0.0128197185 0.0163072796 -0.026480350899999998 0.009546998499999999 0.052247860800000004 -0.0301377094 -0.0322029395 0.061616180199999995 -0.0280270631 -0.0342196412 0.0614768659 -0.025874181200000002 -0.232227 0.12533200000000003 0.362065 -0.00109217 -0.00390842 0.00286386 -421.4137878417969 351.4993591308594 346.0808410644531 0.948517 57.169018 0.13293990000000008 0.0241768774 0.0216466076 0.0267440806 0.0632782305 -0.032641542200000005 0.0319893767 -0.0153144977 -0.0196070669 0.009989455999999999 -0.023494488900000002 0.0096383724 0.0611890787 -0.0304584719 -0.0315725097 0.061649169299999994 -0.0293311248 -0.0326727513 0.0616087584 -0.0281909609 -0.239098 0.102255 0.320878 -0.000592462 -0.00351614 0.00251975 -419.7642211914063 351.5432434082031 345.8372497558594 0.955116 57.566761 0.03203845 0.0118799146 0.011933361799999999 0.0194238104 0.0819066423 -0.0290689906 0.052364873099999994 -0.0121584906 -0.0207505289 0.008646064200000001 -0.015994832 0.0020155634 0.0765288251 -0.0307781479 -0.0309375749 0.061662366600000004 -0.030618446400000002 -0.031096726 0.0616615418 -0.0304584719 -0.23592 0.0999434 0.319537 -0.000260585 -0.00343473 0.00261062 -421.5929260253906 351.73516845703125 346.27178955078125 0.966336 58.243 0.15059984999999998 0.000633771 0.007841551700000001 -0.0163623639 0.0679138036 -0.0269585205 -0.0194229671 -0.016341434 -0.0103828397 0.0248953853 -0.0079488724 0.0020822947 0.062367779000000005 -0.031096726 -0.030298225699999997 0.0616557679 -0.0318882933 -0.0294929706 0.0616351482 -0.0326727513 -0.23897 0.144208 0.326903 -0.00147626 -0.00390842 0.00283964 -420.1165771484375 351.8448181152344 345.89190673828125 0.953413 57.464108 0.15674035000000003 -0.009511133599999999 0.0112226854 -0.026039204700000002 0.0668771873 0.0012041023 0.017780471000000003 -0.015233263700000001 -0.0151531919 0.0256219338 -0.008693718100000001 0.0054927089000000005 0.0629778146 -0.0314141948 -0.0296545534 0.061629375099999995 -0.0331399408 -0.0278629153 0.0615296116 -0.0348299293 -0.239051 0.0925071 0.311498 -0.000116481 -0.00363435 0.00268242 -422.8116149902344 351.4920654296875 346.3127136230469 1.015889 61.229706 0.06385375000000003 -0.011790484399999999 0.013517756899999999 -0.05815406 0.047572385700000004 0.0192631501 -0.0745543775 -0.0096448552 -0.0075579220999999995 0.029073036099999998 -0.0096387113 -0.0036768126 0.032135140699999995 -0.031730543 -0.0290066498 0.061583196900000005 -0.0343726744 -0.0262080137 0.0613450675 -0.0369262359 -0.239078 0.121337 0.32677 -0.000438048 -0.00358347 0.00270447 -422.470947265625 352.1724548339844 346.3076171875 1.001201 60.344433 0.06401160000000002 -0.0089600835 0.020398033700000002 -0.0707835758 0.0033972628 0.0121933124 -0.035735455 -0.020784874 -0.005040052 0.0401812994 -0.020351656399999998 -0.020245731200000002 -0.0180856577 -0.032045759300000004 -0.0283546073 0.061517248 -0.0355857906 -0.024529741400000003 0.0610817528 -0.0389580073 -0.238882 0.126617 0.309776 -0.00050901 -0.00424884 0.00279897 -420.9900817871094 351.466796875 345.5939025878906 0.992423 59.815353 0.10382825000000001 0.008642125 0.0356348545 -0.052470708399999996 -0.0479489541 0.005393960600000001 0.0386035891 -0.0129710153 -0.0167328304 0.0291945921 -0.023454275099999998 -0.0085552651 -0.0645480718 -0.0323598325 -0.027698518999999998 0.0614315496 -0.0367785971 -0.0228295951 0.0607400057 -0.0409216928 -0.234075 0.0974146 0.298531 0.000222187 -0.0038151 0.00279243 -420.85333251953125 351.18255615234375 345.5420837402344 1.010029 60.876503 0.11520325000000002 0.0238616994 0.0478588095 0.0032307022 -0.0543540157 -0.0040707380999999996 0.0441912279 -0.0139804593 -0.0189388388 0.03168946 -0.0074028259 -0.0123741256 -0.0516129656 -0.0326727513 -0.0270384785 0.061326129199999996 -0.0379504132 -0.0211090908 0.060320264900000004 -0.0428138604 -0.233282 0.11846400000000003 0.325979 -0.00084999 -0.00391347 0.00294014 -420.587646484375 351.61083984375 345.6195373535156 1.018208 61.369457 0.07042115 0.0480965005 0.0343151731 0.0342079119 -0.0314828169 0.0132165532 -0.048292319900000005 -0.0143470376 -0.0184863023 0.011768637700000001 -0.0197600065 0.017382806 -0.0179098045 -0.0329845047 -0.02637458 0.061201020700000004 -0.0391005699 -0.0193697628 0.0598230695 -0.044631203099999996 -0.238921 0.120498 0.304895 -0.000333807 -0.00413634 0.00303437 -420.0545349121094 351.0417785644531 345.4137878417969 0.99185 59.780785 0.07814894999999998 0.0534678335 0.0308075246 0.0532008375 0.0132956749 0.0156859619 -0.061138613499999994 -0.009399479300000001 -0.029313592000000003 0.008779002 -0.0204073434 0.0185584784 0.0182615811 -0.0332950814 -0.025706918199999998 0.0610562642 -0.0402284109 -0.0176131622 0.059249057800000005 -0.046370545 -0.238962 0.09501200000000003 0.314811 0.000216932 -0.00392023 0.0029471 -419.06982421875 351.9185791015625 346.1664123535156 0.987348 59.509464 0.1546751 0.0392982427 0.0170774649 0.0574791096 0.026759553 0.0029394838 -0.0239683507 -0.0167098779 -0.0159033403 0.0087853367 0.0015374256 0.0194066355 0.0507207215 -0.0336044704 -0.0250355883 0.0608919062 -0.0413332925 -0.0158408552 0.058598967 -0.0480288462 -0.266087 0.10709 0.299248 -0.00105132 -0.00450458 0.00309268 -418.26556396484375 349.0462341308594 343.4554443359375 1.436316 86.569702 1.4229131 -0.0427083697 -0.0464129349 0.0996567479 -0.025932069199999998 -0.0622545584 -0.056743373 0.0537379838 0.058069927400000006 -0.0341438924 0.0293938108 0.019196724499999998 0.0161411588 -0.0339126607 -0.024360686200000002 0.060707999400000004 -0.0424145842 -0.0140544224 0.0578736318 -0.0496032084 -0.8630799999999998 -0.0970921 0.341567 -0.00682284 -0.00975399 0.00366013 -421.3774719238281 351.5942077636719 346.9112548828125 1.568912 94.561485 1.4925633999999999 0.045151076799999995 -0.0481377521 0.035285227200000005 0.0056501936 0.0311654002 -0.0245838443 -0.012504237 -0.043940126399999994 -0.0627044912 0.0085711408 -0.0777075185 0.0510852912 -0.0342196412 -0.0236823082 0.060504603 -0.0434716687 -0.012255456699999999 0.0570739836 -0.0510908803 -0.339639 0.0410516 0.0332948 0.00264788 -0.00967867 0.00275204 -420.4640808105469 352.61004638671875 348.0830993652344 1.110303 66.92023500000002 0.5170956499999999 0.0280117584 -0.0312860258 0.0214475091 -0.0116762011 -0.0036325454999999998 0.035240392999999995 -0.0180002156 -0.009877961 -0.0265741096 0.0385922851 -0.0134685953 -0.006011544200000001 -0.0345254011 -0.023000551 0.0602817821 -0.0445039428 -0.0104455625 0.056201049100000004 -0.05248926190000001 -0.29743 0.11095600000000001 0.152784 -0.000329981 -0.00762056 0.00342593 -420.7907409667969 352.89971923828125 348.29644775390625 0.993989 59.909744 0.2323024 0.028079520299999997 -0.016826168 0.028160857 -0.0282361845 -0.0312581787 0.0534924395 -0.0252868346 -0.0111549777 -0.0184126066 0.027341874199999998 -0.0027492488 -0.0269027943 -0.0348299293 -0.022315511899999998 0.0600396084 -0.0455108174 -0.0086263535 0.0552559492 -0.0537959092 -0.28358 0.0257528 0.221097 9.1163e-05 -0.00686975 0.0035527 -426.1314086914063 353.28369140625 348.26312255859375 1.062628 64.046722 0.13964239999999997 0.044758226799999995 -0.0141650696 0.037351755699999996 -0.0186145734 -0.022651257799999998 -0.0918327185 -0.029208951 -0.0027196233 -0.045858729400000006 0.0185695111 0.018519311200000003 -0.0094021441 -0.0351332152 -0.0216272887 0.0597781596 -0.046491717800000006 -0.006799452199999999 0.054239897599999996 -0.055008538600000004 -0.323266 0.0588256 0.196565 0.000184775 -0.00629649 0.00373286 -423.09552001953125 352.0726623535156 345.57373046875 1.187228 71.55661 0.52537445 0.034151144700000004 -0.0287410289 0.0500722962 -0.0158047363 0.0357959251 -0.020956825 -0.013804329399999999 -0.0464800134 -0.0937738173 -0.0171423639 0.0223064898 0.0046543436 -0.0354352477 -0.020935979599999998 0.0594975196 -0.0474460842 -0.0049664875 0.053154198799999997 -0.0561250309 -0.372226 0.0783868 0.0387735 0.00549274 -0.00573658 0.0036195 -422.4729919433594 352.69287109375 347.9078674316406 1.154509 69.58457900000002 0.46285275 0.0306520525 -0.0345743506 0.0266529138 -0.027237978599999997 0.0157238044 0.0251656874 -0.022939702000000003 -0.006732343199999999 -0.060804915099999995 0.0171744536 0.0159458586 -0.027209941600000002 -0.0357360162 -0.0202416832 0.0591977785 -0.048373371799999995 -0.0031290940000000002 0.0520002471 -0.057143434800000004 -0.30472 0.15937 0.111606 0.000892309 -0.00557319 0.0035527 -424.6060791015625 353.07427978515625 348.17266845703125 1.011044 60.937695 0.18611735000000001 0.0262122463 -0.0360970358 -0.0113536629 -0.0348832011 -0.0169344164 0.038087568100000004 -0.0302962085 -0.0013875878 -0.0402574375 0.026791249 -0.0105860456 -0.0343758943 -0.036035509900000005 -0.0195444986 0.0588790326 -0.049273051500000005 -0.0012889102 0.050779524000000006 -0.0580619705 -0.29082 0.145254 0.17105 -0.000321398 -0.0061735 0.00371183 -422.3190307617188 352.7900390625 347.19244384765625 1.013808 61.104256 0.26793710000000004 0.0368386929 0.0073427868999999995 0.0105617704 -0.0454859374 -0.0070162127 0.0507766016 -0.0322779495 -0.022536824 -0.0231848076 -0.0008651514999999999 0.013295710300000001 -0.047037525 -0.0363337182 -0.0188445253 0.0585413841 -0.0501446098 0.0005524229 0.049493597199999996 -0.0588790326 -0.273138 0.0614688 0.225539 0.00151493 -0.00595564 0.00389726 -424.8175354003906 351.9634094238281 346.4662780761719 1.089061 65.63990800000002 0.16388470000000002 0.061596839800000004 0.0032109389000000003 0.0315267531 -0.030533694500000003 0.0096191929 -0.0849268532 -0.0233790778 -0.023355925299999997 -0.0180870753 -0.0028433409999999997 0.0106175024 -0.0116614878 -0.0366306304 -0.0181418631 0.058184941500000004 -0.0509875493 0.0023932635000000002 0.048144117699999996 -0.059593193200000005 -0.255587 0.137606 0.241498 0.00078356 -0.00617676 0.00402952 -422.3478393554688 351.45587158203125 345.76385498046875 1.032182 62.211716 0.108923 0.0497413094 -0.018536565300000002 0.0258010407 0.031364411 0.0040120957 -0.0055225437 -0.0149559864 -0.030149668199999997 -0.0310847456 0.009740357600000001 0.0026189696 0.021750458900000002 -0.0369262359 -0.0174366123 0.057809819299999995 -0.0518013888 0.0042319699 0.046732818499999995 -0.0602032042 -0.242794 0.127156 0.244011 0.00147122 -0.0068248 0.00435716 -419.2281494140625 350.97857666015625 344.7453918457031 0.992692 59.831581 0.08466749999999998 0.0348095276 -0.0223317969 0.014574410800000001 0.0557634912 0.0145039634 0.06632855780000001 -0.0135319455 -0.0378466331 -0.0365551147 -0.0027290113 0.00944728 0.0398581441 -0.0372205242 -0.0167288735 0.057416137699999995 -0.052585664000000004 0.0060669025 0.0452615117 -0.060707999400000004 -0.245449 0.110229 0.232639 0.00217939 -0.00646389 0.00436235 -420.5752868652344 351.4612731933594 344.791748046875 0.999825 60.261452 0.14300600000000002 0.0025642931 -0.037649743 -0.0268968861 0.0661978361 0.0376993979 0.005742578199999999 -0.010249352199999999 -0.0266560759 -0.0210126958 0.0097272178 -0.0305091848 0.0441610808 -0.0375134847 -0.0160187477 0.0570040233 -0.0533399272 0.007896425 0.0437320865 -0.0611066967 -0.23995 0.170372 0.225857 0.00154999 -0.00712563 0.00448285 -418.60986328125 351.2239074707031 344.4762878417969 1.025423 61.804321 0.148962 -0.0009187987 -0.023025967400000003 -0.050645346699999996 0.0490300254 0.0416764938 0.0161001392 -0.0050857817999999996 -0.025063035499999997 -0.0171083651 0.0100724818 -0.018180431 0.021308102599999997 -0.0378051071 -0.015306336299999999 0.0565736083 -0.054063747800000006 0.009718906 0.0421465068 -0.0613985992 -0.25152 0.108281 0.228501 0.00279199 -0.00704796 0.00434938 -419.7780151367188 351.1497497558594 344.9977722167969 1.035685 62.422844 0.1653135 -0.0171334409 -0.0193118284 -0.0735812729 0.0321877783 0.0411381562 -0.0234386461 -0.00507096 -0.023573141000000002 -0.0097287454 0.0135179942 -0.0341102842 0.015673116299999998 -0.0380953808 -0.0145917409 0.0561250309 -0.0547567129 0.0115327203 0.0405068086 -0.061583196900000005 -0.241149 0.174043 0.214126 0.00195127 -0.00671242 0.00402953 -420.9861755371094 351.3333435058594 345.7593994140625 0.983956 59.304993 0.136672 -0.0024900586 -0.0223691104 -0.0727932416 -0.0027539602000000002 0.0369786327 -0.028127392200000004 -0.0123517018 -0.0138327092 0.0093019138 0.0113528732 -0.0375805374 -0.0260857552 -0.0383842957 -0.0138750634 0.055658435199999995 -0.055418427 0.0133362505 0.038815097400000005 -0.061660167 -0.223141 0.154843 0.237888 0.0010068 -0.00712563 0.00418589 -419.4292907714844 351.51922607421875 345.7696228027344 0.95368 57.480202 0.154135 -0.0101363239 -0.0127263011 -0.07031522429999999 -0.0072413930000000005 0.0425477823 -0.0073646699 -0.010419418100000001 -0.0230755629 0.0015225877 0.0107984845 -0.017747227 -0.022089953399999997 -0.038671841299999996 -0.0131564061 0.0551739708 -0.056048512300000006 0.0151278882 0.037073545299999996 -0.061629375099999995 -0.225909 0.0755725 0.264686 0.00112226 -0.00637229 0.00414872 -422.5391540527344 351.5458984375 346.2972717285156 0.99331 59.868786 0.09324165000000002 0.0007435906 -0.0088808479 -0.0757722708 -0.0347146864 0.0139785137 0.006933953499999999 -0.015652088600000003 -0.0160425703 0.0090240766 0.0056818501 -0.032341437 -0.0517401876 -0.0389580073 -0.012435871599999999 0.0546717934 -0.056646609199999996 0.0169060359 0.0352843888 -0.061490875 -0.221808 0.124771 0.279832 0.000790097 -0.00628739 0.00422758 -421.4190979003906 351.8424072265625 346.0466003417969 0.996511 60.061737 0.0765191 0.030064459300000002 -0.006155646999999999 -0.0373002673 -0.0550091264 0.0214321863 0.0295048204 -0.021355703599999998 -0.0187099967 -0.0092493245 0.0091634614 -0.026237026 -0.0653853502 -0.0392427837 -0.011713562700000001 0.0541520642 -0.0572123765 0.0186691079 0.033449925 -0.0612449087 -0.228247 0.152528 0.247296 0.000875979 -0.00636969 0.00425514 -421.8249206542969 351.82293701171875 345.6173095703125 0.999066 60.215744 0.12351005 0.0484127316 0.0026190826 0.011435261799999999 -0.061812575 0.015167535800000001 0.0191599877 -0.0201692643 -0.022996419700000003 -0.015206345100000001 0.0089799062 0.0006207575 -0.0565394255 -0.0395261602 -0.0109895824 0.05361495 -0.0577454912 0.020415532 0.0315725097 -0.0608919062 -0.22861 0.113153 0.250784 0.00218733 -0.00630097 0.00402953 -422.38189697265625 351.6009216308594 345.6668395996094 1.068634 64.40873000000002 0.20110165 0.0502104756 -0.016926644299999998 0.0293313488 -0.0029377792 -0.000763488 -0.0328569291 -0.0168848136 -0.0168748812 -0.016550026000000002 0.0148851466 -0.0098609422 0.0165083531 -0.0398081268 -0.010264034 0.053060623200000004 -0.058245649000000004 0.0221437508 0.0296545534 -0.0604324842 -0.226211 0.15643399999999996 0.296272 0.000364827 -0.00624478 0.00434951 -420.5960998535156 351.8451843261719 345.13677978515625 1.005516 60.604469 0.14845314999999992 0.0453497663 -0.0268260464 0.004736679000000001 0.0441332887 0.005874332800000001 0.057393618 -0.0195650265 -0.0182916666 -0.0349230533 0.0050343259999999996 0.00015551469999999998 0.030493763700000003 -0.0400886733 -0.0095370211 0.05248926190000001 -0.0587125645 0.0238522233 0.027698518999999998 -0.0598674458 -0.217145 0.116774 0.264919 0.00134365 -0.00617611 0.00402952 -418.92388916015625 350.9462890625 344.8148498535156 0.980357 59.088093 0.038522499999999925 0.0008725984 -0.0372175938 -0.025676630099999997 0.0611059294 0.0233144034 0.0478309214 -0.0090596712 -0.0247666761 -0.0269856633 0.0162297117 -0.0191241619 0.050967423399999996 -0.0403677898 -0.0088086474 0.0519010494 -0.059145971299999996 0.0255394259 0.025706918199999998 -0.0591977785 -0.217133 0.1392 0.275022 0.00134365 -0.00618397 0.00414129 -421.0126647949219 351.3471374511719 345.2958068847656 1.007184 60.705044 0.11184080000000003 -0.0044028034 -0.031975289500000004 -0.0503804201 0.0409745181 0.0449501271 -0.051447616200000004 -0.0091018651 -0.0154957931 -0.0038214097 0.0288008711 -0.0233231025 0.0203564759 -0.0406454662 -0.0080790168 0.0512961746 -0.059545621900000005 0.027203854 0.0236823082 -0.058424652599999995 -0.217081 0.171392 0.285344 0.000274624 -0.00644871 0.00419302 -418.8890686035156 351.1061706542969 344.8015441894531 1.004064 60.516964 0.15524329999999997 -0.0065468733 -0.0121623551 -0.0809509144 -0.007167575799999999 0.0468455658 -0.0080833911 -0.009949921 -0.0201346004 -0.0112972908 0.0231072113 -0.0200708415 -0.0371693415 -0.0409216928 -0.0073482335 0.050674831600000005 -0.059911288300000004 0.028844023599999997 0.0216272887 -0.0575494194 -0.227216 0.114658 0.271802 0.00152863 -0.00631574 0.00408335 -419.6065673828125 350.95562744140625 344.63525390625 0.991268 59.74575 0.11072160000000003 0.0192430509 0.0039507801 -0.044900701900000006 -0.055385047400000005 0.0218977405 0.0590743412 -0.0093862173 -0.0183916295 0.0091995774 0.0063495805 -0.0406411064 -0.0744813919 -0.0411964596 -0.0066164016 0.050037220099999995 -0.060242761799999996 0.0304584719 0.0195444986 -0.0565736083 -0.233222 0.14483 0.300829 0.000706698 -0.00629628 0.00415229 -418.7110290527344 350.68426513671875 344.7242736816406 0.964481 58.131241 0.044644100000000124 0.039812858300000004 0.005251949499999999 -0.007741430600000001 -0.052619886 0.0130840808 0.025501270299999997 -0.006842773199999999 -0.0256415212 -0.0063694469 0.0045377694 -0.0197844854 -0.060714192800000004 -0.0414697568 -0.0058836257 0.0493835445 -0.0605398531 0.032045759300000004 0.0174366123 -0.0554989249 -0.233199 0.14629 0.289967 0.00124514 -0.00639681 0.0041593 -418.6997375488281 351.148681640625 344.94659423828125 0.99062 59.706665 0.05613050000000005 0.0412848583 0.0014078870999999998 0.032436012 -0.0455369565 0.0279453094 -0.0096363213 -0.010562241299999999 -0.0255451166 -0.0193122599 0.0147107041 -0.0015934738 -0.044646205099999996 -0.0417415748 -0.0051500103000000005 0.048714014900000005 -0.0608023928 0.0336044704 0.015306336299999999 -0.054327247300000006 -0.233317 0.124756 0.296371 0.00124514 -0.00596509 0.00402953 -419.0224914550781 351.0936279296875 345.2769775390625 1.027432 61.925388 0.11839174999999998 0.0582157607 -0.012772509 0.0319409587 0.0138603634 0.007021778100000001 -0.030281242599999997 -0.011617181200000002 -0.023789615299999997 -0.030129748199999997 0.010243732 -0.0148066699 0.0162929617 -0.0420119037 -0.00441566 0.0480288462 -0.061030231 0.0351332152 0.0131564061 -0.053060623200000004 -0.233165 0.171355 0.306573 0.0008256249999999998 -0.00653892 0.00426496 -418.2469787597656 350.9664306640625 345.1755065917969 0.988829 59.598732 0.13786774999999998 0.0340829522 -0.023045924500000002 0.016516708 0.0460921739 -0.013266734799999999 0.0630742309 -0.0107308124 -0.032822774900000004 -0.0282865274 0.0044267445 -0.003509633 0.038559604 -0.042280734 -0.0036806797 0.0473282582 -0.061223237699999995 0.0366306304 0.0109895824 -0.0517012663 -0.229438 0.117038 0.291345 0.0020276 -0.00647699 0.00429297 -418.1385803222656 350.6510314941406 345.1667785644531 0.979582 59.041409 0.08105250000000001 -0.0035727810999999997 -0.0368758521 -0.017105248400000002 0.061312665499999995 0.0148426596 0.0529483066 -0.0048930208 -0.0240924404 -0.0108586098 0.0163893037 -0.0107602254 0.0562844112 -0.0425480561 -0.0029451740999999997 0.04661247599999999 -0.061381302699999994 0.0380953808 0.0088086474 -0.0502515524 -0.226519 0.163823 0.301648 0.00176881 -0.00632974 0.0042781 -419.322021484375 351.18682861328125 345.56072998046875 0.993489 59.879604 0.07241714999999997 -0.0093124935 -0.034069369 -0.048402084000000005 0.0446600806 0.0504304331 -0.0399630012 -0.0070483306 -0.0241159562 -0.0006526168 0.0196752687 -0.0154985517 0.022789805 -0.0428138604 -0.0022092484 0.0458817293 -0.0615043357 0.0395261602 0.0066164016 -0.048714014900000005 -0.22113 0.162831 0.299115 0.000946107 -0.00676698 0.00428822 -419.9136352539063 351.31787109375 345.41162109375 0.990019 59.670471 0.17392715 -0.0112979201 -0.0204441241 -0.0815903172 0.0011651585 0.050291491699999996 -0.0304086059 -0.013733061599999999 -0.0222996827 -0.011413415900000001 0.0159576776 -0.0213265696 -0.0204163805 -0.0430781374 -0.0014730073999999998 0.045136252800000005 -0.0615922667 0.0409216928 0.00441566 -0.0470913411 -0.228975 0.112168 0.28106 0.00220493 -0.00624096 0.00412578 -419.70892333984375 351.0538635253906 345.2958679199219 0.986719 59.471577 0.13666300000000003 -0.0009325541000000001 -0.0015074815 -0.0613914222 -0.0482198104 0.007936186500000001 0.0440378064 -0.0084014763 -0.0173103418 0.0097364924 0.0055182669999999994 -0.029953057400000004 -0.0616718932 -0.043340877699999995 -0.0007365563000000001 0.044376285700000004 -0.0616450454 0.042280734 0.0022092484 -0.0453863669 -0.22543 0.164314 0.31439 0.00135024 -0.00623906 0.00402953 -420.0083312988281 351.2267150878906 345.305908203125 0.9790430000000002 59.008919 0.103757 0.0268821644 0.0051051718 -0.0238664991 -0.0626708349 0.0191489225 0.0361193922 -0.015676752 -0.0207469631 -0.0124191631 0.0090439435 -0.0142302434 -0.0663185574 -0.043602072 -0.0 0.043602072 -0.0616626416 0.043602072 0.0 -0.043602072 -0.225589 0.14021800000000004 0.287831 0.00180337 -0.00666753 0.00420679 -418.4749450683594 351.2902526855469 345.12713623046875 0.9876760000000002 59.529247 0.1174825 0.0495170609 0.0026280007 0.0092119516 -0.0551579143 0.0407852449 0.027633895099999996 -0.0164207235 -0.035568266200000004 -0.0199298595 0.0125735665 -0.0104662604 -0.0560686604 -0.043861710899999996 0.0007365563000000001 0.0428138604 -0.0616450454 0.0448845285 -0.0022092484 -0.0417415748 -0.228376 0.1406 0.261194 0.00273639 -0.00608168 0.00397213 -419.9822998046875 351.1683349609375 345.458740234375 1.031149 62.149441 0.16495350000000003 0.0579179976 -0.0080757247 0.0346984465 -0.0120215375 0.0382898554 -0.0415236092 -0.010280294799999999 -0.0200808536 -0.0234720399 0.0019612633 0.0033117848999999998 -0.0041778690999999995 -0.0441197852 0.0014730073999999998 0.0420119037 -0.0615922667 0.0461269599 -0.00441566 -0.0398081268 -0.228359 0.175024 0.30103 0.00125473 -0.00613095 0.00425473 -419.8565673828125 351.4289245605469 345.59130859375 0.991043 59.732185 0.10123850000000001 0.056805089100000004 -0.0300167971 0.0308545096 0.0170885045 0.0063566079 0.0009942288 -0.017101996100000003 -0.0304237276 -0.034941276800000004 0.0045263993 0.0021113754999999997 0.023876295699999998 -0.044376285700000004 0.0022092484 0.0411964596 -0.0615043357 0.0473282582 -0.0066164016 -0.0378051071 -0.228218 0.162516 0.275531 0.00192908 -0.00666753 0.00430561 -418.25531005859375 351.2121887207031 345.2544860839844 0.969216 58.416641 0.10383699999999998 0.0407484892 -0.0358791065 0.0256597637 0.0482668486 0.0035554942 0.0539125237 -0.016464828799999998 -0.0299553754 -0.0416126972 0.0016582820999999999 0.0040142905 0.04312978940000001 -0.044631203099999996 0.0029451740999999997 0.0403677898 -0.061381302699999994 0.0484873523 -0.0088086474 -0.0357360162 -0.226484 0.13593400000000003 0.282081 0.00245506 -0.0060047 0.004115 -418.1759338378906 351.1607971191406 345.63568115234375 0.952877 57.431824 0.14715649999999997 0.028701872000000003 -0.0351265023 0.0010249777999999999 0.052648460599999995 0.0011090207 0.0446112924 -0.0098325896 -0.0227445068 -0.0231141064 0.009336607 -0.0060287843 0.0462650494 -0.0448845285 0.0036806797 0.0395261602 -0.061223237699999995 0.0496032084 -0.0109895824 -0.0336044704 -0.217435 0.169559 0.322811 0.00158545 -0.00627431 0.00425083 -419.2726135253906 351.5273742675781 346.0040588378906 0.939488 56.624874 0.10519800000000001 0.0182229409 -0.0338687055 -0.0108501648 0.0579869982 -0.0034503828000000004 0.0622162856 -0.0131962843 -0.0200389621 -0.0397974513 0.015384211200000001 -0.0016659834 0.0444134672 -0.045136252800000005 0.00441566 0.038671841299999996 -0.061030231 0.050674831600000005 -0.0131564061 -0.0314141948 -0.22445 0.13193 0.301197 0.00204656 -0.00644401 0.00410284 -420.8453674316406 351.4837951660156 346.1204833984375 0.9762900000000002 58.842968 0.05280699999999996 -0.006793975799999999 -0.0517230571 -0.0363095045 0.0583973322 0.0127460116 0.0222390729 -0.0130555854 -0.0226491013 -0.043096626500000006 0.0171374152 -0.0054351101 0.039511206800000004 -0.0453863669 0.0051500103000000005 0.0378051071 -0.0608023928 0.0517012663 -0.015306336299999999 -0.029169017400000004 -0.2254 0.134249 0.284992 0.00266992 -0.00647163 0.00411852 -423.1495666503906 351.3755187988281 346.8636779785156 0.999244 60.226471 0.16088785 0.00044232129999999996 -0.0407450782 -0.06797435660000001 0.020936735 0.0262064889 -0.0797020017 -0.0098704903 -0.012224295500000001 -0.0096882827 0.0265693889 -0.0287361013 0.0075319943999999995 -0.0456348621 0.0058836257 0.0369262359 -0.0605398531 0.0526815972 -0.0174366123 -0.0268728619 -0.215104 0.177588 0.3028 0.000951953 -0.00650979 0.00415129 -420.6086120605469 351.677001953125 346.87945556640625 0.994784 59.957638 0.10820585 -0.0056418377 -0.0292997571 -0.07544255230000001 -0.0263560917 0.0151979122 -0.0117712867 -0.015842258600000002 -0.013487238300000001 -0.0171775725 0.015481478600000001 -0.0192596417 -0.0532682268 -0.0458817293 0.0066164016 0.036035509900000005 -0.060242761799999996 0.05361495 -0.0195444986 -0.024529741400000003 -0.224103 0.127543 0.305769 0.00169338 -0.0065379 0.00430561 -417.4042053222656 345.8686828613281 339.31640625 1.815561 109.427567 1.4955414499999997 -0.11251557539999998 -0.0319293507 0.0384494658 -0.08004535509999999 0.0138116003 0.0154164325 0.0995342205 0.013283488000000001 -0.0146936464 0.0569853408 0.1381705775 -0.0880710751 -0.0461269599 0.0073482335 0.0351332152 -0.059911288300000004 0.0545004924 -0.0216272887 -0.0221437508 -0.762541 0.0473839 0.608691 -0.000616837 0.00182493 0.00511301 -401.0535888671875 334.28424072265625 328.3331298828125 2.575937 155.256927 2.88368305 -0.17067805 -0.0718612143 0.1256120224 -0.08663171630000001 -0.045284629800000004 0.1150823816 0.28378178579999996 0.0850674557 -0.1532921886 -0.047339258200000005 0.17780082649999998 -0.1862327669 -0.046370545 0.0080790168 0.0342196412 -0.059545621900000005 0.0553374348 -0.0236823082 -0.0197190601 -0.905875 -0.370703 1.10652 -0.0302639 0.00415559 0.00962395 -425.2228088378906 355.01593017578125 350.12860107421875 2.592037 156.227341 2.73717 -0.0631876168 -0.0367112126 0.0375583492 -0.08489829550000001 -0.1203590783 -0.030600706600000003 0.0200725275 0.1991905382 -0.0259916984 0.0187745629 0.0290272092 -0.048963395 -0.04661247599999999 0.0088086474 0.0332950814 -0.059145971299999996 0.0561250309 -0.025706918199999998 -0.0172599069 -0.427198 -0.113192 0.719928 -0.0111408 -0.00221785 0.00283269 -418.3553466796875 352.34033203125 346.60186767578125 1.045631 63.022274 0.28534877 -0.0573264199 -0.0166716833 0.048244563399999996 -0.0617467501 -0.11541549970000001 0.0002953114 0.04103142 0.1445303319 -0.0035610747 0.0153524409 -0.006951460600000001 -0.009903948499999999 -0.0468527442 0.0095370211 0.0323598325 -0.0587125645 0.0568625783 -0.027698518999999998 -0.0147705889 -0.417668 0.00112527 0.677739 -0.00938627 -0.00263223 0.00261535 -423.639892578125 351.9698791503906 346.49847412109375 1.013276 61.072227 0.34659593000000005 -0.042291536399999996 -0.0134743655 0.0470948822 -0.049094894800000004 -0.0801538021 -0.088309666 0.0279944798 0.1099328259 0.0166073222 0.0181485594 0.0087418062 0.0017438274 -0.0470913411 0.010264034 0.0314141948 -0.058245649000000004 0.0575494194 -0.0296545534 -0.012255456699999999 -0.360807 0.0320167 0.657141 -0.00669935 -0.00403342 0.00329215 -419.926513671875 351.51007080078125 345.4720458984375 0.915439 55.175354 0.16992030000000002 -0.0424826175 -0.001135014 0.0740451466 -0.0415815099 -0.0655700278 -0.0848999075 0.0312413879 0.09372581449999999 0.014617131200000001 0.011020733500000001 0.0119122864 0.0307375119 -0.0473282582 0.0109895824 0.0304584719 -0.0577454912 0.058184941500000004 -0.0315725097 -0.009718906 -0.34151 0.061943 0.678027 -0.00511095 -0.00376925 0.0031485 -422.8182678222656 351.62860107421875 345.5771484375 0.942178 56.786961 0.13373820000000008 -0.030593648199999997 -0.01709482 0.0468818349 0.0027989356 -0.0854532959 -0.0417944135 0.0219287457 0.0898018914 0.0098331649 0.0099747337 0.0023751913 0.0547919597 -0.047563487 0.011713562700000001 0.0294929706 -0.0572123765 0.058768578200000005 -0.033449925 -0.007165369699999999 -0.334897 0.0999337 0.624597 -0.00492425 -0.00420071 0.00324443 -420.1407775878906 351.92596435546875 345.08807373046875 0.933395 56.257614 0.14430920000000003 -0.046250888399999995 -0.0104052451 0.0418692257 0.027629508900000002 -0.0698781673 0.029967650699999997 0.0155130674 0.0766410858 0.0177124903 0.006694430899999999 -0.0023744721 0.0651697684 -0.047797019100000004 0.012435871599999999 0.0285180009 -0.056646609199999996 0.0592998088 -0.0352843888 -0.0045993107 -0.324179 0.079351 0.642793 -0.0033767 -0.00394794 0.0031485 -419.969482421875 351.41015625 344.58746337890625 0.937462 56.502728 0.05003750000000005 -0.0597244308 -0.0174657837 0.0205170324 0.0269800332 -0.0288500662 -0.0334259043 0.0218315533 0.0753971016 0.0236579162 0.014848971499999999 -0.0007724815 0.049795287199999996 -0.0480288462 0.0131564061 0.0275338758 -0.056048512300000006 0.0597781596 -0.037073545299999996 -0.0020252136 -0.321165 0.111542 0.64354 -0.0033315 -0.00379147 0.00322854 -419.63848876953125 351.3443298339844 344.4804992675781 0.9451250000000002 56.964588 0.09698099999999997 -0.0702521775 -0.008285513199999999 -0.0160535626 0.0122015653 -0.0204324544 -0.0839466698 0.024480403300000002 0.0758313641 0.0313017635 0.0126319972 -0.0156306957 0.027322829500000003 -0.0482589599 0.0138750634 0.0265409112 -0.055418427 0.0602032042 -0.038815097400000005 0.0005524229 -0.318907 0.123564 0.619648 -0.00372831 -0.0044908 0.0031485 -419.18048095703125 351.6879577636719 344.4288330078125 0.939796 56.643387 0.18094659999999999 -0.050443025 0.005534635600000001 -0.037074899700000004 -0.028419983 -0.042817195 -0.0182192523 0.011159026499999999 0.0684213087 0.027278775699999997 0.0095198262 -0.0216319788 -0.0044323109999999995 -0.0484873523 0.0145917409 0.0255394259 -0.0547567129 0.060574563399999996 -0.0405068086 0.0031290940000000002 -0.323167 0.07629289999999998 0.57046 -0.00252792 -0.00419752 0.00303762 -414.00384521484375 349.22418212890625 342.68914794921875 1.070049 64.494019 0.21908610000000006 -0.052708152 0.0079182766 0.006513110600000001 -0.0498609782 0.0098148278 0.046777630199999996 0.0403207359 0.020822224 0.0502541846 0.036897208 0.0047291051 -0.035526673700000004 -0.048714014900000005 0.015306336299999999 0.024529741400000003 -0.054063747800000006 0.0608919062 -0.0421465068 0.0057002965 -0.348077 0.1267 0.587486 -0.00220837 -0.00530706 0.00414339 -418.7090759277344 349.62359619140625 343.7303161621094 1.170467 70.546387 0.27178749999999996 -0.0023893981 -0.0012341646 0.0010100944 -0.0599368187 -0.042336403099999996 -0.0149318939 0.0170941302 0.0335885442 0.061626487 0.0642324026 -0.0651830978 -0.0364550176 -0.0489389399 0.0160187477 0.023512181899999998 -0.0533399272 0.061154949400000005 -0.0437320865 0.008261536600000001 -0.33583 0.120377 0.482186 -0.00366936 -0.00653068 0.00441713 -418.1610107421875 351.3200378417969 344.73492431640625 1.027613 61.936337 0.3126884999999999 -0.00497006 0.0126512642 0.0092579247 -0.048705720099999995 -0.0238414612 0.0185339692 0.0021065032 0.0396825623 0.0408272371 0.0154864176 -0.026147606299999997 -0.0342736809 -0.0491621191 0.0167288735 0.022487074 -0.052585664000000004 0.0613634587 -0.0452615117 0.010808338300000001 -0.267649 0.07413999999999998 0.510834 -0.00239147 -0.00558849 0.00324476 -417.489990234375 351.2864990234375 345.44915771484375 0.958321 57.759937 0.2731505 -0.005074735 0.0048890231 0.0100420673 -0.0439744171 -0.0401060691 0.0436617433 0.0065404204 0.0432167931 0.0451264027 0.0184506455 -0.0308237434 -0.0192929216 -0.0493835445 0.0174366123 0.0214547469 -0.0518013888 0.061517248 -0.046732818499999995 0.0133362505 -0.228217 0.12664 0.503393 -0.0033686 -0.007427279999999999 0.00390439 -420.375 351.4151611328125 345.7641296386719 0.941575 56.750648 0.13407300000000003 0.0029069583 0.0006707944 0.01951861 -0.0424534078 -0.043066507999999996 -0.003712255 0.00037523389999999997 0.0292738718 0.030870213799999997 0.0151870187 -0.0236009473 -0.0233004292 -0.0496032084 0.0181418631 0.020415532 -0.0509875493 0.061616180199999995 -0.048144117699999996 0.0158408552 -0.229209 0.110662 0.509117 -0.00173758 -0.00692563 0.00380948 -421.5080261230469 351.2952575683594 345.37066650390625 0.944269 56.913033 0.10424134999999994 0.006769233100000001 0.0107000132 0.0462590807 -0.036804540499999996 -0.0186319823 -0.0682190437 -0.0005088801999999999 0.016836226200000002 0.0270132743 0.0115917556 -0.0050701923 -0.0025186732 -0.0498211028 0.0188445253 0.0193697628 -0.0501446098 0.061660167 -0.049493597199999996 0.0183177752 -0.229202 0.132987 0.531374 -0.0007804529999999999 -0.006979 0.00399203 -422.3573303222656 351.1561584472656 345.1759033203125 0.9709120000000002 58.518856 0.08516925000000002 0.011782864399999999 -0.0104401049 0.0295348583 0.0134491946 -0.0446254108 -0.035952914100000004 -0.0047222736 0.0117259652 0.011107481 0.0125608466 -0.0122373499 0.029286481200000002 -0.050037220099999995 0.0195444986 0.0183177752 -0.049273051500000005 0.061649169299999994 -0.050779524000000006 0.0207626817 -0.237238 0.153295 0.494315 -0.000455538 -0.00701308 0.00402836 -418.3320007324219 350.81591796875 344.63946533203125 0.948377 57.160614 0.07644943699999998 -0.0015822092999999999 -0.0080473671 0.0187765725 0.0407474619 -0.0472832754 0.0504368258 -0.0013037927 0.0024553631 0.0043466603 0.006777021899999999 -0.0062910506000000005 0.049837899000000005 -0.0502515524 0.0202416832 0.0172599069 -0.048373371799999995 0.061583196900000005 -0.0520002471 0.023171301800000002 -0.234322 0.12175 0.501665 -9.44926e-06 -0.00684928 0.00394548 -419.0291442871094 350.73736572265625 344.4247131347656 0.950617 57.295597 0.09088003700000002 -0.027714285 -0.024207819300000002 -0.0129071285 0.055317900700000006 -0.0104183468 0.0112526458 0.0035382645 0.0069669703 0.0124798852 0.012185829799999999 -0.021004904799999998 0.0581835422 -0.050464092099999996 0.020935979599999998 0.0161964974 -0.0474460842 0.06146230849999999 -0.053154198799999997 0.0255394259 -0.218651 0.152611 0.492772 -0.00021678 -0.00645179 0.00404976 -419.9078369140625 350.88800048828125 344.8514709472656 0.969725 58.447292 0.09394499999999993 -0.025154659500000003 -0.017485806899999998 -0.0391330298 0.024779842200000003 0.0154465992 -0.0712701306 0.0027627305 0.012742018700000001 0.023055723900000002 0.0103685167 -0.0312163181 0.0202162335 -0.050674831600000005 0.0216272887 0.0151278882 -0.046491717800000006 0.0612866121 -0.054239897599999996 0.0278629153 -0.230683 0.183195 0.484036 -0.00089585 -0.00658135 0.00409299 -418.627685546875 350.71728515625 344.50482177734375 0.961652 57.960705 0.16299870000000002 -0.0337426801 0.0005515402 -0.0530740027 -0.0105213819 0.0256303583 -0.0109153564 0.0006183795999999999 0.0035179946 0.033717347200000004 0.0192872366 -0.0312738584 -0.0221996944 -0.0508837635 0.022315511899999998 0.0140544224 -0.0455108174 0.0610562642 -0.0552559492 0.0301377094 -0.230936 0.123349 0.478599 0.000327734 -0.00616933 0.00377934 -419.7203674316406 350.65936279296875 344.578369140625 0.952331 57.398903 0.07777364999999999 -0.0186221546 0.0160508994 -0.053826232800000005 -0.056643099 -0.0029074471 0.0379722769 -0.000575173 0.0015488459 0.0431091012 0.0088690742 -0.025336368199999997 -0.0631064853 -0.0510908803 0.023000551 0.0129764445 -0.0445039428 0.0607714702 -0.056201049100000004 0.0323598325 -0.231985 0.148855 0.466632 0.000442607 -0.00556147 0.00371704 -418.13525390625 350.9497985839844 344.756103515625 0.937633 56.513058 0.12380815000000002 0.00036187510000000003 0.0187234394 -0.0083638586 -0.0507183005 -0.0059237790000000005 0.0458637684 0.0010292075999999999 0.0078310507 0.031556403399999995 -0.0012147421 -0.0161701065 -0.045829792599999995 -0.0512961746 0.0236823082 0.0118943007 -0.0434716687 0.0604324842 -0.0570739836 0.0345254011 -0.236237 0.177375 0.479539 -0.000426376 -0.00616443 0.00380768 -418.9403076171875 351.10467529296875 345.0097961425781 0.938392 56.558765 0.10957804999999998 0.0143785644 0.0216160915 0.0199830614 -0.0524627204 -0.0049021993 0.0007415027 -0.0026392271 -0.0009759616999999999 0.024780247400000004 0.0096317733 -0.0023311529000000003 -0.0352944101 -0.05149963900000001 0.024360686200000002 0.010808338300000001 -0.0424145842 0.0600396084 -0.0578736318 0.0366306304 -0.23638 0.149087 0.47627 0.000798465 -0.00592235 0.00371704 -419.78643798828125 350.8863830566406 345.4639892578125 1.001771 60.378754 0.05696884999999996 0.0208170322 0.0168423264 0.0371791512 -0.0323974846 0.0082724806 -0.0662129578 -0.0008615541000000001 2.0941300000000002e-05 0.018568343799999998 -0.0022218392000000003 -0.0055745462 -0.0083415891 -0.0517012663 0.0250355883 0.009718906 -0.0413332925 0.059593193200000005 -0.058598967 0.038671841299999996 -0.22889 0.168904 0.477898 0.000267158 -0.00589298 0.00371704 -420.4014587402344 350.7684631347656 345.54400634765625 0.971542 58.556782 0.05882003000000001 0.0277686364 -0.0062234356000000005 0.0302384151 0.0190729319 -0.0204543746 -0.0262468795 -0.0012848293 -0.0034238502 6.77657e-05 0.0058437004 -0.0060586560999999995 0.030137306099999997 -0.0519010494 0.025706918199999998 0.0086263535 -0.0402284109 0.0590936366 -0.059249057800000005 0.0406454662 -0.241789 0.175635 0.46773 -9.46626e-05 -0.0061116 0.00371704 -418.5499267578125 351.0373840332031 345.298583984375 0.944894 56.950672 0.10593753000000004 0.0147674458 -0.012813442 0.0227944074 0.043499028099999996 -0.029141160699999998 0.0392172895 -0.0031365529 -0.0040708296 -0.0098617518 -0.005541515 -0.0017562951999999998 0.0371923318 -0.052098980999999996 0.02637458 0.0075310317 -0.0391005699 0.0585413841 -0.0598230695 0.0425480561 -0.242714 0.13504 0.473003 0.000674008 -0.00575616 0.00365826 -418.80108642578125 350.8735656738281 345.5841369628906 0.947787 57.125031 0.1226045 -0.0035168126 -0.013847573 0.0031612231 0.0504453708 -0.0268678526 0.0238292827 0.001502356 0.0023336695 0.0022684587 -0.009782470500000001 -0.006127095999999999 0.0519638242 -0.052295054199999996 0.0270384785 0.0064332921 -0.0379504132 0.0579369282 -0.060320264900000004 0.044376285700000004 -0.24345 0.18418 0.479026 -0.000250792 -0.00610669 0.00371704 -416.5093078613281 350.900390625 345.2369689941406 0.919721 55.43346 0.09366540000000002 -0.0206116948 -0.012135233300000001 -0.0004889139 0.046414383200000006 -0.0143984892 0.0525787595 -0.0025428385999999997 -0.0029410406 0.007639293 0.0072782911 -0.0071778373999999995 0.047803121100000005 -0.05248926190000001 0.027698518999999998 0.005333487099999999 -0.0367785971 0.0572808079 -0.0607400057 0.0461269599 -0.235468 0.151361 0.47156 0.000657176 -0.00610669 0.00371704 -420.34857177734375 351.2936096191406 345.578857421875 0.939917 56.650684 0.04103350000000004 -0.023809936099999998 -0.0223178375 -0.026657696 0.0381799834 0.0231826352 -0.0173189653 -0.0032868319 0.003843613 0.0039814033 0.0169849896 -0.0144150316 0.045490514800000006 -0.0526815972 0.0283546073 0.0042319699 -0.0355857906 0.0565736083 -0.0610817528 0.047797019100000004 -0.232791 0.156093 0.475802 0.000515596 -0.00572694 0.00365072 -421.6963806152344 351.34075927734375 346.02294921875 0.962 57.981709 0.14948014999999998 -0.014243899499999999 -0.0208441785 -0.037484076 0.0150072219 0.017831583300000002 -0.07287896099999999 -0.0068843119 0.0064787648 0.0217066118 -0.0037820347 -0.0192081433 0.0202706589 -0.052872053200000005 0.0290066498 0.0031290940000000002 -0.0343726744 0.05581596 -0.0613450675 0.0493835445 -0.235539 0.193061 0.452102 -0.000595207 -0.00610669 0.00388145 -420.2373352050781 351.41107177734375 345.3829345703125 0.938735 56.579456 0.14608935 -0.029496871400000003 -0.0022655346 -0.050290697599999996 -0.0046379595 0.026824814300000003 -0.0440001675 -0.0072219632 -0.002942738 0.0118555014 0.0035415177000000003 -0.0127555841 -0.0113043046 -0.053060623200000004 0.0296545534 0.0020252136 -0.0331399408 0.055008538600000004 -0.0615296116 0.0508837635 -0.234946 0.145817 0.451785 0.00107338 -0.00603379 0.00366423 -420.4018249511719 350.7237548828125 345.14306640625 0.945062 56.960773 0.1317968 -0.0248406847 0.007390821 -0.058046083600000006 -0.0271540311 -0.0047840873999999995 -0.009177106800000001 -0.0041129113 0.0036086683000000003 0.030896833199999998 7.32259e-05 -0.0313543862 -0.0379862376 -0.0532473004 0.030298225699999997 0.000920683 -0.0318882933 0.0541520642 -0.0616351482 0.052295054199999996 -0.233642 0.188947 0.48118 0.000292084 -0.00615622 0.00391986 -420.4996948242188 351.0235290527344 345.00054931640625 0.936354 56.435978 0.10370185 -0.0099958689 0.0101450884 -0.04644595 -0.0355689447 0.017335723600000002 0.0080697349 -0.0071041714 -0.0038586634 0.0083178916 -0.001035605 -0.0045829191 -0.0460206149 -0.053432078200000004 0.0309375749 -0.0001841432 -0.030618446400000002 0.0532473004 -0.0616615418 0.05361495 -0.233016 0.157022 0.457933 0.000927371 -0.00627619 0.00371704 -418.3293151855469 350.9952392578125 344.46368408203125 0.929517 56.023869 0.0657309500000001 -0.0085167705 0.0185832579 -0.0341031294 -0.046043016900000004 0.0022058807999999997 0.061454807699999996 -0.0038451576000000003 -0.0046459831 0.0210879889 -0.0107168249 -0.010137572099999999 -0.062043925300000004 -0.05361495 0.0315725097 -0.0012889102 -0.0293311248 0.052295054199999996 -0.0616087584 0.0548411441 -0.233521 0.16364 0.466021 0.00128669 -0.00562511 0.00371704 -418.609375 351.0707092285156 344.86260986328125 0.923501 55.661251 0.14297440000000003 -0.0027537563 0.0239166568 -0.0241012665 -0.046316755099999996 -0.0087363102 0.04550461150000001 -0.0044019625 0.0013603428 0.0237606227 -0.0079498313 -0.0240934769 -0.051645349800000004 -0.0537959092 0.0322029395 -0.0023932635000000002 -0.0280270631 0.0512961746 -0.0614768659 0.0559714938 -0.234697 0.201324 0.465396 -0.000165108 -0.00601961 0.00394053 -420.8558654785156 350.8556823730469 344.8001708984375 0.946771 57.06382 0.2094704 0.0142182691 0.0242970813 -0.0077691094 -0.054337204699999996 0.0116205875 0.0276887015 -0.009252251 -0.0108242174 0.0149181212 -0.0095388171 0.0059968905 -0.04910397440000001 -0.05397494940000001 0.032828774399999996 -0.0034968484000000005 -0.0267070056 0.0502515524 -0.061266033600000006 0.0570040233 -0.241815 0.135914 0.444418 0.00146751 -0.00563199 0.00364148 -421.1351623535156 351.05596923828125 344.61041259765625 0.964176 58.112869 0.099838 0.0238255938 0.024206378799999997 0.016603949 -0.0455188128 0.017970810900000002 -0.025425427400000002 -0.0072379811 -0.0118383954 0.0090632207 -0.0089094013 0.012243144499999999 -0.0359534059 -0.0541520642 0.033449925 -0.0045993107 -0.0253717058 0.0491621191 -0.060976532199999996 0.0579369282 -0.235632 0.177827 0.45725 0.00119967 -0.00533627 0.00342684 -420.9743041992188 350.8965759277344 344.7628173828125 0.97974 59.050896 0.11035405 0.0254472446 0.0181669663 0.030478510299999997 -0.0098339056 0.0188232229 -0.0874599695 -0.0060933977 -0.009365655799999999 0.012551516100000002 -0.010360599100000001 0.0021919187 0.006212776 -0.054327247300000006 0.034066302799999996 -0.0057002965 -0.0240219257 0.0480288462 -0.0606087335 0.058768578200000005 -0.232209 0.205919 0.460147 0.000380749 -0.00566583 0.0037972 -419.68548583984375 350.9368591308594 344.4881591796875 0.962718 58.024979 0.15981954999999992 0.0434572326 0.0134759953 0.037873003599999996 0.0109859485 0.0180881336 -0.039286185099999996 -0.008815724799999999 -0.021841643100000002 -0.014021918700000002 -0.012062503600000002 0.0138476726 0.0177594111 -0.0545004924 0.0346778198 -0.006799452199999999 -0.022658435600000002 0.0468527442 -0.060163109699999995 0.0594975196 -0.236723 0.148684 0.436459 0.00175251 -0.00570949 0.00372497 -418.70587158203125 350.9047546386719 344.5514831542969 1.049567 63.259548 0.16711535 0.023814825 0.0051243257 0.0191002847 0.0457761137 -0.0121058055 0.026883402200000003 0.000464457 -0.0161672608 -0.0308687895 -0.029595094500000002 0.0005034041000000001 0.034157695099999996 -0.0546717934 0.0352843888 -0.007896425 -0.0212820138 0.0456348621 -0.059640233 0.0601224786 -0.243096 0.208144 0.422123 0.000486943 -0.0054139 0.0035472 -418.9501647949219 350.9698181152344 344.9352722167969 1.0275 61.929497 0.10446839999999996 0.013359122900000001 -0.0084664833 0.0142170582 0.053813224400000005 -0.0108142877 0.0376673987 -0.0028023717 -0.0098832801 -0.0086836869 -0.0053336152 -0.00037888669999999996 0.0504345777 -0.0548411441 0.0358859231 -0.0089908627 -0.0198934458 0.044376285700000004 -0.0590407749 0.060642363 -0.231841 0.230889 0.426822 -0.000108395 -0.00578491 0.00389624 -418.6065673828125 350.62451171875 344.8167419433594 0.950138 57.26672 0.19757625000000004 0.0014676821 0.00033405580000000004 0.0037159314 0.052614851 -0.0072145574 0.0430347696 -0.0055474726 -0.0145364942 -0.0053052224 -0.007678050600000001 0.008603279 0.0496174681 -0.055008538600000004 0.036482337000000004 -0.010082414100000001 -0.018493524 0.0430781374 -0.0583655051 0.0610562642 -0.226127 0.14031 0.444392 0.00142433 -0.00574241 0.0037972 -419.5608825683594 350.93426513671875 345.4009094238281 0.928062 55.936207 0.1280148 0.006617082 0.0095160877 0.006912648299999999 0.0469731565 -0.0033011570000000003 0.0055851971 -0.0061310895999999995 -0.006444045600000001 0.0078789092 -0.0171830522 0.0112116717 0.045875762 -0.0551739708 0.037073545299999996 -0.011170728500000001 -0.0170830476 0.0417415748 -0.057615290599999994 0.0613634587 -0.233619 0.168842 0.458099 0.000238534 -0.00606261 0.00373752 -421.56353759765625 351.1623229980469 345.9136047363281 0.929007 55.993153 0.05451605000000001 0.0062619 0.0038774378000000003 0.021524089500000003 0.051602081200000004 -0.0259531202 0.0120703967 -0.011335819099999998 -0.0049119498999999995 0.010206333100000001 -0.0140928123 0.0162336436 0.043055429000000006 -0.0553374348 0.0376594638 -0.012255456699999999 -0.0156628214 0.0403677898 -0.056791094900000005 0.061563409699999995 -0.233186 0.167694 0.466401 0.000513275 -0.00662085 0.0037972 -418.6884460449219 351.4188537597656 345.4598388671875 0.9300020000000002 56.053116 0.09262725000000004 -0.0008469192999999999 0.0012237684 0.017422336200000003 0.0576475607 -0.015412991000000001 0.043030307000000004 -0.0102514627 -0.0097602064 0.0044168268 -0.022661770699999997 0.0085294904 0.0686948294 -0.0554989249 0.038240008799999996 -0.0133362505 -0.014233656 0.0389580073 -0.055893976100000006 0.0616557679 -0.228782 0.140409 0.466145 0.0013179 -0.00621183 0.0037972 -420.4953918457031 351.1655578613281 345.89141845703125 0.952693 57.420715 0.19139110000000006 -0.0016481431 -0.0012536873 -0.0077198943 0.057626763 -0.0087953567 0.003950844199999999 -0.007971773 -0.002523514 0.005435338499999999 -0.0141757374 -0.0089111857 0.061926227 -0.055658435199999995 0.038815097400000005 -0.0144127627 -0.012796367099999999 0.0375134847 -0.0549250863 0.0616403716 -0.228748 0.202497 0.417083 -0.000163272 -0.0062817 0.0038503 -418.4041442871094 351.3333435058594 345.490966796875 0.941253 56.731255 0.19445760000000006 -0.036773567 0.0092110578 -0.0151368622 0.0560736692 0.0021053977 0.0256899487 -0.0085122316 -0.0103731562 0.0128539192 -0.013549044599999999 0.012443520500000001 0.048915449400000005 -0.05581596 0.039384647599999996 -0.0154846479 -0.011351775 0.036035509900000005 -0.053885669500000004 0.061517248 -0.22148 0.143168 0.465195 0.00123664 -0.00626739 0.00366955 -422.4244384765625 350.6268310546875 345.5655212402344 0.993748 59.895184 0.09019299999999998 -0.0231102212 0.0035809207000000003 -0.0452504986 0.026553689900000003 0.0415271452 -0.0957326783 -0.0017414879999999998 -0.012663555600000001 0.012218587 -0.0087979731 -0.0009847838 0.0182880853 -0.0559714938 0.0399485782 -0.0165515619 -0.0099007042 0.0345254011 -0.0527770605 0.0612866121 -0.222802 0.184889 0.485259 0.0008659199999999998 -0.00622404 0.0037972 -421.0320739746094 351.03155517578125 345.2795715332031 0.973408 58.669277 0.05855755000000003 -0.0246530772 0.022827351800000003 -0.048461986799999995 -0.0090033544 0.0245669865 -0.0282077367 -0.0072880161 -0.014112999499999999 0.023742194700000004 -0.0178799526 -0.0017767958 -0.025849704100000002 -0.0561250309 0.0405068086 -0.0176131622 -0.0084439827 0.0329845047 -0.0516006827 0.060948867000000004 -0.217076 0.186647 0.460301 0.000927601 -0.00638611 0.00409576 -419.76055908203125 350.7131042480469 344.8580627441406 0.954479 57.528362 0.11808145000000007 -0.0107272027 0.0428483884 -0.045481765300000004 -0.0395386344 0.0123920571 0.044547691699999996 -0.0067430624 -0.0289708958 0.0312878724 -0.0322022835 0.0071923484 -0.0563508233 -0.05627656599999999 0.041059259300000005 -0.0186691079 -0.0069824421 0.0314141948 -0.0503580468 0.060504603 -0.228744 0.155322 0.45063 0.00187688 -0.00620342 0.00391938 -418.66314697265625 350.2662658691406 344.6717224121094 0.936714 56.457645 0.10684300000000004 0.0011296417999999999 0.046707636799999994 -0.0062487343 -0.0370799233 0.0205338354 0.0442839259 -0.0048249126 -0.023222726699999998 0.0339542146 -0.025052172 -0.0066333016000000005 -0.046475883499999995 -0.056426093600000005 0.041605851299999996 -0.0197190601 -0.0055169164 0.0298158718 -0.0490507482 0.059954596500000006 -0.22393 0.183965 0.471994 0.00118574 -0.00636046 0.00411164 -420.3843078613281 350.7799072265625 344.6791687011719 0.990563 59.703217 0.037690000000000015 0.0213719622 0.0439354704 0.0208558883 -0.03019639 0.0298511021 -0.0201951203 -0.0089042551 -0.0210983904 0.0219319308 -0.015570004699999999 0.0177801638 -0.030808651800000003 -0.0565736083 0.0421465068 -0.0207626817 -0.0040482420000000005 0.0281909609 -0.0476804656 0.0592998088 -0.222283 0.188286 0.450505 0.00120411 -0.00648859 0.00405348 -417.90380859375 350.1667175292969 344.4388732910156 0.94024 56.670155 0.10437000000000003 0.0215020898 0.05221095059999999 0.0323387697 -0.0092074466 0.033127428 -0.0165281522 -0.0029364513 -0.0301447474 0.0155110163 -0.0291634435 0.0206836127 -0.004924322 -0.056719105 0.042681148499999995 -0.0217996377 -0.0025772572 0.0265409112 -0.0462489587 0.0585413841 -0.210677 0.163251 0.482466 0.00143984 -0.00602168 0.0040662 -418.4532775878906 350.86175537109375 345.35711669921875 0.9386310000000002 56.573166 0.15345229999999999 0.0222181219 0.0496605008 0.0384308481 0.0015176109 0.0261619014 -0.0261713166 -0.0065568624 -0.0189467135 0.0224226032 -0.021934032599999997 0.022899531600000002 0.0075194284 -0.0568625783 0.04320970019999999 -0.0228295951 -0.0011048015 0.0248671939 -0.0447580654 0.057680648099999995 -0.201905 0.197146 0.475432 0.000317284 -0.00668689 0.00435346 -419.7340393066406 351.2686462402344 345.7000732421875 0.951528 57.350525 0.08760885000000003 0.0298966145 0.0363880967 0.0401888235 0.0360609977 0.0011340438 -0.0405455731 -0.0071559843 -0.0112678654 0.001278756 -0.0293992369 0.0304581556 0.0380530225 -0.0570040233 0.0437320865 -0.0238522233 0.0003682847 0.023171301800000002 -0.04320970019999999 0.056719105 -0.213971 0.160457 0.45798 0.000640961 -0.00671358 0.00427579 -419.6258239746094 350.8326110839844 345.3352966308594 1.32808 80.046074 1.10770195 0.0466338755 -0.0045629455 0.0452108857 0.028510273 0.058606711900000004 0.0045383437 -0.0083821446 -0.054121162800000004 -0.1264120008 -0.0656220055 0.06444425940000001 0.0047237487 -0.057143434800000004 0.0442482328 -0.0248671939 0.0018411607000000001 0.0214547469 -0.041605851299999996 0.055658435199999995 -0.387708 0.0698633 0.0623497 0.007730919999999999 -0.00513288 0.00455995 -421.9286804199219 351.986572265625 346.7840881347656 1.448526 87.305611 0.94662975 0.0368767433 -0.015569886100000001 0.0311879778 0.028801254199999998 0.0274019442 -0.027637689700000002 -0.016795151100000003 -0.0071492946 -0.0642753924 -0.0170580415 0.0252961734 0.0374730659 -0.0572808079 0.0447580654 -0.025874181200000002 0.003312986 0.0197190601 -0.0399485782 0.0545004924 -0.245279 0.221022 0.252796 0.000195535 -0.00358566 0.00439064 -420.03265380859375 352.2621765136719 346.7864074707031 1.111261 66.977974 0.23146905 0.0191965423 0.0097517223 -0.0021952819 0.0209932689 0.0169289039 0.0187509875 -0.015195520300000001 -0.0051002724 -0.0246458913 -0.0109813553 0.023263653500000002 -0.0015841612 -0.057416137699999995 0.0452615117 -0.0268728619 0.0047829204 0.0179657891 -0.038240008799999996 0.0532473004 -0.223133 0.198169 0.325596 -0.000575956 -0.00494457 0.00424764 -422.753662109375 352.4790954589844 347.1820373535156 1.009739 60.85902 0.2499303 0.026419751499999998 0.025557087200000002 -0.006157446600000001 -0.0090072802 -0.006250615 0.029137866800000002 -0.02606233 -0.013988417 -0.0151362763 -0.020045925 0.035447221099999995 -0.0202722798 -0.0575494194 0.0457584997 -0.0278629153 0.0062501251 0.0161964974 -0.036482337000000004 0.0519010494 -0.212825 0.115584 0.363372 0.00106699 -0.00565255 0.00421334 -419.8230285644531 351.4459228515625 345.6559143066406 1.001595 60.368179 0.10223 0.0289880059 0.0390068096 0.027997977900000002 -0.0199245626 0.0186179868 -0.0107020125 -0.017171006699999998 -0.030160222599999998 -0.014044333 -0.043868965999999995 0.0356601789 -0.0241504561 -0.057680648099999995 0.0462489587 -0.028844023599999997 0.0077137627000000005 0.0144127627 -0.0346778198 0.050464092099999996 -0.197908 0.153006 0.386041 0.00143232 -0.00561038 0.00435028 -423.03448486328125 351.24542236328125 345.2484436035156 1.000253 60.287277 0.15513215000000002 0.0367041818 0.029105649900000002 0.0245257011 0.0230138311 0.0080292213 -0.0420305281 -0.019953838 -0.0336568406 -0.0120179757 -0.0314411617 0.0310006404 0.0185384528 -0.057809819299999995 0.046732818499999995 -0.0298158718 0.0091729979 0.012616175600000001 -0.032828774399999996 0.0489389399 -0.194464 0.195997 0.38152 0.000452407 -0.00630131 0.00476296 -419.1816711425781 351.166259765625 344.3555908203125 0.995545 60.003525 0.19836814999999997 0.027648154900000003 0.0301338907 0.0249665414 0.048947349800000005 0.0191485594 0.017560491299999998 -0.0165534844 -0.046195669 -0.0132254031 -0.0359686566 0.0389417911 0.021391857200000003 -0.0579369282 0.04721001019999999 -0.0307781479 0.010626997800000001 0.010808338300000001 -0.0309375749 0.0473282582 -0.200427 0.137941 0.392725 0.00239329 -0.00603125 0.00451102 -417.5675354003906 351.25360107421875 344.0668029785156 0.956024 57.621502 0.11819599999999998 0.0093625379 0.024069096499999998 0.013754298 0.07187192790000001 0.025998836299999998 0.0738661556 -0.011686357 -0.0379132279 -0.0075740437 -0.0445936254 0.0341324834 0.055332433099999995 -0.0580619705 0.0476804656 -0.031730543 0.0120749325 0.0089908627 -0.0290066498 0.0456348621 -0.195696 0.169642 0.416252 0.00162573 -0.00572778 0.00460473 -419.3764953613281 351.1673583984375 344.31573486328125 0.969483 58.432682 0.14335944999999997 -0.0028825808000000003 0.019986181999999998 -0.0173452084 0.077460527 0.0425219647 0.0370680435 -0.0125187718 -0.0356233431 0.0038834740999999996 -0.0055530331 0.0227306586 0.052377327800000005 -0.058184941500000004 0.048144117699999996 -0.0326727513 0.013515975800000002 0.007165369699999999 -0.0270384785 0.043861710899999996 -0.197584 0.204598 0.370641 0.000908461 -0.0061093 0.00448543 -418.8160705566406 350.8041687011719 343.9140319824219 0.96527 58.178772 0.16764395000000007 -0.017383794299999998 0.0273567436 -0.044172028700000004 0.0723362385 0.0728134148 -0.0077585569 -0.0084262882 -0.0433164951 0.0006381074 -0.0115533248 0.0235729796 0.0333206038 -0.058305837 0.0486009003 -0.0336044704 0.0149493052 0.005333487099999999 -0.0250355883 0.0420119037 -0.186189 0.137163 0.377149 0.00238318 -0.00625496 0.00445969 -418.76995849609375 350.42877197265625 344.1031494140625 0.982813 59.236111 0.128046 -0.0275793277 0.048098307 -0.0674074776 0.0382466502 0.0678989285 -0.049976339800000005 -0.0014587448000000002 -0.0364533561 0.025377378199999998 -0.0345086177 0.0056784812 -0.0030724006 -0.058424652599999995 0.0490507482 -0.0345254011 0.0163741027 0.0034968484000000005 -0.023000551 0.0400886733 -0.184043 0.176029 0.419343 0.00178977 -0.00603658 0.0045447 -418.3017272949219 350.4978332519531 344.22613525390625 0.9847570000000002 59.353317 0.08960550000000009 -0.0213826042 0.060300545700000006 -0.066825354 0.0029250694 0.0547781526 0.0170630264 -0.005137094 -0.0401032998 0.0243981892 -0.0371756133 0.0155075424 -0.0423874614 -0.0585413841 0.049493597199999996 -0.0354352477 0.017789555 0.0016570915 -0.020935979599999998 0.0380953808 -0.183926 0.198566 0.387664 0.00174422 -0.00634493 0.00489625 -418.2889404296875 350.47552490234375 344.2760009765625 0.9813130000000002 59.145706 0.12374200000000002 -0.0144046673 0.0696317737 -0.051166482199999995 -0.0210428538 0.0379278269 0.056864703899999994 -0.0071204068 -0.0450028846 0.0276242041 -0.0469800857 -0.0032818954999999997 -0.045813282999999996 -0.058656027300000003 0.0499293841 -0.0363337182 0.019194854299999998 -0.0001841432 -0.0188445253 0.036035509900000005 -0.202301 0.186852 0.396058 0.00127278 -0.00587845 0.00412899 -418.7112731933594 350.6602478027344 344.6427307128906 0.9646960000000002 58.14418 0.09461300000000009 0.0105099789 0.07063700889999999 -0.02338341 -0.027180998199999997 0.037205915299999996 0.06802220769999999 -0.0097115083 -0.0442782503 0.0325937378 -0.0522096879 0.0137305242 -0.0395487712 -0.058768578200000005 0.0503580468 -0.0372205242 0.020589198700000002 -0.0020252136 -0.0167288735 0.0339126607 -0.182861 0.199 0.387547 0.00170721 -0.0059569 0.00470639 -419.8245544433594 350.76495361328125 345.0623779296875 0.959747 57.845882 0.062120000000000036 0.0214366228 0.0713033158 -0.0042520129 -0.024328547000000002 0.030119767999999998 0.0280687181 -0.0137978933 -0.049619034299999996 0.0288504286 -0.0586228936 0.017954090500000002 -0.042073201399999996 -0.0588790326 0.050779524000000006 -0.0380953808 0.021971792200000003 -0.0038644781 -0.0145917409 0.031730543 -0.185551 0.181325 0.377505 0.00165562 -0.00621217 0.00437899 -419.5951232910156 351.09197998046875 345.2314453125 0.965823 58.212086 0.11128800000000001 0.021386477999999997 0.0767072062 0.0145596267 -0.0198973203 0.0364604719 0.0316911778 -0.014736906499999999 -0.0520747749 0.023880753199999997 -0.0527391952 0.0427320471 -0.0295623265 -0.0589873867 0.0511937557 -0.0389580073 0.023341845899999998 -0.0057002965 -0.012435871599999999 0.0294929706 -0.199058 0.161935 0.399456 0.00252915 -0.0059569 0.00437899 -419.8625793457031 351.43450927734375 345.784423828125 1.009441 60.841042 0.13779949999999994 0.0260563418 0.072221724 0.0362160536 -0.006813435600000001 0.022996133 0.004486493 -0.0144637117 -0.043146937 0.0226597094 -0.047775877300000005 0.0471784288 -0.013007228899999999 -0.0590936366 0.0516006827 -0.0398081268 0.0246985778 -0.0075310317 -0.010264034 0.027203854 -0.187294 0.220903 0.398073 0.00179703 -0.00632036 0.0045971 -422.2482604980469 351.4603576660156 345.68243408203125 0.968674 58.383938 0.1139495 0.0342689078 0.0654799495 0.0425336424 0.017369392 0.0250797425 -0.06331440440000001 -0.0197799308 -0.04837699559999999 0.0032208269 -0.050572310499999995 0.0504082208 -0.0028729896 -0.0591977785 0.0520002471 -0.0406454662 0.026041213599999998 -0.0093550512 -0.0080790168 0.0248671939 -0.182697 0.179165 0.381958 0.00248897 -0.0064403 0.00437899 -420.7378234863281 351.1676025390625 345.3408508300781 0.948902 57.192253 0.0394925 0.040160190400000004 0.0614438863 0.05066816019999999 0.0340669967 0.022389577999999997 -0.0507508325 -0.013051144399999999 -0.0478650914 -0.0045321797 -0.0526932226 0.061173578 0.028930331200000003 -0.0592998088 0.052392391600000005 -0.0414697568 0.0273689869 -0.011170728500000001 -0.0058836257 0.022487074 -0.186873 0.180908 0.395487 0.00237201 -0.00615637 0.00437899 -421.2898864746094 351.5527038574219 345.8719787597656 0.942634 56.81448 0.07079299999999994 0.0332596226 0.051119302 0.0452601574 0.0627745902 0.0125202051 -0.0202914722 -0.018572023400000002 -0.0484164595 0.0049989381 -0.0450878492 0.0513066233 0.053063832400000004 -0.0593997236 0.0527770605 -0.042280734 0.0286811401 -0.0129764445 -0.0036806797 0.020067654 -0.184936 0.19256 0.374865 0.00196341 -0.00628361 0.00457479 -421.4818420410156 351.624755859375 346.1165771484375 0.962598 58.017754 0.12456899999999994 0.0254547686 0.058762414000000006 0.0359049132 0.054239398499999994 0.039904488700000004 -0.0537941309 -0.0206714856 -0.0529402495 -0.010225448 -0.042448392 0.06821294160000001 0.029656297999999998 -0.0594975196 0.053154198799999997 -0.0430781374 0.029976924199999998 -0.0147705889 -0.0014730073999999998 0.0176131622 -0.182875 0.149502 0.375563 0.00293504 -0.005876 0.00437899 -421.2866516113281 350.93756103515625 346.57965087890625 1.313785 79.184486 0.5838386 0.0442127008 -0.028747438900000002 0.045673888200000005 0.032807444500000005 0.0411461188 -0.0015565267000000002 -0.012219836999999999 -0.0711013184 -0.0850286923 0.0320860685 0.0434996003 0.027728736099999998 -0.059593193200000005 0.053523752699999996 -0.043861710899999996 0.0312555998 -0.0165515619 0.0007365563000000001 0.0151278882 -0.199108 0.0946779 0.0262147 0.0007942859999999998 -0.00612699 0.00350207 -399.9601745605469 335.7095947265625 334.87237548828125 2.126 128.13833600000004 2.1411364 -0.1280517782 -0.0692234734 0.1297085093 0.0264703913 0.20212647620000002 0.044718956399999996 0.21649608760000003 -0.1438987491 -0.051908612 0.2725837175 0.007131560699999999 -0.025822702599999997 -0.059686740999999995 0.053885669500000004 -0.044631203099999996 0.0325164369 -0.0183177752 0.0029451740999999997 0.012616175600000001 -0.163138 -0.46237 -0.502026 -0.0160769 -0.00448637 0.00161632 -416.7155456542969 347.0284423828125 338.27484130859375 2.508385 151.18544 1.7217067499999998 -0.0876704714 -0.1231097427 0.0534457667 -0.060056381799999996 -0.1566820157 0.0864498344 0.13066259800000002 0.1058735392 -0.2528589296 -0.232073235 -0.19043857670000003 -0.018399076 -0.0597781596 0.054239897599999996 -0.0453863669 0.033758716 -0.020067654 0.0051500103000000005 0.010082414100000001 -0.144593 -0.347792 0.439702 -0.0276709 -0.00409947 0.000660105 -428.805908203125 353.9019470214844 350.6581726074219 2.028446 122.25853 0.82655815 -0.025629405600000002 -0.1064844145 0.0269844066 -0.0160835322 -0.1352069099 -0.0231695152 0.017747449499999998 0.1532806933 -0.0676913361 0.1067419941 0.0548928012 0.0101125145 -0.0598674458 0.0545863863 -0.0461269599 0.0349817282 -0.0217996377 0.0073482335 0.0075310317 -0.120055 -0.217439 0.356161 -0.0167047 -0.00357945 0.000936408 -422.5929870605469 352.3768005371094 347.3529968261719 1.057573 63.742081 0.2869126 -0.0372934543 -0.09791113060000001 0.036765779 -0.0063169666000000005 -0.1288141408 0.0077413280000000004 0.0305317305 0.1157251464 -0.038638307999999996 0.0627373336 -0.0134890024 0.0426632396 -0.059954596500000006 0.0549250863 -0.0468527442 0.0361847754 -0.023512181899999998 0.0095370211 0.0049664875 -0.115114 -0.132311 0.389803 -0.0140428 -0.00391794 0.00120005 -422.9916687011719 352.130859375 346.5309143066406 0.968452 58.370586 0.1658033 -0.039889662 -0.0954367281 0.0088103091 0.0076124083999999995 -0.1049339936 -0.020610409099999998 0.026262106299999997 0.1070203303 -0.013517774299999999 0.0688715981 -0.0396257408 0.0390798219 -0.0600396084 0.0552559492 -0.047563487 0.0373671711 -0.0252037594 0.011713562700000001 0.0023932635000000002 -0.11942 -0.0676117 0.382854 -0.0127377 -0.00408757 0.0015223 -421.4900817871094 352.22509765625 346.1685485839844 0.982176 59.197731 0.14192439999999998 -0.0558046851 -0.0706098276 -0.023420474500000003 0.0216604435 -0.0701943269 -0.008550604100000001 0.015222325900000002 0.09060300630000001 -0.009311135600000001 0.0550243019 -0.0284520563 0.04716321440000001 -0.0601224786 0.055578927800000004 -0.0482589599 0.038528240299999995 -0.0268728619 0.0138750634 -0.0001841432 -0.11260800000000003 -0.0702246 0.382847 -0.0104295 -0.00405328 0.00182966 -423.6424255371094 352.2194519042969 345.86810302734375 1.0034630000000002 60.480724 0.14448749999999996 -0.0460940505 -0.0553105019 -0.0583586232 -0.0067716065 -0.0416513841 -0.1040707858 0.0110042441 0.08629297289999999 0.0157615186 0.0561222629 -0.0426516391 0.0102182914 -0.0602032042 0.055893976100000006 -0.0489389399 0.0396673204 -0.0285180009 0.0160187477 -0.0027612279999999997 -0.102392 -0.0102651 0.38287 -0.00991538 -0.00466158 0.00219302 -421.90277099609375 351.81500244140625 345.2787170410156 0.984481 59.336681 0.1268682 -0.0547948474 -0.0463257384 -0.0478135479 -0.0486826822 -0.0419529335 -0.028883373900000002 0.0124696545 0.07729747 0.024601654700000003 0.046521195700000004 -0.0487214722 -0.0333964588 -0.0602817821 0.056201049100000004 -0.0496032084 0.0407837614 -0.0301377094 0.0181418631 -0.005333487099999999 -0.0982034 -0.0398787 0.366004 -0.0103043 -0.00533279 0.00265689 -421.8422546386719 352.50921630859375 345.8283386230469 1.024073 61.722923 0.344535486 -0.0216504798 -0.0154094171 -0.0597656716 -0.0671998619 -0.032011793999999996 0.036236968599999995 -0.0034610566 0.055602965899999995 0.021241660899999997 0.0345453264 -0.0236405249 -0.055816234299999996 -0.0603582097 0.0565001029 -0.0502515524 0.041876926 -0.031730543 0.0202416832 -0.007896425 -0.119415 -0.000321314 0.303257 -0.00710248 -0.00432866 0.00244245 -422.1711730957031 351.5225830078125 344.93341064453125 1.268932 76.481079 0.6198898860000001 0.026784846400000003 -0.0228160246 -0.0432289897 -0.0515553051 0.045481266799999996 0.0564727018 -0.013377770800000001 -0.019454991499999998 -0.059468798600000004 0.0038591721999999998 0.023136595899999998 -0.0793468359 -0.0604324842 0.056791094900000005 -0.0508837635 0.0429461904 -0.0332950814 0.022315511899999998 -0.0104455625 -0.21151 -0.0260087 0.159813 -0.0007924899999999998 -0.00378812 0.00211971 -424.112548828125 352.7214050292969 346.77642822265625 1.290278 77.767685 0.5486042 0.0224473533 -0.05523145 -0.0240807644 -0.057226968600000004 0.0151649193 -0.0425916499 -0.0154371995 0.0281335394 -0.0162452477 0.0225942359 -0.0413965209 -0.0431882898 -0.060504603 0.0570739836 -0.05149963900000001 0.0439909442 -0.0348299293 0.024360686200000002 -0.0129764445 -0.117572 0.124869 0.193596 -0.0055711 -0.00430915 0.00222018 -424.0768432617188 352.3007507324219 346.93017578125 1.076316 64.871735 0.2404377 0.0065282913 -0.037076371600000005 -0.0284498335 -0.0145296266 -0.0002060113 -0.0348300385 -0.0174873787 0.006020318199999999 -0.0015273763 0.038327232999999995 -0.028334303999999998 -0.0149453701 -0.060574563399999996 0.057348728499999994 -0.052098980999999996 0.0450105913 -0.0363337182 0.02637458 -0.0154846479 -0.124961 0.0273768 0.238283 -0.00445776 -0.00475034 0.00248304 -423.2519836425781 352.6043701171875 346.9412536621094 1.070907 64.545761 0.07287609999999994 0.0010400405999999999 -0.0363212014 -0.05121451269999999 -0.0100911294 0.0220208294 -0.024530569900000004 -0.0206159411 0.0010494503999999999 0.0006442926000000001 0.0323686035 -0.0188277518 -0.011472773799999999 -0.060642363 0.057615290599999994 -0.0526815972 0.046004549699999994 -0.0378051071 0.0283546073 -0.0179657891 -0.1169 0.0394639 0.232831 -0.00395279 -0.00431941 0.00247342 -422.2267761230469 351.9680480957031 346.0373840332031 1.043865 62.91584 0.16281079999999998 0.0072036109999999995 -0.0148172754 -0.0413669625 -0.0550342285 0.0104536319 0.0463244349 -0.0114889456 0.0082549427 0.0195629699 0.020824224199999998 -0.0293326794 -0.0471719384 -0.060707999400000004 0.0578736318 -0.0532473004 0.0469722521 -0.0392427837 0.030298225699999997 -0.020415532 -0.11221 0.08817719999999998 0.265771 -0.00482867 -0.00491323 0.00253307 -423.38409423828125 352.0017395019531 345.3860778808594 1.021042 61.54026 0.0575217 0.0380783666 -0.0014998632999999998 0.0100344352 -0.055189355499999995 0.0275531334 -0.013140171 -0.0152467991 -0.0028645473 0.011986636 0.0181232865 -0.0057148884 -0.0400035199 -0.0607714702 0.058123715199999995 -0.0537959092 0.0479131463 -0.0406454662 0.0322029395 -0.0228295951 -0.118267 0.0698375 0.260366 -0.00448459 -0.00476633 0.00259649 -420.6625061035156 351.26953125 344.8603210449219 1.02904 62.022346 0.09730379999999997 0.053374200499999996 0.0058280643000000005 0.038593734500000004 -0.0196502383 0.0373108902 -0.054177921500000004 -0.0088971954 -0.0103554784 -0.010358443299999999 0.0126805955 0.007087885699999999 -0.0131216874 -0.0608327732 0.0583655051 -0.054327247300000006 0.0488266951 -0.0420119037 0.034066302799999996 -0.0252037594 -0.125135 0.0474352 0.244845 -0.00393455 -0.00431456 0.00254805 -419.7892150878906 351.7342224121094 344.9761962890625 1.046973 63.103176 0.1949898 0.0348268222 -0.0071921639 0.0222846597 0.038177168 -0.007666212800000001 0.0315534524 -0.0102283949 0.0020103927 0.0078154554 0.0038825555 -0.0054931089 0.051992141799999995 -0.0608919062 0.058598967 -0.0548411441 0.049712377300000006 -0.043340877699999995 0.0358859231 -0.0275338758 -0.112126 0.10774 0.275304 -0.00479333 -0.00498764 0.00284053 -418.7413024902344 351.1280212402344 344.80572509765625 0.997383 60.114265 0.15845739999999997 0.013482196200000001 -0.018684654 -0.0048283247999999996 0.0649365866 0.0094822091 0.0618010524 -0.0078076848 -0.0132017193 -0.0048834025 0.0107021479 -0.0017909292000000002 0.06266650480000001 -0.060948867000000004 0.058824067699999996 -0.0553374348 0.050569687300000006 -0.044631203099999996 0.0376594638 -0.0298158718 -0.126718 0.0593756 0.244366 -0.00396714 -0.00459401 0.00276909 -420.9377746582031 351.9564514160156 345.2381286621094 1.040242 62.697521 0.06017419999999999 -0.011314081699999999 -0.0278842001 -0.0477065966 0.0688739096 0.060157833200000004 -0.0240738002 -0.0118185596 -0.0057897978000000004 0.0011005910000000002 0.0162354137 -0.0062478229 0.0474022611 -0.061003653600000006 0.0590407749 -0.05581596 0.051398136 -0.0458817293 0.039384647599999996 -0.032045759300000004 -0.111431 0.0758303 0.241882 -0.00384966 -0.00473658 0.00251017 -421.99810791015625 351.0489196777344 345.5321044921875 1.033145 62.26973 0.1209072 -0.0147406323 0.0019164622 -0.07832891809999999 0.0007858286999999999 0.0245240442 -0.0313982364 -0.0095381006 -0.0138418155 0.0264993474 -0.00039530809999999996 -0.024030364900000004 -0.011574345500000001 -0.0610562642 0.059249057800000005 -0.05627656599999999 0.052197250300000005 -0.0470913411 0.041059259300000005 -0.0342196412 -0.111476 0.124043 0.266333 -0.00445542 -0.00480476 0.0028002 -420.36517333984375 351.1342468261719 345.2734375 1.008703 60.796574 0.16074429999999998 0.0104759351 0.0085441607 -0.052527981200000004 -0.050008154299999996 0.014420084 0.054802933899999996 -0.0093308946 -0.017644979499999998 0.0224587853 -0.010171875300000001 -0.0189921052 -0.068499219 -0.0611066967 0.0594488867 -0.056719105 0.0529665744 -0.0482589599 0.042681148499999995 -0.0363337182 -0.112557 0.0624852 0.241435 -0.00342674 -0.00437992 0.00278957 -420.7155456542969 350.9720764160156 345.3565368652344 1.008094 60.759869 0.058259700000000025 0.0415136324 0.0125072425 0.0069699213 -0.044191524 0.0202096811 0.0118389709 -0.0106788653 -0.022302747400000003 0.0107642662 -0.0026232565 -0.015773281599999998 -0.0336852052 -0.061154949400000005 0.059640233 -0.057143434800000004 0.053705669000000004 -0.0493835445 0.0442482328 -0.0383842957 -0.12578 0.0808674 0.238196 -0.00368899 -0.0044243 0.00262789 -420.4479370117188 351.3194885253906 345.677001953125 1.0813100000000002 65.172768 0.15503460000000002 0.047682265599999996 0.0175540487 0.0489314856 -0.0101481014 0.0139244733 -0.0756840656 -0.006811980699999999 -0.0101218017 0.0130763145 -0.0064996524 0.0070456124 0.01049434 -0.061201020700000004 0.0598230695 -0.0575494194 0.0544141125 -0.050464092099999996 0.0457584997 -0.0403677898 -0.111499 0.110419 0.271664 -0.00480817 -0.00465371 0.00283398 -419.498046875 351.53302001953125 345.9704895019531 1.029841 62.070583 0.09417479999999998 0.0470628254 0.007376436700000001 0.0361783563 0.0318275237 -0.0161019607 0.00337993 -0.0105687204 -0.0228434812 -0.0004417203 -0.0075867415 0.0120447149 0.0435731803 -0.0612449087 0.05999737 -0.0579369282 0.0550915004 -0.05149963900000001 0.04721001019999999 -0.042280734 -0.11524400000000003 0.0749852 0.250632 -0.0043111 -0.00473658 0.00293332 -417.7709655761719 351.4949951171875 346.0661926269531 1.00018 60.282906 0.08305440000000006 0.0164367723 -0.0004995701 0.013952514099999999 0.066492379 -0.021701244900000003 0.06762079110000001 -0.0110603679 -0.0254391371 -0.008274535500000001 -0.0113863292 0.0027926934000000003 0.0530494656 -0.0612866121 0.060163109699999995 -0.058305837 0.055737446100000004 -0.05248926190000001 0.0486009003 -0.0441197852 -0.12570300000000004 0.0699593 0.236253 -0.00387974 -0.00434618 0.00269127 -420.03070068359375 351.7759094238281 346.6172180175781 1.018497 61.386848 0.1691612 -0.0314743369 -0.0102726609 -0.02180923 0.0696488867 -0.011764894 0.0241853628 -0.0096268385 -0.0051703754 0.0094091357 -0.0048425501 -0.013219706999999999 0.0603396846 -0.061326129199999996 0.060320264900000004 -0.058656027300000003 0.056351581 -0.053432078200000004 0.0499293841 -0.0458817293 -0.111384 0.107338 0.273193 -0.00460122 -0.00498385 0.00294259 -421.60845947265625 352.45343017578125 347.2548828125 1.009959 60.872246 0.15057970000000007 -0.0256647037 0.0005163879 -0.0507417025 0.034918601699999996 0.011617632900000001 -0.0313109273 -0.0194350817 -0.015940431499999998 0.013334853999999998 0.0021401931 -0.0198508594 0.015688409599999998 -0.0613634587 0.060468813200000006 -0.0589873867 0.0569335547 -0.054327247300000006 0.0511937557 -0.047563487 -0.121452 0.0575558 0.230565 -0.00402311 -0.00473658 0.00280594 -422.3707580566406 352.4518737792969 347.8758544921875 1.012851 61.046562 0.0592844 -0.013647577099999999 0.006125055 -0.06887951 -0.012839508999999999 0.010887618 -0.0392331893 -0.022555605899999998 -0.0166405108 0.0201722734 0.0048147549 -0.0328312681 -0.032712656 -0.0613985992 0.0606087335 -0.0592998088 0.0574830349 -0.0551739708 0.052392391600000005 -0.0491621191 -0.12002 0.0707792 0.230593 -0.00359188 -0.00442055 0.00266118 -421.72943115234375 352.23681640625 347.91278076171875 1.00168 60.373264 0.1312348 -0.0026898913 0.0135188589 -0.029777488300000002 -0.0496757054 -0.0224497455 0.03261933 -0.0170265793 -0.0091950457 0.0192573991 0.000224868 -0.0204236831 -0.052530132599999994 -0.0614315496 0.0607400057 -0.059593193200000005 0.057999708 -0.0559714938 0.053523752699999996 -0.050674831600000005 -0.10506 0.10708 0.247001 -0.00459617 -0.0046683 0.00268046 -422.26556396484375 352.25299072265625 347.68084716796875 1.015506 61.206627 0.09617179999999997 0.026363765 0.0228187609 0.0097683903 -0.0552644821 -0.0100202481 0.0265584463 -0.022286539900000003 -0.0143782431 0.0147867239 0.0031726192 0.0055927768 -0.048099828399999996 -0.06146230849999999 0.060862611100000005 -0.0598674458 0.0584832792 -0.056719105 0.0545863863 -0.052098980999999996 -0.116538 0.0761012 0.227561 -0.00410443 -0.00473658 0.00280594 -421.0836791992188 352.23712158203125 347.4114990234375 0.993424 59.875683 0.0528107 0.0344300282 0.026865599900000002 0.0439509109 -0.031134814 0.020750702700000002 -0.0201194326 -0.0212483685 -0.024854825499999997 0.0024740129 -0.007875861999999999 0.0155869187 -0.0246105421 -0.061490875 0.060976532199999996 -0.0601224786 0.0589334724 -0.057416137699999995 0.055578927800000004 -0.053432078200000004 -0.11157 0.0772409 0.227499 -0.00382909 -0.00429321 0.00259183 -423.3153991699219 352.1808776855469 347.6640930175781 1.04036 62.70462 0.1723511 0.0314483635 0.0069168028 0.038593766200000004 0.014005086100000001 -0.0191369675 -0.0301891844 -0.0206926744 -0.0185820124 -0.0035260791999999997 -0.016039978700000002 0.0062774867 0.024999485499999998 -0.061517248 0.0610817528 -0.0603582097 0.0593500308 -0.0580619705 0.0565001029 -0.0546717934 -0.111399 0.127638 0.260449 -0.00475495 -0.00498421 0.00275163 -421.71282958984375 352.2409362792969 347.1488037109375 1.002166 60.402573 0.13683079999999997 0.0271744969 0.0015163845000000001 0.025763855699999998 0.0499472431 -0.0261006619 0.0402759187 -0.0169465364 -0.0250337745 -0.007249771800000001 0.0009704044 0.0063263352 0.0485999375 -0.0615414265 0.061178257800000004 -0.060574563399999996 0.0597327166 -0.058656027300000003 0.057348728499999994 -0.05581596 -0.111503 0.0696532 0.238549 -0.00412388 -0.00453274 0.00280593 -420.95794677734375 351.55804443359375 346.8887023925781 0.980891 59.120312 0.039432699999999966 0.018563746399999997 -0.0017437245999999999 0.015592283500000002 0.0699698942 -0.0189452991 0.06333085299999999 -0.0126904754 -0.0257302339 0.0020127883 -0.0005758355000000001 -0.0008228822 0.056738310099999995 -0.061563409699999995 0.061266033600000006 -0.0607714702 0.0600813114 -0.0591977785 0.058123715199999995 -0.0568625783 -0.111504 0.0859344 0.248921 -0.00396849 -0.00457196 0.00286689 -422.2423706054688 351.723876953125 347.05621337890625 0.994362 59.932224 0.10751260000000001 0.0022134376999999998 -0.0211319623 -0.014810129699999999 0.0659470958 0.0059990238 0.0126242008 -0.0148947101 -0.0227536138 0.013746433700000001 -0.000859843 -0.015347276299999999 0.054628272699999994 -0.061583196900000005 0.0613450675 -0.060948867000000004 0.060395616299999996 -0.059686740999999995 0.058824067699999996 -0.057809819299999995 -0.10703 0.120201 0.230786 -0.00440255 -0.00509613 0.0029214 -421.8899230957031 351.7915954589844 346.7508544921875 1.017657 61.336273 0.14446660000000003 -0.015388519 -0.022791758999999998 -0.041555322900000004 0.060412622400000004 0.0664526441 -0.0352038977 -0.0163509164 -0.0282916005 0.0054836228 0.0111122116 -0.006100890699999999 0.035625105899999995 -0.0616007872 0.0614153483 -0.0611066967 0.060675451799999995 -0.0601224786 0.0594488867 -0.058656027300000003 -0.110814 0.0622799 0.226982 -0.00342081 -0.00461419 0.00280593 -419.475341796875 346.569580078125 339.4344482421875 1.621333 97.721054 0.8422699 -0.060588875099999995 -0.025163469900000002 -0.0345421064 -0.0149674769 0.0055548147 -0.0705371986 0.0881760367 0.010057830799999999 -0.0277921859 0.0133373391 0.09058812179999999 -0.0635773054 -0.061616180199999995 0.0614768659 -0.0612449087 0.060920658200000005 -0.060504603 0.05999737 -0.0593997236 -0.104784 -0.089261 0.363692 -0.0133824 -0.00553932 0.00273287 -425.2885437011719 352.3264465332031 347.6260681152344 1.754944 105.77401 0.244977 -0.0617111459 -0.0424335949 -0.026480202 -0.061380522400000005 -0.054977903700000004 0.008906026800000001 0.0284929712 0.1055191519 -0.0043276145 0.0328242821 -0.0375287711 -0.0202048105 -0.061629375099999995 0.0615296116 -0.0613634587 0.061131095700000006 -0.0608327732 0.060468813200000006 -0.0600396084 -0.0938495 -0.152035 0.379953 -0.0159306 -0.00582372 0.00246532 -420.75860595703125 351.138671875 344.8719177246094 1.066348 64.270981 0.25311920000000004 -0.0369242793 -0.0033569290000000002 -0.0006735921 -0.0777995521 -0.0552759762 0.051621468200000006 0.0335690785 0.078022487 0.0250692512 0.017824441899999998 -0.0234486361 -0.0381334383 -0.0616403716 0.0615735779 -0.06146230849999999 0.061306644 -0.0611066967 0.060862611100000005 -0.060574563399999996 -0.0892588 -0.0874425 0.407397 -0.0135491 -0.0053038 0.00269374 -419.7999267578125 351.4358215332031 345.1805114746094 0.964989 58.16185 0.2307048 -0.023679175 0.0070704538 0.0202688006 -0.06289879450000001 -0.0569715155 0.0406695013 0.0251892076 0.061623254800000006 0.0299540123 0.014245055 -0.023699705 -0.0428694041 -0.061649169299999994 0.0616087584 -0.0615414265 0.06144720309999999 -0.061326129199999996 0.061178257800000004 -0.061003653600000006 -0.068303 -0.01901 0.394174 -0.0122135 -0.0061456 0.00307821 -421.88525390625 351.54473876953125 345.47784423828125 0.967501 58.313236 0.20407260000000002 -0.0112502858 0.0043324475 0.0352424739 -0.06106296 -0.048241136399999995 0.0193180422 0.013328851000000001 0.0471989272 0.0301798489 0.0153739543 -0.0136828072 -0.030833595499999998 -0.0616557679 0.0616351482 -0.0616007872 0.0615526926 -0.061490875 0.0614153483 -0.061326129199999996 -0.0772062 -0.0497254 0.367467 -0.0100973 -0.00551319 0.00307188 -421.8799743652344 351.5860900878906 345.7599182128906 0.981342 59.147472 0.13091309999999998 -0.00023811459999999998 0.0014113579000000001 0.0589832312 -0.05759092440000001 -0.0366861115 -0.010808996699999998 0.0170013236 0.0492634999 0.0243669302 0.008810704300000001 -0.0088384347 -0.015403706699999999 -0.061660167 0.061652743499999996 -0.0616403716 0.0616230524 -0.0616007872 0.0615735779 -0.0615414265 -0.0728679 0.0122509 0.385343 -0.0106585 -0.00574298 0.00321534 -424.6867980957031 351.6780090332031 346.01348876953125 0.975821 58.814686 0.11073759199999994 0.0081499757 -0.006383630899999999 0.0507607209 -0.027885499100000002 -0.044596878099999994 -0.0923937341 0.0100422214 0.040500660699999996 0.0224932248 0.0096666228 -0.019763769599999998 0.0127408286 -0.061662366600000004 0.0616615418 -0.061660167 0.0616582424 -0.0616557679 0.061652743499999996 -0.061649169299999994 -0.0761831 -0.000731992 0.362164 -0.0100236 -0.00628587 0.00346276 diff --git a/pydra/tasks/fsl/tests/data/cope_merged.nii.gz b/pydra/tasks/fsl/tests/data/cope_merged.nii.gz deleted file mode 100644 index d79c4dc..0000000 --- a/pydra/tasks/fsl/tests/data/cope_merged.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccdedd7aef55301fe634a494ca7df384d59bfab309e20cc042954d66b1774bbc -size 25232078 diff --git a/pydra/tasks/fsl/tests/data/design b/pydra/tasks/fsl/tests/data/design deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/design.con b/pydra/tasks/fsl/tests/data/design.con deleted file mode 100644 index 999adde..0000000 --- a/pydra/tasks/fsl/tests/data/design.con +++ /dev/null @@ -1,8 +0,0 @@ -/ContrastName1 group mean -/NumWaves 1 -/NumContrasts 1 -/PPheights 1 -/RequiredEffect 100 - -/Matrix -1 diff --git a/pydra/tasks/fsl/tests/data/design.grp b/pydra/tasks/fsl/tests/data/design.grp deleted file mode 100644 index b90612e..0000000 --- a/pydra/tasks/fsl/tests/data/design.grp +++ /dev/null @@ -1,30 +0,0 @@ -/NumWaves 1 -/NumPoints 26 - -/Matrix -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 diff --git a/pydra/tasks/fsl/tests/data/design.mat b/pydra/tasks/fsl/tests/data/design.mat deleted file mode 100644 index 03cce9e..0000000 --- a/pydra/tasks/fsl/tests/data/design.mat +++ /dev/null @@ -1,31 +0,0 @@ -/NumWaves 1 -/NumPoints 26 -/PPheights 1 - -/Matrix -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 diff --git a/pydra/tasks/fsl/tests/data/design_film_gls.mat b/pydra/tasks/fsl/tests/data/design_film_gls.mat deleted file mode 100644 index b65f2bd..0000000 --- a/pydra/tasks/fsl/tests/data/design_film_gls.mat +++ /dev/null @@ -1,151 +0,0 @@ -/NumWaves 2 -/NumPoints 146 -/PPheights 3.012332e-01 3.012332e-01 - -/Matrix --5.459164e-02 -1.321669e-01 --5.776502e-02 6.606531e-03 --6.080976e-02 1.543109e-01 --6.371286e-02 1.298120e-01 --6.647145e-02 3.844376e-02 --6.908718e-02 -3.150186e-02 --7.156363e-02 6.090263e-02 --7.390440e-02 1.853853e-01 --7.611377e-02 1.503911e-01 --7.819593e-02 5.456673e-02 --7.486357e-02 -2.261410e-02 -5.867573e-02 -6.685146e-02 -2.012061e-01 -8.703843e-02 -1.717945e-01 -9.469297e-02 -7.582675e-02 -9.654834e-02 -1.559045e-03 -9.605199e-02 -8.987555e-02 -9.498077e-02 -2.104731e-01 -9.314661e-02 -1.717227e-01 -9.140213e-02 -7.226508e-02 -8.973824e-02 --8.360482e-03 -8.285842e-02 --5.583817e-02 5.403689e-02 --7.907882e-02 1.997381e-01 --8.966740e-02 1.733180e-01 --9.433347e-02 8.016810e-02 --9.647567e-02 3.258706e-03 --9.258233e-02 -4.131708e-02 -4.231492e-02 -6.264655e-02 -1.861386e-01 -7.145020e-02 -1.579594e-01 -7.446427e-02 -6.316558e-02 -7.508158e-02 --1.527660e-02 -7.507187e-02 --5.598662e-02 -7.425640e-02 -5.674071e-02 -7.349584e-02 -1.909692e-01 -7.278683e-02 -1.590299e-01 -7.212842e-02 -6.292010e-02 -7.153127e-02 --1.615871e-02 -7.100015e-02 --6.194223e-02 -6.523060e-02 --8.438769e-02 7.058237e-02 --9.421868e-02 2.152288e-01 --9.817426e-02 1.877781e-01 --9.964602e-02 9.360361e-02 --1.004003e-01 1.566834e-02 --9.497193e-02 -2.991771e-02 -4.056806e-02 -5.223350e-02 -1.850072e-01 -6.200044e-02 -1.574158e-01 -6.595827e-02 -6.318250e-02 -6.749883e-02 --1.474421e-02 -6.838785e-02 --6.027821e-02 -6.845050e-02 --8.248644e-02 -6.326130e-02 --9.208075e-02 7.197718e-02 --9.579978e-02 2.160541e-01 --9.703767e-02 1.880415e-01 --9.756266e-02 9.332951e-02 --9.720187e-02 1.486645e-02 --9.682290e-02 -3.125984e-02 --9.113464e-02 -5.411225e-02 -4.465926e-02 -6.440030e-02 -1.893469e-01 -6.886134e-02 -1.619991e-01 -7.088827e-02 -6.800471e-02 -7.224792e-02 --9.690209e-03 -7.276583e-02 --5.499909e-02 -7.330789e-02 --7.169342e-02 -7.387266e-02 -5.431262e-02 -7.445841e-02 -1.950681e-01 -7.506335e-02 -1.662489e-01 -7.568549e-02 -7.147623e-02 -7.632279e-02 --8.176363e-04 -7.697310e-02 -8.937981e-02 -7.765713e-02 -2.117738e-01 -7.835313e-02 -1.747124e-01 -7.905909e-02 -7.684715e-02 -7.977294e-02 --2.244466e-03 -7.520110e-02 --4.825783e-02 5.945172e-02 --7.008473e-02 2.030005e-01 --7.931501e-02 1.745170e-01 --8.268742e-02 7.936397e-02 --8.359340e-02 5.028823e-04 --8.379921e-02 -4.596713e-02 --8.313134e-02 -6.381502e-02 --8.245759e-02 6.103882e-02 --8.177899e-02 2.006207e-01 --8.109666e-02 1.706052e-01 --8.041089e-02 7.462413e-02 --7.970375e-02 1.120672e-03 --7.897786e-02 9.012257e-02 --7.826208e-02 2.113333e-01 --7.756605e-02 1.731043e-01 --7.688548e-02 7.409003e-02 --7.090554e-02 -6.129659e-03 -6.517159e-02 -5.322669e-02 -2.101087e-01 -7.611373e-02 -1.829684e-01 -8.637799e-02 -8.914442e-02 -9.075484e-02 -1.161007e-02 -9.261644e-02 --2.824889e-02 -9.372844e-02 -8.527574e-02 -9.393906e-02 -2.202495e-01 -9.412025e-02 -1.890043e-01 -9.426583e-02 -9.353877e-02 -9.436847e-02 -1.506874e-02 -9.442292e-02 --3.014387e-02 -8.913434e-02 --5.207685e-02 4.629598e-02 --6.145878e-02 1.906580e-01 --6.502444e-02 1.630239e-01 --6.616014e-02 6.878507e-02 --6.661982e-02 -9.088744e-03 --6.623232e-02 -4.921326e-02 --6.587989e-02 6.412036e-02 --6.556584e-02 1.989795e-01 --6.528731e-02 1.676985e-01 --6.504170e-02 7.227823e-02 --6.482819e-02 -6.073926e-03 --6.464721e-02 -4.580406e-02 --6.449977e-02 6.792454e-02 --6.438708e-02 2.031816e-01 --6.431039e-02 1.723052e-01 --6.427118e-02 7.729824e-02 --6.427838e-02 -6.342129e-04 --6.434014e-02 -4.522484e-02 --5.915676e-02 -6.642826e-02 -7.607670e-02 -7.496560e-02 -2.201507e-01 -7.757353e-02 -1.921346e-01 -7.764146e-02 -9.741598e-02 -7.693452e-02 -1.896121e-02 -7.530513e-02 --2.713964e-02 -7.363015e-02 --4.997651e-02 -6.657981e-02 --6.027214e-02 7.066638e-02 --6.476492e-02 2.168997e-01 --6.684551e-02 1.911862e-01 --6.828164e-02 9.891084e-02 --6.896161e-02 2.303913e-02 --6.977084e-02 -2.033853e-02 --6.533284e-02 -4.031109e-02 -6.919543e-02 -4.759994e-02 -2.126028e-01 -4.894233e-02 -1.839457e-01 -4.772757e-02 -8.859665e-02 -4.571982e-02 -9.392948e-03 -4.274329e-02 --3.761005e-02 -3.966346e-02 --6.133499e-02 -3.647896e-02 --7.241645e-02 -3.318836e-02 diff --git a/pydra/tasks/fsl/tests/data/dest.nii.gz b/pydra/tasks/fsl/tests/data/dest.nii.gz deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/ev_1.txt b/pydra/tasks/fsl/tests/data/ev_1.txt deleted file mode 100644 index 64e7df8..0000000 --- a/pydra/tasks/fsl/tests/data/ev_1.txt +++ /dev/null @@ -1,12 +0,0 @@ -32.000000 2.000000 1.000000 -42.000000 2.000000 1.000000 -52.000000 2.000000 1.000000 -64.000000 2.000000 1.000000 -102.000000 2.000000 1.000000 -116.000000 2.000000 1.000000 -144.000000 2.000000 1.000000 -164.000000 2.000000 1.000000 -208.000000 2.000000 1.000000 -220.000000 2.000000 1.000000 -232.000000 2.000000 1.000000 -260.000000 2.000000 1.000000 diff --git a/pydra/tasks/fsl/tests/data/ev_2.txt b/pydra/tasks/fsl/tests/data/ev_2.txt deleted file mode 100644 index c992e50..0000000 --- a/pydra/tasks/fsl/tests/data/ev_2.txt +++ /dev/null @@ -1,12 +0,0 @@ -0.000000 2.000000 1.000000 -10.000000 2.000000 1.000000 -20.000000 2.000000 1.000000 -76.000000 2.000000 1.000000 -88.000000 2.000000 1.000000 -130.000000 2.000000 1.000000 -154.000000 2.000000 1.000000 -174.000000 2.000000 1.000000 -184.000000 2.000000 1.000000 -196.000000 2.000000 1.000000 -246.000000 2.000000 1.000000 -274.000000 2.000000 1.000000 diff --git a/pydra/tasks/fsl/tests/data/flirt.mat b/pydra/tasks/fsl/tests/data/flirt.mat deleted file mode 100644 index 080d687..0000000 --- a/pydra/tasks/fsl/tests/data/flirt.mat +++ /dev/null @@ -1,4 +0,0 @@ -1.06898439 0.04500452499 0.07609409025 -19.99484204 --0.04444970083 1.031806413 0.02891208633 17.8281428 --0.0452495497 -0.07397098198 1.22886291 -3.444566823 -0 0 0 1 diff --git a/pydra/tasks/fsl/tests/data/flirt_inv.mat b/pydra/tasks/fsl/tests/data/flirt_inv.mat deleted file mode 100644 index bc9b4b6..0000000 --- a/pydra/tasks/fsl/tests/data/flirt_inv.mat +++ /dev/null @@ -1,4 +0,0 @@ -0.9312133442 -0.04467547969 -0.05661182412 19.22094134 -0.03908945148 0.9656667535 -0.02514024676 -16.52105463 -0.03664238643 0.0564829259 0.8101625361 2.516332053 -0 0 0 1 diff --git a/pydra/tasks/fsl/tests/data/mask.nii.gz b/pydra/tasks/fsl/tests/data/mask.nii.gz deleted file mode 100644 index 1044603..0000000 --- a/pydra/tasks/fsl/tests/data/mask.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:95cc283387609f9d0653014cbc9636f528135135041f639a17c19d88c3680db5 -size 21201 diff --git a/pydra/tasks/fsl/tests/data/struct2mni.nii b/pydra/tasks/fsl/tests/data/struct2mni.nii deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/subjectDesign.con b/pydra/tasks/fsl/tests/data/subjectDesign.con deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/subjectDesign.mat b/pydra/tasks/fsl/tests/data/subjectDesign.mat deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/test.fsf b/pydra/tasks/fsl/tests/data/test.fsf deleted file mode 100644 index d6e5976..0000000 --- a/pydra/tasks/fsl/tests/data/test.fsf +++ /dev/null @@ -1,11836 +0,0 @@ - -# FEAT version number -set fmri(version) 6.00 - -# Are we in MELODIC? -set fmri(inmelodic) 0 - -# Analysis level -# 1 : First-level analysis -# 2 : Higher-level analysis -set fmri(level) 2 - -# Which stages to run -# 0 : No first-level analysis (registration and/or group stats only) -# 7 : Full first-level analysis -# 1 : Pre-processing -# 2 : Statistics -set fmri(analysis) 2 - -# Use relative filenames -set fmri(relative_yn) 0 - -# Balloon help -set fmri(help_yn) 1 - -# Run Featwatcher -set fmri(featwatcher_yn) 1 - -# Cleanup first-level standard-space images -set fmri(sscleanup_yn) 0 - -# Output directory -set fmri(outputdir) "Flanker_2ndLevel" - -# TR(s) -set fmri(tr) 3 - -# Total volumes -set fmri(npts) 52 - -# Delete volumes -set fmri(ndelete) 0 - -# Perfusion tag/control order -set fmri(tagfirst) 1 - -# Number of first-level analyses -set fmri(multiple) 52 - -# Higher-level input type -# 1 : Inputs are lower-level FEAT directories -# 2 : Inputs are cope images from FEAT directories -set fmri(inputtype) 1 - -# Carry out pre-stats processing? -set fmri(filtering_yn) 0 - -# Brain/background threshold, % -set fmri(brain_thresh) 10 - -# Critical z for design efficiency calculation -set fmri(critical_z) 5.3 - -# Noise level -set fmri(noise) 0.66 - -# Noise AR(1) -set fmri(noisear) 0.34 - -# Motion correction -# 0 : None -# 1 : MCFLIRT -set fmri(mc) 1 - -# Spin-history (currently obsolete) -set fmri(sh_yn) 0 - -# B0 fieldmap unwarping? -set fmri(regunwarp_yn) 0 - -# GDC Test -set fmri(gdc) "" - -# EPI dwell time (ms) -set fmri(dwell) 0.0 - -# EPI TE (ms) -set fmri(te) 0.0 - -# % Signal loss threshold -set fmri(signallossthresh) 10 - -# Unwarp direction -set fmri(unwarp_dir) y- - -# Slice timing correction -# 0 : None -# 1 : Regular up (0, 1, 2, 3, ...) -# 2 : Regular down -# 3 : Use slice order file -# 4 : Use slice timings file -# 5 : Interleaved (0, 2, 4 ... 1, 3, 5 ... ) -set fmri(st) 0 - -# Slice timings file -set fmri(st_file) "" - -# BET brain extraction -set fmri(bet_yn) 1 - -# Spatial smoothing FWHM (mm) -set fmri(smooth) 5 - -# Intensity normalization -set fmri(norm_yn) 0 - -# Perfusion subtraction -set fmri(perfsub_yn) 0 - -# Highpass temporal filtering -set fmri(temphp_yn) 1 - -# Lowpass temporal filtering -set fmri(templp_yn) 0 - -# MELODIC ICA data exploration -set fmri(melodic_yn) 0 - -# Carry out main stats? -set fmri(stats_yn) 1 - -# Carry out prewhitening? -set fmri(prewhiten_yn) 1 - -# Add motion parameters to model -# 0 : No -# 1 : Yes -set fmri(motionevs) 0 -set fmri(motionevsbeta) "" -set fmri(scriptevsbeta) "" - -# Robust outlier detection in FLAME? -set fmri(robust_yn) 0 - -# Higher-level modelling -# 3 : Fixed effects -# 0 : Mixed Effects: Simple OLS -# 2 : Mixed Effects: FLAME 1 -# 1 : Mixed Effects: FLAME 1+2 -set fmri(mixed_yn) 3 - -# Higher-level permutations -set fmri(randomisePermutations) 5000 - -# Number of EVs -set fmri(evs_orig) 26 -set fmri(evs_real) 26 -set fmri(evs_vox) 0 - -# Number of contrasts -set fmri(ncon_orig) 1 -set fmri(ncon_real) 26 - -# Number of F-tests -set fmri(nftests_orig) 0 -set fmri(nftests_real) 0 - -# Add constant column to design matrix? (obsolete) -set fmri(constcol) 0 - -# Carry out post-stats steps? -set fmri(poststats_yn) 0 - -# Pre-threshold masking? -set fmri(threshmask) "" - -# Thresholding -# 0 : None -# 1 : Uncorrected -# 2 : Voxel -# 3 : Cluster -set fmri(thresh) 3 - -# P threshold -set fmri(prob_thresh) 0.05 - -# Z threshold -set fmri(z_thresh) 3.1 - -# Z min/max for colour rendering -# 0 : Use actual Z min/max -# 1 : Use preset Z min/max -set fmri(zdisplay) 0 - -# Z min in colour rendering -set fmri(zmin) 2 - -# Z max in colour rendering -set fmri(zmax) 8 - -# Colour rendering type -# 0 : Solid blobs -# 1 : Transparent blobs -set fmri(rendertype) 1 - -# Background image for higher-level stats overlays -# 1 : Mean highres -# 2 : First highres -# 3 : Mean functional -# 4 : First functional -# 5 : Standard space template -set fmri(bgimage) 1 - -# Create time series plots -set fmri(tsplot_yn) 1 - -# Registration to initial structural -set fmri(reginitial_highres_yn) 0 - -# Search space for registration to initial structural -# 0 : No search -# 90 : Normal search -# 180 : Full search -set fmri(reginitial_highres_search) 90 - -# Degrees of Freedom for registration to initial structural -set fmri(reginitial_highres_dof) 3 - -# Registration to main structural -set fmri(reghighres_yn) 0 - -# Search space for registration to main structural -# 0 : No search -# 90 : Normal search -# 180 : Full search -set fmri(reghighres_search) 90 - -# Degrees of Freedom for registration to main structural -set fmri(reghighres_dof) BBR - -# Registration to standard image? -set fmri(regstandard_yn) 1 - -# Use alternate reference images? -set fmri(alternateReference_yn) 0 - -# Standard image -set fmri(regstandard) "/usr/local/fsl/data/standard/MNI152_T1_2mm_brain" - -# Search space for registration to standard space -# 0 : No search -# 90 : Normal search -# 180 : Full search -set fmri(regstandard_search) 90 - -# Degrees of Freedom for registration to standard space -set fmri(regstandard_dof) 12 - -# Do nonlinear registration from structural to standard space? -set fmri(regstandard_nonlinear_yn) 0 - -# Control nonlinear warp field resolution -set fmri(regstandard_nonlinear_warpres) 10 - -# High pass filter cutoff -set fmri(paradigm_hp) 100 - -# Number of lower-level copes feeding into higher-level analysis -set fmri(ncopeinputs) 4 - -# Use lower-level cope 1 for higher-level analysis -set fmri(copeinput.1) 1 - -# Use lower-level cope 2 for higher-level analysis -set fmri(copeinput.2) 1 - -# Use lower-level cope 3 for higher-level analysis -set fmri(copeinput.3) 1 - -# Use lower-level cope 4 for higher-level analysis -set fmri(copeinput.4) 1 - -# 4D AVW data or FEAT directory (1) -set feat_files(1) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-01/run1.feat" - -# 4D AVW data or FEAT directory (2) -set feat_files(2) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-01/run2.feat" - -# 4D AVW data or FEAT directory (3) -set feat_files(3) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-02/run1.feat" - -# 4D AVW data or FEAT directory (4) -set feat_files(4) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-02/run2.feat" - -# 4D AVW data or FEAT directory (5) -set feat_files(5) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-03/run1.feat" - -# 4D AVW data or FEAT directory (6) -set feat_files(6) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-03/run2.feat" - -# 4D AVW data or FEAT directory (7) -set feat_files(7) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-04/run1.feat" - -# 4D AVW data or FEAT directory (8) -set feat_files(8) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-04/run2.feat" - -# 4D AVW data or FEAT directory (9) -set feat_files(9) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-05/run1.feat" - -# 4D AVW data or FEAT directory (10) -set feat_files(10) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-05/run2.feat" - -# 4D AVW data or FEAT directory (11) -set feat_files(11) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-06/run1.feat" - -# 4D AVW data or FEAT directory (12) -set feat_files(12) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-06/run2.feat" - -# 4D AVW data or FEAT directory (13) -set feat_files(13) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-07/run1.feat" - -# 4D AVW data or FEAT directory (14) -set feat_files(14) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-07/run2.feat" - -# 4D AVW data or FEAT directory (15) -set feat_files(15) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-08/run1.feat" - -# 4D AVW data or FEAT directory (16) -set feat_files(16) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-08/run2.feat" - -# 4D AVW data or FEAT directory (17) -set feat_files(17) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-09/run1.feat" - -# 4D AVW data or FEAT directory (18) -set feat_files(18) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-09/run2.feat" - -# 4D AVW data or FEAT directory (19) -set feat_files(19) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-10/run1.feat" - -# 4D AVW data or FEAT directory (20) -set feat_files(20) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-10/run2.feat" - -# 4D AVW data or FEAT directory (21) -set feat_files(21) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-11/run1.feat" - -# 4D AVW data or FEAT directory (22) -set feat_files(22) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-11/run2.feat" - -# 4D AVW data or FEAT directory (23) -set feat_files(23) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-12/run1.feat" - -# 4D AVW data or FEAT directory (24) -set feat_files(24) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-12/run2.feat" - -# 4D AVW data or FEAT directory (25) -set feat_files(25) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-13/run1.feat" - -# 4D AVW data or FEAT directory (26) -set feat_files(26) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-13/run2.feat" - -# 4D AVW data or FEAT directory (27) -set feat_files(27) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-14/run1.feat" - -# 4D AVW data or FEAT directory (28) -set feat_files(28) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-14/run2.feat" - -# 4D AVW data or FEAT directory (29) -set feat_files(29) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-15/run1.feat" - -# 4D AVW data or FEAT directory (30) -set feat_files(30) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-15/run2.feat" - -# 4D AVW data or FEAT directory (31) -set feat_files(31) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-16/run1.feat" - -# 4D AVW data or FEAT directory (32) -set feat_files(32) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-16/run2.feat" - -# 4D AVW data or FEAT directory (33) -set feat_files(33) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-17/run1.feat" - -# 4D AVW data or FEAT directory (34) -set feat_files(34) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-17/run2.feat" - -# 4D AVW data or FEAT directory (35) -set feat_files(35) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-18/run1.feat" - -# 4D AVW data or FEAT directory (36) -set feat_files(36) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-18/run2.feat" - -# 4D AVW data or FEAT directory (37) -set feat_files(37) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-19/run1.feat" - -# 4D AVW data or FEAT directory (38) -set feat_files(38) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-19/run2.feat" - -# 4D AVW data or FEAT directory (39) -set feat_files(39) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-20/run1.feat" - -# 4D AVW data or FEAT directory (40) -set feat_files(40) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-20/run2.feat" - -# 4D AVW data or FEAT directory (41) -set feat_files(41) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-21/run1.feat" - -# 4D AVW data or FEAT directory (42) -set feat_files(42) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-21/run2.feat" - -# 4D AVW data or FEAT directory (43) -set feat_files(43) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-22/run1.feat" - -# 4D AVW data or FEAT directory (44) -set feat_files(44) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-22/run2.feat" - -# 4D AVW data or FEAT directory (45) -set feat_files(45) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-23/run1.feat" - -# 4D AVW data or FEAT directory (46) -set feat_files(46) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-23/run2.feat" - -# 4D AVW data or FEAT directory (47) -set feat_files(47) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-24/run1.feat" - -# 4D AVW data or FEAT directory (48) -set feat_files(48) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-24/run2.feat" - -# 4D AVW data or FEAT directory (49) -set feat_files(49) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-25/run1.feat" - -# 4D AVW data or FEAT directory (50) -set feat_files(50) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-25/run2.feat" - -# 4D AVW data or FEAT directory (51) -set feat_files(51) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-26/run1.feat" - -# 4D AVW data or FEAT directory (52) -set feat_files(52) "/srv/scratch/yc/fsl/nipype_fsl_comp/gui/sub-26/run2.feat" - - -# Add confound EVs text file -set fmri(confoundevs) 0 - -# EV 1 title -set fmri(evtitle1) "" - -# Basic waveform shape (EV 1) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape1) 2 - -# Convolution (EV 1) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve1) 0 - -# Convolve phase (EV 1) -set fmri(convolve_phase1) 0 - -# Apply temporal filtering (EV 1) -set fmri(tempfilt_yn1) 0 - -# Add temporal derivative (EV 1) -set fmri(deriv_yn1) 0 - -# Custom EV file (EV 1) -set fmri(custom1) "dummy" - -# Orthogonalise EV 1 wrt EV 0 -set fmri(ortho1.0) 0 - -# Orthogonalise EV 1 wrt EV 1 -set fmri(ortho1.1) 0 - -# Orthogonalise EV 1 wrt EV 2 -set fmri(ortho1.2) 0 - -# Orthogonalise EV 1 wrt EV 3 -set fmri(ortho1.3) 0 - -# Orthogonalise EV 1 wrt EV 4 -set fmri(ortho1.4) 0 - -# Orthogonalise EV 1 wrt EV 5 -set fmri(ortho1.5) 0 - -# Orthogonalise EV 1 wrt EV 6 -set fmri(ortho1.6) 0 - -# Orthogonalise EV 1 wrt EV 7 -set fmri(ortho1.7) 0 - -# Orthogonalise EV 1 wrt EV 8 -set fmri(ortho1.8) 0 - -# Orthogonalise EV 1 wrt EV 9 -set fmri(ortho1.9) 0 - -# Orthogonalise EV 1 wrt EV 10 -set fmri(ortho1.10) 0 - -# Orthogonalise EV 1 wrt EV 11 -set fmri(ortho1.11) 0 - -# Orthogonalise EV 1 wrt EV 12 -set fmri(ortho1.12) 0 - -# Orthogonalise EV 1 wrt EV 13 -set fmri(ortho1.13) 0 - -# Orthogonalise EV 1 wrt EV 14 -set fmri(ortho1.14) 0 - -# Orthogonalise EV 1 wrt EV 15 -set fmri(ortho1.15) 0 - -# Orthogonalise EV 1 wrt EV 16 -set fmri(ortho1.16) 0 - -# Orthogonalise EV 1 wrt EV 17 -set fmri(ortho1.17) 0 - -# Orthogonalise EV 1 wrt EV 18 -set fmri(ortho1.18) 0 - -# Orthogonalise EV 1 wrt EV 19 -set fmri(ortho1.19) 0 - -# Orthogonalise EV 1 wrt EV 20 -set fmri(ortho1.20) 0 - -# Orthogonalise EV 1 wrt EV 21 -set fmri(ortho1.21) 0 - -# Orthogonalise EV 1 wrt EV 22 -set fmri(ortho1.22) 0 - -# Orthogonalise EV 1 wrt EV 23 -set fmri(ortho1.23) 0 - -# Orthogonalise EV 1 wrt EV 24 -set fmri(ortho1.24) 0 - -# Orthogonalise EV 1 wrt EV 25 -set fmri(ortho1.25) 0 - -# Orthogonalise EV 1 wrt EV 26 -set fmri(ortho1.26) 0 - -# Higher-level EV value for EV 1 and input 1 -set fmri(evg1.1) 1 - -# Higher-level EV value for EV 1 and input 2 -set fmri(evg2.1) 1.0 - -# Higher-level EV value for EV 1 and input 3 -set fmri(evg3.1) 0 - -# Higher-level EV value for EV 1 and input 4 -set fmri(evg4.1) 0 - -# Higher-level EV value for EV 1 and input 5 -set fmri(evg5.1) 0 - -# Higher-level EV value for EV 1 and input 6 -set fmri(evg6.1) 0 - -# Higher-level EV value for EV 1 and input 7 -set fmri(evg7.1) 0 - -# Higher-level EV value for EV 1 and input 8 -set fmri(evg8.1) 0 - -# Higher-level EV value for EV 1 and input 9 -set fmri(evg9.1) 0 - -# Higher-level EV value for EV 1 and input 10 -set fmri(evg10.1) 0 - -# Higher-level EV value for EV 1 and input 11 -set fmri(evg11.1) 0 - -# Higher-level EV value for EV 1 and input 12 -set fmri(evg12.1) 0 - -# Higher-level EV value for EV 1 and input 13 -set fmri(evg13.1) 0 - -# Higher-level EV value for EV 1 and input 14 -set fmri(evg14.1) 0 - -# Higher-level EV value for EV 1 and input 15 -set fmri(evg15.1) 0 - -# Higher-level EV value for EV 1 and input 16 -set fmri(evg16.1) 0 - -# Higher-level EV value for EV 1 and input 17 -set fmri(evg17.1) 0 - -# Higher-level EV value for EV 1 and input 18 -set fmri(evg18.1) 0 - -# Higher-level EV value for EV 1 and input 19 -set fmri(evg19.1) 0 - -# Higher-level EV value for EV 1 and input 20 -set fmri(evg20.1) 0 - -# Higher-level EV value for EV 1 and input 21 -set fmri(evg21.1) 0 - -# Higher-level EV value for EV 1 and input 22 -set fmri(evg22.1) 0 - -# Higher-level EV value for EV 1 and input 23 -set fmri(evg23.1) 0 - -# Higher-level EV value for EV 1 and input 24 -set fmri(evg24.1) 0 - -# Higher-level EV value for EV 1 and input 25 -set fmri(evg25.1) 0 - -# Higher-level EV value for EV 1 and input 26 -set fmri(evg26.1) 0 - -# Higher-level EV value for EV 1 and input 27 -set fmri(evg27.1) 0 - -# Higher-level EV value for EV 1 and input 28 -set fmri(evg28.1) 0 - -# Higher-level EV value for EV 1 and input 29 -set fmri(evg29.1) 0 - -# Higher-level EV value for EV 1 and input 30 -set fmri(evg30.1) 0 - -# Higher-level EV value for EV 1 and input 31 -set fmri(evg31.1) 0 - -# Higher-level EV value for EV 1 and input 32 -set fmri(evg32.1) 0 - -# Higher-level EV value for EV 1 and input 33 -set fmri(evg33.1) 0 - -# Higher-level EV value for EV 1 and input 34 -set fmri(evg34.1) 0 - -# Higher-level EV value for EV 1 and input 35 -set fmri(evg35.1) 0 - -# Higher-level EV value for EV 1 and input 36 -set fmri(evg36.1) 0 - -# Higher-level EV value for EV 1 and input 37 -set fmri(evg37.1) 0 - -# Higher-level EV value for EV 1 and input 38 -set fmri(evg38.1) 0 - -# Higher-level EV value for EV 1 and input 39 -set fmri(evg39.1) 0 - -# Higher-level EV value for EV 1 and input 40 -set fmri(evg40.1) 0 - -# Higher-level EV value for EV 1 and input 41 -set fmri(evg41.1) 0 - -# Higher-level EV value for EV 1 and input 42 -set fmri(evg42.1) 0 - -# Higher-level EV value for EV 1 and input 43 -set fmri(evg43.1) 0 - -# Higher-level EV value for EV 1 and input 44 -set fmri(evg44.1) 0 - -# Higher-level EV value for EV 1 and input 45 -set fmri(evg45.1) 0 - -# Higher-level EV value for EV 1 and input 46 -set fmri(evg46.1) 0 - -# Higher-level EV value for EV 1 and input 47 -set fmri(evg47.1) 0 - -# Higher-level EV value for EV 1 and input 48 -set fmri(evg48.1) 0 - -# Higher-level EV value for EV 1 and input 49 -set fmri(evg49.1) 0 - -# Higher-level EV value for EV 1 and input 50 -set fmri(evg50.1) 0 - -# Higher-level EV value for EV 1 and input 51 -set fmri(evg51.1) 0 - -# Higher-level EV value for EV 1 and input 52 -set fmri(evg52.1) 0 - -# EV 2 title -set fmri(evtitle2) "" - -# Basic waveform shape (EV 2) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape2) 2 - -# Convolution (EV 2) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve2) 0 - -# Convolve phase (EV 2) -set fmri(convolve_phase2) 0 - -# Apply temporal filtering (EV 2) -set fmri(tempfilt_yn2) 0 - -# Add temporal derivative (EV 2) -set fmri(deriv_yn2) 0 - -# Custom EV file (EV 2) -set fmri(custom2) "dummy" - -# Orthogonalise EV 2 wrt EV 0 -set fmri(ortho2.0) 0 - -# Orthogonalise EV 2 wrt EV 1 -set fmri(ortho2.1) 0 - -# Orthogonalise EV 2 wrt EV 2 -set fmri(ortho2.2) 0 - -# Orthogonalise EV 2 wrt EV 3 -set fmri(ortho2.3) 0 - -# Orthogonalise EV 2 wrt EV 4 -set fmri(ortho2.4) 0 - -# Orthogonalise EV 2 wrt EV 5 -set fmri(ortho2.5) 0 - -# Orthogonalise EV 2 wrt EV 6 -set fmri(ortho2.6) 0 - -# Orthogonalise EV 2 wrt EV 7 -set fmri(ortho2.7) 0 - -# Orthogonalise EV 2 wrt EV 8 -set fmri(ortho2.8) 0 - -# Orthogonalise EV 2 wrt EV 9 -set fmri(ortho2.9) 0 - -# Orthogonalise EV 2 wrt EV 10 -set fmri(ortho2.10) 0 - -# Orthogonalise EV 2 wrt EV 11 -set fmri(ortho2.11) 0 - -# Orthogonalise EV 2 wrt EV 12 -set fmri(ortho2.12) 0 - -# Orthogonalise EV 2 wrt EV 13 -set fmri(ortho2.13) 0 - -# Orthogonalise EV 2 wrt EV 14 -set fmri(ortho2.14) 0 - -# Orthogonalise EV 2 wrt EV 15 -set fmri(ortho2.15) 0 - -# Orthogonalise EV 2 wrt EV 16 -set fmri(ortho2.16) 0 - -# Orthogonalise EV 2 wrt EV 17 -set fmri(ortho2.17) 0 - -# Orthogonalise EV 2 wrt EV 18 -set fmri(ortho2.18) 0 - -# Orthogonalise EV 2 wrt EV 19 -set fmri(ortho2.19) 0 - -# Orthogonalise EV 2 wrt EV 20 -set fmri(ortho2.20) 0 - -# Orthogonalise EV 2 wrt EV 21 -set fmri(ortho2.21) 0 - -# Orthogonalise EV 2 wrt EV 22 -set fmri(ortho2.22) 0 - -# Orthogonalise EV 2 wrt EV 23 -set fmri(ortho2.23) 0 - -# Orthogonalise EV 2 wrt EV 24 -set fmri(ortho2.24) 0 - -# Orthogonalise EV 2 wrt EV 25 -set fmri(ortho2.25) 0 - -# Orthogonalise EV 2 wrt EV 26 -set fmri(ortho2.26) 0 - -# Higher-level EV value for EV 2 and input 1 -set fmri(evg1.2) 0 - -# Higher-level EV value for EV 2 and input 2 -set fmri(evg2.2) 0 - -# Higher-level EV value for EV 2 and input 3 -set fmri(evg3.2) 1.0 - -# Higher-level EV value for EV 2 and input 4 -set fmri(evg4.2) 1.0 - -# Higher-level EV value for EV 2 and input 5 -set fmri(evg5.2) 0 - -# Higher-level EV value for EV 2 and input 6 -set fmri(evg6.2) 0 - -# Higher-level EV value for EV 2 and input 7 -set fmri(evg7.2) 0 - -# Higher-level EV value for EV 2 and input 8 -set fmri(evg8.2) 0 - -# Higher-level EV value for EV 2 and input 9 -set fmri(evg9.2) 0 - -# Higher-level EV value for EV 2 and input 10 -set fmri(evg10.2) 0 - -# Higher-level EV value for EV 2 and input 11 -set fmri(evg11.2) 0 - -# Higher-level EV value for EV 2 and input 12 -set fmri(evg12.2) 0 - -# Higher-level EV value for EV 2 and input 13 -set fmri(evg13.2) 0 - -# Higher-level EV value for EV 2 and input 14 -set fmri(evg14.2) 0 - -# Higher-level EV value for EV 2 and input 15 -set fmri(evg15.2) 0 - -# Higher-level EV value for EV 2 and input 16 -set fmri(evg16.2) 0 - -# Higher-level EV value for EV 2 and input 17 -set fmri(evg17.2) 0 - -# Higher-level EV value for EV 2 and input 18 -set fmri(evg18.2) 0 - -# Higher-level EV value for EV 2 and input 19 -set fmri(evg19.2) 0 - -# Higher-level EV value for EV 2 and input 20 -set fmri(evg20.2) 0 - -# Higher-level EV value for EV 2 and input 21 -set fmri(evg21.2) 0 - -# Higher-level EV value for EV 2 and input 22 -set fmri(evg22.2) 0 - -# Higher-level EV value for EV 2 and input 23 -set fmri(evg23.2) 0 - -# Higher-level EV value for EV 2 and input 24 -set fmri(evg24.2) 0 - -# Higher-level EV value for EV 2 and input 25 -set fmri(evg25.2) 0 - -# Higher-level EV value for EV 2 and input 26 -set fmri(evg26.2) 0 - -# Higher-level EV value for EV 2 and input 27 -set fmri(evg27.2) 0 - -# Higher-level EV value for EV 2 and input 28 -set fmri(evg28.2) 0 - -# Higher-level EV value for EV 2 and input 29 -set fmri(evg29.2) 0 - -# Higher-level EV value for EV 2 and input 30 -set fmri(evg30.2) 0 - -# Higher-level EV value for EV 2 and input 31 -set fmri(evg31.2) 0 - -# Higher-level EV value for EV 2 and input 32 -set fmri(evg32.2) 0 - -# Higher-level EV value for EV 2 and input 33 -set fmri(evg33.2) 0 - -# Higher-level EV value for EV 2 and input 34 -set fmri(evg34.2) 0 - -# Higher-level EV value for EV 2 and input 35 -set fmri(evg35.2) 0 - -# Higher-level EV value for EV 2 and input 36 -set fmri(evg36.2) 0 - -# Higher-level EV value for EV 2 and input 37 -set fmri(evg37.2) 0 - -# Higher-level EV value for EV 2 and input 38 -set fmri(evg38.2) 0 - -# Higher-level EV value for EV 2 and input 39 -set fmri(evg39.2) 0 - -# Higher-level EV value for EV 2 and input 40 -set fmri(evg40.2) 0 - -# Higher-level EV value for EV 2 and input 41 -set fmri(evg41.2) 0 - -# Higher-level EV value for EV 2 and input 42 -set fmri(evg42.2) 0 - -# Higher-level EV value for EV 2 and input 43 -set fmri(evg43.2) 0 - -# Higher-level EV value for EV 2 and input 44 -set fmri(evg44.2) 0 - -# Higher-level EV value for EV 2 and input 45 -set fmri(evg45.2) 0 - -# Higher-level EV value for EV 2 and input 46 -set fmri(evg46.2) 0 - -# Higher-level EV value for EV 2 and input 47 -set fmri(evg47.2) 0 - -# Higher-level EV value for EV 2 and input 48 -set fmri(evg48.2) 0 - -# Higher-level EV value for EV 2 and input 49 -set fmri(evg49.2) 0 - -# Higher-level EV value for EV 2 and input 50 -set fmri(evg50.2) 0 - -# Higher-level EV value for EV 2 and input 51 -set fmri(evg51.2) 0 - -# Higher-level EV value for EV 2 and input 52 -set fmri(evg52.2) 0 - -# EV 3 title -set fmri(evtitle3) "" - -# Basic waveform shape (EV 3) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape3) 2 - -# Convolution (EV 3) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve3) 0 - -# Convolve phase (EV 3) -set fmri(convolve_phase3) 0 - -# Apply temporal filtering (EV 3) -set fmri(tempfilt_yn3) 0 - -# Add temporal derivative (EV 3) -set fmri(deriv_yn3) 0 - -# Custom EV file (EV 3) -set fmri(custom3) "dummy" - -# Orthogonalise EV 3 wrt EV 0 -set fmri(ortho3.0) 0 - -# Orthogonalise EV 3 wrt EV 1 -set fmri(ortho3.1) 0 - -# Orthogonalise EV 3 wrt EV 2 -set fmri(ortho3.2) 0 - -# Orthogonalise EV 3 wrt EV 3 -set fmri(ortho3.3) 0 - -# Orthogonalise EV 3 wrt EV 4 -set fmri(ortho3.4) 0 - -# Orthogonalise EV 3 wrt EV 5 -set fmri(ortho3.5) 0 - -# Orthogonalise EV 3 wrt EV 6 -set fmri(ortho3.6) 0 - -# Orthogonalise EV 3 wrt EV 7 -set fmri(ortho3.7) 0 - -# Orthogonalise EV 3 wrt EV 8 -set fmri(ortho3.8) 0 - -# Orthogonalise EV 3 wrt EV 9 -set fmri(ortho3.9) 0 - -# Orthogonalise EV 3 wrt EV 10 -set fmri(ortho3.10) 0 - -# Orthogonalise EV 3 wrt EV 11 -set fmri(ortho3.11) 0 - -# Orthogonalise EV 3 wrt EV 12 -set fmri(ortho3.12) 0 - -# Orthogonalise EV 3 wrt EV 13 -set fmri(ortho3.13) 0 - -# Orthogonalise EV 3 wrt EV 14 -set fmri(ortho3.14) 0 - -# Orthogonalise EV 3 wrt EV 15 -set fmri(ortho3.15) 0 - -# Orthogonalise EV 3 wrt EV 16 -set fmri(ortho3.16) 0 - -# Orthogonalise EV 3 wrt EV 17 -set fmri(ortho3.17) 0 - -# Orthogonalise EV 3 wrt EV 18 -set fmri(ortho3.18) 0 - -# Orthogonalise EV 3 wrt EV 19 -set fmri(ortho3.19) 0 - -# Orthogonalise EV 3 wrt EV 20 -set fmri(ortho3.20) 0 - -# Orthogonalise EV 3 wrt EV 21 -set fmri(ortho3.21) 0 - -# Orthogonalise EV 3 wrt EV 22 -set fmri(ortho3.22) 0 - -# Orthogonalise EV 3 wrt EV 23 -set fmri(ortho3.23) 0 - -# Orthogonalise EV 3 wrt EV 24 -set fmri(ortho3.24) 0 - -# Orthogonalise EV 3 wrt EV 25 -set fmri(ortho3.25) 0 - -# Orthogonalise EV 3 wrt EV 26 -set fmri(ortho3.26) 0 - -# Higher-level EV value for EV 3 and input 1 -set fmri(evg1.3) 0 - -# Higher-level EV value for EV 3 and input 2 -set fmri(evg2.3) 0 - -# Higher-level EV value for EV 3 and input 3 -set fmri(evg3.3) 0 - -# Higher-level EV value for EV 3 and input 4 -set fmri(evg4.3) 0 - -# Higher-level EV value for EV 3 and input 5 -set fmri(evg5.3) 1.0 - -# Higher-level EV value for EV 3 and input 6 -set fmri(evg6.3) 1.0 - -# Higher-level EV value for EV 3 and input 7 -set fmri(evg7.3) 0 - -# Higher-level EV value for EV 3 and input 8 -set fmri(evg8.3) 0 - -# Higher-level EV value for EV 3 and input 9 -set fmri(evg9.3) 0 - -# Higher-level EV value for EV 3 and input 10 -set fmri(evg10.3) 0 - -# Higher-level EV value for EV 3 and input 11 -set fmri(evg11.3) 0 - -# Higher-level EV value for EV 3 and input 12 -set fmri(evg12.3) 0 - -# Higher-level EV value for EV 3 and input 13 -set fmri(evg13.3) 0 - -# Higher-level EV value for EV 3 and input 14 -set fmri(evg14.3) 0 - -# Higher-level EV value for EV 3 and input 15 -set fmri(evg15.3) 0 - -# Higher-level EV value for EV 3 and input 16 -set fmri(evg16.3) 0 - -# Higher-level EV value for EV 3 and input 17 -set fmri(evg17.3) 0 - -# Higher-level EV value for EV 3 and input 18 -set fmri(evg18.3) 0 - -# Higher-level EV value for EV 3 and input 19 -set fmri(evg19.3) 0 - -# Higher-level EV value for EV 3 and input 20 -set fmri(evg20.3) 0 - -# Higher-level EV value for EV 3 and input 21 -set fmri(evg21.3) 0 - -# Higher-level EV value for EV 3 and input 22 -set fmri(evg22.3) 0 - -# Higher-level EV value for EV 3 and input 23 -set fmri(evg23.3) 0 - -# Higher-level EV value for EV 3 and input 24 -set fmri(evg24.3) 0 - -# Higher-level EV value for EV 3 and input 25 -set fmri(evg25.3) 0 - -# Higher-level EV value for EV 3 and input 26 -set fmri(evg26.3) 0 - -# Higher-level EV value for EV 3 and input 27 -set fmri(evg27.3) 0 - -# Higher-level EV value for EV 3 and input 28 -set fmri(evg28.3) 0 - -# Higher-level EV value for EV 3 and input 29 -set fmri(evg29.3) 0 - -# Higher-level EV value for EV 3 and input 30 -set fmri(evg30.3) 0 - -# Higher-level EV value for EV 3 and input 31 -set fmri(evg31.3) 0 - -# Higher-level EV value for EV 3 and input 32 -set fmri(evg32.3) 0 - -# Higher-level EV value for EV 3 and input 33 -set fmri(evg33.3) 0 - -# Higher-level EV value for EV 3 and input 34 -set fmri(evg34.3) 0 - -# Higher-level EV value for EV 3 and input 35 -set fmri(evg35.3) 0 - -# Higher-level EV value for EV 3 and input 36 -set fmri(evg36.3) 0 - -# Higher-level EV value for EV 3 and input 37 -set fmri(evg37.3) 0 - -# Higher-level EV value for EV 3 and input 38 -set fmri(evg38.3) 0 - -# Higher-level EV value for EV 3 and input 39 -set fmri(evg39.3) 0 - -# Higher-level EV value for EV 3 and input 40 -set fmri(evg40.3) 0 - -# Higher-level EV value for EV 3 and input 41 -set fmri(evg41.3) 0 - -# Higher-level EV value for EV 3 and input 42 -set fmri(evg42.3) 0 - -# Higher-level EV value for EV 3 and input 43 -set fmri(evg43.3) 0 - -# Higher-level EV value for EV 3 and input 44 -set fmri(evg44.3) 0 - -# Higher-level EV value for EV 3 and input 45 -set fmri(evg45.3) 0 - -# Higher-level EV value for EV 3 and input 46 -set fmri(evg46.3) 0 - -# Higher-level EV value for EV 3 and input 47 -set fmri(evg47.3) 0 - -# Higher-level EV value for EV 3 and input 48 -set fmri(evg48.3) 0 - -# Higher-level EV value for EV 3 and input 49 -set fmri(evg49.3) 0 - -# Higher-level EV value for EV 3 and input 50 -set fmri(evg50.3) 0 - -# Higher-level EV value for EV 3 and input 51 -set fmri(evg51.3) 0 - -# Higher-level EV value for EV 3 and input 52 -set fmri(evg52.3) 0 - -# EV 4 title -set fmri(evtitle4) "" - -# Basic waveform shape (EV 4) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape4) 2 - -# Convolution (EV 4) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve4) 0 - -# Convolve phase (EV 4) -set fmri(convolve_phase4) 0 - -# Apply temporal filtering (EV 4) -set fmri(tempfilt_yn4) 0 - -# Add temporal derivative (EV 4) -set fmri(deriv_yn4) 0 - -# Custom EV file (EV 4) -set fmri(custom4) "dummy" - -# Orthogonalise EV 4 wrt EV 0 -set fmri(ortho4.0) 0 - -# Orthogonalise EV 4 wrt EV 1 -set fmri(ortho4.1) 0 - -# Orthogonalise EV 4 wrt EV 2 -set fmri(ortho4.2) 0 - -# Orthogonalise EV 4 wrt EV 3 -set fmri(ortho4.3) 0 - -# Orthogonalise EV 4 wrt EV 4 -set fmri(ortho4.4) 0 - -# Orthogonalise EV 4 wrt EV 5 -set fmri(ortho4.5) 0 - -# Orthogonalise EV 4 wrt EV 6 -set fmri(ortho4.6) 0 - -# Orthogonalise EV 4 wrt EV 7 -set fmri(ortho4.7) 0 - -# Orthogonalise EV 4 wrt EV 8 -set fmri(ortho4.8) 0 - -# Orthogonalise EV 4 wrt EV 9 -set fmri(ortho4.9) 0 - -# Orthogonalise EV 4 wrt EV 10 -set fmri(ortho4.10) 0 - -# Orthogonalise EV 4 wrt EV 11 -set fmri(ortho4.11) 0 - -# Orthogonalise EV 4 wrt EV 12 -set fmri(ortho4.12) 0 - -# Orthogonalise EV 4 wrt EV 13 -set fmri(ortho4.13) 0 - -# Orthogonalise EV 4 wrt EV 14 -set fmri(ortho4.14) 0 - -# Orthogonalise EV 4 wrt EV 15 -set fmri(ortho4.15) 0 - -# Orthogonalise EV 4 wrt EV 16 -set fmri(ortho4.16) 0 - -# Orthogonalise EV 4 wrt EV 17 -set fmri(ortho4.17) 0 - -# Orthogonalise EV 4 wrt EV 18 -set fmri(ortho4.18) 0 - -# Orthogonalise EV 4 wrt EV 19 -set fmri(ortho4.19) 0 - -# Orthogonalise EV 4 wrt EV 20 -set fmri(ortho4.20) 0 - -# Orthogonalise EV 4 wrt EV 21 -set fmri(ortho4.21) 0 - -# Orthogonalise EV 4 wrt EV 22 -set fmri(ortho4.22) 0 - -# Orthogonalise EV 4 wrt EV 23 -set fmri(ortho4.23) 0 - -# Orthogonalise EV 4 wrt EV 24 -set fmri(ortho4.24) 0 - -# Orthogonalise EV 4 wrt EV 25 -set fmri(ortho4.25) 0 - -# Orthogonalise EV 4 wrt EV 26 -set fmri(ortho4.26) 0 - -# Higher-level EV value for EV 4 and input 1 -set fmri(evg1.4) 0 - -# Higher-level EV value for EV 4 and input 2 -set fmri(evg2.4) 0 - -# Higher-level EV value for EV 4 and input 3 -set fmri(evg3.4) 0 - -# Higher-level EV value for EV 4 and input 4 -set fmri(evg4.4) 0 - -# Higher-level EV value for EV 4 and input 5 -set fmri(evg5.4) 0 - -# Higher-level EV value for EV 4 and input 6 -set fmri(evg6.4) 0 - -# Higher-level EV value for EV 4 and input 7 -set fmri(evg7.4) 1.0 - -# Higher-level EV value for EV 4 and input 8 -set fmri(evg8.4) 1.0 - -# Higher-level EV value for EV 4 and input 9 -set fmri(evg9.4) 0 - -# Higher-level EV value for EV 4 and input 10 -set fmri(evg10.4) 0 - -# Higher-level EV value for EV 4 and input 11 -set fmri(evg11.4) 0 - -# Higher-level EV value for EV 4 and input 12 -set fmri(evg12.4) 0 - -# Higher-level EV value for EV 4 and input 13 -set fmri(evg13.4) 0 - -# Higher-level EV value for EV 4 and input 14 -set fmri(evg14.4) 0 - -# Higher-level EV value for EV 4 and input 15 -set fmri(evg15.4) 0 - -# Higher-level EV value for EV 4 and input 16 -set fmri(evg16.4) 0 - -# Higher-level EV value for EV 4 and input 17 -set fmri(evg17.4) 0 - -# Higher-level EV value for EV 4 and input 18 -set fmri(evg18.4) 0 - -# Higher-level EV value for EV 4 and input 19 -set fmri(evg19.4) 0 - -# Higher-level EV value for EV 4 and input 20 -set fmri(evg20.4) 0 - -# Higher-level EV value for EV 4 and input 21 -set fmri(evg21.4) 0 - -# Higher-level EV value for EV 4 and input 22 -set fmri(evg22.4) 0 - -# Higher-level EV value for EV 4 and input 23 -set fmri(evg23.4) 0 - -# Higher-level EV value for EV 4 and input 24 -set fmri(evg24.4) 0 - -# Higher-level EV value for EV 4 and input 25 -set fmri(evg25.4) 0 - -# Higher-level EV value for EV 4 and input 26 -set fmri(evg26.4) 0 - -# Higher-level EV value for EV 4 and input 27 -set fmri(evg27.4) 0 - -# Higher-level EV value for EV 4 and input 28 -set fmri(evg28.4) 0 - -# Higher-level EV value for EV 4 and input 29 -set fmri(evg29.4) 0 - -# Higher-level EV value for EV 4 and input 30 -set fmri(evg30.4) 0 - -# Higher-level EV value for EV 4 and input 31 -set fmri(evg31.4) 0 - -# Higher-level EV value for EV 4 and input 32 -set fmri(evg32.4) 0 - -# Higher-level EV value for EV 4 and input 33 -set fmri(evg33.4) 0 - -# Higher-level EV value for EV 4 and input 34 -set fmri(evg34.4) 0 - -# Higher-level EV value for EV 4 and input 35 -set fmri(evg35.4) 0 - -# Higher-level EV value for EV 4 and input 36 -set fmri(evg36.4) 0 - -# Higher-level EV value for EV 4 and input 37 -set fmri(evg37.4) 0 - -# Higher-level EV value for EV 4 and input 38 -set fmri(evg38.4) 0 - -# Higher-level EV value for EV 4 and input 39 -set fmri(evg39.4) 0 - -# Higher-level EV value for EV 4 and input 40 -set fmri(evg40.4) 0 - -# Higher-level EV value for EV 4 and input 41 -set fmri(evg41.4) 0 - -# Higher-level EV value for EV 4 and input 42 -set fmri(evg42.4) 0 - -# Higher-level EV value for EV 4 and input 43 -set fmri(evg43.4) 0 - -# Higher-level EV value for EV 4 and input 44 -set fmri(evg44.4) 0 - -# Higher-level EV value for EV 4 and input 45 -set fmri(evg45.4) 0 - -# Higher-level EV value for EV 4 and input 46 -set fmri(evg46.4) 0 - -# Higher-level EV value for EV 4 and input 47 -set fmri(evg47.4) 0 - -# Higher-level EV value for EV 4 and input 48 -set fmri(evg48.4) 0 - -# Higher-level EV value for EV 4 and input 49 -set fmri(evg49.4) 0 - -# Higher-level EV value for EV 4 and input 50 -set fmri(evg50.4) 0 - -# Higher-level EV value for EV 4 and input 51 -set fmri(evg51.4) 0 - -# Higher-level EV value for EV 4 and input 52 -set fmri(evg52.4) 0 - -# EV 5 title -set fmri(evtitle5) "" - -# Basic waveform shape (EV 5) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape5) 2 - -# Convolution (EV 5) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve5) 0 - -# Convolve phase (EV 5) -set fmri(convolve_phase5) 0 - -# Apply temporal filtering (EV 5) -set fmri(tempfilt_yn5) 0 - -# Add temporal derivative (EV 5) -set fmri(deriv_yn5) 0 - -# Custom EV file (EV 5) -set fmri(custom5) "dummy" - -# Orthogonalise EV 5 wrt EV 0 -set fmri(ortho5.0) 0 - -# Orthogonalise EV 5 wrt EV 1 -set fmri(ortho5.1) 0 - -# Orthogonalise EV 5 wrt EV 2 -set fmri(ortho5.2) 0 - -# Orthogonalise EV 5 wrt EV 3 -set fmri(ortho5.3) 0 - -# Orthogonalise EV 5 wrt EV 4 -set fmri(ortho5.4) 0 - -# Orthogonalise EV 5 wrt EV 5 -set fmri(ortho5.5) 0 - -# Orthogonalise EV 5 wrt EV 6 -set fmri(ortho5.6) 0 - -# Orthogonalise EV 5 wrt EV 7 -set fmri(ortho5.7) 0 - -# Orthogonalise EV 5 wrt EV 8 -set fmri(ortho5.8) 0 - -# Orthogonalise EV 5 wrt EV 9 -set fmri(ortho5.9) 0 - -# Orthogonalise EV 5 wrt EV 10 -set fmri(ortho5.10) 0 - -# Orthogonalise EV 5 wrt EV 11 -set fmri(ortho5.11) 0 - -# Orthogonalise EV 5 wrt EV 12 -set fmri(ortho5.12) 0 - -# Orthogonalise EV 5 wrt EV 13 -set fmri(ortho5.13) 0 - -# Orthogonalise EV 5 wrt EV 14 -set fmri(ortho5.14) 0 - -# Orthogonalise EV 5 wrt EV 15 -set fmri(ortho5.15) 0 - -# Orthogonalise EV 5 wrt EV 16 -set fmri(ortho5.16) 0 - -# Orthogonalise EV 5 wrt EV 17 -set fmri(ortho5.17) 0 - -# Orthogonalise EV 5 wrt EV 18 -set fmri(ortho5.18) 0 - -# Orthogonalise EV 5 wrt EV 19 -set fmri(ortho5.19) 0 - -# Orthogonalise EV 5 wrt EV 20 -set fmri(ortho5.20) 0 - -# Orthogonalise EV 5 wrt EV 21 -set fmri(ortho5.21) 0 - -# Orthogonalise EV 5 wrt EV 22 -set fmri(ortho5.22) 0 - -# Orthogonalise EV 5 wrt EV 23 -set fmri(ortho5.23) 0 - -# Orthogonalise EV 5 wrt EV 24 -set fmri(ortho5.24) 0 - -# Orthogonalise EV 5 wrt EV 25 -set fmri(ortho5.25) 0 - -# Orthogonalise EV 5 wrt EV 26 -set fmri(ortho5.26) 0 - -# Higher-level EV value for EV 5 and input 1 -set fmri(evg1.5) 0 - -# Higher-level EV value for EV 5 and input 2 -set fmri(evg2.5) 0 - -# Higher-level EV value for EV 5 and input 3 -set fmri(evg3.5) 0 - -# Higher-level EV value for EV 5 and input 4 -set fmri(evg4.5) 0 - -# Higher-level EV value for EV 5 and input 5 -set fmri(evg5.5) 0 - -# Higher-level EV value for EV 5 and input 6 -set fmri(evg6.5) 0 - -# Higher-level EV value for EV 5 and input 7 -set fmri(evg7.5) 0 - -# Higher-level EV value for EV 5 and input 8 -set fmri(evg8.5) 0 - -# Higher-level EV value for EV 5 and input 9 -set fmri(evg9.5) 1.0 - -# Higher-level EV value for EV 5 and input 10 -set fmri(evg10.5) 1.0 - -# Higher-level EV value for EV 5 and input 11 -set fmri(evg11.5) 0 - -# Higher-level EV value for EV 5 and input 12 -set fmri(evg12.5) 0 - -# Higher-level EV value for EV 5 and input 13 -set fmri(evg13.5) 0 - -# Higher-level EV value for EV 5 and input 14 -set fmri(evg14.5) 0 - -# Higher-level EV value for EV 5 and input 15 -set fmri(evg15.5) 0 - -# Higher-level EV value for EV 5 and input 16 -set fmri(evg16.5) 0 - -# Higher-level EV value for EV 5 and input 17 -set fmri(evg17.5) 0 - -# Higher-level EV value for EV 5 and input 18 -set fmri(evg18.5) 0 - -# Higher-level EV value for EV 5 and input 19 -set fmri(evg19.5) 0 - -# Higher-level EV value for EV 5 and input 20 -set fmri(evg20.5) 0 - -# Higher-level EV value for EV 5 and input 21 -set fmri(evg21.5) 0 - -# Higher-level EV value for EV 5 and input 22 -set fmri(evg22.5) 0 - -# Higher-level EV value for EV 5 and input 23 -set fmri(evg23.5) 0 - -# Higher-level EV value for EV 5 and input 24 -set fmri(evg24.5) 0 - -# Higher-level EV value for EV 5 and input 25 -set fmri(evg25.5) 0 - -# Higher-level EV value for EV 5 and input 26 -set fmri(evg26.5) 0 - -# Higher-level EV value for EV 5 and input 27 -set fmri(evg27.5) 0 - -# Higher-level EV value for EV 5 and input 28 -set fmri(evg28.5) 0 - -# Higher-level EV value for EV 5 and input 29 -set fmri(evg29.5) 0 - -# Higher-level EV value for EV 5 and input 30 -set fmri(evg30.5) 0 - -# Higher-level EV value for EV 5 and input 31 -set fmri(evg31.5) 0 - -# Higher-level EV value for EV 5 and input 32 -set fmri(evg32.5) 0 - -# Higher-level EV value for EV 5 and input 33 -set fmri(evg33.5) 0 - -# Higher-level EV value for EV 5 and input 34 -set fmri(evg34.5) 0 - -# Higher-level EV value for EV 5 and input 35 -set fmri(evg35.5) 0 - -# Higher-level EV value for EV 5 and input 36 -set fmri(evg36.5) 0 - -# Higher-level EV value for EV 5 and input 37 -set fmri(evg37.5) 0 - -# Higher-level EV value for EV 5 and input 38 -set fmri(evg38.5) 0 - -# Higher-level EV value for EV 5 and input 39 -set fmri(evg39.5) 0 - -# Higher-level EV value for EV 5 and input 40 -set fmri(evg40.5) 0 - -# Higher-level EV value for EV 5 and input 41 -set fmri(evg41.5) 0 - -# Higher-level EV value for EV 5 and input 42 -set fmri(evg42.5) 0 - -# Higher-level EV value for EV 5 and input 43 -set fmri(evg43.5) 0 - -# Higher-level EV value for EV 5 and input 44 -set fmri(evg44.5) 0 - -# Higher-level EV value for EV 5 and input 45 -set fmri(evg45.5) 0 - -# Higher-level EV value for EV 5 and input 46 -set fmri(evg46.5) 0 - -# Higher-level EV value for EV 5 and input 47 -set fmri(evg47.5) 0 - -# Higher-level EV value for EV 5 and input 48 -set fmri(evg48.5) 0 - -# Higher-level EV value for EV 5 and input 49 -set fmri(evg49.5) 0 - -# Higher-level EV value for EV 5 and input 50 -set fmri(evg50.5) 0 - -# Higher-level EV value for EV 5 and input 51 -set fmri(evg51.5) 0 - -# Higher-level EV value for EV 5 and input 52 -set fmri(evg52.5) 0 - -# EV 6 title -set fmri(evtitle6) "" - -# Basic waveform shape (EV 6) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape6) 2 - -# Convolution (EV 6) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve6) 0 - -# Convolve phase (EV 6) -set fmri(convolve_phase6) 0 - -# Apply temporal filtering (EV 6) -set fmri(tempfilt_yn6) 0 - -# Add temporal derivative (EV 6) -set fmri(deriv_yn6) 0 - -# Custom EV file (EV 6) -set fmri(custom6) "dummy" - -# Orthogonalise EV 6 wrt EV 0 -set fmri(ortho6.0) 0 - -# Orthogonalise EV 6 wrt EV 1 -set fmri(ortho6.1) 0 - -# Orthogonalise EV 6 wrt EV 2 -set fmri(ortho6.2) 0 - -# Orthogonalise EV 6 wrt EV 3 -set fmri(ortho6.3) 0 - -# Orthogonalise EV 6 wrt EV 4 -set fmri(ortho6.4) 0 - -# Orthogonalise EV 6 wrt EV 5 -set fmri(ortho6.5) 0 - -# Orthogonalise EV 6 wrt EV 6 -set fmri(ortho6.6) 0 - -# Orthogonalise EV 6 wrt EV 7 -set fmri(ortho6.7) 0 - -# Orthogonalise EV 6 wrt EV 8 -set fmri(ortho6.8) 0 - -# Orthogonalise EV 6 wrt EV 9 -set fmri(ortho6.9) 0 - -# Orthogonalise EV 6 wrt EV 10 -set fmri(ortho6.10) 0 - -# Orthogonalise EV 6 wrt EV 11 -set fmri(ortho6.11) 0 - -# Orthogonalise EV 6 wrt EV 12 -set fmri(ortho6.12) 0 - -# Orthogonalise EV 6 wrt EV 13 -set fmri(ortho6.13) 0 - -# Orthogonalise EV 6 wrt EV 14 -set fmri(ortho6.14) 0 - -# Orthogonalise EV 6 wrt EV 15 -set fmri(ortho6.15) 0 - -# Orthogonalise EV 6 wrt EV 16 -set fmri(ortho6.16) 0 - -# Orthogonalise EV 6 wrt EV 17 -set fmri(ortho6.17) 0 - -# Orthogonalise EV 6 wrt EV 18 -set fmri(ortho6.18) 0 - -# Orthogonalise EV 6 wrt EV 19 -set fmri(ortho6.19) 0 - -# Orthogonalise EV 6 wrt EV 20 -set fmri(ortho6.20) 0 - -# Orthogonalise EV 6 wrt EV 21 -set fmri(ortho6.21) 0 - -# Orthogonalise EV 6 wrt EV 22 -set fmri(ortho6.22) 0 - -# Orthogonalise EV 6 wrt EV 23 -set fmri(ortho6.23) 0 - -# Orthogonalise EV 6 wrt EV 24 -set fmri(ortho6.24) 0 - -# Orthogonalise EV 6 wrt EV 25 -set fmri(ortho6.25) 0 - -# Orthogonalise EV 6 wrt EV 26 -set fmri(ortho6.26) 0 - -# Higher-level EV value for EV 6 and input 1 -set fmri(evg1.6) 0 - -# Higher-level EV value for EV 6 and input 2 -set fmri(evg2.6) 0 - -# Higher-level EV value for EV 6 and input 3 -set fmri(evg3.6) 0 - -# Higher-level EV value for EV 6 and input 4 -set fmri(evg4.6) 0 - -# Higher-level EV value for EV 6 and input 5 -set fmri(evg5.6) 0 - -# Higher-level EV value for EV 6 and input 6 -set fmri(evg6.6) 0 - -# Higher-level EV value for EV 6 and input 7 -set fmri(evg7.6) 0 - -# Higher-level EV value for EV 6 and input 8 -set fmri(evg8.6) 0 - -# Higher-level EV value for EV 6 and input 9 -set fmri(evg9.6) 0 - -# Higher-level EV value for EV 6 and input 10 -set fmri(evg10.6) 0 - -# Higher-level EV value for EV 6 and input 11 -set fmri(evg11.6) 1.0 - -# Higher-level EV value for EV 6 and input 12 -set fmri(evg12.6) 1.0 - -# Higher-level EV value for EV 6 and input 13 -set fmri(evg13.6) 0 - -# Higher-level EV value for EV 6 and input 14 -set fmri(evg14.6) 0 - -# Higher-level EV value for EV 6 and input 15 -set fmri(evg15.6) 0 - -# Higher-level EV value for EV 6 and input 16 -set fmri(evg16.6) 0 - -# Higher-level EV value for EV 6 and input 17 -set fmri(evg17.6) 0 - -# Higher-level EV value for EV 6 and input 18 -set fmri(evg18.6) 0 - -# Higher-level EV value for EV 6 and input 19 -set fmri(evg19.6) 0 - -# Higher-level EV value for EV 6 and input 20 -set fmri(evg20.6) 0 - -# Higher-level EV value for EV 6 and input 21 -set fmri(evg21.6) 0 - -# Higher-level EV value for EV 6 and input 22 -set fmri(evg22.6) 0 - -# Higher-level EV value for EV 6 and input 23 -set fmri(evg23.6) 0 - -# Higher-level EV value for EV 6 and input 24 -set fmri(evg24.6) 0 - -# Higher-level EV value for EV 6 and input 25 -set fmri(evg25.6) 0 - -# Higher-level EV value for EV 6 and input 26 -set fmri(evg26.6) 0 - -# Higher-level EV value for EV 6 and input 27 -set fmri(evg27.6) 0 - -# Higher-level EV value for EV 6 and input 28 -set fmri(evg28.6) 0 - -# Higher-level EV value for EV 6 and input 29 -set fmri(evg29.6) 0 - -# Higher-level EV value for EV 6 and input 30 -set fmri(evg30.6) 0 - -# Higher-level EV value for EV 6 and input 31 -set fmri(evg31.6) 0 - -# Higher-level EV value for EV 6 and input 32 -set fmri(evg32.6) 0 - -# Higher-level EV value for EV 6 and input 33 -set fmri(evg33.6) 0 - -# Higher-level EV value for EV 6 and input 34 -set fmri(evg34.6) 0 - -# Higher-level EV value for EV 6 and input 35 -set fmri(evg35.6) 0 - -# Higher-level EV value for EV 6 and input 36 -set fmri(evg36.6) 0 - -# Higher-level EV value for EV 6 and input 37 -set fmri(evg37.6) 0 - -# Higher-level EV value for EV 6 and input 38 -set fmri(evg38.6) 0 - -# Higher-level EV value for EV 6 and input 39 -set fmri(evg39.6) 0 - -# Higher-level EV value for EV 6 and input 40 -set fmri(evg40.6) 0 - -# Higher-level EV value for EV 6 and input 41 -set fmri(evg41.6) 0 - -# Higher-level EV value for EV 6 and input 42 -set fmri(evg42.6) 0 - -# Higher-level EV value for EV 6 and input 43 -set fmri(evg43.6) 0 - -# Higher-level EV value for EV 6 and input 44 -set fmri(evg44.6) 0 - -# Higher-level EV value for EV 6 and input 45 -set fmri(evg45.6) 0 - -# Higher-level EV value for EV 6 and input 46 -set fmri(evg46.6) 0 - -# Higher-level EV value for EV 6 and input 47 -set fmri(evg47.6) 0 - -# Higher-level EV value for EV 6 and input 48 -set fmri(evg48.6) 0 - -# Higher-level EV value for EV 6 and input 49 -set fmri(evg49.6) 0 - -# Higher-level EV value for EV 6 and input 50 -set fmri(evg50.6) 0 - -# Higher-level EV value for EV 6 and input 51 -set fmri(evg51.6) 0 - -# Higher-level EV value for EV 6 and input 52 -set fmri(evg52.6) 0 - -# EV 7 title -set fmri(evtitle7) "" - -# Basic waveform shape (EV 7) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape7) 2 - -# Convolution (EV 7) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve7) 0 - -# Convolve phase (EV 7) -set fmri(convolve_phase7) 0 - -# Apply temporal filtering (EV 7) -set fmri(tempfilt_yn7) 0 - -# Add temporal derivative (EV 7) -set fmri(deriv_yn7) 0 - -# Custom EV file (EV 7) -set fmri(custom7) "dummy" - -# Orthogonalise EV 7 wrt EV 0 -set fmri(ortho7.0) 0 - -# Orthogonalise EV 7 wrt EV 1 -set fmri(ortho7.1) 0 - -# Orthogonalise EV 7 wrt EV 2 -set fmri(ortho7.2) 0 - -# Orthogonalise EV 7 wrt EV 3 -set fmri(ortho7.3) 0 - -# Orthogonalise EV 7 wrt EV 4 -set fmri(ortho7.4) 0 - -# Orthogonalise EV 7 wrt EV 5 -set fmri(ortho7.5) 0 - -# Orthogonalise EV 7 wrt EV 6 -set fmri(ortho7.6) 0 - -# Orthogonalise EV 7 wrt EV 7 -set fmri(ortho7.7) 0 - -# Orthogonalise EV 7 wrt EV 8 -set fmri(ortho7.8) 0 - -# Orthogonalise EV 7 wrt EV 9 -set fmri(ortho7.9) 0 - -# Orthogonalise EV 7 wrt EV 10 -set fmri(ortho7.10) 0 - -# Orthogonalise EV 7 wrt EV 11 -set fmri(ortho7.11) 0 - -# Orthogonalise EV 7 wrt EV 12 -set fmri(ortho7.12) 0 - -# Orthogonalise EV 7 wrt EV 13 -set fmri(ortho7.13) 0 - -# Orthogonalise EV 7 wrt EV 14 -set fmri(ortho7.14) 0 - -# Orthogonalise EV 7 wrt EV 15 -set fmri(ortho7.15) 0 - -# Orthogonalise EV 7 wrt EV 16 -set fmri(ortho7.16) 0 - -# Orthogonalise EV 7 wrt EV 17 -set fmri(ortho7.17) 0 - -# Orthogonalise EV 7 wrt EV 18 -set fmri(ortho7.18) 0 - -# Orthogonalise EV 7 wrt EV 19 -set fmri(ortho7.19) 0 - -# Orthogonalise EV 7 wrt EV 20 -set fmri(ortho7.20) 0 - -# Orthogonalise EV 7 wrt EV 21 -set fmri(ortho7.21) 0 - -# Orthogonalise EV 7 wrt EV 22 -set fmri(ortho7.22) 0 - -# Orthogonalise EV 7 wrt EV 23 -set fmri(ortho7.23) 0 - -# Orthogonalise EV 7 wrt EV 24 -set fmri(ortho7.24) 0 - -# Orthogonalise EV 7 wrt EV 25 -set fmri(ortho7.25) 0 - -# Orthogonalise EV 7 wrt EV 26 -set fmri(ortho7.26) 0 - -# Higher-level EV value for EV 7 and input 1 -set fmri(evg1.7) 0 - -# Higher-level EV value for EV 7 and input 2 -set fmri(evg2.7) 0 - -# Higher-level EV value for EV 7 and input 3 -set fmri(evg3.7) 0 - -# Higher-level EV value for EV 7 and input 4 -set fmri(evg4.7) 0 - -# Higher-level EV value for EV 7 and input 5 -set fmri(evg5.7) 0 - -# Higher-level EV value for EV 7 and input 6 -set fmri(evg6.7) 0 - -# Higher-level EV value for EV 7 and input 7 -set fmri(evg7.7) 0 - -# Higher-level EV value for EV 7 and input 8 -set fmri(evg8.7) 0 - -# Higher-level EV value for EV 7 and input 9 -set fmri(evg9.7) 0 - -# Higher-level EV value for EV 7 and input 10 -set fmri(evg10.7) 0 - -# Higher-level EV value for EV 7 and input 11 -set fmri(evg11.7) 0 - -# Higher-level EV value for EV 7 and input 12 -set fmri(evg12.7) 0 - -# Higher-level EV value for EV 7 and input 13 -set fmri(evg13.7) 1.0 - -# Higher-level EV value for EV 7 and input 14 -set fmri(evg14.7) 1.0 - -# Higher-level EV value for EV 7 and input 15 -set fmri(evg15.7) 0 - -# Higher-level EV value for EV 7 and input 16 -set fmri(evg16.7) 0 - -# Higher-level EV value for EV 7 and input 17 -set fmri(evg17.7) 0 - -# Higher-level EV value for EV 7 and input 18 -set fmri(evg18.7) 0 - -# Higher-level EV value for EV 7 and input 19 -set fmri(evg19.7) 0 - -# Higher-level EV value for EV 7 and input 20 -set fmri(evg20.7) 0 - -# Higher-level EV value for EV 7 and input 21 -set fmri(evg21.7) 0 - -# Higher-level EV value for EV 7 and input 22 -set fmri(evg22.7) 0 - -# Higher-level EV value for EV 7 and input 23 -set fmri(evg23.7) 0 - -# Higher-level EV value for EV 7 and input 24 -set fmri(evg24.7) 0 - -# Higher-level EV value for EV 7 and input 25 -set fmri(evg25.7) 0 - -# Higher-level EV value for EV 7 and input 26 -set fmri(evg26.7) 0 - -# Higher-level EV value for EV 7 and input 27 -set fmri(evg27.7) 0 - -# Higher-level EV value for EV 7 and input 28 -set fmri(evg28.7) 0 - -# Higher-level EV value for EV 7 and input 29 -set fmri(evg29.7) 0 - -# Higher-level EV value for EV 7 and input 30 -set fmri(evg30.7) 0 - -# Higher-level EV value for EV 7 and input 31 -set fmri(evg31.7) 0 - -# Higher-level EV value for EV 7 and input 32 -set fmri(evg32.7) 0 - -# Higher-level EV value for EV 7 and input 33 -set fmri(evg33.7) 0 - -# Higher-level EV value for EV 7 and input 34 -set fmri(evg34.7) 0 - -# Higher-level EV value for EV 7 and input 35 -set fmri(evg35.7) 0 - -# Higher-level EV value for EV 7 and input 36 -set fmri(evg36.7) 0 - -# Higher-level EV value for EV 7 and input 37 -set fmri(evg37.7) 0 - -# Higher-level EV value for EV 7 and input 38 -set fmri(evg38.7) 0 - -# Higher-level EV value for EV 7 and input 39 -set fmri(evg39.7) 0 - -# Higher-level EV value for EV 7 and input 40 -set fmri(evg40.7) 0 - -# Higher-level EV value for EV 7 and input 41 -set fmri(evg41.7) 0 - -# Higher-level EV value for EV 7 and input 42 -set fmri(evg42.7) 0 - -# Higher-level EV value for EV 7 and input 43 -set fmri(evg43.7) 0 - -# Higher-level EV value for EV 7 and input 44 -set fmri(evg44.7) 0 - -# Higher-level EV value for EV 7 and input 45 -set fmri(evg45.7) 0 - -# Higher-level EV value for EV 7 and input 46 -set fmri(evg46.7) 0 - -# Higher-level EV value for EV 7 and input 47 -set fmri(evg47.7) 0 - -# Higher-level EV value for EV 7 and input 48 -set fmri(evg48.7) 0 - -# Higher-level EV value for EV 7 and input 49 -set fmri(evg49.7) 0 - -# Higher-level EV value for EV 7 and input 50 -set fmri(evg50.7) 0 - -# Higher-level EV value for EV 7 and input 51 -set fmri(evg51.7) 0 - -# Higher-level EV value for EV 7 and input 52 -set fmri(evg52.7) 0 - -# EV 8 title -set fmri(evtitle8) "" - -# Basic waveform shape (EV 8) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape8) 2 - -# Convolution (EV 8) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve8) 0 - -# Convolve phase (EV 8) -set fmri(convolve_phase8) 0 - -# Apply temporal filtering (EV 8) -set fmri(tempfilt_yn8) 0 - -# Add temporal derivative (EV 8) -set fmri(deriv_yn8) 0 - -# Custom EV file (EV 8) -set fmri(custom8) "dummy" - -# Orthogonalise EV 8 wrt EV 0 -set fmri(ortho8.0) 0 - -# Orthogonalise EV 8 wrt EV 1 -set fmri(ortho8.1) 0 - -# Orthogonalise EV 8 wrt EV 2 -set fmri(ortho8.2) 0 - -# Orthogonalise EV 8 wrt EV 3 -set fmri(ortho8.3) 0 - -# Orthogonalise EV 8 wrt EV 4 -set fmri(ortho8.4) 0 - -# Orthogonalise EV 8 wrt EV 5 -set fmri(ortho8.5) 0 - -# Orthogonalise EV 8 wrt EV 6 -set fmri(ortho8.6) 0 - -# Orthogonalise EV 8 wrt EV 7 -set fmri(ortho8.7) 0 - -# Orthogonalise EV 8 wrt EV 8 -set fmri(ortho8.8) 0 - -# Orthogonalise EV 8 wrt EV 9 -set fmri(ortho8.9) 0 - -# Orthogonalise EV 8 wrt EV 10 -set fmri(ortho8.10) 0 - -# Orthogonalise EV 8 wrt EV 11 -set fmri(ortho8.11) 0 - -# Orthogonalise EV 8 wrt EV 12 -set fmri(ortho8.12) 0 - -# Orthogonalise EV 8 wrt EV 13 -set fmri(ortho8.13) 0 - -# Orthogonalise EV 8 wrt EV 14 -set fmri(ortho8.14) 0 - -# Orthogonalise EV 8 wrt EV 15 -set fmri(ortho8.15) 0 - -# Orthogonalise EV 8 wrt EV 16 -set fmri(ortho8.16) 0 - -# Orthogonalise EV 8 wrt EV 17 -set fmri(ortho8.17) 0 - -# Orthogonalise EV 8 wrt EV 18 -set fmri(ortho8.18) 0 - -# Orthogonalise EV 8 wrt EV 19 -set fmri(ortho8.19) 0 - -# Orthogonalise EV 8 wrt EV 20 -set fmri(ortho8.20) 0 - -# Orthogonalise EV 8 wrt EV 21 -set fmri(ortho8.21) 0 - -# Orthogonalise EV 8 wrt EV 22 -set fmri(ortho8.22) 0 - -# Orthogonalise EV 8 wrt EV 23 -set fmri(ortho8.23) 0 - -# Orthogonalise EV 8 wrt EV 24 -set fmri(ortho8.24) 0 - -# Orthogonalise EV 8 wrt EV 25 -set fmri(ortho8.25) 0 - -# Orthogonalise EV 8 wrt EV 26 -set fmri(ortho8.26) 0 - -# Higher-level EV value for EV 8 and input 1 -set fmri(evg1.8) 0 - -# Higher-level EV value for EV 8 and input 2 -set fmri(evg2.8) 0 - -# Higher-level EV value for EV 8 and input 3 -set fmri(evg3.8) 0 - -# Higher-level EV value for EV 8 and input 4 -set fmri(evg4.8) 0 - -# Higher-level EV value for EV 8 and input 5 -set fmri(evg5.8) 0 - -# Higher-level EV value for EV 8 and input 6 -set fmri(evg6.8) 0 - -# Higher-level EV value for EV 8 and input 7 -set fmri(evg7.8) 0 - -# Higher-level EV value for EV 8 and input 8 -set fmri(evg8.8) 0 - -# Higher-level EV value for EV 8 and input 9 -set fmri(evg9.8) 0 - -# Higher-level EV value for EV 8 and input 10 -set fmri(evg10.8) 0 - -# Higher-level EV value for EV 8 and input 11 -set fmri(evg11.8) 0 - -# Higher-level EV value for EV 8 and input 12 -set fmri(evg12.8) 0 - -# Higher-level EV value for EV 8 and input 13 -set fmri(evg13.8) 0 - -# Higher-level EV value for EV 8 and input 14 -set fmri(evg14.8) 0 - -# Higher-level EV value for EV 8 and input 15 -set fmri(evg15.8) 1.0 - -# Higher-level EV value for EV 8 and input 16 -set fmri(evg16.8) 1.0 - -# Higher-level EV value for EV 8 and input 17 -set fmri(evg17.8) 0 - -# Higher-level EV value for EV 8 and input 18 -set fmri(evg18.8) 0 - -# Higher-level EV value for EV 8 and input 19 -set fmri(evg19.8) 0 - -# Higher-level EV value for EV 8 and input 20 -set fmri(evg20.8) 0 - -# Higher-level EV value for EV 8 and input 21 -set fmri(evg21.8) 0 - -# Higher-level EV value for EV 8 and input 22 -set fmri(evg22.8) 0 - -# Higher-level EV value for EV 8 and input 23 -set fmri(evg23.8) 0 - -# Higher-level EV value for EV 8 and input 24 -set fmri(evg24.8) 0 - -# Higher-level EV value for EV 8 and input 25 -set fmri(evg25.8) 0 - -# Higher-level EV value for EV 8 and input 26 -set fmri(evg26.8) 0 - -# Higher-level EV value for EV 8 and input 27 -set fmri(evg27.8) 0 - -# Higher-level EV value for EV 8 and input 28 -set fmri(evg28.8) 0 - -# Higher-level EV value for EV 8 and input 29 -set fmri(evg29.8) 0 - -# Higher-level EV value for EV 8 and input 30 -set fmri(evg30.8) 0 - -# Higher-level EV value for EV 8 and input 31 -set fmri(evg31.8) 0 - -# Higher-level EV value for EV 8 and input 32 -set fmri(evg32.8) 0 - -# Higher-level EV value for EV 8 and input 33 -set fmri(evg33.8) 0 - -# Higher-level EV value for EV 8 and input 34 -set fmri(evg34.8) 0 - -# Higher-level EV value for EV 8 and input 35 -set fmri(evg35.8) 0 - -# Higher-level EV value for EV 8 and input 36 -set fmri(evg36.8) 0 - -# Higher-level EV value for EV 8 and input 37 -set fmri(evg37.8) 0 - -# Higher-level EV value for EV 8 and input 38 -set fmri(evg38.8) 0 - -# Higher-level EV value for EV 8 and input 39 -set fmri(evg39.8) 0 - -# Higher-level EV value for EV 8 and input 40 -set fmri(evg40.8) 0 - -# Higher-level EV value for EV 8 and input 41 -set fmri(evg41.8) 0 - -# Higher-level EV value for EV 8 and input 42 -set fmri(evg42.8) 0 - -# Higher-level EV value for EV 8 and input 43 -set fmri(evg43.8) 0 - -# Higher-level EV value for EV 8 and input 44 -set fmri(evg44.8) 0 - -# Higher-level EV value for EV 8 and input 45 -set fmri(evg45.8) 0 - -# Higher-level EV value for EV 8 and input 46 -set fmri(evg46.8) 0 - -# Higher-level EV value for EV 8 and input 47 -set fmri(evg47.8) 0 - -# Higher-level EV value for EV 8 and input 48 -set fmri(evg48.8) 0 - -# Higher-level EV value for EV 8 and input 49 -set fmri(evg49.8) 0 - -# Higher-level EV value for EV 8 and input 50 -set fmri(evg50.8) 0 - -# Higher-level EV value for EV 8 and input 51 -set fmri(evg51.8) 0 - -# Higher-level EV value for EV 8 and input 52 -set fmri(evg52.8) 0 - -# EV 9 title -set fmri(evtitle9) "" - -# Basic waveform shape (EV 9) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape9) 2 - -# Convolution (EV 9) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve9) 0 - -# Convolve phase (EV 9) -set fmri(convolve_phase9) 0 - -# Apply temporal filtering (EV 9) -set fmri(tempfilt_yn9) 0 - -# Add temporal derivative (EV 9) -set fmri(deriv_yn9) 0 - -# Custom EV file (EV 9) -set fmri(custom9) "dummy" - -# Orthogonalise EV 9 wrt EV 0 -set fmri(ortho9.0) 0 - -# Orthogonalise EV 9 wrt EV 1 -set fmri(ortho9.1) 0 - -# Orthogonalise EV 9 wrt EV 2 -set fmri(ortho9.2) 0 - -# Orthogonalise EV 9 wrt EV 3 -set fmri(ortho9.3) 0 - -# Orthogonalise EV 9 wrt EV 4 -set fmri(ortho9.4) 0 - -# Orthogonalise EV 9 wrt EV 5 -set fmri(ortho9.5) 0 - -# Orthogonalise EV 9 wrt EV 6 -set fmri(ortho9.6) 0 - -# Orthogonalise EV 9 wrt EV 7 -set fmri(ortho9.7) 0 - -# Orthogonalise EV 9 wrt EV 8 -set fmri(ortho9.8) 0 - -# Orthogonalise EV 9 wrt EV 9 -set fmri(ortho9.9) 0 - -# Orthogonalise EV 9 wrt EV 10 -set fmri(ortho9.10) 0 - -# Orthogonalise EV 9 wrt EV 11 -set fmri(ortho9.11) 0 - -# Orthogonalise EV 9 wrt EV 12 -set fmri(ortho9.12) 0 - -# Orthogonalise EV 9 wrt EV 13 -set fmri(ortho9.13) 0 - -# Orthogonalise EV 9 wrt EV 14 -set fmri(ortho9.14) 0 - -# Orthogonalise EV 9 wrt EV 15 -set fmri(ortho9.15) 0 - -# Orthogonalise EV 9 wrt EV 16 -set fmri(ortho9.16) 0 - -# Orthogonalise EV 9 wrt EV 17 -set fmri(ortho9.17) 0 - -# Orthogonalise EV 9 wrt EV 18 -set fmri(ortho9.18) 0 - -# Orthogonalise EV 9 wrt EV 19 -set fmri(ortho9.19) 0 - -# Orthogonalise EV 9 wrt EV 20 -set fmri(ortho9.20) 0 - -# Orthogonalise EV 9 wrt EV 21 -set fmri(ortho9.21) 0 - -# Orthogonalise EV 9 wrt EV 22 -set fmri(ortho9.22) 0 - -# Orthogonalise EV 9 wrt EV 23 -set fmri(ortho9.23) 0 - -# Orthogonalise EV 9 wrt EV 24 -set fmri(ortho9.24) 0 - -# Orthogonalise EV 9 wrt EV 25 -set fmri(ortho9.25) 0 - -# Orthogonalise EV 9 wrt EV 26 -set fmri(ortho9.26) 0 - -# Higher-level EV value for EV 9 and input 1 -set fmri(evg1.9) 0 - -# Higher-level EV value for EV 9 and input 2 -set fmri(evg2.9) 0 - -# Higher-level EV value for EV 9 and input 3 -set fmri(evg3.9) 0 - -# Higher-level EV value for EV 9 and input 4 -set fmri(evg4.9) 0 - -# Higher-level EV value for EV 9 and input 5 -set fmri(evg5.9) 0 - -# Higher-level EV value for EV 9 and input 6 -set fmri(evg6.9) 0 - -# Higher-level EV value for EV 9 and input 7 -set fmri(evg7.9) 0 - -# Higher-level EV value for EV 9 and input 8 -set fmri(evg8.9) 0 - -# Higher-level EV value for EV 9 and input 9 -set fmri(evg9.9) 0 - -# Higher-level EV value for EV 9 and input 10 -set fmri(evg10.9) 0 - -# Higher-level EV value for EV 9 and input 11 -set fmri(evg11.9) 0 - -# Higher-level EV value for EV 9 and input 12 -set fmri(evg12.9) 0 - -# Higher-level EV value for EV 9 and input 13 -set fmri(evg13.9) 0 - -# Higher-level EV value for EV 9 and input 14 -set fmri(evg14.9) 0 - -# Higher-level EV value for EV 9 and input 15 -set fmri(evg15.9) 0 - -# Higher-level EV value for EV 9 and input 16 -set fmri(evg16.9) 0 - -# Higher-level EV value for EV 9 and input 17 -set fmri(evg17.9) 1.0 - -# Higher-level EV value for EV 9 and input 18 -set fmri(evg18.9) 1.0 - -# Higher-level EV value for EV 9 and input 19 -set fmri(evg19.9) 0 - -# Higher-level EV value for EV 9 and input 20 -set fmri(evg20.9) 0 - -# Higher-level EV value for EV 9 and input 21 -set fmri(evg21.9) 0 - -# Higher-level EV value for EV 9 and input 22 -set fmri(evg22.9) 0 - -# Higher-level EV value for EV 9 and input 23 -set fmri(evg23.9) 0 - -# Higher-level EV value for EV 9 and input 24 -set fmri(evg24.9) 0 - -# Higher-level EV value for EV 9 and input 25 -set fmri(evg25.9) 0 - -# Higher-level EV value for EV 9 and input 26 -set fmri(evg26.9) 0 - -# Higher-level EV value for EV 9 and input 27 -set fmri(evg27.9) 0 - -# Higher-level EV value for EV 9 and input 28 -set fmri(evg28.9) 0 - -# Higher-level EV value for EV 9 and input 29 -set fmri(evg29.9) 0 - -# Higher-level EV value for EV 9 and input 30 -set fmri(evg30.9) 0 - -# Higher-level EV value for EV 9 and input 31 -set fmri(evg31.9) 0 - -# Higher-level EV value for EV 9 and input 32 -set fmri(evg32.9) 0 - -# Higher-level EV value for EV 9 and input 33 -set fmri(evg33.9) 0 - -# Higher-level EV value for EV 9 and input 34 -set fmri(evg34.9) 0 - -# Higher-level EV value for EV 9 and input 35 -set fmri(evg35.9) 0 - -# Higher-level EV value for EV 9 and input 36 -set fmri(evg36.9) 0 - -# Higher-level EV value for EV 9 and input 37 -set fmri(evg37.9) 0 - -# Higher-level EV value for EV 9 and input 38 -set fmri(evg38.9) 0 - -# Higher-level EV value for EV 9 and input 39 -set fmri(evg39.9) 0 - -# Higher-level EV value for EV 9 and input 40 -set fmri(evg40.9) 0 - -# Higher-level EV value for EV 9 and input 41 -set fmri(evg41.9) 0 - -# Higher-level EV value for EV 9 and input 42 -set fmri(evg42.9) 0 - -# Higher-level EV value for EV 9 and input 43 -set fmri(evg43.9) 0 - -# Higher-level EV value for EV 9 and input 44 -set fmri(evg44.9) 0 - -# Higher-level EV value for EV 9 and input 45 -set fmri(evg45.9) 0 - -# Higher-level EV value for EV 9 and input 46 -set fmri(evg46.9) 0 - -# Higher-level EV value for EV 9 and input 47 -set fmri(evg47.9) 0 - -# Higher-level EV value for EV 9 and input 48 -set fmri(evg48.9) 0 - -# Higher-level EV value for EV 9 and input 49 -set fmri(evg49.9) 0 - -# Higher-level EV value for EV 9 and input 50 -set fmri(evg50.9) 0 - -# Higher-level EV value for EV 9 and input 51 -set fmri(evg51.9) 0 - -# Higher-level EV value for EV 9 and input 52 -set fmri(evg52.9) 0 - -# EV 10 title -set fmri(evtitle10) "" - -# Basic waveform shape (EV 10) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape10) 2 - -# Convolution (EV 10) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve10) 0 - -# Convolve phase (EV 10) -set fmri(convolve_phase10) 0 - -# Apply temporal filtering (EV 10) -set fmri(tempfilt_yn10) 0 - -# Add temporal derivative (EV 10) -set fmri(deriv_yn10) 0 - -# Custom EV file (EV 10) -set fmri(custom10) "dummy" - -# Orthogonalise EV 10 wrt EV 0 -set fmri(ortho10.0) 0 - -# Orthogonalise EV 10 wrt EV 1 -set fmri(ortho10.1) 0 - -# Orthogonalise EV 10 wrt EV 2 -set fmri(ortho10.2) 0 - -# Orthogonalise EV 10 wrt EV 3 -set fmri(ortho10.3) 0 - -# Orthogonalise EV 10 wrt EV 4 -set fmri(ortho10.4) 0 - -# Orthogonalise EV 10 wrt EV 5 -set fmri(ortho10.5) 0 - -# Orthogonalise EV 10 wrt EV 6 -set fmri(ortho10.6) 0 - -# Orthogonalise EV 10 wrt EV 7 -set fmri(ortho10.7) 0 - -# Orthogonalise EV 10 wrt EV 8 -set fmri(ortho10.8) 0 - -# Orthogonalise EV 10 wrt EV 9 -set fmri(ortho10.9) 0 - -# Orthogonalise EV 10 wrt EV 10 -set fmri(ortho10.10) 0 - -# Orthogonalise EV 10 wrt EV 11 -set fmri(ortho10.11) 0 - -# Orthogonalise EV 10 wrt EV 12 -set fmri(ortho10.12) 0 - -# Orthogonalise EV 10 wrt EV 13 -set fmri(ortho10.13) 0 - -# Orthogonalise EV 10 wrt EV 14 -set fmri(ortho10.14) 0 - -# Orthogonalise EV 10 wrt EV 15 -set fmri(ortho10.15) 0 - -# Orthogonalise EV 10 wrt EV 16 -set fmri(ortho10.16) 0 - -# Orthogonalise EV 10 wrt EV 17 -set fmri(ortho10.17) 0 - -# Orthogonalise EV 10 wrt EV 18 -set fmri(ortho10.18) 0 - -# Orthogonalise EV 10 wrt EV 19 -set fmri(ortho10.19) 0 - -# Orthogonalise EV 10 wrt EV 20 -set fmri(ortho10.20) 0 - -# Orthogonalise EV 10 wrt EV 21 -set fmri(ortho10.21) 0 - -# Orthogonalise EV 10 wrt EV 22 -set fmri(ortho10.22) 0 - -# Orthogonalise EV 10 wrt EV 23 -set fmri(ortho10.23) 0 - -# Orthogonalise EV 10 wrt EV 24 -set fmri(ortho10.24) 0 - -# Orthogonalise EV 10 wrt EV 25 -set fmri(ortho10.25) 0 - -# Orthogonalise EV 10 wrt EV 26 -set fmri(ortho10.26) 0 - -# Higher-level EV value for EV 10 and input 1 -set fmri(evg1.10) 0 - -# Higher-level EV value for EV 10 and input 2 -set fmri(evg2.10) 0 - -# Higher-level EV value for EV 10 and input 3 -set fmri(evg3.10) 0 - -# Higher-level EV value for EV 10 and input 4 -set fmri(evg4.10) 0 - -# Higher-level EV value for EV 10 and input 5 -set fmri(evg5.10) 0 - -# Higher-level EV value for EV 10 and input 6 -set fmri(evg6.10) 0 - -# Higher-level EV value for EV 10 and input 7 -set fmri(evg7.10) 0 - -# Higher-level EV value for EV 10 and input 8 -set fmri(evg8.10) 0 - -# Higher-level EV value for EV 10 and input 9 -set fmri(evg9.10) 0 - -# Higher-level EV value for EV 10 and input 10 -set fmri(evg10.10) 0 - -# Higher-level EV value for EV 10 and input 11 -set fmri(evg11.10) 0 - -# Higher-level EV value for EV 10 and input 12 -set fmri(evg12.10) 0 - -# Higher-level EV value for EV 10 and input 13 -set fmri(evg13.10) 0 - -# Higher-level EV value for EV 10 and input 14 -set fmri(evg14.10) 0 - -# Higher-level EV value for EV 10 and input 15 -set fmri(evg15.10) 0 - -# Higher-level EV value for EV 10 and input 16 -set fmri(evg16.10) 0 - -# Higher-level EV value for EV 10 and input 17 -set fmri(evg17.10) 0 - -# Higher-level EV value for EV 10 and input 18 -set fmri(evg18.10) 0 - -# Higher-level EV value for EV 10 and input 19 -set fmri(evg19.10) 1.0 - -# Higher-level EV value for EV 10 and input 20 -set fmri(evg20.10) 1.0 - -# Higher-level EV value for EV 10 and input 21 -set fmri(evg21.10) 0 - -# Higher-level EV value for EV 10 and input 22 -set fmri(evg22.10) 0 - -# Higher-level EV value for EV 10 and input 23 -set fmri(evg23.10) 0 - -# Higher-level EV value for EV 10 and input 24 -set fmri(evg24.10) 0 - -# Higher-level EV value for EV 10 and input 25 -set fmri(evg25.10) 0 - -# Higher-level EV value for EV 10 and input 26 -set fmri(evg26.10) 0 - -# Higher-level EV value for EV 10 and input 27 -set fmri(evg27.10) 0 - -# Higher-level EV value for EV 10 and input 28 -set fmri(evg28.10) 0 - -# Higher-level EV value for EV 10 and input 29 -set fmri(evg29.10) 0 - -# Higher-level EV value for EV 10 and input 30 -set fmri(evg30.10) 0 - -# Higher-level EV value for EV 10 and input 31 -set fmri(evg31.10) 0 - -# Higher-level EV value for EV 10 and input 32 -set fmri(evg32.10) 0 - -# Higher-level EV value for EV 10 and input 33 -set fmri(evg33.10) 0 - -# Higher-level EV value for EV 10 and input 34 -set fmri(evg34.10) 0 - -# Higher-level EV value for EV 10 and input 35 -set fmri(evg35.10) 0 - -# Higher-level EV value for EV 10 and input 36 -set fmri(evg36.10) 0 - -# Higher-level EV value for EV 10 and input 37 -set fmri(evg37.10) 0 - -# Higher-level EV value for EV 10 and input 38 -set fmri(evg38.10) 0 - -# Higher-level EV value for EV 10 and input 39 -set fmri(evg39.10) 0 - -# Higher-level EV value for EV 10 and input 40 -set fmri(evg40.10) 0 - -# Higher-level EV value for EV 10 and input 41 -set fmri(evg41.10) 0 - -# Higher-level EV value for EV 10 and input 42 -set fmri(evg42.10) 0 - -# Higher-level EV value for EV 10 and input 43 -set fmri(evg43.10) 0 - -# Higher-level EV value for EV 10 and input 44 -set fmri(evg44.10) 0 - -# Higher-level EV value for EV 10 and input 45 -set fmri(evg45.10) 0 - -# Higher-level EV value for EV 10 and input 46 -set fmri(evg46.10) 0 - -# Higher-level EV value for EV 10 and input 47 -set fmri(evg47.10) 0 - -# Higher-level EV value for EV 10 and input 48 -set fmri(evg48.10) 0 - -# Higher-level EV value for EV 10 and input 49 -set fmri(evg49.10) 0 - -# Higher-level EV value for EV 10 and input 50 -set fmri(evg50.10) 0 - -# Higher-level EV value for EV 10 and input 51 -set fmri(evg51.10) 0 - -# Higher-level EV value for EV 10 and input 52 -set fmri(evg52.10) 0 - -# EV 11 title -set fmri(evtitle11) "" - -# Basic waveform shape (EV 11) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape11) 2 - -# Convolution (EV 11) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve11) 0 - -# Convolve phase (EV 11) -set fmri(convolve_phase11) 0 - -# Apply temporal filtering (EV 11) -set fmri(tempfilt_yn11) 0 - -# Add temporal derivative (EV 11) -set fmri(deriv_yn11) 0 - -# Custom EV file (EV 11) -set fmri(custom11) "dummy" - -# Orthogonalise EV 11 wrt EV 0 -set fmri(ortho11.0) 0 - -# Orthogonalise EV 11 wrt EV 1 -set fmri(ortho11.1) 0 - -# Orthogonalise EV 11 wrt EV 2 -set fmri(ortho11.2) 0 - -# Orthogonalise EV 11 wrt EV 3 -set fmri(ortho11.3) 0 - -# Orthogonalise EV 11 wrt EV 4 -set fmri(ortho11.4) 0 - -# Orthogonalise EV 11 wrt EV 5 -set fmri(ortho11.5) 0 - -# Orthogonalise EV 11 wrt EV 6 -set fmri(ortho11.6) 0 - -# Orthogonalise EV 11 wrt EV 7 -set fmri(ortho11.7) 0 - -# Orthogonalise EV 11 wrt EV 8 -set fmri(ortho11.8) 0 - -# Orthogonalise EV 11 wrt EV 9 -set fmri(ortho11.9) 0 - -# Orthogonalise EV 11 wrt EV 10 -set fmri(ortho11.10) 0 - -# Orthogonalise EV 11 wrt EV 11 -set fmri(ortho11.11) 0 - -# Orthogonalise EV 11 wrt EV 12 -set fmri(ortho11.12) 0 - -# Orthogonalise EV 11 wrt EV 13 -set fmri(ortho11.13) 0 - -# Orthogonalise EV 11 wrt EV 14 -set fmri(ortho11.14) 0 - -# Orthogonalise EV 11 wrt EV 15 -set fmri(ortho11.15) 0 - -# Orthogonalise EV 11 wrt EV 16 -set fmri(ortho11.16) 0 - -# Orthogonalise EV 11 wrt EV 17 -set fmri(ortho11.17) 0 - -# Orthogonalise EV 11 wrt EV 18 -set fmri(ortho11.18) 0 - -# Orthogonalise EV 11 wrt EV 19 -set fmri(ortho11.19) 0 - -# Orthogonalise EV 11 wrt EV 20 -set fmri(ortho11.20) 0 - -# Orthogonalise EV 11 wrt EV 21 -set fmri(ortho11.21) 0 - -# Orthogonalise EV 11 wrt EV 22 -set fmri(ortho11.22) 0 - -# Orthogonalise EV 11 wrt EV 23 -set fmri(ortho11.23) 0 - -# Orthogonalise EV 11 wrt EV 24 -set fmri(ortho11.24) 0 - -# Orthogonalise EV 11 wrt EV 25 -set fmri(ortho11.25) 0 - -# Orthogonalise EV 11 wrt EV 26 -set fmri(ortho11.26) 0 - -# Higher-level EV value for EV 11 and input 1 -set fmri(evg1.11) 0 - -# Higher-level EV value for EV 11 and input 2 -set fmri(evg2.11) 0 - -# Higher-level EV value for EV 11 and input 3 -set fmri(evg3.11) 0 - -# Higher-level EV value for EV 11 and input 4 -set fmri(evg4.11) 0 - -# Higher-level EV value for EV 11 and input 5 -set fmri(evg5.11) 0 - -# Higher-level EV value for EV 11 and input 6 -set fmri(evg6.11) 0 - -# Higher-level EV value for EV 11 and input 7 -set fmri(evg7.11) 0 - -# Higher-level EV value for EV 11 and input 8 -set fmri(evg8.11) 0 - -# Higher-level EV value for EV 11 and input 9 -set fmri(evg9.11) 0 - -# Higher-level EV value for EV 11 and input 10 -set fmri(evg10.11) 0 - -# Higher-level EV value for EV 11 and input 11 -set fmri(evg11.11) 0 - -# Higher-level EV value for EV 11 and input 12 -set fmri(evg12.11) 0 - -# Higher-level EV value for EV 11 and input 13 -set fmri(evg13.11) 0 - -# Higher-level EV value for EV 11 and input 14 -set fmri(evg14.11) 0 - -# Higher-level EV value for EV 11 and input 15 -set fmri(evg15.11) 0 - -# Higher-level EV value for EV 11 and input 16 -set fmri(evg16.11) 0 - -# Higher-level EV value for EV 11 and input 17 -set fmri(evg17.11) 0 - -# Higher-level EV value for EV 11 and input 18 -set fmri(evg18.11) 0 - -# Higher-level EV value for EV 11 and input 19 -set fmri(evg19.11) 0 - -# Higher-level EV value for EV 11 and input 20 -set fmri(evg20.11) 0 - -# Higher-level EV value for EV 11 and input 21 -set fmri(evg21.11) 1.0 - -# Higher-level EV value for EV 11 and input 22 -set fmri(evg22.11) 1.0 - -# Higher-level EV value for EV 11 and input 23 -set fmri(evg23.11) 0 - -# Higher-level EV value for EV 11 and input 24 -set fmri(evg24.11) 0 - -# Higher-level EV value for EV 11 and input 25 -set fmri(evg25.11) 0 - -# Higher-level EV value for EV 11 and input 26 -set fmri(evg26.11) 0 - -# Higher-level EV value for EV 11 and input 27 -set fmri(evg27.11) 0 - -# Higher-level EV value for EV 11 and input 28 -set fmri(evg28.11) 0 - -# Higher-level EV value for EV 11 and input 29 -set fmri(evg29.11) 0 - -# Higher-level EV value for EV 11 and input 30 -set fmri(evg30.11) 0 - -# Higher-level EV value for EV 11 and input 31 -set fmri(evg31.11) 0 - -# Higher-level EV value for EV 11 and input 32 -set fmri(evg32.11) 0 - -# Higher-level EV value for EV 11 and input 33 -set fmri(evg33.11) 0 - -# Higher-level EV value for EV 11 and input 34 -set fmri(evg34.11) 0 - -# Higher-level EV value for EV 11 and input 35 -set fmri(evg35.11) 0 - -# Higher-level EV value for EV 11 and input 36 -set fmri(evg36.11) 0 - -# Higher-level EV value for EV 11 and input 37 -set fmri(evg37.11) 0 - -# Higher-level EV value for EV 11 and input 38 -set fmri(evg38.11) 0 - -# Higher-level EV value for EV 11 and input 39 -set fmri(evg39.11) 0 - -# Higher-level EV value for EV 11 and input 40 -set fmri(evg40.11) 0 - -# Higher-level EV value for EV 11 and input 41 -set fmri(evg41.11) 0 - -# Higher-level EV value for EV 11 and input 42 -set fmri(evg42.11) 0 - -# Higher-level EV value for EV 11 and input 43 -set fmri(evg43.11) 0 - -# Higher-level EV value for EV 11 and input 44 -set fmri(evg44.11) 0 - -# Higher-level EV value for EV 11 and input 45 -set fmri(evg45.11) 0 - -# Higher-level EV value for EV 11 and input 46 -set fmri(evg46.11) 0 - -# Higher-level EV value for EV 11 and input 47 -set fmri(evg47.11) 0 - -# Higher-level EV value for EV 11 and input 48 -set fmri(evg48.11) 0 - -# Higher-level EV value for EV 11 and input 49 -set fmri(evg49.11) 0 - -# Higher-level EV value for EV 11 and input 50 -set fmri(evg50.11) 0 - -# Higher-level EV value for EV 11 and input 51 -set fmri(evg51.11) 0 - -# Higher-level EV value for EV 11 and input 52 -set fmri(evg52.11) 0 - -# EV 12 title -set fmri(evtitle12) "" - -# Basic waveform shape (EV 12) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape12) 2 - -# Convolution (EV 12) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve12) 0 - -# Convolve phase (EV 12) -set fmri(convolve_phase12) 0 - -# Apply temporal filtering (EV 12) -set fmri(tempfilt_yn12) 0 - -# Add temporal derivative (EV 12) -set fmri(deriv_yn12) 0 - -# Custom EV file (EV 12) -set fmri(custom12) "dummy" - -# Orthogonalise EV 12 wrt EV 0 -set fmri(ortho12.0) 0 - -# Orthogonalise EV 12 wrt EV 1 -set fmri(ortho12.1) 0 - -# Orthogonalise EV 12 wrt EV 2 -set fmri(ortho12.2) 0 - -# Orthogonalise EV 12 wrt EV 3 -set fmri(ortho12.3) 0 - -# Orthogonalise EV 12 wrt EV 4 -set fmri(ortho12.4) 0 - -# Orthogonalise EV 12 wrt EV 5 -set fmri(ortho12.5) 0 - -# Orthogonalise EV 12 wrt EV 6 -set fmri(ortho12.6) 0 - -# Orthogonalise EV 12 wrt EV 7 -set fmri(ortho12.7) 0 - -# Orthogonalise EV 12 wrt EV 8 -set fmri(ortho12.8) 0 - -# Orthogonalise EV 12 wrt EV 9 -set fmri(ortho12.9) 0 - -# Orthogonalise EV 12 wrt EV 10 -set fmri(ortho12.10) 0 - -# Orthogonalise EV 12 wrt EV 11 -set fmri(ortho12.11) 0 - -# Orthogonalise EV 12 wrt EV 12 -set fmri(ortho12.12) 0 - -# Orthogonalise EV 12 wrt EV 13 -set fmri(ortho12.13) 0 - -# Orthogonalise EV 12 wrt EV 14 -set fmri(ortho12.14) 0 - -# Orthogonalise EV 12 wrt EV 15 -set fmri(ortho12.15) 0 - -# Orthogonalise EV 12 wrt EV 16 -set fmri(ortho12.16) 0 - -# Orthogonalise EV 12 wrt EV 17 -set fmri(ortho12.17) 0 - -# Orthogonalise EV 12 wrt EV 18 -set fmri(ortho12.18) 0 - -# Orthogonalise EV 12 wrt EV 19 -set fmri(ortho12.19) 0 - -# Orthogonalise EV 12 wrt EV 20 -set fmri(ortho12.20) 0 - -# Orthogonalise EV 12 wrt EV 21 -set fmri(ortho12.21) 0 - -# Orthogonalise EV 12 wrt EV 22 -set fmri(ortho12.22) 0 - -# Orthogonalise EV 12 wrt EV 23 -set fmri(ortho12.23) 0 - -# Orthogonalise EV 12 wrt EV 24 -set fmri(ortho12.24) 0 - -# Orthogonalise EV 12 wrt EV 25 -set fmri(ortho12.25) 0 - -# Orthogonalise EV 12 wrt EV 26 -set fmri(ortho12.26) 0 - -# Higher-level EV value for EV 12 and input 1 -set fmri(evg1.12) 0 - -# Higher-level EV value for EV 12 and input 2 -set fmri(evg2.12) 0 - -# Higher-level EV value for EV 12 and input 3 -set fmri(evg3.12) 0 - -# Higher-level EV value for EV 12 and input 4 -set fmri(evg4.12) 0 - -# Higher-level EV value for EV 12 and input 5 -set fmri(evg5.12) 0 - -# Higher-level EV value for EV 12 and input 6 -set fmri(evg6.12) 0 - -# Higher-level EV value for EV 12 and input 7 -set fmri(evg7.12) 0 - -# Higher-level EV value for EV 12 and input 8 -set fmri(evg8.12) 0 - -# Higher-level EV value for EV 12 and input 9 -set fmri(evg9.12) 0 - -# Higher-level EV value for EV 12 and input 10 -set fmri(evg10.12) 0 - -# Higher-level EV value for EV 12 and input 11 -set fmri(evg11.12) 0 - -# Higher-level EV value for EV 12 and input 12 -set fmri(evg12.12) 0 - -# Higher-level EV value for EV 12 and input 13 -set fmri(evg13.12) 0 - -# Higher-level EV value for EV 12 and input 14 -set fmri(evg14.12) 0 - -# Higher-level EV value for EV 12 and input 15 -set fmri(evg15.12) 0 - -# Higher-level EV value for EV 12 and input 16 -set fmri(evg16.12) 0 - -# Higher-level EV value for EV 12 and input 17 -set fmri(evg17.12) 0 - -# Higher-level EV value for EV 12 and input 18 -set fmri(evg18.12) 0 - -# Higher-level EV value for EV 12 and input 19 -set fmri(evg19.12) 0 - -# Higher-level EV value for EV 12 and input 20 -set fmri(evg20.12) 0 - -# Higher-level EV value for EV 12 and input 21 -set fmri(evg21.12) 0 - -# Higher-level EV value for EV 12 and input 22 -set fmri(evg22.12) 0 - -# Higher-level EV value for EV 12 and input 23 -set fmri(evg23.12) 1.0 - -# Higher-level EV value for EV 12 and input 24 -set fmri(evg24.12) 1.0 - -# Higher-level EV value for EV 12 and input 25 -set fmri(evg25.12) 0 - -# Higher-level EV value for EV 12 and input 26 -set fmri(evg26.12) 0 - -# Higher-level EV value for EV 12 and input 27 -set fmri(evg27.12) 0 - -# Higher-level EV value for EV 12 and input 28 -set fmri(evg28.12) 0 - -# Higher-level EV value for EV 12 and input 29 -set fmri(evg29.12) 0 - -# Higher-level EV value for EV 12 and input 30 -set fmri(evg30.12) 0 - -# Higher-level EV value for EV 12 and input 31 -set fmri(evg31.12) 0 - -# Higher-level EV value for EV 12 and input 32 -set fmri(evg32.12) 0 - -# Higher-level EV value for EV 12 and input 33 -set fmri(evg33.12) 0 - -# Higher-level EV value for EV 12 and input 34 -set fmri(evg34.12) 0 - -# Higher-level EV value for EV 12 and input 35 -set fmri(evg35.12) 0 - -# Higher-level EV value for EV 12 and input 36 -set fmri(evg36.12) 0 - -# Higher-level EV value for EV 12 and input 37 -set fmri(evg37.12) 0 - -# Higher-level EV value for EV 12 and input 38 -set fmri(evg38.12) 0 - -# Higher-level EV value for EV 12 and input 39 -set fmri(evg39.12) 0 - -# Higher-level EV value for EV 12 and input 40 -set fmri(evg40.12) 0 - -# Higher-level EV value for EV 12 and input 41 -set fmri(evg41.12) 0 - -# Higher-level EV value for EV 12 and input 42 -set fmri(evg42.12) 0 - -# Higher-level EV value for EV 12 and input 43 -set fmri(evg43.12) 0 - -# Higher-level EV value for EV 12 and input 44 -set fmri(evg44.12) 0 - -# Higher-level EV value for EV 12 and input 45 -set fmri(evg45.12) 0 - -# Higher-level EV value for EV 12 and input 46 -set fmri(evg46.12) 0 - -# Higher-level EV value for EV 12 and input 47 -set fmri(evg47.12) 0 - -# Higher-level EV value for EV 12 and input 48 -set fmri(evg48.12) 0 - -# Higher-level EV value for EV 12 and input 49 -set fmri(evg49.12) 0 - -# Higher-level EV value for EV 12 and input 50 -set fmri(evg50.12) 0 - -# Higher-level EV value for EV 12 and input 51 -set fmri(evg51.12) 0 - -# Higher-level EV value for EV 12 and input 52 -set fmri(evg52.12) 0 - -# EV 13 title -set fmri(evtitle13) "" - -# Basic waveform shape (EV 13) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape13) 2 - -# Convolution (EV 13) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve13) 0 - -# Convolve phase (EV 13) -set fmri(convolve_phase13) 0 - -# Apply temporal filtering (EV 13) -set fmri(tempfilt_yn13) 0 - -# Add temporal derivative (EV 13) -set fmri(deriv_yn13) 0 - -# Custom EV file (EV 13) -set fmri(custom13) "dummy" - -# Orthogonalise EV 13 wrt EV 0 -set fmri(ortho13.0) 0 - -# Orthogonalise EV 13 wrt EV 1 -set fmri(ortho13.1) 0 - -# Orthogonalise EV 13 wrt EV 2 -set fmri(ortho13.2) 0 - -# Orthogonalise EV 13 wrt EV 3 -set fmri(ortho13.3) 0 - -# Orthogonalise EV 13 wrt EV 4 -set fmri(ortho13.4) 0 - -# Orthogonalise EV 13 wrt EV 5 -set fmri(ortho13.5) 0 - -# Orthogonalise EV 13 wrt EV 6 -set fmri(ortho13.6) 0 - -# Orthogonalise EV 13 wrt EV 7 -set fmri(ortho13.7) 0 - -# Orthogonalise EV 13 wrt EV 8 -set fmri(ortho13.8) 0 - -# Orthogonalise EV 13 wrt EV 9 -set fmri(ortho13.9) 0 - -# Orthogonalise EV 13 wrt EV 10 -set fmri(ortho13.10) 0 - -# Orthogonalise EV 13 wrt EV 11 -set fmri(ortho13.11) 0 - -# Orthogonalise EV 13 wrt EV 12 -set fmri(ortho13.12) 0 - -# Orthogonalise EV 13 wrt EV 13 -set fmri(ortho13.13) 0 - -# Orthogonalise EV 13 wrt EV 14 -set fmri(ortho13.14) 0 - -# Orthogonalise EV 13 wrt EV 15 -set fmri(ortho13.15) 0 - -# Orthogonalise EV 13 wrt EV 16 -set fmri(ortho13.16) 0 - -# Orthogonalise EV 13 wrt EV 17 -set fmri(ortho13.17) 0 - -# Orthogonalise EV 13 wrt EV 18 -set fmri(ortho13.18) 0 - -# Orthogonalise EV 13 wrt EV 19 -set fmri(ortho13.19) 0 - -# Orthogonalise EV 13 wrt EV 20 -set fmri(ortho13.20) 0 - -# Orthogonalise EV 13 wrt EV 21 -set fmri(ortho13.21) 0 - -# Orthogonalise EV 13 wrt EV 22 -set fmri(ortho13.22) 0 - -# Orthogonalise EV 13 wrt EV 23 -set fmri(ortho13.23) 0 - -# Orthogonalise EV 13 wrt EV 24 -set fmri(ortho13.24) 0 - -# Orthogonalise EV 13 wrt EV 25 -set fmri(ortho13.25) 0 - -# Orthogonalise EV 13 wrt EV 26 -set fmri(ortho13.26) 0 - -# Higher-level EV value for EV 13 and input 1 -set fmri(evg1.13) 0 - -# Higher-level EV value for EV 13 and input 2 -set fmri(evg2.13) 0 - -# Higher-level EV value for EV 13 and input 3 -set fmri(evg3.13) 0 - -# Higher-level EV value for EV 13 and input 4 -set fmri(evg4.13) 0 - -# Higher-level EV value for EV 13 and input 5 -set fmri(evg5.13) 0 - -# Higher-level EV value for EV 13 and input 6 -set fmri(evg6.13) 0 - -# Higher-level EV value for EV 13 and input 7 -set fmri(evg7.13) 0 - -# Higher-level EV value for EV 13 and input 8 -set fmri(evg8.13) 0 - -# Higher-level EV value for EV 13 and input 9 -set fmri(evg9.13) 0 - -# Higher-level EV value for EV 13 and input 10 -set fmri(evg10.13) 0 - -# Higher-level EV value for EV 13 and input 11 -set fmri(evg11.13) 0 - -# Higher-level EV value for EV 13 and input 12 -set fmri(evg12.13) 0 - -# Higher-level EV value for EV 13 and input 13 -set fmri(evg13.13) 0 - -# Higher-level EV value for EV 13 and input 14 -set fmri(evg14.13) 0 - -# Higher-level EV value for EV 13 and input 15 -set fmri(evg15.13) 0 - -# Higher-level EV value for EV 13 and input 16 -set fmri(evg16.13) 0 - -# Higher-level EV value for EV 13 and input 17 -set fmri(evg17.13) 0 - -# Higher-level EV value for EV 13 and input 18 -set fmri(evg18.13) 0 - -# Higher-level EV value for EV 13 and input 19 -set fmri(evg19.13) 0 - -# Higher-level EV value for EV 13 and input 20 -set fmri(evg20.13) 0 - -# Higher-level EV value for EV 13 and input 21 -set fmri(evg21.13) 0 - -# Higher-level EV value for EV 13 and input 22 -set fmri(evg22.13) 0 - -# Higher-level EV value for EV 13 and input 23 -set fmri(evg23.13) 0 - -# Higher-level EV value for EV 13 and input 24 -set fmri(evg24.13) 0 - -# Higher-level EV value for EV 13 and input 25 -set fmri(evg25.13) 1.0 - -# Higher-level EV value for EV 13 and input 26 -set fmri(evg26.13) 1.0 - -# Higher-level EV value for EV 13 and input 27 -set fmri(evg27.13) 0 - -# Higher-level EV value for EV 13 and input 28 -set fmri(evg28.13) 0 - -# Higher-level EV value for EV 13 and input 29 -set fmri(evg29.13) 0 - -# Higher-level EV value for EV 13 and input 30 -set fmri(evg30.13) 0 - -# Higher-level EV value for EV 13 and input 31 -set fmri(evg31.13) 0 - -# Higher-level EV value for EV 13 and input 32 -set fmri(evg32.13) 0 - -# Higher-level EV value for EV 13 and input 33 -set fmri(evg33.13) 0 - -# Higher-level EV value for EV 13 and input 34 -set fmri(evg34.13) 0 - -# Higher-level EV value for EV 13 and input 35 -set fmri(evg35.13) 0 - -# Higher-level EV value for EV 13 and input 36 -set fmri(evg36.13) 0 - -# Higher-level EV value for EV 13 and input 37 -set fmri(evg37.13) 0 - -# Higher-level EV value for EV 13 and input 38 -set fmri(evg38.13) 0 - -# Higher-level EV value for EV 13 and input 39 -set fmri(evg39.13) 0 - -# Higher-level EV value for EV 13 and input 40 -set fmri(evg40.13) 0 - -# Higher-level EV value for EV 13 and input 41 -set fmri(evg41.13) 0 - -# Higher-level EV value for EV 13 and input 42 -set fmri(evg42.13) 0 - -# Higher-level EV value for EV 13 and input 43 -set fmri(evg43.13) 0 - -# Higher-level EV value for EV 13 and input 44 -set fmri(evg44.13) 0 - -# Higher-level EV value for EV 13 and input 45 -set fmri(evg45.13) 0 - -# Higher-level EV value for EV 13 and input 46 -set fmri(evg46.13) 0 - -# Higher-level EV value for EV 13 and input 47 -set fmri(evg47.13) 0 - -# Higher-level EV value for EV 13 and input 48 -set fmri(evg48.13) 0 - -# Higher-level EV value for EV 13 and input 49 -set fmri(evg49.13) 0 - -# Higher-level EV value for EV 13 and input 50 -set fmri(evg50.13) 0 - -# Higher-level EV value for EV 13 and input 51 -set fmri(evg51.13) 0 - -# Higher-level EV value for EV 13 and input 52 -set fmri(evg52.13) 0 - -# EV 14 title -set fmri(evtitle14) "" - -# Basic waveform shape (EV 14) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape14) 2 - -# Convolution (EV 14) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve14) 0 - -# Convolve phase (EV 14) -set fmri(convolve_phase14) 0 - -# Apply temporal filtering (EV 14) -set fmri(tempfilt_yn14) 0 - -# Add temporal derivative (EV 14) -set fmri(deriv_yn14) 0 - -# Custom EV file (EV 14) -set fmri(custom14) "dummy" - -# Orthogonalise EV 14 wrt EV 0 -set fmri(ortho14.0) 0 - -# Orthogonalise EV 14 wrt EV 1 -set fmri(ortho14.1) 0 - -# Orthogonalise EV 14 wrt EV 2 -set fmri(ortho14.2) 0 - -# Orthogonalise EV 14 wrt EV 3 -set fmri(ortho14.3) 0 - -# Orthogonalise EV 14 wrt EV 4 -set fmri(ortho14.4) 0 - -# Orthogonalise EV 14 wrt EV 5 -set fmri(ortho14.5) 0 - -# Orthogonalise EV 14 wrt EV 6 -set fmri(ortho14.6) 0 - -# Orthogonalise EV 14 wrt EV 7 -set fmri(ortho14.7) 0 - -# Orthogonalise EV 14 wrt EV 8 -set fmri(ortho14.8) 0 - -# Orthogonalise EV 14 wrt EV 9 -set fmri(ortho14.9) 0 - -# Orthogonalise EV 14 wrt EV 10 -set fmri(ortho14.10) 0 - -# Orthogonalise EV 14 wrt EV 11 -set fmri(ortho14.11) 0 - -# Orthogonalise EV 14 wrt EV 12 -set fmri(ortho14.12) 0 - -# Orthogonalise EV 14 wrt EV 13 -set fmri(ortho14.13) 0 - -# Orthogonalise EV 14 wrt EV 14 -set fmri(ortho14.14) 0 - -# Orthogonalise EV 14 wrt EV 15 -set fmri(ortho14.15) 0 - -# Orthogonalise EV 14 wrt EV 16 -set fmri(ortho14.16) 0 - -# Orthogonalise EV 14 wrt EV 17 -set fmri(ortho14.17) 0 - -# Orthogonalise EV 14 wrt EV 18 -set fmri(ortho14.18) 0 - -# Orthogonalise EV 14 wrt EV 19 -set fmri(ortho14.19) 0 - -# Orthogonalise EV 14 wrt EV 20 -set fmri(ortho14.20) 0 - -# Orthogonalise EV 14 wrt EV 21 -set fmri(ortho14.21) 0 - -# Orthogonalise EV 14 wrt EV 22 -set fmri(ortho14.22) 0 - -# Orthogonalise EV 14 wrt EV 23 -set fmri(ortho14.23) 0 - -# Orthogonalise EV 14 wrt EV 24 -set fmri(ortho14.24) 0 - -# Orthogonalise EV 14 wrt EV 25 -set fmri(ortho14.25) 0 - -# Orthogonalise EV 14 wrt EV 26 -set fmri(ortho14.26) 0 - -# Higher-level EV value for EV 14 and input 1 -set fmri(evg1.14) 0 - -# Higher-level EV value for EV 14 and input 2 -set fmri(evg2.14) 0 - -# Higher-level EV value for EV 14 and input 3 -set fmri(evg3.14) 0 - -# Higher-level EV value for EV 14 and input 4 -set fmri(evg4.14) 0 - -# Higher-level EV value for EV 14 and input 5 -set fmri(evg5.14) 0 - -# Higher-level EV value for EV 14 and input 6 -set fmri(evg6.14) 0 - -# Higher-level EV value for EV 14 and input 7 -set fmri(evg7.14) 0 - -# Higher-level EV value for EV 14 and input 8 -set fmri(evg8.14) 0 - -# Higher-level EV value for EV 14 and input 9 -set fmri(evg9.14) 0 - -# Higher-level EV value for EV 14 and input 10 -set fmri(evg10.14) 0 - -# Higher-level EV value for EV 14 and input 11 -set fmri(evg11.14) 0 - -# Higher-level EV value for EV 14 and input 12 -set fmri(evg12.14) 0 - -# Higher-level EV value for EV 14 and input 13 -set fmri(evg13.14) 0 - -# Higher-level EV value for EV 14 and input 14 -set fmri(evg14.14) 0 - -# Higher-level EV value for EV 14 and input 15 -set fmri(evg15.14) 0 - -# Higher-level EV value for EV 14 and input 16 -set fmri(evg16.14) 0 - -# Higher-level EV value for EV 14 and input 17 -set fmri(evg17.14) 0 - -# Higher-level EV value for EV 14 and input 18 -set fmri(evg18.14) 0 - -# Higher-level EV value for EV 14 and input 19 -set fmri(evg19.14) 0 - -# Higher-level EV value for EV 14 and input 20 -set fmri(evg20.14) 0 - -# Higher-level EV value for EV 14 and input 21 -set fmri(evg21.14) 0 - -# Higher-level EV value for EV 14 and input 22 -set fmri(evg22.14) 0 - -# Higher-level EV value for EV 14 and input 23 -set fmri(evg23.14) 0 - -# Higher-level EV value for EV 14 and input 24 -set fmri(evg24.14) 0 - -# Higher-level EV value for EV 14 and input 25 -set fmri(evg25.14) 0 - -# Higher-level EV value for EV 14 and input 26 -set fmri(evg26.14) 0 - -# Higher-level EV value for EV 14 and input 27 -set fmri(evg27.14) 1.0 - -# Higher-level EV value for EV 14 and input 28 -set fmri(evg28.14) 1.0 - -# Higher-level EV value for EV 14 and input 29 -set fmri(evg29.14) 0 - -# Higher-level EV value for EV 14 and input 30 -set fmri(evg30.14) 0 - -# Higher-level EV value for EV 14 and input 31 -set fmri(evg31.14) 0 - -# Higher-level EV value for EV 14 and input 32 -set fmri(evg32.14) 0 - -# Higher-level EV value for EV 14 and input 33 -set fmri(evg33.14) 0 - -# Higher-level EV value for EV 14 and input 34 -set fmri(evg34.14) 0 - -# Higher-level EV value for EV 14 and input 35 -set fmri(evg35.14) 0 - -# Higher-level EV value for EV 14 and input 36 -set fmri(evg36.14) 0 - -# Higher-level EV value for EV 14 and input 37 -set fmri(evg37.14) 0 - -# Higher-level EV value for EV 14 and input 38 -set fmri(evg38.14) 0 - -# Higher-level EV value for EV 14 and input 39 -set fmri(evg39.14) 0 - -# Higher-level EV value for EV 14 and input 40 -set fmri(evg40.14) 0 - -# Higher-level EV value for EV 14 and input 41 -set fmri(evg41.14) 0 - -# Higher-level EV value for EV 14 and input 42 -set fmri(evg42.14) 0 - -# Higher-level EV value for EV 14 and input 43 -set fmri(evg43.14) 0 - -# Higher-level EV value for EV 14 and input 44 -set fmri(evg44.14) 0 - -# Higher-level EV value for EV 14 and input 45 -set fmri(evg45.14) 0 - -# Higher-level EV value for EV 14 and input 46 -set fmri(evg46.14) 0 - -# Higher-level EV value for EV 14 and input 47 -set fmri(evg47.14) 0 - -# Higher-level EV value for EV 14 and input 48 -set fmri(evg48.14) 0 - -# Higher-level EV value for EV 14 and input 49 -set fmri(evg49.14) 0 - -# Higher-level EV value for EV 14 and input 50 -set fmri(evg50.14) 0 - -# Higher-level EV value for EV 14 and input 51 -set fmri(evg51.14) 0 - -# Higher-level EV value for EV 14 and input 52 -set fmri(evg52.14) 0 - -# EV 15 title -set fmri(evtitle15) "" - -# Basic waveform shape (EV 15) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape15) 2 - -# Convolution (EV 15) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve15) 0 - -# Convolve phase (EV 15) -set fmri(convolve_phase15) 0 - -# Apply temporal filtering (EV 15) -set fmri(tempfilt_yn15) 0 - -# Add temporal derivative (EV 15) -set fmri(deriv_yn15) 0 - -# Custom EV file (EV 15) -set fmri(custom15) "dummy" - -# Orthogonalise EV 15 wrt EV 0 -set fmri(ortho15.0) 0 - -# Orthogonalise EV 15 wrt EV 1 -set fmri(ortho15.1) 0 - -# Orthogonalise EV 15 wrt EV 2 -set fmri(ortho15.2) 0 - -# Orthogonalise EV 15 wrt EV 3 -set fmri(ortho15.3) 0 - -# Orthogonalise EV 15 wrt EV 4 -set fmri(ortho15.4) 0 - -# Orthogonalise EV 15 wrt EV 5 -set fmri(ortho15.5) 0 - -# Orthogonalise EV 15 wrt EV 6 -set fmri(ortho15.6) 0 - -# Orthogonalise EV 15 wrt EV 7 -set fmri(ortho15.7) 0 - -# Orthogonalise EV 15 wrt EV 8 -set fmri(ortho15.8) 0 - -# Orthogonalise EV 15 wrt EV 9 -set fmri(ortho15.9) 0 - -# Orthogonalise EV 15 wrt EV 10 -set fmri(ortho15.10) 0 - -# Orthogonalise EV 15 wrt EV 11 -set fmri(ortho15.11) 0 - -# Orthogonalise EV 15 wrt EV 12 -set fmri(ortho15.12) 0 - -# Orthogonalise EV 15 wrt EV 13 -set fmri(ortho15.13) 0 - -# Orthogonalise EV 15 wrt EV 14 -set fmri(ortho15.14) 0 - -# Orthogonalise EV 15 wrt EV 15 -set fmri(ortho15.15) 0 - -# Orthogonalise EV 15 wrt EV 16 -set fmri(ortho15.16) 0 - -# Orthogonalise EV 15 wrt EV 17 -set fmri(ortho15.17) 0 - -# Orthogonalise EV 15 wrt EV 18 -set fmri(ortho15.18) 0 - -# Orthogonalise EV 15 wrt EV 19 -set fmri(ortho15.19) 0 - -# Orthogonalise EV 15 wrt EV 20 -set fmri(ortho15.20) 0 - -# Orthogonalise EV 15 wrt EV 21 -set fmri(ortho15.21) 0 - -# Orthogonalise EV 15 wrt EV 22 -set fmri(ortho15.22) 0 - -# Orthogonalise EV 15 wrt EV 23 -set fmri(ortho15.23) 0 - -# Orthogonalise EV 15 wrt EV 24 -set fmri(ortho15.24) 0 - -# Orthogonalise EV 15 wrt EV 25 -set fmri(ortho15.25) 0 - -# Orthogonalise EV 15 wrt EV 26 -set fmri(ortho15.26) 0 - -# Higher-level EV value for EV 15 and input 1 -set fmri(evg1.15) 0 - -# Higher-level EV value for EV 15 and input 2 -set fmri(evg2.15) 0 - -# Higher-level EV value for EV 15 and input 3 -set fmri(evg3.15) 0 - -# Higher-level EV value for EV 15 and input 4 -set fmri(evg4.15) 0 - -# Higher-level EV value for EV 15 and input 5 -set fmri(evg5.15) 0 - -# Higher-level EV value for EV 15 and input 6 -set fmri(evg6.15) 0 - -# Higher-level EV value for EV 15 and input 7 -set fmri(evg7.15) 0 - -# Higher-level EV value for EV 15 and input 8 -set fmri(evg8.15) 0 - -# Higher-level EV value for EV 15 and input 9 -set fmri(evg9.15) 0 - -# Higher-level EV value for EV 15 and input 10 -set fmri(evg10.15) 0 - -# Higher-level EV value for EV 15 and input 11 -set fmri(evg11.15) 0 - -# Higher-level EV value for EV 15 and input 12 -set fmri(evg12.15) 0 - -# Higher-level EV value for EV 15 and input 13 -set fmri(evg13.15) 0 - -# Higher-level EV value for EV 15 and input 14 -set fmri(evg14.15) 0 - -# Higher-level EV value for EV 15 and input 15 -set fmri(evg15.15) 0 - -# Higher-level EV value for EV 15 and input 16 -set fmri(evg16.15) 0 - -# Higher-level EV value for EV 15 and input 17 -set fmri(evg17.15) 0 - -# Higher-level EV value for EV 15 and input 18 -set fmri(evg18.15) 0 - -# Higher-level EV value for EV 15 and input 19 -set fmri(evg19.15) 0 - -# Higher-level EV value for EV 15 and input 20 -set fmri(evg20.15) 0 - -# Higher-level EV value for EV 15 and input 21 -set fmri(evg21.15) 0 - -# Higher-level EV value for EV 15 and input 22 -set fmri(evg22.15) 0 - -# Higher-level EV value for EV 15 and input 23 -set fmri(evg23.15) 0 - -# Higher-level EV value for EV 15 and input 24 -set fmri(evg24.15) 0 - -# Higher-level EV value for EV 15 and input 25 -set fmri(evg25.15) 0 - -# Higher-level EV value for EV 15 and input 26 -set fmri(evg26.15) 0 - -# Higher-level EV value for EV 15 and input 27 -set fmri(evg27.15) 0 - -# Higher-level EV value for EV 15 and input 28 -set fmri(evg28.15) 0 - -# Higher-level EV value for EV 15 and input 29 -set fmri(evg29.15) 1.0 - -# Higher-level EV value for EV 15 and input 30 -set fmri(evg30.15) 1.0 - -# Higher-level EV value for EV 15 and input 31 -set fmri(evg31.15) 0 - -# Higher-level EV value for EV 15 and input 32 -set fmri(evg32.15) 0 - -# Higher-level EV value for EV 15 and input 33 -set fmri(evg33.15) 0 - -# Higher-level EV value for EV 15 and input 34 -set fmri(evg34.15) 0 - -# Higher-level EV value for EV 15 and input 35 -set fmri(evg35.15) 0 - -# Higher-level EV value for EV 15 and input 36 -set fmri(evg36.15) 0 - -# Higher-level EV value for EV 15 and input 37 -set fmri(evg37.15) 0 - -# Higher-level EV value for EV 15 and input 38 -set fmri(evg38.15) 0 - -# Higher-level EV value for EV 15 and input 39 -set fmri(evg39.15) 0 - -# Higher-level EV value for EV 15 and input 40 -set fmri(evg40.15) 0 - -# Higher-level EV value for EV 15 and input 41 -set fmri(evg41.15) 0 - -# Higher-level EV value for EV 15 and input 42 -set fmri(evg42.15) 0 - -# Higher-level EV value for EV 15 and input 43 -set fmri(evg43.15) 0 - -# Higher-level EV value for EV 15 and input 44 -set fmri(evg44.15) 0 - -# Higher-level EV value for EV 15 and input 45 -set fmri(evg45.15) 0 - -# Higher-level EV value for EV 15 and input 46 -set fmri(evg46.15) 0 - -# Higher-level EV value for EV 15 and input 47 -set fmri(evg47.15) 0 - -# Higher-level EV value for EV 15 and input 48 -set fmri(evg48.15) 0 - -# Higher-level EV value for EV 15 and input 49 -set fmri(evg49.15) 0 - -# Higher-level EV value for EV 15 and input 50 -set fmri(evg50.15) 0 - -# Higher-level EV value for EV 15 and input 51 -set fmri(evg51.15) 0 - -# Higher-level EV value for EV 15 and input 52 -set fmri(evg52.15) 0 - -# EV 16 title -set fmri(evtitle16) "" - -# Basic waveform shape (EV 16) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape16) 2 - -# Convolution (EV 16) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve16) 0 - -# Convolve phase (EV 16) -set fmri(convolve_phase16) 0 - -# Apply temporal filtering (EV 16) -set fmri(tempfilt_yn16) 0 - -# Add temporal derivative (EV 16) -set fmri(deriv_yn16) 0 - -# Custom EV file (EV 16) -set fmri(custom16) "dummy" - -# Orthogonalise EV 16 wrt EV 0 -set fmri(ortho16.0) 0 - -# Orthogonalise EV 16 wrt EV 1 -set fmri(ortho16.1) 0 - -# Orthogonalise EV 16 wrt EV 2 -set fmri(ortho16.2) 0 - -# Orthogonalise EV 16 wrt EV 3 -set fmri(ortho16.3) 0 - -# Orthogonalise EV 16 wrt EV 4 -set fmri(ortho16.4) 0 - -# Orthogonalise EV 16 wrt EV 5 -set fmri(ortho16.5) 0 - -# Orthogonalise EV 16 wrt EV 6 -set fmri(ortho16.6) 0 - -# Orthogonalise EV 16 wrt EV 7 -set fmri(ortho16.7) 0 - -# Orthogonalise EV 16 wrt EV 8 -set fmri(ortho16.8) 0 - -# Orthogonalise EV 16 wrt EV 9 -set fmri(ortho16.9) 0 - -# Orthogonalise EV 16 wrt EV 10 -set fmri(ortho16.10) 0 - -# Orthogonalise EV 16 wrt EV 11 -set fmri(ortho16.11) 0 - -# Orthogonalise EV 16 wrt EV 12 -set fmri(ortho16.12) 0 - -# Orthogonalise EV 16 wrt EV 13 -set fmri(ortho16.13) 0 - -# Orthogonalise EV 16 wrt EV 14 -set fmri(ortho16.14) 0 - -# Orthogonalise EV 16 wrt EV 15 -set fmri(ortho16.15) 0 - -# Orthogonalise EV 16 wrt EV 16 -set fmri(ortho16.16) 0 - -# Orthogonalise EV 16 wrt EV 17 -set fmri(ortho16.17) 0 - -# Orthogonalise EV 16 wrt EV 18 -set fmri(ortho16.18) 0 - -# Orthogonalise EV 16 wrt EV 19 -set fmri(ortho16.19) 0 - -# Orthogonalise EV 16 wrt EV 20 -set fmri(ortho16.20) 0 - -# Orthogonalise EV 16 wrt EV 21 -set fmri(ortho16.21) 0 - -# Orthogonalise EV 16 wrt EV 22 -set fmri(ortho16.22) 0 - -# Orthogonalise EV 16 wrt EV 23 -set fmri(ortho16.23) 0 - -# Orthogonalise EV 16 wrt EV 24 -set fmri(ortho16.24) 0 - -# Orthogonalise EV 16 wrt EV 25 -set fmri(ortho16.25) 0 - -# Orthogonalise EV 16 wrt EV 26 -set fmri(ortho16.26) 0 - -# Higher-level EV value for EV 16 and input 1 -set fmri(evg1.16) 0 - -# Higher-level EV value for EV 16 and input 2 -set fmri(evg2.16) 0 - -# Higher-level EV value for EV 16 and input 3 -set fmri(evg3.16) 0 - -# Higher-level EV value for EV 16 and input 4 -set fmri(evg4.16) 0 - -# Higher-level EV value for EV 16 and input 5 -set fmri(evg5.16) 0 - -# Higher-level EV value for EV 16 and input 6 -set fmri(evg6.16) 0 - -# Higher-level EV value for EV 16 and input 7 -set fmri(evg7.16) 0 - -# Higher-level EV value for EV 16 and input 8 -set fmri(evg8.16) 0 - -# Higher-level EV value for EV 16 and input 9 -set fmri(evg9.16) 0 - -# Higher-level EV value for EV 16 and input 10 -set fmri(evg10.16) 0 - -# Higher-level EV value for EV 16 and input 11 -set fmri(evg11.16) 0 - -# Higher-level EV value for EV 16 and input 12 -set fmri(evg12.16) 0 - -# Higher-level EV value for EV 16 and input 13 -set fmri(evg13.16) 0 - -# Higher-level EV value for EV 16 and input 14 -set fmri(evg14.16) 0 - -# Higher-level EV value for EV 16 and input 15 -set fmri(evg15.16) 0 - -# Higher-level EV value for EV 16 and input 16 -set fmri(evg16.16) 0 - -# Higher-level EV value for EV 16 and input 17 -set fmri(evg17.16) 0 - -# Higher-level EV value for EV 16 and input 18 -set fmri(evg18.16) 0 - -# Higher-level EV value for EV 16 and input 19 -set fmri(evg19.16) 0 - -# Higher-level EV value for EV 16 and input 20 -set fmri(evg20.16) 0 - -# Higher-level EV value for EV 16 and input 21 -set fmri(evg21.16) 0 - -# Higher-level EV value for EV 16 and input 22 -set fmri(evg22.16) 0 - -# Higher-level EV value for EV 16 and input 23 -set fmri(evg23.16) 0 - -# Higher-level EV value for EV 16 and input 24 -set fmri(evg24.16) 0 - -# Higher-level EV value for EV 16 and input 25 -set fmri(evg25.16) 0 - -# Higher-level EV value for EV 16 and input 26 -set fmri(evg26.16) 0 - -# Higher-level EV value for EV 16 and input 27 -set fmri(evg27.16) 0 - -# Higher-level EV value for EV 16 and input 28 -set fmri(evg28.16) 0 - -# Higher-level EV value for EV 16 and input 29 -set fmri(evg29.16) 0 - -# Higher-level EV value for EV 16 and input 30 -set fmri(evg30.16) 0 - -# Higher-level EV value for EV 16 and input 31 -set fmri(evg31.16) 1.0 - -# Higher-level EV value for EV 16 and input 32 -set fmri(evg32.16) 1.0 - -# Higher-level EV value for EV 16 and input 33 -set fmri(evg33.16) 0 - -# Higher-level EV value for EV 16 and input 34 -set fmri(evg34.16) 0 - -# Higher-level EV value for EV 16 and input 35 -set fmri(evg35.16) 0 - -# Higher-level EV value for EV 16 and input 36 -set fmri(evg36.16) 0 - -# Higher-level EV value for EV 16 and input 37 -set fmri(evg37.16) 0 - -# Higher-level EV value for EV 16 and input 38 -set fmri(evg38.16) 0 - -# Higher-level EV value for EV 16 and input 39 -set fmri(evg39.16) 0 - -# Higher-level EV value for EV 16 and input 40 -set fmri(evg40.16) 0 - -# Higher-level EV value for EV 16 and input 41 -set fmri(evg41.16) 0 - -# Higher-level EV value for EV 16 and input 42 -set fmri(evg42.16) 0 - -# Higher-level EV value for EV 16 and input 43 -set fmri(evg43.16) 0 - -# Higher-level EV value for EV 16 and input 44 -set fmri(evg44.16) 0 - -# Higher-level EV value for EV 16 and input 45 -set fmri(evg45.16) 0 - -# Higher-level EV value for EV 16 and input 46 -set fmri(evg46.16) 0 - -# Higher-level EV value for EV 16 and input 47 -set fmri(evg47.16) 0 - -# Higher-level EV value for EV 16 and input 48 -set fmri(evg48.16) 0 - -# Higher-level EV value for EV 16 and input 49 -set fmri(evg49.16) 0 - -# Higher-level EV value for EV 16 and input 50 -set fmri(evg50.16) 0 - -# Higher-level EV value for EV 16 and input 51 -set fmri(evg51.16) 0 - -# Higher-level EV value for EV 16 and input 52 -set fmri(evg52.16) 0 - -# EV 17 title -set fmri(evtitle17) "" - -# Basic waveform shape (EV 17) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape17) 2 - -# Convolution (EV 17) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve17) 0 - -# Convolve phase (EV 17) -set fmri(convolve_phase17) 0 - -# Apply temporal filtering (EV 17) -set fmri(tempfilt_yn17) 0 - -# Add temporal derivative (EV 17) -set fmri(deriv_yn17) 0 - -# Custom EV file (EV 17) -set fmri(custom17) "dummy" - -# Orthogonalise EV 17 wrt EV 0 -set fmri(ortho17.0) 0 - -# Orthogonalise EV 17 wrt EV 1 -set fmri(ortho17.1) 0 - -# Orthogonalise EV 17 wrt EV 2 -set fmri(ortho17.2) 0 - -# Orthogonalise EV 17 wrt EV 3 -set fmri(ortho17.3) 0 - -# Orthogonalise EV 17 wrt EV 4 -set fmri(ortho17.4) 0 - -# Orthogonalise EV 17 wrt EV 5 -set fmri(ortho17.5) 0 - -# Orthogonalise EV 17 wrt EV 6 -set fmri(ortho17.6) 0 - -# Orthogonalise EV 17 wrt EV 7 -set fmri(ortho17.7) 0 - -# Orthogonalise EV 17 wrt EV 8 -set fmri(ortho17.8) 0 - -# Orthogonalise EV 17 wrt EV 9 -set fmri(ortho17.9) 0 - -# Orthogonalise EV 17 wrt EV 10 -set fmri(ortho17.10) 0 - -# Orthogonalise EV 17 wrt EV 11 -set fmri(ortho17.11) 0 - -# Orthogonalise EV 17 wrt EV 12 -set fmri(ortho17.12) 0 - -# Orthogonalise EV 17 wrt EV 13 -set fmri(ortho17.13) 0 - -# Orthogonalise EV 17 wrt EV 14 -set fmri(ortho17.14) 0 - -# Orthogonalise EV 17 wrt EV 15 -set fmri(ortho17.15) 0 - -# Orthogonalise EV 17 wrt EV 16 -set fmri(ortho17.16) 0 - -# Orthogonalise EV 17 wrt EV 17 -set fmri(ortho17.17) 0 - -# Orthogonalise EV 17 wrt EV 18 -set fmri(ortho17.18) 0 - -# Orthogonalise EV 17 wrt EV 19 -set fmri(ortho17.19) 0 - -# Orthogonalise EV 17 wrt EV 20 -set fmri(ortho17.20) 0 - -# Orthogonalise EV 17 wrt EV 21 -set fmri(ortho17.21) 0 - -# Orthogonalise EV 17 wrt EV 22 -set fmri(ortho17.22) 0 - -# Orthogonalise EV 17 wrt EV 23 -set fmri(ortho17.23) 0 - -# Orthogonalise EV 17 wrt EV 24 -set fmri(ortho17.24) 0 - -# Orthogonalise EV 17 wrt EV 25 -set fmri(ortho17.25) 0 - -# Orthogonalise EV 17 wrt EV 26 -set fmri(ortho17.26) 0 - -# Higher-level EV value for EV 17 and input 1 -set fmri(evg1.17) 0 - -# Higher-level EV value for EV 17 and input 2 -set fmri(evg2.17) 0 - -# Higher-level EV value for EV 17 and input 3 -set fmri(evg3.17) 0 - -# Higher-level EV value for EV 17 and input 4 -set fmri(evg4.17) 0 - -# Higher-level EV value for EV 17 and input 5 -set fmri(evg5.17) 0 - -# Higher-level EV value for EV 17 and input 6 -set fmri(evg6.17) 0 - -# Higher-level EV value for EV 17 and input 7 -set fmri(evg7.17) 0 - -# Higher-level EV value for EV 17 and input 8 -set fmri(evg8.17) 0 - -# Higher-level EV value for EV 17 and input 9 -set fmri(evg9.17) 0 - -# Higher-level EV value for EV 17 and input 10 -set fmri(evg10.17) 0 - -# Higher-level EV value for EV 17 and input 11 -set fmri(evg11.17) 0 - -# Higher-level EV value for EV 17 and input 12 -set fmri(evg12.17) 0 - -# Higher-level EV value for EV 17 and input 13 -set fmri(evg13.17) 0 - -# Higher-level EV value for EV 17 and input 14 -set fmri(evg14.17) 0 - -# Higher-level EV value for EV 17 and input 15 -set fmri(evg15.17) 0 - -# Higher-level EV value for EV 17 and input 16 -set fmri(evg16.17) 0 - -# Higher-level EV value for EV 17 and input 17 -set fmri(evg17.17) 0 - -# Higher-level EV value for EV 17 and input 18 -set fmri(evg18.17) 0 - -# Higher-level EV value for EV 17 and input 19 -set fmri(evg19.17) 0 - -# Higher-level EV value for EV 17 and input 20 -set fmri(evg20.17) 0 - -# Higher-level EV value for EV 17 and input 21 -set fmri(evg21.17) 0 - -# Higher-level EV value for EV 17 and input 22 -set fmri(evg22.17) 0 - -# Higher-level EV value for EV 17 and input 23 -set fmri(evg23.17) 0 - -# Higher-level EV value for EV 17 and input 24 -set fmri(evg24.17) 0 - -# Higher-level EV value for EV 17 and input 25 -set fmri(evg25.17) 0 - -# Higher-level EV value for EV 17 and input 26 -set fmri(evg26.17) 0 - -# Higher-level EV value for EV 17 and input 27 -set fmri(evg27.17) 0 - -# Higher-level EV value for EV 17 and input 28 -set fmri(evg28.17) 0 - -# Higher-level EV value for EV 17 and input 29 -set fmri(evg29.17) 0 - -# Higher-level EV value for EV 17 and input 30 -set fmri(evg30.17) 0 - -# Higher-level EV value for EV 17 and input 31 -set fmri(evg31.17) 0 - -# Higher-level EV value for EV 17 and input 32 -set fmri(evg32.17) 0 - -# Higher-level EV value for EV 17 and input 33 -set fmri(evg33.17) 1.0 - -# Higher-level EV value for EV 17 and input 34 -set fmri(evg34.17) 1.0 - -# Higher-level EV value for EV 17 and input 35 -set fmri(evg35.17) 0 - -# Higher-level EV value for EV 17 and input 36 -set fmri(evg36.17) 0 - -# Higher-level EV value for EV 17 and input 37 -set fmri(evg37.17) 0 - -# Higher-level EV value for EV 17 and input 38 -set fmri(evg38.17) 0 - -# Higher-level EV value for EV 17 and input 39 -set fmri(evg39.17) 0 - -# Higher-level EV value for EV 17 and input 40 -set fmri(evg40.17) 0 - -# Higher-level EV value for EV 17 and input 41 -set fmri(evg41.17) 0 - -# Higher-level EV value for EV 17 and input 42 -set fmri(evg42.17) 0 - -# Higher-level EV value for EV 17 and input 43 -set fmri(evg43.17) 0 - -# Higher-level EV value for EV 17 and input 44 -set fmri(evg44.17) 0 - -# Higher-level EV value for EV 17 and input 45 -set fmri(evg45.17) 0 - -# Higher-level EV value for EV 17 and input 46 -set fmri(evg46.17) 0 - -# Higher-level EV value for EV 17 and input 47 -set fmri(evg47.17) 0 - -# Higher-level EV value for EV 17 and input 48 -set fmri(evg48.17) 0 - -# Higher-level EV value for EV 17 and input 49 -set fmri(evg49.17) 0 - -# Higher-level EV value for EV 17 and input 50 -set fmri(evg50.17) 0 - -# Higher-level EV value for EV 17 and input 51 -set fmri(evg51.17) 0 - -# Higher-level EV value for EV 17 and input 52 -set fmri(evg52.17) 0 - -# EV 18 title -set fmri(evtitle18) "" - -# Basic waveform shape (EV 18) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape18) 2 - -# Convolution (EV 18) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve18) 0 - -# Convolve phase (EV 18) -set fmri(convolve_phase18) 0 - -# Apply temporal filtering (EV 18) -set fmri(tempfilt_yn18) 0 - -# Add temporal derivative (EV 18) -set fmri(deriv_yn18) 0 - -# Custom EV file (EV 18) -set fmri(custom18) "dummy" - -# Orthogonalise EV 18 wrt EV 0 -set fmri(ortho18.0) 0 - -# Orthogonalise EV 18 wrt EV 1 -set fmri(ortho18.1) 0 - -# Orthogonalise EV 18 wrt EV 2 -set fmri(ortho18.2) 0 - -# Orthogonalise EV 18 wrt EV 3 -set fmri(ortho18.3) 0 - -# Orthogonalise EV 18 wrt EV 4 -set fmri(ortho18.4) 0 - -# Orthogonalise EV 18 wrt EV 5 -set fmri(ortho18.5) 0 - -# Orthogonalise EV 18 wrt EV 6 -set fmri(ortho18.6) 0 - -# Orthogonalise EV 18 wrt EV 7 -set fmri(ortho18.7) 0 - -# Orthogonalise EV 18 wrt EV 8 -set fmri(ortho18.8) 0 - -# Orthogonalise EV 18 wrt EV 9 -set fmri(ortho18.9) 0 - -# Orthogonalise EV 18 wrt EV 10 -set fmri(ortho18.10) 0 - -# Orthogonalise EV 18 wrt EV 11 -set fmri(ortho18.11) 0 - -# Orthogonalise EV 18 wrt EV 12 -set fmri(ortho18.12) 0 - -# Orthogonalise EV 18 wrt EV 13 -set fmri(ortho18.13) 0 - -# Orthogonalise EV 18 wrt EV 14 -set fmri(ortho18.14) 0 - -# Orthogonalise EV 18 wrt EV 15 -set fmri(ortho18.15) 0 - -# Orthogonalise EV 18 wrt EV 16 -set fmri(ortho18.16) 0 - -# Orthogonalise EV 18 wrt EV 17 -set fmri(ortho18.17) 0 - -# Orthogonalise EV 18 wrt EV 18 -set fmri(ortho18.18) 0 - -# Orthogonalise EV 18 wrt EV 19 -set fmri(ortho18.19) 0 - -# Orthogonalise EV 18 wrt EV 20 -set fmri(ortho18.20) 0 - -# Orthogonalise EV 18 wrt EV 21 -set fmri(ortho18.21) 0 - -# Orthogonalise EV 18 wrt EV 22 -set fmri(ortho18.22) 0 - -# Orthogonalise EV 18 wrt EV 23 -set fmri(ortho18.23) 0 - -# Orthogonalise EV 18 wrt EV 24 -set fmri(ortho18.24) 0 - -# Orthogonalise EV 18 wrt EV 25 -set fmri(ortho18.25) 0 - -# Orthogonalise EV 18 wrt EV 26 -set fmri(ortho18.26) 0 - -# Higher-level EV value for EV 18 and input 1 -set fmri(evg1.18) 0 - -# Higher-level EV value for EV 18 and input 2 -set fmri(evg2.18) 0 - -# Higher-level EV value for EV 18 and input 3 -set fmri(evg3.18) 0 - -# Higher-level EV value for EV 18 and input 4 -set fmri(evg4.18) 0 - -# Higher-level EV value for EV 18 and input 5 -set fmri(evg5.18) 0 - -# Higher-level EV value for EV 18 and input 6 -set fmri(evg6.18) 0 - -# Higher-level EV value for EV 18 and input 7 -set fmri(evg7.18) 0 - -# Higher-level EV value for EV 18 and input 8 -set fmri(evg8.18) 0 - -# Higher-level EV value for EV 18 and input 9 -set fmri(evg9.18) 0 - -# Higher-level EV value for EV 18 and input 10 -set fmri(evg10.18) 0 - -# Higher-level EV value for EV 18 and input 11 -set fmri(evg11.18) 0 - -# Higher-level EV value for EV 18 and input 12 -set fmri(evg12.18) 0 - -# Higher-level EV value for EV 18 and input 13 -set fmri(evg13.18) 0 - -# Higher-level EV value for EV 18 and input 14 -set fmri(evg14.18) 0 - -# Higher-level EV value for EV 18 and input 15 -set fmri(evg15.18) 0 - -# Higher-level EV value for EV 18 and input 16 -set fmri(evg16.18) 0 - -# Higher-level EV value for EV 18 and input 17 -set fmri(evg17.18) 0 - -# Higher-level EV value for EV 18 and input 18 -set fmri(evg18.18) 0 - -# Higher-level EV value for EV 18 and input 19 -set fmri(evg19.18) 0 - -# Higher-level EV value for EV 18 and input 20 -set fmri(evg20.18) 0 - -# Higher-level EV value for EV 18 and input 21 -set fmri(evg21.18) 0 - -# Higher-level EV value for EV 18 and input 22 -set fmri(evg22.18) 0 - -# Higher-level EV value for EV 18 and input 23 -set fmri(evg23.18) 0 - -# Higher-level EV value for EV 18 and input 24 -set fmri(evg24.18) 0 - -# Higher-level EV value for EV 18 and input 25 -set fmri(evg25.18) 0 - -# Higher-level EV value for EV 18 and input 26 -set fmri(evg26.18) 0 - -# Higher-level EV value for EV 18 and input 27 -set fmri(evg27.18) 0 - -# Higher-level EV value for EV 18 and input 28 -set fmri(evg28.18) 0 - -# Higher-level EV value for EV 18 and input 29 -set fmri(evg29.18) 0 - -# Higher-level EV value for EV 18 and input 30 -set fmri(evg30.18) 0 - -# Higher-level EV value for EV 18 and input 31 -set fmri(evg31.18) 0 - -# Higher-level EV value for EV 18 and input 32 -set fmri(evg32.18) 0 - -# Higher-level EV value for EV 18 and input 33 -set fmri(evg33.18) 0 - -# Higher-level EV value for EV 18 and input 34 -set fmri(evg34.18) 0 - -# Higher-level EV value for EV 18 and input 35 -set fmri(evg35.18) 1.0 - -# Higher-level EV value for EV 18 and input 36 -set fmri(evg36.18) 1.0 - -# Higher-level EV value for EV 18 and input 37 -set fmri(evg37.18) 0 - -# Higher-level EV value for EV 18 and input 38 -set fmri(evg38.18) 0 - -# Higher-level EV value for EV 18 and input 39 -set fmri(evg39.18) 0 - -# Higher-level EV value for EV 18 and input 40 -set fmri(evg40.18) 0 - -# Higher-level EV value for EV 18 and input 41 -set fmri(evg41.18) 0 - -# Higher-level EV value for EV 18 and input 42 -set fmri(evg42.18) 0 - -# Higher-level EV value for EV 18 and input 43 -set fmri(evg43.18) 0 - -# Higher-level EV value for EV 18 and input 44 -set fmri(evg44.18) 0 - -# Higher-level EV value for EV 18 and input 45 -set fmri(evg45.18) 0 - -# Higher-level EV value for EV 18 and input 46 -set fmri(evg46.18) 0 - -# Higher-level EV value for EV 18 and input 47 -set fmri(evg47.18) 0 - -# Higher-level EV value for EV 18 and input 48 -set fmri(evg48.18) 0 - -# Higher-level EV value for EV 18 and input 49 -set fmri(evg49.18) 0 - -# Higher-level EV value for EV 18 and input 50 -set fmri(evg50.18) 0 - -# Higher-level EV value for EV 18 and input 51 -set fmri(evg51.18) 0 - -# Higher-level EV value for EV 18 and input 52 -set fmri(evg52.18) 0 - -# EV 19 title -set fmri(evtitle19) "" - -# Basic waveform shape (EV 19) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape19) 2 - -# Convolution (EV 19) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve19) 0 - -# Convolve phase (EV 19) -set fmri(convolve_phase19) 0 - -# Apply temporal filtering (EV 19) -set fmri(tempfilt_yn19) 0 - -# Add temporal derivative (EV 19) -set fmri(deriv_yn19) 0 - -# Custom EV file (EV 19) -set fmri(custom19) "dummy" - -# Orthogonalise EV 19 wrt EV 0 -set fmri(ortho19.0) 0 - -# Orthogonalise EV 19 wrt EV 1 -set fmri(ortho19.1) 0 - -# Orthogonalise EV 19 wrt EV 2 -set fmri(ortho19.2) 0 - -# Orthogonalise EV 19 wrt EV 3 -set fmri(ortho19.3) 0 - -# Orthogonalise EV 19 wrt EV 4 -set fmri(ortho19.4) 0 - -# Orthogonalise EV 19 wrt EV 5 -set fmri(ortho19.5) 0 - -# Orthogonalise EV 19 wrt EV 6 -set fmri(ortho19.6) 0 - -# Orthogonalise EV 19 wrt EV 7 -set fmri(ortho19.7) 0 - -# Orthogonalise EV 19 wrt EV 8 -set fmri(ortho19.8) 0 - -# Orthogonalise EV 19 wrt EV 9 -set fmri(ortho19.9) 0 - -# Orthogonalise EV 19 wrt EV 10 -set fmri(ortho19.10) 0 - -# Orthogonalise EV 19 wrt EV 11 -set fmri(ortho19.11) 0 - -# Orthogonalise EV 19 wrt EV 12 -set fmri(ortho19.12) 0 - -# Orthogonalise EV 19 wrt EV 13 -set fmri(ortho19.13) 0 - -# Orthogonalise EV 19 wrt EV 14 -set fmri(ortho19.14) 0 - -# Orthogonalise EV 19 wrt EV 15 -set fmri(ortho19.15) 0 - -# Orthogonalise EV 19 wrt EV 16 -set fmri(ortho19.16) 0 - -# Orthogonalise EV 19 wrt EV 17 -set fmri(ortho19.17) 0 - -# Orthogonalise EV 19 wrt EV 18 -set fmri(ortho19.18) 0 - -# Orthogonalise EV 19 wrt EV 19 -set fmri(ortho19.19) 0 - -# Orthogonalise EV 19 wrt EV 20 -set fmri(ortho19.20) 0 - -# Orthogonalise EV 19 wrt EV 21 -set fmri(ortho19.21) 0 - -# Orthogonalise EV 19 wrt EV 22 -set fmri(ortho19.22) 0 - -# Orthogonalise EV 19 wrt EV 23 -set fmri(ortho19.23) 0 - -# Orthogonalise EV 19 wrt EV 24 -set fmri(ortho19.24) 0 - -# Orthogonalise EV 19 wrt EV 25 -set fmri(ortho19.25) 0 - -# Orthogonalise EV 19 wrt EV 26 -set fmri(ortho19.26) 0 - -# Higher-level EV value for EV 19 and input 1 -set fmri(evg1.19) 0 - -# Higher-level EV value for EV 19 and input 2 -set fmri(evg2.19) 0 - -# Higher-level EV value for EV 19 and input 3 -set fmri(evg3.19) 0 - -# Higher-level EV value for EV 19 and input 4 -set fmri(evg4.19) 0 - -# Higher-level EV value for EV 19 and input 5 -set fmri(evg5.19) 0 - -# Higher-level EV value for EV 19 and input 6 -set fmri(evg6.19) 0 - -# Higher-level EV value for EV 19 and input 7 -set fmri(evg7.19) 0 - -# Higher-level EV value for EV 19 and input 8 -set fmri(evg8.19) 0 - -# Higher-level EV value for EV 19 and input 9 -set fmri(evg9.19) 0 - -# Higher-level EV value for EV 19 and input 10 -set fmri(evg10.19) 0 - -# Higher-level EV value for EV 19 and input 11 -set fmri(evg11.19) 0 - -# Higher-level EV value for EV 19 and input 12 -set fmri(evg12.19) 0 - -# Higher-level EV value for EV 19 and input 13 -set fmri(evg13.19) 0 - -# Higher-level EV value for EV 19 and input 14 -set fmri(evg14.19) 0 - -# Higher-level EV value for EV 19 and input 15 -set fmri(evg15.19) 0 - -# Higher-level EV value for EV 19 and input 16 -set fmri(evg16.19) 0 - -# Higher-level EV value for EV 19 and input 17 -set fmri(evg17.19) 0 - -# Higher-level EV value for EV 19 and input 18 -set fmri(evg18.19) 0 - -# Higher-level EV value for EV 19 and input 19 -set fmri(evg19.19) 0 - -# Higher-level EV value for EV 19 and input 20 -set fmri(evg20.19) 0 - -# Higher-level EV value for EV 19 and input 21 -set fmri(evg21.19) 0 - -# Higher-level EV value for EV 19 and input 22 -set fmri(evg22.19) 0 - -# Higher-level EV value for EV 19 and input 23 -set fmri(evg23.19) 0 - -# Higher-level EV value for EV 19 and input 24 -set fmri(evg24.19) 0 - -# Higher-level EV value for EV 19 and input 25 -set fmri(evg25.19) 0 - -# Higher-level EV value for EV 19 and input 26 -set fmri(evg26.19) 0 - -# Higher-level EV value for EV 19 and input 27 -set fmri(evg27.19) 0 - -# Higher-level EV value for EV 19 and input 28 -set fmri(evg28.19) 0 - -# Higher-level EV value for EV 19 and input 29 -set fmri(evg29.19) 0 - -# Higher-level EV value for EV 19 and input 30 -set fmri(evg30.19) 0 - -# Higher-level EV value for EV 19 and input 31 -set fmri(evg31.19) 0 - -# Higher-level EV value for EV 19 and input 32 -set fmri(evg32.19) 0 - -# Higher-level EV value for EV 19 and input 33 -set fmri(evg33.19) 0 - -# Higher-level EV value for EV 19 and input 34 -set fmri(evg34.19) 0 - -# Higher-level EV value for EV 19 and input 35 -set fmri(evg35.19) 0 - -# Higher-level EV value for EV 19 and input 36 -set fmri(evg36.19) 0 - -# Higher-level EV value for EV 19 and input 37 -set fmri(evg37.19) 1.0 - -# Higher-level EV value for EV 19 and input 38 -set fmri(evg38.19) 1.0 - -# Higher-level EV value for EV 19 and input 39 -set fmri(evg39.19) 0 - -# Higher-level EV value for EV 19 and input 40 -set fmri(evg40.19) 0 - -# Higher-level EV value for EV 19 and input 41 -set fmri(evg41.19) 0 - -# Higher-level EV value for EV 19 and input 42 -set fmri(evg42.19) 0 - -# Higher-level EV value for EV 19 and input 43 -set fmri(evg43.19) 0 - -# Higher-level EV value for EV 19 and input 44 -set fmri(evg44.19) 0 - -# Higher-level EV value for EV 19 and input 45 -set fmri(evg45.19) 0 - -# Higher-level EV value for EV 19 and input 46 -set fmri(evg46.19) 0 - -# Higher-level EV value for EV 19 and input 47 -set fmri(evg47.19) 0 - -# Higher-level EV value for EV 19 and input 48 -set fmri(evg48.19) 0 - -# Higher-level EV value for EV 19 and input 49 -set fmri(evg49.19) 0 - -# Higher-level EV value for EV 19 and input 50 -set fmri(evg50.19) 0 - -# Higher-level EV value for EV 19 and input 51 -set fmri(evg51.19) 0 - -# Higher-level EV value for EV 19 and input 52 -set fmri(evg52.19) 0 - -# EV 20 title -set fmri(evtitle20) "" - -# Basic waveform shape (EV 20) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape20) 2 - -# Convolution (EV 20) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve20) 0 - -# Convolve phase (EV 20) -set fmri(convolve_phase20) 0 - -# Apply temporal filtering (EV 20) -set fmri(tempfilt_yn20) 0 - -# Add temporal derivative (EV 20) -set fmri(deriv_yn20) 0 - -# Custom EV file (EV 20) -set fmri(custom20) "dummy" - -# Orthogonalise EV 20 wrt EV 0 -set fmri(ortho20.0) 0 - -# Orthogonalise EV 20 wrt EV 1 -set fmri(ortho20.1) 0 - -# Orthogonalise EV 20 wrt EV 2 -set fmri(ortho20.2) 0 - -# Orthogonalise EV 20 wrt EV 3 -set fmri(ortho20.3) 0 - -# Orthogonalise EV 20 wrt EV 4 -set fmri(ortho20.4) 0 - -# Orthogonalise EV 20 wrt EV 5 -set fmri(ortho20.5) 0 - -# Orthogonalise EV 20 wrt EV 6 -set fmri(ortho20.6) 0 - -# Orthogonalise EV 20 wrt EV 7 -set fmri(ortho20.7) 0 - -# Orthogonalise EV 20 wrt EV 8 -set fmri(ortho20.8) 0 - -# Orthogonalise EV 20 wrt EV 9 -set fmri(ortho20.9) 0 - -# Orthogonalise EV 20 wrt EV 10 -set fmri(ortho20.10) 0 - -# Orthogonalise EV 20 wrt EV 11 -set fmri(ortho20.11) 0 - -# Orthogonalise EV 20 wrt EV 12 -set fmri(ortho20.12) 0 - -# Orthogonalise EV 20 wrt EV 13 -set fmri(ortho20.13) 0 - -# Orthogonalise EV 20 wrt EV 14 -set fmri(ortho20.14) 0 - -# Orthogonalise EV 20 wrt EV 15 -set fmri(ortho20.15) 0 - -# Orthogonalise EV 20 wrt EV 16 -set fmri(ortho20.16) 0 - -# Orthogonalise EV 20 wrt EV 17 -set fmri(ortho20.17) 0 - -# Orthogonalise EV 20 wrt EV 18 -set fmri(ortho20.18) 0 - -# Orthogonalise EV 20 wrt EV 19 -set fmri(ortho20.19) 0 - -# Orthogonalise EV 20 wrt EV 20 -set fmri(ortho20.20) 0 - -# Orthogonalise EV 20 wrt EV 21 -set fmri(ortho20.21) 0 - -# Orthogonalise EV 20 wrt EV 22 -set fmri(ortho20.22) 0 - -# Orthogonalise EV 20 wrt EV 23 -set fmri(ortho20.23) 0 - -# Orthogonalise EV 20 wrt EV 24 -set fmri(ortho20.24) 0 - -# Orthogonalise EV 20 wrt EV 25 -set fmri(ortho20.25) 0 - -# Orthogonalise EV 20 wrt EV 26 -set fmri(ortho20.26) 0 - -# Higher-level EV value for EV 20 and input 1 -set fmri(evg1.20) 0 - -# Higher-level EV value for EV 20 and input 2 -set fmri(evg2.20) 0 - -# Higher-level EV value for EV 20 and input 3 -set fmri(evg3.20) 0 - -# Higher-level EV value for EV 20 and input 4 -set fmri(evg4.20) 0 - -# Higher-level EV value for EV 20 and input 5 -set fmri(evg5.20) 0 - -# Higher-level EV value for EV 20 and input 6 -set fmri(evg6.20) 0 - -# Higher-level EV value for EV 20 and input 7 -set fmri(evg7.20) 0 - -# Higher-level EV value for EV 20 and input 8 -set fmri(evg8.20) 0 - -# Higher-level EV value for EV 20 and input 9 -set fmri(evg9.20) 0 - -# Higher-level EV value for EV 20 and input 10 -set fmri(evg10.20) 0 - -# Higher-level EV value for EV 20 and input 11 -set fmri(evg11.20) 0 - -# Higher-level EV value for EV 20 and input 12 -set fmri(evg12.20) 0 - -# Higher-level EV value for EV 20 and input 13 -set fmri(evg13.20) 0 - -# Higher-level EV value for EV 20 and input 14 -set fmri(evg14.20) 0 - -# Higher-level EV value for EV 20 and input 15 -set fmri(evg15.20) 0 - -# Higher-level EV value for EV 20 and input 16 -set fmri(evg16.20) 0 - -# Higher-level EV value for EV 20 and input 17 -set fmri(evg17.20) 0 - -# Higher-level EV value for EV 20 and input 18 -set fmri(evg18.20) 0 - -# Higher-level EV value for EV 20 and input 19 -set fmri(evg19.20) 0 - -# Higher-level EV value for EV 20 and input 20 -set fmri(evg20.20) 0 - -# Higher-level EV value for EV 20 and input 21 -set fmri(evg21.20) 0 - -# Higher-level EV value for EV 20 and input 22 -set fmri(evg22.20) 0 - -# Higher-level EV value for EV 20 and input 23 -set fmri(evg23.20) 0 - -# Higher-level EV value for EV 20 and input 24 -set fmri(evg24.20) 0 - -# Higher-level EV value for EV 20 and input 25 -set fmri(evg25.20) 0 - -# Higher-level EV value for EV 20 and input 26 -set fmri(evg26.20) 0 - -# Higher-level EV value for EV 20 and input 27 -set fmri(evg27.20) 0 - -# Higher-level EV value for EV 20 and input 28 -set fmri(evg28.20) 0 - -# Higher-level EV value for EV 20 and input 29 -set fmri(evg29.20) 0 - -# Higher-level EV value for EV 20 and input 30 -set fmri(evg30.20) 0 - -# Higher-level EV value for EV 20 and input 31 -set fmri(evg31.20) 0 - -# Higher-level EV value for EV 20 and input 32 -set fmri(evg32.20) 0 - -# Higher-level EV value for EV 20 and input 33 -set fmri(evg33.20) 0 - -# Higher-level EV value for EV 20 and input 34 -set fmri(evg34.20) 0 - -# Higher-level EV value for EV 20 and input 35 -set fmri(evg35.20) 0 - -# Higher-level EV value for EV 20 and input 36 -set fmri(evg36.20) 0 - -# Higher-level EV value for EV 20 and input 37 -set fmri(evg37.20) 0 - -# Higher-level EV value for EV 20 and input 38 -set fmri(evg38.20) 0 - -# Higher-level EV value for EV 20 and input 39 -set fmri(evg39.20) 1.0 - -# Higher-level EV value for EV 20 and input 40 -set fmri(evg40.20) 1.0 - -# Higher-level EV value for EV 20 and input 41 -set fmri(evg41.20) 0 - -# Higher-level EV value for EV 20 and input 42 -set fmri(evg42.20) 0 - -# Higher-level EV value for EV 20 and input 43 -set fmri(evg43.20) 0 - -# Higher-level EV value for EV 20 and input 44 -set fmri(evg44.20) 0 - -# Higher-level EV value for EV 20 and input 45 -set fmri(evg45.20) 0 - -# Higher-level EV value for EV 20 and input 46 -set fmri(evg46.20) 0 - -# Higher-level EV value for EV 20 and input 47 -set fmri(evg47.20) 0 - -# Higher-level EV value for EV 20 and input 48 -set fmri(evg48.20) 0 - -# Higher-level EV value for EV 20 and input 49 -set fmri(evg49.20) 0 - -# Higher-level EV value for EV 20 and input 50 -set fmri(evg50.20) 0 - -# Higher-level EV value for EV 20 and input 51 -set fmri(evg51.20) 0 - -# Higher-level EV value for EV 20 and input 52 -set fmri(evg52.20) 0 - -# EV 21 title -set fmri(evtitle21) "" - -# Basic waveform shape (EV 21) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape21) 2 - -# Convolution (EV 21) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve21) 0 - -# Convolve phase (EV 21) -set fmri(convolve_phase21) 0 - -# Apply temporal filtering (EV 21) -set fmri(tempfilt_yn21) 0 - -# Add temporal derivative (EV 21) -set fmri(deriv_yn21) 0 - -# Custom EV file (EV 21) -set fmri(custom21) "dummy" - -# Orthogonalise EV 21 wrt EV 0 -set fmri(ortho21.0) 0 - -# Orthogonalise EV 21 wrt EV 1 -set fmri(ortho21.1) 0 - -# Orthogonalise EV 21 wrt EV 2 -set fmri(ortho21.2) 0 - -# Orthogonalise EV 21 wrt EV 3 -set fmri(ortho21.3) 0 - -# Orthogonalise EV 21 wrt EV 4 -set fmri(ortho21.4) 0 - -# Orthogonalise EV 21 wrt EV 5 -set fmri(ortho21.5) 0 - -# Orthogonalise EV 21 wrt EV 6 -set fmri(ortho21.6) 0 - -# Orthogonalise EV 21 wrt EV 7 -set fmri(ortho21.7) 0 - -# Orthogonalise EV 21 wrt EV 8 -set fmri(ortho21.8) 0 - -# Orthogonalise EV 21 wrt EV 9 -set fmri(ortho21.9) 0 - -# Orthogonalise EV 21 wrt EV 10 -set fmri(ortho21.10) 0 - -# Orthogonalise EV 21 wrt EV 11 -set fmri(ortho21.11) 0 - -# Orthogonalise EV 21 wrt EV 12 -set fmri(ortho21.12) 0 - -# Orthogonalise EV 21 wrt EV 13 -set fmri(ortho21.13) 0 - -# Orthogonalise EV 21 wrt EV 14 -set fmri(ortho21.14) 0 - -# Orthogonalise EV 21 wrt EV 15 -set fmri(ortho21.15) 0 - -# Orthogonalise EV 21 wrt EV 16 -set fmri(ortho21.16) 0 - -# Orthogonalise EV 21 wrt EV 17 -set fmri(ortho21.17) 0 - -# Orthogonalise EV 21 wrt EV 18 -set fmri(ortho21.18) 0 - -# Orthogonalise EV 21 wrt EV 19 -set fmri(ortho21.19) 0 - -# Orthogonalise EV 21 wrt EV 20 -set fmri(ortho21.20) 0 - -# Orthogonalise EV 21 wrt EV 21 -set fmri(ortho21.21) 0 - -# Orthogonalise EV 21 wrt EV 22 -set fmri(ortho21.22) 0 - -# Orthogonalise EV 21 wrt EV 23 -set fmri(ortho21.23) 0 - -# Orthogonalise EV 21 wrt EV 24 -set fmri(ortho21.24) 0 - -# Orthogonalise EV 21 wrt EV 25 -set fmri(ortho21.25) 0 - -# Orthogonalise EV 21 wrt EV 26 -set fmri(ortho21.26) 0 - -# Higher-level EV value for EV 21 and input 1 -set fmri(evg1.21) 0 - -# Higher-level EV value for EV 21 and input 2 -set fmri(evg2.21) 0 - -# Higher-level EV value for EV 21 and input 3 -set fmri(evg3.21) 0 - -# Higher-level EV value for EV 21 and input 4 -set fmri(evg4.21) 0 - -# Higher-level EV value for EV 21 and input 5 -set fmri(evg5.21) 0 - -# Higher-level EV value for EV 21 and input 6 -set fmri(evg6.21) 0 - -# Higher-level EV value for EV 21 and input 7 -set fmri(evg7.21) 0 - -# Higher-level EV value for EV 21 and input 8 -set fmri(evg8.21) 0 - -# Higher-level EV value for EV 21 and input 9 -set fmri(evg9.21) 0 - -# Higher-level EV value for EV 21 and input 10 -set fmri(evg10.21) 0 - -# Higher-level EV value for EV 21 and input 11 -set fmri(evg11.21) 0 - -# Higher-level EV value for EV 21 and input 12 -set fmri(evg12.21) 0 - -# Higher-level EV value for EV 21 and input 13 -set fmri(evg13.21) 0 - -# Higher-level EV value for EV 21 and input 14 -set fmri(evg14.21) 0 - -# Higher-level EV value for EV 21 and input 15 -set fmri(evg15.21) 0 - -# Higher-level EV value for EV 21 and input 16 -set fmri(evg16.21) 0 - -# Higher-level EV value for EV 21 and input 17 -set fmri(evg17.21) 0 - -# Higher-level EV value for EV 21 and input 18 -set fmri(evg18.21) 0 - -# Higher-level EV value for EV 21 and input 19 -set fmri(evg19.21) 0 - -# Higher-level EV value for EV 21 and input 20 -set fmri(evg20.21) 0 - -# Higher-level EV value for EV 21 and input 21 -set fmri(evg21.21) 0 - -# Higher-level EV value for EV 21 and input 22 -set fmri(evg22.21) 0 - -# Higher-level EV value for EV 21 and input 23 -set fmri(evg23.21) 0 - -# Higher-level EV value for EV 21 and input 24 -set fmri(evg24.21) 0 - -# Higher-level EV value for EV 21 and input 25 -set fmri(evg25.21) 0 - -# Higher-level EV value for EV 21 and input 26 -set fmri(evg26.21) 0 - -# Higher-level EV value for EV 21 and input 27 -set fmri(evg27.21) 0 - -# Higher-level EV value for EV 21 and input 28 -set fmri(evg28.21) 0 - -# Higher-level EV value for EV 21 and input 29 -set fmri(evg29.21) 0 - -# Higher-level EV value for EV 21 and input 30 -set fmri(evg30.21) 0 - -# Higher-level EV value for EV 21 and input 31 -set fmri(evg31.21) 0 - -# Higher-level EV value for EV 21 and input 32 -set fmri(evg32.21) 0 - -# Higher-level EV value for EV 21 and input 33 -set fmri(evg33.21) 0 - -# Higher-level EV value for EV 21 and input 34 -set fmri(evg34.21) 0 - -# Higher-level EV value for EV 21 and input 35 -set fmri(evg35.21) 0 - -# Higher-level EV value for EV 21 and input 36 -set fmri(evg36.21) 0 - -# Higher-level EV value for EV 21 and input 37 -set fmri(evg37.21) 0 - -# Higher-level EV value for EV 21 and input 38 -set fmri(evg38.21) 0 - -# Higher-level EV value for EV 21 and input 39 -set fmri(evg39.21) 0 - -# Higher-level EV value for EV 21 and input 40 -set fmri(evg40.21) 0 - -# Higher-level EV value for EV 21 and input 41 -set fmri(evg41.21) 1.0 - -# Higher-level EV value for EV 21 and input 42 -set fmri(evg42.21) 1.0 - -# Higher-level EV value for EV 21 and input 43 -set fmri(evg43.21) 0 - -# Higher-level EV value for EV 21 and input 44 -set fmri(evg44.21) 0 - -# Higher-level EV value for EV 21 and input 45 -set fmri(evg45.21) 0 - -# Higher-level EV value for EV 21 and input 46 -set fmri(evg46.21) 0 - -# Higher-level EV value for EV 21 and input 47 -set fmri(evg47.21) 0 - -# Higher-level EV value for EV 21 and input 48 -set fmri(evg48.21) 0 - -# Higher-level EV value for EV 21 and input 49 -set fmri(evg49.21) 0 - -# Higher-level EV value for EV 21 and input 50 -set fmri(evg50.21) 0 - -# Higher-level EV value for EV 21 and input 51 -set fmri(evg51.21) 0 - -# Higher-level EV value for EV 21 and input 52 -set fmri(evg52.21) 0 - -# EV 22 title -set fmri(evtitle22) "" - -# Basic waveform shape (EV 22) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape22) 2 - -# Convolution (EV 22) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve22) 0 - -# Convolve phase (EV 22) -set fmri(convolve_phase22) 0 - -# Apply temporal filtering (EV 22) -set fmri(tempfilt_yn22) 0 - -# Add temporal derivative (EV 22) -set fmri(deriv_yn22) 0 - -# Custom EV file (EV 22) -set fmri(custom22) "dummy" - -# Orthogonalise EV 22 wrt EV 0 -set fmri(ortho22.0) 0 - -# Orthogonalise EV 22 wrt EV 1 -set fmri(ortho22.1) 0 - -# Orthogonalise EV 22 wrt EV 2 -set fmri(ortho22.2) 0 - -# Orthogonalise EV 22 wrt EV 3 -set fmri(ortho22.3) 0 - -# Orthogonalise EV 22 wrt EV 4 -set fmri(ortho22.4) 0 - -# Orthogonalise EV 22 wrt EV 5 -set fmri(ortho22.5) 0 - -# Orthogonalise EV 22 wrt EV 6 -set fmri(ortho22.6) 0 - -# Orthogonalise EV 22 wrt EV 7 -set fmri(ortho22.7) 0 - -# Orthogonalise EV 22 wrt EV 8 -set fmri(ortho22.8) 0 - -# Orthogonalise EV 22 wrt EV 9 -set fmri(ortho22.9) 0 - -# Orthogonalise EV 22 wrt EV 10 -set fmri(ortho22.10) 0 - -# Orthogonalise EV 22 wrt EV 11 -set fmri(ortho22.11) 0 - -# Orthogonalise EV 22 wrt EV 12 -set fmri(ortho22.12) 0 - -# Orthogonalise EV 22 wrt EV 13 -set fmri(ortho22.13) 0 - -# Orthogonalise EV 22 wrt EV 14 -set fmri(ortho22.14) 0 - -# Orthogonalise EV 22 wrt EV 15 -set fmri(ortho22.15) 0 - -# Orthogonalise EV 22 wrt EV 16 -set fmri(ortho22.16) 0 - -# Orthogonalise EV 22 wrt EV 17 -set fmri(ortho22.17) 0 - -# Orthogonalise EV 22 wrt EV 18 -set fmri(ortho22.18) 0 - -# Orthogonalise EV 22 wrt EV 19 -set fmri(ortho22.19) 0 - -# Orthogonalise EV 22 wrt EV 20 -set fmri(ortho22.20) 0 - -# Orthogonalise EV 22 wrt EV 21 -set fmri(ortho22.21) 0 - -# Orthogonalise EV 22 wrt EV 22 -set fmri(ortho22.22) 0 - -# Orthogonalise EV 22 wrt EV 23 -set fmri(ortho22.23) 0 - -# Orthogonalise EV 22 wrt EV 24 -set fmri(ortho22.24) 0 - -# Orthogonalise EV 22 wrt EV 25 -set fmri(ortho22.25) 0 - -# Orthogonalise EV 22 wrt EV 26 -set fmri(ortho22.26) 0 - -# Higher-level EV value for EV 22 and input 1 -set fmri(evg1.22) 0 - -# Higher-level EV value for EV 22 and input 2 -set fmri(evg2.22) 0 - -# Higher-level EV value for EV 22 and input 3 -set fmri(evg3.22) 0 - -# Higher-level EV value for EV 22 and input 4 -set fmri(evg4.22) 0 - -# Higher-level EV value for EV 22 and input 5 -set fmri(evg5.22) 0 - -# Higher-level EV value for EV 22 and input 6 -set fmri(evg6.22) 0 - -# Higher-level EV value for EV 22 and input 7 -set fmri(evg7.22) 0 - -# Higher-level EV value for EV 22 and input 8 -set fmri(evg8.22) 0 - -# Higher-level EV value for EV 22 and input 9 -set fmri(evg9.22) 0 - -# Higher-level EV value for EV 22 and input 10 -set fmri(evg10.22) 0 - -# Higher-level EV value for EV 22 and input 11 -set fmri(evg11.22) 0 - -# Higher-level EV value for EV 22 and input 12 -set fmri(evg12.22) 0 - -# Higher-level EV value for EV 22 and input 13 -set fmri(evg13.22) 0 - -# Higher-level EV value for EV 22 and input 14 -set fmri(evg14.22) 0 - -# Higher-level EV value for EV 22 and input 15 -set fmri(evg15.22) 0 - -# Higher-level EV value for EV 22 and input 16 -set fmri(evg16.22) 0 - -# Higher-level EV value for EV 22 and input 17 -set fmri(evg17.22) 0 - -# Higher-level EV value for EV 22 and input 18 -set fmri(evg18.22) 0 - -# Higher-level EV value for EV 22 and input 19 -set fmri(evg19.22) 0 - -# Higher-level EV value for EV 22 and input 20 -set fmri(evg20.22) 0 - -# Higher-level EV value for EV 22 and input 21 -set fmri(evg21.22) 0 - -# Higher-level EV value for EV 22 and input 22 -set fmri(evg22.22) 0 - -# Higher-level EV value for EV 22 and input 23 -set fmri(evg23.22) 0 - -# Higher-level EV value for EV 22 and input 24 -set fmri(evg24.22) 0 - -# Higher-level EV value for EV 22 and input 25 -set fmri(evg25.22) 0 - -# Higher-level EV value for EV 22 and input 26 -set fmri(evg26.22) 0 - -# Higher-level EV value for EV 22 and input 27 -set fmri(evg27.22) 0 - -# Higher-level EV value for EV 22 and input 28 -set fmri(evg28.22) 0 - -# Higher-level EV value for EV 22 and input 29 -set fmri(evg29.22) 0 - -# Higher-level EV value for EV 22 and input 30 -set fmri(evg30.22) 0 - -# Higher-level EV value for EV 22 and input 31 -set fmri(evg31.22) 0 - -# Higher-level EV value for EV 22 and input 32 -set fmri(evg32.22) 0 - -# Higher-level EV value for EV 22 and input 33 -set fmri(evg33.22) 0 - -# Higher-level EV value for EV 22 and input 34 -set fmri(evg34.22) 0 - -# Higher-level EV value for EV 22 and input 35 -set fmri(evg35.22) 0 - -# Higher-level EV value for EV 22 and input 36 -set fmri(evg36.22) 0 - -# Higher-level EV value for EV 22 and input 37 -set fmri(evg37.22) 0 - -# Higher-level EV value for EV 22 and input 38 -set fmri(evg38.22) 0 - -# Higher-level EV value for EV 22 and input 39 -set fmri(evg39.22) 0 - -# Higher-level EV value for EV 22 and input 40 -set fmri(evg40.22) 0 - -# Higher-level EV value for EV 22 and input 41 -set fmri(evg41.22) 0 - -# Higher-level EV value for EV 22 and input 42 -set fmri(evg42.22) 0 - -# Higher-level EV value for EV 22 and input 43 -set fmri(evg43.22) 1.0 - -# Higher-level EV value for EV 22 and input 44 -set fmri(evg44.22) 1.0 - -# Higher-level EV value for EV 22 and input 45 -set fmri(evg45.22) 0 - -# Higher-level EV value for EV 22 and input 46 -set fmri(evg46.22) 0 - -# Higher-level EV value for EV 22 and input 47 -set fmri(evg47.22) 0 - -# Higher-level EV value for EV 22 and input 48 -set fmri(evg48.22) 0 - -# Higher-level EV value for EV 22 and input 49 -set fmri(evg49.22) 0 - -# Higher-level EV value for EV 22 and input 50 -set fmri(evg50.22) 0 - -# Higher-level EV value for EV 22 and input 51 -set fmri(evg51.22) 0 - -# Higher-level EV value for EV 22 and input 52 -set fmri(evg52.22) 0 - -# EV 23 title -set fmri(evtitle23) "" - -# Basic waveform shape (EV 23) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape23) 2 - -# Convolution (EV 23) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve23) 0 - -# Convolve phase (EV 23) -set fmri(convolve_phase23) 0 - -# Apply temporal filtering (EV 23) -set fmri(tempfilt_yn23) 0 - -# Add temporal derivative (EV 23) -set fmri(deriv_yn23) 0 - -# Custom EV file (EV 23) -set fmri(custom23) "dummy" - -# Orthogonalise EV 23 wrt EV 0 -set fmri(ortho23.0) 0 - -# Orthogonalise EV 23 wrt EV 1 -set fmri(ortho23.1) 0 - -# Orthogonalise EV 23 wrt EV 2 -set fmri(ortho23.2) 0 - -# Orthogonalise EV 23 wrt EV 3 -set fmri(ortho23.3) 0 - -# Orthogonalise EV 23 wrt EV 4 -set fmri(ortho23.4) 0 - -# Orthogonalise EV 23 wrt EV 5 -set fmri(ortho23.5) 0 - -# Orthogonalise EV 23 wrt EV 6 -set fmri(ortho23.6) 0 - -# Orthogonalise EV 23 wrt EV 7 -set fmri(ortho23.7) 0 - -# Orthogonalise EV 23 wrt EV 8 -set fmri(ortho23.8) 0 - -# Orthogonalise EV 23 wrt EV 9 -set fmri(ortho23.9) 0 - -# Orthogonalise EV 23 wrt EV 10 -set fmri(ortho23.10) 0 - -# Orthogonalise EV 23 wrt EV 11 -set fmri(ortho23.11) 0 - -# Orthogonalise EV 23 wrt EV 12 -set fmri(ortho23.12) 0 - -# Orthogonalise EV 23 wrt EV 13 -set fmri(ortho23.13) 0 - -# Orthogonalise EV 23 wrt EV 14 -set fmri(ortho23.14) 0 - -# Orthogonalise EV 23 wrt EV 15 -set fmri(ortho23.15) 0 - -# Orthogonalise EV 23 wrt EV 16 -set fmri(ortho23.16) 0 - -# Orthogonalise EV 23 wrt EV 17 -set fmri(ortho23.17) 0 - -# Orthogonalise EV 23 wrt EV 18 -set fmri(ortho23.18) 0 - -# Orthogonalise EV 23 wrt EV 19 -set fmri(ortho23.19) 0 - -# Orthogonalise EV 23 wrt EV 20 -set fmri(ortho23.20) 0 - -# Orthogonalise EV 23 wrt EV 21 -set fmri(ortho23.21) 0 - -# Orthogonalise EV 23 wrt EV 22 -set fmri(ortho23.22) 0 - -# Orthogonalise EV 23 wrt EV 23 -set fmri(ortho23.23) 0 - -# Orthogonalise EV 23 wrt EV 24 -set fmri(ortho23.24) 0 - -# Orthogonalise EV 23 wrt EV 25 -set fmri(ortho23.25) 0 - -# Orthogonalise EV 23 wrt EV 26 -set fmri(ortho23.26) 0 - -# Higher-level EV value for EV 23 and input 1 -set fmri(evg1.23) 0 - -# Higher-level EV value for EV 23 and input 2 -set fmri(evg2.23) 0 - -# Higher-level EV value for EV 23 and input 3 -set fmri(evg3.23) 0 - -# Higher-level EV value for EV 23 and input 4 -set fmri(evg4.23) 0 - -# Higher-level EV value for EV 23 and input 5 -set fmri(evg5.23) 0 - -# Higher-level EV value for EV 23 and input 6 -set fmri(evg6.23) 0 - -# Higher-level EV value for EV 23 and input 7 -set fmri(evg7.23) 0 - -# Higher-level EV value for EV 23 and input 8 -set fmri(evg8.23) 0 - -# Higher-level EV value for EV 23 and input 9 -set fmri(evg9.23) 0 - -# Higher-level EV value for EV 23 and input 10 -set fmri(evg10.23) 0 - -# Higher-level EV value for EV 23 and input 11 -set fmri(evg11.23) 0 - -# Higher-level EV value for EV 23 and input 12 -set fmri(evg12.23) 0 - -# Higher-level EV value for EV 23 and input 13 -set fmri(evg13.23) 0 - -# Higher-level EV value for EV 23 and input 14 -set fmri(evg14.23) 0 - -# Higher-level EV value for EV 23 and input 15 -set fmri(evg15.23) 0 - -# Higher-level EV value for EV 23 and input 16 -set fmri(evg16.23) 0 - -# Higher-level EV value for EV 23 and input 17 -set fmri(evg17.23) 0 - -# Higher-level EV value for EV 23 and input 18 -set fmri(evg18.23) 0 - -# Higher-level EV value for EV 23 and input 19 -set fmri(evg19.23) 0 - -# Higher-level EV value for EV 23 and input 20 -set fmri(evg20.23) 0 - -# Higher-level EV value for EV 23 and input 21 -set fmri(evg21.23) 0 - -# Higher-level EV value for EV 23 and input 22 -set fmri(evg22.23) 0 - -# Higher-level EV value for EV 23 and input 23 -set fmri(evg23.23) 0 - -# Higher-level EV value for EV 23 and input 24 -set fmri(evg24.23) 0 - -# Higher-level EV value for EV 23 and input 25 -set fmri(evg25.23) 0 - -# Higher-level EV value for EV 23 and input 26 -set fmri(evg26.23) 0 - -# Higher-level EV value for EV 23 and input 27 -set fmri(evg27.23) 0 - -# Higher-level EV value for EV 23 and input 28 -set fmri(evg28.23) 0 - -# Higher-level EV value for EV 23 and input 29 -set fmri(evg29.23) 0 - -# Higher-level EV value for EV 23 and input 30 -set fmri(evg30.23) 0 - -# Higher-level EV value for EV 23 and input 31 -set fmri(evg31.23) 0 - -# Higher-level EV value for EV 23 and input 32 -set fmri(evg32.23) 0 - -# Higher-level EV value for EV 23 and input 33 -set fmri(evg33.23) 0 - -# Higher-level EV value for EV 23 and input 34 -set fmri(evg34.23) 0 - -# Higher-level EV value for EV 23 and input 35 -set fmri(evg35.23) 0 - -# Higher-level EV value for EV 23 and input 36 -set fmri(evg36.23) 0 - -# Higher-level EV value for EV 23 and input 37 -set fmri(evg37.23) 0 - -# Higher-level EV value for EV 23 and input 38 -set fmri(evg38.23) 0 - -# Higher-level EV value for EV 23 and input 39 -set fmri(evg39.23) 0 - -# Higher-level EV value for EV 23 and input 40 -set fmri(evg40.23) 0 - -# Higher-level EV value for EV 23 and input 41 -set fmri(evg41.23) 0 - -# Higher-level EV value for EV 23 and input 42 -set fmri(evg42.23) 0 - -# Higher-level EV value for EV 23 and input 43 -set fmri(evg43.23) 0 - -# Higher-level EV value for EV 23 and input 44 -set fmri(evg44.23) 0 - -# Higher-level EV value for EV 23 and input 45 -set fmri(evg45.23) 1.0 - -# Higher-level EV value for EV 23 and input 46 -set fmri(evg46.23) 1.0 - -# Higher-level EV value for EV 23 and input 47 -set fmri(evg47.23) 0 - -# Higher-level EV value for EV 23 and input 48 -set fmri(evg48.23) 0 - -# Higher-level EV value for EV 23 and input 49 -set fmri(evg49.23) 0 - -# Higher-level EV value for EV 23 and input 50 -set fmri(evg50.23) 0 - -# Higher-level EV value for EV 23 and input 51 -set fmri(evg51.23) 0 - -# Higher-level EV value for EV 23 and input 52 -set fmri(evg52.23) 0 - -# EV 24 title -set fmri(evtitle24) "" - -# Basic waveform shape (EV 24) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape24) 2 - -# Convolution (EV 24) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve24) 0 - -# Convolve phase (EV 24) -set fmri(convolve_phase24) 0 - -# Apply temporal filtering (EV 24) -set fmri(tempfilt_yn24) 0 - -# Add temporal derivative (EV 24) -set fmri(deriv_yn24) 0 - -# Custom EV file (EV 24) -set fmri(custom24) "dummy" - -# Orthogonalise EV 24 wrt EV 0 -set fmri(ortho24.0) 0 - -# Orthogonalise EV 24 wrt EV 1 -set fmri(ortho24.1) 0 - -# Orthogonalise EV 24 wrt EV 2 -set fmri(ortho24.2) 0 - -# Orthogonalise EV 24 wrt EV 3 -set fmri(ortho24.3) 0 - -# Orthogonalise EV 24 wrt EV 4 -set fmri(ortho24.4) 0 - -# Orthogonalise EV 24 wrt EV 5 -set fmri(ortho24.5) 0 - -# Orthogonalise EV 24 wrt EV 6 -set fmri(ortho24.6) 0 - -# Orthogonalise EV 24 wrt EV 7 -set fmri(ortho24.7) 0 - -# Orthogonalise EV 24 wrt EV 8 -set fmri(ortho24.8) 0 - -# Orthogonalise EV 24 wrt EV 9 -set fmri(ortho24.9) 0 - -# Orthogonalise EV 24 wrt EV 10 -set fmri(ortho24.10) 0 - -# Orthogonalise EV 24 wrt EV 11 -set fmri(ortho24.11) 0 - -# Orthogonalise EV 24 wrt EV 12 -set fmri(ortho24.12) 0 - -# Orthogonalise EV 24 wrt EV 13 -set fmri(ortho24.13) 0 - -# Orthogonalise EV 24 wrt EV 14 -set fmri(ortho24.14) 0 - -# Orthogonalise EV 24 wrt EV 15 -set fmri(ortho24.15) 0 - -# Orthogonalise EV 24 wrt EV 16 -set fmri(ortho24.16) 0 - -# Orthogonalise EV 24 wrt EV 17 -set fmri(ortho24.17) 0 - -# Orthogonalise EV 24 wrt EV 18 -set fmri(ortho24.18) 0 - -# Orthogonalise EV 24 wrt EV 19 -set fmri(ortho24.19) 0 - -# Orthogonalise EV 24 wrt EV 20 -set fmri(ortho24.20) 0 - -# Orthogonalise EV 24 wrt EV 21 -set fmri(ortho24.21) 0 - -# Orthogonalise EV 24 wrt EV 22 -set fmri(ortho24.22) 0 - -# Orthogonalise EV 24 wrt EV 23 -set fmri(ortho24.23) 0 - -# Orthogonalise EV 24 wrt EV 24 -set fmri(ortho24.24) 0 - -# Orthogonalise EV 24 wrt EV 25 -set fmri(ortho24.25) 0 - -# Orthogonalise EV 24 wrt EV 26 -set fmri(ortho24.26) 0 - -# Higher-level EV value for EV 24 and input 1 -set fmri(evg1.24) 0 - -# Higher-level EV value for EV 24 and input 2 -set fmri(evg2.24) 0 - -# Higher-level EV value for EV 24 and input 3 -set fmri(evg3.24) 0 - -# Higher-level EV value for EV 24 and input 4 -set fmri(evg4.24) 0 - -# Higher-level EV value for EV 24 and input 5 -set fmri(evg5.24) 0 - -# Higher-level EV value for EV 24 and input 6 -set fmri(evg6.24) 0 - -# Higher-level EV value for EV 24 and input 7 -set fmri(evg7.24) 0 - -# Higher-level EV value for EV 24 and input 8 -set fmri(evg8.24) 0 - -# Higher-level EV value for EV 24 and input 9 -set fmri(evg9.24) 0 - -# Higher-level EV value for EV 24 and input 10 -set fmri(evg10.24) 0 - -# Higher-level EV value for EV 24 and input 11 -set fmri(evg11.24) 0 - -# Higher-level EV value for EV 24 and input 12 -set fmri(evg12.24) 0 - -# Higher-level EV value for EV 24 and input 13 -set fmri(evg13.24) 0 - -# Higher-level EV value for EV 24 and input 14 -set fmri(evg14.24) 0 - -# Higher-level EV value for EV 24 and input 15 -set fmri(evg15.24) 0 - -# Higher-level EV value for EV 24 and input 16 -set fmri(evg16.24) 0 - -# Higher-level EV value for EV 24 and input 17 -set fmri(evg17.24) 0 - -# Higher-level EV value for EV 24 and input 18 -set fmri(evg18.24) 0 - -# Higher-level EV value for EV 24 and input 19 -set fmri(evg19.24) 0 - -# Higher-level EV value for EV 24 and input 20 -set fmri(evg20.24) 0 - -# Higher-level EV value for EV 24 and input 21 -set fmri(evg21.24) 0 - -# Higher-level EV value for EV 24 and input 22 -set fmri(evg22.24) 0 - -# Higher-level EV value for EV 24 and input 23 -set fmri(evg23.24) 0 - -# Higher-level EV value for EV 24 and input 24 -set fmri(evg24.24) 0 - -# Higher-level EV value for EV 24 and input 25 -set fmri(evg25.24) 0 - -# Higher-level EV value for EV 24 and input 26 -set fmri(evg26.24) 0 - -# Higher-level EV value for EV 24 and input 27 -set fmri(evg27.24) 0 - -# Higher-level EV value for EV 24 and input 28 -set fmri(evg28.24) 0 - -# Higher-level EV value for EV 24 and input 29 -set fmri(evg29.24) 0 - -# Higher-level EV value for EV 24 and input 30 -set fmri(evg30.24) 0 - -# Higher-level EV value for EV 24 and input 31 -set fmri(evg31.24) 0 - -# Higher-level EV value for EV 24 and input 32 -set fmri(evg32.24) 0 - -# Higher-level EV value for EV 24 and input 33 -set fmri(evg33.24) 0 - -# Higher-level EV value for EV 24 and input 34 -set fmri(evg34.24) 0 - -# Higher-level EV value for EV 24 and input 35 -set fmri(evg35.24) 0 - -# Higher-level EV value for EV 24 and input 36 -set fmri(evg36.24) 0 - -# Higher-level EV value for EV 24 and input 37 -set fmri(evg37.24) 0 - -# Higher-level EV value for EV 24 and input 38 -set fmri(evg38.24) 0 - -# Higher-level EV value for EV 24 and input 39 -set fmri(evg39.24) 0 - -# Higher-level EV value for EV 24 and input 40 -set fmri(evg40.24) 0 - -# Higher-level EV value for EV 24 and input 41 -set fmri(evg41.24) 0 - -# Higher-level EV value for EV 24 and input 42 -set fmri(evg42.24) 0 - -# Higher-level EV value for EV 24 and input 43 -set fmri(evg43.24) 0 - -# Higher-level EV value for EV 24 and input 44 -set fmri(evg44.24) 0 - -# Higher-level EV value for EV 24 and input 45 -set fmri(evg45.24) 0 - -# Higher-level EV value for EV 24 and input 46 -set fmri(evg46.24) 0 - -# Higher-level EV value for EV 24 and input 47 -set fmri(evg47.24) 1.0 - -# Higher-level EV value for EV 24 and input 48 -set fmri(evg48.24) 1.0 - -# Higher-level EV value for EV 24 and input 49 -set fmri(evg49.24) 0 - -# Higher-level EV value for EV 24 and input 50 -set fmri(evg50.24) 0 - -# Higher-level EV value for EV 24 and input 51 -set fmri(evg51.24) 0 - -# Higher-level EV value for EV 24 and input 52 -set fmri(evg52.24) 0 - -# EV 25 title -set fmri(evtitle25) "" - -# Basic waveform shape (EV 25) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape25) 2 - -# Convolution (EV 25) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve25) 0 - -# Convolve phase (EV 25) -set fmri(convolve_phase25) 0 - -# Apply temporal filtering (EV 25) -set fmri(tempfilt_yn25) 0 - -# Add temporal derivative (EV 25) -set fmri(deriv_yn25) 0 - -# Custom EV file (EV 25) -set fmri(custom25) "dummy" - -# Orthogonalise EV 25 wrt EV 0 -set fmri(ortho25.0) 0 - -# Orthogonalise EV 25 wrt EV 1 -set fmri(ortho25.1) 0 - -# Orthogonalise EV 25 wrt EV 2 -set fmri(ortho25.2) 0 - -# Orthogonalise EV 25 wrt EV 3 -set fmri(ortho25.3) 0 - -# Orthogonalise EV 25 wrt EV 4 -set fmri(ortho25.4) 0 - -# Orthogonalise EV 25 wrt EV 5 -set fmri(ortho25.5) 0 - -# Orthogonalise EV 25 wrt EV 6 -set fmri(ortho25.6) 0 - -# Orthogonalise EV 25 wrt EV 7 -set fmri(ortho25.7) 0 - -# Orthogonalise EV 25 wrt EV 8 -set fmri(ortho25.8) 0 - -# Orthogonalise EV 25 wrt EV 9 -set fmri(ortho25.9) 0 - -# Orthogonalise EV 25 wrt EV 10 -set fmri(ortho25.10) 0 - -# Orthogonalise EV 25 wrt EV 11 -set fmri(ortho25.11) 0 - -# Orthogonalise EV 25 wrt EV 12 -set fmri(ortho25.12) 0 - -# Orthogonalise EV 25 wrt EV 13 -set fmri(ortho25.13) 0 - -# Orthogonalise EV 25 wrt EV 14 -set fmri(ortho25.14) 0 - -# Orthogonalise EV 25 wrt EV 15 -set fmri(ortho25.15) 0 - -# Orthogonalise EV 25 wrt EV 16 -set fmri(ortho25.16) 0 - -# Orthogonalise EV 25 wrt EV 17 -set fmri(ortho25.17) 0 - -# Orthogonalise EV 25 wrt EV 18 -set fmri(ortho25.18) 0 - -# Orthogonalise EV 25 wrt EV 19 -set fmri(ortho25.19) 0 - -# Orthogonalise EV 25 wrt EV 20 -set fmri(ortho25.20) 0 - -# Orthogonalise EV 25 wrt EV 21 -set fmri(ortho25.21) 0 - -# Orthogonalise EV 25 wrt EV 22 -set fmri(ortho25.22) 0 - -# Orthogonalise EV 25 wrt EV 23 -set fmri(ortho25.23) 0 - -# Orthogonalise EV 25 wrt EV 24 -set fmri(ortho25.24) 0 - -# Orthogonalise EV 25 wrt EV 25 -set fmri(ortho25.25) 0 - -# Orthogonalise EV 25 wrt EV 26 -set fmri(ortho25.26) 0 - -# Higher-level EV value for EV 25 and input 1 -set fmri(evg1.25) 0 - -# Higher-level EV value for EV 25 and input 2 -set fmri(evg2.25) 0 - -# Higher-level EV value for EV 25 and input 3 -set fmri(evg3.25) 0 - -# Higher-level EV value for EV 25 and input 4 -set fmri(evg4.25) 0 - -# Higher-level EV value for EV 25 and input 5 -set fmri(evg5.25) 0 - -# Higher-level EV value for EV 25 and input 6 -set fmri(evg6.25) 0 - -# Higher-level EV value for EV 25 and input 7 -set fmri(evg7.25) 0 - -# Higher-level EV value for EV 25 and input 8 -set fmri(evg8.25) 0 - -# Higher-level EV value for EV 25 and input 9 -set fmri(evg9.25) 0 - -# Higher-level EV value for EV 25 and input 10 -set fmri(evg10.25) 0 - -# Higher-level EV value for EV 25 and input 11 -set fmri(evg11.25) 0 - -# Higher-level EV value for EV 25 and input 12 -set fmri(evg12.25) 0 - -# Higher-level EV value for EV 25 and input 13 -set fmri(evg13.25) 0 - -# Higher-level EV value for EV 25 and input 14 -set fmri(evg14.25) 0 - -# Higher-level EV value for EV 25 and input 15 -set fmri(evg15.25) 0 - -# Higher-level EV value for EV 25 and input 16 -set fmri(evg16.25) 0 - -# Higher-level EV value for EV 25 and input 17 -set fmri(evg17.25) 0 - -# Higher-level EV value for EV 25 and input 18 -set fmri(evg18.25) 0 - -# Higher-level EV value for EV 25 and input 19 -set fmri(evg19.25) 0 - -# Higher-level EV value for EV 25 and input 20 -set fmri(evg20.25) 0 - -# Higher-level EV value for EV 25 and input 21 -set fmri(evg21.25) 0 - -# Higher-level EV value for EV 25 and input 22 -set fmri(evg22.25) 0 - -# Higher-level EV value for EV 25 and input 23 -set fmri(evg23.25) 0 - -# Higher-level EV value for EV 25 and input 24 -set fmri(evg24.25) 0 - -# Higher-level EV value for EV 25 and input 25 -set fmri(evg25.25) 0 - -# Higher-level EV value for EV 25 and input 26 -set fmri(evg26.25) 0 - -# Higher-level EV value for EV 25 and input 27 -set fmri(evg27.25) 0 - -# Higher-level EV value for EV 25 and input 28 -set fmri(evg28.25) 0 - -# Higher-level EV value for EV 25 and input 29 -set fmri(evg29.25) 0 - -# Higher-level EV value for EV 25 and input 30 -set fmri(evg30.25) 0 - -# Higher-level EV value for EV 25 and input 31 -set fmri(evg31.25) 0 - -# Higher-level EV value for EV 25 and input 32 -set fmri(evg32.25) 0 - -# Higher-level EV value for EV 25 and input 33 -set fmri(evg33.25) 0 - -# Higher-level EV value for EV 25 and input 34 -set fmri(evg34.25) 0 - -# Higher-level EV value for EV 25 and input 35 -set fmri(evg35.25) 0 - -# Higher-level EV value for EV 25 and input 36 -set fmri(evg36.25) 0 - -# Higher-level EV value for EV 25 and input 37 -set fmri(evg37.25) 0 - -# Higher-level EV value for EV 25 and input 38 -set fmri(evg38.25) 0 - -# Higher-level EV value for EV 25 and input 39 -set fmri(evg39.25) 0 - -# Higher-level EV value for EV 25 and input 40 -set fmri(evg40.25) 0 - -# Higher-level EV value for EV 25 and input 41 -set fmri(evg41.25) 0 - -# Higher-level EV value for EV 25 and input 42 -set fmri(evg42.25) 0 - -# Higher-level EV value for EV 25 and input 43 -set fmri(evg43.25) 0 - -# Higher-level EV value for EV 25 and input 44 -set fmri(evg44.25) 0 - -# Higher-level EV value for EV 25 and input 45 -set fmri(evg45.25) 0 - -# Higher-level EV value for EV 25 and input 46 -set fmri(evg46.25) 0 - -# Higher-level EV value for EV 25 and input 47 -set fmri(evg47.25) 0 - -# Higher-level EV value for EV 25 and input 48 -set fmri(evg48.25) 0 - -# Higher-level EV value for EV 25 and input 49 -set fmri(evg49.25) 1.0 - -# Higher-level EV value for EV 25 and input 50 -set fmri(evg50.25) 1.0 - -# Higher-level EV value for EV 25 and input 51 -set fmri(evg51.25) 0 - -# Higher-level EV value for EV 25 and input 52 -set fmri(evg52.25) 0 - -# EV 26 title -set fmri(evtitle26) "" - -# Basic waveform shape (EV 26) -# 0 : Square -# 1 : Sinusoid -# 2 : Custom (1 entry per volume) -# 3 : Custom (3 column format) -# 4 : Interaction -# 10 : Empty (all zeros) -set fmri(shape26) 2 - -# Convolution (EV 26) -# 0 : None -# 1 : Gaussian -# 2 : Gamma -# 3 : Double-Gamma HRF -# 4 : Gamma basis functions -# 5 : Sine basis functions -# 6 : FIR basis functions -# 8 : Alternate Double-Gamma -set fmri(convolve26) 0 - -# Convolve phase (EV 26) -set fmri(convolve_phase26) 0 - -# Apply temporal filtering (EV 26) -set fmri(tempfilt_yn26) 0 - -# Add temporal derivative (EV 26) -set fmri(deriv_yn26) 0 - -# Custom EV file (EV 26) -set fmri(custom26) "dummy" - -# Orthogonalise EV 26 wrt EV 0 -set fmri(ortho26.0) 0 - -# Orthogonalise EV 26 wrt EV 1 -set fmri(ortho26.1) 0 - -# Orthogonalise EV 26 wrt EV 2 -set fmri(ortho26.2) 0 - -# Orthogonalise EV 26 wrt EV 3 -set fmri(ortho26.3) 0 - -# Orthogonalise EV 26 wrt EV 4 -set fmri(ortho26.4) 0 - -# Orthogonalise EV 26 wrt EV 5 -set fmri(ortho26.5) 0 - -# Orthogonalise EV 26 wrt EV 6 -set fmri(ortho26.6) 0 - -# Orthogonalise EV 26 wrt EV 7 -set fmri(ortho26.7) 0 - -# Orthogonalise EV 26 wrt EV 8 -set fmri(ortho26.8) 0 - -# Orthogonalise EV 26 wrt EV 9 -set fmri(ortho26.9) 0 - -# Orthogonalise EV 26 wrt EV 10 -set fmri(ortho26.10) 0 - -# Orthogonalise EV 26 wrt EV 11 -set fmri(ortho26.11) 0 - -# Orthogonalise EV 26 wrt EV 12 -set fmri(ortho26.12) 0 - -# Orthogonalise EV 26 wrt EV 13 -set fmri(ortho26.13) 0 - -# Orthogonalise EV 26 wrt EV 14 -set fmri(ortho26.14) 0 - -# Orthogonalise EV 26 wrt EV 15 -set fmri(ortho26.15) 0 - -# Orthogonalise EV 26 wrt EV 16 -set fmri(ortho26.16) 0 - -# Orthogonalise EV 26 wrt EV 17 -set fmri(ortho26.17) 0 - -# Orthogonalise EV 26 wrt EV 18 -set fmri(ortho26.18) 0 - -# Orthogonalise EV 26 wrt EV 19 -set fmri(ortho26.19) 0 - -# Orthogonalise EV 26 wrt EV 20 -set fmri(ortho26.20) 0 - -# Orthogonalise EV 26 wrt EV 21 -set fmri(ortho26.21) 0 - -# Orthogonalise EV 26 wrt EV 22 -set fmri(ortho26.22) 0 - -# Orthogonalise EV 26 wrt EV 23 -set fmri(ortho26.23) 0 - -# Orthogonalise EV 26 wrt EV 24 -set fmri(ortho26.24) 0 - -# Orthogonalise EV 26 wrt EV 25 -set fmri(ortho26.25) 0 - -# Orthogonalise EV 26 wrt EV 26 -set fmri(ortho26.26) 0 - -# Higher-level EV value for EV 26 and input 1 -set fmri(evg1.26) 0 - -# Higher-level EV value for EV 26 and input 2 -set fmri(evg2.26) 0 - -# Higher-level EV value for EV 26 and input 3 -set fmri(evg3.26) 0 - -# Higher-level EV value for EV 26 and input 4 -set fmri(evg4.26) 0 - -# Higher-level EV value for EV 26 and input 5 -set fmri(evg5.26) 0 - -# Higher-level EV value for EV 26 and input 6 -set fmri(evg6.26) 0 - -# Higher-level EV value for EV 26 and input 7 -set fmri(evg7.26) 0 - -# Higher-level EV value for EV 26 and input 8 -set fmri(evg8.26) 0 - -# Higher-level EV value for EV 26 and input 9 -set fmri(evg9.26) 0 - -# Higher-level EV value for EV 26 and input 10 -set fmri(evg10.26) 0 - -# Higher-level EV value for EV 26 and input 11 -set fmri(evg11.26) 0 - -# Higher-level EV value for EV 26 and input 12 -set fmri(evg12.26) 0 - -# Higher-level EV value for EV 26 and input 13 -set fmri(evg13.26) 0 - -# Higher-level EV value for EV 26 and input 14 -set fmri(evg14.26) 0 - -# Higher-level EV value for EV 26 and input 15 -set fmri(evg15.26) 0 - -# Higher-level EV value for EV 26 and input 16 -set fmri(evg16.26) 0 - -# Higher-level EV value for EV 26 and input 17 -set fmri(evg17.26) 0 - -# Higher-level EV value for EV 26 and input 18 -set fmri(evg18.26) 0 - -# Higher-level EV value for EV 26 and input 19 -set fmri(evg19.26) 0 - -# Higher-level EV value for EV 26 and input 20 -set fmri(evg20.26) 0 - -# Higher-level EV value for EV 26 and input 21 -set fmri(evg21.26) 0 - -# Higher-level EV value for EV 26 and input 22 -set fmri(evg22.26) 0 - -# Higher-level EV value for EV 26 and input 23 -set fmri(evg23.26) 0 - -# Higher-level EV value for EV 26 and input 24 -set fmri(evg24.26) 0 - -# Higher-level EV value for EV 26 and input 25 -set fmri(evg25.26) 0 - -# Higher-level EV value for EV 26 and input 26 -set fmri(evg26.26) 0 - -# Higher-level EV value for EV 26 and input 27 -set fmri(evg27.26) 0 - -# Higher-level EV value for EV 26 and input 28 -set fmri(evg28.26) 0 - -# Higher-level EV value for EV 26 and input 29 -set fmri(evg29.26) 0 - -# Higher-level EV value for EV 26 and input 30 -set fmri(evg30.26) 0 - -# Higher-level EV value for EV 26 and input 31 -set fmri(evg31.26) 0 - -# Higher-level EV value for EV 26 and input 32 -set fmri(evg32.26) 0 - -# Higher-level EV value for EV 26 and input 33 -set fmri(evg33.26) 0 - -# Higher-level EV value for EV 26 and input 34 -set fmri(evg34.26) 0 - -# Higher-level EV value for EV 26 and input 35 -set fmri(evg35.26) 0 - -# Higher-level EV value for EV 26 and input 36 -set fmri(evg36.26) 0 - -# Higher-level EV value for EV 26 and input 37 -set fmri(evg37.26) 0 - -# Higher-level EV value for EV 26 and input 38 -set fmri(evg38.26) 0 - -# Higher-level EV value for EV 26 and input 39 -set fmri(evg39.26) 0 - -# Higher-level EV value for EV 26 and input 40 -set fmri(evg40.26) 0 - -# Higher-level EV value for EV 26 and input 41 -set fmri(evg41.26) 0 - -# Higher-level EV value for EV 26 and input 42 -set fmri(evg42.26) 0 - -# Higher-level EV value for EV 26 and input 43 -set fmri(evg43.26) 0 - -# Higher-level EV value for EV 26 and input 44 -set fmri(evg44.26) 0 - -# Higher-level EV value for EV 26 and input 45 -set fmri(evg45.26) 0 - -# Higher-level EV value for EV 26 and input 46 -set fmri(evg46.26) 0 - -# Higher-level EV value for EV 26 and input 47 -set fmri(evg47.26) 0 - -# Higher-level EV value for EV 26 and input 48 -set fmri(evg48.26) 0 - -# Higher-level EV value for EV 26 and input 49 -set fmri(evg49.26) 0 - -# Higher-level EV value for EV 26 and input 50 -set fmri(evg50.26) 0 - -# Higher-level EV value for EV 26 and input 51 -set fmri(evg51.26) 1.0 - -# Higher-level EV value for EV 26 and input 52 -set fmri(evg52.26) 1.0 - -# Setup Orthogonalisation at higher level? -set fmri(level2orth) 0 - -# Group membership for input 1 -set fmri(groupmem.1) 1 - -# Group membership for input 2 -set fmri(groupmem.2) 1 - -# Group membership for input 3 -set fmri(groupmem.3) 1 - -# Group membership for input 4 -set fmri(groupmem.4) 1 - -# Group membership for input 5 -set fmri(groupmem.5) 1 - -# Group membership for input 6 -set fmri(groupmem.6) 1 - -# Group membership for input 7 -set fmri(groupmem.7) 1 - -# Group membership for input 8 -set fmri(groupmem.8) 1 - -# Group membership for input 9 -set fmri(groupmem.9) 1 - -# Group membership for input 10 -set fmri(groupmem.10) 1 - -# Group membership for input 11 -set fmri(groupmem.11) 1 - -# Group membership for input 12 -set fmri(groupmem.12) 1 - -# Group membership for input 13 -set fmri(groupmem.13) 1 - -# Group membership for input 14 -set fmri(groupmem.14) 1 - -# Group membership for input 15 -set fmri(groupmem.15) 1 - -# Group membership for input 16 -set fmri(groupmem.16) 1 - -# Group membership for input 17 -set fmri(groupmem.17) 1 - -# Group membership for input 18 -set fmri(groupmem.18) 1 - -# Group membership for input 19 -set fmri(groupmem.19) 1 - -# Group membership for input 20 -set fmri(groupmem.20) 1 - -# Group membership for input 21 -set fmri(groupmem.21) 1 - -# Group membership for input 22 -set fmri(groupmem.22) 1 - -# Group membership for input 23 -set fmri(groupmem.23) 1 - -# Group membership for input 24 -set fmri(groupmem.24) 1 - -# Group membership for input 25 -set fmri(groupmem.25) 1 - -# Group membership for input 26 -set fmri(groupmem.26) 1 - -# Group membership for input 27 -set fmri(groupmem.27) 1 - -# Group membership for input 28 -set fmri(groupmem.28) 1 - -# Group membership for input 29 -set fmri(groupmem.29) 1 - -# Group membership for input 30 -set fmri(groupmem.30) 1 - -# Group membership for input 31 -set fmri(groupmem.31) 1 - -# Group membership for input 32 -set fmri(groupmem.32) 1 - -# Group membership for input 33 -set fmri(groupmem.33) 1 - -# Group membership for input 34 -set fmri(groupmem.34) 1 - -# Group membership for input 35 -set fmri(groupmem.35) 1 - -# Group membership for input 36 -set fmri(groupmem.36) 1 - -# Group membership for input 37 -set fmri(groupmem.37) 1 - -# Group membership for input 38 -set fmri(groupmem.38) 1 - -# Group membership for input 39 -set fmri(groupmem.39) 1 - -# Group membership for input 40 -set fmri(groupmem.40) 1 - -# Group membership for input 41 -set fmri(groupmem.41) 1 - -# Group membership for input 42 -set fmri(groupmem.42) 1 - -# Group membership for input 43 -set fmri(groupmem.43) 1 - -# Group membership for input 44 -set fmri(groupmem.44) 1 - -# Group membership for input 45 -set fmri(groupmem.45) 1 - -# Group membership for input 46 -set fmri(groupmem.46) 1 - -# Group membership for input 47 -set fmri(groupmem.47) 1 - -# Group membership for input 48 -set fmri(groupmem.48) 1 - -# Group membership for input 49 -set fmri(groupmem.49) 1 - -# Group membership for input 50 -set fmri(groupmem.50) 1 - -# Group membership for input 51 -set fmri(groupmem.51) 1 - -# Group membership for input 52 -set fmri(groupmem.52) 1 - -# Contrast & F-tests mode -# real : control real EVs -# orig : control original EVs -set fmri(con_mode_old) real -set fmri(con_mode) real - -# Display images for contrast_real 1 -set fmri(conpic_real.1) 1 - -# Title for contrast_real 1 -set fmri(conname_real.1) "" - -# Real contrast_real vector 1 element 1 -set fmri(con_real1.1) 1 - -# Real contrast_real vector 1 element 2 -set fmri(con_real1.2) 0 - -# Real contrast_real vector 1 element 3 -set fmri(con_real1.3) 0 - -# Real contrast_real vector 1 element 4 -set fmri(con_real1.4) 0 - -# Real contrast_real vector 1 element 5 -set fmri(con_real1.5) 0 - -# Real contrast_real vector 1 element 6 -set fmri(con_real1.6) 0 - -# Real contrast_real vector 1 element 7 -set fmri(con_real1.7) 0 - -# Real contrast_real vector 1 element 8 -set fmri(con_real1.8) 0 - -# Real contrast_real vector 1 element 9 -set fmri(con_real1.9) 0 - -# Real contrast_real vector 1 element 10 -set fmri(con_real1.10) 0 - -# Real contrast_real vector 1 element 11 -set fmri(con_real1.11) 0 - -# Real contrast_real vector 1 element 12 -set fmri(con_real1.12) 0 - -# Real contrast_real vector 1 element 13 -set fmri(con_real1.13) 0 - -# Real contrast_real vector 1 element 14 -set fmri(con_real1.14) 0 - -# Real contrast_real vector 1 element 15 -set fmri(con_real1.15) 0 - -# Real contrast_real vector 1 element 16 -set fmri(con_real1.16) 0 - -# Real contrast_real vector 1 element 17 -set fmri(con_real1.17) 0 - -# Real contrast_real vector 1 element 18 -set fmri(con_real1.18) 0 - -# Real contrast_real vector 1 element 19 -set fmri(con_real1.19) 0 - -# Real contrast_real vector 1 element 20 -set fmri(con_real1.20) 0 - -# Real contrast_real vector 1 element 21 -set fmri(con_real1.21) 0 - -# Real contrast_real vector 1 element 22 -set fmri(con_real1.22) 0 - -# Real contrast_real vector 1 element 23 -set fmri(con_real1.23) 0 - -# Real contrast_real vector 1 element 24 -set fmri(con_real1.24) 0 - -# Real contrast_real vector 1 element 25 -set fmri(con_real1.25) 0 - -# Real contrast_real vector 1 element 26 -set fmri(con_real1.26) 0 - -# Display images for contrast_real 2 -set fmri(conpic_real.2) 1 - -# Title for contrast_real 2 -set fmri(conname_real.2) "" - -# Real contrast_real vector 2 element 1 -set fmri(con_real2.1) 0 - -# Real contrast_real vector 2 element 2 -set fmri(con_real2.2) 1.0 - -# Real contrast_real vector 2 element 3 -set fmri(con_real2.3) 0 - -# Real contrast_real vector 2 element 4 -set fmri(con_real2.4) 0 - -# Real contrast_real vector 2 element 5 -set fmri(con_real2.5) 0 - -# Real contrast_real vector 2 element 6 -set fmri(con_real2.6) 0 - -# Real contrast_real vector 2 element 7 -set fmri(con_real2.7) 0 - -# Real contrast_real vector 2 element 8 -set fmri(con_real2.8) 0 - -# Real contrast_real vector 2 element 9 -set fmri(con_real2.9) 0 - -# Real contrast_real vector 2 element 10 -set fmri(con_real2.10) 0 - -# Real contrast_real vector 2 element 11 -set fmri(con_real2.11) 0 - -# Real contrast_real vector 2 element 12 -set fmri(con_real2.12) 0 - -# Real contrast_real vector 2 element 13 -set fmri(con_real2.13) 0 - -# Real contrast_real vector 2 element 14 -set fmri(con_real2.14) 0 - -# Real contrast_real vector 2 element 15 -set fmri(con_real2.15) 0 - -# Real contrast_real vector 2 element 16 -set fmri(con_real2.16) 0 - -# Real contrast_real vector 2 element 17 -set fmri(con_real2.17) 0 - -# Real contrast_real vector 2 element 18 -set fmri(con_real2.18) 0 - -# Real contrast_real vector 2 element 19 -set fmri(con_real2.19) 0 - -# Real contrast_real vector 2 element 20 -set fmri(con_real2.20) 0 - -# Real contrast_real vector 2 element 21 -set fmri(con_real2.21) 0 - -# Real contrast_real vector 2 element 22 -set fmri(con_real2.22) 0 - -# Real contrast_real vector 2 element 23 -set fmri(con_real2.23) 0 - -# Real contrast_real vector 2 element 24 -set fmri(con_real2.24) 0 - -# Real contrast_real vector 2 element 25 -set fmri(con_real2.25) 0 - -# Real contrast_real vector 2 element 26 -set fmri(con_real2.26) 0 - -# Display images for contrast_real 3 -set fmri(conpic_real.3) 1 - -# Title for contrast_real 3 -set fmri(conname_real.3) "" - -# Real contrast_real vector 3 element 1 -set fmri(con_real3.1) 0 - -# Real contrast_real vector 3 element 2 -set fmri(con_real3.2) 0 - -# Real contrast_real vector 3 element 3 -set fmri(con_real3.3) 1.0 - -# Real contrast_real vector 3 element 4 -set fmri(con_real3.4) 0 - -# Real contrast_real vector 3 element 5 -set fmri(con_real3.5) 0 - -# Real contrast_real vector 3 element 6 -set fmri(con_real3.6) 0 - -# Real contrast_real vector 3 element 7 -set fmri(con_real3.7) 0 - -# Real contrast_real vector 3 element 8 -set fmri(con_real3.8) 0 - -# Real contrast_real vector 3 element 9 -set fmri(con_real3.9) 0 - -# Real contrast_real vector 3 element 10 -set fmri(con_real3.10) 0 - -# Real contrast_real vector 3 element 11 -set fmri(con_real3.11) 0 - -# Real contrast_real vector 3 element 12 -set fmri(con_real3.12) 0 - -# Real contrast_real vector 3 element 13 -set fmri(con_real3.13) 0 - -# Real contrast_real vector 3 element 14 -set fmri(con_real3.14) 0 - -# Real contrast_real vector 3 element 15 -set fmri(con_real3.15) 0 - -# Real contrast_real vector 3 element 16 -set fmri(con_real3.16) 0 - -# Real contrast_real vector 3 element 17 -set fmri(con_real3.17) 0 - -# Real contrast_real vector 3 element 18 -set fmri(con_real3.18) 0 - -# Real contrast_real vector 3 element 19 -set fmri(con_real3.19) 0 - -# Real contrast_real vector 3 element 20 -set fmri(con_real3.20) 0 - -# Real contrast_real vector 3 element 21 -set fmri(con_real3.21) 0 - -# Real contrast_real vector 3 element 22 -set fmri(con_real3.22) 0 - -# Real contrast_real vector 3 element 23 -set fmri(con_real3.23) 0 - -# Real contrast_real vector 3 element 24 -set fmri(con_real3.24) 0 - -# Real contrast_real vector 3 element 25 -set fmri(con_real3.25) 0 - -# Real contrast_real vector 3 element 26 -set fmri(con_real3.26) 0 - -# Display images for contrast_real 4 -set fmri(conpic_real.4) 1 - -# Title for contrast_real 4 -set fmri(conname_real.4) "" - -# Real contrast_real vector 4 element 1 -set fmri(con_real4.1) 0 - -# Real contrast_real vector 4 element 2 -set fmri(con_real4.2) 0 - -# Real contrast_real vector 4 element 3 -set fmri(con_real4.3) 0 - -# Real contrast_real vector 4 element 4 -set fmri(con_real4.4) 1.0 - -# Real contrast_real vector 4 element 5 -set fmri(con_real4.5) 0 - -# Real contrast_real vector 4 element 6 -set fmri(con_real4.6) 0 - -# Real contrast_real vector 4 element 7 -set fmri(con_real4.7) 0 - -# Real contrast_real vector 4 element 8 -set fmri(con_real4.8) 0 - -# Real contrast_real vector 4 element 9 -set fmri(con_real4.9) 0 - -# Real contrast_real vector 4 element 10 -set fmri(con_real4.10) 0 - -# Real contrast_real vector 4 element 11 -set fmri(con_real4.11) 0 - -# Real contrast_real vector 4 element 12 -set fmri(con_real4.12) 0 - -# Real contrast_real vector 4 element 13 -set fmri(con_real4.13) 0 - -# Real contrast_real vector 4 element 14 -set fmri(con_real4.14) 0 - -# Real contrast_real vector 4 element 15 -set fmri(con_real4.15) 0 - -# Real contrast_real vector 4 element 16 -set fmri(con_real4.16) 0 - -# Real contrast_real vector 4 element 17 -set fmri(con_real4.17) 0 - -# Real contrast_real vector 4 element 18 -set fmri(con_real4.18) 0 - -# Real contrast_real vector 4 element 19 -set fmri(con_real4.19) 0 - -# Real contrast_real vector 4 element 20 -set fmri(con_real4.20) 0 - -# Real contrast_real vector 4 element 21 -set fmri(con_real4.21) 0 - -# Real contrast_real vector 4 element 22 -set fmri(con_real4.22) 0 - -# Real contrast_real vector 4 element 23 -set fmri(con_real4.23) 0 - -# Real contrast_real vector 4 element 24 -set fmri(con_real4.24) 0 - -# Real contrast_real vector 4 element 25 -set fmri(con_real4.25) 0 - -# Real contrast_real vector 4 element 26 -set fmri(con_real4.26) 0 - -# Display images for contrast_real 5 -set fmri(conpic_real.5) 1 - -# Title for contrast_real 5 -set fmri(conname_real.5) "" - -# Real contrast_real vector 5 element 1 -set fmri(con_real5.1) 0 - -# Real contrast_real vector 5 element 2 -set fmri(con_real5.2) 0 - -# Real contrast_real vector 5 element 3 -set fmri(con_real5.3) 0 - -# Real contrast_real vector 5 element 4 -set fmri(con_real5.4) 0 - -# Real contrast_real vector 5 element 5 -set fmri(con_real5.5) 1.0 - -# Real contrast_real vector 5 element 6 -set fmri(con_real5.6) 0 - -# Real contrast_real vector 5 element 7 -set fmri(con_real5.7) 0 - -# Real contrast_real vector 5 element 8 -set fmri(con_real5.8) 0 - -# Real contrast_real vector 5 element 9 -set fmri(con_real5.9) 0 - -# Real contrast_real vector 5 element 10 -set fmri(con_real5.10) 0 - -# Real contrast_real vector 5 element 11 -set fmri(con_real5.11) 0 - -# Real contrast_real vector 5 element 12 -set fmri(con_real5.12) 0 - -# Real contrast_real vector 5 element 13 -set fmri(con_real5.13) 0 - -# Real contrast_real vector 5 element 14 -set fmri(con_real5.14) 0 - -# Real contrast_real vector 5 element 15 -set fmri(con_real5.15) 0 - -# Real contrast_real vector 5 element 16 -set fmri(con_real5.16) 0 - -# Real contrast_real vector 5 element 17 -set fmri(con_real5.17) 0 - -# Real contrast_real vector 5 element 18 -set fmri(con_real5.18) 0 - -# Real contrast_real vector 5 element 19 -set fmri(con_real5.19) 0 - -# Real contrast_real vector 5 element 20 -set fmri(con_real5.20) 0 - -# Real contrast_real vector 5 element 21 -set fmri(con_real5.21) 0 - -# Real contrast_real vector 5 element 22 -set fmri(con_real5.22) 0 - -# Real contrast_real vector 5 element 23 -set fmri(con_real5.23) 0 - -# Real contrast_real vector 5 element 24 -set fmri(con_real5.24) 0 - -# Real contrast_real vector 5 element 25 -set fmri(con_real5.25) 0 - -# Real contrast_real vector 5 element 26 -set fmri(con_real5.26) 0 - -# Display images for contrast_real 6 -set fmri(conpic_real.6) 1 - -# Title for contrast_real 6 -set fmri(conname_real.6) "" - -# Real contrast_real vector 6 element 1 -set fmri(con_real6.1) 0 - -# Real contrast_real vector 6 element 2 -set fmri(con_real6.2) 0 - -# Real contrast_real vector 6 element 3 -set fmri(con_real6.3) 0 - -# Real contrast_real vector 6 element 4 -set fmri(con_real6.4) 0 - -# Real contrast_real vector 6 element 5 -set fmri(con_real6.5) 0 - -# Real contrast_real vector 6 element 6 -set fmri(con_real6.6) 1.0 - -# Real contrast_real vector 6 element 7 -set fmri(con_real6.7) 0 - -# Real contrast_real vector 6 element 8 -set fmri(con_real6.8) 0 - -# Real contrast_real vector 6 element 9 -set fmri(con_real6.9) 0 - -# Real contrast_real vector 6 element 10 -set fmri(con_real6.10) 0 - -# Real contrast_real vector 6 element 11 -set fmri(con_real6.11) 0 - -# Real contrast_real vector 6 element 12 -set fmri(con_real6.12) 0 - -# Real contrast_real vector 6 element 13 -set fmri(con_real6.13) 0 - -# Real contrast_real vector 6 element 14 -set fmri(con_real6.14) 0 - -# Real contrast_real vector 6 element 15 -set fmri(con_real6.15) 0 - -# Real contrast_real vector 6 element 16 -set fmri(con_real6.16) 0 - -# Real contrast_real vector 6 element 17 -set fmri(con_real6.17) 0 - -# Real contrast_real vector 6 element 18 -set fmri(con_real6.18) 0 - -# Real contrast_real vector 6 element 19 -set fmri(con_real6.19) 0 - -# Real contrast_real vector 6 element 20 -set fmri(con_real6.20) 0 - -# Real contrast_real vector 6 element 21 -set fmri(con_real6.21) 0 - -# Real contrast_real vector 6 element 22 -set fmri(con_real6.22) 0 - -# Real contrast_real vector 6 element 23 -set fmri(con_real6.23) 0 - -# Real contrast_real vector 6 element 24 -set fmri(con_real6.24) 0 - -# Real contrast_real vector 6 element 25 -set fmri(con_real6.25) 0 - -# Real contrast_real vector 6 element 26 -set fmri(con_real6.26) 0 - -# Display images for contrast_real 7 -set fmri(conpic_real.7) 1 - -# Title for contrast_real 7 -set fmri(conname_real.7) "" - -# Real contrast_real vector 7 element 1 -set fmri(con_real7.1) 0 - -# Real contrast_real vector 7 element 2 -set fmri(con_real7.2) 0 - -# Real contrast_real vector 7 element 3 -set fmri(con_real7.3) 0 - -# Real contrast_real vector 7 element 4 -set fmri(con_real7.4) 0 - -# Real contrast_real vector 7 element 5 -set fmri(con_real7.5) 0 - -# Real contrast_real vector 7 element 6 -set fmri(con_real7.6) 0 - -# Real contrast_real vector 7 element 7 -set fmri(con_real7.7) 1.0 - -# Real contrast_real vector 7 element 8 -set fmri(con_real7.8) 0 - -# Real contrast_real vector 7 element 9 -set fmri(con_real7.9) 0 - -# Real contrast_real vector 7 element 10 -set fmri(con_real7.10) 0 - -# Real contrast_real vector 7 element 11 -set fmri(con_real7.11) 0 - -# Real contrast_real vector 7 element 12 -set fmri(con_real7.12) 0 - -# Real contrast_real vector 7 element 13 -set fmri(con_real7.13) 0 - -# Real contrast_real vector 7 element 14 -set fmri(con_real7.14) 0 - -# Real contrast_real vector 7 element 15 -set fmri(con_real7.15) 0 - -# Real contrast_real vector 7 element 16 -set fmri(con_real7.16) 0 - -# Real contrast_real vector 7 element 17 -set fmri(con_real7.17) 0 - -# Real contrast_real vector 7 element 18 -set fmri(con_real7.18) 0 - -# Real contrast_real vector 7 element 19 -set fmri(con_real7.19) 0 - -# Real contrast_real vector 7 element 20 -set fmri(con_real7.20) 0 - -# Real contrast_real vector 7 element 21 -set fmri(con_real7.21) 0 - -# Real contrast_real vector 7 element 22 -set fmri(con_real7.22) 0 - -# Real contrast_real vector 7 element 23 -set fmri(con_real7.23) 0 - -# Real contrast_real vector 7 element 24 -set fmri(con_real7.24) 0 - -# Real contrast_real vector 7 element 25 -set fmri(con_real7.25) 0 - -# Real contrast_real vector 7 element 26 -set fmri(con_real7.26) 0 - -# Display images for contrast_real 8 -set fmri(conpic_real.8) 1 - -# Title for contrast_real 8 -set fmri(conname_real.8) "" - -# Real contrast_real vector 8 element 1 -set fmri(con_real8.1) 0 - -# Real contrast_real vector 8 element 2 -set fmri(con_real8.2) 0 - -# Real contrast_real vector 8 element 3 -set fmri(con_real8.3) 0 - -# Real contrast_real vector 8 element 4 -set fmri(con_real8.4) 0 - -# Real contrast_real vector 8 element 5 -set fmri(con_real8.5) 0 - -# Real contrast_real vector 8 element 6 -set fmri(con_real8.6) 0 - -# Real contrast_real vector 8 element 7 -set fmri(con_real8.7) 0 - -# Real contrast_real vector 8 element 8 -set fmri(con_real8.8) 1.0 - -# Real contrast_real vector 8 element 9 -set fmri(con_real8.9) 0 - -# Real contrast_real vector 8 element 10 -set fmri(con_real8.10) 0 - -# Real contrast_real vector 8 element 11 -set fmri(con_real8.11) 0 - -# Real contrast_real vector 8 element 12 -set fmri(con_real8.12) 0 - -# Real contrast_real vector 8 element 13 -set fmri(con_real8.13) 0 - -# Real contrast_real vector 8 element 14 -set fmri(con_real8.14) 0 - -# Real contrast_real vector 8 element 15 -set fmri(con_real8.15) 0 - -# Real contrast_real vector 8 element 16 -set fmri(con_real8.16) 0 - -# Real contrast_real vector 8 element 17 -set fmri(con_real8.17) 0 - -# Real contrast_real vector 8 element 18 -set fmri(con_real8.18) 0 - -# Real contrast_real vector 8 element 19 -set fmri(con_real8.19) 0 - -# Real contrast_real vector 8 element 20 -set fmri(con_real8.20) 0 - -# Real contrast_real vector 8 element 21 -set fmri(con_real8.21) 0 - -# Real contrast_real vector 8 element 22 -set fmri(con_real8.22) 0 - -# Real contrast_real vector 8 element 23 -set fmri(con_real8.23) 0 - -# Real contrast_real vector 8 element 24 -set fmri(con_real8.24) 0 - -# Real contrast_real vector 8 element 25 -set fmri(con_real8.25) 0 - -# Real contrast_real vector 8 element 26 -set fmri(con_real8.26) 0 - -# Display images for contrast_real 9 -set fmri(conpic_real.9) 1 - -# Title for contrast_real 9 -set fmri(conname_real.9) "" - -# Real contrast_real vector 9 element 1 -set fmri(con_real9.1) 0 - -# Real contrast_real vector 9 element 2 -set fmri(con_real9.2) 0 - -# Real contrast_real vector 9 element 3 -set fmri(con_real9.3) 0 - -# Real contrast_real vector 9 element 4 -set fmri(con_real9.4) 0 - -# Real contrast_real vector 9 element 5 -set fmri(con_real9.5) 0 - -# Real contrast_real vector 9 element 6 -set fmri(con_real9.6) 0 - -# Real contrast_real vector 9 element 7 -set fmri(con_real9.7) 0 - -# Real contrast_real vector 9 element 8 -set fmri(con_real9.8) 0 - -# Real contrast_real vector 9 element 9 -set fmri(con_real9.9) 1.0 - -# Real contrast_real vector 9 element 10 -set fmri(con_real9.10) 0 - -# Real contrast_real vector 9 element 11 -set fmri(con_real9.11) 0 - -# Real contrast_real vector 9 element 12 -set fmri(con_real9.12) 0 - -# Real contrast_real vector 9 element 13 -set fmri(con_real9.13) 0 - -# Real contrast_real vector 9 element 14 -set fmri(con_real9.14) 0 - -# Real contrast_real vector 9 element 15 -set fmri(con_real9.15) 0 - -# Real contrast_real vector 9 element 16 -set fmri(con_real9.16) 0 - -# Real contrast_real vector 9 element 17 -set fmri(con_real9.17) 0 - -# Real contrast_real vector 9 element 18 -set fmri(con_real9.18) 0 - -# Real contrast_real vector 9 element 19 -set fmri(con_real9.19) 0 - -# Real contrast_real vector 9 element 20 -set fmri(con_real9.20) 0 - -# Real contrast_real vector 9 element 21 -set fmri(con_real9.21) 0 - -# Real contrast_real vector 9 element 22 -set fmri(con_real9.22) 0 - -# Real contrast_real vector 9 element 23 -set fmri(con_real9.23) 0 - -# Real contrast_real vector 9 element 24 -set fmri(con_real9.24) 0 - -# Real contrast_real vector 9 element 25 -set fmri(con_real9.25) 0 - -# Real contrast_real vector 9 element 26 -set fmri(con_real9.26) 0 - -# Display images for contrast_real 10 -set fmri(conpic_real.10) 1 - -# Title for contrast_real 10 -set fmri(conname_real.10) "" - -# Real contrast_real vector 10 element 1 -set fmri(con_real10.1) 0 - -# Real contrast_real vector 10 element 2 -set fmri(con_real10.2) 0 - -# Real contrast_real vector 10 element 3 -set fmri(con_real10.3) 0 - -# Real contrast_real vector 10 element 4 -set fmri(con_real10.4) 0 - -# Real contrast_real vector 10 element 5 -set fmri(con_real10.5) 0 - -# Real contrast_real vector 10 element 6 -set fmri(con_real10.6) 0 - -# Real contrast_real vector 10 element 7 -set fmri(con_real10.7) 0 - -# Real contrast_real vector 10 element 8 -set fmri(con_real10.8) 0 - -# Real contrast_real vector 10 element 9 -set fmri(con_real10.9) 0 - -# Real contrast_real vector 10 element 10 -set fmri(con_real10.10) 1.0 - -# Real contrast_real vector 10 element 11 -set fmri(con_real10.11) 0 - -# Real contrast_real vector 10 element 12 -set fmri(con_real10.12) 0 - -# Real contrast_real vector 10 element 13 -set fmri(con_real10.13) 0 - -# Real contrast_real vector 10 element 14 -set fmri(con_real10.14) 0 - -# Real contrast_real vector 10 element 15 -set fmri(con_real10.15) 0 - -# Real contrast_real vector 10 element 16 -set fmri(con_real10.16) 0 - -# Real contrast_real vector 10 element 17 -set fmri(con_real10.17) 0 - -# Real contrast_real vector 10 element 18 -set fmri(con_real10.18) 0 - -# Real contrast_real vector 10 element 19 -set fmri(con_real10.19) 0 - -# Real contrast_real vector 10 element 20 -set fmri(con_real10.20) 0 - -# Real contrast_real vector 10 element 21 -set fmri(con_real10.21) 0 - -# Real contrast_real vector 10 element 22 -set fmri(con_real10.22) 0 - -# Real contrast_real vector 10 element 23 -set fmri(con_real10.23) 0 - -# Real contrast_real vector 10 element 24 -set fmri(con_real10.24) 0 - -# Real contrast_real vector 10 element 25 -set fmri(con_real10.25) 0 - -# Real contrast_real vector 10 element 26 -set fmri(con_real10.26) 0 - -# Display images for contrast_real 11 -set fmri(conpic_real.11) 1 - -# Title for contrast_real 11 -set fmri(conname_real.11) "" - -# Real contrast_real vector 11 element 1 -set fmri(con_real11.1) 0 - -# Real contrast_real vector 11 element 2 -set fmri(con_real11.2) 0 - -# Real contrast_real vector 11 element 3 -set fmri(con_real11.3) 0 - -# Real contrast_real vector 11 element 4 -set fmri(con_real11.4) 0 - -# Real contrast_real vector 11 element 5 -set fmri(con_real11.5) 0 - -# Real contrast_real vector 11 element 6 -set fmri(con_real11.6) 0 - -# Real contrast_real vector 11 element 7 -set fmri(con_real11.7) 0 - -# Real contrast_real vector 11 element 8 -set fmri(con_real11.8) 0 - -# Real contrast_real vector 11 element 9 -set fmri(con_real11.9) 0 - -# Real contrast_real vector 11 element 10 -set fmri(con_real11.10) 0 - -# Real contrast_real vector 11 element 11 -set fmri(con_real11.11) 1.0 - -# Real contrast_real vector 11 element 12 -set fmri(con_real11.12) 0 - -# Real contrast_real vector 11 element 13 -set fmri(con_real11.13) 0 - -# Real contrast_real vector 11 element 14 -set fmri(con_real11.14) 0 - -# Real contrast_real vector 11 element 15 -set fmri(con_real11.15) 0 - -# Real contrast_real vector 11 element 16 -set fmri(con_real11.16) 0 - -# Real contrast_real vector 11 element 17 -set fmri(con_real11.17) 0 - -# Real contrast_real vector 11 element 18 -set fmri(con_real11.18) 0 - -# Real contrast_real vector 11 element 19 -set fmri(con_real11.19) 0 - -# Real contrast_real vector 11 element 20 -set fmri(con_real11.20) 0 - -# Real contrast_real vector 11 element 21 -set fmri(con_real11.21) 0 - -# Real contrast_real vector 11 element 22 -set fmri(con_real11.22) 0 - -# Real contrast_real vector 11 element 23 -set fmri(con_real11.23) 0 - -# Real contrast_real vector 11 element 24 -set fmri(con_real11.24) 0 - -# Real contrast_real vector 11 element 25 -set fmri(con_real11.25) 0 - -# Real contrast_real vector 11 element 26 -set fmri(con_real11.26) 0 - -# Display images for contrast_real 12 -set fmri(conpic_real.12) 1 - -# Title for contrast_real 12 -set fmri(conname_real.12) "" - -# Real contrast_real vector 12 element 1 -set fmri(con_real12.1) 0 - -# Real contrast_real vector 12 element 2 -set fmri(con_real12.2) 0 - -# Real contrast_real vector 12 element 3 -set fmri(con_real12.3) 0 - -# Real contrast_real vector 12 element 4 -set fmri(con_real12.4) 0 - -# Real contrast_real vector 12 element 5 -set fmri(con_real12.5) 0 - -# Real contrast_real vector 12 element 6 -set fmri(con_real12.6) 0 - -# Real contrast_real vector 12 element 7 -set fmri(con_real12.7) 0 - -# Real contrast_real vector 12 element 8 -set fmri(con_real12.8) 0 - -# Real contrast_real vector 12 element 9 -set fmri(con_real12.9) 0 - -# Real contrast_real vector 12 element 10 -set fmri(con_real12.10) 0 - -# Real contrast_real vector 12 element 11 -set fmri(con_real12.11) 0 - -# Real contrast_real vector 12 element 12 -set fmri(con_real12.12) 1.0 - -# Real contrast_real vector 12 element 13 -set fmri(con_real12.13) 0 - -# Real contrast_real vector 12 element 14 -set fmri(con_real12.14) 0 - -# Real contrast_real vector 12 element 15 -set fmri(con_real12.15) 0 - -# Real contrast_real vector 12 element 16 -set fmri(con_real12.16) 0 - -# Real contrast_real vector 12 element 17 -set fmri(con_real12.17) 0 - -# Real contrast_real vector 12 element 18 -set fmri(con_real12.18) 0 - -# Real contrast_real vector 12 element 19 -set fmri(con_real12.19) 0 - -# Real contrast_real vector 12 element 20 -set fmri(con_real12.20) 0 - -# Real contrast_real vector 12 element 21 -set fmri(con_real12.21) 0 - -# Real contrast_real vector 12 element 22 -set fmri(con_real12.22) 0 - -# Real contrast_real vector 12 element 23 -set fmri(con_real12.23) 0 - -# Real contrast_real vector 12 element 24 -set fmri(con_real12.24) 0 - -# Real contrast_real vector 12 element 25 -set fmri(con_real12.25) 0 - -# Real contrast_real vector 12 element 26 -set fmri(con_real12.26) 0 - -# Display images for contrast_real 13 -set fmri(conpic_real.13) 1 - -# Title for contrast_real 13 -set fmri(conname_real.13) "" - -# Real contrast_real vector 13 element 1 -set fmri(con_real13.1) 0 - -# Real contrast_real vector 13 element 2 -set fmri(con_real13.2) 0 - -# Real contrast_real vector 13 element 3 -set fmri(con_real13.3) 0 - -# Real contrast_real vector 13 element 4 -set fmri(con_real13.4) 0 - -# Real contrast_real vector 13 element 5 -set fmri(con_real13.5) 0 - -# Real contrast_real vector 13 element 6 -set fmri(con_real13.6) 0 - -# Real contrast_real vector 13 element 7 -set fmri(con_real13.7) 0 - -# Real contrast_real vector 13 element 8 -set fmri(con_real13.8) 0 - -# Real contrast_real vector 13 element 9 -set fmri(con_real13.9) 0 - -# Real contrast_real vector 13 element 10 -set fmri(con_real13.10) 0 - -# Real contrast_real vector 13 element 11 -set fmri(con_real13.11) 0 - -# Real contrast_real vector 13 element 12 -set fmri(con_real13.12) 0 - -# Real contrast_real vector 13 element 13 -set fmri(con_real13.13) 1.0 - -# Real contrast_real vector 13 element 14 -set fmri(con_real13.14) 0 - -# Real contrast_real vector 13 element 15 -set fmri(con_real13.15) 0 - -# Real contrast_real vector 13 element 16 -set fmri(con_real13.16) 0 - -# Real contrast_real vector 13 element 17 -set fmri(con_real13.17) 0 - -# Real contrast_real vector 13 element 18 -set fmri(con_real13.18) 0 - -# Real contrast_real vector 13 element 19 -set fmri(con_real13.19) 0 - -# Real contrast_real vector 13 element 20 -set fmri(con_real13.20) 0 - -# Real contrast_real vector 13 element 21 -set fmri(con_real13.21) 0 - -# Real contrast_real vector 13 element 22 -set fmri(con_real13.22) 0 - -# Real contrast_real vector 13 element 23 -set fmri(con_real13.23) 0 - -# Real contrast_real vector 13 element 24 -set fmri(con_real13.24) 0 - -# Real contrast_real vector 13 element 25 -set fmri(con_real13.25) 0 - -# Real contrast_real vector 13 element 26 -set fmri(con_real13.26) 0 - -# Display images for contrast_real 14 -set fmri(conpic_real.14) 1 - -# Title for contrast_real 14 -set fmri(conname_real.14) "" - -# Real contrast_real vector 14 element 1 -set fmri(con_real14.1) 0 - -# Real contrast_real vector 14 element 2 -set fmri(con_real14.2) 0 - -# Real contrast_real vector 14 element 3 -set fmri(con_real14.3) 0 - -# Real contrast_real vector 14 element 4 -set fmri(con_real14.4) 0 - -# Real contrast_real vector 14 element 5 -set fmri(con_real14.5) 0 - -# Real contrast_real vector 14 element 6 -set fmri(con_real14.6) 0 - -# Real contrast_real vector 14 element 7 -set fmri(con_real14.7) 0 - -# Real contrast_real vector 14 element 8 -set fmri(con_real14.8) 0 - -# Real contrast_real vector 14 element 9 -set fmri(con_real14.9) 0 - -# Real contrast_real vector 14 element 10 -set fmri(con_real14.10) 0 - -# Real contrast_real vector 14 element 11 -set fmri(con_real14.11) 0 - -# Real contrast_real vector 14 element 12 -set fmri(con_real14.12) 0 - -# Real contrast_real vector 14 element 13 -set fmri(con_real14.13) 0 - -# Real contrast_real vector 14 element 14 -set fmri(con_real14.14) 1.0 - -# Real contrast_real vector 14 element 15 -set fmri(con_real14.15) 0 - -# Real contrast_real vector 14 element 16 -set fmri(con_real14.16) 0 - -# Real contrast_real vector 14 element 17 -set fmri(con_real14.17) 0 - -# Real contrast_real vector 14 element 18 -set fmri(con_real14.18) 0 - -# Real contrast_real vector 14 element 19 -set fmri(con_real14.19) 0 - -# Real contrast_real vector 14 element 20 -set fmri(con_real14.20) 0 - -# Real contrast_real vector 14 element 21 -set fmri(con_real14.21) 0 - -# Real contrast_real vector 14 element 22 -set fmri(con_real14.22) 0 - -# Real contrast_real vector 14 element 23 -set fmri(con_real14.23) 0 - -# Real contrast_real vector 14 element 24 -set fmri(con_real14.24) 0 - -# Real contrast_real vector 14 element 25 -set fmri(con_real14.25) 0 - -# Real contrast_real vector 14 element 26 -set fmri(con_real14.26) 0 - -# Display images for contrast_real 15 -set fmri(conpic_real.15) 1 - -# Title for contrast_real 15 -set fmri(conname_real.15) "" - -# Real contrast_real vector 15 element 1 -set fmri(con_real15.1) 0 - -# Real contrast_real vector 15 element 2 -set fmri(con_real15.2) 0 - -# Real contrast_real vector 15 element 3 -set fmri(con_real15.3) 0 - -# Real contrast_real vector 15 element 4 -set fmri(con_real15.4) 0 - -# Real contrast_real vector 15 element 5 -set fmri(con_real15.5) 0 - -# Real contrast_real vector 15 element 6 -set fmri(con_real15.6) 0 - -# Real contrast_real vector 15 element 7 -set fmri(con_real15.7) 0 - -# Real contrast_real vector 15 element 8 -set fmri(con_real15.8) 0 - -# Real contrast_real vector 15 element 9 -set fmri(con_real15.9) 0 - -# Real contrast_real vector 15 element 10 -set fmri(con_real15.10) 0 - -# Real contrast_real vector 15 element 11 -set fmri(con_real15.11) 0 - -# Real contrast_real vector 15 element 12 -set fmri(con_real15.12) 0 - -# Real contrast_real vector 15 element 13 -set fmri(con_real15.13) 0 - -# Real contrast_real vector 15 element 14 -set fmri(con_real15.14) 0 - -# Real contrast_real vector 15 element 15 -set fmri(con_real15.15) 1.0 - -# Real contrast_real vector 15 element 16 -set fmri(con_real15.16) 0 - -# Real contrast_real vector 15 element 17 -set fmri(con_real15.17) 0 - -# Real contrast_real vector 15 element 18 -set fmri(con_real15.18) 0 - -# Real contrast_real vector 15 element 19 -set fmri(con_real15.19) 0 - -# Real contrast_real vector 15 element 20 -set fmri(con_real15.20) 0 - -# Real contrast_real vector 15 element 21 -set fmri(con_real15.21) 0 - -# Real contrast_real vector 15 element 22 -set fmri(con_real15.22) 0 - -# Real contrast_real vector 15 element 23 -set fmri(con_real15.23) 0 - -# Real contrast_real vector 15 element 24 -set fmri(con_real15.24) 0 - -# Real contrast_real vector 15 element 25 -set fmri(con_real15.25) 0 - -# Real contrast_real vector 15 element 26 -set fmri(con_real15.26) 0 - -# Display images for contrast_real 16 -set fmri(conpic_real.16) 1 - -# Title for contrast_real 16 -set fmri(conname_real.16) "" - -# Real contrast_real vector 16 element 1 -set fmri(con_real16.1) 0 - -# Real contrast_real vector 16 element 2 -set fmri(con_real16.2) 0 - -# Real contrast_real vector 16 element 3 -set fmri(con_real16.3) 0 - -# Real contrast_real vector 16 element 4 -set fmri(con_real16.4) 0 - -# Real contrast_real vector 16 element 5 -set fmri(con_real16.5) 0 - -# Real contrast_real vector 16 element 6 -set fmri(con_real16.6) 0 - -# Real contrast_real vector 16 element 7 -set fmri(con_real16.7) 0 - -# Real contrast_real vector 16 element 8 -set fmri(con_real16.8) 0 - -# Real contrast_real vector 16 element 9 -set fmri(con_real16.9) 0 - -# Real contrast_real vector 16 element 10 -set fmri(con_real16.10) 0 - -# Real contrast_real vector 16 element 11 -set fmri(con_real16.11) 0 - -# Real contrast_real vector 16 element 12 -set fmri(con_real16.12) 0 - -# Real contrast_real vector 16 element 13 -set fmri(con_real16.13) 0 - -# Real contrast_real vector 16 element 14 -set fmri(con_real16.14) 0 - -# Real contrast_real vector 16 element 15 -set fmri(con_real16.15) 0 - -# Real contrast_real vector 16 element 16 -set fmri(con_real16.16) 1.0 - -# Real contrast_real vector 16 element 17 -set fmri(con_real16.17) 0 - -# Real contrast_real vector 16 element 18 -set fmri(con_real16.18) 0 - -# Real contrast_real vector 16 element 19 -set fmri(con_real16.19) 0 - -# Real contrast_real vector 16 element 20 -set fmri(con_real16.20) 0 - -# Real contrast_real vector 16 element 21 -set fmri(con_real16.21) 0 - -# Real contrast_real vector 16 element 22 -set fmri(con_real16.22) 0 - -# Real contrast_real vector 16 element 23 -set fmri(con_real16.23) 0 - -# Real contrast_real vector 16 element 24 -set fmri(con_real16.24) 0 - -# Real contrast_real vector 16 element 25 -set fmri(con_real16.25) 0 - -# Real contrast_real vector 16 element 26 -set fmri(con_real16.26) 0 - -# Display images for contrast_real 17 -set fmri(conpic_real.17) 1 - -# Title for contrast_real 17 -set fmri(conname_real.17) "" - -# Real contrast_real vector 17 element 1 -set fmri(con_real17.1) 0 - -# Real contrast_real vector 17 element 2 -set fmri(con_real17.2) 0 - -# Real contrast_real vector 17 element 3 -set fmri(con_real17.3) 0 - -# Real contrast_real vector 17 element 4 -set fmri(con_real17.4) 0 - -# Real contrast_real vector 17 element 5 -set fmri(con_real17.5) 0 - -# Real contrast_real vector 17 element 6 -set fmri(con_real17.6) 0 - -# Real contrast_real vector 17 element 7 -set fmri(con_real17.7) 0 - -# Real contrast_real vector 17 element 8 -set fmri(con_real17.8) 0 - -# Real contrast_real vector 17 element 9 -set fmri(con_real17.9) 0 - -# Real contrast_real vector 17 element 10 -set fmri(con_real17.10) 0 - -# Real contrast_real vector 17 element 11 -set fmri(con_real17.11) 0 - -# Real contrast_real vector 17 element 12 -set fmri(con_real17.12) 0 - -# Real contrast_real vector 17 element 13 -set fmri(con_real17.13) 0 - -# Real contrast_real vector 17 element 14 -set fmri(con_real17.14) 0 - -# Real contrast_real vector 17 element 15 -set fmri(con_real17.15) 0 - -# Real contrast_real vector 17 element 16 -set fmri(con_real17.16) 0 - -# Real contrast_real vector 17 element 17 -set fmri(con_real17.17) 1.0 - -# Real contrast_real vector 17 element 18 -set fmri(con_real17.18) 0 - -# Real contrast_real vector 17 element 19 -set fmri(con_real17.19) 0 - -# Real contrast_real vector 17 element 20 -set fmri(con_real17.20) 0 - -# Real contrast_real vector 17 element 21 -set fmri(con_real17.21) 0 - -# Real contrast_real vector 17 element 22 -set fmri(con_real17.22) 0 - -# Real contrast_real vector 17 element 23 -set fmri(con_real17.23) 0 - -# Real contrast_real vector 17 element 24 -set fmri(con_real17.24) 0 - -# Real contrast_real vector 17 element 25 -set fmri(con_real17.25) 0 - -# Real contrast_real vector 17 element 26 -set fmri(con_real17.26) 0 - -# Display images for contrast_real 18 -set fmri(conpic_real.18) 1 - -# Title for contrast_real 18 -set fmri(conname_real.18) "" - -# Real contrast_real vector 18 element 1 -set fmri(con_real18.1) 0 - -# Real contrast_real vector 18 element 2 -set fmri(con_real18.2) 0 - -# Real contrast_real vector 18 element 3 -set fmri(con_real18.3) 0 - -# Real contrast_real vector 18 element 4 -set fmri(con_real18.4) 0 - -# Real contrast_real vector 18 element 5 -set fmri(con_real18.5) 0 - -# Real contrast_real vector 18 element 6 -set fmri(con_real18.6) 0 - -# Real contrast_real vector 18 element 7 -set fmri(con_real18.7) 0 - -# Real contrast_real vector 18 element 8 -set fmri(con_real18.8) 0 - -# Real contrast_real vector 18 element 9 -set fmri(con_real18.9) 0 - -# Real contrast_real vector 18 element 10 -set fmri(con_real18.10) 0 - -# Real contrast_real vector 18 element 11 -set fmri(con_real18.11) 0 - -# Real contrast_real vector 18 element 12 -set fmri(con_real18.12) 0 - -# Real contrast_real vector 18 element 13 -set fmri(con_real18.13) 0 - -# Real contrast_real vector 18 element 14 -set fmri(con_real18.14) 0 - -# Real contrast_real vector 18 element 15 -set fmri(con_real18.15) 0 - -# Real contrast_real vector 18 element 16 -set fmri(con_real18.16) 0 - -# Real contrast_real vector 18 element 17 -set fmri(con_real18.17) 0 - -# Real contrast_real vector 18 element 18 -set fmri(con_real18.18) 1.0 - -# Real contrast_real vector 18 element 19 -set fmri(con_real18.19) 0 - -# Real contrast_real vector 18 element 20 -set fmri(con_real18.20) 0 - -# Real contrast_real vector 18 element 21 -set fmri(con_real18.21) 0 - -# Real contrast_real vector 18 element 22 -set fmri(con_real18.22) 0 - -# Real contrast_real vector 18 element 23 -set fmri(con_real18.23) 0 - -# Real contrast_real vector 18 element 24 -set fmri(con_real18.24) 0 - -# Real contrast_real vector 18 element 25 -set fmri(con_real18.25) 0 - -# Real contrast_real vector 18 element 26 -set fmri(con_real18.26) 0 - -# Display images for contrast_real 19 -set fmri(conpic_real.19) 1 - -# Title for contrast_real 19 -set fmri(conname_real.19) "" - -# Real contrast_real vector 19 element 1 -set fmri(con_real19.1) 0 - -# Real contrast_real vector 19 element 2 -set fmri(con_real19.2) 0 - -# Real contrast_real vector 19 element 3 -set fmri(con_real19.3) 0 - -# Real contrast_real vector 19 element 4 -set fmri(con_real19.4) 0 - -# Real contrast_real vector 19 element 5 -set fmri(con_real19.5) 0 - -# Real contrast_real vector 19 element 6 -set fmri(con_real19.6) 0 - -# Real contrast_real vector 19 element 7 -set fmri(con_real19.7) 0 - -# Real contrast_real vector 19 element 8 -set fmri(con_real19.8) 0 - -# Real contrast_real vector 19 element 9 -set fmri(con_real19.9) 0 - -# Real contrast_real vector 19 element 10 -set fmri(con_real19.10) 0 - -# Real contrast_real vector 19 element 11 -set fmri(con_real19.11) 0 - -# Real contrast_real vector 19 element 12 -set fmri(con_real19.12) 0 - -# Real contrast_real vector 19 element 13 -set fmri(con_real19.13) 0 - -# Real contrast_real vector 19 element 14 -set fmri(con_real19.14) 0 - -# Real contrast_real vector 19 element 15 -set fmri(con_real19.15) 0 - -# Real contrast_real vector 19 element 16 -set fmri(con_real19.16) 0 - -# Real contrast_real vector 19 element 17 -set fmri(con_real19.17) 0 - -# Real contrast_real vector 19 element 18 -set fmri(con_real19.18) 0 - -# Real contrast_real vector 19 element 19 -set fmri(con_real19.19) 1.0 - -# Real contrast_real vector 19 element 20 -set fmri(con_real19.20) 0 - -# Real contrast_real vector 19 element 21 -set fmri(con_real19.21) 0 - -# Real contrast_real vector 19 element 22 -set fmri(con_real19.22) 0 - -# Real contrast_real vector 19 element 23 -set fmri(con_real19.23) 0 - -# Real contrast_real vector 19 element 24 -set fmri(con_real19.24) 0 - -# Real contrast_real vector 19 element 25 -set fmri(con_real19.25) 0 - -# Real contrast_real vector 19 element 26 -set fmri(con_real19.26) 0 - -# Display images for contrast_real 20 -set fmri(conpic_real.20) 1 - -# Title for contrast_real 20 -set fmri(conname_real.20) "" - -# Real contrast_real vector 20 element 1 -set fmri(con_real20.1) 0 - -# Real contrast_real vector 20 element 2 -set fmri(con_real20.2) 0 - -# Real contrast_real vector 20 element 3 -set fmri(con_real20.3) 0 - -# Real contrast_real vector 20 element 4 -set fmri(con_real20.4) 0 - -# Real contrast_real vector 20 element 5 -set fmri(con_real20.5) 0 - -# Real contrast_real vector 20 element 6 -set fmri(con_real20.6) 0 - -# Real contrast_real vector 20 element 7 -set fmri(con_real20.7) 0 - -# Real contrast_real vector 20 element 8 -set fmri(con_real20.8) 0 - -# Real contrast_real vector 20 element 9 -set fmri(con_real20.9) 0 - -# Real contrast_real vector 20 element 10 -set fmri(con_real20.10) 0 - -# Real contrast_real vector 20 element 11 -set fmri(con_real20.11) 0 - -# Real contrast_real vector 20 element 12 -set fmri(con_real20.12) 0 - -# Real contrast_real vector 20 element 13 -set fmri(con_real20.13) 0 - -# Real contrast_real vector 20 element 14 -set fmri(con_real20.14) 0 - -# Real contrast_real vector 20 element 15 -set fmri(con_real20.15) 0 - -# Real contrast_real vector 20 element 16 -set fmri(con_real20.16) 0 - -# Real contrast_real vector 20 element 17 -set fmri(con_real20.17) 0 - -# Real contrast_real vector 20 element 18 -set fmri(con_real20.18) 0 - -# Real contrast_real vector 20 element 19 -set fmri(con_real20.19) 0 - -# Real contrast_real vector 20 element 20 -set fmri(con_real20.20) 1.0 - -# Real contrast_real vector 20 element 21 -set fmri(con_real20.21) 0 - -# Real contrast_real vector 20 element 22 -set fmri(con_real20.22) 0 - -# Real contrast_real vector 20 element 23 -set fmri(con_real20.23) 0 - -# Real contrast_real vector 20 element 24 -set fmri(con_real20.24) 0 - -# Real contrast_real vector 20 element 25 -set fmri(con_real20.25) 0 - -# Real contrast_real vector 20 element 26 -set fmri(con_real20.26) 0 - -# Display images for contrast_real 21 -set fmri(conpic_real.21) 1 - -# Title for contrast_real 21 -set fmri(conname_real.21) "" - -# Real contrast_real vector 21 element 1 -set fmri(con_real21.1) 0 - -# Real contrast_real vector 21 element 2 -set fmri(con_real21.2) 0 - -# Real contrast_real vector 21 element 3 -set fmri(con_real21.3) 0 - -# Real contrast_real vector 21 element 4 -set fmri(con_real21.4) 0 - -# Real contrast_real vector 21 element 5 -set fmri(con_real21.5) 0 - -# Real contrast_real vector 21 element 6 -set fmri(con_real21.6) 0 - -# Real contrast_real vector 21 element 7 -set fmri(con_real21.7) 0 - -# Real contrast_real vector 21 element 8 -set fmri(con_real21.8) 0 - -# Real contrast_real vector 21 element 9 -set fmri(con_real21.9) 0 - -# Real contrast_real vector 21 element 10 -set fmri(con_real21.10) 0 - -# Real contrast_real vector 21 element 11 -set fmri(con_real21.11) 0 - -# Real contrast_real vector 21 element 12 -set fmri(con_real21.12) 0 - -# Real contrast_real vector 21 element 13 -set fmri(con_real21.13) 0 - -# Real contrast_real vector 21 element 14 -set fmri(con_real21.14) 0 - -# Real contrast_real vector 21 element 15 -set fmri(con_real21.15) 0 - -# Real contrast_real vector 21 element 16 -set fmri(con_real21.16) 0 - -# Real contrast_real vector 21 element 17 -set fmri(con_real21.17) 0 - -# Real contrast_real vector 21 element 18 -set fmri(con_real21.18) 0 - -# Real contrast_real vector 21 element 19 -set fmri(con_real21.19) 0 - -# Real contrast_real vector 21 element 20 -set fmri(con_real21.20) 0 - -# Real contrast_real vector 21 element 21 -set fmri(con_real21.21) 1.0 - -# Real contrast_real vector 21 element 22 -set fmri(con_real21.22) 0 - -# Real contrast_real vector 21 element 23 -set fmri(con_real21.23) 0 - -# Real contrast_real vector 21 element 24 -set fmri(con_real21.24) 0 - -# Real contrast_real vector 21 element 25 -set fmri(con_real21.25) 0 - -# Real contrast_real vector 21 element 26 -set fmri(con_real21.26) 0 - -# Display images for contrast_real 22 -set fmri(conpic_real.22) 1 - -# Title for contrast_real 22 -set fmri(conname_real.22) "" - -# Real contrast_real vector 22 element 1 -set fmri(con_real22.1) 0 - -# Real contrast_real vector 22 element 2 -set fmri(con_real22.2) 0 - -# Real contrast_real vector 22 element 3 -set fmri(con_real22.3) 0 - -# Real contrast_real vector 22 element 4 -set fmri(con_real22.4) 0 - -# Real contrast_real vector 22 element 5 -set fmri(con_real22.5) 0 - -# Real contrast_real vector 22 element 6 -set fmri(con_real22.6) 0 - -# Real contrast_real vector 22 element 7 -set fmri(con_real22.7) 0 - -# Real contrast_real vector 22 element 8 -set fmri(con_real22.8) 0 - -# Real contrast_real vector 22 element 9 -set fmri(con_real22.9) 0 - -# Real contrast_real vector 22 element 10 -set fmri(con_real22.10) 0 - -# Real contrast_real vector 22 element 11 -set fmri(con_real22.11) 0 - -# Real contrast_real vector 22 element 12 -set fmri(con_real22.12) 0 - -# Real contrast_real vector 22 element 13 -set fmri(con_real22.13) 0 - -# Real contrast_real vector 22 element 14 -set fmri(con_real22.14) 0 - -# Real contrast_real vector 22 element 15 -set fmri(con_real22.15) 0 - -# Real contrast_real vector 22 element 16 -set fmri(con_real22.16) 0 - -# Real contrast_real vector 22 element 17 -set fmri(con_real22.17) 0 - -# Real contrast_real vector 22 element 18 -set fmri(con_real22.18) 0 - -# Real contrast_real vector 22 element 19 -set fmri(con_real22.19) 0 - -# Real contrast_real vector 22 element 20 -set fmri(con_real22.20) 0 - -# Real contrast_real vector 22 element 21 -set fmri(con_real22.21) 0 - -# Real contrast_real vector 22 element 22 -set fmri(con_real22.22) 1.0 - -# Real contrast_real vector 22 element 23 -set fmri(con_real22.23) 0 - -# Real contrast_real vector 22 element 24 -set fmri(con_real22.24) 0 - -# Real contrast_real vector 22 element 25 -set fmri(con_real22.25) 0 - -# Real contrast_real vector 22 element 26 -set fmri(con_real22.26) 0 - -# Display images for contrast_real 23 -set fmri(conpic_real.23) 1 - -# Title for contrast_real 23 -set fmri(conname_real.23) "" - -# Real contrast_real vector 23 element 1 -set fmri(con_real23.1) 0 - -# Real contrast_real vector 23 element 2 -set fmri(con_real23.2) 0 - -# Real contrast_real vector 23 element 3 -set fmri(con_real23.3) 0 - -# Real contrast_real vector 23 element 4 -set fmri(con_real23.4) 0 - -# Real contrast_real vector 23 element 5 -set fmri(con_real23.5) 0 - -# Real contrast_real vector 23 element 6 -set fmri(con_real23.6) 0 - -# Real contrast_real vector 23 element 7 -set fmri(con_real23.7) 0 - -# Real contrast_real vector 23 element 8 -set fmri(con_real23.8) 0 - -# Real contrast_real vector 23 element 9 -set fmri(con_real23.9) 0 - -# Real contrast_real vector 23 element 10 -set fmri(con_real23.10) 0 - -# Real contrast_real vector 23 element 11 -set fmri(con_real23.11) 0 - -# Real contrast_real vector 23 element 12 -set fmri(con_real23.12) 0 - -# Real contrast_real vector 23 element 13 -set fmri(con_real23.13) 0 - -# Real contrast_real vector 23 element 14 -set fmri(con_real23.14) 0 - -# Real contrast_real vector 23 element 15 -set fmri(con_real23.15) 0 - -# Real contrast_real vector 23 element 16 -set fmri(con_real23.16) 0 - -# Real contrast_real vector 23 element 17 -set fmri(con_real23.17) 0 - -# Real contrast_real vector 23 element 18 -set fmri(con_real23.18) 0 - -# Real contrast_real vector 23 element 19 -set fmri(con_real23.19) 0 - -# Real contrast_real vector 23 element 20 -set fmri(con_real23.20) 0 - -# Real contrast_real vector 23 element 21 -set fmri(con_real23.21) 0 - -# Real contrast_real vector 23 element 22 -set fmri(con_real23.22) 0 - -# Real contrast_real vector 23 element 23 -set fmri(con_real23.23) 1.0 - -# Real contrast_real vector 23 element 24 -set fmri(con_real23.24) 0 - -# Real contrast_real vector 23 element 25 -set fmri(con_real23.25) 0 - -# Real contrast_real vector 23 element 26 -set fmri(con_real23.26) 0 - -# Display images for contrast_real 24 -set fmri(conpic_real.24) 1 - -# Title for contrast_real 24 -set fmri(conname_real.24) "" - -# Real contrast_real vector 24 element 1 -set fmri(con_real24.1) 0 - -# Real contrast_real vector 24 element 2 -set fmri(con_real24.2) 0 - -# Real contrast_real vector 24 element 3 -set fmri(con_real24.3) 0 - -# Real contrast_real vector 24 element 4 -set fmri(con_real24.4) 0 - -# Real contrast_real vector 24 element 5 -set fmri(con_real24.5) 0 - -# Real contrast_real vector 24 element 6 -set fmri(con_real24.6) 0 - -# Real contrast_real vector 24 element 7 -set fmri(con_real24.7) 0 - -# Real contrast_real vector 24 element 8 -set fmri(con_real24.8) 0 - -# Real contrast_real vector 24 element 9 -set fmri(con_real24.9) 0 - -# Real contrast_real vector 24 element 10 -set fmri(con_real24.10) 0 - -# Real contrast_real vector 24 element 11 -set fmri(con_real24.11) 0 - -# Real contrast_real vector 24 element 12 -set fmri(con_real24.12) 0 - -# Real contrast_real vector 24 element 13 -set fmri(con_real24.13) 0 - -# Real contrast_real vector 24 element 14 -set fmri(con_real24.14) 0 - -# Real contrast_real vector 24 element 15 -set fmri(con_real24.15) 0 - -# Real contrast_real vector 24 element 16 -set fmri(con_real24.16) 0 - -# Real contrast_real vector 24 element 17 -set fmri(con_real24.17) 0 - -# Real contrast_real vector 24 element 18 -set fmri(con_real24.18) 0 - -# Real contrast_real vector 24 element 19 -set fmri(con_real24.19) 0 - -# Real contrast_real vector 24 element 20 -set fmri(con_real24.20) 0 - -# Real contrast_real vector 24 element 21 -set fmri(con_real24.21) 0 - -# Real contrast_real vector 24 element 22 -set fmri(con_real24.22) 0 - -# Real contrast_real vector 24 element 23 -set fmri(con_real24.23) 0 - -# Real contrast_real vector 24 element 24 -set fmri(con_real24.24) 1.0 - -# Real contrast_real vector 24 element 25 -set fmri(con_real24.25) 0 - -# Real contrast_real vector 24 element 26 -set fmri(con_real24.26) 0 - -# Display images for contrast_real 25 -set fmri(conpic_real.25) 1 - -# Title for contrast_real 25 -set fmri(conname_real.25) "" - -# Real contrast_real vector 25 element 1 -set fmri(con_real25.1) 0 - -# Real contrast_real vector 25 element 2 -set fmri(con_real25.2) 0 - -# Real contrast_real vector 25 element 3 -set fmri(con_real25.3) 0 - -# Real contrast_real vector 25 element 4 -set fmri(con_real25.4) 0 - -# Real contrast_real vector 25 element 5 -set fmri(con_real25.5) 0 - -# Real contrast_real vector 25 element 6 -set fmri(con_real25.6) 0 - -# Real contrast_real vector 25 element 7 -set fmri(con_real25.7) 0 - -# Real contrast_real vector 25 element 8 -set fmri(con_real25.8) 0 - -# Real contrast_real vector 25 element 9 -set fmri(con_real25.9) 0 - -# Real contrast_real vector 25 element 10 -set fmri(con_real25.10) 0 - -# Real contrast_real vector 25 element 11 -set fmri(con_real25.11) 0 - -# Real contrast_real vector 25 element 12 -set fmri(con_real25.12) 0 - -# Real contrast_real vector 25 element 13 -set fmri(con_real25.13) 0 - -# Real contrast_real vector 25 element 14 -set fmri(con_real25.14) 0 - -# Real contrast_real vector 25 element 15 -set fmri(con_real25.15) 0 - -# Real contrast_real vector 25 element 16 -set fmri(con_real25.16) 0 - -# Real contrast_real vector 25 element 17 -set fmri(con_real25.17) 0 - -# Real contrast_real vector 25 element 18 -set fmri(con_real25.18) 0 - -# Real contrast_real vector 25 element 19 -set fmri(con_real25.19) 0 - -# Real contrast_real vector 25 element 20 -set fmri(con_real25.20) 0 - -# Real contrast_real vector 25 element 21 -set fmri(con_real25.21) 0 - -# Real contrast_real vector 25 element 22 -set fmri(con_real25.22) 0 - -# Real contrast_real vector 25 element 23 -set fmri(con_real25.23) 0 - -# Real contrast_real vector 25 element 24 -set fmri(con_real25.24) 0 - -# Real contrast_real vector 25 element 25 -set fmri(con_real25.25) 1.0 - -# Real contrast_real vector 25 element 26 -set fmri(con_real25.26) 0 - -# Display images for contrast_real 26 -set fmri(conpic_real.26) 1 - -# Title for contrast_real 26 -set fmri(conname_real.26) "" - -# Real contrast_real vector 26 element 1 -set fmri(con_real26.1) 0 - -# Real contrast_real vector 26 element 2 -set fmri(con_real26.2) 0 - -# Real contrast_real vector 26 element 3 -set fmri(con_real26.3) 0 - -# Real contrast_real vector 26 element 4 -set fmri(con_real26.4) 0 - -# Real contrast_real vector 26 element 5 -set fmri(con_real26.5) 0 - -# Real contrast_real vector 26 element 6 -set fmri(con_real26.6) 0 - -# Real contrast_real vector 26 element 7 -set fmri(con_real26.7) 0 - -# Real contrast_real vector 26 element 8 -set fmri(con_real26.8) 0 - -# Real contrast_real vector 26 element 9 -set fmri(con_real26.9) 0 - -# Real contrast_real vector 26 element 10 -set fmri(con_real26.10) 0 - -# Real contrast_real vector 26 element 11 -set fmri(con_real26.11) 0 - -# Real contrast_real vector 26 element 12 -set fmri(con_real26.12) 0 - -# Real contrast_real vector 26 element 13 -set fmri(con_real26.13) 0 - -# Real contrast_real vector 26 element 14 -set fmri(con_real26.14) 0 - -# Real contrast_real vector 26 element 15 -set fmri(con_real26.15) 0 - -# Real contrast_real vector 26 element 16 -set fmri(con_real26.16) 0 - -# Real contrast_real vector 26 element 17 -set fmri(con_real26.17) 0 - -# Real contrast_real vector 26 element 18 -set fmri(con_real26.18) 0 - -# Real contrast_real vector 26 element 19 -set fmri(con_real26.19) 0 - -# Real contrast_real vector 26 element 20 -set fmri(con_real26.20) 0 - -# Real contrast_real vector 26 element 21 -set fmri(con_real26.21) 0 - -# Real contrast_real vector 26 element 22 -set fmri(con_real26.22) 0 - -# Real contrast_real vector 26 element 23 -set fmri(con_real26.23) 0 - -# Real contrast_real vector 26 element 24 -set fmri(con_real26.24) 0 - -# Real contrast_real vector 26 element 25 -set fmri(con_real26.25) 0 - -# Real contrast_real vector 26 element 26 -set fmri(con_real26.26) 1.0 - -# Contrast masking - use >0 instead of thresholding? -set fmri(conmask_zerothresh_yn) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 2? -set fmri(conmask1_2) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 3? -set fmri(conmask1_3) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 4? -set fmri(conmask1_4) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 5? -set fmri(conmask1_5) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 6? -set fmri(conmask1_6) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 7? -set fmri(conmask1_7) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 8? -set fmri(conmask1_8) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 9? -set fmri(conmask1_9) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 10? -set fmri(conmask1_10) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 11? -set fmri(conmask1_11) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 12? -set fmri(conmask1_12) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 13? -set fmri(conmask1_13) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 14? -set fmri(conmask1_14) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 15? -set fmri(conmask1_15) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 16? -set fmri(conmask1_16) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 17? -set fmri(conmask1_17) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 18? -set fmri(conmask1_18) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 19? -set fmri(conmask1_19) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 20? -set fmri(conmask1_20) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 21? -set fmri(conmask1_21) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 22? -set fmri(conmask1_22) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 23? -set fmri(conmask1_23) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 24? -set fmri(conmask1_24) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 25? -set fmri(conmask1_25) 0 - -# Mask real contrast/F-test 1 with real contrast/F-test 26? -set fmri(conmask1_26) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 1? -set fmri(conmask2_1) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 3? -set fmri(conmask2_3) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 4? -set fmri(conmask2_4) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 5? -set fmri(conmask2_5) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 6? -set fmri(conmask2_6) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 7? -set fmri(conmask2_7) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 8? -set fmri(conmask2_8) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 9? -set fmri(conmask2_9) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 10? -set fmri(conmask2_10) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 11? -set fmri(conmask2_11) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 12? -set fmri(conmask2_12) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 13? -set fmri(conmask2_13) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 14? -set fmri(conmask2_14) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 15? -set fmri(conmask2_15) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 16? -set fmri(conmask2_16) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 17? -set fmri(conmask2_17) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 18? -set fmri(conmask2_18) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 19? -set fmri(conmask2_19) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 20? -set fmri(conmask2_20) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 21? -set fmri(conmask2_21) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 22? -set fmri(conmask2_22) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 23? -set fmri(conmask2_23) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 24? -set fmri(conmask2_24) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 25? -set fmri(conmask2_25) 0 - -# Mask real contrast/F-test 2 with real contrast/F-test 26? -set fmri(conmask2_26) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 1? -set fmri(conmask3_1) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 2? -set fmri(conmask3_2) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 4? -set fmri(conmask3_4) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 5? -set fmri(conmask3_5) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 6? -set fmri(conmask3_6) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 7? -set fmri(conmask3_7) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 8? -set fmri(conmask3_8) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 9? -set fmri(conmask3_9) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 10? -set fmri(conmask3_10) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 11? -set fmri(conmask3_11) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 12? -set fmri(conmask3_12) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 13? -set fmri(conmask3_13) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 14? -set fmri(conmask3_14) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 15? -set fmri(conmask3_15) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 16? -set fmri(conmask3_16) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 17? -set fmri(conmask3_17) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 18? -set fmri(conmask3_18) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 19? -set fmri(conmask3_19) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 20? -set fmri(conmask3_20) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 21? -set fmri(conmask3_21) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 22? -set fmri(conmask3_22) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 23? -set fmri(conmask3_23) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 24? -set fmri(conmask3_24) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 25? -set fmri(conmask3_25) 0 - -# Mask real contrast/F-test 3 with real contrast/F-test 26? -set fmri(conmask3_26) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 1? -set fmri(conmask4_1) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 2? -set fmri(conmask4_2) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 3? -set fmri(conmask4_3) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 5? -set fmri(conmask4_5) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 6? -set fmri(conmask4_6) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 7? -set fmri(conmask4_7) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 8? -set fmri(conmask4_8) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 9? -set fmri(conmask4_9) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 10? -set fmri(conmask4_10) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 11? -set fmri(conmask4_11) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 12? -set fmri(conmask4_12) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 13? -set fmri(conmask4_13) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 14? -set fmri(conmask4_14) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 15? -set fmri(conmask4_15) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 16? -set fmri(conmask4_16) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 17? -set fmri(conmask4_17) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 18? -set fmri(conmask4_18) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 19? -set fmri(conmask4_19) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 20? -set fmri(conmask4_20) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 21? -set fmri(conmask4_21) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 22? -set fmri(conmask4_22) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 23? -set fmri(conmask4_23) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 24? -set fmri(conmask4_24) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 25? -set fmri(conmask4_25) 0 - -# Mask real contrast/F-test 4 with real contrast/F-test 26? -set fmri(conmask4_26) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 1? -set fmri(conmask5_1) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 2? -set fmri(conmask5_2) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 3? -set fmri(conmask5_3) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 4? -set fmri(conmask5_4) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 6? -set fmri(conmask5_6) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 7? -set fmri(conmask5_7) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 8? -set fmri(conmask5_8) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 9? -set fmri(conmask5_9) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 10? -set fmri(conmask5_10) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 11? -set fmri(conmask5_11) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 12? -set fmri(conmask5_12) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 13? -set fmri(conmask5_13) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 14? -set fmri(conmask5_14) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 15? -set fmri(conmask5_15) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 16? -set fmri(conmask5_16) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 17? -set fmri(conmask5_17) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 18? -set fmri(conmask5_18) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 19? -set fmri(conmask5_19) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 20? -set fmri(conmask5_20) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 21? -set fmri(conmask5_21) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 22? -set fmri(conmask5_22) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 23? -set fmri(conmask5_23) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 24? -set fmri(conmask5_24) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 25? -set fmri(conmask5_25) 0 - -# Mask real contrast/F-test 5 with real contrast/F-test 26? -set fmri(conmask5_26) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 1? -set fmri(conmask6_1) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 2? -set fmri(conmask6_2) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 3? -set fmri(conmask6_3) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 4? -set fmri(conmask6_4) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 5? -set fmri(conmask6_5) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 7? -set fmri(conmask6_7) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 8? -set fmri(conmask6_8) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 9? -set fmri(conmask6_9) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 10? -set fmri(conmask6_10) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 11? -set fmri(conmask6_11) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 12? -set fmri(conmask6_12) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 13? -set fmri(conmask6_13) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 14? -set fmri(conmask6_14) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 15? -set fmri(conmask6_15) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 16? -set fmri(conmask6_16) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 17? -set fmri(conmask6_17) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 18? -set fmri(conmask6_18) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 19? -set fmri(conmask6_19) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 20? -set fmri(conmask6_20) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 21? -set fmri(conmask6_21) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 22? -set fmri(conmask6_22) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 23? -set fmri(conmask6_23) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 24? -set fmri(conmask6_24) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 25? -set fmri(conmask6_25) 0 - -# Mask real contrast/F-test 6 with real contrast/F-test 26? -set fmri(conmask6_26) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 1? -set fmri(conmask7_1) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 2? -set fmri(conmask7_2) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 3? -set fmri(conmask7_3) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 4? -set fmri(conmask7_4) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 5? -set fmri(conmask7_5) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 6? -set fmri(conmask7_6) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 8? -set fmri(conmask7_8) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 9? -set fmri(conmask7_9) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 10? -set fmri(conmask7_10) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 11? -set fmri(conmask7_11) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 12? -set fmri(conmask7_12) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 13? -set fmri(conmask7_13) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 14? -set fmri(conmask7_14) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 15? -set fmri(conmask7_15) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 16? -set fmri(conmask7_16) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 17? -set fmri(conmask7_17) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 18? -set fmri(conmask7_18) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 19? -set fmri(conmask7_19) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 20? -set fmri(conmask7_20) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 21? -set fmri(conmask7_21) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 22? -set fmri(conmask7_22) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 23? -set fmri(conmask7_23) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 24? -set fmri(conmask7_24) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 25? -set fmri(conmask7_25) 0 - -# Mask real contrast/F-test 7 with real contrast/F-test 26? -set fmri(conmask7_26) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 1? -set fmri(conmask8_1) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 2? -set fmri(conmask8_2) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 3? -set fmri(conmask8_3) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 4? -set fmri(conmask8_4) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 5? -set fmri(conmask8_5) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 6? -set fmri(conmask8_6) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 7? -set fmri(conmask8_7) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 9? -set fmri(conmask8_9) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 10? -set fmri(conmask8_10) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 11? -set fmri(conmask8_11) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 12? -set fmri(conmask8_12) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 13? -set fmri(conmask8_13) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 14? -set fmri(conmask8_14) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 15? -set fmri(conmask8_15) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 16? -set fmri(conmask8_16) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 17? -set fmri(conmask8_17) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 18? -set fmri(conmask8_18) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 19? -set fmri(conmask8_19) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 20? -set fmri(conmask8_20) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 21? -set fmri(conmask8_21) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 22? -set fmri(conmask8_22) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 23? -set fmri(conmask8_23) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 24? -set fmri(conmask8_24) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 25? -set fmri(conmask8_25) 0 - -# Mask real contrast/F-test 8 with real contrast/F-test 26? -set fmri(conmask8_26) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 1? -set fmri(conmask9_1) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 2? -set fmri(conmask9_2) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 3? -set fmri(conmask9_3) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 4? -set fmri(conmask9_4) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 5? -set fmri(conmask9_5) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 6? -set fmri(conmask9_6) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 7? -set fmri(conmask9_7) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 8? -set fmri(conmask9_8) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 10? -set fmri(conmask9_10) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 11? -set fmri(conmask9_11) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 12? -set fmri(conmask9_12) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 13? -set fmri(conmask9_13) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 14? -set fmri(conmask9_14) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 15? -set fmri(conmask9_15) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 16? -set fmri(conmask9_16) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 17? -set fmri(conmask9_17) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 18? -set fmri(conmask9_18) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 19? -set fmri(conmask9_19) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 20? -set fmri(conmask9_20) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 21? -set fmri(conmask9_21) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 22? -set fmri(conmask9_22) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 23? -set fmri(conmask9_23) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 24? -set fmri(conmask9_24) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 25? -set fmri(conmask9_25) 0 - -# Mask real contrast/F-test 9 with real contrast/F-test 26? -set fmri(conmask9_26) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 1? -set fmri(conmask10_1) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 2? -set fmri(conmask10_2) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 3? -set fmri(conmask10_3) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 4? -set fmri(conmask10_4) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 5? -set fmri(conmask10_5) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 6? -set fmri(conmask10_6) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 7? -set fmri(conmask10_7) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 8? -set fmri(conmask10_8) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 9? -set fmri(conmask10_9) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 11? -set fmri(conmask10_11) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 12? -set fmri(conmask10_12) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 13? -set fmri(conmask10_13) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 14? -set fmri(conmask10_14) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 15? -set fmri(conmask10_15) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 16? -set fmri(conmask10_16) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 17? -set fmri(conmask10_17) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 18? -set fmri(conmask10_18) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 19? -set fmri(conmask10_19) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 20? -set fmri(conmask10_20) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 21? -set fmri(conmask10_21) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 22? -set fmri(conmask10_22) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 23? -set fmri(conmask10_23) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 24? -set fmri(conmask10_24) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 25? -set fmri(conmask10_25) 0 - -# Mask real contrast/F-test 10 with real contrast/F-test 26? -set fmri(conmask10_26) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 1? -set fmri(conmask11_1) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 2? -set fmri(conmask11_2) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 3? -set fmri(conmask11_3) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 4? -set fmri(conmask11_4) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 5? -set fmri(conmask11_5) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 6? -set fmri(conmask11_6) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 7? -set fmri(conmask11_7) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 8? -set fmri(conmask11_8) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 9? -set fmri(conmask11_9) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 10? -set fmri(conmask11_10) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 12? -set fmri(conmask11_12) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 13? -set fmri(conmask11_13) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 14? -set fmri(conmask11_14) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 15? -set fmri(conmask11_15) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 16? -set fmri(conmask11_16) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 17? -set fmri(conmask11_17) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 18? -set fmri(conmask11_18) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 19? -set fmri(conmask11_19) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 20? -set fmri(conmask11_20) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 21? -set fmri(conmask11_21) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 22? -set fmri(conmask11_22) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 23? -set fmri(conmask11_23) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 24? -set fmri(conmask11_24) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 25? -set fmri(conmask11_25) 0 - -# Mask real contrast/F-test 11 with real contrast/F-test 26? -set fmri(conmask11_26) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 1? -set fmri(conmask12_1) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 2? -set fmri(conmask12_2) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 3? -set fmri(conmask12_3) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 4? -set fmri(conmask12_4) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 5? -set fmri(conmask12_5) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 6? -set fmri(conmask12_6) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 7? -set fmri(conmask12_7) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 8? -set fmri(conmask12_8) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 9? -set fmri(conmask12_9) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 10? -set fmri(conmask12_10) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 11? -set fmri(conmask12_11) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 13? -set fmri(conmask12_13) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 14? -set fmri(conmask12_14) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 15? -set fmri(conmask12_15) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 16? -set fmri(conmask12_16) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 17? -set fmri(conmask12_17) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 18? -set fmri(conmask12_18) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 19? -set fmri(conmask12_19) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 20? -set fmri(conmask12_20) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 21? -set fmri(conmask12_21) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 22? -set fmri(conmask12_22) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 23? -set fmri(conmask12_23) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 24? -set fmri(conmask12_24) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 25? -set fmri(conmask12_25) 0 - -# Mask real contrast/F-test 12 with real contrast/F-test 26? -set fmri(conmask12_26) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 1? -set fmri(conmask13_1) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 2? -set fmri(conmask13_2) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 3? -set fmri(conmask13_3) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 4? -set fmri(conmask13_4) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 5? -set fmri(conmask13_5) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 6? -set fmri(conmask13_6) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 7? -set fmri(conmask13_7) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 8? -set fmri(conmask13_8) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 9? -set fmri(conmask13_9) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 10? -set fmri(conmask13_10) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 11? -set fmri(conmask13_11) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 12? -set fmri(conmask13_12) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 14? -set fmri(conmask13_14) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 15? -set fmri(conmask13_15) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 16? -set fmri(conmask13_16) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 17? -set fmri(conmask13_17) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 18? -set fmri(conmask13_18) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 19? -set fmri(conmask13_19) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 20? -set fmri(conmask13_20) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 21? -set fmri(conmask13_21) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 22? -set fmri(conmask13_22) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 23? -set fmri(conmask13_23) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 24? -set fmri(conmask13_24) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 25? -set fmri(conmask13_25) 0 - -# Mask real contrast/F-test 13 with real contrast/F-test 26? -set fmri(conmask13_26) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 1? -set fmri(conmask14_1) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 2? -set fmri(conmask14_2) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 3? -set fmri(conmask14_3) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 4? -set fmri(conmask14_4) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 5? -set fmri(conmask14_5) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 6? -set fmri(conmask14_6) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 7? -set fmri(conmask14_7) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 8? -set fmri(conmask14_8) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 9? -set fmri(conmask14_9) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 10? -set fmri(conmask14_10) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 11? -set fmri(conmask14_11) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 12? -set fmri(conmask14_12) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 13? -set fmri(conmask14_13) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 15? -set fmri(conmask14_15) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 16? -set fmri(conmask14_16) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 17? -set fmri(conmask14_17) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 18? -set fmri(conmask14_18) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 19? -set fmri(conmask14_19) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 20? -set fmri(conmask14_20) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 21? -set fmri(conmask14_21) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 22? -set fmri(conmask14_22) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 23? -set fmri(conmask14_23) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 24? -set fmri(conmask14_24) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 25? -set fmri(conmask14_25) 0 - -# Mask real contrast/F-test 14 with real contrast/F-test 26? -set fmri(conmask14_26) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 1? -set fmri(conmask15_1) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 2? -set fmri(conmask15_2) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 3? -set fmri(conmask15_3) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 4? -set fmri(conmask15_4) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 5? -set fmri(conmask15_5) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 6? -set fmri(conmask15_6) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 7? -set fmri(conmask15_7) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 8? -set fmri(conmask15_8) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 9? -set fmri(conmask15_9) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 10? -set fmri(conmask15_10) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 11? -set fmri(conmask15_11) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 12? -set fmri(conmask15_12) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 13? -set fmri(conmask15_13) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 14? -set fmri(conmask15_14) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 16? -set fmri(conmask15_16) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 17? -set fmri(conmask15_17) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 18? -set fmri(conmask15_18) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 19? -set fmri(conmask15_19) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 20? -set fmri(conmask15_20) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 21? -set fmri(conmask15_21) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 22? -set fmri(conmask15_22) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 23? -set fmri(conmask15_23) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 24? -set fmri(conmask15_24) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 25? -set fmri(conmask15_25) 0 - -# Mask real contrast/F-test 15 with real contrast/F-test 26? -set fmri(conmask15_26) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 1? -set fmri(conmask16_1) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 2? -set fmri(conmask16_2) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 3? -set fmri(conmask16_3) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 4? -set fmri(conmask16_4) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 5? -set fmri(conmask16_5) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 6? -set fmri(conmask16_6) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 7? -set fmri(conmask16_7) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 8? -set fmri(conmask16_8) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 9? -set fmri(conmask16_9) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 10? -set fmri(conmask16_10) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 11? -set fmri(conmask16_11) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 12? -set fmri(conmask16_12) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 13? -set fmri(conmask16_13) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 14? -set fmri(conmask16_14) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 15? -set fmri(conmask16_15) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 17? -set fmri(conmask16_17) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 18? -set fmri(conmask16_18) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 19? -set fmri(conmask16_19) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 20? -set fmri(conmask16_20) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 21? -set fmri(conmask16_21) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 22? -set fmri(conmask16_22) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 23? -set fmri(conmask16_23) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 24? -set fmri(conmask16_24) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 25? -set fmri(conmask16_25) 0 - -# Mask real contrast/F-test 16 with real contrast/F-test 26? -set fmri(conmask16_26) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 1? -set fmri(conmask17_1) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 2? -set fmri(conmask17_2) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 3? -set fmri(conmask17_3) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 4? -set fmri(conmask17_4) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 5? -set fmri(conmask17_5) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 6? -set fmri(conmask17_6) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 7? -set fmri(conmask17_7) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 8? -set fmri(conmask17_8) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 9? -set fmri(conmask17_9) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 10? -set fmri(conmask17_10) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 11? -set fmri(conmask17_11) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 12? -set fmri(conmask17_12) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 13? -set fmri(conmask17_13) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 14? -set fmri(conmask17_14) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 15? -set fmri(conmask17_15) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 16? -set fmri(conmask17_16) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 18? -set fmri(conmask17_18) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 19? -set fmri(conmask17_19) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 20? -set fmri(conmask17_20) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 21? -set fmri(conmask17_21) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 22? -set fmri(conmask17_22) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 23? -set fmri(conmask17_23) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 24? -set fmri(conmask17_24) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 25? -set fmri(conmask17_25) 0 - -# Mask real contrast/F-test 17 with real contrast/F-test 26? -set fmri(conmask17_26) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 1? -set fmri(conmask18_1) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 2? -set fmri(conmask18_2) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 3? -set fmri(conmask18_3) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 4? -set fmri(conmask18_4) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 5? -set fmri(conmask18_5) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 6? -set fmri(conmask18_6) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 7? -set fmri(conmask18_7) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 8? -set fmri(conmask18_8) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 9? -set fmri(conmask18_9) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 10? -set fmri(conmask18_10) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 11? -set fmri(conmask18_11) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 12? -set fmri(conmask18_12) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 13? -set fmri(conmask18_13) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 14? -set fmri(conmask18_14) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 15? -set fmri(conmask18_15) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 16? -set fmri(conmask18_16) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 17? -set fmri(conmask18_17) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 19? -set fmri(conmask18_19) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 20? -set fmri(conmask18_20) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 21? -set fmri(conmask18_21) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 22? -set fmri(conmask18_22) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 23? -set fmri(conmask18_23) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 24? -set fmri(conmask18_24) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 25? -set fmri(conmask18_25) 0 - -# Mask real contrast/F-test 18 with real contrast/F-test 26? -set fmri(conmask18_26) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 1? -set fmri(conmask19_1) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 2? -set fmri(conmask19_2) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 3? -set fmri(conmask19_3) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 4? -set fmri(conmask19_4) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 5? -set fmri(conmask19_5) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 6? -set fmri(conmask19_6) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 7? -set fmri(conmask19_7) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 8? -set fmri(conmask19_8) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 9? -set fmri(conmask19_9) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 10? -set fmri(conmask19_10) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 11? -set fmri(conmask19_11) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 12? -set fmri(conmask19_12) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 13? -set fmri(conmask19_13) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 14? -set fmri(conmask19_14) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 15? -set fmri(conmask19_15) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 16? -set fmri(conmask19_16) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 17? -set fmri(conmask19_17) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 18? -set fmri(conmask19_18) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 20? -set fmri(conmask19_20) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 21? -set fmri(conmask19_21) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 22? -set fmri(conmask19_22) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 23? -set fmri(conmask19_23) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 24? -set fmri(conmask19_24) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 25? -set fmri(conmask19_25) 0 - -# Mask real contrast/F-test 19 with real contrast/F-test 26? -set fmri(conmask19_26) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 1? -set fmri(conmask20_1) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 2? -set fmri(conmask20_2) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 3? -set fmri(conmask20_3) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 4? -set fmri(conmask20_4) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 5? -set fmri(conmask20_5) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 6? -set fmri(conmask20_6) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 7? -set fmri(conmask20_7) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 8? -set fmri(conmask20_8) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 9? -set fmri(conmask20_9) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 10? -set fmri(conmask20_10) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 11? -set fmri(conmask20_11) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 12? -set fmri(conmask20_12) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 13? -set fmri(conmask20_13) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 14? -set fmri(conmask20_14) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 15? -set fmri(conmask20_15) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 16? -set fmri(conmask20_16) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 17? -set fmri(conmask20_17) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 18? -set fmri(conmask20_18) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 19? -set fmri(conmask20_19) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 21? -set fmri(conmask20_21) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 22? -set fmri(conmask20_22) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 23? -set fmri(conmask20_23) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 24? -set fmri(conmask20_24) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 25? -set fmri(conmask20_25) 0 - -# Mask real contrast/F-test 20 with real contrast/F-test 26? -set fmri(conmask20_26) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 1? -set fmri(conmask21_1) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 2? -set fmri(conmask21_2) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 3? -set fmri(conmask21_3) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 4? -set fmri(conmask21_4) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 5? -set fmri(conmask21_5) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 6? -set fmri(conmask21_6) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 7? -set fmri(conmask21_7) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 8? -set fmri(conmask21_8) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 9? -set fmri(conmask21_9) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 10? -set fmri(conmask21_10) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 11? -set fmri(conmask21_11) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 12? -set fmri(conmask21_12) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 13? -set fmri(conmask21_13) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 14? -set fmri(conmask21_14) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 15? -set fmri(conmask21_15) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 16? -set fmri(conmask21_16) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 17? -set fmri(conmask21_17) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 18? -set fmri(conmask21_18) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 19? -set fmri(conmask21_19) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 20? -set fmri(conmask21_20) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 22? -set fmri(conmask21_22) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 23? -set fmri(conmask21_23) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 24? -set fmri(conmask21_24) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 25? -set fmri(conmask21_25) 0 - -# Mask real contrast/F-test 21 with real contrast/F-test 26? -set fmri(conmask21_26) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 1? -set fmri(conmask22_1) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 2? -set fmri(conmask22_2) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 3? -set fmri(conmask22_3) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 4? -set fmri(conmask22_4) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 5? -set fmri(conmask22_5) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 6? -set fmri(conmask22_6) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 7? -set fmri(conmask22_7) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 8? -set fmri(conmask22_8) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 9? -set fmri(conmask22_9) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 10? -set fmri(conmask22_10) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 11? -set fmri(conmask22_11) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 12? -set fmri(conmask22_12) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 13? -set fmri(conmask22_13) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 14? -set fmri(conmask22_14) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 15? -set fmri(conmask22_15) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 16? -set fmri(conmask22_16) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 17? -set fmri(conmask22_17) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 18? -set fmri(conmask22_18) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 19? -set fmri(conmask22_19) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 20? -set fmri(conmask22_20) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 21? -set fmri(conmask22_21) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 23? -set fmri(conmask22_23) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 24? -set fmri(conmask22_24) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 25? -set fmri(conmask22_25) 0 - -# Mask real contrast/F-test 22 with real contrast/F-test 26? -set fmri(conmask22_26) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 1? -set fmri(conmask23_1) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 2? -set fmri(conmask23_2) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 3? -set fmri(conmask23_3) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 4? -set fmri(conmask23_4) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 5? -set fmri(conmask23_5) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 6? -set fmri(conmask23_6) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 7? -set fmri(conmask23_7) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 8? -set fmri(conmask23_8) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 9? -set fmri(conmask23_9) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 10? -set fmri(conmask23_10) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 11? -set fmri(conmask23_11) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 12? -set fmri(conmask23_12) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 13? -set fmri(conmask23_13) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 14? -set fmri(conmask23_14) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 15? -set fmri(conmask23_15) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 16? -set fmri(conmask23_16) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 17? -set fmri(conmask23_17) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 18? -set fmri(conmask23_18) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 19? -set fmri(conmask23_19) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 20? -set fmri(conmask23_20) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 21? -set fmri(conmask23_21) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 22? -set fmri(conmask23_22) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 24? -set fmri(conmask23_24) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 25? -set fmri(conmask23_25) 0 - -# Mask real contrast/F-test 23 with real contrast/F-test 26? -set fmri(conmask23_26) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 1? -set fmri(conmask24_1) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 2? -set fmri(conmask24_2) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 3? -set fmri(conmask24_3) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 4? -set fmri(conmask24_4) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 5? -set fmri(conmask24_5) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 6? -set fmri(conmask24_6) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 7? -set fmri(conmask24_7) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 8? -set fmri(conmask24_8) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 9? -set fmri(conmask24_9) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 10? -set fmri(conmask24_10) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 11? -set fmri(conmask24_11) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 12? -set fmri(conmask24_12) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 13? -set fmri(conmask24_13) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 14? -set fmri(conmask24_14) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 15? -set fmri(conmask24_15) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 16? -set fmri(conmask24_16) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 17? -set fmri(conmask24_17) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 18? -set fmri(conmask24_18) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 19? -set fmri(conmask24_19) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 20? -set fmri(conmask24_20) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 21? -set fmri(conmask24_21) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 22? -set fmri(conmask24_22) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 23? -set fmri(conmask24_23) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 25? -set fmri(conmask24_25) 0 - -# Mask real contrast/F-test 24 with real contrast/F-test 26? -set fmri(conmask24_26) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 1? -set fmri(conmask25_1) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 2? -set fmri(conmask25_2) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 3? -set fmri(conmask25_3) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 4? -set fmri(conmask25_4) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 5? -set fmri(conmask25_5) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 6? -set fmri(conmask25_6) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 7? -set fmri(conmask25_7) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 8? -set fmri(conmask25_8) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 9? -set fmri(conmask25_9) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 10? -set fmri(conmask25_10) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 11? -set fmri(conmask25_11) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 12? -set fmri(conmask25_12) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 13? -set fmri(conmask25_13) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 14? -set fmri(conmask25_14) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 15? -set fmri(conmask25_15) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 16? -set fmri(conmask25_16) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 17? -set fmri(conmask25_17) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 18? -set fmri(conmask25_18) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 19? -set fmri(conmask25_19) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 20? -set fmri(conmask25_20) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 21? -set fmri(conmask25_21) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 22? -set fmri(conmask25_22) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 23? -set fmri(conmask25_23) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 24? -set fmri(conmask25_24) 0 - -# Mask real contrast/F-test 25 with real contrast/F-test 26? -set fmri(conmask25_26) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 1? -set fmri(conmask26_1) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 2? -set fmri(conmask26_2) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 3? -set fmri(conmask26_3) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 4? -set fmri(conmask26_4) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 5? -set fmri(conmask26_5) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 6? -set fmri(conmask26_6) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 7? -set fmri(conmask26_7) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 8? -set fmri(conmask26_8) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 9? -set fmri(conmask26_9) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 10? -set fmri(conmask26_10) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 11? -set fmri(conmask26_11) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 12? -set fmri(conmask26_12) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 13? -set fmri(conmask26_13) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 14? -set fmri(conmask26_14) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 15? -set fmri(conmask26_15) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 16? -set fmri(conmask26_16) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 17? -set fmri(conmask26_17) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 18? -set fmri(conmask26_18) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 19? -set fmri(conmask26_19) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 20? -set fmri(conmask26_20) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 21? -set fmri(conmask26_21) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 22? -set fmri(conmask26_22) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 23? -set fmri(conmask26_23) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 24? -set fmri(conmask26_24) 0 - -# Mask real contrast/F-test 26 with real contrast/F-test 25? -set fmri(conmask26_25) 0 - -# Do contrast masking at all? -set fmri(conmask1_1) 0 - -########################################################## -# Now options that don't appear in the GUI - -# Alternative (to BETting) mask image -set fmri(alternative_mask) "" - -# Initial structural space registration initialisation transform -set fmri(init_initial_highres) "" - -# Structural space registration initialisation transform -set fmri(init_highres) "" - -# Standard space registration initialisation transform -set fmri(init_standard) "" - -# For full FEAT analysis: overwrite existing .feat output dir? -set fmri(overwrite_yn) 0 diff --git a/pydra/tasks/fsl/tests/data/test.nii.gz b/pydra/tasks/fsl/tests/data/test.nii.gz deleted file mode 100644 index a25d016..0000000 --- a/pydra/tasks/fsl/tests/data/test.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:05271ea95146ecc19af198d7052cdfa5ef98a6796b2179c6789422447978974a -size 28061534 diff --git a/pydra/tasks/fsl/tests/data/test2.nii b/pydra/tasks/fsl/tests/data/test2.nii deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/test3.nii b/pydra/tasks/fsl/tests/data/test3.nii deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/test_film_gls.nii.gz b/pydra/tasks/fsl/tests/data/test_film_gls.nii.gz deleted file mode 100644 index 75ee73d..0000000 --- a/pydra/tasks/fsl/tests/data/test_film_gls.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f164986665ec302f7d09ebfb3fe8047df8787e24394e680d513e180e6a25df30 -size 27889429 diff --git a/pydra/tasks/fsl/tests/data/test_warpcoef.nii.gz b/pydra/tasks/fsl/tests/data/test_warpcoef.nii.gz deleted file mode 100644 index 0991c88..0000000 --- a/pydra/tasks/fsl/tests/data/test_warpcoef.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bb3d96bd875f3bd3ccb37caa761336c7e9f52779d19cd21a059d777b04885785 -size 325 diff --git a/pydra/tasks/fsl/tests/data/timeDesign.con b/pydra/tasks/fsl/tests/data/timeDesign.con deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/timeDesign.mat b/pydra/tasks/fsl/tests/data/timeDesign.mat deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/varcope_merged.nii.gz b/pydra/tasks/fsl/tests/data/varcope_merged.nii.gz deleted file mode 100644 index d777854..0000000 --- a/pydra/tasks/fsl/tests/data/varcope_merged.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:67fd15e24c00fd6736ca6a5492fb2b51672e20dde9aa693bc75a910f8c2ed4ca -size 23935446 diff --git a/pydra/tasks/fsl/tests/data/warpfield.nii b/pydra/tasks/fsl/tests/data/warpfield.nii deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/tests/data/warpfield.nii.gz b/pydra/tasks/fsl/tests/data/warpfield.nii.gz deleted file mode 100644 index a25d016..0000000 --- a/pydra/tasks/fsl/tests/data/warpfield.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:05271ea95146ecc19af198d7052cdfa5ef98a6796b2179c6789422447978974a -size 28061534 diff --git a/pydra/tasks/fsl/tests/data/zstat1.nii.gz b/pydra/tasks/fsl/tests/data/zstat1.nii.gz deleted file mode 100644 index 246c3e4..0000000 --- a/pydra/tasks/fsl/tests/data/zstat1.nii.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:217ee66ca638ee732b7e82c16ff841f38aa7dd19b7a473d6e94b7de2fdb685e0 -size 961353 diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/utils/complex.py b/pydra/tasks/fsl/utils/complex.py deleted file mode 100644 index 0170b06..0000000 --- a/pydra/tasks/fsl/utils/complex.py +++ /dev/null @@ -1,267 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def Complex_output(inputs): - import attr - - if inputs.complex_cartesian: - in_file = inputs.real_in_file - elif inputs.complex_polar: - in_file = inputs.magnitude_in_file - elif inputs.complex_split or inputs.complex_merge: - in_file = inputs.complex_in_file - else: - return None - return f"{in_file}_cplx" - - -input_fields = [ - ( - "complex_in_file", - specs.File, - {"help_string": "", "argstr": "{complex_in_file}", "position": 2}, - ), - ( - "complex_in_file2", - specs.File, - {"help_string": "", "argstr": "{complex_in_file2}", "position": 3}, - ), - ( - "real_in_file", - specs.File, - {"help_string": "", "argstr": "{real_in_file}", "position": 2}, - ), - ( - "imaginary_in_file", - specs.File, - {"help_string": "", "argstr": "{imaginary_in_file}", "position": 3}, - ), - ( - "magnitude_in_file", - specs.File, - {"help_string": "", "argstr": "{magnitude_in_file}", "position": 2}, - ), - ( - "phase_in_file", - specs.File, - {"help_string": "", "argstr": "{phase_in_file}", "position": 3}, - ), - ( - "complex_out_file", - str, - { - "help_string": "", - "argstr": "{complex_out_file}", - "position": -3, - "xor": [ - "complex_out_file", - "magnitude_out_file", - "phase_out_file", - "real_out_file", - "imaginary_out_file", - "real_polar", - "real_cartesian", - ], - }, - ), - ( - "magnitude_out_file", - str, - { - "help_string": "", - "argstr": "{magnitude_out_file}", - "position": -4, - "xor": [ - "complex_out_file", - "real_out_file", - "imaginary_out_file", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - "output_file_template": "{in_file}_mag", - }, - ), - ( - "phase_out_file", - str, - { - "help_string": "", - "argstr": "{phase_out_file}", - "position": -3, - "xor": [ - "complex_out_file", - "real_out_file", - "imaginary_out_file", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - "output_file_template": "{in_file}_phase", - }, - ), - ( - "real_out_file", - str, - { - "help_string": "", - "argstr": "{real_out_file}", - "position": -4, - "xor": [ - "complex_out_file", - "magnitude_out_file", - "phase_out_file", - "real_polar", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - "output_file_template": "{in_file}_real", - }, - ), - ( - "imaginary_out_file", - str, - { - "help_string": "", - "argstr": "{imaginary_out_file}", - "position": -3, - "xor": [ - "complex_out_file", - "magnitude_out_file", - "phase_out_file", - "real_polar", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - "output_file_template": "{in_file}_imag", - }, - ), - ("start_vol", int, {"help_string": "", "argstr": "{start_vol}", "position": -2}), - ("end_vol", int, {"help_string": "", "argstr": "{end_vol}", "position": -1}), - ( - "real_polar", - bool, - { - "help_string": "", - "argstr": "-realpolar", - "position": 1, - "xor": [ - "real_polar", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - }, - ), - ( - "real_cartesian", - bool, - { - "help_string": "", - "argstr": "-realcartesian", - "position": 1, - "xor": [ - "real_polar", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - }, - ), - ( - "complex_cartesian", - bool, - { - "help_string": "", - "argstr": "-complex", - "position": 1, - "xor": [ - "real_polar", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - }, - ), - ( - "complex_polar", - bool, - { - "help_string": "", - "argstr": "-complexpolar", - "position": 1, - "xor": [ - "real_polar", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - }, - ), - ( - "complex_split", - bool, - { - "help_string": "", - "argstr": "-complexsplit", - "position": 1, - "xor": [ - "real_polar", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - ], - }, - ), - ( - "complex_merge", - bool, - { - "help_string": "", - "argstr": "-complexmerge", - "position": 1, - "xor": [ - "real_polar", - "real_cartesian", - "complex_cartesian", - "complex_polar", - "complex_split", - "complex_merge", - "start_vol", - "end_vol", - ], - }, - ), -] -Complex_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -Complex_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class Complex(ShellCommandTask): - input_spec = Complex_input_spec - output_spec = Complex_output_spec - executable = "fslcomplex" diff --git a/pydra/tasks/fsl/utils/convertwarp.py b/pydra/tasks/fsl/utils/convertwarp.py deleted file mode 100644 index 5d8ab40..0000000 --- a/pydra/tasks/fsl/utils/convertwarp.py +++ /dev/null @@ -1,169 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "reference", - specs.File, - { - "help_string": "Name of a file in target space of the full transform.", - "argstr": "--ref={reference}", - "mandatory": True, - "position": 1, - }, - ), - ( - "out_file", - str, - { - "help_string": "Name of output file, containing warps that are the combination of all those given as arguments. The format of this will be a field-file (rather than spline coefficients) with any affine components included.", - "argstr": "--out={out_file}", - "position": -1, - "output_file_template": "{reference}_concatwarp", - }, - ), - ( - "premat", - specs.File, - { - "help_string": "filename for pre-transform (affine matrix)", - "argstr": "--premat={premat}", - }, - ), - ( - "warp1", - specs.File, - { - "help_string": "Name of file containing initial warp-fields/coefficients (follows premat). This could e.g. be a fnirt-transform from a subjects structural scan to an average of a group of subjects.", - "argstr": "--warp1={warp1}", - }, - ), - ( - "midmat", - specs.File, - { - "help_string": "Name of file containing mid-warp-affine transform", - "argstr": "--midmat={midmat}", - }, - ), - ( - "warp2", - specs.File, - { - "help_string": "Name of file containing secondary warp-fields/coefficients (after warp1/midmat but before postmat). This could e.g. be a fnirt-transform from the average of a group of subjects to some standard space (e.g. MNI152).", - "argstr": "--warp2={warp2}", - }, - ), - ( - "postmat", - specs.File, - { - "help_string": "Name of file containing an affine transform (applied last). It could e.g. be an affine transform that maps the MNI152-space into a better approximation to the Talairach-space (if indeed there is one).", - "argstr": "--postmat={postmat}", - }, - ), - ( - "shift_in_file", - specs.File, - { - "help_string": 'Name of file containing a "shiftmap", a non-linear transform with displacements only in one direction (applied first, before premat). This would typically be a fieldmap that has been pre-processed using fugue that maps a subjects functional (EPI) data onto an undistorted space (i.e. a space that corresponds to his/her true anatomy).', - "argstr": "--shiftmap={shift_in_file}", - }, - ), - ( - "shift_direction", - ty.Any, - { - "help_string": "Indicates the direction that the distortions from --shiftmap goes. It depends on the direction and polarity of the phase-encoding in the EPI sequence.", - "argstr": "--shiftdir={shift_direction}", - "requires": ["shift_in_file"], - }, - ), - ( - "cons_jacobian", - bool, - { - "help_string": "Constrain the Jacobian of the warpfield to lie within specified min/max limits.", - "argstr": "--constrainj", - }, - ), - ( - "jacobian_min", - float, - { - "help_string": "Minimum acceptable Jacobian value for constraint (default 0.01)", - "argstr": "--jmin={jacobian_min}", - }, - ), - ( - "jacobian_max", - float, - { - "help_string": "Maximum acceptable Jacobian value for constraint (default 100.0)", - "argstr": "--jmax={jacobian_max}", - }, - ), - ( - "abswarp", - bool, - { - "help_string": "If set it indicates that the warps in --warp1 and --warp2 should be interpreted as absolute. I.e. the values in --warp1/2 are the coordinates in the next space, rather than displacements. This flag is ignored if --warp1/2 was created by fnirt, which always creates relative displacements.", - "argstr": "--abs", - "xor": ["relwarp"], - }, - ), - ( - "relwarp", - bool, - { - "help_string": "If set it indicates that the warps in --warp1/2 should be interpreted as relative. I.e. the values in --warp1/2 are displacements from the coordinates in the next space.", - "argstr": "--rel", - "xor": ["abswarp"], - }, - ), - ( - "out_abswarp", - bool, - { - "help_string": "If set it indicates that the warps in --out should be absolute, i.e. the values in --out are displacements from the coordinates in --ref.", - "argstr": "--absout", - "xor": ["out_relwarp"], - }, - ), - ( - "out_relwarp", - bool, - { - "help_string": "If set it indicates that the warps in --out should be relative, i.e. the values in --out are displacements from the coordinates in --ref.", - "argstr": "--relout", - "xor": ["out_abswarp"], - }, - ), -] -ConvertWarp_input_spec = specs.SpecInfo( - name="Input", fields=input_fields, bases=(specs.ShellSpec,) -) - -output_fields = [] -ConvertWarp_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ConvertWarp(ShellCommandTask): - """ - Example - ------- - >>> task = ConvertWarp() - >>> task.inputs.warp1 = "warpfield.nii" - >>> task.inputs.reference = "test.nii.gz" - >>> task.inputs.relwarp = True - >>> task.inputs.out_file = "test_concatwarp.nii.gz" - >>> task.cmdline - 'convertwarp --ref=test.nii.gz --warp1=warpfield.nii --rel --out=test_concatwarp.nii.gz' - """ - - input_spec = ConvertWarp_input_spec - output_spec = ConvertWarp_output_spec - executable = "convertwarp" diff --git a/pydra/tasks/fsl/utils/convertxfm.py b/pydra/tasks/fsl/utils/convertxfm.py deleted file mode 100644 index 48dc601..0000000 --- a/pydra/tasks/fsl/utils/convertxfm.py +++ /dev/null @@ -1,110 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def ConvertXFM_output(inputs): - import attr - - in_file = inputs.in_file - if inputs.invert_xfm: - return f"{in_file}_inv" - elif inputs.concat_xfm: - if inputs.in_file2.exists(): - in_file2 = inputs.in_file2 - return f"{in_file}_{in_file2}" - else: - raise Exception("in_file2 is needed to use concat_xfm") - - elif inputs.fix_scale_skew: - return f"{in_file}_fix" - else: - raise Exception("this function requires invert_xfm, or concat_xfm," "or fix_scale_skew") - - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input transformation matrix", - "argstr": "{in_file}", - "mandatory": True, - "position": -1, - }, - ), - ( - "in_file2", - specs.File, - { - "help_string": "second input matrix (for use with fix_scale_skew or concat_xfm)", - "argstr": "{in_file2}", - "position": -2, - }, - ), - ( - "invert_xfm", - bool, - { - "help_string": "invert input transformation", - "argstr": "-inverse", - "position": -3, - "xor": ["invert_xfm", "concat_xfm", "fix_scale_skew"], - }, - ), - ( - "concat_xfm", - bool, - { - "help_string": "write joint transformation of two input matrices", - "argstr": "-concat", - "position": -3, - "requires": ["in_file2"], - "xor": ["invert_xfm", "concat_xfm", "fix_scale_skew"], - }, - ), - ( - "fix_scale_skew", - bool, - { - "help_string": "use secondary matrix to fix scale and skew", - "argstr": "-fixscaleskew", - "position": -3, - "requires": ["in_file2"], - "xor": ["invert_xfm", "concat_xfm", "fix_scale_skew"], - }, - ), - ( - "out_file", - str, - { - "help_string": "final transformation matrix", - "argstr": "-omat {out_file}", - "position": 1, - "output_file_template": ConvertXFM_output, - }, - ), -] -ConvertXFM_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -ConvertXFM_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ConvertXFM(ShellCommandTask): - """ - Example - ------- - >>> task = ConvertXFM() - >>> task.inputs.in_file = "flirt.mat" - >>> task.inputs.invert_xfm = True - >>> task.inputs.out_file = "flirt_inv.mat" - >>> task.cmdline - 'convert_xfm -omat flirt_inv.mat -inverse flirt.mat' - """ - - input_spec = ConvertXFM_input_spec - output_spec = ConvertXFM_output_spec - executable = "convert_xfm" diff --git a/pydra/tasks/fsl/utils/copygeom.py b/pydra/tasks/fsl/utils/copygeom.py deleted file mode 100644 index 11b94c7..0000000 --- a/pydra/tasks/fsl/utils/copygeom.py +++ /dev/null @@ -1,69 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "source image", - "argstr": "{in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "dest_file", - str, - { - "help_string": "destination image", - "argstr": "{dest_file}", - "copyfile": True, - "mandatory": True, - "position": 1, - "output_file_template": "{dest_file}", - }, - ), - ( - "ignore_dims", - bool, - { - "help_string": "Do not copy image dimensions", - "argstr": "-d", - "position": "-1", - }, - ), -] -CopyGeom_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "out_file", - specs.File, - { - "help_string": "image with new geometry header", - "requires": ["in_file", "dest_file"], - "output_file_template": "{dest_file}", - }, - ) -] -CopyGeom_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class CopyGeom(ShellCommandTask): - """ - Example - ------- - >>> task = CopyGeom() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.dest_file = "dest.nii.gz" - >>> task.cmdline - 'fslcpgeom test.nii.gz dest.nii.gz' - """ - - input_spec = CopyGeom_input_spec - output_spec = CopyGeom_output_spec - executable = "fslcpgeom" diff --git a/pydra/tasks/fsl/utils/extractroi.py b/pydra/tasks/fsl/utils/extractroi.py deleted file mode 100644 index da34f08..0000000 --- a/pydra/tasks/fsl/utils/extractroi.py +++ /dev/null @@ -1,58 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input file", - "argstr": "{in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "roi_file", - str, - { - "help_string": "output file", - "argstr": "{roi_file}", - "position": 1, - "output_file_template": "{in_file}_trim", - }, - ), - ("x_min", int, {"help_string": "", "argstr": "{x_min}", "position": 2}), - ("x_size", int, {"help_string": "", "argstr": "{x_size}", "position": 3}), - ("y_min", int, {"help_string": "", "argstr": "{y_min}", "position": 4}), - ("y_size", int, {"help_string": "", "argstr": "{y_size}", "position": 5}), - ("z_min", int, {"help_string": "", "argstr": "{z_min}", "position": 6}), - ("z_size", int, {"help_string": "", "argstr": "{z_size}", "position": 7}), - ("t_min", int, {"help_string": "", "argstr": "{t_min}", "position": 8}), - ("t_size", int, {"help_string": "", "argstr": "{t_size}", "position": 9}), -] -ExtractROI_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -ExtractROI_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ExtractROI(ShellCommandTask): - """ - Example - ------- - >>> task = ExtractROI() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.t_min = 0 - >>> task.inputs.t_size = 3 - >>> task.inputs.roi_file = "test_trim.nii.gz" - >>> task.cmdline - 'fslroi test.nii.gz test_trim.nii.gz 0 3' - """ - - input_spec = ExtractROI_input_spec - output_spec = ExtractROI_output_spec - executable = "fslroi" diff --git a/pydra/tasks/fsl/utils/filterregressor.py b/pydra/tasks/fsl/utils/filterregressor.py deleted file mode 100644 index 21985d0..0000000 --- a/pydra/tasks/fsl/utils/filterregressor.py +++ /dev/null @@ -1,91 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input file name (4D image)", - "argstr": "-i {in_file}", - "mandatory": True, - "position": 1, - }, - ), - ( - "out_file", - str, - { - "help_string": "output file name for the filtered data", - "argstr": "-o {out_file}", - "position": 2, - "output_file_template": "{in_file}_filtered", - }, - ), - ( - "design_file", - specs.File, - { - "help_string": "name of the matrix with time courses (e.g. GLM design or MELODIC mixing matrix)", - "argstr": "-d {design_file}", - "mandatory": True, - "position": 3, - }, - ), - ( - "filter_columns", - list, - { - "help_string": "(1-based) column indices to filter out of the data", - "argstr": "-f '{filter_columns}'", - "mandatory": True, - "position": 4, - "xor": ["filter_all"], - }, - ), - ( - "mask", - specs.File, - {"help_string": "mask image file name", "argstr": "-m {mask}"}, - ), - ( - "var_norm", - bool, - {"help_string": "perform variance-normalization on data", "argstr": "--vn"}, - ), - ( - "out_vnscales", - bool, - { - "help_string": "output scaling factors for variance normalization", - "argstr": "--out_vnscales", - }, - ), -] -FilterRegressor_input_spec = specs.SpecInfo( - name="Input", fields=input_fields, bases=(specs.ShellSpec,) -) - -output_fields = [] -FilterRegressor_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class FilterRegressor(ShellCommandTask): - """ - Example - ------- - >>> task = FilterRegressor() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.design_file = "design" - >>> task.inputs.filter_columns = "1,2,3" - >>> task.inputs.out_file = "test_filtered.nii.gz" - >>> task.cmdline - 'fsl_regfilt -i test.nii.gz -o test_filtered.nii.gz -d design -f 1,2,3' - """ - - input_spec = FilterRegressor_input_spec - output_spec = FilterRegressor_output_spec - executable = "fsl_regfilt" diff --git a/pydra/tasks/fsl/utils/imagemaths.py b/pydra/tasks/fsl/utils/imagemaths.py deleted file mode 100644 index 7cdf89e..0000000 --- a/pydra/tasks/fsl/utils/imagemaths.py +++ /dev/null @@ -1,75 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - {"help_string": "", "argstr": "{in_file}", "mandatory": True, "position": 1}, - ), - ( - "in_file2", - specs.File, - {"help_string": "", "argstr": "{in_file2}", "position": 3}, - ), - ( - "mask_file", - specs.File, - { - "help_string": "use (following image>0) to mask current image", - "argstr": "-mas {mask_file}", - }, - ), - ( - "out_file", - str, - { - "help_string": "", - "argstr": "{out_file}", - "position": -2, - "output_file_template": "{in_file}_maths", - }, - ), - ( - "op_string", - str, - { - "help_string": "string defining the operation, i. e. -add", - "argstr": "{op_string}", - "position": 2, - }, - ), - ( - "out_data_type", - ty.Any, - { - "help_string": "output datatype, one of (char, short, int, float, double, input)", - "argstr": "-odt {out_data_type}", - "position": -1, - }, - ), -] -ImageMaths_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -ImageMaths_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ImageMaths(ShellCommandTask): - """ - Example - ------- - >>> task = ImageMaths() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.op_string = "-add 5" - >>> task.inputs.out_file = "test_maths.nii.gz" - >>> task.cmdline - 'fslmaths test.nii.gz -add 5 test_maths.nii.gz' - """ - - input_spec = ImageMaths_input_spec - output_spec = ImageMaths_output_spec - executable = "fslmaths" diff --git a/pydra/tasks/fsl/utils/imagemeants.py b/pydra/tasks/fsl/utils/imagemeants.py deleted file mode 100644 index 64b0eef..0000000 --- a/pydra/tasks/fsl/utils/imagemeants.py +++ /dev/null @@ -1,105 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input file for computing the average timeseries", - "argstr": "-i {in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "out_file", - str, - { - "help_string": "name of output text matrix", - "argstr": "-o {out_file}", - "output_file_template": "{in_file}_meants.txt", - }, - ), - ("mask", specs.File, {"help_string": "input 3D mask", "argstr": "-m {mask}"}), - ( - "spatial_coord", - list, - { - "help_string": " requested spatial coordinate (instead of mask)", - "argstr": "-c {spatial_coord}", - }, - ), - ( - "use_mm", - bool, - { - "help_string": "use mm instead of voxel coordinates (for -c option)", - "argstr": "--usemm", - }, - ), - ( - "show_all", - bool, - { - "help_string": "show all voxel time series (within mask) instead of averaging", - "argstr": "--showall", - }, - ), - ( - "eig", - bool, - { - "help_string": "calculate Eigenvariate(s) instead of mean (output will have 0 mean)", - "argstr": "--eig", - }, - ), - ( - "order", - int, - 1, - {"help_string": "select number of Eigenvariates", "argstr": "--order={order}"}, - ), - ( - "nobin", - bool, - { - "help_string": "do not binarise the mask for calculation of Eigenvariates", - "argstr": "--no_bin", - }, - ), - ( - "transpose", - bool, - { - "help_string": "output results in transpose format (one row per voxel/mean)", - "argstr": "--transpose", - }, - ), -] -ImageMeants_input_spec = specs.SpecInfo( - name="Input", fields=input_fields, bases=(specs.ShellSpec,) -) - -output_fields = [] -ImageMeants_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ImageMeants(ShellCommandTask): - """ - Example - ------- - >>> task = ImageMeants() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.mask = "mask.nii.gz" - >>> task.inputs.out_file = "test_meants.txt" - >>> task.cmdline - 'fslmeants -i test.nii.gz -o test_meants.txt -m mask.nii.gz --order=1' - """ - - input_spec = ImageMeants_input_spec - output_spec = ImageMeants_output_spec - executable = "fslmeants" diff --git a/pydra/tasks/fsl/utils/imagestats.py b/pydra/tasks/fsl/utils/imagestats.py deleted file mode 100644 index 54a6438..0000000 --- a/pydra/tasks/fsl/utils/imagestats.py +++ /dev/null @@ -1,77 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "split_4d", - bool, - { - "help_string": "give a separate output line for each 3D volume of a 4D timeseries", - "argstr": "-t", - "position": 1, - }, - ), - ( - "in_file", - specs.File, - { - "help_string": "input file to generate stats of", - "argstr": "{in_file}", - "mandatory": True, - "position": 3, - }, - ), - ( - "op_string", - str, - { - "help_string": "string defining the operation, options are applied in order, e.g. -M -l 10 -M will report the non-zero mean, apply a threshold and then report the new nonzero mean", - "argstr": "{op_string}", - "mandatory": True, - "position": 4, - }, - ), - ( - "mask_file", - specs.File, - {"help_string": "mask file used for option -k %s", "argstr": ""}, - ), - ( - "index_mask_file", - specs.File, - { - "help_string": "generate seperate n submasks from indexMask, for indexvalues 1..n where n is the maximum index value in indexMask, and generate statistics for each submask", - "argstr": "-K {index_mask_file}", - "position": 2, - }, - ), -] -ImageStats_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "out_stat", - ty.Any, - {"help_string": "stats output", "requires": ["in_file", "op_string"]}, - ) -] -ImageStats_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class ImageStats(ShellCommandTask): - """ - Example - ------- - >>> task = ImageStats() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.op_string = "-M" - >>> task.cmdline - 'fslstats test.nii.gz -M' - """ - - input_spec = ImageStats_input_spec - output_spec = ImageStats_output_spec - executable = "fslstats" diff --git a/pydra/tasks/fsl/utils/invwarp.py b/pydra/tasks/fsl/utils/invwarp.py deleted file mode 100644 index 26b77c5..0000000 --- a/pydra/tasks/fsl/utils/invwarp.py +++ /dev/null @@ -1,111 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "warp", - specs.File, - { - "help_string": "Name of file containing warp-coefficients/fields. This would typically be the output from the --cout switch of fnirt (but can also use fields, like the output from --fout).", - "argstr": "--warp={warp}", - "mandatory": True, - }, - ), - ( - "reference", - specs.File, - { - "help_string": "Name of a file in target space. Note that the target space is now different from the target space that was used to create the --warp file. It would typically be the file that was specified with the --in argument when running fnirt.", - "argstr": "--ref={reference}", - "mandatory": True, - }, - ), - ( - "inverse_warp", - str, - { - "help_string": 'Name of output file, containing warps that are the "reverse" of those in --warp. This will be a field-file (rather than a file of spline coefficients), and it will have any affine component included as part of the displacements.', - "argstr": "--out={inverse_warp}", - "output_file_template": "{warp}_inverse", - }, - ), - ( - "absolute", - bool, - { - "help_string": "If set it indicates that the warps in --warp should be interpreted as absolute, provided that it is not created by fnirt (which always uses relative warps). If set it also indicates that the output --out should be absolute.", - "argstr": "--abs", - "xor": ["relative"], - }, - ), - ( - "relative", - bool, - { - "help_string": "If set it indicates that the warps in --warp should be interpreted as relative. I.e. the values in --warp are displacements from the coordinates in the --ref space. If set it also indicates that the output --out should be relative.", - "argstr": "--rel", - "xor": ["absolute"], - }, - ), - ( - "niter", - int, - { - "help_string": "Determines how many iterations of the gradient-descent search that should be run.", - "argstr": "--niter={niter}", - }, - ), - ( - "regularise", - float, - { - "help_string": "Regularization strength (deafult=1.0).", - "argstr": "--regularise={regularise}", - }, - ), - ( - "noconstraint", - bool, - {"help_string": "Do not apply Jacobian constraint", "argstr": "--noconstraint"}, - ), - ( - "jacobian_min", - float, - { - "help_string": "Minimum acceptable Jacobian value for constraint (default 0.01)", - "argstr": "--jmin={jacobian_min}", - }, - ), - ( - "jacobian_max", - float, - { - "help_string": "Maximum acceptable Jacobian value for constraint (default 100.0)", - "argstr": "--jmax={jacobian_max}", - }, - ), -] -InvWarp_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -InvWarp_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class InvWarp(ShellCommandTask): - """ - Example - ------- - >>> task = InvWarp() - >>> task.inputs.reference = "anatomical.nii" - >>> task.inputs.warp = "struct2mni.nii" - >>> task.inputs.inverse_warp = "struct2mni_inverse.nii.gz" - >>> task.cmdline - 'invwarp --warp=struct2mni.nii --ref=anatomical.nii --out=struct2mni_inverse.nii.gz' - """ - - input_spec = InvWarp_input_spec - output_spec = InvWarp_output_spec - executable = "invwarp" diff --git a/pydra/tasks/fsl/utils/slice.py b/pydra/tasks/fsl/utils/slice.py deleted file mode 100644 index f728857..0000000 --- a/pydra/tasks/fsl/utils/slice.py +++ /dev/null @@ -1,44 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input filename", - "argstr": "{in_file}", - "copyfile": False, - "mandatory": True, - "position": 0, - }, - ), - ( - "out_base_name", - str, - {"help_string": "outputs prefix", "argstr": "{out_base_name}", "position": 1}, - ), -] -Slice_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -Slice_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class Slice(ShellCommandTask): - """ - Example - ------- - >>> task = Slice() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.out_base_name = "sl" - >>> task.cmdline - 'fslslice test.nii.gz sl' - """ - - input_spec = Slice_input_spec - output_spec = Slice_output_spec - executable = "fslslice" diff --git a/pydra/tasks/fsl/utils/smooth.py b/pydra/tasks/fsl/utils/smooth.py deleted file mode 100644 index cc24ae7..0000000 --- a/pydra/tasks/fsl/utils/smooth.py +++ /dev/null @@ -1,55 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - {"help_string": "", "argstr": "{in_file}", "mandatory": True, "position": 0}, - ), - ( - "sigma", - float, - { - "help_string": "gaussian kernel sigma in mm (not voxels)", - "argstr": "-kernel gauss {sigma:.03f} -fmean", - "mandatory": True, - "position": 1, - "xor": ["fwhm"], - }, - ), - ( - "smoothed_file", - str, - { - "help_string": "", - "argstr": "{smoothed_file}", - "position": 2, - "output_file_template": "{in_file}_smooth", - }, - ), -] -Smooth_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [] -Smooth_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class Smooth(ShellCommandTask): - """ - Example - ------- - >>> task = Smooth() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.sigma = 3.397 - >>> task.inputs.smoothed_file = "test_smooth.nii.gz" - >>> task.cmdline - 'fslmaths test.nii.gz -kernel gauss 3.397 -fmean test_smooth.nii.gz' - """ - - input_spec = Smooth_input_spec - output_spec = Smooth_output_spec - executable = "fslmaths" diff --git a/pydra/tasks/fsl/utils/split.py b/pydra/tasks/fsl/utils/split.py deleted file mode 100644 index cc001c6..0000000 --- a/pydra/tasks/fsl/utils/split.py +++ /dev/null @@ -1,72 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - - -def Split_output(inputs): - import os, glob - - output_dir = os.getcwd() - return sorted(glob.glob(os.path.join(output_dir, f"{inputs.output_basename}*.*"))) - - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input filename", - "argstr": "{in_file}", - "mandatory": True, - "position": 0, - }, - ), - ( - "output_basename", - str, - {"help_string": "outputs prefix", "argstr": "{output_basename}", "position": 1}, - ), - ( - "dimension", - ty.Any, - { - "help_string": "dimension along which the file will be split", - "argstr": "-{dimension}", - "mandatory": True, - "position": 2, - }, - ), -] -Split_input_spec = specs.SpecInfo(name="Input", fields=input_fields, bases=(specs.ShellSpec,)) - -output_fields = [ - ( - "out_files", - specs.MultiOutputFile, - { - "help_string": "output files", - "requires": ["in_file", "output_basename", "dimension"], - "callable": Split_output, - }, - ) -] -Split_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class Split(ShellCommandTask): - """ - Example - ------- - >>> task = Split() - >>> task.inputs.in_file = "test.nii.gz" - >>> task.inputs.output_basename = "test_split" - >>> task.inputs.dimension = "t" - >>> task.cmdline - 'fslsplit test.nii.gz test_split -t' - """ - - input_spec = Split_input_spec - output_spec = Split_output_spec - executable = "fslsplit" diff --git a/pydra/tasks/fsl/utils/swapdimensions.py b/pydra/tasks/fsl/utils/swapdimensions.py deleted file mode 100644 index 9731072..0000000 --- a/pydra/tasks/fsl/utils/swapdimensions.py +++ /dev/null @@ -1,48 +0,0 @@ -from pydra.engine import specs -from pydra import ShellCommandTask -import typing as ty - -input_fields = [ - ( - "in_file", - specs.File, - { - "help_string": "input image", - "argstr": "{in_file}", - "mandatory": True, - "position": "1", - }, - ), - ( - "new_dims", - ty.Any, - { - "help_string": "3-tuple of new dimension order", - "argstr": "{new_dims} {new_dims} {new_dims}", - "mandatory": True, - }, - ), - ( - "out_file", - str, - { - "help_string": "image to write", - "argstr": "{out_file}", - "output_file_template": "{in_file}_newdims", - }, - ), -] -SwapDimensions_input_spec = specs.SpecInfo( - name="Input", fields=input_fields, bases=(specs.ShellSpec,) -) - -output_fields = [] -SwapDimensions_output_spec = specs.SpecInfo( - name="Output", fields=output_fields, bases=(specs.ShellOutSpec,) -) - - -class SwapDimensions(ShellCommandTask): - input_spec = SwapDimensions_input_spec - output_spec = SwapDimensions_output_spec - executable = "fslswapdim" diff --git a/pydra/tasks/fsl/utils/tests/__init__.py b/pydra/tasks/fsl/utils/tests/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/utils/tests/test_run_complex.py b/pydra/tasks/fsl/utils/tests/test_run_complex.py deleted file mode 100644 index 3b8279a..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_complex.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..complex import Complex - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_Complex(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Complex(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Complex(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_Complex_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Complex(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Complex(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_run_convertwarp.py b/pydra/tasks/fsl/utils/tests/test_run_convertwarp.py deleted file mode 100644 index cb2ab5a..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_convertwarp.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..convertwarp import ConvertWarp - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_ConvertWarp(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ConvertWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ConvertWarp(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_ConvertWarp_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ConvertWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ConvertWarp(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_run_convertxfm.py b/pydra/tasks/fsl/utils/tests/test_run_convertxfm.py deleted file mode 100644 index ea9abea..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_convertxfm.py +++ /dev/null @@ -1,43 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..convertxfm import ConvertXFM - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", [({"in_file": "flirt.mat", "invert_xfm": True}, ["out_file"])] -) -def test_ConvertXFM(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ConvertXFM(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ConvertXFM(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/utils/tests/test_run_copygeom.py b/pydra/tasks/fsl/utils/tests/test_run_copygeom.py deleted file mode 100644 index 9ee77fd..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_copygeom.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..copygeom import CopyGeom - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_CopyGeom(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = CopyGeom(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = CopyGeom(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_CopyGeom_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = CopyGeom(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = CopyGeom(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_run_extractroi.py b/pydra/tasks/fsl/utils/tests/test_run_extractroi.py deleted file mode 100644 index e3bddd8..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_extractroi.py +++ /dev/null @@ -1,44 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..extractroi import ExtractROI - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [({"in_file": "test.nii.gz", "t_min": 0, "t_size": 1}, ["roi_file"])], -) -def test_ExtractROI(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ExtractROI(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ExtractROI(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/utils/tests/test_run_filterregressor.py b/pydra/tasks/fsl/utils/tests/test_run_filterregressor.py deleted file mode 100644 index 27e9983..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_filterregressor.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..filterregressor import FilterRegressor - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_FilterRegressor(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FilterRegressor(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FilterRegressor(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FilterRegressor_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FilterRegressor(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FilterRegressor(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_run_imagemaths.py b/pydra/tasks/fsl/utils/tests/test_run_imagemaths.py deleted file mode 100644 index ef0dd5a..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_imagemaths.py +++ /dev/null @@ -1,41 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..imagemaths import ImageMaths - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", [(None, ["out_file"])]) -def test_ImageMaths(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageMaths(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageMaths(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/utils/tests/test_run_imagemeants.py b/pydra/tasks/fsl/utils/tests/test_run_imagemeants.py deleted file mode 100644 index 240d2bf..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_imagemeants.py +++ /dev/null @@ -1,41 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..imagemeants import ImageMeants - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", [(None, ["out_file"])]) -def test_ImageMeants(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageMeants(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageMeants(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/utils/tests/test_run_imagestats.py b/pydra/tasks/fsl/utils/tests/test_run_imagestats.py deleted file mode 100644 index 59023c2..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_imagestats.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..imagestats import ImageStats - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_ImageStats(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageStats(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageStats(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_ImageStats_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageStats(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageStats(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_run_invwarp.py b/pydra/tasks/fsl/utils/tests/test_run_invwarp.py deleted file mode 100644 index 9933a37..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_invwarp.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..invwarp import InvWarp - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_InvWarp(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = InvWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = InvWarp(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_InvWarp_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = InvWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = InvWarp(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_run_slice.py b/pydra/tasks/fsl/utils/tests/test_run_slice.py deleted file mode 100644 index cfe8272..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_slice.py +++ /dev/null @@ -1,22 +0,0 @@ -import os, pytest -from pathlib import Path -from ..slice import Slice - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", [(None, [])]) -def test_Slice(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = Slice(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - assert getattr(res.output, out_nm).exists() diff --git a/pydra/tasks/fsl/utils/tests/test_run_smooth.py b/pydra/tasks/fsl/utils/tests/test_run_smooth.py deleted file mode 100644 index e6b34a5..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_smooth.py +++ /dev/null @@ -1,43 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..smooth import Smooth - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", [({"in_file": "test.nii.gz", "sigma": 3.397}, ["smoothed_file"])] -) -def test_Smooth(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Smooth(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Smooth(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/utils/tests/test_run_split.py b/pydra/tasks/fsl/utils/tests/test_run_split.py deleted file mode 100644 index 970a85e..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_split.py +++ /dev/null @@ -1,53 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..split import Split - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "in_file": "test.nii.gz", - "output_basename": "test_split", - "dimension": "t", - }, - ["out_files"], - ) - ], -) -def test_Split(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Split(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Split(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) diff --git a/pydra/tasks/fsl/utils/tests/test_run_swapdimensions.py b/pydra/tasks/fsl/utils/tests/test_run_swapdimensions.py deleted file mode 100644 index fd8b523..0000000 --- a/pydra/tasks/fsl/utils/tests/test_run_swapdimensions.py +++ /dev/null @@ -1,72 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..swapdimensions import SwapDimensions - - -@pytest.mark.xfail("FSLDIR" not in os.environ, reason="no FSL found", raises=FileNotFoundError) -@pytest.mark.parametrize("inputs, outputs", []) -def test_SwapDimensions(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = SwapDimensions(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = SwapDimensions(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - res = task() - print("RESULT: ", res) - for out_nm in outputs: - if isinstance(getattr(res.output, out_nm), list): - assert [os.path.exists(x) for x in getattr(res.output, out_nm)] - else: - assert os.path.exists(getattr(res.output, out_nm)) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_SwapDimensions_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = SwapDimensions(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = SwapDimensions(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_complex.py b/pydra/tasks/fsl/utils/tests/test_spec_complex.py deleted file mode 100644 index 2ab9134..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_complex.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..complex import Complex - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_Complex(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Complex(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Complex(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_Complex_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Complex(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Complex(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_convertwarp.py b/pydra/tasks/fsl/utils/tests/test_spec_convertwarp.py deleted file mode 100644 index d89b807..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_convertwarp.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..convertwarp import ConvertWarp - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_ConvertWarp(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ConvertWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ConvertWarp(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_ConvertWarp_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ConvertWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ConvertWarp(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_convertxfm.py b/pydra/tasks/fsl/utils/tests/test_spec_convertxfm.py deleted file mode 100644 index 456096a..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_convertxfm.py +++ /dev/null @@ -1,35 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..convertxfm import ConvertXFM - - -@pytest.mark.parametrize( - "inputs, outputs", [({"in_file": "flirt.mat", "invert_xfm": True}, ["out_file"])] -) -def test_ConvertXFM(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ConvertXFM(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ConvertXFM(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_copygeom.py b/pydra/tasks/fsl/utils/tests/test_spec_copygeom.py deleted file mode 100644 index 4e6b5bb..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_copygeom.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..copygeom import CopyGeom - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_CopyGeom(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = CopyGeom(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = CopyGeom(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_CopyGeom_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = CopyGeom(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = CopyGeom(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_extractroi.py b/pydra/tasks/fsl/utils/tests/test_spec_extractroi.py deleted file mode 100644 index 3496f3f..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_extractroi.py +++ /dev/null @@ -1,36 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..extractroi import ExtractROI - - -@pytest.mark.parametrize( - "inputs, outputs", - [({"in_file": "test.nii.gz", "t_min": 0, "t_size": 1}, ["roi_file"])], -) -def test_ExtractROI(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ExtractROI(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ExtractROI(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_filterregressor.py b/pydra/tasks/fsl/utils/tests/test_spec_filterregressor.py deleted file mode 100644 index 4a55c64..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_filterregressor.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..filterregressor import FilterRegressor - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_FilterRegressor(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FilterRegressor(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FilterRegressor(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_FilterRegressor_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = FilterRegressor(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = FilterRegressor(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_imagemaths.py b/pydra/tasks/fsl/utils/tests/test_spec_imagemaths.py deleted file mode 100644 index 8ec0bb2..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_imagemaths.py +++ /dev/null @@ -1,33 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..imagemaths import ImageMaths - - -@pytest.mark.parametrize("inputs, outputs", [(None, ["out_file"])]) -def test_ImageMaths(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageMaths(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageMaths(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_imagemeants.py b/pydra/tasks/fsl/utils/tests/test_spec_imagemeants.py deleted file mode 100644 index 4d4d0d0..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_imagemeants.py +++ /dev/null @@ -1,33 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..imagemeants import ImageMeants - - -@pytest.mark.parametrize("inputs, outputs", [(None, ["out_file"])]) -def test_ImageMeants(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageMeants(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageMeants(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_imagestats.py b/pydra/tasks/fsl/utils/tests/test_spec_imagestats.py deleted file mode 100644 index 7db868d..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_imagestats.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..imagestats import ImageStats - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_ImageStats(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageStats(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageStats(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_ImageStats_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = ImageStats(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = ImageStats(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_invwarp.py b/pydra/tasks/fsl/utils/tests/test_spec_invwarp.py deleted file mode 100644 index 4cc3ca9..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_invwarp.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..invwarp import InvWarp - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_InvWarp(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = InvWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = InvWarp(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_InvWarp_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = InvWarp(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = InvWarp(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/utils/tests/test_spec_slice.py b/pydra/tasks/fsl/utils/tests/test_spec_slice.py deleted file mode 100644 index 1933828..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_slice.py +++ /dev/null @@ -1,17 +0,0 @@ -import os, pytest -from pathlib import Path -from ..slice import Slice - - -@pytest.mark.parametrize("inputs, outputs", [(None, [])]) -def test_Slice(test_data, inputs, outputs): - in_file = Path(test_data) / "test.nii.gz" - if inputs is None: - inputs = {} - for key, val in inputs.items(): - try: - inputs[key] = eval(val) - except: - pass - task = Slice(in_file=in_file, **inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_smooth.py b/pydra/tasks/fsl/utils/tests/test_spec_smooth.py deleted file mode 100644 index cec0b9c..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_smooth.py +++ /dev/null @@ -1,35 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..smooth import Smooth - - -@pytest.mark.parametrize( - "inputs, outputs", [({"in_file": "test.nii.gz", "sigma": 3.397}, ["smoothed_file"])] -) -def test_Smooth(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Smooth(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Smooth(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_split.py b/pydra/tasks/fsl/utils/tests/test_spec_split.py deleted file mode 100644 index af3704b..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_split.py +++ /dev/null @@ -1,45 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..split import Split - - -@pytest.mark.parametrize( - "inputs, outputs", - [ - ( - { - "in_file": "test.nii.gz", - "output_basename": "test_split", - "dimension": "t", - }, - ["out_files"], - ) - ], -) -def test_Split(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = Split(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = Split(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) diff --git a/pydra/tasks/fsl/utils/tests/test_spec_swapdimensions.py b/pydra/tasks/fsl/utils/tests/test_spec_swapdimensions.py deleted file mode 100644 index f1dbbfa..0000000 --- a/pydra/tasks/fsl/utils/tests/test_spec_swapdimensions.py +++ /dev/null @@ -1,64 +0,0 @@ -import re, os, shutil, pytest -from pathlib import Path -from ..swapdimensions import SwapDimensions - - -@pytest.mark.parametrize("inputs, outputs", []) -def test_SwapDimensions(test_data, inputs, outputs): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = SwapDimensions(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = SwapDimensions(**inputs) - assert set(task.generated_output_names) == set(["return_code", "stdout", "stderr"] + outputs) - - -@pytest.mark.parametrize("inputs, error", [(None, "AttributeError")]) -def test_SwapDimensions_exception(test_data, inputs, error): - if inputs is None: - in_file = Path(test_data) / "test.nii.gz" - task = SwapDimensions(in_file=in_file) - else: - for key, val in inputs.items(): - try: - pattern = r"\.[a-zA-Z]*" - if isinstance(val, str): - if re.findall(pattern, val) != []: - inputs[key] = Path(test_data) / val - elif "_dir" in key: - dirpath = Path(test_data) / val - if dirpath.exists() and dirpath.is_dir(): - shutil.rmtree(dirpath) - inputs[key] = Path(test_data) / val - else: - inputs[key] = eval(val) - elif isinstance(val, list): - if all(re.findall(pattern, _) != [] for _ in val): - inputs[key] = [Path(test_data) / _ for _ in val] - else: - inputs[key] = eval(val) - except: - pass - task = SwapDimensions(**inputs) - with pytest.raises(eval(error)): - task.generated_output_names diff --git a/pydra/tasks/fsl/v1/__init__.py b/pydra/tasks/fsl/v1/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/pydra/tasks/fsl/model/__init__.py b/pydra/tasks/fsl/v1_0/__init__.py similarity index 100% rename from pydra/tasks/fsl/model/__init__.py rename to pydra/tasks/fsl/v1_0/__init__.py diff --git a/pyproject.toml b/pyproject.toml index 01ce137..a668cff 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -44,6 +44,7 @@ doc = [ "sphinxcontrib-versioning", ] test = [ + "nipype2pydra", "pytest >= 4.4.0", "pytest-cov", "pytest-env", diff --git a/related-packages/fileformats-extras/README.rst b/related-packages/fileformats-extras/README.rst index 56cb579..385482c 100644 --- a/related-packages/fileformats-extras/README.rst +++ b/related-packages/fileformats-extras/README.rst @@ -1,12 +1,14 @@ -FileFormats-fsl Extras -====================================== +FileFormats-medimage-fsl Extras +=============================== + .. image:: https://github.com/nipype/pydra-freesurfer/actions/workflows/ci-cd.yaml/badge.svg :target: https://github.com/nipype/pydra-freesurfer/actions/workflows/ci-cd.yaml -This is a extras module for the `fileformats-fsl `__ +This is a extras module for the `fileformats-medimage-fsl `__ fileformats extension package, which provides additional functionality to format classes (i.e. aside -from basic identification and validation), such as conversion tools, metadata parsers, test data generators, etc... +from basic identification and validation), such as conversion tools, metadata parsers, +sample data generators, etc... Quick Installation @@ -14,9 +16,10 @@ Quick Installation This extension can be installed for Python 3 using *pip*:: - $ pip3 install fileformats-fsl-extras + $ pip3 install fileformats-medimage-fsl-extras -This will install the core package and any other dependencies +This will install the package, base packages, and any other dependencies required to +implement the extra functionality. License ------- diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py index d96e129..ff3794c 100644 --- a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py @@ -1,7 +1,8 @@ +from ._version import __version__ # noqa: F401 from pathlib import Path import typing as ty from random import Random -from fileformats.core import FileSet +from fileformats.core import FileSet, SampleFileGenerator from fileformats.medimage_fsl import ( Con, ) @@ -9,5 +10,5 @@ @FileSet.generate_sample_data.register -def gen_sample_con_data(con: Con, dest_dir: Path, seed: ty.Union[int, Random] = 0, stem: ty.Optional[str] = None) -> ty.Iterable[Path]: +def gen_sample_con_data(con: Con, generator: SampleFileGenerator) -> ty.Iterable[Path]: raise NotImplementedError diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py deleted file mode 100644 index accac60..0000000 --- a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# file generated by setuptools_scm -# don't change, don't track in version control -TYPE_CHECKING = False -if TYPE_CHECKING: - from typing import Tuple, Union - VERSION_TUPLE = Tuple[Union[int, str], ...] -else: - VERSION_TUPLE = object - -version: str -__version__: str -__version_tuple__: VERSION_TUPLE -version_tuple: VERSION_TUPLE - -__version__ = version = '0.1.dev228+g48cd321.d20231122' -__version_tuple__ = version_tuple = (0, 1, 'dev228', 'g48cd321.d20231122') diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py new file mode 100644 index 0000000..3c22cdb --- /dev/null +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py @@ -0,0 +1,10 @@ +import pytest +from fileformats.medimage_fsl import ( + Con, +) + + + +@pytest.mark.xfail(reason="generate_sample_data not implemented") +def test_generate_sample_con_data(): + assert isinstance(Con.sample(), Con) diff --git a/related-packages/fileformats-extras/pyproject.toml b/related-packages/fileformats-extras/pyproject.toml index d35d999..c6304d3 100644 --- a/related-packages/fileformats-extras/pyproject.toml +++ b/related-packages/fileformats-extras/pyproject.toml @@ -8,9 +8,9 @@ description = "Extensions to add functionality to tool-specific *fileformats* cl readme = "README.rst" requires-python = ">=3.8" dependencies = [ - "fileformats >= 0.7", + "fileformats", "fileformats-medimage-fsl", - "pydra >= 0.22.0" + "pydra >= 0.23.0a" ] license = {file = "LICENSE"} authors = [ diff --git a/related-packages/fileformats/README.rst b/related-packages/fileformats/README.rst index 99ef16e..36df02a 100644 --- a/related-packages/fileformats/README.rst +++ b/related-packages/fileformats/README.rst @@ -1,22 +1,11 @@ -How to customise this template -============================== +FileFormats-medimage-fsl +======================== -#. Rename the `related-packages/fileformats/fsl` directory to the name of the fileformats subpackage (e.g. `medimage_fsl`) -#. Search and replace "fsl" with the name of the fileformats subpackage the extras are to be added -#. Replace name + email placeholders in `pyproject.toml` for developers and maintainers -#. Add the extension file-format classes -#. Ensure that all the extension file-format classes are imported into the extras package root, i.e. `fileformats/fsl` -#. Delete these instructions - -... - -FileFormats Extension - fsl -==================================== .. image:: https://github.com/nipype/pydra-fsl/actions/workflows/ci-cd.yml/badge.svg :target: https://github.com/nipype/pydra-fsl/actions/workflows/ci-cd.yml -This is the "fsl" extension module for the -`fileformats `__ package +This is an extension module of the `fileformats `__ +package for defining file formats that are specific to the CHANGME software toolkit. Quick Installation @@ -24,9 +13,9 @@ Quick Installation This extension can be installed for Python 3 using *pip*:: - $ pip3 install fileformats-fsl + $ pip3 install fileformats-medimage-fsl -This will install the core package and any other dependencies +This will install the format extensions and dependent base packages. License ------- diff --git a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py index d6ea01b..31549f9 100644 --- a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py +++ b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py @@ -1,3 +1,4 @@ +from ._version import __version__ # noqa: F401 from fileformats.generic import File class Con(File): diff --git a/related-packages/fileformats/fileformats/medimage_fsl/_version.py b/related-packages/fileformats/fileformats/medimage_fsl/_version.py deleted file mode 100644 index accac60..0000000 --- a/related-packages/fileformats/fileformats/medimage_fsl/_version.py +++ /dev/null @@ -1,16 +0,0 @@ -# file generated by setuptools_scm -# don't change, don't track in version control -TYPE_CHECKING = False -if TYPE_CHECKING: - from typing import Tuple, Union - VERSION_TUPLE = Tuple[Union[int, str], ...] -else: - VERSION_TUPLE = object - -version: str -__version__: str -__version_tuple__: VERSION_TUPLE -version_tuple: VERSION_TUPLE - -__version__ = version = '0.1.dev228+g48cd321.d20231122' -__version_tuple__ = version_tuple = (0, 1, 'dev228', 'g48cd321.d20231122') diff --git a/related-packages/fileformats/pyproject.toml b/related-packages/fileformats/pyproject.toml index b36b6b6..f0b3af0 100644 --- a/related-packages/fileformats/pyproject.toml +++ b/related-packages/fileformats/pyproject.toml @@ -8,8 +8,8 @@ description = "Classes for representing different file formats in Python classes readme = "README.rst" requires-python = ">=3.8" dependencies = [ - "fileformats >= 0.4", - "fileformats-medimage >= 0.2" + "fileformats", + "fileformats-medimage" ] license = {file = "LICENSE"} authors = [ diff --git a/report_progress.py b/report_progress.py new file mode 100644 index 0000000..1fc0767 --- /dev/null +++ b/report_progress.py @@ -0,0 +1,31 @@ +#!/usr/bin/env python3 +from pathlib import Path +import json +import yaml +import click + + +@click.command +@click.argument( + "out_json_path", + type=click.Path(path_type=Path), + help="The output path to save the report", +) +def report_progress(out_json_path: Path): + + out_json_path.parent.mkdir(exist_ok=True, parents=True) + + SPECS_DIR = Path(__file__).parent / "nipype-auto-conv" / "specs" + + report = {} + + for spec_path in SPECS_DIR.glob("*.yaml"): + with open(spec_path) as f: + spec = yaml.load(f, Loader=yaml.SafeLoader) + + report[spec["task_name"]] = { + n: not s["xfail"] for n, s in spec["tests"].items() + } + + with open(out_json_path, "w") as f: + json.dump(report, f) diff --git a/specs/callables.py b/specs/callables.py deleted file mode 100644 index 44240cf..0000000 --- a/specs/callables.py +++ /dev/null @@ -1,411 +0,0 @@ -def Cluster_output(field, inputs): - import os, attr - from pydra.engine.helpers_file import split_filename - - in_file = inputs.in_file - name = field.name - pth, fname, ext = split_filename(in_file) - - if name == "index_file": - return os.path.join(pth, f"{fname}_index{ext}") - elif name == "localmax_txt_file": - return os.path.join(pth, f"{fname}_localmax.txt") - elif name == "localmax_vol_file": - return os.path.join(pth, f"{fname}_localmax{ext}") - elif name == "max_file": - return os.path.join(pth, f"{fname}_max{ext}") - elif name == "mean_file": - return os.path.join(pth, f"{fname}_mean{ext}") - elif name == "pval_file": - return os.path.join(pth, f"{fname}_pval{ext}") - elif name == "size_file": - return os.path.join(pth, f"{fname}_size{ext}") - elif name == "threshold_file": - return os.path.join(pth, f"{fname}_threshold{ext}") - - else: - raise Exception( - f"this function should be run only for index_file, localmax_txt_file, localmax_vol_file, max_file, mean_file, pval_file, size_file, or threshold_file not {name}" - ) - - -def Complex_output(inputs): - import attr - - if inputs.complex_cartesian: - in_file = inputs.real_in_file - elif inputs.complex_polar: - in_file = inputs.magnitude_in_file - elif inputs.complex_split or inputs.complex_merge: - in_file = inputs.complex_in_file - else: - return None - return f"{in_file}_cplx" - - -def ConvertXFM_output(inputs): - import attr - - in_file = inputs.in_file - if inputs.invert_xfm: - return f"{in_file}_inv" - elif inputs.concat_xfm: - if inputs.in_file2.exists(): - in_file2 = inputs.in_file2 - return f"{in_file}_{in_file2}" - else: - raise Exception("in_file2 is needed to use concat_xfm") - - elif inputs.fix_scale_skew: - return f"{in_file}_fix" - else: - raise Exception("this function requires invert_xfm, or concat_xfm," "or fix_scale_skew") - - -def FAST_output(field, in_files, out_basename): - import attr - - if out_basename in [None, attr.NOTHING]: - out_basename = in_files[-1] - name = field.name - if name == "tissue_class_map": - return f"{out_basename}_seg" - elif name == "mixeltype": - return f"{out_basename}_mixeltype" - elif name == "partial_volume_map": - return f"{out_basename}_pveseg" - else: - raise Exception( - f"this function should be run only for issue_class_map, " - f"or mixeltype, not for {name}" - ) - - outputs = [] - if len(in_files) > 1: - # for multi-image segmentation there is one corrected image - # per input - for val, f in enumerate(in_files): - # image numbering is 1-based - outputs.append(f"{out_basename}_restore_{val+1}") - else: - # single image segmentation has unnumbered output image - outputs.append(f"{out_basename}_restore") - return outputs - - -def FAST_output_nclass(field, in_files, nclasses, out_basename): - import attr - - if out_basename in [None, attr.NOTHING]: - out_basename = in_files[-1] - name = field.name - - if name == "tissue_class_files": - suffix = "seg" - elif name == "partial_volume_files": - suffix = "pve" - elif name == "probability_maps": - suffix = "prob" - else: - raise Exception( - f"this function should be run only for tissue_class_files, " - f"partial_volume_files or probability_maps, not for {name}" - ) - - outputs = [] - for ii in range(nclasses): - outputs.append(f"{out_basename}_{suffix}_{ii}") - return outputs - - -def FAST_output_infile(field, in_files, out_basename): - import attr - - if out_basename in [None, attr.NOTHING]: - out_basename = in_files[-1] - name = field.name - if name == "restored_image": - suffix = "restore" - elif name == "bias_field": - suffix = "bias" - else: - raise Exception( - f"this function should be run only for restored_image, " - f"or bias_field, not for {name}" - ) - - outputs = [] - if len(in_files) > 1: - # for multi-image segmentation there is one corrected image - # per input - for val, f in enumerate(in_files): - # image numbering is 1-based - outputs.append(f"{out_basename}_{suffix}_{val+1}") - else: - # single image segmentation has unnumbered output image - outputs.append(f"{out_basename}_{suffix}") - return outputs - - -def FEAT_output(fsf_file): - is_ica = False - with open(fsf_file, "rt") as fp: - text = fp.read() - if "set fmri(inmelodic) 1" in text: - is_ica = True - for line in text.split("\n"): - if line.find("set fmri(outputdir)") > -1: - try: - outputdir_spec = line.split('"')[-2] - if os.path.exists(outputdir_spec): - outputs = outputdir_spec - except: - pass - - if not outputs: - if is_ica: - outputs = glob(os.path.join(os.getcwd(), "*ica"))[0] - else: - outputs = glob(os.path.join(os.getcwd(), "*feat"))[0] - print("Outputs from FEATmodel:", outputs) - return outputs - - -def FEATModel_output(field, fsf_file): - import os - - # TODO: figure out file names and get rid off the globs - outputs = {} - _, fname = os.path.split(fsf_file) - root = fname.split(".")[0] - name = field.name - if name == "design_file": - design_file = glob(os.path.join(os.getcwd(), "%s*.mat" % root)) - assert len(design_file) == 1, "No mat file generated by FEAT Model" - outputs = design_file[0] - elif name == "design_image": - design_image = glob(os.path.join(os.getcwd(), "%s.png" % root)) - assert len(design_image) == 1, "No design image generated by FEAT Model" - outputs = design_image[0] - elif name == "design_cov": - design_cov = glob(os.path.join(os.getcwd(), "%s_cov.png" % root)) - assert len(design_cov) == 1, "No covariance image generated by FEAT Model" - outputs = design_cov[0] - elif name == "con_file": - con_file = glob(os.path.join(os.getcwd(), "%s*.con" % root)) - assert len(con_file) == 1, "No con file generated by FEAT Model" - outputs = con_file[0] - elif name == "fcon_file": - fcon_file = glob(os.path.join(os.getcwd(), "%s*.fts" % root)) - if fcon_file: - assert len(fcon_file) == 1, "No fts file generated by FEAT Model" - outputs = fcon_file[0] - else: - raise Exception( - f"this function should be run only for design_file, design_image" - f"design_cov, con_file, or fcon_file, not for {name}" - ) - return outputs - - -def FILMGLS_output(field, inputs): - import os, attr - - def _get_pe_files(design_file, pth): - files = None - if design_file not in [None, attr.NOTHING]: - fp = open(design_file, "rt") - for line in fp.readlines(): - if line.startswith("/NumWaves"): - numpes = int(line.split()[-1]) - files = [] - for i in range(numpes): - files.append(os.path.join(pth, ("pe%d.nii.gz" % (i + 1)))) - break - fp.close() - return files - - def _get_numcons(inputs): - numtcons = 0 - numfcons = 0 - if inputs.tcon_file not in [None, attr.NOTHING]: - fp = open(inputs.tcon_file, "rt") - for line in fp.readlines(): - if line.startswith("/NumContrasts"): - numtcons = int(line.split()[-1]) - break - fp.close() - if inputs.fcon_file not in [None, attr.NOTHING]: - fp = open(inputs.fcon_file, "rt") - for line in fp.readlines(): - if line.startswith("/NumContrasts"): - numfcons = int(line.split()[-1]) - break - fp.close() - return numtcons, numfcons - - name = field.name - pth = inputs.results_dir - if name == "results_dir": - return pth - elif name == "param_estimates": - design_file = inputs.design_file - pe_files = _get_pe_files(design_file, pth) - if pe_files: - return pe_files - elif name == "residual4d": - return os.path.join(pth, "res4d.nii.gz") - elif name == "dof_file": - return os.path.join(pth, "dof") - elif name == "sigmasquareds": - return os.path.join(pth, "sigmasquareds.nii.gz") - elif name == "thresholdac": - return os.path.join(pth, "threshac1.nii.gz") - elif name == "logfile": - return os.path.join(pth, "logfile") - - numtcons, numfcons = _get_numcons(inputs) - base_contrast = 1 - copes = [] - varcopes = [] - zstats = [] - tstats = [] - for i in range(numtcons): - copes.append(os.path.join(pth, ("cope%d.nii.gz" % (base_contrast + i)))) - varcopes.append(os.path.join(pth, ("varcope%d.nii.gz" % (base_contrast + i)))) - zstats.append(os.path.join(pth, ("zstat%d.nii.gz" % (base_contrast + i)))) - tstats.append(os.path.join(pth, ("tstat%d.nii.gz" % (base_contrast + i)))) - if copes: - if name == "copes": - return copes - elif name == "varcopes": - return varcopes - elif name == "zstats": - return zstats - elif name == "tstats": - return tstats - fstats = [] - zfstats = [] - for i in range(numfcons): - fstats.append(os.path.join(pth, ("fstat%d.nii.gz" % (base_contrast + i)))) - zfstats.append(os.path.join(pth, ("zfstat%d.nii.gz" % (base_contrast + i)))) - if fstats: - if name == "fstats": - return fstats - elif name == "zfstats": - return - - -def FLAMEO_output(field, inputs): - import os, glob, attr - - def human_order_sorted(l): - """ - Sorts string in human order (i.e. 'stat10' will go after 'stat2') - """ - - def atoi(text): - return int(text) if text.isdigit() else text - - def natural_keys(text): - import re - - if isinstance(text, tuple): - text = text[0] - return [atoi(c) for c in re.split(r"(\d+)", text)] - - return sorted(l, key=natural_keys) - - pth = inputs.log_dir - name = field.name - - if name == "pes": - pes = human_order_sorted(glob.glob(os.path.join(pth, "pe[0-9]*.*"))) - if len(pes) >= 1: - return pes - elif name == "res4d": - res4d = human_order_sorted(glob.glob(os.path.join(pth, "res4d.*"))) - if len(res4d) == 1: - return res4d[0] - elif name == "copes": - copes = human_order_sorted(glob.glob(os.path.join(pth, "cope[0-9]*.*"))) - if len(copes) >= 1: - return copes - elif name == "var_copes": - var_copes = human_order_sorted(glob.glob(os.path.join(pth, "varcope[0-9]*.*"))) - if len(var_copes) >= 1: - return var_copes - elif name == "zstats": - zstats = human_order_sorted(glob.glob(os.path.join(pth, "zstat[0-9]*.*"))) - if len(zstats) >= 1: - return zstats - elif name == "tstats": - tstats = human_order_sorted(glob.glob(os.path.join(pth, "tstat[0-9]*.*"))) - if len(tstats) >= 1: - return tstats - elif name == "mrefvars": - mrefs = human_order_sorted(glob.glob(os.path.join(pth, "mean_random_effects_var[0-9]*.*"))) - if len(mrefs) >= 1: - return mrefs - elif name == "tdof": - tdof = human_order_sorted(glob.glob(os.path.join(pth, "tdof_t[0-9]*.*"))) - if len(tdof) >= 1: - return tdof - elif name == "weights": - weights = human_order_sorted(glob.glob(os.path.join(pth, "weights[0-9]*.*"))) - if len(weights) >= 1: - return weights - elif name == "stats_dir": - return pth - elif inputs.f_con_file not in [None, attr.NOTHING]: - if name == "zfstats": - zfstats = human_order_sorted(glob.glob(os.path.join(pth, "zfstat[0-9]*.*"))) - if len(zfstats) >= 1: - return zfstats - elif name == "fstats": - fstats = human_order_sorted(glob.glob(os.path.join(pth, "fstat[0-9]*.*"))) - if len(fstats) >= 1: - return fstats - else: - raise Exception( - f"this function should be run only for pes, res4d, copes, var_copes, zfstats," - f"fstats, zstats, tstats, mrefs, tdof, weights, or stats_dir, not for {name}" - ) - - -def MELODIC_output(field, inputs): - import os, attr - - name = field.name - if name == "out_dir": - if inputs.out_dir not in [None, attr.NOTHING]: - outputs = inputs.out_dir - else: - outputs = os.getcwd() - elif name == "report_dir": - if inputs.report not in [None, attr.NOTHING]: - if inputs.out_dir not in [None, attr.NOTHING]: - out_dir = inputs.out_dir - else: - out_dir = os.getcwd() - outputs = os.path.join(out_dir, "report") - return outputs - - -# def SLICE_output(inputs): -# import glob - -# suffix = "slice_*" -# if inputs.out_base_name: -# fname_template = f"{inputs.out_base_name}_{suffix}" -# else: -# fname_template = f"{inputs.in_file}_{suffix}" - -# return sorted(glob(fname_template)) - - -def Split_output(inputs): - import os, glob - - output_dir = os.getcwd() - return sorted(glob.glob(os.path.join(output_dir, f"{inputs.output_basename}*.*"))) diff --git a/specs/fsl_aroma_param.yml b/specs/fsl_aroma_param.yml deleted file mode 100644 index e62318c..0000000 --- a/specs/fsl_aroma_param.yml +++ /dev/null @@ -1,8 +0,0 @@ -# ICA_AROMA: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: diff --git a/specs/fsl_dti_param.yml b/specs/fsl_dti_param.yml deleted file mode 100644 index 112fd97..0000000 --- a/specs/fsl_dti_param.yml +++ /dev/null @@ -1,125 +0,0 @@ -# BEDPOSTX: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# BEDPOSTX5: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# DTIFit: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# DistanceMap: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# FSLXCommand: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# FindTheBiggest: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MakeDyadicVectors: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# ProbTrackX: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# ProbTrackX2: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# ProjThresh: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# TrackSckeleton: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# VecReg: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# XFibres: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# XFibres5: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: diff --git a/specs/fsl_epi_param.yml b/specs/fsl_epi_param.yml deleted file mode 100644 index 451c55e..0000000 --- a/specs/fsl_epi_param.yml +++ /dev/null @@ -1,80 +0,0 @@ -# ApplyTOPUP: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# EPIDeWarp: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# Eddy: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# EddyCorrect: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# EddyQuad: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# EpiReg: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# PrepareFieldmap: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# SigLoss: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# TOPUP: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: diff --git a/specs/fsl_fix_param.yml b/specs/fsl_fix_param.yml deleted file mode 100644 index 177ef20..0000000 --- a/specs/fsl_fix_param.yml +++ /dev/null @@ -1,44 +0,0 @@ -# Classifier: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# Cleaner: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# FeatureExtractor: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# Training: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# TrainingSetCreator: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: diff --git a/specs/fsl_maths_param.yml b/specs/fsl_maths_param.yml deleted file mode 100644 index 87128ad..0000000 --- a/specs/fsl_maths_param.yml +++ /dev/null @@ -1,170 +0,0 @@ -# AR1Image: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# ApplyMask: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# BinaryMaths: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# ChangeDataType: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# DilateImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# ErodeImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# IsotropicSmooth: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MathsCommand: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MaxImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MeanImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MedianImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MinImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# MultiImageMaths: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# PercentileImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# SpatialFilter: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# StdImage: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# TemporalFilter: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# Threshold: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# UnaryMaths: -# output_requirements: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: diff --git a/specs/fsl_model_param.yml b/specs/fsl_model_param.yml deleted file mode 100644 index de66663..0000000 --- a/specs/fsl_model_param.yml +++ /dev/null @@ -1,349 +0,0 @@ -Cluster: - output_requirements: - index_file: [in_file, out_index_file] - localmax_txt_file: [in_file, out_localmax_txt_file] - localmax_vol_file: [in_file, out_localmax_vol_file] - max_file: [in_file, out_max_file] - mean_file: [in_file, out_mean_file] - pval_file: [in_file, out_pval_file] - size_file: [in_file, out_size_file] - threshold_file: [in_file, out_threshold_file] - output_callables: - index_file: Cluster_output - localmax_txt_file: Cluster_output - localmax_vol_file: Cluster_output - max_file: Cluster_output - mean_file: Cluster_output - pval_file: Cluster_output - size_file: Cluster_output - threshold_file: Cluster_output - output_templates: - - inputs_drop: - doctest: - in_file: zstat1.nii.gz - threshold: 2.3 - use_mm: True - out_index_file: zstat1_index.nii.gz - out_threshold_file: zstat1_threshold.nii.gz - out_localmax_txt_file: zstat1_localmax.txt - out_localmax_vol_file: zstat1_localmax.nii.gz - out_size_file: zstat1_size.nii.gz - out_max_file: zstat1_max.nii.gz - out_mean_file: zstat1_mean.nii.gz - out_pval_file: zstat1_pval.nii.gz - cmdline: cluster --in=zstat1.nii.gz --thresh=2.3000000000 --mm - tests_inputs: - - in_file: zstat1.nii.gz - threshold: 2.3 - use_mm: True - out_index_file: 'zstat1_index.nii.gz' - out_threshold_file: 'zstat1_threshold.nii.gz' - out_localmax_txt_file: 'zstat1_localmax.txt' - out_localmax_vol_file: 'zstat1_localmax.nii.gz' - out_size_file: 'zstat1_size.nii.gz' - out_max_file: 'zstat1_max.nii.gz' - out_mean_file: 'zstat1_mean.nii.gz' - out_pval_file: 'zstat1_pval.nii.gz' - tests_outputs: - - [out_index_file,out_localmax_txt_file,out_localmax_vol_file,out_threshold_file,out_max_file,out_mean_file,out_pval_file,out_size_file,out_threshold_file] - - -# ContrastMgr: -# output_requirements: -# copes: -# fstats: -# neffs: -# tstats: -# varcopes: -# zfstats: -# zstats: - -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# DualRegression: -# output_requirements: -# out_dir: [group_IC_maps_4D, in_files, n_perm] -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# in_files: [functional.nii, functional2.nii, functional3.nii] -# group_IC_maps_4D: allFA.nii -# des_norm: False -# one_sample_group_mean: True -# n_perm: 10 -# out_dir: my_output_directory -# cmdline: dual_regression allFA.nii 0 -1 10 my_output_directory functional.nii functional2.nii functional3.nii -# tests_inputs: -# - -# tests_outputs: -# - - -FEAT: # need a simpler test.fsf - output_requirements: - feat_dir: [fsf_file] - output_callables: - feat_dir: FEAT_output - output_templates: - inputs_drop: - doctest: - fsf_file: test.fsf - cmdline: feat test.fsf - tests_inputs: - - - tests_outputs: - - AttributeError - -FEATModel: - output_requirements: - con_file: - design_cov: - design_file: - design_image: - fcon_file: - - output_callables: - con_file: FEATModel_output - design_cov: FEATModel_output - design_file: FEATModel_output - design_image: FEATModel_output - fcon_file: FEATModel_output - output_templates: - inputs_drop: - doctest: # feat_model [confound matrix text file] - tests_inputs: - - - tests_outputs: - - AttributeError - -# FEATRegister: -# output_requirements: -# fsf_file: [feat_dirs, reg_image] -# output_callables: -# output_templates: -# fsf_file: register.fsf -# inputs_drop: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -FILMGLS: - output_requirements: - corrections: - dof_file: - logfile: - param_estimates: - residual4d: - results_dir: - sigmasquareds: - thresholdac: - output_callables: - corrections: FILMGLS_output - dof_file: FILMGLS_output - logfile: FILMGLS_output - param_estimates: FILMGLS_output - residual4d: FILMGLS_output - results_dir: FILMGLS_output - sigmasquareds: FILMGLS_output - thresholdac: FILMGLS_output - output_templates: - inputs_drop: - doctest: - in_file: test_film_gls.nii.gz - design_file: design_film_gls.mat - threshold: 10 - results_dir: stats - cmdline: film_gls --rn=stats --in=test_film_gls.nii.gz --pd=design_film_gls.mat --thr=10 - tests_inputs: - - in_file: test_film_gls.nii.gz - design_file: design_film_gls.mat - threshold: 10 - results_dir: stats - tests_outputs: - - [dof_file,logfile,param_estimates,residual4d,results_dir,sigmasquareds,thresholdac] - -FLAMEO: - output_requirements: - copes: - var_copes: - mrefvars: - weights: - pes: - res4d: - tdof: - tstats: [t_con_file] - zstats: [t_con_file] - zfstats: [f_con_file] - fstats: [f_con_file] - stats_dir: - - output_callables: - copes: FLAMEO_output - fstats: FLAMEO_output - mrefvars: FLAMEO_output - pes: FLAMEO_output - res4d: FLAMEO_output - tdof: FLAMEO_output - tstats: FLAMEO_output - var_copes: FLAMEO_output - weights: FLAMEO_output - zfstats: FLAMEO_output - zstats: FLAMEO_output - stats_dir: FLAMEO_output - - output_templates: - - inputs_drop: - - doctest: - cope_file: cope_merged.nii.gz - var_cope_file: varcope_merged.nii.gz - cov_split_file: design.grp - design_file: design.mat - t_con_file: design.con - mask_file: mask.nii.gz - run_mode: fe - cmdline: flameo --copefile=cope_merged.nii.gz --varcopefile=varcope_merged.nii.gz --maskfile=mask.nii.gz --designfile=design.mat --tcontrastsfile=design.con --covsplitfile=design.grp --runmode=fe --ld=stats - - tests_inputs: - - cope_file: cope_merged.nii.gz - var_cope_file: varcope_merged.nii.gz - cov_split_file: design.grp - design_file: design.mat - t_con_file: design.con - mask_file: mask.nii.gz - run_mode: fe - log_dir: stats - tests_outputs: - - [copes, var_copes, mrefvars, pes, res4d, tdof, weights, tstats, zstats, stats_dir] - -GLM: - output_requirements: - out_file: [in_file] - output_callables: - output_templates: - out_file: "{in_file}_glm" - inputs_drop: - doctest: - in_file: test.nii.gz - design: confounds_regressors.tsv - cmdline: fsl_glm -i test.nii.gz -d confounds_regressors.tsv # doctest: +ELLIPSIS - tests_inputs: - - in_file: test.nii.gz - design: confounds_regressors.tsv - tests_outputs: - - out_file - -# L2Model: -# output_requirements: -# design_con: -# design_grp: -# design_mat: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# Level1Design: -# output_requirements: -# ev_files: -# fsf_files: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -MELODIC: - output_requirements: - out_dir: - report_dir: - output_callables: - out_dir: MELODIC_output - report_dir: MELODIC_output - output_templates: - inputs_drop: - doctest: - approach: tica - in_files: [test2.nii,test3.nii] - no_bet: True - bg_threshold: 10 - tr_sec: 1.5 - out_stats: True - t_des: timeDesign.mat - t_con: timeDesign.con - s_des: subjectDesign.mat - s_con: subjectDesign.con - out_dir: groupICA.out - cmdline: melodic -i test2.nii,test3.nii -o groupICA.out --nobet --bgthreshold=10 -a tica --tr=1.5 --Tdes=timeDesign.mat --Tcon=timeDesign.con --Sdes=subjectDesign.mat --Scon=subjectDesign.con --Ostats - tests_inputs: - - - tests_outputs: - - AttributeError - -# MultipleRegressDesign: -# output_requirements: -# design_con: -# design_fts: -# design_grp: -# design_mat: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# Randomise: -# output_requirements: -# f_corrected_p_files: -# f_p_files: -# fstat_files: -# t_corrected_p_files: -# t_p_files: -# tstat_files: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# cmdline: randomise -i allFA.nii -o "randomise" -d design.mat -t design.con -m mask.nii -# tests_inputs: -# tests_outputs: - -# SMM: -# output_requirements: -# activation_p_map: -# deactivation_p_map: -# null_p_map: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# tests_inputs: -# tests_outputs: - -# SmoothEstimate: # need new test data -# output_requirements: -# dlh: -# resels: -# volume: -# output_callables: -# output_templates: -# inputs_drop: -# doctest: -# zstat_file: zstat1.nii.gz -# mask_file: mask.nii -# cmdline: smoothest --mask=mask.nii --zstat=zstat1.nii.gz -# tests_inputs: -# tests_outputs: diff --git a/specs/fsl_possum_param.yml b/specs/fsl_possum_param.yml deleted file mode 100644 index f589896..0000000 --- a/specs/fsl_possum_param.yml +++ /dev/null @@ -1,11 +0,0 @@ -# B0Calc: -# output_requirements: -# out_file : [in_file] -# output_templates: -# out_file: "{in_file}_b0field" -# tests_inputs: -# - - -# tests_outputs: -# - AttributeError -# Exception: format from --b0x=%0.2f --b0y=%0.2f --b0=%0.2f is not supported TODO diff --git a/specs/fsl_preprocess_param.yml b/specs/fsl_preprocess_param.yml deleted file mode 100644 index 458fc42..0000000 --- a/specs/fsl_preprocess_param.yml +++ /dev/null @@ -1,231 +0,0 @@ -BET: - output_requirements: - out_file: [in_file] - mask_file: - - [mask: True] - - [reduce_bias: True] - outline_file: [outline: True] - meshfile: - - [mesh: True] - - [surfaces: True] - inskull_mask_file: [surfaces: True] - inskull_mesh_file: [surfaces: True] - outskull_mask_file: [surfaces: True] - outskull_mesh_file: [surfaces: True] - outskin_mask_file: [surfaces: True] - outskin_mesh_file: [surfaces: True] - skull_mask_file: [surfaces: True] - skull_file: [skull: True] - - output_templates: - out_file: "{in_file}_brain" - mask_file: "{out_file}_mask" - outline_file: "{out_file}_overlay" - meshfile: "{out_file}_mesh.vtk" - inskull_mask_file: "{out_file}_inskull_mask" - inskull_mesh_file: "{out_file}_inskull_mesh" - outskull_mask_file: "{out_file}_outskull_mask" - outskull_mesh_file: "{out_file}_outskull_mesh" - outskin_mask_file: "{out_file}_outskin_mask" - outskin_mesh_file: "{out_file}_outskin_mesh" - skull_mask_file: "{out_file}_skull_mask" - skull_file: "{out_file}_skull" - - - doctest: - in_file: "test.nii.gz" - out_file: test_brain.nii.gz - frac: 0.7 - cmdline: 'bet test.nii.gz test_brain.nii.gz -f 0.70' - - tests_inputs: - - - - mask: True - - surfaces: True - - tests_outputs: - - out_file - - [out_file, mask_file] - - [out_file, meshfile, inskull_mask_file, inskull_mesh_file, outskull_mask_file, - outskull_mesh_file, outskin_mask_file, outskin_mesh_file, skull_mask_file] - - -FAST: - inputs_metadata: - number_classes: - default: 3 - - output_requirements: - tissue_class_files: [segments: True] - partial_volume_map: [no_pve: False] # possibly [False, None, attr.NOTHING] - partial_volume_files: [no_pve: False] # possibly [False, None, attr.NOTHING] - bias_field: [output_biasfield: True] - probability_maps: [probability_maps: True] - - output_callables: - tissue_class_map: FAST_output - tissue_class_files: FAST_output_nclass - restored_image: FAST_output_infile - mixeltype: FAST_output - partial_volume_map: FAST_output - partial_volume_files: FAST_output_nclass - bias_field: FAST_output_infile - probability_maps: FAST_output_nclass - - doctest: - in_files: "test.nii.gz" - out_basename: "fast_" - cmdline: 'fast -o fast_ -n 3 test.nii.gz' - - tests_inputs: - - - - tests_outputs: - - AttributeError - - -MCFLIRT: - output_requirements: - out_file: [in_file] - variance_img: [in_file, stats_imgs: True] - std_img: [in_file, stats_imgs: True] - mean_img: [in_file, mean_vol: True] - par_file: [save_plots] -# mat_file: -# rms_files: [save_rms] - - - output_templates: - out_file: "{in_file}_mcf" - variance_img: "{out_file}_variance.ext" - std_img: "{out_file}_sigma.ext" - mean_img: "{out_file}_mean_reg.ext" - par_file: "{out_file}.par" -# mat_file: -# rms_files: - - tests_inputs: - - - - tests_outputs: - - out_file - - -FLIRT: - output_requirements: - - output_templates: - - tests_inputs: - - - - tests_outputs: - - AttributeError - - -FNIRT: - output_requirements: - warped_file: [in_file] - field_file: [in_file] - jacobian_file: [in_file] - modulatedref_file: [in_file] - #out_intensitymap_file: [in_file] - log_file: [in_file] - fieldcoeff_file: [in_file] - - - output_templates: - warped_file: "{in_file}_warped" - field_file: "{in_file}_field" - jacobian_file: "{in_file}_field_jacobian" - modulatedref_file: "{in_file}_modulated" - #out_intensitymap_file: "{in_file}_intmap" - log_file: "{in_file}_log.txt" - fieldcoeff_file: "{in_file}_fieldwarp" - - tests_inputs: - - - - ref_file: f"{in_file}" - - tests_outputs: - - AttributeError - - [warped_file, field_file, jacobian_file, modulatedref_file, log_file, fieldcoeff_file] - - -ApplyWarp: - output_templates: - out_file: "{in_file}_warp" - - tests_inputs: - - ref_file: f"{in_file}" - - tests_outputs: - - out_file - - -SliceTimer: - output_requirements: - slice_time_corrected_file: [out_file] - - output_templates: - out_file: "{in_file}_st" - slice_time_corrected_file: "{out_file}" - - tests_inputs: - - ref_file: f"{in_file}" - - tests_outputs: - - [out_file, slice_time_corrected_file] - - -SUSAN: - output_requirements: - smoothed_file: [out_file] - - output_templates: - out_file: "{in_file}_smooth" - smoothed_file: "{out_file}" - - tests_inputs: - - - - - brightness_threshold: 0.01 - fwhm: 2 - - tests_outputs: - - AttributeError - - [out_file, smoothed_file] - - -PRELUDE: - output_requirements: - unwrapped_phase_file: [phase_file] - - output_templates: - unwrapped_phase_file: "{phase_file}_unwrapped" - - tests_inputs: - - - - tests_outputs: - - AttributeError - - -FIRST: - output_requirements: - original_segmentations: [in_file] - segmentation_file: [in_file] - vtk_surfaces: [in_file] - bvars: [in_file] - - output_templates: - original_segmentations: "{in_file}_original_segmentations" - segmentation_file: "{in_file}_segmentation_file" - vtk_surfaces: "{in_file}_vtk_surfaces" - bvars: "{in_file}_bvars" - - tests_inputs: - - - - tests_outputs: - - AttributeError diff --git a/specs/fsl_utils_param.yml b/specs/fsl_utils_param.yml deleted file mode 100644 index f62cc9f..0000000 --- a/specs/fsl_utils_param.yml +++ /dev/null @@ -1,401 +0,0 @@ -# AvScale: # complex output -# output_requirements: -# average_scaling: -# backward_half_transform: -# determinant: -# forward_half_transform: -# left_right_orientation_preserved: -# rot_angles: -# rotation_translation_matrix: -# scales: -# skews: -# translations: -# output_templates: -# doctest: -# mat_file: "flirt.mat" -# cmdline: "avscale flirt.mat" -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -Complex: # this one needs to rethink, the callable is not shown up - output_requirements: - - output_callables: - complex_out_file: Complex_output - output_templates: - imaginary_out_file: "{in_file}_imag" - magnitude_out_file: "{in_file}_mag" - phase_out_file: "{in_file}_phase" - real_out_file: "{in_file}_real" - doctest: - tests_inputs: - - - tests_outputs: - - AttributeError - - -ConvertWarp: # needs more test data - output_requirements: - out_file: [reference] - output_templates: - out_file: "{reference}_concatwarp" - doctest: - warp1: warpfield.nii - reference: test.nii.gz - relwarp: True - out_file: test_concatwarp.nii.gz - cmdline: convertwarp --ref=test.nii.gz --warp1=warpfield.nii --rel --out=test_concatwarp.nii.gz - tests_inputs: - - - tests_outputs: - - AttributeError - -ConvertXFM: - output_requirements: - out_file: [in_file] - - output_templates: - out_file: [ConvertXFM_output] - - doctest: - in_file: flirt.mat - invert_xfm: True - out_file: flirt_inv.mat - cmdline: convert_xfm -omat flirt_inv.mat -inverse flirt.mat - tests_inputs: - - in_file: flirt.mat - invert_xfm: True - tests_outputs: - - out_file - -CopyGeom: - output_requirements: - out_file: [in_file, dest_file] - output_templates: - dest_file: "original" - out_file: "{dest_file}" - doctest: - in_file: test.nii.gz - dest_file: dest.nii.gz - cmdline: fslcpgeom test.nii.gz dest.nii.gz - tests_inputs: - - - - tests_outputs: - - AttributeError - -ExtractROI: - output_requirements: - roi_file: [in_file] - output_templates: - roi_file: "{in_file}_trim" - inputs_drop: - - crop_list - doctest: - in_file: test.nii.gz - t_min: 0 - t_size: 3 - roi_file: test_trim.nii.gz - cmdline: fslroi test.nii.gz test_trim.nii.gz 0 3 - tests_inputs: - - in_file: test.nii.gz - t_min: 0 - t_size: 1 - tests_outputs: - - roi_file - -FilterRegressor: - output_requirements: - out_file: [in_file, design_file] - inputs_drop: - - filter_all - output_templates: - out_file: "{in_file}_filtered" - doctest: - in_file: test.nii.gz - design_file: design - filter_columns: 1,2,3 - out_file: test_filtered.nii.gz - cmdline: fsl_regfilt -i test.nii.gz -o test_filtered.nii.gz -d design -f 1,2,3 - tests_inputs: - - - tests_outputs: - - AttributeError - -ImageMaths: - output_requirements: - out_file: [in_file] - output_templates: - out_file: "{in_file}_maths" - inputs_drop: # input from nipype interface that's not required by fsl - - suffix - - doctest: - in_file: test.nii.gz - op_string: -add 5 - out_file: test_maths.nii.gz - cmdline: fslmaths test.nii.gz -add 5 test_maths.nii.gz - tests_inputs: - - - tests_outputs: - - out_file - -ImageMeants: - output_requirements: - out_file: [in_file] - output_templates: - out_file: "{in_file}_meants.txt" - doctest: - in_file: test.nii.gz - mask: mask.nii.gz - out_file: test_meants.txt - cmdline: fslmeants -i test.nii.gz -o test_meants.txt -m mask.nii.gz --order=1 - tests_inputs: - - - tests_outputs: - - out_file - -ImageStats: - output_requirements: - out_stat: [in_file, op_string] - output_templates: - doctest: - in_file: test.nii.gz - op_string: -M - cmdline: fslstats test.nii.gz -M - tests_inputs: - - - tests_outputs: - - AttributeError - -InvWarp: - output_requirements: - inverse_warp: [reference, warp] - output_templates: - inverse_warp: "{warp}_inverse" - doctest: - reference: anatomical.nii - warp: struct2mni.nii - inverse_warp: struct2mni_inverse.nii.gz - cmdline: invwarp --warp=struct2mni.nii --ref=anatomical.nii --out=struct2mni_inverse.nii.gz - tests_inputs: - - - tests_outputs: - - AttributeError - -# Merge: #need to fix -# output_requirements: -# merged_file: [in_files] -# output_templates: -# merged_file: "{in_files[0]}_merged" -# doctest: -# in_files: [test.nii, test2.nii] -# dimension: t -# tr: 2.25 -# cmdline: fslmerge -tr test_merged.nii.gz test.nii test2.nii 2.25 -# tests_inputs: -# - in_files: [test.nii, test2.nii] -# dimension: t -# tr: 2.25 -# tests_outputs: -# - merged_file - -# MotionOutliers: -# output_requirements: -# out_file: [in_file] -# out_metric_plot: [in_file] -# out_metric_values: [in_file] -# output_templates: -# out_file: "{infile}_outlier" -# out_metric_plot: "{infile}_metrics" -# out_metric_values: "{infile}_metrics" -# doctest: -# in_file: "epi.nii" -# cmdline: "fsl_motion_outliers -i epi.nii -o epi_outliers.txt -p epi_metrics.png -s epi_metrics.txt" -# tests_inputs: -# - -# tests_outputs: -# - [out_file, out_metric_plot, out_metric_values] - -# Overlay: -# output_requirements: -# out_file: ["auto_thresh_bg", "background_image", "stat_image", "stat_thresh"] -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# PlotMotionParams: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# PlotTimeSeries: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# PowerSpectrum: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# Reorient2Std: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# RobustFOV: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# SigLoss: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# Slice: #needs to fix -# output_requirements: -# out_files: [in_file] -# output_templates: -# out_files: [SLICE_output] -# doctest: -# in_file: test.nii.gz -# out_base_name: sl -# cmdline: fslslice test.nii.gz sl -# tests_inputs: -# - in_file: test.nii.gz -# out_base_name: sl -# tests_outputs: -# - out_files - -# Slicer: -# output_requirements: -# out_file: [in_file] -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -Smooth: - output_requirements: - smoothed_file: [in_file, sigma] - - output_templates: - smoothed_file: "{in_file}_smooth" - - inputs_drop: - - fwhm - - doctest: - in_file: test.nii.gz - sigma: 3.397 - smoothed_file: test_smooth.nii.gz - cmdline: fslmaths test.nii.gz -kernel gauss 3.397 -fmean test_smooth.nii.gz - - tests_inputs: - - in_file: test.nii.gz - sigma: 3.397 - tests_outputs: - - smoothed_file - -Split: - output_requirements: - out_files: [in_file, output_basename, dimension] - output_callables: - out_files: Split_output - doctest: - in_file: test.nii.gz - output_basename: test_split - dimension: t - cmdline: fslsplit test.nii.gz test_split -t - - tests_inputs: - - in_file: test.nii.gz - output_basename: test_split - dimension: t - tests_outputs: - - out_files - -SwapDimensions: - output_requirements: - out_file: [in_file, new_dims] - output_templates: - out_file: "{in_file}_newdims" - doctest: - tests_inputs: - - - tests_outputs: - - AttributeError - -# WarpPoints: -# output_requirements: -# out_file: [dest_file, in_coords, src_file] -# output_templates: -# out_file: "{in_coords}_warped" -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# WarpPointsFromStd: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# WarpPointsToStd: -# output_requirements: -# output_templates: -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError - -# WarpUtils: -# output_requirements: -# out_file: [in_file, reference, write_jacobian] -# out_jacobian: [in_file, reference, write_jacobian: True] -# output_templates: -# out_file: "{in_file}_coeffs" -# doctest: -# tests_inputs: -# - -# tests_outputs: -# - AttributeError diff --git a/tools/increment_tool_version.py b/tools/increment_tool_version.py new file mode 100755 index 0000000..e6d56ed --- /dev/null +++ b/tools/increment_tool_version.py @@ -0,0 +1,69 @@ +#!/usr/bin/env python3 +from pathlib import Path +import inspect +from importlib import import_module +import click +from looseversion import LooseVersion +from pydra.engine.core import TaskBase + + +PKG_DIR = Path(__file__).parent.parent +TASKS_DIR = PKG_DIR / "pydra" / "tasks" / "ants" +VERSION_GRANULARITY = ( + 2 # Number of version parts to include: 1 - major, 2 - minor, 3 - micro +) + + +@click.command( + help="""Increment the latest version or create a new sub-package for interfaces for +a new release of AFNI depending on whether one already exists or not. + +NEW_VERSION the version of AFNI to create a new sub-package for +""" +) +@click.argument("new_version", type=LooseVersion) +def increment_tool_version(new_version: LooseVersion): + + # Get the name of the sub-package, e.g. "v2_5" + new_subpkg_name = "_".join(str(p) for p in new_version.version[:VERSION_GRANULARITY]) # type: ignore + if not new_subpkg_name.startswith("v"): + new_subpkg_name = "v" + new_subpkg_name + sub_pkg_dir = TASKS_DIR / new_subpkg_name + if not sub_pkg_dir.exists(): + + prev_version = sorted( + ( + p.name + for p in TASKS_DIR.iterdir() + if p.is_dir() and p.name.startswith("v") + ), + key=lambda x: LooseVersion(".".join(x.split("_"))).version, + )[-1] + prev_ver_mod = import_module(f"pydra.tasks.ants.{prev_version}") + + mod_attrs = [getattr(prev_ver_mod, a) for a in dir(prev_ver_mod)] + task_classes = [ + a for a in mod_attrs if inspect.isclass(a) and issubclass(a, TaskBase) + ] + + code_str = ( + f"from pydra.tasks.ants import {prev_version}\n" + "from . import _tool_version\n" + ) + + for task_cls in task_classes: + code_str += ( + f"\n\nclass {task_cls.__name__}({prev_version}.{task_cls.__name__}):\n" + " TOOL_VERSION = _tool_version.TOOL_VERSION\n" + ) + + sub_pkg_dir.mkdir(exist_ok=True) + with open(sub_pkg_dir / "__init__.py", "w") as f: + f.write(code_str) + + with open(sub_pkg_dir / "_tool_version.py", "w") as f: + f.write(f'TOOL_VERSION = "{new_version}"\n') + + +if __name__ == "__main__": + increment_tool_version() diff --git a/tools/rename_template.py b/tools/rename_template.py new file mode 100755 index 0000000..2c75953 --- /dev/null +++ b/tools/rename_template.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +import sys +import os +import re +import fnmatch +import functools +from pathlib import Path + +PACKAGE_ROOT = Path(__file__).absolute().parent.parent + + +@functools.lru_cache() +def load_gitignore(repo): + gitignore = repo / ".gitignore" + ignore = [fnmatch.translate(".git/"), fnmatch.translate(Path(__file__).name)] + if gitignore.exists(): + ignore.extend( + fnmatch.translate(line.strip()) + for line in gitignore.read_text().splitlines() + if line.strip() and not line[0] == "#" + ) + return re.compile("|".join(ignore)) + + +cmd, new_name, *_ = sys.argv + +for root_, dirs, files in os.walk(PACKAGE_ROOT): + ignore = load_gitignore(PACKAGE_ROOT).search + for d in [d for d in dirs if ignore(f"{d}/")]: + dirs.remove(d) + for f in [f for f in files if ignore(f)]: + files.remove(f) + + root = Path(root_) + for src in list(dirs): + if "fsl" in src: + dst = src.replace("fsl", new_name) + print(f"Renaming: {root / src} -> {root / dst}") + os.rename(root / src, root / dst) + dirs.remove(src) + dirs.append(dst) + for fname in files: + text = Path.read_text(root / fname) + if "fsl" in text: + print(f"Rewriting: {root / fname}") + Path.write_text(root / fname, text.replace("fsl", new_name)) diff --git a/tools/requirements.txt b/tools/requirements.txt new file mode 100644 index 0000000..3b7ccec --- /dev/null +++ b/tools/requirements.txt @@ -0,0 +1,3 @@ +click >= 8.1.3 +looseversion >= 1.1 +pydra >= 0.23 \ No newline at end of file From e9fa0f851b7f175c9fb51b7af2db2e7c6dad66f8 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 15:24:29 +1100 Subject: [PATCH 006/224] started to manual touch up auto-conv yaml specs --- nipype-auto-conv/specs/accuracy_tester.yaml | 89 +++++----- nipype-auto-conv/specs/apply_mask.yaml | 106 ++++++------ nipype-auto-conv/specs/apply_warp.yaml | 152 +++++++++--------- .../fileformats/medimage_fsl/__init__.py | 7 +- 4 files changed, 179 insertions(+), 175 deletions(-) diff --git a/nipype-auto-conv/specs/accuracy_tester.yaml b/nipype-auto-conv/specs/accuracy_tester.yaml index 54388d1..b9facd6 100644 --- a/nipype-auto-conv/specs/accuracy_tester.yaml +++ b/nipype-auto-conv/specs/accuracy_tester.yaml @@ -5,10 +5,10 @@ # # Docs # ---- -# +# # Test the accuracy of an existing training dataset on a set of hand-labelled subjects. # Note: This may or may not be working. Couldn't presently not confirm because fix fails on this (even outside of nipype) without leaving an error msg. -# +# task_name: AccuracyTester nipype_name: AccuracyTester nipype_module: nipype.interfaces.fsl.fix @@ -18,18 +18,17 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - mel_icas: generic/directory+list-of + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + trained_wts_file: generic/file + # type=file|default=: trained-weights file + mel_icas: medimage-fsl/melodic-ica+list-of # type=inputmultiobject|default=[]: Melodic output directories output_directory: Path # type=directory: Path to folder in which to store the results of the accuracy test. - # type=directory|default=: Path to folder in which to store the results of the accuracy test. - trained_wts_file: generic/file - # type=file|default=: trained-weights file callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -41,11 +40,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. output_directory: generic/directory # type=directory: Path to folder in which to store the results of the accuracy test. # type=directory|default=: Path to folder in which to store the results of the accuracy test. @@ -57,33 +56,33 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - mel_icas: - # type=inputmultiobject|default=[]: Melodic output directories - trained_wts_file: - # type=file|default=: trained-weights file - output_directory: - # type=directory: Path to folder in which to store the results of the accuracy test. - # type=directory|default=: Path to folder in which to store the results of the accuracy test. - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mel_icas: + # type=inputmultiobject|default=[]: Melodic output directories + trained_wts_file: + # type=file|default=: trained-weights file + output_directory: + # type=directory: Path to folder in which to store the results of the accuracy test. + # type=directory|default=: Path to folder in which to store the results of the accuracy test. + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: [] diff --git a/nipype-auto-conv/specs/apply_mask.yaml b/nipype-auto-conv/specs/apply_mask.yaml index 53f7d01..aaab93c 100644 --- a/nipype-auto-conv/specs/apply_mask.yaml +++ b/nipype-auto-conv/specs/apply_mask.yaml @@ -15,15 +15,15 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - in_file: generic/file - # type=file|default=: image to operate on - mask_file: generic/file + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + mask_file: medimage/nifti-gz # type=file|default=: binary image defining mask space + in_file: medimage/nifti-gz + # type=file|default=: image to operate on out_file: Path # type=file: image written after calculations # type=file|default=: image to write @@ -38,60 +38,60 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - out_file: generic/file + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + out_file: medimage/nifti-gz # type=file: image written after calculations # type=file|default=: image to write callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: - # dict[str, str] - `output_file_template` values to be provided to output fields - out_file: out_file + # dict[str, str] - `output_file_template` values to be provided to output fields + out_file: out_file.nii.gz # type=file: image written after calculations # type=file|default=: image to write requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - mask_file: - # type=file|default=: binary image defining mask space - in_file: - # type=file|default=: image to operate on - out_file: - # type=file: image written after calculations - # type=file|default=: image to write - internal_datatype: - # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) - output_datatype: - # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) - nan2zeros: - # type=bool|default=False: change NaNs to zeros before doing anything - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mask_file: + # type=file|default=: binary image defining mask space + in_file: + # type=file|default=: image to operate on + out_file: + # type=file: image written after calculations + # type=file|default=: image to write + internal_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for calculations (default is float) + output_datatype: + # type=enum|default='float'|allowed['char','double','float','input','int','short']: datatype to use for output (default uses input type) + nan2zeros: + # type=bool|default=False: change NaNs to zeros before doing anything + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: [] diff --git a/nipype-auto-conv/specs/apply_warp.yaml b/nipype-auto-conv/specs/apply_warp.yaml index 08f921e..f0630ac 100644 --- a/nipype-auto-conv/specs/apply_warp.yaml +++ b/nipype-auto-conv/specs/apply_warp.yaml @@ -6,7 +6,7 @@ # Docs # ---- # FSL's applywarp wrapper to apply the results of a FNIRT registration -# +# # Examples # -------- # >>> from nipype.interfaces import fsl @@ -16,9 +16,9 @@ # >>> aw.inputs.ref_file = example_data('mni.nii') # >>> aw.inputs.field_file = 'my_coefficients_filed.nii' #doctest: +SKIP # >>> res = aw.run() #doctest: +SKIP -# -# -# +# +# +# task_name: ApplyWarp nipype_name: ApplyWarp nipype_module: nipype.interfaces.fsl.preprocess @@ -28,26 +28,26 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - field_file: generic/file - # type=file|default=: file containing warp field - in_file: generic/file + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + in_file: medimage/nifti-gz # type=file|default=: image to be warped - mask_file: generic/file + ref_file: medimage/nifti-gz + # type=file|default=: reference image + field_file: medimage/nifti-gz + # type=file|default=: file containing warp field + premat: Path + # type=file|default=: filename for pre-transform (affine matrix) + postmat: Path + # type=file|default=: filename for post-transform (affine matrix) + mask_file: Path # type=file|default=: filename for mask image (in reference space) out_file: Path # type=file: Warped output file # type=file|default=: output filename - postmat: generic/file - # type=file|default=: filename for post-transform (affine matrix) - premat: generic/file - # type=file|default=: filename for pre-transform (affine matrix) - ref_file: generic/file - # type=file|default=: reference image callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -59,11 +59,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. out_file: generic/file # type=file: Warped output file # type=file|default=: output filename @@ -71,62 +71,62 @@ outputs: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: - # dict[str, str] - `output_file_template` values to be provided to output fields + # dict[str, str] - `output_file_template` values to be provided to output fields out_file: out_file # type=file: Warped output file # type=file|default=: output filename requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - in_file: - # type=file|default=: image to be warped - out_file: - # type=file: Warped output file - # type=file|default=: output filename - ref_file: - # type=file|default=: reference image - field_file: - # type=file|default=: file containing warp field - abswarp: - # type=bool|default=False: treat warp field as absolute: x' = w(x) - relwarp: - # type=bool|default=False: treat warp field as relative: x' = x + w(x) - datatype: - # type=enum|default='char'|allowed['char','double','float','int','short']: Force output data type [char short int float double]. - supersample: - # type=bool|default=False: intermediary supersampling of output, default is off - superlevel: - # type=traitcompound|default=None: level of intermediary supersampling, a for 'automatic' or integer level. Default = 2 - premat: - # type=file|default=: filename for pre-transform (affine matrix) - postmat: - # type=file|default=: filename for post-transform (affine matrix) - mask_file: - # type=file|default=: filename for mask image (in reference space) - interp: - # type=enum|default='nn'|allowed['nn','sinc','spline','trilinear']: interpolation method - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: image to be warped + out_file: + # type=file: Warped output file + # type=file|default=: output filename + ref_file: + # type=file|default=: reference image + field_file: + # type=file|default=: file containing warp field + abswarp: + # type=bool|default=False: treat warp field as absolute: x' = w(x) + relwarp: + # type=bool|default=False: treat warp field as relative: x' = x + w(x) + datatype: + # type=enum|default='char'|allowed['char','double','float','int','short']: Force output data type [char short int float double]. + supersample: + # type=bool|default=False: intermediary supersampling of output, default is off + superlevel: + # type=traitcompound|default=None: level of intermediary supersampling, a for 'automatic' or integer level. Default = 2 + premat: + # type=file|default=: filename for pre-transform (affine matrix) + postmat: + # type=file|default=: filename for post-transform (affine matrix) + mask_file: + # type=file|default=: filename for mask image (in reference space) + interp: + # type=enum|default='nn'|allowed['nn','sinc','spline','trilinear']: interpolation method + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: [] diff --git a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py index 31549f9..8ec8dec 100644 --- a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py +++ b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py @@ -1,6 +1,11 @@ from ._version import __version__ # noqa: F401 -from fileformats.generic import File +from fileformats.generic import File, Directory + class Con(File): ext = ".con" binary = True + + +class MelodicIca(Directory): + """Directory containing output from Melodic ICA""" From c433bc4a9001f03f639fa730208de94acf86b689 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 15:24:50 +1100 Subject: [PATCH 007/224] updated apply mask to use NiftiGz[Mask] data type --- nipype-auto-conv/specs/apply_mask.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/nipype-auto-conv/specs/apply_mask.yaml b/nipype-auto-conv/specs/apply_mask.yaml index aaab93c..13d115d 100644 --- a/nipype-auto-conv/specs/apply_mask.yaml +++ b/nipype-auto-conv/specs/apply_mask.yaml @@ -20,7 +20,7 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mask_file: medimage/nifti-gz + mask_file: medimage/mask+nifti-gz # type=file|default=: binary image defining mask space in_file: medimage/nifti-gz # type=file|default=: image to operate on From 7415eded272fac1a0181276abc6b8339e0758d51 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 15:29:10 +1100 Subject: [PATCH 008/224] updated to latest package generation version --- .github/workflows/pythonpackage.yml | 119 ------- README.rst | 158 +++++++++- nipype-auto-conv/specs/ar1_image.yaml | 2 +- nipype-auto-conv/specs/bedpostx5.yaml | 292 +++++++++--------- nipype-auto-conv/specs/cluster.yaml | 264 ++++++++-------- nipype-auto-conv/specs/fast.yaml | 10 +- nipype-auto-conv/specs/fnirt.yaml | 4 +- nipype-auto-conv/specs/melodic.yaml | 5 - nipype-auto-conv/specs/prob_track_x.yaml | 4 +- nipype-auto-conv/specs/prob_track_x2.yaml | 4 +- nipype-auto-conv/specs/smm.yaml | 90 +++--- nipype-auto-conv/specs/topup.yaml | 274 ++++++++-------- nipype-auto-conv/specs/training.yaml | 2 +- nipype-auto-conv/specs/x_fibres_5.yaml | 170 +++++----- .../fileformats/medimage_fsl/__init__.py | 4 - 15 files changed, 710 insertions(+), 692 deletions(-) delete mode 100644 .github/workflows/pythonpackage.yml diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml deleted file mode 100644 index c139864..0000000 --- a/.github/workflows/pythonpackage.yml +++ /dev/null @@ -1,119 +0,0 @@ -#This workflow will install Python dependencies, run tests and lint with a variety of Python versions -# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions - -# For deployment, it will be necessary to create a PyPI API token and store it as a secret -# https://docs.github.com/en/actions/reference/encrypted-secrets - -name: Python package - -# Set once -env: - SUBPACKAGE: fsl - -on: - push: - branches: [ master ] - tags: [ '*' ] - pull_request: - branches: [ master ] - - -jobs: - devcheck: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.7, 3.9] # Check oldest and newest versions - pip-flags: ['', '--editable'] - pydra: - - 'pydra' - - '--editable git+https://github.com/nipype/pydra.git#egg=pydra' - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - - name: Install Pydra - run: | - pip install ${{ matrix.pydra }} - python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - - name: Install task package - run: | - pip install ${{ matrix.pip-flags }} ".[dev]" - python -c "import pydra.tasks.$SUBPACKAGE as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - - test: - runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.7, 3.8, 3.9] - - steps: - - uses: actions/checkout@v2 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - - name: Install task package - run: | - pip install ".[test]" - python -c "import pydra.tasks.$SUBPACKAGE as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - - name: Test with pytest - run: | - pytest -sv --doctest-modules pydra/tasks/$SUBPACKAGE \ - --cov pydra.tasks.$SUBPACKAGE --cov-report xml - - uses: codecov/codecov-action@v1 - if: ${{ always() }} - - - deploy: - needs: [devcheck, test] - runs-on: ubuntu-latest - strategy: - matrix: - python-version: [3.9] - steps: - - uses: actions/checkout@v2 - with: - submodules: recursive - fetch-depth: 0 - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v2 - with: - python-version: ${{ matrix.python-version }} - - name: Install build tools - run: python -m pip install --upgrade pip build twine - - name: Build source and wheel distributions - run: python -m build - - name: Check distributions - run: twine check dist/* - - uses: actions/upload-artifact@v2 - with: - name: distributions - path: dist/ - # Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. - # Secrets are not accessible in the if: condition [0], so set an output variable [1] - # [0] https://github.community/t/16928 - # [1] https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter - - name: Check for PyPI token on tag - id: deployable - if: github.event_name == 'push' && startsWith(github.ref, 'refs/tags') - env: - PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" - run: if [ -n "$PYPI_API_TOKEN" ]; then echo ::set-output name=DEPLOY::true; fi - - name: Upload to PyPI - if: steps.deployable.outputs.DEPLOY - uses: pypa/gh-action-pypi-publish@27b31702a0e7fc50959f5ad993c78deac1bdfc29 # v1.4.2 - with: - user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} diff --git a/README.rst b/README.rst index c2e2bc2..578d9ec 100644 --- a/README.rst +++ b/README.rst @@ -14,10 +14,12 @@ Pydra task package for fsl :alt: Latest Version -This package contains a collection of Pydra task interfaces for the fsl toolkit. -The basis of this collection has been formed by the semi-automatic conversion of -existing `Nipype `__ interfaces to Pydra using the -`Nipype2Pydra `__ tool +This repository aims to be the canonical set of Pydra tasks for incorporating +`FSL `__ tools into a Pydra workflow. + +Part of this effort is to establish a (mostly) declarative language for describing tasks that +potentially have intricate rules for determining the availability and names from the choice of +inputs. Automatically-generated vs manually-curated tasks @@ -161,3 +163,151 @@ docs `__ for instr new fileformat types, and see `fileformats-medimage-extras `__ for an example on how to implement methods to generate sample data for them. + + +Interface progress +================== + +Below is a list of all planned interfaces, with completed interfaces checked. The list was copied from the nipype documentation at https://nipype.readthedocs.io/en/latest/api/generated/nipype.interfaces.fsl.html. + +Preprocess +---------- + +- [x] ApplyWarp (`applywarp`) +- [ ] ApplyXFM (`flirt`) +- [x] BET (`bet`) +- [x] FAST (`fast`) +- [x] FIRST (`first`) +- [x] FLIRT (`flirt`) +- [x] FNIRT (`fnirt`) +- [ ] FUGUE (`fugue`) +- [x] MCFLIRT (`mcflirt`) +- [x] PRELUDE (`prelude`) +- [x] SUSAN (`susan`) +- [x] SliceTimer (`slicetimer`) + +AROMA +----- + +- [ ] ICA_AROMA (`ICA_AROMA.py`) + +DTI +--- + +- [ ] BEDPOSTX / BEDPOSTX5 (`bedpostx`) +- [ ] DTIFit (`dtifit`) +- [ ] DistanceMap (`distancemap`) +- [ ] FSLXCommand (`xfibres` and `bedpost`) +- [ ] FindTheBiggest (`find_the_biggest`) +- [ ] MakeDyadicVectors (`make_dyadic_vectors`) +- [ ] ProbTrackX (`probtrackx`) +- [ ] ProbTrackX2 (`probtrackx2`) +- [ ] ProjThresh (`proj_thresh`) +- [ ] TractSkeleton (`tbss_skeleton`) +- [ ] VecReg (`vecreg`) +- [ ] XFibres / XFibres5 (`xfibres`) + +EPI +--- + +- [ ] ApplyTOPUP (`applytopup`) +- [ ] EPIDeWarp (`epidewarp.fsl`; depreciated) +- [ ] Eddy (`eddy_openmp`) +- [ ] EddyCorrect (`eddy_correct`; depreciated) +- [ ] EddyQuad (`eddy_quad`) +- [ ] EpiReg (`epi_reg`) +- [ ] PrepareFieldmap (`fsl_prepare_fieldmap`) +- [ ] SigLoss (`sigloss`) +- [ ] TOPUP (`topup`) + +FIX +--- + +- [ ] Classifier (`fix -c`) +- [ ] Cleaner (`fix -a`) +- [ ] FeatureExtractor (`fix -f`) +- [ ] Training (`fix -t`) +- [ ] TrainingSetCreator + +Utils +----- + +- [ ] AvScale (`avscale`) +- [ ] Complex (`fslcomplex`) +- [ ] ConvertWarp (`convertwarp`) +- [ ] ConvertXFM (`convert_xfm`) +- [ ] CopyGeom (`fslcpgeom`) +- [ ] ExtractROI (`fslroi`) +- [ ] FilterRegressor (`fsl_regfilt`) +- [ ] ImageMaths (`fslmaths`) +- [ ] ImageMeants (`fslmeants`) +- [ ] ImageStats (`fslstats`) +- [ ] InvWarp (`invwarp`) +- [ ] Merge (`fslmerge`) +- [ ] MotionOutliers (`fsl_motion_outliers`) +- [ ] Overlay (`overlay`) +- [ ] PlotMotionParams (`fsl_tsplot`) +- [ ] PlotTimeSeries (`fsl_tsplot`) +- [ ] PowerSpectrum (`fslpspec`) +- [ ] Reorient2Std (`fslreorient2std`) +- [ ] RobustFOV (`robustfov`) +- [ ] SigLoss (`sigloss`) +- [ ] Slice (`fslslice`) +- [ ] Slicer (`slicer`) +- [ ] Smooth (`fslmaths`) +- [ ] Split (`fslsplit`) +- [ ] SwapDimensions (`fslswapdim`) +- [ ] Text2Vest (`text2vest`) +- [ ] Vest2Text (`vest2text`) +- [ ] WarpPoints (`img2imgcoord`) +- [ ] WarpPointsFromStd (`std2imgcoord`) +- [ ] WarpPointsToStd (`img2stdcoord`) +- [ ] WarpUtils (`fnirtfileutils`) + +POSSUM +------ + +- [ ] B0Calc (`b0calc`) + +### Model + +- [ ] Cluster (`cluster`) +- [ ] ContrastMgr (`contrast_mgr`) +- [ ] DualRegression (`dual_regression`) +- [ ] FEAT (`feat`) +- [ ] FEATModel (`feat_model`) +- [ ] FEATRegister +- [ ] FILMGLS (`film_gls`) +- [ ] FLAMEO (`flameo`) +- [ ] GLM (`fsl_glm`) +- [ ] L2Model +- [ ] Level1Design +- [ ] MELODIC (`melodic`) +- [ ] MultipleRegressDesign +- [ ] Randomise (`randomise`) +- [ ] SMM (`mm --ld=logdir`) +- [ ] SmoothEstimate (`smoothest`) + +Maths +----- + +- [ ] AR1Image (`fslmaths`) +- [ ] ApplyMask (`fslmaths`) +- [ ] BinaryMaths (`fslmaths`) +- [ ] ChangeDataType (`fslmaths`) +- [ ] DilateImage (`fslmaths`) +- [ ] ErodeImage (`fslmaths`) +- [ ] IsotropicSmooth (`fslmaths`) +- [ ] MathsCommand (`fslmaths`) +- [ ] MaxImage (`fslmaths`) +- [ ] MaxnImage (`fslmaths`) +- [ ] MeanImage (`fslmaths`) +- [ ] MedianImage (`fslmaths`) +- [ ] MinImage (`fslmaths`) +- [ ] MultiImageMaths (`fslmaths`) +- [ ] PercentileImage (`fslmaths`) +- [ ] SpatialFilter (`fslmaths`) +- [ ] StdImage (`fslmaths`) +- [ ] TemporalFilter (`fslmaths`) +- [ ] Threshold (`fslmaths`) +- [ ] UnaryMaths (`fslmaths`) diff --git a/nipype-auto-conv/specs/ar1_image.yaml b/nipype-auto-conv/specs/ar1_image.yaml index 722dc9a..33491e2 100644 --- a/nipype-auto-conv/specs/ar1_image.yaml +++ b/nipype-auto-conv/specs/ar1_image.yaml @@ -62,7 +62,7 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) dimension: - # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to find AR(1) coefficientacross + # type=enum|default='T'|allowed['T','X','Y','Z']: dimension to find AR(1) coefficient across in_file: # type=file|default=: image to operate on out_file: diff --git a/nipype-auto-conv/specs/bedpostx5.yaml b/nipype-auto-conv/specs/bedpostx5.yaml index 8708280..4ef3d5b 100644 --- a/nipype-auto-conv/specs/bedpostx5.yaml +++ b/nipype-auto-conv/specs/bedpostx5.yaml @@ -5,7 +5,7 @@ # # Docs # ---- -# +# # BEDPOSTX stands for Bayesian Estimation of Diffusion Parameters Obtained # using Sampling Techniques. The X stands for modelling Crossing Fibres. # bedpostx runs Markov Chain Monte Carlo sampling to build up distributions @@ -13,22 +13,22 @@ # for running probabilistic tractography. For an overview of the modelling # carried out within bedpostx see this `technical report # `_. -# -# +# +# # .. note:: Consider using # :func:`niflow.nipype1.workflows.fsl.dmri.create_bedpostx_pipeline` instead. -# -# +# +# # Example # ------- -# +# # >>> from nipype.interfaces import fsl # >>> bedp = fsl.BEDPOSTX5(bvecs='bvecs', bvals='bvals', dwi='diffusion.nii', # ... mask='mask.nii', n_fibres=1) # >>> bedp.cmdline # 'bedpostx bedpostx -b 0 --burnin_noard=0 --forcedir -n 1 -j 5000 -s 1 --updateproposalevery=40' -# -# +# +# task_name: BEDPOSTX5 nipype_name: BEDPOSTX5 nipype_module: nipype.interfaces.fsl.dti @@ -38,11 +38,11 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. bvals: medimage/bval # type=file|default=: b values file bvecs: medimage/bvec @@ -52,7 +52,7 @@ inputs: grad_dev: generic/file # type=file|default=: grad_dev file, if gradnonlin, -g is True logdir: generic/directory - # type=directory|default=: + # type=directory|default=: mask: medimage/nifti1 # type=file|default=: bet binary mask file out_dir: generic/directory @@ -68,11 +68,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. dyads: generic/file+list-of # type=outputmultiobject: Mean of PDD distribution in vector form. dyads_dispersion: generic/file+list-of @@ -101,131 +101,131 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - dwi: - # type=file|default=: diffusion weighted image data file - mask: - # type=file|default=: bet binary mask file - bvecs: - # type=file|default=: b vectors file - bvals: - # type=file|default=: b values file - logdir: - # type=directory|default=: - n_fibres: - # type=range|default=2: Maximum number of fibres to fit in each voxel - model: - # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model - fudge: - # type=int|default=0: ARD fudge factor - n_jumps: - # type=int|default=5000: Num of jumps to be made by MCMC - burn_in: - # type=range|default=0: Total num of jumps at start of MCMC to be discarded - sample_every: - # type=range|default=1: Num of jumps for each sample (MCMC) - out_dir: - # type=directory|default='bedpostx': output directory - gradnonlin: - # type=bool|default=False: consider gradient nonlinearities, default off - grad_dev: - # type=file|default=: grad_dev file, if gradnonlin, -g is True - use_gpu: - # type=bool|default=False: Use the GPU version of bedpostx - burn_in_no_ard: - # type=range|default=0: num of burnin jumps before the ard is imposed - update_proposal_every: - # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) - seed: - # type=int|default=0: seed for pseudo random number generator - no_ard: - # type=bool|default=False: Turn ARD off on all fibres - all_ard: - # type=bool|default=False: Turn ARD on on all fibres - no_spat: - # type=bool|default=False: Initialise with tensor, not spatially - non_linear: - # type=bool|default=False: Initialise with nonlinear fitting - cnlinear: - # type=bool|default=False: Initialise with constrained nonlinear fitting - rician: - # type=bool|default=False: use Rician noise modeling - f0_noard: - # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 - f0_ard: - # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 - force_dir: - # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - bvecs: - # type=file|default=: b vectors file - bvals: - # type=file|default=: b values file - dwi: - # type=file|default=: diffusion weighted image data file - mask: - # type=file|default=: bet binary mask file - n_fibres: '1' - # type=range|default=2: Maximum number of fibres to fit in each voxel - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: bet binary mask file + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + logdir: + # type=directory|default=: + n_fibres: + # type=range|default=2: Maximum number of fibres to fit in each voxel + model: + # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model + fudge: + # type=int|default=0: ARD fudge factor + n_jumps: + # type=int|default=5000: Num of jumps to be made by MCMC + burn_in: + # type=range|default=0: Total num of jumps at start of MCMC to be discarded + sample_every: + # type=range|default=1: Num of jumps for each sample (MCMC) + out_dir: + # type=directory|default='bedpostx': output directory + gradnonlin: + # type=bool|default=False: consider gradient nonlinearities, default off + grad_dev: + # type=file|default=: grad_dev file, if gradnonlin, -g is True + use_gpu: + # type=bool|default=False: Use the GPU version of bedpostx + burn_in_no_ard: + # type=range|default=0: num of burnin jumps before the ard is imposed + update_proposal_every: + # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) + seed: + # type=int|default=0: seed for pseudo random number generator + no_ard: + # type=bool|default=False: Turn ARD off on all fibres + all_ard: + # type=bool|default=False: Turn ARD on on all fibres + no_spat: + # type=bool|default=False: Initialise with tensor, not spatially + non_linear: + # type=bool|default=False: Initialise with nonlinear fitting + cnlinear: + # type=bool|default=False: Initialise with constrained nonlinear fitting + rician: + # type=bool|default=False: use Rician noise modeling + f0_noard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + f0_ard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + force_dir: + # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: bet binary mask file + n_fibres: "1" + # type=range|default=2: Maximum number of fibres to fit in each voxel + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: -- cmdline: bedpostx bedpostx -b 0 --burnin_noard=0 --forcedir -n 1 -j 5000 -s 1 --updateproposalevery=40 - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - bvecs: '"bvecs"' - # type=file|default=: b vectors file - bvals: '"bvals"' - # type=file|default=: b values file - dwi: '"diffusion.nii"' - # type=file|default=: diffusion weighted image data file - mask: '"mask.nii"' - # type=file|default=: bet binary mask file - n_fibres: '1' - # type=range|default=2: Maximum number of fibres to fit in each voxel - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: bedpostx bedpostx -b 0 --burnin_noard=0 --forcedir -n 1 -j 5000 -s 1 --updateproposalevery=40 + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + bvecs: '"bvecs"' + # type=file|default=: b vectors file + bvals: '"bvals"' + # type=file|default=: b values file + dwi: '"diffusion.nii"' + # type=file|default=: diffusion weighted image data file + mask: '"mask.nii"' + # type=file|default=: bet binary mask file + n_fibres: "1" + # type=range|default=2: Maximum number of fibres to fit in each voxel + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/cluster.yaml b/nipype-auto-conv/specs/cluster.yaml index 0a2b28a..48b618e 100644 --- a/nipype-auto-conv/specs/cluster.yaml +++ b/nipype-auto-conv/specs/cluster.yaml @@ -6,10 +6,10 @@ # Docs # ---- # Uses FSL cluster to perform clustering on statistical output -# +# # Examples # -------- -# +# # >>> cl = Cluster() # >>> cl.inputs.threshold = 2.3 # >>> cl.inputs.in_file = 'zstat1.nii.gz' @@ -17,8 +17,6 @@ # >>> cl.inputs.use_mm = True # >>> cl.cmdline # 'cluster --in=zstat1.nii.gz --olmax=stats.txt --thresh=2.3000000000 --mm' -# -# task_name: Cluster nipype_name: Cluster nipype_module: nipype.interfaces.fsl.model @@ -28,11 +26,11 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. cope_file: generic/file # type=file|default=: cope volume in_file: medimage/nifti-gz @@ -54,11 +52,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. index_file: generic/file # type=file: output of cluster index (in size order) localmax_txt_file: generic/file @@ -83,123 +81,123 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - in_file: - # type=file|default=: input volume - threshold: - # type=float|default=0.0: threshold for input volume - out_index_file: - # type=traitcompound|default=None: output of cluster index (in size order) - out_threshold_file: - # type=traitcompound|default=None: thresholded image - out_localmax_txt_file: - # type=traitcompound|default=None: local maxima text file - out_localmax_vol_file: - # type=traitcompound|default=None: output of local maxima volume - out_size_file: - # type=traitcompound|default=None: filename for output of size image - out_max_file: - # type=traitcompound|default=None: filename for output of max image - out_mean_file: - # type=traitcompound|default=None: filename for output of mean image - out_pval_file: - # type=traitcompound|default=None: filename for image output of log pvals - pthreshold: - # type=float|default=0.0: p-threshold for clusters - peak_distance: - # type=float|default=0.0: minimum distance between local maxima/minima, in mm (default 0) - cope_file: - # type=file|default=: cope volume - volume: - # type=int|default=0: number of voxels in the mask - dlh: - # type=float|default=0.0: smoothness estimate = sqrt(det(Lambda)) - fractional: - # type=bool|default=False: interprets the threshold as a fraction of the robust range - connectivity: - # type=int|default=0: the connectivity of voxels (default 26) - use_mm: - # type=bool|default=False: use mm, not voxel, coordinates - find_min: - # type=bool|default=False: find minima instead of maxima - no_table: - # type=bool|default=False: suppresses printing of the table info - minclustersize: - # type=bool|default=False: prints out minimum significant cluster size - xfm_file: - # type=file|default=: filename for Linear: input->standard-space transform. Non-linear: input->highres transform - std_space_file: - # type=file|default=: filename for standard-space volume - num_maxima: - # type=int|default=0: no of local maxima to report - warpfield_file: - # type=file|default=: file contining warpfield - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - threshold: '2.3' - # type=float|default=0.0: threshold for input volume - in_file: - # type=file|default=: input volume - out_localmax_txt_file: '"stats.txt"' - # type=traitcompound|default=None: local maxima text file - use_mm: 'True' - # type=bool|default=False: use mm, not voxel, coordinates - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: input volume + threshold: + # type=float|default=0.0: threshold for input volume + out_index_file: + # type=traitcompound|default=None: output of cluster index (in size order) + out_threshold_file: + # type=traitcompound|default=None: thresholded image + out_localmax_txt_file: + # type=traitcompound|default=None: local maxima text file + out_localmax_vol_file: + # type=traitcompound|default=None: output of local maxima volume + out_size_file: + # type=traitcompound|default=None: filename for output of size image + out_max_file: + # type=traitcompound|default=None: filename for output of max image + out_mean_file: + # type=traitcompound|default=None: filename for output of mean image + out_pval_file: + # type=traitcompound|default=None: filename for image output of log pvals + pthreshold: + # type=float|default=0.0: p-threshold for clusters + peak_distance: + # type=float|default=0.0: minimum distance between local maxima/minima, in mm (default 0) + cope_file: + # type=file|default=: cope volume + volume: + # type=int|default=0: number of voxels in the mask + dlh: + # type=float|default=0.0: smoothness estimate = sqrt(det(Lambda)) + fractional: + # type=bool|default=False: interprets the threshold as a fraction of the robust range + connectivity: + # type=int|default=0: the connectivity of voxels (default 26) + use_mm: + # type=bool|default=False: use mm, not voxel, coordinates + find_min: + # type=bool|default=False: find minima instead of maxima + no_table: + # type=bool|default=False: suppresses printing of the table info + minclustersize: + # type=bool|default=False: prints out minimum significant cluster size + xfm_file: + # type=file|default=: filename for Linear: input->standard-space transform. Non-linear: input->highres transform + std_space_file: + # type=file|default=: filename for standard-space volume + num_maxima: + # type=int|default=0: no of local maxima to report + warpfield_file: + # type=file|default=: file containing warpfield + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + threshold: "2.3" + # type=float|default=0.0: threshold for input volume + in_file: + # type=file|default=: input volume + out_localmax_txt_file: '"stats.txt"' + # type=traitcompound|default=None: local maxima text file + use_mm: "True" + # type=bool|default=False: use mm, not voxel, coordinates + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: -- cmdline: cluster --in=zstat1.nii.gz --olmax=stats.txt --thresh=2.3000000000 --mm - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - threshold: '2.3' - # type=float|default=0.0: threshold for input volume - in_file: '"zstat1.nii.gz"' - # type=file|default=: input volume - out_localmax_txt_file: '"stats.txt"' - # type=traitcompound|default=None: local maxima text file - use_mm: 'True' - # type=bool|default=False: use mm, not voxel, coordinates - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: cluster --in=zstat1.nii.gz --olmax=stats.txt --thresh=2.3000000000 --mm + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + threshold: "2.3" + # type=float|default=0.0: threshold for input volume + in_file: '"zstat1.nii.gz"' + # type=file|default=: input volume + out_localmax_txt_file: '"stats.txt"' + # type=traitcompound|default=None: local maxima text file + use_mm: "True" + # type=bool|default=False: use mm, not voxel, coordinates + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/fast.yaml b/nipype-auto-conv/specs/fast.yaml index 007930a..e565d4a 100644 --- a/nipype-auto-conv/specs/fast.yaml +++ b/nipype-auto-conv/specs/fast.yaml @@ -13,12 +13,12 @@ # Examples # -------- # >>> from nipype.interfaces import fsl -# >>> fastr = fsl.FAST() -# >>> fastr.inputs.in_files = 'structural.nii' -# >>> fastr.inputs.out_basename = 'fast_' -# >>> fastr.cmdline +# >>> fast = fsl.FAST() +# >>> fast.inputs.in_files = 'structural.nii' +# >>> fast.inputs.out_basename = 'fast_' +# >>> fast.cmdline # 'fast -o fast_ -S 1 structural.nii' -# >>> out = fastr.run() # doctest: +SKIP +# >>> out = fast.run() # doctest: +SKIP # # task_name: FAST diff --git a/nipype-auto-conv/specs/fnirt.yaml b/nipype-auto-conv/specs/fnirt.yaml index 84d3b6d..d802e0d 100644 --- a/nipype-auto-conv/specs/fnirt.yaml +++ b/nipype-auto-conv/specs/fnirt.yaml @@ -269,10 +269,8 @@ doctests: # '.mock()' method of the corresponding class is used instead. in_fwhm: '[8, 4, 2, 2]' # type=list|default=[]: FWHM (in mm) of gaussian smoothing kernel for input volume, default [6, 4, 2, 2] - subsampling_scheme: '[4, 2, 1, 1]' + subsampling_scheme: '[4, 2, 1, 1] Specify the resolution of the warps >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6)' # type=list|default=[]: sub-sampling scheme, list, default [4, 2, 1, 1] - warp_resolution: (6, 6, 6) - # type=tuple|default=(0, 0, 0): (approximate) resolution (in mm) of warp basis in x-, y- and z-direction, default 10, 10, 10 imports: *id001 # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys diff --git a/nipype-auto-conv/specs/melodic.yaml b/nipype-auto-conv/specs/melodic.yaml index 05f40e8..efdf7c8 100644 --- a/nipype-auto-conv/specs/melodic.yaml +++ b/nipype-auto-conv/specs/melodic.yaml @@ -83,11 +83,6 @@ outputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - out_dir: generic/directory - # type=directory: - # type=directory|default=: output directory name - report_dir: generic/directory - # type=directory: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields diff --git a/nipype-auto-conv/specs/prob_track_x.yaml b/nipype-auto-conv/specs/prob_track_x.yaml index 03071e9..76fb58a 100644 --- a/nipype-auto-conv/specs/prob_track_x.yaml +++ b/nipype-auto-conv/specs/prob_track_x.yaml @@ -152,7 +152,7 @@ tests: c_thresh: # type=float|default=0.0: curvature threshold - default=0.2 sample_random_points: - # type=bool|default=False: sample random points within seed voxels + # type=float|default=0.0: sample random points within seed voxels step_length: # type=float|default=0.0: step_length in mm - default=0.5 loop_check: @@ -166,7 +166,7 @@ tests: mod_euler: # type=bool|default=False: use modified euler streamlining random_seed: - # type=bool|default=False: random seed + # type=int|default=0: random seed s2tastext: # type=bool|default=False: output seed-to-target counts as a text file (useful when seeding from a mesh) verbose: diff --git a/nipype-auto-conv/specs/prob_track_x2.yaml b/nipype-auto-conv/specs/prob_track_x2.yaml index 5b8140d..40e5b0e 100644 --- a/nipype-auto-conv/specs/prob_track_x2.yaml +++ b/nipype-auto-conv/specs/prob_track_x2.yaml @@ -203,7 +203,7 @@ tests: c_thresh: # type=float|default=0.0: curvature threshold - default=0.2 sample_random_points: - # type=bool|default=False: sample random points within seed voxels + # type=float|default=0.0: sample random points within seed voxels step_length: # type=float|default=0.0: step_length in mm - default=0.5 loop_check: @@ -217,7 +217,7 @@ tests: mod_euler: # type=bool|default=False: use modified euler streamlining random_seed: - # type=bool|default=False: random seed + # type=int|default=0: random seed s2tastext: # type=bool|default=False: output seed-to-target counts as a text file (useful when seeding from a mesh) verbose: diff --git a/nipype-auto-conv/specs/smm.yaml b/nipype-auto-conv/specs/smm.yaml index 04aad0b..2f1b196 100644 --- a/nipype-auto-conv/specs/smm.yaml +++ b/nipype-auto-conv/specs/smm.yaml @@ -5,12 +5,12 @@ # # Docs # ---- -# +# # Spatial Mixture Modelling. For more detail on the spatial mixture modelling # see Mixture Models with Adaptive Spatial Regularisation for Segmentation # with an Application to FMRI Data; Woolrich, M., Behrens, T., Beckmann, C., # and Smith, S.; IEEE Trans. Medical Imaging, 24(1):1-11, 2005. -# +# task_name: SMM nipype_name: SMM nipype_module: nipype.interfaces.fsl.model @@ -20,11 +20,11 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. mask: generic/file # type=file|default=: mask file spatial_data_file: generic/file @@ -40,17 +40,17 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. activation_p_map: generic/file - # type=file: + # type=file: deactivation_p_map: generic/file - # type=file: + # type=file: null_p_map: generic/file - # type=file: + # type=file: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -59,34 +59,34 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - spatial_data_file: - # type=file|default=: statistics spatial map - mask: - # type=file|default=: mask file - no_deactivation_class: - # type=bool|default=False: enforces no deactivation class - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + spatial_data_file: + # type=file|default=: statistics spatial map + mask: + # type=file|default=: mask file + no_deactivation_class: + # type=bool|default=False: enforces no deactivation class + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: [] diff --git a/nipype-auto-conv/specs/topup.yaml b/nipype-auto-conv/specs/topup.yaml index 128a753..c5277ee 100644 --- a/nipype-auto-conv/specs/topup.yaml +++ b/nipype-auto-conv/specs/topup.yaml @@ -5,7 +5,7 @@ # # Docs # ---- -# +# # Interface for FSL topup, a tool for estimating and correcting # susceptibility induced distortions. See FSL documentation for # `reference `_, @@ -13,10 +13,10 @@ # `_, # and `exemplary config files # `_. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import TOPUP # >>> topup = TOPUP() # >>> topup.inputs.in_file = "b0_b0rev.nii" @@ -25,8 +25,8 @@ # >>> topup.cmdline # doctest: +ELLIPSIS # 'topup --config=b02b0.cnf --datain=topup_encoding.txt --imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz --fout=b0_b0rev_field.nii.gz --jacout=jac --logout=b0_b0rev_topup.log --rbmout=xfm --dfout=warpfield' # >>> res = topup.run() # doctest: +SKIP -# -# +# +# task_name: TOPUP nipype_name: TOPUP nipype_module: nipype.interfaces.fsl.epi @@ -36,26 +36,26 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. encoding_file: text/text-file # type=file|default=: name of text file with PE directions/times in_file: medimage/nifti1 # type=file|default=: name of 4D file with images out_base: Path # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) + readout_times: generic/file+list-of + # type=inputmultiobject|default=[]: readout times (dwell times by # phase-encode steps minus 1) out_corrected: Path # type=file: name of 4D image file with unwarped images # type=file|default=: name of 4D image file with unwarped images out_field: Path # type=file: name of image file with field (Hz) - # type=file|default=: name of image file with field (Hz) out_logfile: Path # type=file: name of log-file - # type=file|default=: name of log-file callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -67,11 +67,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. out_corrected: generic/file # type=file: name of 4D image file with unwarped images # type=file|default=: name of 4D image file with unwarped images @@ -101,124 +101,124 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - in_file: - # type=file|default=: name of 4D file with images - encoding_file: - # type=file|default=: name of text file with PE directions/times - encoding_direction: - # type=list|default=[]: encoding direction for automatic generation of encoding_file - readout_times: - # type=inputmultiobject|default=[]: readout times (dwell times by # phase-encode steps minus 1) - out_base: - # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) - out_field: - # type=file: name of image file with field (Hz) - # type=file|default=: name of image file with field (Hz) - out_warp_prefix: - # type=str|default='warpfield': prefix for the warpfield images (in mm) - out_mat_prefix: - # type=str|default='xfm': prefix for the realignment matrices - out_jac_prefix: - # type=str|default='jac': prefix for the warpfield images - out_corrected: - # type=file: name of 4D image file with unwarped images - # type=file|default=: name of 4D image file with unwarped images - out_logfile: - # type=file: name of log-file - # type=file|default=: name of log-file - warp_res: - # type=float|default=0.0: (approximate) resolution (in mm) of warp basis for the different sub-sampling levels - subsamp: - # type=int|default=0: sub-sampling scheme - fwhm: - # type=float|default=0.0: FWHM (in mm) of gaussian smoothing kernel - config: - # type=string|default='b02b0.cnf': Name of config file specifying command line arguments - max_iter: - # type=int|default=0: max # of non-linear iterations - reg_lambda: - # type=float|default=0.0: Weight of regularisation, default depending on --ssqlambda and --regmod switches. - ssqlambda: - # type=enum|default=1|allowed[0,1]: Weight lambda by the current value of the ssd. If used (=1), the effective weight of regularisation term becomes higher for the initial iterations, therefore initial steps are a little smoother than they would without weighting. This reduces the risk of finding a local minimum. - regmod: - # type=enum|default='bending_energy'|allowed['bending_energy','membrane_energy']: Regularisation term implementation. Defaults to bending_energy. Note that the two functions have vastly different scales. The membrane energy is based on the first derivatives and the bending energy on the second derivatives. The second derivatives will typically be much smaller than the first derivatives, so input lambda will have to be larger for bending_energy to yield approximately the same level of regularisation. - estmov: - # type=enum|default=1|allowed[0,1]: estimate movements if set - minmet: - # type=enum|default=0|allowed[0,1]: Minimisation method 0=Levenberg-Marquardt, 1=Scaled Conjugate Gradient - splineorder: - # type=int|default=0: order of spline, 2->Qadratic spline, 3->Cubic spline - numprec: - # type=enum|default='double'|allowed['double','float']: Precision for representing Hessian, double or float. - interp: - # type=enum|default='spline'|allowed['linear','spline']: Image interpolation model, linear or spline. - scale: - # type=enum|default=0|allowed[0,1]: If set (=1), the images are individually scaled to a common mean - regrid: - # type=enum|default=1|allowed[0,1]: If set (=1), the calculations are done in a different grid - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - in_file: - # type=file|default=: name of 4D file with images - encoding_file: - # type=file|default=: name of text file with PE directions/times - output_type: '"NIFTI_GZ"' - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: name of 4D file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + encoding_direction: + # type=list|default=[]: encoding direction for automatic generation of encoding_file + readout_times: + # type=inputmultiobject|default=[]: readout times (dwell times by # phase-encode steps minus 1) + out_base: + # type=file|default=: base-name of output files (spline coefficients (Hz) and movement parameters) + out_field: + # type=file: name of image file with field (Hz) + # type=file|default=: name of image file with field (Hz) + out_warp_prefix: + # type=str|default='warpfield': prefix for the warpfield images (in mm) + out_mat_prefix: + # type=str|default='xfm': prefix for the realignment matrices + out_jac_prefix: + # type=str|default='jac': prefix for the warpfield images + out_corrected: + # type=file: name of 4D image file with unwarped images + # type=file|default=: name of 4D image file with unwarped images + out_logfile: + # type=file: name of log-file + # type=file|default=: name of log-file + warp_res: + # type=float|default=0.0: (approximate) resolution (in mm) of warp basis for the different sub-sampling levels + subsamp: + # type=int|default=0: sub-sampling scheme + fwhm: + # type=float|default=0.0: FWHM (in mm) of gaussian smoothing kernel + config: + # type=string|default='b02b0.cnf': Name of config file specifying command line arguments + max_iter: + # type=int|default=0: max # of non-linear iterations + reg_lambda: + # type=float|default=0.0: Weight of regularisation, default depending on --ssqlambda and --regmod switches. + ssqlambda: + # type=enum|default=1|allowed[0,1]: Weight lambda by the current value of the ssd. If used (=1), the effective weight of regularisation term becomes higher for the initial iterations, therefore initial steps are a little smoother than they would without weighting. This reduces the risk of finding a local minimum. + regmod: + # type=enum|default='bending_energy'|allowed['bending_energy','membrane_energy']: Regularisation term implementation. Defaults to bending_energy. Note that the two functions have vastly different scales. The membrane energy is based on the first derivatives and the bending energy on the second derivatives. The second derivatives will typically be much smaller than the first derivatives, so input lambda will have to be larger for bending_energy to yield approximately the same level of regularisation. + estmov: + # type=enum|default=1|allowed[0,1]: estimate movements if set + minmet: + # type=enum|default=0|allowed[0,1]: Minimisation method 0=Levenberg-Marquardt, 1=Scaled Conjugate Gradient + splineorder: + # type=int|default=0: order of spline, 2->Qadratic spline, 3->Cubic spline + numprec: + # type=enum|default='double'|allowed['double','float']: Precision for representing Hessian, double or float. + interp: + # type=enum|default='spline'|allowed['linear','spline']: Image interpolation model, linear or spline. + scale: + # type=enum|default=0|allowed[0,1]: If set (=1), the images are individually scaled to a common mean + regrid: + # type=enum|default=1|allowed[0,1]: If set (=1), the calculations are done in a different grid + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: name of 4D file with images + encoding_file: + # type=file|default=: name of text file with PE directions/times + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: -- cmdline: topup --config=b02b0.cnf --datain=topup_encoding.txt --imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz --fout=b0_b0rev_field.nii.gz --jacout=jac --logout=b0_b0rev_topup.log --rbmout=xfm --dfout=warpfield - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - in_file: '"b0_b0rev.nii"' - # type=file|default=: name of 4D file with images - encoding_file: '"topup_encoding.txt"' - # type=file|default=: name of text file with PE directions/times - output_type: '"NIFTI_GZ"' - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: topup --config=b02b0.cnf --datain=topup_encoding.txt --imain=b0_b0rev.nii --out=b0_b0rev_base --iout=b0_b0rev_corrected.nii.gz --fout=b0_b0rev_field.nii.gz --jacout=jac --logout=b0_b0rev_topup.log --rbmout=xfm --dfout=warpfield + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: '"b0_b0rev.nii"' + # type=file|default=: name of 4D file with images + encoding_file: '"topup_encoding.txt"' + # type=file|default=: name of text file with PE directions/times + output_type: '"NIFTI_GZ"' + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/training.yaml b/nipype-auto-conv/specs/training.yaml index 52ac302..00b59f7 100644 --- a/nipype-auto-conv/specs/training.yaml +++ b/nipype-auto-conv/specs/training.yaml @@ -22,7 +22,7 @@ inputs: # from the nipype interface, but you may want to be more specific, particularly # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. - mel_icas: generic/directory+list-of + mel_icas: generic/file+list-of # type=inputmultiobject|default=[]: Melodic output directories callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` diff --git a/nipype-auto-conv/specs/x_fibres_5.yaml b/nipype-auto-conv/specs/x_fibres_5.yaml index 9ea798f..95887a8 100644 --- a/nipype-auto-conv/specs/x_fibres_5.yaml +++ b/nipype-auto-conv/specs/x_fibres_5.yaml @@ -5,10 +5,10 @@ # # Docs # ---- -# +# # Perform model parameters estimation for local (voxelwise) diffusion # parameters -# +# task_name: XFibres5 nipype_name: XFibres5 nipype_module: nipype.interfaces.fsl.dti @@ -18,11 +18,11 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. bvals: generic/file # type=file|default=: b values file bvecs: generic/file @@ -32,7 +32,7 @@ inputs: gradnonlin: generic/file # type=file|default=: gradient file corresponding to slice logdir: generic/directory - # type=directory|default='.': + # type=directory|default='.': mask: generic/file # type=file|default=: brain binary mask file (i.e. from BET) callable_defaults: @@ -46,11 +46,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. dyads: generic/file+list-of # type=outputmultiobject: Mean of PDD distribution in vector form. fsamples: generic/file+list-of @@ -75,76 +75,76 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - gradnonlin: - # type=file|default=: gradient file corresponding to slice - dwi: - # type=file|default=: diffusion weighted image data file - mask: - # type=file|default=: brain binary mask file (i.e. from BET) - bvecs: - # type=file|default=: b vectors file - bvals: - # type=file|default=: b values file - logdir: - # type=directory|default='.': - n_fibres: - # type=range|default=2: Maximum number of fibres to fit in each voxel - model: - # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model - fudge: - # type=int|default=0: ARD fudge factor - n_jumps: - # type=int|default=5000: Num of jumps to be made by MCMC - burn_in: - # type=range|default=0: Total num of jumps at start of MCMC to be discarded - burn_in_no_ard: - # type=range|default=0: num of burnin jumps before the ard is imposed - sample_every: - # type=range|default=1: Num of jumps for each sample (MCMC) - update_proposal_every: - # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) - seed: - # type=int|default=0: seed for pseudo random number generator - no_ard: - # type=bool|default=False: Turn ARD off on all fibres - all_ard: - # type=bool|default=False: Turn ARD on on all fibres - no_spat: - # type=bool|default=False: Initialise with tensor, not spatially - non_linear: - # type=bool|default=False: Initialise with nonlinear fitting - cnlinear: - # type=bool|default=False: Initialise with constrained nonlinear fitting - rician: - # type=bool|default=False: use Rician noise modeling - f0_noard: - # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 - f0_ard: - # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 - force_dir: - # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + gradnonlin: + # type=file|default=: gradient file corresponding to slice + dwi: + # type=file|default=: diffusion weighted image data file + mask: + # type=file|default=: brain binary mask file (i.e. from BET) + bvecs: + # type=file|default=: b vectors file + bvals: + # type=file|default=: b values file + logdir: + # type=directory|default='.': + n_fibres: + # type=range|default=2: Maximum number of fibres to fit in each voxel + model: + # type=enum|default=1|allowed[1,2,3]: use monoexponential (1, default, required for single-shell) or multiexponential (2, multi-shell) model + fudge: + # type=int|default=0: ARD fudge factor + n_jumps: + # type=int|default=5000: Num of jumps to be made by MCMC + burn_in: + # type=range|default=0: Total num of jumps at start of MCMC to be discarded + burn_in_no_ard: + # type=range|default=0: num of burnin jumps before the ard is imposed + sample_every: + # type=range|default=1: Num of jumps for each sample (MCMC) + update_proposal_every: + # type=range|default=40: Num of jumps for each update to the proposal density std (MCMC) + seed: + # type=int|default=0: seed for pseudo random number generator + no_ard: + # type=bool|default=False: Turn ARD off on all fibres + all_ard: + # type=bool|default=False: Turn ARD on on all fibres + no_spat: + # type=bool|default=False: Initialise with tensor, not spatially + non_linear: + # type=bool|default=False: Initialise with nonlinear fitting + cnlinear: + # type=bool|default=False: Initialise with constrained nonlinear fitting + rician: + # type=bool|default=False: use Rician noise modeling + f0_noard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + f0_ard: + # type=bool|default=False: Noise floor model: add to the model an unattenuated signal compartment f0 + force_dir: + # type=bool|default=True: use the actual directory name given (do not add + to make a new directory) + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: [] diff --git a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py index 8ec8dec..36da2c8 100644 --- a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py +++ b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py @@ -5,7 +5,3 @@ class Con(File): ext = ".con" binary = True - - -class MelodicIca(Directory): - """Directory containing output from Melodic ICA""" From 587b7820f019d2888d5b8b7fdfc342b65dbff968 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 15:31:57 +1100 Subject: [PATCH 009/224] updated nipype converter specs --- nipype-auto-conv/specs/eddy.yaml | 538 +++++++++++++------------- nipype-auto-conv/specs/eddy_quad.yaml | 196 +++++----- nipype-auto-conv/specs/topup.yaml | 17 +- 3 files changed, 382 insertions(+), 369 deletions(-) diff --git a/nipype-auto-conv/specs/eddy.yaml b/nipype-auto-conv/specs/eddy.yaml index 368ad6b..cf7bf91 100644 --- a/nipype-auto-conv/specs/eddy.yaml +++ b/nipype-auto-conv/specs/eddy.yaml @@ -5,18 +5,18 @@ # # Docs # ---- -# +# # Interface for FSL eddy, a tool for estimating and correcting eddy # currents induced distortions. `User guide # `__ and # `more info regarding acqp file # `_. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import Eddy -# +# # Running eddy on a CPU using OpenMP: # >>> eddy = Eddy() # >>> eddy.inputs.in_file = 'epi.nii' @@ -27,12 +27,12 @@ # >>> eddy.inputs.in_bval = 'bvals.scheme' # >>> eddy.cmdline # doctest: +ELLIPSIS # 'eddy_openmp --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none' -# +# # Running eddy on an Nvidia GPU using cuda: # >>> eddy.inputs.use_cuda = True # >>> eddy.cmdline # doctest: +ELLIPSIS # 'eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none' -# +# # Running eddy with slice-to-volume motion correction: # >>> eddy.inputs.mporder = 6 # >>> eddy.inputs.slice2vol_niter = 5 @@ -42,8 +42,8 @@ # >>> eddy.cmdline # doctest: +ELLIPSIS # 'eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --mporder=6 --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --s2v_interp=trilinear --s2v_lambda=1 --s2v_niter=5 --slspec=epi_slspec.txt --slm=none' # >>> res = eddy.run() # doctest: +SKIP -# -# +# +# task_name: Eddy nipype_name: Eddy nipype_module: nipype.interfaces.fsl.epi @@ -53,35 +53,35 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - field: generic/file - # type=file|default=: Non-topup derived fieldmap scaled in Hz - field_mat: generic/file - # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain - in_acqp: generic/file - # type=file|default=: File containing acquisition parameters - in_bval: generic/file - # type=file|default=: File containing the b-values for all volumes in --imain - in_bvec: generic/file - # type=file|default=: File containing the b-vectors for all volumes in --imain + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 # type=file|default=: File containing all the images to estimate distortions for - in_index: text/text-file - # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup in_mask: generic/file # type=file|default=: Mask to indicate brain + in_index: text/text-file + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + in_acqp: generic/file + # type=file|default=: File containing acquisition parameters + in_bvec: medimage/bvec + # type=file|default=: File containing the b-vectors for all volumes in --imain + in_bval: medimage/bval + # type=file|default=: File containing the b-values for all volumes in --imain + session: generic/file + # type=file|default=: File containing session indices for all volumes in --imain in_topup_fieldcoef: generic/file # type=file|default=: Topup results file containing the field coefficients in_topup_movpar: generic/file # type=file|default=: Topup results file containing the movement parameters (movpar.txt) + field: generic/file + # type=file|default=: Non-topup derived fieldmap scaled in Hz + field_mat: generic/file + # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain json: generic/file # type=file|default='': Name of .json text file with information about slice timing - session: generic/file - # type=file|default=: File containing session indices for all volumes in --imain slice_order: text/text-file # type=file|default='': Name of text file completely specifying slice/group acquisition callable_defaults: @@ -95,11 +95,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. out_cnr_maps: generic/file # type=file: path/name of file with the cnr_maps out_corrected: generic/file @@ -138,241 +138,241 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - in_file: - # type=file|default=: File containing all the images to estimate distortions for - in_mask: - # type=file|default=: Mask to indicate brain - in_index: - # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup - in_acqp: - # type=file|default=: File containing acquisition parameters - in_bvec: - # type=file|default=: File containing the b-vectors for all volumes in --imain - in_bval: - # type=file|default=: File containing the b-values for all volumes in --imain - out_base: - # type=str|default='eddy_corrected': Basename for output image - session: - # type=file|default=: File containing session indices for all volumes in --imain - in_topup_fieldcoef: - # type=file|default=: Topup results file containing the field coefficients - in_topup_movpar: - # type=file|default=: Topup results file containing the movement parameters (movpar.txt) - field: - # type=file|default=: Non-topup derived fieldmap scaled in Hz - field_mat: - # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain - flm: - # type=enum|default='quadratic'|allowed['cubic','linear','quadratic']: First level EC model - slm: - # type=enum|default='none'|allowed['linear','none','quadratic']: Second level EC model - fep: - # type=bool|default=False: Fill empty planes in x- or y-directions - initrand: - # type=bool|default=False: Resets rand for when selecting voxels - interp: - # type=enum|default='spline'|allowed['spline','trilinear']: Interpolation model for estimation step - nvoxhp: - # type=int|default=1000: # of voxels used to estimate the hyperparameters - fudge_factor: - # type=float|default=10.0: Fudge factor for hyperparameter error variance - dont_sep_offs_move: - # type=bool|default=False: Do NOT attempt to separate field offset from subject movement - dont_peas: - # type=bool|default=False: Do NOT perform a post-eddy alignment of shells - fwhm: - # type=float|default=0.0: FWHM for conditioning filter when estimating the parameters - niter: - # type=int|default=5: Number of iterations - method: - # type=enum|default='jac'|allowed['jac','lsr']: Final resampling method (jacobian/least squares) - repol: - # type=bool|default=False: Detect and replace outlier slices - outlier_nstd: - # type=int|default=0: Number of std off to qualify as outlier - outlier_nvox: - # type=int|default=0: Min # of voxels in a slice for inclusion in outlier detection - outlier_type: - # type=enum|default='sw'|allowed['both','gw','sw']: Type of outliers, slicewise (sw), groupwise (gw) or both (both) - outlier_pos: - # type=bool|default=False: Consider both positive and negative outliers if set - outlier_sqr: - # type=bool|default=False: Consider outliers among sums-of-squared differences if set - multiband_factor: - # type=int|default=0: Multi-band factor - multiband_offset: - # type=enum|default=0|allowed[-1,0,1]: Multi-band offset (-1 if bottom slice removed, 1 if top slice removed - mporder: - # type=int|default=0: Order of slice-to-vol movement model - slice2vol_niter: - # type=int|default=0: Number of iterations for slice-to-vol - slice2vol_lambda: - # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) - slice2vol_interp: - # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step - slice_order: - # type=file|default='': Name of text file completely specifying slice/group acquisition - json: - # type=file|default='': Name of .json text file with information about slice timing - estimate_move_by_susceptibility: - # type=bool|default=False: Estimate how susceptibility field changes with subject movement - mbs_niter: - # type=int|default=0: Number of iterations for MBS estimation - mbs_lambda: - # type=int|default=0: Weighting of regularisation for MBS estimation - mbs_ksp: - # type=int|default=0: Knot-spacing for MBS field estimation - num_threads: - # type=int|default=1: Number of openmp threads to use - is_shelled: - # type=bool|default=False: Override internal check to ensure that date are acquired on a set of b-value shells - use_cuda: - # type=bool|default=False: Run eddy using cuda gpu - cnr_maps: - # type=bool|default=False: Output CNR-Maps - residuals: - # type=bool|default=False: Output Residuals - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - in_file: - # type=file|default=: File containing all the images to estimate distortions for - in_index: - # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - use_cuda: 'True' - # type=bool|default=False: Run eddy using cuda gpu - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - mporder: '6' - # type=int|default=0: Order of slice-to-vol movement model - slice2vol_niter: '5' - # type=int|default=0: Number of iterations for slice-to-vol - slice2vol_lambda: '1' - # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) - slice2vol_interp: '"trilinear"' - # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step - slice_order: - # type=file|default='': Name of text file completely specifying slice/group acquisition - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: File containing all the images to estimate distortions for + in_mask: + # type=file|default=: Mask to indicate brain + in_index: + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + in_acqp: + # type=file|default=: File containing acquisition parameters + in_bvec: + # type=file|default=: File containing the b-vectors for all volumes in --imain + in_bval: + # type=file|default=: File containing the b-values for all volumes in --imain + out_base: + # type=str|default='eddy_corrected': Basename for output image + session: + # type=file|default=: File containing session indices for all volumes in --imain + in_topup_fieldcoef: + # type=file|default=: Topup results file containing the field coefficients + in_topup_movpar: + # type=file|default=: Topup results file containing the movement parameters (movpar.txt) + field: + # type=file|default=: Non-topup derived fieldmap scaled in Hz + field_mat: + # type=file|default=: Matrix specifying the relative positions of the fieldmap, --field, and the first volume of the input file, --imain + flm: + # type=enum|default='quadratic'|allowed['cubic','linear','quadratic']: First level EC model + slm: + # type=enum|default='none'|allowed['linear','none','quadratic']: Second level EC model + fep: + # type=bool|default=False: Fill empty planes in x- or y-directions + initrand: + # type=bool|default=False: Resets rand for when selecting voxels + interp: + # type=enum|default='spline'|allowed['spline','trilinear']: Interpolation model for estimation step + nvoxhp: + # type=int|default=1000: # of voxels used to estimate the hyperparameters + fudge_factor: + # type=float|default=10.0: Fudge factor for hyperparameter error variance + dont_sep_offs_move: + # type=bool|default=False: Do NOT attempt to separate field offset from subject movement + dont_peas: + # type=bool|default=False: Do NOT perform a post-eddy alignment of shells + fwhm: + # type=float|default=0.0: FWHM for conditioning filter when estimating the parameters + niter: + # type=int|default=5: Number of iterations + method: + # type=enum|default='jac'|allowed['jac','lsr']: Final resampling method (jacobian/least squares) + repol: + # type=bool|default=False: Detect and replace outlier slices + outlier_nstd: + # type=int|default=0: Number of std off to qualify as outlier + outlier_nvox: + # type=int|default=0: Min # of voxels in a slice for inclusion in outlier detection + outlier_type: + # type=enum|default='sw'|allowed['both','gw','sw']: Type of outliers, slicewise (sw), groupwise (gw) or both (both) + outlier_pos: + # type=bool|default=False: Consider both positive and negative outliers if set + outlier_sqr: + # type=bool|default=False: Consider outliers among sums-of-squared differences if set + multiband_factor: + # type=int|default=0: Multi-band factor + multiband_offset: + # type=enum|default=0|allowed[-1,0,1]: Multi-band offset (-1 if bottom slice removed, 1 if top slice removed + mporder: + # type=int|default=0: Order of slice-to-vol movement model + slice2vol_niter: + # type=int|default=0: Number of iterations for slice-to-vol + slice2vol_lambda: + # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) + slice2vol_interp: + # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step + slice_order: + # type=file|default='': Name of text file completely specifying slice/group acquisition + json: + # type=file|default='': Name of .json text file with information about slice timing + estimate_move_by_susceptibility: + # type=bool|default=False: Estimate how susceptibility field changes with subject movement + mbs_niter: + # type=int|default=0: Number of iterations for MBS estimation + mbs_lambda: + # type=int|default=0: Weighting of regularisation for MBS estimation + mbs_ksp: + # type=int|default=0: Knot-spacing for MBS field estimation + num_threads: + # type=int|default=1: Number of openmp threads to use + is_shelled: + # type=bool|default=False: Override internal check to ensure that date are acquired on a set of b-value shells + use_cuda: + # type=bool|default=False: Run eddy using cuda gpu + cnr_maps: + # type=bool|default=False: Output CNR-Maps + residuals: + # type=bool|default=False: Output Residuals + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + in_file: + # type=file|default=: File containing all the images to estimate distortions for + in_index: + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + use_cuda: "True" + # type=bool|default=False: Run eddy using cuda gpu + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + mporder: "6" + # type=int|default=0: Order of slice-to-vol movement model + slice2vol_niter: "5" + # type=int|default=0: Number of iterations for slice-to-vol + slice2vol_lambda: "1" + # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) + slice2vol_interp: '"trilinear"' + # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step + slice_order: + # type=file|default='': Name of text file completely specifying slice/group acquisition + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: -- cmdline: eddy_openmp --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - in_file: '"epi.nii"' - # type=file|default=: File containing all the images to estimate distortions for - in_index: '"epi_index.txt"' - # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS -- cmdline: eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - use_cuda: 'True' - # type=bool|default=False: Run eddy using cuda gpu - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS -- cmdline: eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --mporder=6 --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --s2v_interp=trilinear --s2v_lambda=1 --s2v_niter=5 --slspec=epi_slspec.txt --slm=none - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - mporder: '6' - # type=int|default=0: Order of slice-to-vol movement model - slice2vol_niter: '5' - # type=int|default=0: Number of iterations for slice-to-vol - slice2vol_lambda: '1' - # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) - slice2vol_interp: '"trilinear"' - # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step - slice_order: '"epi_slspec.txt"' - # type=file|default='': Name of text file completely specifying slice/group acquisition - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: eddy_openmp --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + in_file: '"epi.nii"' + # type=file|default=: File containing all the images to estimate distortions for + in_index: '"epi_index.txt"' + # type=file|default=: File containing indices for all volumes in --imain into --acqp and --topup + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --slm=none + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + use_cuda: "True" + # type=bool|default=False: Run eddy using cuda gpu + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: eddy_cuda --flm=quadratic --ff=10.0 --acqp=epi_acqp.txt --bvals=bvals.scheme --bvecs=bvecs.scheme --imain=epi.nii --index=epi_index.txt --mask=epi_mask.nii --interp=spline --resamp=jac --mporder=6 --niter=5 --nvoxhp=1000 --out=.../eddy_corrected --s2v_interp=trilinear --s2v_lambda=1 --s2v_niter=5 --slspec=epi_slspec.txt --slm=none + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + mporder: "6" + # type=int|default=0: Order of slice-to-vol movement model + slice2vol_niter: "5" + # type=int|default=0: Number of iterations for slice-to-vol + slice2vol_lambda: "1" + # type=int|default=0: Regularisation weight for slice-to-vol movement (reasonable range 1-10) + slice2vol_interp: '"trilinear"' + # type=enum|default='trilinear'|allowed['spline','trilinear']: Slice-to-vol interpolation model for estimation step + slice_order: '"epi_slspec.txt"' + # type=file|default='': Name of text file completely specifying slice/group acquisition + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/eddy_quad.yaml b/nipype-auto-conv/specs/eddy_quad.yaml index 916b9fd..a90ca6e 100644 --- a/nipype-auto-conv/specs/eddy_quad.yaml +++ b/nipype-auto-conv/specs/eddy_quad.yaml @@ -5,14 +5,14 @@ # # Docs # ---- -# +# # Interface for FSL eddy_quad, a tool for generating single subject reports # and storing the quality assessment indices for each subject. # `User guide `__ -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import EddyQuad # >>> quad = EddyQuad() # >>> quad.inputs.base_name = 'eddy_corrected' @@ -27,8 +27,8 @@ # >>> quad.cmdline # 'eddy_quad eddy_corrected --bvals bvals.scheme --bvecs bvecs.scheme --field fieldmap_phase_fslprepared.nii --eddyIdx epi_index.txt --mask epi_mask.nii --output-dir eddy_corrected.qc --eddyParams epi_acqp.txt --verbose' # >>> res = quad.run() # doctest: +SKIP -# -# +# +# task_name: EddyQuad nipype_name: EddyQuad nipype_module: nipype.interfaces.fsl.epi @@ -38,14 +38,14 @@ inputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. - bval_file: generic/file + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. + bval_file: medimage/bval # type=file|default=: b-values file - bvec_file: generic/file + bvec_file: medimage/bvec # type=file|default=: b-vectors file - only used when .eddy_residuals file is present field: generic/file # type=file|default=: TOPUP estimated field (in Hz) @@ -68,11 +68,11 @@ outputs: rename: # dict[str, str] - fields to rename in the Pydra interface types: - # dict[str, type] - override inferred types (use "mime-like" string for file-format types, - # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred - # from the nipype interface, but you may want to be more specific, particularly - # for file types, where specifying the format also specifies the file that will be - # passed to the field in the automatically generated unittests. + # dict[str, type] - override inferred types (use "mime-like" string for file-format types, + # e.g. 'medimage/nifti-gz'). For most fields the type will be correctly inferred + # from the nipype interface, but you may want to be more specific, particularly + # for file types, where specifying the format also specifies the file that will be + # passed to the field in the automatically generated unittests. avg_b0_pe_png: generic/file+list-of # type=list: Image showing mid-sagittal, -coronal and -axial slices of each averaged pe-direction b0 volume. Generated when using the -f option. avg_b_png: generic/file+list-of @@ -97,85 +97,85 @@ outputs: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - base_name: - # type=str|default='eddy_corrected': Basename (including path) for EDDY output files, i.e., corrected images and QC files - idx_file: - # type=file|default=: File containing indices for all volumes into acquisition parameters - param_file: - # type=file|default=: File containing acquisition parameters - mask_file: - # type=file|default=: Binary mask file - bval_file: - # type=file|default=: b-values file - bvec_file: - # type=file|default=: b-vectors file - only used when .eddy_residuals file is present - output_dir: - # type=str|default='': Output directory - default = '.qc' - field: - # type=file|default=: TOPUP estimated field (in Hz) - slice_spec: - # type=file|default=: Text file specifying slice/group acquisition - verbose: - # type=bool|default=False: Display debug messages - output_type: - # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type - args: - # type=str|default='': Additional parameters to the command - environ: - # type=dict|default={}: Environment variables - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file -- inputs: - # dict[str, str] - values to provide to inputs fields in the task initialisation - # (if not specified, will try to choose a sensible value) - param_file: - # type=file|default=: File containing acquisition parameters - output_dir: '"eddy_corrected.qc"' - # type=str|default='': Output directory - default = '.qc' - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - expected_outputs: - # dict[str, str] - expected values for selected outputs, noting that tests will typically - # be terminated before they complete for time-saving reasons, and therefore - # these values will be ignored, when running in CI - timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised - # successfully. Set to 0 to disable the timeout (warning, this could - # lead to the unittests taking a very long time to complete) - xfail: true - # bool - whether the unittest is expected to fail or not. Set to false - # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + base_name: + # type=str|default='eddy_corrected': Basename (including path) for EDDY output files, i.e., corrected images and QC files + idx_file: + # type=file|default=: File containing indices for all volumes into acquisition parameters + param_file: + # type=file|default=: File containing acquisition parameters + mask_file: + # type=file|default=: Binary mask file + bval_file: + # type=file|default=: b-values file + bvec_file: + # type=file|default=: b-vectors file - only used when .eddy_residuals file is present + output_dir: + # type=str|default='': Output directory - default = '.qc' + field: + # type=file|default=: TOPUP estimated field (in Hz) + slice_spec: + # type=file|default=: Text file specifying slice/group acquisition + verbose: + # type=bool|default=False: Display debug messages + output_type: + # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type + args: + # type=str|default='': Additional parameters to the command + environ: + # type=dict|default={}: Environment variables + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file + - inputs: + # dict[str, str] - values to provide to inputs fields in the task initialisation + # (if not specified, will try to choose a sensible value) + param_file: + # type=file|default=: File containing acquisition parameters + output_dir: '"eddy_corrected.qc"' + # type=str|default='': Output directory - default = '.qc' + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + expected_outputs: + # dict[str, str] - expected values for selected outputs, noting that tests will typically + # be terminated before they complete for time-saving reasons, and therefore + # these values will be ignored, when running in CI + timeout: 10 + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised + # successfully. Set to 0 to disable the timeout (warning, this could + # lead to the unittests taking a very long time to complete) + xfail: true + # bool - whether the unittest is expected to fail or not. Set to false + # when you are satisfied with the edits you have made to this file doctests: -- cmdline: eddy_quad eddy_corrected --bvals bvals.scheme --bvecs bvecs.scheme --field fieldmap_phase_fslprepared.nii --eddyIdx epi_index.txt --mask epi_mask.nii --output-dir eddy_corrected.qc --eddyParams epi_acqp.txt --verbose - # str - the expected cmdline output - inputs: - # dict[str, str] - name-value pairs for inputs to be provided to the doctest. - # If the field is of file-format type and the value is None, then the - # '.mock()' method of the corresponding class is used instead. - param_file: '"epi_acqp.txt"' - # type=file|default=: File containing acquisition parameters - output_dir: '"eddy_corrected.qc"' - # type=str|default='': Output directory - default = '.qc' - imports: - # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item - # consisting of 'module', 'name', and optionally 'alias' keys - directive: - # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS + - cmdline: eddy_quad eddy_corrected --bvals bvals.scheme --bvecs bvecs.scheme --field fieldmap_phase_fslprepared.nii --eddyIdx epi_index.txt --mask epi_mask.nii --output-dir eddy_corrected.qc --eddyParams epi_acqp.txt --verbose + # str - the expected cmdline output + inputs: + # dict[str, str] - name-value pairs for inputs to be provided to the doctest. + # If the field is of file-format type and the value is None, then the + # '.mock()' method of the corresponding class is used instead. + param_file: '"epi_acqp.txt"' + # type=file|default=: File containing acquisition parameters + output_dir: '"eddy_corrected.qc"' + # type=str|default='': Output directory - default = '.qc' + imports: + # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item + # consisting of 'module', 'name', and optionally 'alias' keys + directive: + # str - any doctest directive to place on the cmdline call, e.g. # doctest: +ELLIPSIS diff --git a/nipype-auto-conv/specs/topup.yaml b/nipype-auto-conv/specs/topup.yaml index c5277ee..cd2b5cb 100644 --- a/nipype-auto-conv/specs/topup.yaml +++ b/nipype-auto-conv/specs/topup.yaml @@ -56,10 +56,23 @@ inputs: # type=file: name of image file with field (Hz) out_logfile: Path # type=file: name of log-file + # type=file|default=: name of log-file + warp_res: typing.List[float] + subsamp: typing.List[int] + fwhm: typing.List[float] + reg_lambda: typing.List[float] + regmod: str + estmov: typing.List[int] + minmet: typing.List[int] + splineorder: int + interp: str + scale: bool callable_defaults: - # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` - # to set as the `default` method of input fields + # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` + # to set as the `default` method of input fields metadata: + scale: + argstr: "--scale {int(scale)}" # dict[str, dict[str, any]] - additional metadata to set on any of the input fields (e.g. out_file: position: 1) outputs: omit: From fedc15440747522a0bd502633792f4d5ff5859f0 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 15:32:17 +1100 Subject: [PATCH 010/224] updated actions versions --- .github/workflows/ci-cd.yaml | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index d1dc4fd..99c03e3 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -21,12 +21,12 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 - name: Install build dependencies run: python -m pip install --upgrade pip - name: Install requirements @@ -50,7 +50,7 @@ jobs: - '--editable git+https://github.com/nipype/pydra.git#egg=pydra' steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') @@ -63,7 +63,7 @@ jobs: run: | sed -i '/\/pydra\/tasks\/fsl\/auto/d' .gitignore - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install build dependencies @@ -90,12 +90,12 @@ jobs: matrix: python-version: ['3.8', '3.11'] steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install build dependencies @@ -149,7 +149,7 @@ jobs: source $FREESURFER_HOME/SetUpFreeSurfer.sh echo $FREESURFER_LICENCE > $FREESURFER_HOME/license.txt export PATH=$FREESURFER_HOME/bin:$PATH - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') @@ -162,7 +162,7 @@ jobs: run: | sed -i '/\/src\/pydra\/tasks\/fsl\/auto/d' .gitignore - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install build dependencies @@ -187,12 +187,12 @@ jobs: needs: [devcheck, test] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install build tools @@ -219,12 +219,12 @@ jobs: needs: [deploy-fileformats] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install build tools @@ -251,7 +251,7 @@ jobs: needs: [deploy-fileformats-extras] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 @@ -270,7 +270,7 @@ jobs: git commit -am"added auto-generated version to make new tag for package version" git tag ${TAG}post${POST} - name: Set up Python - uses: actions/setup-python@v4 + uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install build tools From bd9b5a69ead53db16ce57fda8d9069866774a954 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Fri, 22 Mar 2024 04:37:43 +0000 Subject: [PATCH 011/224] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .github/workflows/ci-cd.yaml | 28 ++-- README.rst | 6 +- nipype-auto-conv/requirements.txt | 2 +- nipype-auto-conv/specs/apply_topup.yaml | 20 +-- nipype-auto-conv/specs/apply_xfm.yaml | 16 +-- nipype-auto-conv/specs/ar1_image.yaml | 8 +- nipype-auto-conv/specs/av_scale.yaml | 16 +-- nipype-auto-conv/specs/b0_calc.yaml | 18 +-- nipype-auto-conv/specs/bet.yaml | 16 +-- nipype-auto-conv/specs/bet_callables.py | 22 +-- nipype-auto-conv/specs/binary_maths.yaml | 8 +- nipype-auto-conv/specs/change_data_type.yaml | 4 +- nipype-auto-conv/specs/classifier.yaml | 8 +- nipype-auto-conv/specs/cleaner.yaml | 8 +- nipype-auto-conv/specs/complex.yaml | 134 +++++++++--------- nipype-auto-conv/specs/contrast_mgr.yaml | 8 +- nipype-auto-conv/specs/convert_warp.yaml | 20 +-- nipype-auto-conv/specs/convert_xfm.yaml | 18 +-- nipype-auto-conv/specs/copy_geom.yaml | 6 +- nipype-auto-conv/specs/dilate_image.yaml | 4 +- nipype-auto-conv/specs/distance_map.yaml | 12 +- nipype-auto-conv/specs/dti_fit.yaml | 16 +-- nipype-auto-conv/specs/dual_regression.yaml | 28 ++-- nipype-auto-conv/specs/eddy_callables.py | 6 +- nipype-auto-conv/specs/eddy_correct.yaml | 20 +-- nipype-auto-conv/specs/epi_de_warp.yaml | 22 +-- nipype-auto-conv/specs/epi_reg.yaml | 20 +-- nipype-auto-conv/specs/erode_image.yaml | 4 +- nipype-auto-conv/specs/extract_roi.yaml | 58 ++++---- nipype-auto-conv/specs/fast.yaml | 28 ++-- nipype-auto-conv/specs/fast_callables.py | 20 +-- nipype-auto-conv/specs/feat.yaml | 6 +- nipype-auto-conv/specs/feat_model.yaml | 4 +- nipype-auto-conv/specs/feature_extractor.yaml | 8 +- nipype-auto-conv/specs/filmgls.yaml | 22 +-- nipype-auto-conv/specs/filter_regressor.yaml | 8 +- nipype-auto-conv/specs/find_the_biggest.yaml | 18 +-- nipype-auto-conv/specs/first.yaml | 14 +- nipype-auto-conv/specs/flameo.yaml | 22 +-- nipype-auto-conv/specs/flirt.yaml | 18 +-- nipype-auto-conv/specs/fnirt.yaml | 28 ++-- nipype-auto-conv/specs/fugue.yaml | 50 +++---- nipype-auto-conv/specs/glm.yaml | 16 +-- nipype-auto-conv/specs/ica__aroma.yaml | 20 +-- nipype-auto-conv/specs/image_maths.yaml | 56 ++++---- nipype-auto-conv/specs/image_meants.yaml | 8 +- nipype-auto-conv/specs/image_stats.yaml | 20 +-- nipype-auto-conv/specs/inv_warp.yaml | 22 +-- nipype-auto-conv/specs/isotropic_smooth.yaml | 4 +- nipype-auto-conv/specs/l2_model.yaml | 12 +- nipype-auto-conv/specs/level_1_design.yaml | 12 +- .../specs/make_dyadic_vectors.yaml | 24 ++-- nipype-auto-conv/specs/maths_command.yaml | 6 +- nipype-auto-conv/specs/max_image.yaml | 14 +- nipype-auto-conv/specs/maxn_image.yaml | 8 +- nipype-auto-conv/specs/mcflirt.yaml | 16 +-- nipype-auto-conv/specs/mean_image.yaml | 4 +- nipype-auto-conv/specs/median_image.yaml | 4 +- nipype-auto-conv/specs/melodic.yaml | 28 ++-- nipype-auto-conv/specs/merge.yaml | 42 +++--- nipype-auto-conv/specs/min_image.yaml | 4 +- nipype-auto-conv/specs/motion_outliers.yaml | 30 ++-- nipype-auto-conv/specs/multi_image_maths.yaml | 14 +- .../specs/multiple_regress_design.yaml | 16 +-- nipype-auto-conv/specs/overlay.yaml | 16 +-- nipype-auto-conv/specs/percentile_image.yaml | 14 +- .../specs/plot_motion_params.yaml | 20 +-- nipype-auto-conv/specs/plot_time_series.yaml | 14 +- nipype-auto-conv/specs/power_spectrum.yaml | 14 +- nipype-auto-conv/specs/prelude.yaml | 12 +- nipype-auto-conv/specs/prepare_fieldmap.yaml | 24 ++-- nipype-auto-conv/specs/prob_track_x.yaml | 40 +++--- nipype-auto-conv/specs/prob_track_x2.yaml | 38 ++--- nipype-auto-conv/specs/proj_thresh.yaml | 16 +-- nipype-auto-conv/specs/randomise.yaml | 14 +- nipype-auto-conv/specs/reorient_2_std.yaml | 36 ++--- nipype-auto-conv/specs/robust_fov.yaml | 8 +- nipype-auto-conv/specs/sig_loss.yaml | 14 +- nipype-auto-conv/specs/slice.yaml | 22 +-- nipype-auto-conv/specs/slice_timer.yaml | 10 +- nipype-auto-conv/specs/slicer.yaml | 16 +-- nipype-auto-conv/specs/smooth.yaml | 64 ++++----- nipype-auto-conv/specs/smooth_estimate.yaml | 16 +-- nipype-auto-conv/specs/spatial_filter.yaml | 4 +- nipype-auto-conv/specs/split.yaml | 8 +- nipype-auto-conv/specs/std_image.yaml | 6 +- nipype-auto-conv/specs/susan.yaml | 12 +- nipype-auto-conv/specs/swap_dimensions.yaml | 10 +- nipype-auto-conv/specs/temporal_filter.yaml | 8 +- nipype-auto-conv/specs/text_2_vest.yaml | 14 +- nipype-auto-conv/specs/threshold.yaml | 4 +- nipype-auto-conv/specs/tract_skeleton.yaml | 14 +- nipype-auto-conv/specs/training.yaml | 8 +- .../specs/training_set_creator.yaml | 10 +- nipype-auto-conv/specs/unary_maths.yaml | 4 +- nipype-auto-conv/specs/vec_reg.yaml | 16 +-- nipype-auto-conv/specs/vest_2_text.yaml | 14 +- nipype-auto-conv/specs/warp_points.yaml | 22 +-- .../specs/warp_points_from_std.yaml | 22 +-- .../specs/warp_points_to_std.yaml | 24 ++-- nipype-auto-conv/specs/warp_utils.yaml | 20 +-- .../extras/medimage_fsl/__init__.py | 1 - .../tests/test_generate_sample_data.py | 1 - tools/requirements.txt | 2 +- 104 files changed, 906 insertions(+), 908 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index 99c03e3..6e93b4e 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -24,7 +24,7 @@ jobs: uses: actions/checkout@v4 - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' - run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 - name: Install build dependencies @@ -53,8 +53,8 @@ jobs: uses: actions/checkout@v4 - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' - run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - - name: Download tasks converted from Nipype + run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 with: name: converted-nipype @@ -83,7 +83,7 @@ jobs: python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import fileformats.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import fileformats.extras.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - + fileformats-test: runs-on: ubuntu-latest strategy: @@ -120,7 +120,7 @@ jobs: - name: Removed unnecessary tools to free space run: | sudo rm -rf /usr/share/dotnet - sudo rm -rf "$AGENT_TOOLSDIRECTORY" + sudo rm -rf "$AGENT_TOOLSDIRECTORY" - name: Get Download cache Key id: cache-key run: echo "::set-output name=key::fsl-linux-ubuntu22_amd64-7.4.1" @@ -153,7 +153,7 @@ jobs: - name: Revert version to most recent tag on upstream update if: github.event_name == 'repository_dispatch' run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - - name: Download tasks converted from Nipype + - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 with: name: converted-nipype @@ -190,7 +190,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - fetch-depth: 0 + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: @@ -213,7 +213,7 @@ jobs: with: user: __token__ password: ${{ secrets.PYPI_FILEFORMATS_API_TOKEN }} - packages-dir: ./related-packages/fileformats/dist + packages-dir: ./related-packages/fileformats/dist deploy-fileformats-extras: needs: [deploy-fileformats] @@ -222,7 +222,7 @@ jobs: - uses: actions/checkout@v4 with: submodules: recursive - fetch-depth: 0 + fetch-depth: 0 - name: Set up Python uses: actions/setup-python@v5 with: @@ -245,7 +245,7 @@ jobs: with: user: __token__ password: ${{ secrets.PYPI_FILEFORMATS_EXTRAS_API_TOKEN }} - packages-dir: ./related-packages/fileformats-extras/dist + packages-dir: ./related-packages/fileformats-extras/dist deploy: needs: [deploy-fileformats-extras] @@ -255,7 +255,7 @@ jobs: with: submodules: recursive fetch-depth: 0 - - name: Download tasks converted from Nipype + - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 with: name: converted-nipype @@ -268,7 +268,7 @@ jobs: git checkout $TAG git add -f pydra/tasks/fsl/auto/_version.py git commit -am"added auto-generated version to make new tag for package version" - git tag ${TAG}post${POST} + git tag ${TAG}post${POST} - name: Set up Python uses: actions/setup-python@v5 with: @@ -297,9 +297,9 @@ jobs: uses: pypa/gh-action-pypi-publish@release/v1 with: user: __token__ - password: ${{ secrets.PYPI_API_TOKEN }} + password: ${{ secrets.PYPI_API_TOKEN }} # Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. # Secrets are not accessible in the if: condition [0], so set an output variable [1] # [0] https://github.community/t/16928 -# [1] https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter \ No newline at end of file +# [1] https://docs.github.com/en/actions/reference/workflow-commands-for-github-actions#setting-an-output-parameter diff --git a/README.rst b/README.rst index 578d9ec..ed18628 100644 --- a/README.rst +++ b/README.rst @@ -19,7 +19,7 @@ This repository aims to be the canonical set of Pydra tasks for incorporating Part of this effort is to establish a (mostly) declarative language for describing tasks that potentially have intricate rules for determining the availability and names from the choice of -inputs. +inputs. Automatically-generated vs manually-curated tasks @@ -29,7 +29,7 @@ Automatically generated tasks can be found in the `pydra.tasks.fsl.auto` package These packages should be treated with extreme caution as they likely do not pass testing. Generated tasks that have been edited and pass testing are imported into one or more of the `pydra.tasks.fsl.v*` packages, corresponding to the version of the fsl toolkit -they are designed for. +they are designed for. Tests ----- @@ -160,7 +160,7 @@ in the ``inputs > types`` and ``outputs > types`` dicts of the YAML spec. If the required file-type is not found implemented within fileformats, please see the `fileformats docs `__ for instructions on how to define -new fileformat types, and see +new fileformat types, and see `fileformats-medimage-extras `__ for an example on how to implement methods to generate sample data for them. diff --git a/nipype-auto-conv/requirements.txt b/nipype-auto-conv/requirements.txt index 9858b15..cb69c8a 100644 --- a/nipype-auto-conv/requirements.txt +++ b/nipype-auto-conv/requirements.txt @@ -9,4 +9,4 @@ fileformats-medimage >=0.4 fileformats-datascience >= 0.1 fileformats-medimage-fsl traits -nipype2pydra \ No newline at end of file +nipype2pydra diff --git a/nipype-auto-conv/specs/apply_topup.yaml b/nipype-auto-conv/specs/apply_topup.yaml index 07ed94f..e74a9e4 100644 --- a/nipype-auto-conv/specs/apply_topup.yaml +++ b/nipype-auto-conv/specs/apply_topup.yaml @@ -5,18 +5,18 @@ # # Docs # ---- -# +# # Interface for FSL topup, a tool for estimating and correcting # susceptibility induced distortions. # `General reference # `_ # and `use example # `_. -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import ApplyTOPUP # >>> applytopup = ApplyTOPUP() # >>> applytopup.inputs.in_files = ["epi.nii", "epi_rev.nii"] @@ -27,8 +27,8 @@ # >>> applytopup.cmdline # doctest: +ELLIPSIS # 'applytopup --datain=topup_encoding.txt --imain=epi.nii,epi_rev.nii --inindex=1,2 --topup=topup --out=epi_corrected.nii.gz' # >>> res = applytopup.run() # doctest: +SKIP -# -# +# +# task_name: ApplyTOPUP nipype_name: ApplyTOPUP nipype_module: nipype.interfaces.fsl.epi @@ -117,8 +117,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -145,8 +145,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/apply_xfm.yaml b/nipype-auto-conv/specs/apply_xfm.yaml index ae9ca24..2504b98 100644 --- a/nipype-auto-conv/specs/apply_xfm.yaml +++ b/nipype-auto-conv/specs/apply_xfm.yaml @@ -7,13 +7,13 @@ # ---- # Currently just a light wrapper around FLIRT, # with no modifications -# +# # ApplyXFM is used to apply an existing transform to an image -# -# +# +# # Examples # -------- -# +# # >>> import nipype.interfaces.fsl as fsl # >>> from nipype.testing import example_data # >>> applyxfm = fsl.preprocess.ApplyXFM() @@ -23,8 +23,8 @@ # >>> applyxfm.inputs.reference = example_data('mni.nii') # >>> applyxfm.inputs.apply_xfm = True # >>> result = applyxfm.run() # doctest: +SKIP -# -# +# +# task_name: ApplyXFM nipype_name: ApplyXFM nipype_module: nipype.interfaces.fsl.preprocess @@ -217,8 +217,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/ar1_image.yaml b/nipype-auto-conv/specs/ar1_image.yaml index 33491e2..4cca722 100644 --- a/nipype-auto-conv/specs/ar1_image.yaml +++ b/nipype-auto-conv/specs/ar1_image.yaml @@ -7,8 +7,8 @@ # ---- # Use fslmaths to generate an AR1 coefficient image across a # given dimension. (Should use -odt float and probably demean first) -# -# +# +# task_name: AR1Image nipype_name: AR1Image nipype_module: nipype.interfaces.fsl.maths @@ -88,8 +88,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/av_scale.yaml b/nipype-auto-conv/specs/av_scale.yaml index ca20362..02fe620 100644 --- a/nipype-auto-conv/specs/av_scale.yaml +++ b/nipype-auto-conv/specs/av_scale.yaml @@ -6,16 +6,16 @@ # Docs # ---- # Use FSL avscale command to extract info from mat file output of FLIRT -# +# # Examples # -------- -# +# # >>> avscale = AvScale() # >>> avscale.inputs.mat_file = 'flirt.mat' # >>> res = avscale.run() # doctest: +SKIP -# -# -# +# +# +# task_name: AvScale nipype_name: AvScale nipype_module: nipype.interfaces.fsl.utils @@ -68,7 +68,7 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) all_param: - # type=bool|default=False: + # type=bool|default=False: mat_file: # type=file|default=: mat file to read ref_file: @@ -85,8 +85,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/b0_calc.yaml b/nipype-auto-conv/specs/b0_calc.yaml index a277b11..edd6ef7 100644 --- a/nipype-auto-conv/specs/b0_calc.yaml +++ b/nipype-auto-conv/specs/b0_calc.yaml @@ -5,15 +5,15 @@ # # Docs # ---- -# +# # B0 inhomogeneities occur at interfaces of materials with different magnetic susceptibilities, # such as tissue-air interfaces. These differences lead to distortion in the local magnetic field, # as Maxwell’s equations need to be satisfied. An example of B0 inhomogneity is the first volume # of the 4D volume ```$FSLDIR/data/possum/b0_ppm.nii.gz```. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import B0Calc # >>> b0calc = B0Calc() # >>> b0calc.inputs.in_file = 'tissue+air_map.nii' @@ -21,8 +21,8 @@ # >>> b0calc.inputs.output_type = "NIFTI_GZ" # >>> b0calc.cmdline # 'b0calc -i tissue+air_map.nii -o tissue+air_map_b0field.nii.gz --chi0=4.000000e-07 -d -9.450000e-06 --extendboundary=1.00 --b0x=0.00 --gx=0.0000 --b0y=0.00 --gy=0.0000 --b0=3.00 --gz=0.0000' -# -# +# +# task_name: B0Calc nipype_name: B0Calc nipype_module: nipype.interfaces.fsl.possum @@ -115,8 +115,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -139,8 +139,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/bet.yaml b/nipype-auto-conv/specs/bet.yaml index 9067cd2..40c9a43 100644 --- a/nipype-auto-conv/specs/bet.yaml +++ b/nipype-auto-conv/specs/bet.yaml @@ -6,10 +6,10 @@ # Docs # ---- # FSL BET wrapper for skull stripping -# +# # For complete details, see the `BET Documentation. # `_ -# +# # Examples # -------- # >>> from nipype.interfaces import fsl @@ -20,8 +20,8 @@ # >>> btr.cmdline # 'bet structural.nii brain_anat.nii -f 0.70' # >>> res = btr.run() # doctest: +SKIP -# -# +# +# task_name: BET nipype_name: BET nipype_module: nipype.interfaces.fsl.preprocess @@ -151,8 +151,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -176,8 +176,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/bet_callables.py b/nipype-auto-conv/specs/bet_callables.py index 6163733..1e2b1c3 100644 --- a/nipype-auto-conv/specs/bet_callables.py +++ b/nipype-auto-conv/specs/bet_callables.py @@ -206,7 +206,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if ((inputs.mask is not attrs.NOTHING) and inputs.mask) or ( (inputs.reduce_bias is not attrs.NOTHING) and inputs.reduce_bias @@ -217,7 +217,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if (inputs.outline is not attrs.NOTHING) and inputs.outline: outputs["outline_file"] = _gen_fname( @@ -226,7 +226,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if (inputs.surfaces is not attrs.NOTHING) and inputs.surfaces: outputs["inskull_mask_file"] = _gen_fname( @@ -235,7 +235,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["inskull_mesh_file"] = _gen_fname( suffix="_inskull_mesh", @@ -243,7 +243,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["outskull_mask_file"] = _gen_fname( suffix="_outskull_mask", @@ -251,7 +251,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["outskull_mesh_file"] = _gen_fname( suffix="_outskull_mesh", @@ -259,7 +259,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["outskin_mask_file"] = _gen_fname( suffix="_outskin_mask", @@ -267,7 +267,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["outskin_mesh_file"] = _gen_fname( suffix="_outskin_mesh", @@ -275,7 +275,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["skull_mask_file"] = _gen_fname( suffix="_skull_mask", @@ -283,7 +283,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if (inputs.skull is not attrs.NOTHING) and inputs.skull: outputs["skull_file"] = _gen_fname( @@ -292,7 +292,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if (inputs.no_output is not attrs.NOTHING) and inputs.no_output: outputs["out_file"] = attrs.NOTHING diff --git a/nipype-auto-conv/specs/binary_maths.yaml b/nipype-auto-conv/specs/binary_maths.yaml index bd135d3..3c32248 100644 --- a/nipype-auto-conv/specs/binary_maths.yaml +++ b/nipype-auto-conv/specs/binary_maths.yaml @@ -7,8 +7,8 @@ # ---- # Use fslmaths to perform mathematical operations using a second image or # a numeric value. -# -# +# +# task_name: BinaryMaths nipype_name: BinaryMaths nipype_module: nipype.interfaces.fsl.maths @@ -94,8 +94,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/change_data_type.yaml b/nipype-auto-conv/specs/change_data_type.yaml index e1c6460..2206fa7 100644 --- a/nipype-auto-conv/specs/change_data_type.yaml +++ b/nipype-auto-conv/specs/change_data_type.yaml @@ -83,8 +83,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/classifier.yaml b/nipype-auto-conv/specs/classifier.yaml index 2b42cb0..99a202a 100644 --- a/nipype-auto-conv/specs/classifier.yaml +++ b/nipype-auto-conv/specs/classifier.yaml @@ -5,9 +5,9 @@ # # Docs # ---- -# +# # Classify ICA components using a specific training dataset ( is in the range 0-100, typically 5-20). -# +# task_name: Classifier nipype_name: Classifier nipype_module: nipype.interfaces.fsl.fix @@ -80,8 +80,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/cleaner.yaml b/nipype-auto-conv/specs/cleaner.yaml index 6be0935..f316007 100644 --- a/nipype-auto-conv/specs/cleaner.yaml +++ b/nipype-auto-conv/specs/cleaner.yaml @@ -5,9 +5,9 @@ # # Docs # ---- -# +# # Extract features (for later training and/or classifying) -# +# task_name: Cleaner nipype_name: Cleaner nipype_module: nipype.interfaces.fsl.fix @@ -85,8 +85,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/complex.yaml b/nipype-auto-conv/specs/complex.yaml index 1910446..b612ec1 100644 --- a/nipype-auto-conv/specs/complex.yaml +++ b/nipype-auto-conv/specs/complex.yaml @@ -6,17 +6,17 @@ # Docs # ---- # fslcomplex is a tool for converting complex data -# +# # Examples # -------- -# +# # >>> cplx = Complex() # >>> cplx.inputs.complex_in_file = "complex.nii" # >>> cplx.real_polar = True # >>> res = cplx.run() # doctest: +SKIP -# -# -# +# +# +# task_name: Complex nipype_name: Complex nipype_module: nipype.interfaces.fsl.utils @@ -32,32 +32,32 @@ inputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. complex_in_file: generic/file - # type=file|default=: + # type=file|default=: complex_in_file2: generic/file - # type=file|default=: + # type=file|default=: complex_out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: imaginary_in_file: generic/file - # type=file|default=: + # type=file|default=: imaginary_out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: magnitude_in_file: generic/file - # type=file|default=: + # type=file|default=: magnitude_out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: phase_in_file: generic/file - # type=file|default=: + # type=file|default=: phase_out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: real_in_file: generic/file - # type=file|default=: + # type=file|default=: real_out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -75,40 +75,40 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. complex_out_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: imaginary_out_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: magnitude_out_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: phase_out_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: real_out_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields complex_out_file: complex_out_file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: imaginary_out_file: imaginary_out_file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: magnitude_out_file: magnitude_out_file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: phase_out_file: phase_out_file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: real_out_file: real_out_file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -116,48 +116,48 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) complex_in_file: - # type=file|default=: + # type=file|default=: complex_in_file2: - # type=file|default=: + # type=file|default=: real_in_file: - # type=file|default=: + # type=file|default=: imaginary_in_file: - # type=file|default=: + # type=file|default=: magnitude_in_file: - # type=file|default=: + # type=file|default=: phase_in_file: - # type=file|default=: + # type=file|default=: complex_out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: magnitude_out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: phase_out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: real_out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: imaginary_out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: start_vol: - # type=int|default=0: + # type=int|default=0: end_vol: - # type=int|default=0: + # type=int|default=0: real_polar: - # type=bool|default=False: + # type=bool|default=False: real_cartesian: - # type=bool|default=False: + # type=bool|default=False: complex_cartesian: - # type=bool|default=False: + # type=bool|default=False: complex_polar: - # type=bool|default=False: + # type=bool|default=False: complex_split: - # type=bool|default=False: + # type=bool|default=False: complex_merge: - # type=bool|default=False: + # type=bool|default=False: output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type args: @@ -172,8 +172,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/contrast_mgr.yaml b/nipype-auto-conv/specs/contrast_mgr.yaml index a3f5071..4d5e94d 100644 --- a/nipype-auto-conv/specs/contrast_mgr.yaml +++ b/nipype-auto-conv/specs/contrast_mgr.yaml @@ -6,11 +6,11 @@ # Docs # ---- # Use FSL contrast_mgr command to evaluate contrasts -# +# # In interface mode this file assumes that all the required inputs are in the # same location. This has deprecated for FSL versions 5.0.7+ as the necessary # corrections file is no longer generated by FILMGLS. -# +# task_name: ContrastMgr nipype_name: ContrastMgr nipype_module: nipype.interfaces.fsl.model @@ -108,8 +108,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/convert_warp.yaml b/nipype-auto-conv/specs/convert_warp.yaml index e4d553f..9a3fcfe 100644 --- a/nipype-auto-conv/specs/convert_warp.yaml +++ b/nipype-auto-conv/specs/convert_warp.yaml @@ -7,11 +7,11 @@ # ---- # Use FSL `convertwarp `_ # for combining multiple transforms into one. -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import ConvertWarp # >>> warputils = ConvertWarp() # >>> warputils.inputs.warp1 = "warpfield.nii" @@ -21,9 +21,9 @@ # >>> warputils.cmdline # doctest: +ELLIPSIS # 'convertwarp --ref=T1.nii --rel --warp1=warpfield.nii --out=T1_concatwarp.nii.gz' # >>> res = warputils.run() # doctest: +SKIP -# -# -# +# +# +# task_name: ConvertWarp nipype_name: ConvertWarp nipype_module: nipype.interfaces.fsl.utils @@ -132,8 +132,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -158,8 +158,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/convert_xfm.yaml b/nipype-auto-conv/specs/convert_xfm.yaml index 6cc22d8..1348dc2 100644 --- a/nipype-auto-conv/specs/convert_xfm.yaml +++ b/nipype-auto-conv/specs/convert_xfm.yaml @@ -6,10 +6,10 @@ # Docs # ---- # Use the FSL utility convert_xfm to modify FLIRT transformation matrices. -# +# # Examples # -------- -# +# # >>> import nipype.interfaces.fsl as fsl # >>> invt = fsl.ConvertXFM() # >>> invt.inputs.in_file = "flirt.mat" @@ -17,9 +17,9 @@ # >>> invt.inputs.out_file = 'flirt_inv.mat' # >>> invt.cmdline # 'convert_xfm -omat flirt_inv.mat -inverse flirt.mat' -# -# -# +# +# +# task_name: ConvertXFM nipype_name: ConvertXFM nipype_module: nipype.interfaces.fsl.utils @@ -101,8 +101,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -127,8 +127,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/copy_geom.yaml b/nipype-auto-conv/specs/copy_geom.yaml index 677859c..296945d 100644 --- a/nipype-auto-conv/specs/copy_geom.yaml +++ b/nipype-auto-conv/specs/copy_geom.yaml @@ -12,7 +12,7 @@ # Analyze to Analyze or Nifti to Nifti will work properly. Copying from # different files will result in loss of information or potentially incorrect # settings. -# +# task_name: CopyGeom nipype_name: CopyGeom nipype_module: nipype.interfaces.fsl.utils @@ -80,8 +80,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/dilate_image.yaml b/nipype-auto-conv/specs/dilate_image.yaml index 5f29bf3..e4b6cc6 100644 --- a/nipype-auto-conv/specs/dilate_image.yaml +++ b/nipype-auto-conv/specs/dilate_image.yaml @@ -93,8 +93,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/distance_map.yaml b/nipype-auto-conv/specs/distance_map.yaml index d027bbd..872a507 100644 --- a/nipype-auto-conv/specs/distance_map.yaml +++ b/nipype-auto-conv/specs/distance_map.yaml @@ -7,16 +7,16 @@ # ---- # Use FSL's distancemap to generate a map of the distance to the nearest # nonzero voxel. -# +# # Example # ------- -# +# # >>> import nipype.interfaces.fsl as fsl # >>> mapper = fsl.DistanceMap() # >>> mapper.inputs.in_file = "skeleton_mask.nii.gz" # >>> mapper.run() # doctest: +SKIP -# -# +# +# task_name: DistanceMap nipype_name: DistanceMap nipype_module: nipype.interfaces.fsl.dti @@ -100,8 +100,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/dti_fit.yaml b/nipype-auto-conv/specs/dti_fit.yaml index 19a0a2e..6a42635 100644 --- a/nipype-auto-conv/specs/dti_fit.yaml +++ b/nipype-auto-conv/specs/dti_fit.yaml @@ -7,10 +7,10 @@ # ---- # Use FSL dtifit command for fitting a diffusion tensor model at each # voxel -# +# # Example # ------- -# +# # >>> from nipype.interfaces import fsl # >>> dti = fsl.DTIFit() # >>> dti.inputs.dwi = 'diffusion.nii' @@ -20,8 +20,8 @@ # >>> dti.inputs.mask = 'mask.nii' # >>> dti.cmdline # 'dtifit -k diffusion.nii -o TP -m mask.nii -r bvecs -b bvals' -# -# +# +# task_name: DTIFit nipype_name: DTIFit nipype_module: nipype.interfaces.fsl.dti @@ -147,8 +147,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -175,8 +175,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/dual_regression.yaml b/nipype-auto-conv/specs/dual_regression.yaml index 06b866e..5d90159 100644 --- a/nipype-auto-conv/specs/dual_regression.yaml +++ b/nipype-auto-conv/specs/dual_regression.yaml @@ -6,10 +6,10 @@ # Docs # ---- # Wrapper Script for Dual Regression Workflow -# +# # Examples # -------- -# +# # >>> dual_regression = DualRegression() # >>> dual_regression.inputs.in_files = ["functional.nii", "functional2.nii", "functional3.nii"] # >>> dual_regression.inputs.group_IC_maps_4D = "allFA.nii" @@ -20,8 +20,8 @@ # >>> dual_regression.cmdline # 'dual_regression allFA.nii 0 -1 10 my_output_directory functional.nii functional2.nii functional3.nii' # >>> dual_regression.run() # doctest: +SKIP -# -# +# +# task_name: DualRegression nipype_name: DualRegression nipype_module: nipype.interfaces.fsl.model @@ -45,7 +45,7 @@ inputs: in_files: medimage/nifti1+list-of # type=inputmultiobject|default=[]: List all subjects' preprocessed, standard-space 4D datasets out_dir: Path - # type=directory: + # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` @@ -64,7 +64,7 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. out_dir: generic/directory - # type=directory: + # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` @@ -72,7 +72,7 @@ outputs: templates: # dict[str, str] - `output_file_template` values to be provided to output fields out_dir: '"my_output_directory"' - # type=directory: + # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present @@ -95,7 +95,7 @@ tests: n_perm: # type=int|default=0: Number of permutations for randomise; set to 1 for just raw tstat output, set to 0 to not run randomise at all. out_dir: - # type=directory: + # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type @@ -111,8 +111,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -132,7 +132,7 @@ tests: n_perm: '10' # type=int|default=0: Number of permutations for randomise; set to 1 for just raw tstat output, set to 0 to not run randomise at all. out_dir: '"my_output_directory"' - # type=directory: + # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles imports: # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item @@ -142,8 +142,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -167,7 +167,7 @@ doctests: n_perm: '10' # type=int|default=0: Number of permutations for randomise; set to 1 for just raw tstat output, set to 0 to not run randomise at all. out_dir: '"my_output_directory"' - # type=directory: + # type=directory: # type=directory|default='output': This directory will be created to hold all output and logfiles imports: # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item diff --git a/nipype-auto-conv/specs/eddy_callables.py b/nipype-auto-conv/specs/eddy_callables.py index 1fc233f..f1e71ba 100644 --- a/nipype-auto-conv/specs/eddy_callables.py +++ b/nipype-auto-conv/specs/eddy_callables.py @@ -170,9 +170,9 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): if os.path.exists(out_shell_alignment_parameters): outputs["out_shell_alignment_parameters"] = out_shell_alignment_parameters if os.path.exists(out_shell_pe_translation_parameters): - outputs["out_shell_pe_translation_parameters"] = ( - out_shell_pe_translation_parameters - ) + outputs[ + "out_shell_pe_translation_parameters" + ] = out_shell_pe_translation_parameters if os.path.exists(out_outlier_map): outputs["out_outlier_map"] = out_outlier_map if os.path.exists(out_outlier_n_stdev_map): diff --git a/nipype-auto-conv/specs/eddy_correct.yaml b/nipype-auto-conv/specs/eddy_correct.yaml index 6094f53..40b9f06 100644 --- a/nipype-auto-conv/specs/eddy_correct.yaml +++ b/nipype-auto-conv/specs/eddy_correct.yaml @@ -5,21 +5,21 @@ # # Docs # ---- -# -# +# +# # .. warning:: Deprecated in FSL. Please use # :class:`nipype.interfaces.fsl.epi.Eddy` instead -# +# # Example # ------- -# +# # >>> from nipype.interfaces.fsl import EddyCorrect # >>> eddyc = EddyCorrect(in_file='diffusion.nii', # ... out_file="diffusion_edc.nii", ref_num=0) # >>> eddyc.cmdline # 'eddy_correct diffusion.nii diffusion_edc.nii 0' -# -# +# +# task_name: EddyCorrect nipype_name: EddyCorrect nipype_module: nipype.interfaces.fsl.epi @@ -87,8 +87,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -111,8 +111,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/epi_de_warp.yaml b/nipype-auto-conv/specs/epi_de_warp.yaml index fd2d31c..55bee74 100644 --- a/nipype-auto-conv/specs/epi_de_warp.yaml +++ b/nipype-auto-conv/specs/epi_de_warp.yaml @@ -5,16 +5,16 @@ # # Docs # ---- -# +# # Wraps the unwarping script `epidewarp.fsl # `_. -# +# # .. warning:: deprecated in FSL, please use # :func:`niflow.nipype1.workflows.dmri.preprocess.epi.sdc_fmb` instead. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import EPIDeWarp # >>> dewarp = EPIDeWarp() # >>> dewarp.inputs.epi_file = "functional.nii" @@ -24,9 +24,9 @@ # >>> dewarp.cmdline # doctest: +ELLIPSIS # 'epidewarp.fsl --mag magnitude.nii --dph phase.nii --epi functional.nii --esp 0.58 --exfdw .../exfdw.nii.gz --nocleanup --sigma 2 --tediff 2.46 --tmpdir .../temp --vsm .../vsm.nii.gz' # >>> res = dewarp.run() # doctest: +SKIP -# -# -# +# +# +# task_name: EPIDeWarp nipype_name: EPIDeWarp nipype_module: nipype.interfaces.fsl.epi @@ -133,8 +133,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -159,8 +159,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/epi_reg.yaml b/nipype-auto-conv/specs/epi_reg.yaml index c187a6a..d20b581 100644 --- a/nipype-auto-conv/specs/epi_reg.yaml +++ b/nipype-auto-conv/specs/epi_reg.yaml @@ -5,14 +5,14 @@ # # Docs # ---- -# -# +# +# # Runs FSL epi_reg script for simultaneous coregistration and fieldmap # unwarping. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import EpiReg # >>> epireg = EpiReg() # >>> epireg.inputs.epi='epi.nii' @@ -27,8 +27,8 @@ # >>> epireg.cmdline # doctest: +ELLIPSIS # 'epi_reg --echospacing=0.000670 --fmap=fieldmap_phase_fslprepared.nii --fmapmag=fieldmap_mag.nii --fmapmagbrain=fieldmap_mag_brain.nii --noclean --pedir=y --epi=epi.nii --t1=T1.nii --t1brain=T1_brain.nii --out=epi2struct' # >>> epireg.run() # doctest: +SKIP -# -# +# +# task_name: EpiReg nipype_name: EpiReg nipype_module: nipype.interfaces.fsl.epi @@ -157,8 +157,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -193,8 +193,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/erode_image.yaml b/nipype-auto-conv/specs/erode_image.yaml index 9bcb725..5ae2aac 100644 --- a/nipype-auto-conv/specs/erode_image.yaml +++ b/nipype-auto-conv/specs/erode_image.yaml @@ -93,8 +93,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/extract_roi.yaml b/nipype-auto-conv/specs/extract_roi.yaml index a58d740..ae4c2c2 100644 --- a/nipype-auto-conv/specs/extract_roi.yaml +++ b/nipype-auto-conv/specs/extract_roi.yaml @@ -7,7 +7,7 @@ # ---- # Uses FSL Fslroi command to extract region of interest (ROI) # from an image. -# +# # You can a) take a 3D ROI from a 3D data set (or if it is 4D, the # same ROI is taken from each time point and a new 4D data set is # created), b) extract just some time points from a 4D data set, or @@ -15,20 +15,20 @@ # arguments are minimum index and size (not maximum index). So to # extract voxels 10 to 12 inclusive you would specify 10 and 3 (not # 10 and 12). -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import ExtractROI # >>> from nipype.testing import anatfile # >>> fslroi = ExtractROI(in_file=anatfile, roi_file='bar.nii', t_min=0, # ... t_size=1) # >>> fslroi.cmdline == 'fslroi %s bar.nii 0 1' % anatfile # True -# -# -# +# +# +# task_name: ExtractROI nipype_name: ExtractROI nipype_module: nipype.interfaces.fsl.utils @@ -46,7 +46,7 @@ inputs: in_file: generic/file # type=file|default=: input file roi_file: Path - # type=file: + # type=file: # type=file|default=: output file callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` @@ -65,7 +65,7 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. roi_file: medimage/nifti1 - # type=file: + # type=file: # type=file|default=: output file callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` @@ -73,7 +73,7 @@ outputs: templates: # dict[str, str] - `output_file_template` values to be provided to output fields roi_file: '"bar.nii"' - # type=file: + # type=file: # type=file|default=: output file requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present @@ -84,24 +84,24 @@ tests: in_file: # type=file|default=: input file roi_file: - # type=file: + # type=file: # type=file|default=: output file x_min: - # type=int|default=0: + # type=int|default=0: x_size: - # type=int|default=0: + # type=int|default=0: y_min: - # type=int|default=0: + # type=int|default=0: y_size: - # type=int|default=0: + # type=int|default=0: z_min: - # type=int|default=0: + # type=int|default=0: z_size: - # type=int|default=0: + # type=int|default=0: t_min: - # type=int|default=0: + # type=int|default=0: t_size: - # type=int|default=0: + # type=int|default=0: crop_list: # type=list|default=[]: list of two tuples specifying crop options output_type: @@ -118,8 +118,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -131,12 +131,12 @@ tests: in_file: # type=file|default=: input file roi_file: '"bar.nii"' - # type=file: + # type=file: # type=file|default=: output file t_min: '0' - # type=int|default=0: + # type=int|default=0: t_size: '1' - # type=int|default=0: + # type=int|default=0: imports: &id001 # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys @@ -148,8 +148,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -165,12 +165,12 @@ doctests: in_file: anatfile # type=file|default=: input file roi_file: '"bar.nii"' - # type=file: + # type=file: # type=file|default=: output file t_min: '0' - # type=int|default=0: + # type=int|default=0: t_size: '1' - # type=int|default=0: + # type=int|default=0: imports: *id001 # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys diff --git a/nipype-auto-conv/specs/fast.yaml b/nipype-auto-conv/specs/fast.yaml index e565d4a..37d0d67 100644 --- a/nipype-auto-conv/specs/fast.yaml +++ b/nipype-auto-conv/specs/fast.yaml @@ -6,10 +6,10 @@ # Docs # ---- # FSL FAST wrapper for segmentation and bias correction -# +# # For complete details, see the `FAST Documentation. # `_ -# +# # Examples # -------- # >>> from nipype.interfaces import fsl @@ -19,8 +19,8 @@ # >>> fast.cmdline # 'fast -o fast_ -S 1 structural.nii' # >>> out = fast.run() # doctest: +SKIP -# -# +# +# task_name: FAST nipype_name: FAST nipype_module: nipype.interfaces.fsl.preprocess @@ -62,20 +62,20 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. bias_field: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: mixeltype: generic/file # type=file: path/name of mixeltype volume file _mixeltype partial_volume_files: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: partial_volume_map: generic/file # type=file: path/name of partial volume file _pveseg probability_maps: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: # type=bool|default=False: outputs individual probability maps restored_image: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: tissue_class_files: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: tissue_class_map: generic/file # type=file: path/name of binary segmented volume file one val for each class _seg callables: @@ -132,7 +132,7 @@ tests: manual_seg: # type=file|default=: Filename containing intensities probability_maps: - # type=outputmultiobject: + # type=outputmultiobject: # type=bool|default=False: outputs individual probability maps output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type @@ -148,8 +148,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -170,8 +170,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/fast_callables.py b/nipype-auto-conv/specs/fast_callables.py index b83ee37..490163d 100644 --- a/nipype-auto-conv/specs/fast_callables.py +++ b/nipype-auto-conv/specs/fast_callables.py @@ -151,7 +151,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if inputs.segments: outputs["tissue_class_files"] = [] @@ -163,7 +163,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) if inputs.output_biascorrected is not attrs.NOTHING: @@ -180,7 +180,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) else: @@ -192,7 +192,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) @@ -202,7 +202,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) if not inputs.no_pve: outputs["partial_volume_map"] = _gen_fname( @@ -211,7 +211,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) outputs["partial_volume_files"] = [] for i in range(nclasses): @@ -222,7 +222,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) if inputs.output_biasfield: @@ -239,7 +239,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) else: @@ -251,7 +251,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) @@ -265,7 +265,7 @@ def _list_outputs(inputs=None, stdout=None, stderr=None, output_dir=None): inputs=inputs, stdout=stdout, stderr=stderr, - output_dir=output_dir + output_dir=output_dir, ) ) return outputs diff --git a/nipype-auto-conv/specs/feat.yaml b/nipype-auto-conv/specs/feat.yaml index 9bde358..042b1c0 100644 --- a/nipype-auto-conv/specs/feat.yaml +++ b/nipype-auto-conv/specs/feat.yaml @@ -39,7 +39,7 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. feat_dir: generic/directory - # type=directory: + # type=directory: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -67,8 +67,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/feat_model.yaml b/nipype-auto-conv/specs/feat_model.yaml index 430e8ce..bda2496 100644 --- a/nipype-auto-conv/specs/feat_model.yaml +++ b/nipype-auto-conv/specs/feat_model.yaml @@ -79,8 +79,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/feature_extractor.yaml b/nipype-auto-conv/specs/feature_extractor.yaml index fdd69d3..d994561 100644 --- a/nipype-auto-conv/specs/feature_extractor.yaml +++ b/nipype-auto-conv/specs/feature_extractor.yaml @@ -5,9 +5,9 @@ # # Docs # ---- -# +# # Extract features (for later training and/or classifying) -# +# task_name: FeatureExtractor nipype_name: FeatureExtractor nipype_module: nipype.interfaces.fsl.fix @@ -70,8 +70,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/filmgls.yaml b/nipype-auto-conv/specs/filmgls.yaml index 2e15e91..74615c3 100644 --- a/nipype-auto-conv/specs/filmgls.yaml +++ b/nipype-auto-conv/specs/filmgls.yaml @@ -6,31 +6,31 @@ # Docs # ---- # Use FSL film_gls command to fit a design matrix to voxel timeseries -# +# # Examples # -------- -# +# # Initialize with no options, assigning them when calling run: -# +# # >>> from nipype.interfaces import fsl # >>> fgls = fsl.FILMGLS() # >>> res = fgls.run('in_file', 'design_file', 'thresh', rn='stats') #doctest: +SKIP -# +# # Assign options through the ``inputs`` attribute: -# +# # >>> fgls = fsl.FILMGLS() # >>> fgls.inputs.in_file = 'functional.nii' # >>> fgls.inputs.design_file = 'design.mat' # >>> fgls.inputs.threshold = 10 # >>> fgls.inputs.results_dir = 'stats' # >>> res = fgls.run() #doctest: +SKIP -# +# # Specify options when creating an instance: -# +# # >>> fgls = fsl.FILMGLS(in_file='functional.nii', design_file='design.mat', threshold=10, results_dir='stats') # >>> res = fgls.run() #doctest: +SKIP -# -# +# +# task_name: FILMGLS nipype_name: FILMGLS nipype_module: nipype.interfaces.fsl.model @@ -165,8 +165,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/filter_regressor.yaml b/nipype-auto-conv/specs/filter_regressor.yaml index f3af84b..74a9915 100644 --- a/nipype-auto-conv/specs/filter_regressor.yaml +++ b/nipype-auto-conv/specs/filter_regressor.yaml @@ -6,9 +6,9 @@ # Docs # ---- # Data de-noising by regressing out part of a design matrix -# +# # Uses simple OLS regression on 4D images -# +# task_name: FilterRegressor nipype_name: FilterRegressor nipype_module: nipype.interfaces.fsl.utils @@ -96,8 +96,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/find_the_biggest.yaml b/nipype-auto-conv/specs/find_the_biggest.yaml index 5955dcb..a2d7e9c 100644 --- a/nipype-auto-conv/specs/find_the_biggest.yaml +++ b/nipype-auto-conv/specs/find_the_biggest.yaml @@ -5,22 +5,22 @@ # # Docs # ---- -# +# # Use FSL find_the_biggest for performing hard segmentation on # the outputs of connectivity-based thresholding in probtrack. # For complete details, see the `FDT # Documentation. `_ -# +# # Example # ------- -# +# # >>> from nipype.interfaces import fsl # >>> ldir = ['seeds_to_M1.nii', 'seeds_to_M2.nii'] # >>> fBig = fsl.FindTheBiggest(in_files=ldir, out_file='biggestSegmentation') # >>> fBig.cmdline # 'find_the_biggest seeds_to_M1.nii seeds_to_M2.nii biggestSegmentation' -# -# +# +# task_name: FindTheBiggest nipype_name: FindTheBiggest nipype_module: nipype.interfaces.fsl.dti @@ -92,8 +92,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -115,8 +115,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/first.yaml b/nipype-auto-conv/specs/first.yaml index bb3e430..057b131 100644 --- a/nipype-auto-conv/specs/first.yaml +++ b/nipype-auto-conv/specs/first.yaml @@ -6,19 +6,19 @@ # Docs # ---- # FSL run_first_all wrapper for segmentation of subcortical volumes -# +# # http://www.fmrib.ox.ac.uk/fsl/first/index.html -# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> first = fsl.FIRST() # >>> first.inputs.in_file = 'structural.nii' # >>> first.inputs.out_file = 'segmented.nii' # >>> res = first.run() #doctest: +SKIP -# -# +# +# task_name: FIRST nipype_name: FIRST nipype_module: nipype.interfaces.fsl.preprocess @@ -106,8 +106,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/flameo.yaml b/nipype-auto-conv/specs/flameo.yaml index 2b735aa..92e69a3 100644 --- a/nipype-auto-conv/specs/flameo.yaml +++ b/nipype-auto-conv/specs/flameo.yaml @@ -6,12 +6,12 @@ # Docs # ---- # Use FSL flameo command to perform higher level model fits -# +# # Examples # -------- -# +# # Initialize FLAMEO with no options, assigning them when calling run: -# +# # >>> from nipype.interfaces import fsl # >>> flameo = fsl.FLAMEO() # >>> flameo.inputs.cope_file = 'cope.nii.gz' @@ -23,8 +23,8 @@ # >>> flameo.inputs.run_mode = 'fe' # >>> flameo.cmdline # 'flameo --copefile=cope.nii.gz --covsplitfile=cov_split.mat --designfile=design.mat --ld=stats --maskfile=mask.nii --runmode=fe --tcontrastsfile=design.con --varcopefile=varcope.nii.gz' -# -# +# +# task_name: FLAMEO nipype_name: FLAMEO nipype_module: nipype.interfaces.fsl.model @@ -50,7 +50,7 @@ inputs: f_con_file: generic/file # type=file|default=: ascii matrix specifying f-contrasts log_dir: generic/directory - # type=directory|default='stats': + # type=directory|default='stats': mask_file: medimage/nifti1 # type=file|default=: mask file t_con_file: medimage-fsl/con @@ -143,7 +143,7 @@ tests: outlier_iter: # type=int|default=0: Number of max iterations to use when inferring outliers. Default is 12. log_dir: - # type=directory|default='stats': + # type=directory|default='stats': output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type args: @@ -158,8 +158,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -190,8 +190,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/flirt.yaml b/nipype-auto-conv/specs/flirt.yaml index 5e39a3a..f079021 100644 --- a/nipype-auto-conv/specs/flirt.yaml +++ b/nipype-auto-conv/specs/flirt.yaml @@ -6,13 +6,13 @@ # Docs # ---- # FSL FLIRT wrapper for coregistration -# +# # For complete details, see the `FLIRT Documentation. # `_ -# +# # To print out the command line help, use: # fsl.FLIRT().inputs_help() -# +# # Examples # -------- # >>> from nipype.interfaces import fsl @@ -24,8 +24,8 @@ # >>> flt.cmdline # doctest: +ELLIPSIS # 'flirt -in structural.nii -ref mni.nii -out structural_flirt.nii.gz -omat structural_flirt.mat -bins 640 -searchcost mutualinfo' # >>> res = flt.run() #doctest: +SKIP -# -# +# +# task_name: FLIRT nipype_name: FLIRT nipype_module: nipype.interfaces.fsl.preprocess @@ -218,8 +218,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -249,8 +249,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/fnirt.yaml b/nipype-auto-conv/specs/fnirt.yaml index d802e0d..d434bec 100644 --- a/nipype-auto-conv/specs/fnirt.yaml +++ b/nipype-auto-conv/specs/fnirt.yaml @@ -6,35 +6,35 @@ # Docs # ---- # FSL FNIRT wrapper for non-linear registration -# +# # For complete details, see the `FNIRT Documentation. # `_ -# +# # Examples # -------- # >>> from nipype.interfaces import fsl # >>> from nipype.testing import example_data # >>> fnt = fsl.FNIRT(affine_file=example_data('trans.mat')) # >>> res = fnt.run(ref_file=example_data('mni.nii', in_file=example_data('structural.nii')) #doctest: +SKIP -# +# # T1 -> Mni153 -# +# # >>> from nipype.interfaces import fsl # >>> fnirt_mprage = fsl.FNIRT() # >>> fnirt_mprage.inputs.in_fwhm = [8, 4, 2, 2] # >>> fnirt_mprage.inputs.subsampling_scheme = [4, 2, 1, 1] -# +# # Specify the resolution of the warps -# +# # >>> fnirt_mprage.inputs.warp_resolution = (6, 6, 6) # >>> res = fnirt_mprage.run(in_file='structural.nii', ref_file='mni.nii', warped_file='warped.nii', fieldcoeff_file='fieldcoeff.nii')#doctest: +SKIP -# +# # We can check the command line and confirm that it's what we expect. -# +# # >>> fnirt_mprage.cmdline #doctest: +SKIP # 'fnirt --cout=fieldcoeff.nii --in=structural.nii --infwhm=8,4,2,2 --ref=mni.nii --subsamp=4,2,1,1 --warpres=6,6,6 --iout=warped.nii' -# -# +# +# task_name: FNIRT nipype_name: FNIRT nipype_module: nipype.interfaces.fsl.preprocess @@ -226,8 +226,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -253,8 +253,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/fugue.yaml b/nipype-auto-conv/specs/fugue.yaml index 20d9554..cf5bd47 100644 --- a/nipype-auto-conv/specs/fugue.yaml +++ b/nipype-auto-conv/specs/fugue.yaml @@ -6,25 +6,25 @@ # Docs # ---- # FSL FUGUE set of tools for EPI distortion correction -# +# # `FUGUE `_ is, most generally, # a set of tools for EPI distortion correction. -# +# # Distortions may be corrected for # 1. improving registration with non-distorted images (e.g. structurals), # or # 2. dealing with motion-dependent changes. -# +# # FUGUE is designed to deal only with the first case - # improving registration. -# -# +# +# # Examples # -------- -# -# +# +# # Unwarping an input image (shift map is known): -# +# # >>> from nipype.interfaces.fsl.preprocess import FUGUE # >>> fugue = FUGUE() # >>> fugue.inputs.in_file = 'epi.nii' @@ -35,10 +35,10 @@ # >>> fugue.cmdline # doctest: +ELLIPSIS # 'fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --unwarp=epi_unwarped.nii.gz' # >>> fugue.run() #doctest: +SKIP -# -# +# +# # Warping an input image (shift map is known): -# +# # >>> from nipype.interfaces.fsl.preprocess import FUGUE # >>> fugue = FUGUE() # >>> fugue.inputs.in_file = 'epi.nii' @@ -50,10 +50,10 @@ # >>> fugue.cmdline # doctest: +ELLIPSIS # 'fugue --in=epi.nii --mask=epi_mask.nii --loadshift=vsm.nii --unwarpdir=y --warp=epi_warped.nii.gz' # >>> fugue.run() #doctest: +SKIP -# -# +# +# # Computing the vsm (unwrapped phase map is known): -# +# # >>> from nipype.interfaces.fsl.preprocess import FUGUE # >>> fugue = FUGUE() # >>> fugue.inputs.phasemap_in_file = 'epi_phasediff.nii' @@ -65,9 +65,9 @@ # >>> fugue.cmdline # doctest: +ELLIPSIS # 'fugue --dwelltoasym=0.9390243902 --mask=epi_mask.nii --phasemap=epi_phasediff.nii --saveshift=epi_phasediff_vsm.nii.gz --unwarpdir=y' # >>> fugue.run() #doctest: +SKIP -# -# -# +# +# +# task_name: FUGUE nipype_name: FUGUE nipype_module: nipype.interfaces.fsl.preprocess @@ -225,8 +225,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -253,8 +253,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -283,8 +283,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -313,8 +313,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/glm.yaml b/nipype-auto-conv/specs/glm.yaml index 532b6d8..3668994 100644 --- a/nipype-auto-conv/specs/glm.yaml +++ b/nipype-auto-conv/specs/glm.yaml @@ -5,17 +5,17 @@ # # Docs # ---- -# +# # FSL GLM: -# +# # Example # ------- # >>> import nipype.interfaces.fsl as fsl # >>> glm = fsl.GLM(in_file='functional.nii', design='maps.nii', output_type='NIFTI') # >>> glm.cmdline # 'fsl_glm -i functional.nii -d maps.nii -o functional_glm.nii' -# -# +# +# task_name: GLM nipype_name: GLM nipype_module: nipype.interfaces.fsl.model @@ -175,8 +175,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -200,8 +200,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/ica__aroma.yaml b/nipype-auto-conv/specs/ica__aroma.yaml index 2a98008..bd97c5f 100644 --- a/nipype-auto-conv/specs/ica__aroma.yaml +++ b/nipype-auto-conv/specs/ica__aroma.yaml @@ -5,20 +5,20 @@ # # Docs # ---- -# +# # Interface for the ICA_AROMA.py script. -# +# # ICA-AROMA (i.e. 'ICA-based Automatic Removal Of Motion Artifacts') concerns # a data-driven method to identify and remove motion-related independent # components from fMRI data. To that end it exploits a small, but robust # set of theoretically motivated features, preventing the need for classifier # re-training and therefore providing direct and easy applicability. -# +# # See link for further documentation: https://github.com/rhr-pruim/ICA-AROMA -# +# # Example # ------- -# +# # >>> from nipype.interfaces.fsl import ICA_AROMA # >>> from nipype.testing import example_data # >>> AROMA_obj = ICA_AROMA() @@ -31,7 +31,7 @@ # >>> AROMA_obj.inputs.out_dir = 'ICA_testout' # >>> AROMA_obj.cmdline # doctest: +ELLIPSIS # 'ICA_AROMA.py -den both -warp warpfield.nii -i functional.nii -m mask.nii.gz -affmat func_to_struct.mat -mc fsl_mcflirt_movpar.txt -o .../ICA_testout' -# +# task_name: ICA_AROMA nipype_name: ICA_AROMA nipype_module: nipype.interfaces.fsl.aroma @@ -132,8 +132,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -168,8 +168,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/image_maths.yaml b/nipype-auto-conv/specs/image_maths.yaml index f156853..c0cb2c5 100644 --- a/nipype-auto-conv/specs/image_maths.yaml +++ b/nipype-auto-conv/specs/image_maths.yaml @@ -7,20 +7,20 @@ # ---- # Use FSL fslmaths command to allow mathematical manipulation of images # `FSL info `_ -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> from nipype.testing import anatfile # >>> maths = fsl.ImageMaths(in_file=anatfile, op_string= '-add 5', # ... out_file='foo_maths.nii') # >>> maths.cmdline == 'fslmaths %s -add 5 foo_maths.nii' % anatfile # True -# -# -# +# +# +# task_name: ImageMaths nipype_name: ImageMaths nipype_module: nipype.interfaces.fsl.utils @@ -36,14 +36,14 @@ inputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. in_file: generic/file - # type=file|default=: + # type=file|default=: in_file2: generic/file - # type=file|default=: + # type=file|default=: mask_file: generic/file # type=file|default=: use (following image>0) to mask current image out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -61,16 +61,16 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. out_file: medimage/nifti1 - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields out_file: '"foo_maths.nii"' - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -78,14 +78,14 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) in_file: - # type=file|default=: + # type=file|default=: in_file2: - # type=file|default=: + # type=file|default=: mask_file: # type=file|default=: use (following image>0) to mask current image out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: op_string: # type=str|default='': string defining the operation, i. e. -add suffix: @@ -106,8 +106,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -117,12 +117,12 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) in_file: - # type=file|default=: + # type=file|default=: op_string: '"-add 5"' # type=str|default='': string defining the operation, i. e. -add out_file: '"foo_maths.nii"' - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: imports: &id001 # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys @@ -134,8 +134,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -149,12 +149,12 @@ doctests: # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. in_file: anatfile - # type=file|default=: + # type=file|default=: op_string: '"-add 5"' # type=str|default='': string defining the operation, i. e. -add out_file: '"foo_maths.nii"' - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: imports: *id001 # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys diff --git a/nipype-auto-conv/specs/image_meants.yaml b/nipype-auto-conv/specs/image_meants.yaml index 37df853..c677a44 100644 --- a/nipype-auto-conv/specs/image_meants.yaml +++ b/nipype-auto-conv/specs/image_meants.yaml @@ -8,8 +8,8 @@ # Use fslmeants for printing the average timeseries (intensities) to # the screen (or saves to a file). The average is taken over all voxels # in the mask (or all voxels in the image if no mask is specified) -# -# +# +# task_name: ImageMeants nipype_name: ImageMeants nipype_module: nipype.interfaces.fsl.utils @@ -99,8 +99,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/image_stats.yaml b/nipype-auto-conv/specs/image_stats.yaml index 8c2f3fc..b390726 100644 --- a/nipype-auto-conv/specs/image_stats.yaml +++ b/nipype-auto-conv/specs/image_stats.yaml @@ -8,19 +8,19 @@ # Use FSL fslstats command to calculate stats from images # `FSL info # `_ -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import ImageStats # >>> from nipype.testing import funcfile # >>> stats = ImageStats(in_file=funcfile, op_string= '-M') # >>> stats.cmdline == 'fslstats %s -M'%funcfile # True -# -# -# +# +# +# task_name: ImageStats nipype_name: ImageStats nipype_module: nipype.interfaces.fsl.utils @@ -94,8 +94,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -119,8 +119,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/inv_warp.yaml b/nipype-auto-conv/specs/inv_warp.yaml index 9151af0..a34cde0 100644 --- a/nipype-auto-conv/specs/inv_warp.yaml +++ b/nipype-auto-conv/specs/inv_warp.yaml @@ -5,13 +5,13 @@ # # Docs # ---- -# +# # Use FSL Invwarp to invert a FNIRT warp -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import InvWarp # >>> invwarp = InvWarp() # >>> invwarp.inputs.warp = "struct2mni.nii" @@ -20,9 +20,9 @@ # >>> invwarp.cmdline # 'invwarp --out=struct2mni_inverse.nii.gz --ref=anatomical.nii --warp=struct2mni.nii' # >>> res = invwarp.run() # doctest: +SKIP -# -# -# +# +# +# task_name: InvWarp nipype_name: InvWarp nipype_module: nipype.interfaces.fsl.utils @@ -109,8 +109,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -133,8 +133,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/isotropic_smooth.yaml b/nipype-auto-conv/specs/isotropic_smooth.yaml index 6ffdabd..51d44a9 100644 --- a/nipype-auto-conv/specs/isotropic_smooth.yaml +++ b/nipype-auto-conv/specs/isotropic_smooth.yaml @@ -87,8 +87,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/l2_model.yaml b/nipype-auto-conv/specs/l2_model.yaml index fb142c5..fdfd1e2 100644 --- a/nipype-auto-conv/specs/l2_model.yaml +++ b/nipype-auto-conv/specs/l2_model.yaml @@ -6,14 +6,14 @@ # Docs # ---- # Generate subject specific second level model -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import L2Model # >>> model = L2Model(num_copes=3) # 3 sessions -# -# +# +# task_name: L2Model nipype_name: L2Model nipype_module: nipype.interfaces.fsl.model @@ -71,8 +71,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/level_1_design.yaml b/nipype-auto-conv/specs/level_1_design.yaml index a85f6a9..4c3d611 100644 --- a/nipype-auto-conv/specs/level_1_design.yaml +++ b/nipype-auto-conv/specs/level_1_design.yaml @@ -6,17 +6,17 @@ # Docs # ---- # Generate FEAT specific files -# +# # Examples # -------- -# +# # >>> level1design = Level1Design() # >>> level1design.inputs.interscan_interval = 2.5 # >>> level1design.inputs.bases = {'dgamma':{'derivs': False}} # >>> level1design.inputs.session_info = 'session_info.npz' # >>> level1design.run() # doctest: +SKIP -# -# +# +# task_name: Level1Design nipype_name: Level1Design nipype_module: nipype.interfaces.fsl.model @@ -80,8 +80,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/make_dyadic_vectors.yaml b/nipype-auto-conv/specs/make_dyadic_vectors.yaml index e41d3cd..0ad7027 100644 --- a/nipype-auto-conv/specs/make_dyadic_vectors.yaml +++ b/nipype-auto-conv/specs/make_dyadic_vectors.yaml @@ -22,13 +22,13 @@ inputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. mask: generic/file - # type=file|default=: + # type=file|default=: output: generic/file - # type=file|default='dyads': + # type=file|default='dyads': phi_vol: generic/file - # type=file|default=: + # type=file|default=: theta_vol: generic/file - # type=file|default=: + # type=file|default=: callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -46,9 +46,9 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. dispersion: generic/file - # type=file: + # type=file: dyads: generic/file - # type=file: + # type=file: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -61,13 +61,13 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) theta_vol: - # type=file|default=: + # type=file|default=: phi_vol: - # type=file|default=: + # type=file|default=: mask: - # type=file|default=: + # type=file|default=: output: - # type=file|default='dyads': + # type=file|default='dyads': perc: # type=float|default=0.0: the {perc}% angle of the output cone of uncertainty (output will be in degrees) output_type: @@ -84,8 +84,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/maths_command.yaml b/nipype-auto-conv/specs/maths_command.yaml index e9acb76..9b8e624 100644 --- a/nipype-auto-conv/specs/maths_command.yaml +++ b/nipype-auto-conv/specs/maths_command.yaml @@ -5,7 +5,7 @@ # # Docs # ---- -# +# task_name: MathsCommand nipype_name: MathsCommand nipype_module: nipype.interfaces.fsl.maths @@ -83,8 +83,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/max_image.yaml b/nipype-auto-conv/specs/max_image.yaml index 1d0e2d0..3e56aed 100644 --- a/nipype-auto-conv/specs/max_image.yaml +++ b/nipype-auto-conv/specs/max_image.yaml @@ -6,7 +6,7 @@ # Docs # ---- # Use fslmaths to generate a max image across a given dimension. -# +# # Examples # -------- # >>> from nipype.interfaces.fsl.maths import MaxImage @@ -15,8 +15,8 @@ # >>> maxer.dimension = "T" # >>> maxer.cmdline # doctest: +SKIP # 'fslmaths functional.nii -Tmax functional_max.nii' -# -# +# +# task_name: MaxImage nipype_name: MaxImage nipype_module: nipype.interfaces.fsl.maths @@ -96,8 +96,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -116,8 +116,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/maxn_image.yaml b/nipype-auto-conv/specs/maxn_image.yaml index ac326f3..c60f028 100644 --- a/nipype-auto-conv/specs/maxn_image.yaml +++ b/nipype-auto-conv/specs/maxn_image.yaml @@ -7,8 +7,8 @@ # ---- # Use fslmaths to generate an image of index of max across # a given dimension. -# -# +# +# task_name: MaxnImage nipype_name: MaxnImage nipype_module: nipype.interfaces.fsl.maths @@ -88,8 +88,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/mcflirt.yaml b/nipype-auto-conv/specs/mcflirt.yaml index f1ea002..5db6ff0 100644 --- a/nipype-auto-conv/specs/mcflirt.yaml +++ b/nipype-auto-conv/specs/mcflirt.yaml @@ -6,10 +6,10 @@ # Docs # ---- # FSL MCFLIRT wrapper for within-modality motion correction -# +# # For complete details, see the `MCFLIRT Documentation. # `_ -# +# # Examples # -------- # >>> from nipype.interfaces import fsl @@ -20,8 +20,8 @@ # >>> mcflt.cmdline # 'mcflirt -in functional.nii -cost mutualinfo -out moco.nii' # >>> res = mcflt.run() # doctest: +SKIP -# -# +# +# task_name: MCFLIRT nipype_name: MCFLIRT nipype_module: nipype.interfaces.fsl.preprocess @@ -145,8 +145,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -170,8 +170,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/mean_image.yaml b/nipype-auto-conv/specs/mean_image.yaml index c30b541..78394bf 100644 --- a/nipype-auto-conv/specs/mean_image.yaml +++ b/nipype-auto-conv/specs/mean_image.yaml @@ -85,8 +85,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/median_image.yaml b/nipype-auto-conv/specs/median_image.yaml index 9b40b41..e297a4a 100644 --- a/nipype-auto-conv/specs/median_image.yaml +++ b/nipype-auto-conv/specs/median_image.yaml @@ -85,8 +85,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/melodic.yaml b/nipype-auto-conv/specs/melodic.yaml index efdf7c8..e6c7c27 100644 --- a/nipype-auto-conv/specs/melodic.yaml +++ b/nipype-auto-conv/specs/melodic.yaml @@ -7,10 +7,10 @@ # ---- # Multivariate Exploratory Linear Optimised Decomposition into Independent # Components -# +# # Examples # -------- -# +# # >>> melodic_setup = MELODIC() # >>> melodic_setup.inputs.approach = 'tica' # >>> melodic_setup.inputs.in_files = ['functional.nii', 'functional2.nii', 'functional3.nii'] @@ -27,9 +27,9 @@ # >>> melodic_setup.cmdline # 'melodic -i functional.nii,functional2.nii,functional3.nii -a tica --bgthreshold=10.000000 --mmthresh=0.500000 --nobet -o groupICA.out --Ostats --Scon=subjectDesign.con --Sdes=subjectDesign.mat --Tcon=timeDesign.con --Tdes=timeDesign.mat --tr=1.500000' # >>> melodic_setup.run() # doctest: +SKIP -# -# -# +# +# +# task_name: MELODIC nipype_name: MELODIC nipype_module: nipype.interfaces.fsl.model @@ -55,7 +55,7 @@ inputs: mix: generic/file # type=file|default=: mixing matrix for mixture modelling / filtering out_dir: Path - # type=directory: + # type=directory: # type=directory|default=: output directory name s_con: medimage-fsl/con # type=file|default=: t-contrast matrix across subject-domain @@ -89,7 +89,7 @@ outputs: templates: # dict[str, str] - `output_file_template` values to be provided to output fields out_dir: '"groupICA.out"' - # type=directory: + # type=directory: # type=directory|default=: output directory name requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present @@ -100,7 +100,7 @@ tests: in_files: # type=inputmultiobject|default=[]: input file names (either single file name or a list) out_dir: - # type=directory: + # type=directory: # type=directory|default=: output directory name mask: # type=file|default=: file name of mask for thresholding @@ -208,8 +208,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -241,7 +241,7 @@ tests: s_con: # type=file|default=: t-contrast matrix across subject-domain out_dir: '"groupICA.out"' - # type=directory: + # type=directory: # type=directory|default=: output directory name imports: # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item @@ -251,8 +251,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -288,7 +288,7 @@ doctests: s_con: '"subjectDesign.con"' # type=file|default=: t-contrast matrix across subject-domain out_dir: '"groupICA.out"' - # type=directory: + # type=directory: # type=directory|default=: output directory name imports: # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item diff --git a/nipype-auto-conv/specs/merge.yaml b/nipype-auto-conv/specs/merge.yaml index dcf8551..6dd97e4 100644 --- a/nipype-auto-conv/specs/merge.yaml +++ b/nipype-auto-conv/specs/merge.yaml @@ -6,17 +6,17 @@ # Docs # ---- # Use fslmerge to concatenate images -# +# # Images can be concatenated across time, x, y, or z dimensions. Across the # time (t) dimension the TR is set by default to 1 sec. -# +# # Note: to set the TR to a different value, specify 't' for dimension and # specify the TR value in seconds for the tr input. The dimension will be # automatically updated to 'tr'. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import Merge # >>> merger = Merge() # >>> merger.inputs.in_files = ['functional2.nii', 'functional3.nii'] @@ -27,9 +27,9 @@ # >>> merger.inputs.tr = 2.25 # >>> merger.cmdline # 'fslmerge -tr functional2_merged.nii.gz functional2.nii functional3.nii 2.25' -# -# -# +# +# +# task_name: Merge nipype_name: Merge nipype_module: nipype.interfaces.fsl.utils @@ -45,10 +45,10 @@ inputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. in_files: medimage/nifti1+list-of - # type=list|default=[]: + # type=list|default=[]: merged_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -66,8 +66,8 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. merged_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -80,14 +80,14 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) in_files: - # type=list|default=[]: + # type=list|default=[]: dimension: # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t tr: # type=float|default=0.0: use to specify TR in seconds (default is 1.00 sec), overrides dimension and sets it to tr merged_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type args: @@ -102,8 +102,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -113,7 +113,7 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) in_files: - # type=list|default=[]: + # type=list|default=[]: dimension: '"t"' # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t output_type: '"NIFTI_GZ"' @@ -128,8 +128,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -143,7 +143,7 @@ doctests: # If the field is of file-format type and the value is None, then the # '.mock()' method of the corresponding class is used instead. in_files: '["functional2.nii", "functional3.nii"]' - # type=list|default=[]: + # type=list|default=[]: dimension: '"t"' # type=enum|default='t'|allowed['a','t','x','y','z']: dimension along which to merge, optionally set tr input when dimension is t output_type: '"NIFTI_GZ"' diff --git a/nipype-auto-conv/specs/min_image.yaml b/nipype-auto-conv/specs/min_image.yaml index d6c0721..3b50baa 100644 --- a/nipype-auto-conv/specs/min_image.yaml +++ b/nipype-auto-conv/specs/min_image.yaml @@ -85,8 +85,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/motion_outliers.yaml b/nipype-auto-conv/specs/motion_outliers.yaml index cca7ee4..0c8650c 100644 --- a/nipype-auto-conv/specs/motion_outliers.yaml +++ b/nipype-auto-conv/specs/motion_outliers.yaml @@ -5,7 +5,7 @@ # # Docs # ---- -# +# # Use FSL fsl_motion_outliers`http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLMotionOutliers`_ to find outliers in timeseries (4d) data. # Examples # -------- @@ -15,7 +15,7 @@ # >>> mo.cmdline # doctest: +ELLIPSIS # 'fsl_motion_outliers -i epi.nii -o epi_outliers.txt -p epi_metrics.png -s epi_metrics.txt' # >>> res = mo.run() # doctest: +SKIP -# +# task_name: MotionOutliers nipype_name: MotionOutliers nipype_module: nipype.interfaces.fsl.utils @@ -35,13 +35,13 @@ inputs: mask: generic/file # type=file|default=: mask image for calculating metric out_file: Path - # type=file: + # type=file: # type=file|default=: output outlier file name out_metric_plot: Path - # type=file: + # type=file: # type=file|default=: output metric values plot (DVARS etc.) file name out_metric_values: Path - # type=file: + # type=file: # type=file|default=: output metric values (DVARS etc.) file name callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` @@ -60,13 +60,13 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. out_file: generic/file - # type=file: + # type=file: # type=file|default=: output outlier file name out_metric_plot: generic/file - # type=file: + # type=file: # type=file|default=: output metric values plot (DVARS etc.) file name out_metric_values: generic/file - # type=file: + # type=file: # type=file|default=: output metric values (DVARS etc.) file name callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` @@ -82,7 +82,7 @@ tests: in_file: # type=file|default=: unfiltered 4D image out_file: - # type=file: + # type=file: # type=file|default=: output outlier file name mask: # type=file|default=: mask image for calculating metric @@ -95,10 +95,10 @@ tests: dummy: # type=int|default=0: number of dummy scans to delete (before running anything and creating EVs) out_metric_values: - # type=file: + # type=file: # type=file|default=: output metric values (DVARS etc.) file name out_metric_plot: - # type=file: + # type=file: # type=file|default=: output metric values plot (DVARS etc.) file name output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type @@ -114,8 +114,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -134,8 +134,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/multi_image_maths.yaml b/nipype-auto-conv/specs/multi_image_maths.yaml index 72a24c1..17e28ce 100644 --- a/nipype-auto-conv/specs/multi_image_maths.yaml +++ b/nipype-auto-conv/specs/multi_image_maths.yaml @@ -6,7 +6,7 @@ # Docs # ---- # Use fslmaths to perform a sequence of mathematical operations. -# +# # Examples # -------- # >>> from nipype.interfaces.fsl import MultiImageMaths @@ -17,8 +17,8 @@ # >>> maths.inputs.out_file = "functional4.nii" # >>> maths.cmdline # 'fslmaths functional.nii -add functional2.nii -mul -1 -div functional3.nii functional4.nii' -# -# +# +# task_name: MultiImageMaths nipype_name: MultiImageMaths nipype_module: nipype.interfaces.fsl.maths @@ -102,8 +102,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -129,8 +129,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/multiple_regress_design.yaml b/nipype-auto-conv/specs/multiple_regress_design.yaml index bd39d05..38e5a82 100644 --- a/nipype-auto-conv/specs/multiple_regress_design.yaml +++ b/nipype-auto-conv/specs/multiple_regress_design.yaml @@ -6,24 +6,24 @@ # Docs # ---- # Generate multiple regression design -# +# # .. note:: # FSL does not demean columns for higher level analysis. -# +# # Please see `FSL documentation # `_ # for more details on model specification for higher level analysis. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import MultipleRegressDesign # >>> model = MultipleRegressDesign() # >>> model.inputs.contrasts = [['group mean', 'T',['reg1'],[1]]] # >>> model.inputs.regressors = dict(reg1=[1, 1, 1], reg2=[2.,-4, 3]) # >>> model.run() # doctest: +SKIP -# -# +# +# task_name: MultipleRegressDesign nipype_name: MultipleRegressDesign nipype_module: nipype.interfaces.fsl.model @@ -87,8 +87,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/overlay.yaml b/nipype-auto-conv/specs/overlay.yaml index 155e80a..6ffac87 100644 --- a/nipype-auto-conv/specs/overlay.yaml +++ b/nipype-auto-conv/specs/overlay.yaml @@ -7,11 +7,11 @@ # ---- # Use FSL's overlay command to combine background and statistical images # into one volume -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> combine = fsl.Overlay() # >>> combine.inputs.background_image = 'mean_func.nii.gz' @@ -20,9 +20,9 @@ # >>> combine.inputs.stat_thresh = (3.5, 10) # >>> combine.inputs.show_negative_stats = True # >>> res = combine.run() #doctest: +SKIP -# -# -# +# +# +# task_name: Overlay nipype_name: Overlay nipype_module: nipype.interfaces.fsl.utils @@ -120,8 +120,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/percentile_image.yaml b/nipype-auto-conv/specs/percentile_image.yaml index 01a5156..d57bf3b 100644 --- a/nipype-auto-conv/specs/percentile_image.yaml +++ b/nipype-auto-conv/specs/percentile_image.yaml @@ -6,7 +6,7 @@ # Docs # ---- # Use fslmaths to generate a percentile image across a given dimension. -# +# # Examples # -------- # >>> from nipype.interfaces.fsl.maths import MaxImage @@ -16,8 +16,8 @@ # >>> percer.perc = 90 # >>> percer.cmdline # doctest: +SKIP # 'fslmaths functional.nii -Tperc 90 functional_perc.nii' -# -# +# +# task_name: PercentileImage nipype_name: PercentileImage nipype_module: nipype.interfaces.fsl.maths @@ -99,8 +99,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -119,8 +119,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/plot_motion_params.yaml b/nipype-auto-conv/specs/plot_motion_params.yaml index 997f47b..c375af6 100644 --- a/nipype-auto-conv/specs/plot_motion_params.yaml +++ b/nipype-auto-conv/specs/plot_motion_params.yaml @@ -7,30 +7,30 @@ # ---- # Use fsl_tsplot to plot the estimated motion parameters from a # realignment program. -# -# +# +# # Examples # -------- -# +# # >>> import nipype.interfaces.fsl as fsl # >>> plotter = fsl.PlotMotionParams() # >>> plotter.inputs.in_file = 'functional.par' # >>> plotter.inputs.in_source = 'fsl' # >>> plotter.inputs.plot_type = 'rotations' # >>> res = plotter.run() #doctest: +SKIP -# -# +# +# # Notes # ----- -# +# # The 'in_source' attribute determines the order of columns that are expected # in the source file. FSL prints motion parameters in the order rotations, # translations, while SPM prints them in the opposite order. This interface # should be able to plot timecourses of motion parameters generated from # other sources as long as they fall under one of these two patterns. For # more flexibility, see the :class:`fsl.PlotTimeSeries` interface. -# -# +# +# task_name: PlotMotionParams nipype_name: PlotMotionParams nipype_module: nipype.interfaces.fsl.utils @@ -106,8 +106,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/plot_time_series.yaml b/nipype-auto-conv/specs/plot_time_series.yaml index 8d0c3cd..17abf1a 100644 --- a/nipype-auto-conv/specs/plot_time_series.yaml +++ b/nipype-auto-conv/specs/plot_time_series.yaml @@ -6,19 +6,19 @@ # Docs # ---- # Use fsl_tsplot to create images of time course plots. -# +# # Examples # -------- -# +# # >>> import nipype.interfaces.fsl as fsl # >>> plotter = fsl.PlotTimeSeries() # >>> plotter.inputs.in_file = 'functional.par' # >>> plotter.inputs.title = 'Functional timeseries' # >>> plotter.inputs.labels = ['run1', 'run2'] # >>> plotter.run() #doctest: +SKIP -# -# -# +# +# +# task_name: PlotTimeSeries nipype_name: PlotTimeSeries nipype_module: nipype.interfaces.fsl.utils @@ -116,8 +116,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/power_spectrum.yaml b/nipype-auto-conv/specs/power_spectrum.yaml index 770bf1d..8375cfe 100644 --- a/nipype-auto-conv/specs/power_spectrum.yaml +++ b/nipype-auto-conv/specs/power_spectrum.yaml @@ -6,17 +6,17 @@ # Docs # ---- # Use FSL PowerSpectrum command for power spectrum estimation. -# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> pspec = fsl.PowerSpectrum() # >>> pspec.inputs.in_file = 'functional.nii' # >>> res = pspec.run() # doctest: +SKIP -# -# -# +# +# +# task_name: PowerSpectrum nipype_name: PowerSpectrum nipype_module: nipype.interfaces.fsl.utils @@ -88,8 +88,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/prelude.yaml b/nipype-auto-conv/specs/prelude.yaml index ac6a82c..e4148fc 100644 --- a/nipype-auto-conv/specs/prelude.yaml +++ b/nipype-auto-conv/specs/prelude.yaml @@ -6,13 +6,13 @@ # Docs # ---- # FSL prelude wrapper for phase unwrapping -# +# # Examples # -------- -# +# # Please insert examples for use of this command -# -# +# +# task_name: PRELUDE nipype_name: PRELUDE nipype_module: nipype.interfaces.fsl.preprocess @@ -124,8 +124,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/prepare_fieldmap.yaml b/nipype-auto-conv/specs/prepare_fieldmap.yaml index 90a0e12..bcd7324 100644 --- a/nipype-auto-conv/specs/prepare_fieldmap.yaml +++ b/nipype-auto-conv/specs/prepare_fieldmap.yaml @@ -5,17 +5,17 @@ # # Docs # ---- -# +# # Interface for the fsl_prepare_fieldmap script (FSL 5.0) -# +# # Prepares a fieldmap suitable for FEAT from SIEMENS data - saves output in # rad/s format (e.g. ```fsl_prepare_fieldmap SIEMENS # images_3_gre_field_mapping images_4_gre_field_mapping fmap_rads 2.65```). -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import PrepareFieldmap # >>> prepare = PrepareFieldmap() # >>> prepare.inputs.in_phase = "phase.nii" @@ -24,9 +24,9 @@ # >>> prepare.cmdline # doctest: +ELLIPSIS # 'fsl_prepare_fieldmap SIEMENS phase.nii magnitude.nii .../phase_fslprepared.nii.gz 2.460000' # >>> res = prepare.run() # doctest: +SKIP -# -# -# +# +# +# task_name: PrepareFieldmap nipype_name: PrepareFieldmap nipype_module: nipype.interfaces.fsl.epi @@ -105,8 +105,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -129,8 +129,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/prob_track_x.yaml b/nipype-auto-conv/specs/prob_track_x.yaml index 76fb58a..f03ab34 100644 --- a/nipype-auto-conv/specs/prob_track_x.yaml +++ b/nipype-auto-conv/specs/prob_track_x.yaml @@ -6,16 +6,16 @@ # Docs # ---- # Use FSL probtrackx for tractography on bedpostx results -# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> pbx = fsl.ProbTrackX(samples_base_name='merged', mask='mask.nii', seed='MASK_average_thal_right.nii', mode='seedmask', xfm='trans.mat', n_samples=3, n_steps=10, force_dir=True, opd=True, os2t=True, target_masks = ['targets_MASK1.nii', 'targets_MASK2.nii'], thsamples='merged_thsamples.nii', fsamples='merged_fsamples.nii', phsamples='merged_phsamples.nii', out_dir='.') # >>> pbx.cmdline # 'probtrackx --forcedir -m mask.nii --mode=seedmask --nsamples=3 --nsteps=10 --opd --os2t --dir=. --samples=merged --seed=MASK_average_thal_right.nii --targetmasks=targets.txt --xfm=trans.mat' -# -# +# +# task_name: ProbTrackX nipype_name: ProbTrackX nipype_module: nipype.interfaces.fsl.dti @@ -33,7 +33,7 @@ inputs: avoid_mp: generic/file # type=file|default=: reject pathways passing through locations given by this mask fsamples: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: inv_xfm: generic/file # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) mask: medimage/nifti1 @@ -45,7 +45,7 @@ inputs: out_dir: Path # type=directory|default=: directory to put the final volumes in phsamples: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: seed_ref: generic/file # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent stop_mask: generic/file @@ -53,7 +53,7 @@ inputs: target_masks: medimage/nifti1+list-of # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification thsamples: medimage/nifti1+list-of - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: waypoints: generic/file # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks xfm: datascience/text-matrix @@ -106,11 +106,11 @@ tests: mesh: # type=file|default=: Freesurfer-type surface descriptor (in ascii format) thsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: phsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: fsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: samples_base_name: # type=str|default='merged': the rootname/base_name for samples files mask: @@ -185,8 +185,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -218,11 +218,11 @@ tests: target_masks: # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification thsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: fsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: phsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: out_dir: '"."' # type=directory|default=: directory to put the final volumes in imports: @@ -233,8 +233,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -270,11 +270,11 @@ doctests: target_masks: '["targets_MASK1.nii", "targets_MASK2.nii"]' # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification thsamples: '"merged_thsamples.nii"' - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: fsamples: '"merged_fsamples.nii"' - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: phsamples: '"merged_phsamples.nii"' - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: out_dir: '"."' # type=directory|default=: directory to put the final volumes in imports: diff --git a/nipype-auto-conv/specs/prob_track_x2.yaml b/nipype-auto-conv/specs/prob_track_x2.yaml index 40e5b0e..736c84e 100644 --- a/nipype-auto-conv/specs/prob_track_x2.yaml +++ b/nipype-auto-conv/specs/prob_track_x2.yaml @@ -6,10 +6,10 @@ # Docs # ---- # Use FSL probtrackx2 for tractography on bedpostx results -# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> pbx2 = fsl.ProbTrackX2() # >>> pbx2.inputs.seed = 'seed_source.nii.gz' @@ -22,7 +22,7 @@ # >>> pbx2.inputs.n_steps = 10 # >>> pbx2.cmdline # 'probtrackx2 --forcedir -m nodif_brain_mask.nii.gz --nsamples=3 --nsteps=10 --opd --dir=. --samples=merged --seed=seed_source.nii.gz' -# +# task_name: ProbTrackX2 nipype_name: ProbTrackX2 nipype_module: nipype.interfaces.fsl.dti @@ -44,7 +44,7 @@ inputs: fopd: generic/file # type=file|default=: Other mask for binning tract distribution fsamples: medimage/nifti-gz+list-of - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: inv_xfm: generic/file # type=file|default=: transformation matrix taking DTI space to seed space (compulsory when using a warp_field for seeds_to_dti) lrtarget3: generic/file @@ -54,7 +54,7 @@ inputs: out_dir: Path # type=directory|default=: directory to put the final volumes in phsamples: medimage/nifti-gz+list-of - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: seed_ref: generic/file # type=file|default=: reference vol to define seed space in simple mode - diffusion space assumed if absent stop_mask: generic/file @@ -68,7 +68,7 @@ inputs: target_masks: generic/file+list-of # type=inputmultiobject|default=[]: list of target masks - required for seeds_to_targets classification thsamples: medimage/nifti-gz+list-of - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: waypoints: generic/file # type=file|default=: waypoint mask or ascii list of waypoint masks - only keep paths going through ALL the masks xfm: generic/file @@ -157,11 +157,11 @@ tests: meshspace: # type=enum|default='caret'|allowed['caret','first','freesurfer','vox']: Mesh reference space - either "caret" (default) or "freesurfer" or "first" or "vox" thsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: phsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: fsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: samples_base_name: # type=str|default='merged': the rootname/base_name for samples files mask: @@ -236,8 +236,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -249,11 +249,11 @@ tests: seed: '"seed_source.nii.gz"' # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file thsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: fsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: phsamples: - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: mask: # type=file|default=: bet binary mask file in diffusion space out_dir: '"."' @@ -270,8 +270,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -287,11 +287,11 @@ doctests: seed: '"seed_source.nii.gz"' # type=traitcompound|default=None: seed volume(s), or voxel(s) or freesurfer label file thsamples: '"merged_th1samples.nii.gz"' - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: fsamples: '"merged_f1samples.nii.gz"' - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: phsamples: '"merged_ph1samples.nii.gz"' - # type=inputmultiobject|default=[]: + # type=inputmultiobject|default=[]: mask: '"nodif_brain_mask.nii.gz"' # type=file|default=: bet binary mask file in diffusion space out_dir: '"."' diff --git a/nipype-auto-conv/specs/proj_thresh.yaml b/nipype-auto-conv/specs/proj_thresh.yaml index 5ad5502..c111a93 100644 --- a/nipype-auto-conv/specs/proj_thresh.yaml +++ b/nipype-auto-conv/specs/proj_thresh.yaml @@ -8,17 +8,17 @@ # Use FSL proj_thresh for thresholding some outputs of probtrack # For complete details, see the FDT Documentation # -# +# # Example # ------- -# +# # >>> from nipype.interfaces import fsl # >>> ldir = ['seeds_to_M1.nii', 'seeds_to_M2.nii'] # >>> pThresh = fsl.ProjThresh(in_files=ldir, threshold=3) # >>> pThresh.cmdline # 'proj_thresh seeds_to_M1.nii seeds_to_M2.nii 3' -# -# +# +# task_name: ProjThresh nipype_name: ProjThresh nipype_module: nipype.interfaces.fsl.dti @@ -82,8 +82,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -104,8 +104,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/randomise.yaml b/nipype-auto-conv/specs/randomise.yaml index 6b7ee93..df78e2e 100644 --- a/nipype-auto-conv/specs/randomise.yaml +++ b/nipype-auto-conv/specs/randomise.yaml @@ -8,15 +8,15 @@ # FSL Randomise: feeds the 4D projected FA data into GLM # modelling and thresholding # in order to find voxels which correlate with your model -# +# # Example # ------- # >>> import nipype.interfaces.fsl as fsl # >>> rand = fsl.Randomise(in_file='allFA.nii', mask = 'mask.nii', tcon='design.con', design_mat='design.mat') # >>> rand.cmdline # 'randomise -i allFA.nii -o "randomise" -d design.mat -t design.con -m mask.nii' -# -# +# +# task_name: Randomise nipype_name: Randomise nipype_module: nipype.interfaces.fsl.model @@ -150,8 +150,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -177,8 +177,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/reorient_2_std.yaml b/nipype-auto-conv/specs/reorient_2_std.yaml index 17ce6e8..a0ab8b6 100644 --- a/nipype-auto-conv/specs/reorient_2_std.yaml +++ b/nipype-auto-conv/specs/reorient_2_std.yaml @@ -7,17 +7,17 @@ # ---- # fslreorient2std is a tool for reorienting the image to match the # approximate orientation of the standard template images (MNI152). -# -# +# +# # Examples # -------- -# +# # >>> reorient = Reorient2Std() # >>> reorient.inputs.in_file = "functional.nii" # >>> res = reorient.run() # doctest: +SKIP -# -# -# +# +# +# task_name: Reorient2Std nipype_name: Reorient2Std nipype_module: nipype.interfaces.fsl.utils @@ -33,10 +33,10 @@ inputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. in_file: generic/file - # type=file|default=: + # type=file|default=: out_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -54,16 +54,16 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. out_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields templates: # dict[str, str] - `output_file_template` values to be provided to output fields out_file: out_file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: requirements: # dict[str, list[str]] - input fields that are required to be provided for the output field to be present tests: @@ -71,10 +71,10 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) in_file: - # type=file|default=: + # type=file|default=: out_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type args: @@ -89,8 +89,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/robust_fov.yaml b/nipype-auto-conv/specs/robust_fov.yaml index 151fb65..31eed5b 100644 --- a/nipype-auto-conv/specs/robust_fov.yaml +++ b/nipype-auto-conv/specs/robust_fov.yaml @@ -6,10 +6,10 @@ # Docs # ---- # Automatically crops an image removing lower head and neck. -# +# # Interface is stable 5.0.0 to 5.0.9, but default brainsize changed from # 150mm to 170mm. -# +# task_name: RobustFOV nipype_name: RobustFOV nipype_module: nipype.interfaces.fsl.utils @@ -89,8 +89,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/sig_loss.yaml b/nipype-auto-conv/specs/sig_loss.yaml index 67dcec9..adf86db 100644 --- a/nipype-auto-conv/specs/sig_loss.yaml +++ b/nipype-auto-conv/specs/sig_loss.yaml @@ -6,17 +6,17 @@ # Docs # ---- # Estimates signal loss from a field map (in rad/s) -# +# # Examples # -------- -# +# # >>> sigloss = SigLoss() # >>> sigloss.inputs.in_file = "phase.nii" # >>> sigloss.inputs.echo_time = 0.03 # >>> res = sigloss.run() # doctest: +SKIP -# -# -# +# +# +# task_name: SigLoss nipype_name: SigLoss nipype_module: nipype.interfaces.fsl.utils @@ -96,8 +96,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/slice.yaml b/nipype-auto-conv/specs/slice.yaml index 92408dd..6ff12e7 100644 --- a/nipype-auto-conv/specs/slice.yaml +++ b/nipype-auto-conv/specs/slice.yaml @@ -6,20 +6,20 @@ # Docs # ---- # Use fslslice to split a 3D file into lots of 2D files (along z-axis). -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import Slice # >>> slice = Slice() # >>> slice.inputs.in_file = 'functional.nii' # >>> slice.inputs.out_base_name = 'sl' # >>> slice.cmdline # 'fslslice functional.nii sl' -# -# -# +# +# +# task_name: Slice nipype_name: Slice nipype_module: nipype.interfaces.fsl.utils @@ -53,7 +53,7 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. out_files: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -83,8 +83,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -105,8 +105,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/slice_timer.yaml b/nipype-auto-conv/specs/slice_timer.yaml index dff7e08..5bef559 100644 --- a/nipype-auto-conv/specs/slice_timer.yaml +++ b/nipype-auto-conv/specs/slice_timer.yaml @@ -6,7 +6,7 @@ # Docs # ---- # FSL slicetimer wrapper to perform slice timing correction -# +# # Examples # -------- # >>> from nipype.interfaces import fsl @@ -15,8 +15,8 @@ # >>> st.inputs.in_file = example_data('functional.nii') # >>> st.inputs.interleaved = True # >>> result = st.run() #doctest: +SKIP -# -# +# +# task_name: SliceTimer nipype_name: SliceTimer nipype_module: nipype.interfaces.fsl.preprocess @@ -102,8 +102,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/slicer.yaml b/nipype-auto-conv/specs/slicer.yaml index da04f77..3652534 100644 --- a/nipype-auto-conv/specs/slicer.yaml +++ b/nipype-auto-conv/specs/slicer.yaml @@ -6,11 +6,11 @@ # Docs # ---- # Use FSL's slicer command to output a png image from a volume. -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> from nipype.testing import example_data # >>> slice = fsl.Slicer() @@ -18,9 +18,9 @@ # >>> slice.inputs.all_axial = True # >>> slice.inputs.image_width = 750 # >>> res = slice.run() #doctest: +SKIP -# -# -# +# +# +# task_name: Slicer nipype_name: Slicer nipype_module: nipype.interfaces.fsl.utils @@ -126,8 +126,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/smooth.yaml b/nipype-auto-conv/specs/smooth.yaml index fd618db..afc1c3e 100644 --- a/nipype-auto-conv/specs/smooth.yaml +++ b/nipype-auto-conv/specs/smooth.yaml @@ -5,32 +5,32 @@ # # Docs # ---- -# +# # Use fslmaths to smooth the image -# +# # Examples # -------- -# +# # Setting the kernel width using sigma: -# +# # >>> sm = Smooth() # >>> sm.inputs.output_type = 'NIFTI_GZ' # >>> sm.inputs.in_file = 'functional2.nii' # >>> sm.inputs.sigma = 8.0 # >>> sm.cmdline # doctest: +ELLIPSIS # 'fslmaths functional2.nii -kernel gauss 8.000 -fmean functional2_smooth.nii.gz' -# +# # Setting the kernel width using fwhm: -# +# # >>> sm = Smooth() # >>> sm.inputs.output_type = 'NIFTI_GZ' # >>> sm.inputs.in_file = 'functional2.nii' # >>> sm.inputs.fwhm = 8.0 # >>> sm.cmdline # doctest: +ELLIPSIS # 'fslmaths functional2.nii -kernel gauss 3.397 -fmean functional2_smooth.nii.gz' -# +# # One of sigma or fwhm must be set: -# +# # >>> from nipype.interfaces.fsl import Smooth # >>> sm = Smooth() # >>> sm.inputs.output_type = 'NIFTI_GZ' @@ -39,8 +39,8 @@ # Traceback (most recent call last): # ... # ValueError: Smooth requires a value for one of the inputs ... -# -# +# +# task_name: Smooth nipype_name: Smooth nipype_module: nipype.interfaces.fsl.utils @@ -56,10 +56,10 @@ inputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. in_file: medimage/nifti1 - # type=file|default=: + # type=file|default=: smoothed_file: Path - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callable_defaults: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set as the `default` method of input fields @@ -77,8 +77,8 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. smoothed_file: generic/file - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -91,14 +91,14 @@ tests: # dict[str, str] - values to provide to inputs fields in the task initialisation # (if not specified, will try to choose a sensible value) in_file: - # type=file|default=: + # type=file|default=: sigma: # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) fwhm: # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) smoothed_file: - # type=file: - # type=file|default=: + # type=file: + # type=file|default=: output_type: # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type args: @@ -113,8 +113,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -126,7 +126,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type in_file: - # type=file|default=: + # type=file|default=: sigma: '8.0' # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) imports: @@ -137,8 +137,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -150,7 +150,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type in_file: - # type=file|default=: + # type=file|default=: fwhm: '8.0' # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) imports: @@ -161,8 +161,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -174,7 +174,7 @@ tests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type in_file: - # type=file|default=: + # type=file|default=: imports: # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys @@ -183,8 +183,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -200,7 +200,7 @@ doctests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type in_file: '"functional2.nii"' - # type=file|default=: + # type=file|default=: sigma: '8.0' # type=float|default=0.0: gaussian kernel sigma in mm (not voxels) imports: @@ -217,7 +217,7 @@ doctests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type in_file: '"functional2.nii"' - # type=file|default=: + # type=file|default=: fwhm: '8.0' # type=float|default=0.0: gaussian kernel fwhm, will be converted to sigma in mm (not voxels) imports: @@ -234,7 +234,7 @@ doctests: output_type: '"NIFTI_GZ"' # type=enum|default='NIFTI'|allowed['NIFTI','NIFTI_GZ','NIFTI_PAIR','NIFTI_PAIR_GZ']: FSL output type in_file: '"functional2.nii"' - # type=file|default=: + # type=file|default=: imports: # list[nipype2pydra.task.base.importstatement] - list import statements required by the test, with each list item # consisting of 'module', 'name', and optionally 'alias' keys diff --git a/nipype-auto-conv/specs/smooth_estimate.yaml b/nipype-auto-conv/specs/smooth_estimate.yaml index fdea86a..1da7862 100644 --- a/nipype-auto-conv/specs/smooth_estimate.yaml +++ b/nipype-auto-conv/specs/smooth_estimate.yaml @@ -6,17 +6,17 @@ # Docs # ---- # Estimates the smoothness of an image -# +# # Examples # -------- -# +# # >>> est = SmoothEstimate() # >>> est.inputs.zstat_file = 'zstat1.nii.gz' # >>> est.inputs.mask_file = 'mask.nii' # >>> est.cmdline # 'smoothest --mask=mask.nii --zstat=zstat1.nii.gz' -# -# +# +# task_name: SmoothEstimate nipype_name: SmoothEstimate nipype_module: nipype.interfaces.fsl.model @@ -92,8 +92,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -114,8 +114,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/spatial_filter.yaml b/nipype-auto-conv/specs/spatial_filter.yaml index 2f09a21..8956e06 100644 --- a/nipype-auto-conv/specs/spatial_filter.yaml +++ b/nipype-auto-conv/specs/spatial_filter.yaml @@ -93,8 +93,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/split.yaml b/nipype-auto-conv/specs/split.yaml index afa9aea..a27bd79 100644 --- a/nipype-auto-conv/specs/split.yaml +++ b/nipype-auto-conv/specs/split.yaml @@ -7,7 +7,7 @@ # ---- # Uses FSL Fslsplit command to separate a volume into images in # time, x, y or z dimension. -# +# task_name: Split nipype_name: Split nipype_module: nipype.interfaces.fsl.utils @@ -41,7 +41,7 @@ outputs: # for file types, where specifying the format also specifies the file that will be # passed to the field in the automatically generated unittests. out_files: generic/file+list-of - # type=outputmultiobject: + # type=outputmultiobject: callables: # dict[str, str] - names of methods/callable classes defined in the adjacent `*_callables.py` # to set to the `callable` attribute of output fields @@ -73,8 +73,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/std_image.yaml b/nipype-auto-conv/specs/std_image.yaml index 7e77e98..bbdb636 100644 --- a/nipype-auto-conv/specs/std_image.yaml +++ b/nipype-auto-conv/specs/std_image.yaml @@ -7,7 +7,7 @@ # ---- # Use fslmaths to generate a standard deviation in an image across a given # dimension. -# +# task_name: StdImage nipype_name: StdImage nipype_module: nipype.interfaces.fsl.maths @@ -87,8 +87,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/susan.yaml b/nipype-auto-conv/specs/susan.yaml index 527da30..ebe726c 100644 --- a/nipype-auto-conv/specs/susan.yaml +++ b/nipype-auto-conv/specs/susan.yaml @@ -6,13 +6,13 @@ # Docs # ---- # FSL SUSAN wrapper to perform smoothing -# +# # For complete details, see the `SUSAN Documentation. # `_ -# +# # Examples # -------- -# +# # >>> from nipype.interfaces import fsl # >>> from nipype.testing import example_data # >>> anatfile # doctest: +SKIP @@ -22,7 +22,7 @@ # >>> sus.inputs.brightness_threshold = 2000.0 # >>> sus.inputs.fwhm = 8.0 # >>> result = sus.run() # doctest: +SKIP -# +# task_name: SUSAN nipype_name: SUSAN nipype_module: nipype.interfaces.fsl.preprocess @@ -100,8 +100,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/swap_dimensions.yaml b/nipype-auto-conv/specs/swap_dimensions.yaml index f0be367..c2fb752 100644 --- a/nipype-auto-conv/specs/swap_dimensions.yaml +++ b/nipype-auto-conv/specs/swap_dimensions.yaml @@ -6,13 +6,13 @@ # Docs # ---- # Use fslswapdim to alter the orientation of an image. -# +# # This interface accepts a three-tuple corresponding to the new # orientation. You may either provide dimension ids in the form of # (-)x, (-)y, or (-z), or nifti-syle dimension codes # (RL, LR, AP, PA, IS, SI). -# -# +# +# task_name: SwapDimensions nipype_name: SwapDimensions nipype_module: nipype.interfaces.fsl.utils @@ -86,8 +86,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/temporal_filter.yaml b/nipype-auto-conv/specs/temporal_filter.yaml index 0534a5b..7f7667a 100644 --- a/nipype-auto-conv/specs/temporal_filter.yaml +++ b/nipype-auto-conv/specs/temporal_filter.yaml @@ -7,8 +7,8 @@ # ---- # Use fslmaths to apply a low, high, or bandpass temporal filter to a # timeseries. -# -# +# +# task_name: TemporalFilter nipype_name: TemporalFilter nipype_module: nipype.interfaces.fsl.maths @@ -90,8 +90,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/text_2_vest.yaml b/nipype-auto-conv/specs/text_2_vest.yaml index 0507307..7c7ec5d 100644 --- a/nipype-auto-conv/specs/text_2_vest.yaml +++ b/nipype-auto-conv/specs/text_2_vest.yaml @@ -5,10 +5,10 @@ # # Docs # ---- -# +# # Use FSL Text2Vest`https://web.mit.edu/fsl_v5.0.10/fsl/doc/wiki/GLM(2f)CreatingDesignMatricesByHand.html`_ # to convert your plain text design matrix data into the format used by the FSL tools. -# +# # Examples # -------- # >>> from nipype.interfaces.fsl import Text2Vest @@ -18,7 +18,7 @@ # >>> t2v.cmdline # 'Text2Vest design.txt design.mat' # >>> res = t2v.run() # doctest: +SKIP -# +# task_name: Text2Vest nipype_name: Text2Vest nipype_module: nipype.interfaces.fsl.utils @@ -87,8 +87,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -110,8 +110,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/threshold.yaml b/nipype-auto-conv/specs/threshold.yaml index a9c7d62..3b898b7 100644 --- a/nipype-auto-conv/specs/threshold.yaml +++ b/nipype-auto-conv/specs/threshold.yaml @@ -91,8 +91,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/tract_skeleton.yaml b/nipype-auto-conv/specs/tract_skeleton.yaml index 0533538..bf7687c 100644 --- a/nipype-auto-conv/specs/tract_skeleton.yaml +++ b/nipype-auto-conv/specs/tract_skeleton.yaml @@ -7,7 +7,7 @@ # ---- # Use FSL's tbss_skeleton to skeletonise an FA image or project arbitrary # values onto a skeleton. -# +# # There are two ways to use this interface. To create a skeleton from an FA # image, just supply the ``in_file`` and set ``skeleton_file`` to True (or # specify a skeleton filename. To project values onto a skeleton, you must @@ -17,17 +17,17 @@ # projection, but ``use_cingulum_mask`` is set to True by default. This mask # controls where the projection algorithm searches within a circular space # around a tract, rather than in a single perpendicular direction. -# +# # Example # ------- -# +# # >>> import nipype.interfaces.fsl as fsl # >>> skeletor = fsl.TractSkeleton() # >>> skeletor.inputs.in_file = "all_FA.nii.gz" # >>> skeletor.inputs.skeleton_file = True # >>> skeletor.run() # doctest: +SKIP -# -# +# +# task_name: TractSkeleton nipype_name: TractSkeleton nipype_module: nipype.interfaces.fsl.dti @@ -128,8 +128,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/training.yaml b/nipype-auto-conv/specs/training.yaml index 00b59f7..fde680a 100644 --- a/nipype-auto-conv/specs/training.yaml +++ b/nipype-auto-conv/specs/training.yaml @@ -5,9 +5,9 @@ # # Docs # ---- -# +# # Train the classifier based on your own FEAT/MELODIC output directory. -# +# task_name: Training nipype_name: Training nipype_module: nipype.interfaces.fsl.fix @@ -71,8 +71,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/training_set_creator.yaml b/nipype-auto-conv/specs/training_set_creator.yaml index af7716c..69429c7 100644 --- a/nipype-auto-conv/specs/training_set_creator.yaml +++ b/nipype-auto-conv/specs/training_set_creator.yaml @@ -7,12 +7,12 @@ # ---- # Goes through set of provided melodic output directories, to find all # the ones that have a hand_labels_noise.txt file in them. -# +# # This is outsourced as a separate class, so that the pipeline is # rerun every time a handlabeled file has been changed, or a new one # created. -# -# +# +# task_name: TrainingSetCreator nipype_name: TrainingSetCreator nipype_module: nipype.interfaces.fsl.fix @@ -68,8 +68,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/unary_maths.yaml b/nipype-auto-conv/specs/unary_maths.yaml index 2c0829b..7666385 100644 --- a/nipype-auto-conv/specs/unary_maths.yaml +++ b/nipype-auto-conv/specs/unary_maths.yaml @@ -85,8 +85,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/vec_reg.yaml b/nipype-auto-conv/specs/vec_reg.yaml index 58dd74e..d8908a0 100644 --- a/nipype-auto-conv/specs/vec_reg.yaml +++ b/nipype-auto-conv/specs/vec_reg.yaml @@ -8,16 +8,16 @@ # Use FSL vecreg for registering vector data # For complete details, see the FDT Documentation # -# +# # Example # ------- -# +# # >>> from nipype.interfaces import fsl # >>> vreg = fsl.VecReg(in_file='diffusion.nii', affine_mat='trans.mat', ref_vol='mni.nii', out_file='diffusion_vreg.nii') # >>> vreg.cmdline # 'vecreg -t trans.mat -i diffusion.nii -o diffusion_vreg.nii -r mni.nii' -# -# +# +# task_name: VecReg nipype_name: VecReg nipype_module: nipype.interfaces.fsl.dti @@ -119,8 +119,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -146,8 +146,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/vest_2_text.yaml b/nipype-auto-conv/specs/vest_2_text.yaml index 599cedc..b4dbeb3 100644 --- a/nipype-auto-conv/specs/vest_2_text.yaml +++ b/nipype-auto-conv/specs/vest_2_text.yaml @@ -5,10 +5,10 @@ # # Docs # ---- -# +# # Use FSL Vest2Text`https://web.mit.edu/fsl_v5.0.10/fsl/doc/wiki/GLM(2f)CreatingDesignMatricesByHand.html`_ # to convert your design.mat design.con and design.fts files into plain text. -# +# # Examples # -------- # >>> from nipype.interfaces.fsl import Vest2Text @@ -17,7 +17,7 @@ # >>> v2t.cmdline # 'Vest2Text design.mat design.txt' # >>> res = v2t.run() # doctest: +SKIP -# +# task_name: Vest2Text nipype_name: Vest2Text nipype_module: nipype.interfaces.fsl.utils @@ -86,8 +86,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -106,8 +106,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/warp_points.yaml b/nipype-auto-conv/specs/warp_points.yaml index 2bb497c..4acaa41 100644 --- a/nipype-auto-conv/specs/warp_points.yaml +++ b/nipype-auto-conv/specs/warp_points.yaml @@ -7,13 +7,13 @@ # ---- # Use FSL `img2imgcoord `_ # to transform point sets. Accepts plain text files and vtk files. -# +# # .. Note:: transformation of TrackVis trk files is not yet implemented -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import WarpPoints # >>> warppoints = WarpPoints() # >>> warppoints.inputs.in_coords = 'surf.txt' @@ -24,9 +24,9 @@ # >>> warppoints.cmdline # doctest: +ELLIPSIS # 'img2imgcoord -mm -dest T1.nii -src epi.nii -warp warpfield.nii surf.txt' # >>> res = warppoints.run() # doctest: +SKIP -# -# -# +# +# +# task_name: WarpPoints nipype_name: WarpPoints nipype_module: nipype.interfaces.fsl.utils @@ -113,8 +113,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -141,8 +141,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/warp_points_from_std.yaml b/nipype-auto-conv/specs/warp_points_from_std.yaml index fbf7d17..7320302 100644 --- a/nipype-auto-conv/specs/warp_points_from_std.yaml +++ b/nipype-auto-conv/specs/warp_points_from_std.yaml @@ -5,15 +5,15 @@ # # Docs # ---- -# +# # Use FSL `std2imgcoord `_ # to transform point sets to standard space coordinates. Accepts plain text coordinates # files. -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import WarpPointsFromStd # >>> warppoints = WarpPointsFromStd() # >>> warppoints.inputs.in_coords = 'surf.txt' @@ -24,9 +24,9 @@ # >>> warppoints.cmdline # doctest: +ELLIPSIS # 'std2imgcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt' # >>> res = warppoints.run() # doctest: +SKIP -# -# -# +# +# +# task_name: WarpPointsFromStd nipype_name: WarpPointsFromStd nipype_module: nipype.interfaces.fsl.utils @@ -106,8 +106,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -134,8 +134,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/warp_points_to_std.yaml b/nipype-auto-conv/specs/warp_points_to_std.yaml index 395843c..0cfbe88 100644 --- a/nipype-auto-conv/specs/warp_points_to_std.yaml +++ b/nipype-auto-conv/specs/warp_points_to_std.yaml @@ -5,17 +5,17 @@ # # Docs # ---- -# +# # Use FSL `img2stdcoord `_ # to transform point sets to standard space coordinates. Accepts plain text # files and vtk files. -# +# # .. Note:: transformation of TrackVis trk files is not yet implemented -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import WarpPointsToStd # >>> warppoints = WarpPointsToStd() # >>> warppoints.inputs.in_coords = 'surf.txt' @@ -26,9 +26,9 @@ # >>> warppoints.cmdline # doctest: +ELLIPSIS # 'img2stdcoord -mm -img T1.nii -std mni.nii -warp warpfield.nii surf.txt' # >>> res = warppoints.run() # doctest: +SKIP -# -# -# +# +# +# task_name: WarpPointsToStd nipype_name: WarpPointsToStd nipype_module: nipype.interfaces.fsl.utils @@ -119,8 +119,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -147,8 +147,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/nipype-auto-conv/specs/warp_utils.yaml b/nipype-auto-conv/specs/warp_utils.yaml index 3132d25..0210a25 100644 --- a/nipype-auto-conv/specs/warp_utils.yaml +++ b/nipype-auto-conv/specs/warp_utils.yaml @@ -7,11 +7,11 @@ # ---- # Use FSL `fnirtfileutils `_ # to convert field->coefficients, coefficients->field, coefficients->other_coefficients etc -# -# +# +# # Examples # -------- -# +# # >>> from nipype.interfaces.fsl import WarpUtils # >>> warputils = WarpUtils() # >>> warputils.inputs.in_file = "warpfield.nii" @@ -22,9 +22,9 @@ # >>> warputils.cmdline # doctest: +ELLIPSIS # 'fnirtfileutils --in=warpfield.nii --outformat=spline --ref=T1.nii --warpres=10.0000,10.0000,10.0000 --out=warpfield_coeffs.nii.gz' # >>> res = invwarp.run() # doctest: +SKIP -# -# -# +# +# +# task_name: WarpUtils nipype_name: WarpUtils nipype_module: nipype.interfaces.fsl.utils @@ -116,8 +116,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true @@ -144,8 +144,8 @@ tests: # be terminated before they complete for time-saving reasons, and therefore # these values will be ignored, when running in CI timeout: 10 - # int - the value to set for the timeout in the generated test, - # after which the test will be considered to have been initialised + # int - the value to set for the timeout in the generated test, + # after which the test will be considered to have been initialised # successfully. Set to 0 to disable the timeout (warning, this could # lead to the unittests taking a very long time to complete) xfail: true diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py index ff3794c..9a674a9 100644 --- a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/__init__.py @@ -8,7 +8,6 @@ ) - @FileSet.generate_sample_data.register def gen_sample_con_data(con: Con, generator: SampleFileGenerator) -> ty.Iterable[Path]: raise NotImplementedError diff --git a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py index 3c22cdb..a213223 100644 --- a/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py +++ b/related-packages/fileformats-extras/fileformats/extras/medimage_fsl/tests/test_generate_sample_data.py @@ -4,7 +4,6 @@ ) - @pytest.mark.xfail(reason="generate_sample_data not implemented") def test_generate_sample_con_data(): assert isinstance(Con.sample(), Con) diff --git a/tools/requirements.txt b/tools/requirements.txt index 3b7ccec..bdc0666 100644 --- a/tools/requirements.txt +++ b/tools/requirements.txt @@ -1,3 +1,3 @@ click >= 8.1.3 looseversion >= 1.1 -pydra >= 0.23 \ No newline at end of file +pydra >= 0.23 From 69935aa62eab034b4782300e015bb8e04b2eacfb Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 16:04:13 +1100 Subject: [PATCH 012/224] starting to set up install --- .github/workflows/fsli.tar.gz | Bin 0 -> 28551 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .github/workflows/fsli.tar.gz diff --git a/.github/workflows/fsli.tar.gz b/.github/workflows/fsli.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..5a3daa4ecb43e28fe1a9bf3e220a0fe25ae46927 GIT binary patch literal 28551 zcmV(?K-a$?iwFR65dCEU1MIz9ZzET_DCWJBoFqzs>=WPw2SE^&Tkcb&n=DCvwKb;q zmb=w%d2|~|?Vh$QaEfG6s%er%R~2<}?;hlL@8926Um zm$buk3H0CpuYCTa|LQ;fyPySQ*@8Kt({OvvX3%~#N~kD|2h2ks#4@Xh#1l$*xG3BMb`KmYqDpWL_JC1nitBrVGI_5bm2{^h2v(c&FG8f90rNfwU^{4vaCqj)V(CP`c*^u#`?{l7cCV_W?^IfoJCahYbb zHT4*a^fn%MvVPHf^tdzXmpAjIC%vuxC;!=3dC&k14H$S}F`}Vs(@Bg`c5x@HGa`5K$vy~@b2FK9C?%QQ8crnS! zqsPydji4FV_ukIFDdIowukXEho^Ji&yYcq+Bpbatx*GnRUG6^o;pf5gC)2?nzni~J zpIj!-pIp4Xd9o4Td^sIHynZ)$G+GS4{qo|6S9_N~%=U}755HXe@a^{HaQc1m!<&~s z|L{kC9>00=^XS``#o*iTZ+2(jJo)4GH-q@q(faV!-qT%b>uT}CbmJy|v$GgHI$ykf zv$q(%DX8ub-+uXMFulHf`{wB9KR)_y^25W)&!bo0U5vh+Tn^GN%^03jJ74ad{Gk|Z zeEIX?$=>?zw@2gAtI5?5CmT0Eyt$sd{p0>*_v(E2`>QSaY=5(*KYLsC&-0CyhtD>e zmSqW8|9!p6RyH0zTDsGK;^=*I{>@-~^xaXMK6&x-hwP`v#|PuZ`VYVV=KT5Ac073W zs@Okx6hHg!_Yc2&@%#O!3lHFzepWWtpERxs4&c`!NLHSHxool(GOV|I^y14O{(vL= zX8pTw&fm#so6mK%fhu9O^6TKPfByXSpWmMQyXF3W1PtJ_hn4&P@zeEx=KualKC7Ru zEsA_?kj~bU*<~=lDKE0w%IeB$aQy0f+I2ZwKucD{XeLeE|v?*@9i1jR5<=Vb(M z?%lh0a*-AR{J*?N>|%tcrDP|#x=4o?!7!c$gCsx<5tNxKiM67Y6>5je2UA#_&6Sm) zi^b!?B*EhFHMvfPixO&IrR7C%NMjBjM$dvQ4`#^~?Br#Y(peA(_b%gE3d6gns>AHl zJey6E8IBX%onyrPFzqmo%-ofO$v- zZW4-=7WiaPMKE5>hPVz;VMfy#0)~cb7)r+g<@iP~$3Tsdn}Auu(ypwm;248`f4nFc zdD8F8FoJoW&dR=Oz7ven%e0_xi&;9%MoE8?mPsB@ij@_qLWQ$zQm~u>CNVD6yR3-j zF+eZS@3OgiS1bneJR2rOq23kxU71{$S9v@)^~x*tuKtPhbAWr1G?zfYL6ZRd<}!G< zA>rIyVmzD1Xy5OB&_LPm81|aVNtQ`L&W<4-+`nJ5+Q#&$HZ9xBlc| zr5P+>e$t7X#na>=JPUei1oqPv9%pqL?vUw7Nl$#dJi`qdV4~|R>j;LsSla3zumBE$ zORlUOzWsjt2<8L}9$h9mVy1pN8)v7R56|E=oB((!=OBX9xC>vCyw&gH%=`T|lvx#w z3hXE@YJrCqekLW}Diz{s*nx6E4%|sP4~8rKemp2}D*?Xj0Va#!CxR8)=cnz6%eKN{ zh<)|@YLHkVd=z~dt%rz!cPdwIAmxJDVmg4X1G+Tvwj@M8N8B`8xw=SZ36z9e0xm^e zCmYjEQ@zIV?iPk=q_F;r?U!4xcTf5|`^P6+ySrN_I|uvy7duDW&rc4H-twgWoTalC z{7tUsaJj%GlDERYgzZic0(4+n(9(-!94{tioh%roc>-rWZJr@yzgzw>hY_yqgCE592CKdyMr zJ$}MEFFXZGWQ->f@ioom_0cYFFV$d`ra}@z>IArxh=RaPV9jjBEs-Lv@ZIsjKK~Rt zOwk8;Ch{qRD;{JEKs=XmIw2|p`dyK&gEY@^lF)F}*!rd)O$ER{fd7Etil@L0x?^1d z>Z^nwYbaoFr``!*6hO)3(0T#`n_z!i!4S4J5Ffe~1ddRU#XK3N<5UrXIIeEI*6r%D zz>>oEQJ3zTY>vZIdmGpI#rF4VosWNo_4TanD7jSMqw>16SC^pZz9tBDs;d(RD09Jc zt5*e}2xQd^_CK_cOtLwWt+YjSb3tvTplDyc)~mHrhdIM%HQ1G2fwn{-=Y^kqA6~?> z^CY;)uAojF0FEr;bJ}r49Wqgg1EHVO;#~I~t?cZ-JYd-Mf{m4(y~Bf}ldXL`YY$ic z@ET4X9DRKEXyx$eVDIpROFmwCvvst;v;Qsqda|;8baZeetvp@X-aCAy+I&X8wvKm> z`Pb|H7u!d>JNw)4>x-46?c?neDf#8f*8cI%^Me<(6W-JEn$c|r;g9Q&9-TgVHVr#^ zy%9v`7iDmsCpTO{Pe4`p@}XPd+dN5TRMt#SH~w@=e;-qo)!>`SB6+X?79ywZiz@^9a$Q{?)WHNyT#2*Hly6}cu_$c9K4Qy3Ory!Jka{=VP z8HWMCs_?i{;k7eevp}l+dbNB(3>_ba$<4}#m6cI4#!I>n&!#Cn?O&xMxOB(x9%-)L zel|MdPD@p6`W(Zy`X~uU}o$$z>eYUNx|m_ zyRY~5k7-!td{HuIh(b6(2L(_@JP1u|;wR^MGaX$YQmcKseny3b-rA-=aA-{v#Je=M z42#l&$qHM28pIxZWSRkaZ(qaJRuM2APw$eOt1KVsF+{=6I5^3H;%<$Y_G)*kw;~SCx)6}m z#v@^RgbQ!7`5X3#Qh_<&Q}{;h@qloG3}g!q6bn779l{{sV#E!JOofZ$9Xs_B+V;LY)hlp1JR?915eBM+w@w%` zhol~vIVspa=wW&NSSSe&;6a8d<%`=T5HzK_O}MRCz;Yvi0w=Vgok5Wqf%e^D{mfT^(@%de4( zrS(O&AC?$yk|iM`?47JA?d%Y!0Zf>%0Q(SX3)!#~7iHtL0Zn=uS)&;m%2gafW> zJZ29!@sgYapO(P-hC|;1%Q-6@$jtdp1?wdXL!g_ z?U@c)C(T^Ef~tQ&h~2z2&QAf0;MDAnEI>7h6s(U7u_u4;QUw9hBdFM<*4!Nie9h*7 zRN%L|Q;6Pna6MLY&n!NPNUx?(WjX@LrQ@5vk|4Lt(!Wg47da|RfRwvJ&4en0BrqPe zd@-8=LjkkK3lmG#+LJ7lE$_$BjkyHcXMd4cYtqS(&hQ1rPz8D>E!c8i-tMc3p%f@CGk? zsKdA|o{~J1kconY-IUVVkkp|l9UxX($@!Qz~hS?rliX4;p2c$rOgAh8XdaRyzVFG|2@`4d)B|V-vm58TxW7dNzh%!(|N1LC&%hkiF69T;_f72EL9W*D1Hro=94!rlG45UX4zH1Yp2v` zk^TbjWP!ORtuR*TdI~SfA(gLIfO~j0YDw2+Rw7%Q;3+9o*^6vJ$iBy%D%V^K9z9(b zf(MA8MM*Rq7EmSba|tNVfIPrLU=C-+}%-rw82e=PTmKpu&^ z%?Im`MjtlcZ>~QanN@{mIy}6N8ic~0%=6BYWYmvG@UAsVbJSH-*QsDO2~L3&2(S*I z9<0RXQ?Lzz0J%&j$$3KTn;zM5MHAHC@x{66?c{Psuqroe&ZDov@6L>RJe zt(XX{UT7H=gjFKXrSafLnpYts%|*f1%p7sj7T~ELDI61{EMb`CsA15Ruvmg3DP|f` z42uUUiY>mEhq)OX^J!wiDv0wcMiAPP9tb?HbqMVWI$_D9xB1#k=jENd7a0LG&!LCy93J{ zP6k`s@WLp-!9As!_(v`Wtlneqo2uvcA2w~SuEOZrE2=95r>Z6Ro{fV?XHF9x-4SrU zHk5?Npdwm6t+)%TpqhA3nI%N>w`CWjRc35=>w-Hh9hG)>tR7oT#H~4&xdktn~rg?(ewv?rjLLn4fhZyD?EvaOim~K(tOcLD=&q;xbM0iwnq)L!z z8<{3|_G3D+OyWsX&e@aRBKa#rZ&#TVS;*2}SLV=G{=t|6Me=nT&*JkWXG#f999&ba z>@vx7Ak6#lgA@!MQHuc!US>U9eBg6|)-MzKQQsf2GCB&ReWh%JOMYpwr%3`$xH6itZ< zPc(fu!tae@5BcbdcDuqv<;kVIBZN4-8Yy9j!?~wpd%@iemZ7c!cM11nklIa}Oh(fC zN+Vl+d%H5owp~kB6&J+|EmxSzTA+Md0=1%t$p`-`&S(8>)=$vXriJn;rR#vNRUz67 zpt1QP<=qRIfQd^ovZ$B{%$06L%j;2##&94_G+8uQviLEaaK<8PC%E zJQ4xGKe#grU#iBiQ{cMns{+d-5L8307;veDKeYNp7YJkICI{-4AY!k~fUZjtz_Mbb zLLfmr5Cx9c8{GWF5WuGV!*Rxde}q$Ksm@Yd1`WHfr- zjqb0k*2NKz0#E=^!WhWntY?6UAGu@%1opk7!FIRH2iF#vq}Cjz_61q#$OZJ*TsQFE zplvovA!LOY2rDI-Gjr}1I+ZIpci))@yj^4^EyqZ2iXm++`1Q>rL+ zRm0dqgx^=3MvVZ{S~Lq>9;7+RW6|kb=voSYwaaG*fDe(p4=(PnWt#u1D!Piv10< z;w*bEdKpeJS|M2LxI}V^pRo1*LtAsD4coOM zfmBT^3D+cv;c8~95uf~VlnzT<`WTZjE?QN@v$UiQWw~+ygO{gh^iWvJeiXbDwTe=6 z6v5M8)g@WgK*z9RzJnezLDg2>8^e(wUX`?F*00s)ceY_iD z(M#B&&ky!rZ0TQnTYKM_Ux#l`ULEZ7&vpe>U=Mf&Upi7nc&a#27Jz9`q5)%?cS!Dq zt0GuK@vmO9sKNtpQi*yY%=!-4!V59?8Ys&qMbca(0DZfzw#daL;pMPjr-ih`ECrjk zde=l$bgQIZM03w~%7X>b(Iof`I(V^jv<4_6PsnJvK$j=J?%>@U>n2_eTI81ldkPC8 z@7z{KnOA5_kffDa><)mD4A7jYB00U-a{jV zWcsg_O?H4S`QDmj*s6Q9KHCk77s|Ey5_XP_J=46#s0|e;R47hv!&DprSQt8 z-n4F~1Q}IGRZ`feT1gFxDj5-*7tv|^X1s5j6y+nhO@TxsX3+B*cJFx(Tqq+&PXUX# zdbF|r?4hqrQB2T*BOTvVi0&6^3&zG=KOobGBEBT_LEF|EW8})##oDc}hS^ecMoNsd zTefsv+fSxrJ+V69uix})&DV@Q)C6#>_Y35D;WWbp+G?90qSqcwfz^Oy=Pv^=^e&b+ z-Ltb18lfedVep{IA*p4#&0qt%$2W=aDs+=C(Di6WCRMXBSrLqarVl~`>=QuIJcVhM}{GPpn%XfZD~5XS5lI~CBu6?Fki38$JH67wK^FNw6->=4T! zYc=SSphMYM$Y|SI@}a0bgQ&?;_)+x8X#<};HWVC;CqaAhlY{36yZw{hW2dnF0zFmp zWEhvq2KiC6v2G*hAP`5YUeJ2f2_Ch*QZ(FAioH{hk_l7?vKHe5v|#o~(^x(CpYQH$ z@1KP2O{ok;B2R(4wilX_`P;i|Lzf%p$9^Sw}gfVsodmC6qGWnT@ zG53IOBW>?D6nj5lXV1%v@XRY_{C#pG-l(b__c-ClT-$-xMXS$}yWJ_*B)-6p5@F!z zmkBZOa~DAdwOJEpRA%zPGVrcE2Iv!;Um|_?;Cm1Z!2?~Em z=~NLOHW0H-PPIs&lL+4sxop)Y`d-;YZ40H;6cu&81nnVhS6?3@yMxlgnhRkZ-IJP; z7?pbF(;&U0!8NEV=x|l#g|BByV4&G+Z^yTY3u#DxvAzCiJ9VO5IjjtW_qR- znU5H~(rc<`NlY!fbIbGFb&6L7zL!NaHs1QxbJ(wGNjid{m9f+m#gpuCuA9pfau>|< z8)K;cO&-r+U_>k4v8uii2pSXsBNtb0)L?Xo2B*>Ia14LFn@AR3oe~Kuf*`NlO{`ep z9cKitmY-$CK)D3+vLj<35-63J3;@bE^1y&83SLxuEG&^J7Qxs|C~D1IshdFr-LIg} zucNQ9Px!-~!WZu5Yr-hwTZHl^~1xy6zzKKRa0Z=Lu8(}q6sFp~5p<*PosTR%V5em<#Emmh%3J|CT zv1+8=4NY7WLGZS)>V$3EaiE_Sfycq!**BB9tIcX?D#YyGmY5hl6c)@T#1=9ufIzUjq}8C}G3x;H%)-W-vgl1>AIefEe@Qzs7sfCpM5;o{^bR z3HryP>ijBP%IIESXA1Is6qK2b4uyfkJNp%>u4)jD--7O{Me_J3Ai2EP*)1d&t%%TF z4$0L(YSm#E=B1b9f;J4r)zY4Wk?fWqXJOk{{&b>B8qy12S=$|-qr6z&R2JMCAnNdD zqt+>uItv~w!D^Ze!)pyMHN7?Md(9?l`2K5Iy>-yTs5gnH15_e!s=K?DpKhGB@oK_0 z#r_6JAqu&NHt)>rW`jQ`!_snlOet25mdfL03_a#>6Quyb_@)pyHdoPTjzSlWHU=4S zWS8+|!Gdv?MbJI0O*dlG%OEC0jN$^el+zHYI8{TA;RoQs#T3mu(o4j03zkpUTL7w= zRikd@Vh+q>VtN(Y;dPOC1wxFSNrg*J8)QEbOq22=BZU-$Nl%DRThg)MA~7Nr+{634 zc`KfZ6-WGy_4RgL95Pq-8!5Y+ZzxwGM_JQ{Bb}E0ehaT#&+!LRG?}1hZ~avXy%%^S zoAglQY1s?kZ$=yA58nE?+D&!IL%ZoE0#F8~VCm}s-yvePtpx-C&qW)fL2b6MSqqLb zf&K6W^LmE&N(-$sgL`}5-0KAQ?%(UQD-|?YHUn*}iFBlT%-a;&DUyUNJsVM=8e25D z0gk9&X8q})+8e-F-F|3&MrKoD(yl@tG1ipRvBqGp&XOK-LwoUcI$g*x(H~U|a)rjD zBg*fzEohrRCKxO^b-BB3?KA^mq;3*KjQ4XAh5vP!4Vx-pX8tzPqn!n(~^y zS87|MHiLAEXkejPfcjo9LKL_ZA^zH;oR!No86?4FWFnzC&Gh>iKdDb8Y*GF{6eVtc zK6@JH*I?Va#4u4+)x6LW=H0S3EfnQ%jlHUZz_A9DM?Lww7KkyZvwLWnoLWj}!GG(u zK5FFiBu6%N>8NGjQphSboccztcUyS_S8(uofITTZ+@^ckzK+QkQ|{yXV&GG!^tHLX zgJ#=wqcC(sbYM&rC*%p6x&xvy)*IY59d-jB8$j+xUILk_i`~MMmY+J5Pj&6xbyv}S z@MEZdXB_C-@2C8gf(N}6>HjG76wbmuwv}01AQH;T0*y!o4NX%4(voeXW@V6)sc8>D z7qO468D2AVE!x`eP=l=^?r7OcXS)@3^zPIWk=Z=9k87`PB&^%iyRl))d?&aY*He_t z({ZA5x=j6>=^$ecFZ@Sj8`tokE(MmVnJWY?<|S}L$`KB@s8(rI_Y z?tOF}n0HY+8zt8*tkA9&QE{f)!F>{|NEK6#q(7z`iZNA37+6aDZ-302k%zMm?rnrE z80honunvyB3JM9RD_m`&8u0m6)p!Bv81XwsYcF-0Yg^C@cvIO|y<>G)4GV?vVG`N#aOR>K&PxJsJz2jM z(5kj+*%F#GExj(_pg=58u{J0c<8gW|yI_qmyD{z;7;-Dlnkwn71K9^pHc|MB8J`lA z`wibEq#(dJ9mtDVMezegF?bjNv%Eq-HRM(Zvr&{!Z`lWQIwWpFGBcpB5w=i+LhbPc z+i<3zm|3Gs3;OMhlqCp765)DGX#i9;vC+1Dx~8IUFx}|JtZgpb2Ez3ePso`K)^Ih1 zUUap)1aP8H7+^g;gge(05O|KE7OD6Gk@*mnp@=Y`&K)cHE=t|d?Kr?l)rLNy+H=Xu z!GS(vD~CjMNH$7bp@Sv_Bu;}%XV&G&d7@K7Y}7?91_vi7h{r^sg-+4Ikw#hbLSkXq z{YgA6C}LTW%wr6XNNrJA`l2HyJQ8=F%on%~<)iW^==lcb7O}pExjJ zdR#;UN>bYO#!U6UL$<#9W}3}VEokh61-vVF7kUk+zP(J5BV=Jc!Y11_#V1HJVP46> z-Y2fY^dxpDSl=K>XpDX`O&xj2e{_*q%!G+lK}*G5A_|VlL_iWn(2g0#b24e+NQEj5 z3w_`b?3=2%0sv+q{O8=V@}%xowW^dYgC*_kl)3Eu8;9xYd8mwmmPe05%~xhA);}hC z3d(~`M4_tmMH~9#XUiXRrK>`V6CsP@DlE55{t`%_qMC?NZw>5FqQ-Wd;nRP3^u}_W zabebYF_!g*_m>mL*38k`ZJYm8otoW?GkuYgC<6%?3>QBdsldUuR~3g2MpurjTXu>) zbk3Ae?Vb;Y+9QX}J4@AaBw5VdOevrY+=uY3axoBm&=QnTXG94;TGiWwpjR(slU~+- zaOP{N^p3>h_m zu?xka&1S`7$`^odOIgtDb3I}sB#%vWLf_nQa)82sDDA0=jwMsRrJ&U! z*{b;uOtpw5t%}pKDlCIz`zA(|B@xpCm5U4YFwD1H~dG zj`3c&h#Yj`44&78hFG7LHFL7LTRL$mA%aYp&pgS?8w~{$ILreJMUp8WW+-J$$msS0 zo;;m6kRpYE0+qFalrgY#a_hh$e;x*pa)GS^NJ|b0MpooA&2HMkjjFX=_@zZZp1_sf zYTsJRg6VCwESYO4;NBM{S ziKfK_?w?4ru1HcZRe56F>P%2}Soh9aPXAR+T?B3fd3xpqiop*>_cK?bf3;Se;_5ux zyNf%-F}A9K{66gkRrNfZ%N*e{O_Oa7>_dj3YNA{{;lxDjr-5#VFgP10Gj;CB%$xiz zyn$(?fd@UFmRx<5USpP3kQRQ#>WB%K?diPqw8;(_wIjr6_4YG^4BcOSVz80F?!1`u zaEEiC8@tPSXg&vKUH`p055D8@Tbu@e7|o?yt|}?u$y#P9%QvBagSCn_V_P&BDylXN zlpsm_%HW3#GTDfaj53kIAh&s_H(Csn;2sU=p5mRHM;0`h zY%h&u|8y}aQ#KW+)`}$-Bqt=Q^^CVFg+fOH3ffX@40b}s?C?=C2IyS`IT<(LZA^iY zBb|mt1O&0~(y4xQZWf=p#bP!@a|>m&!#-2iZO8LTXCrd41nvbEI2gyxtZ4(8W4%2Dk($W%6GP)$)I&ndp#di2D>skFPQ71VRA;bxGr zEk~*~=y_PpIb$1=)cSzurVkrUSM=+u%ZgWgRhy%Vh4(|JH9b$SZg{5Mme$Xl7fLOL zRf&4?7&Ch57yR_~x4Tj??szC0iS_+Kuu&_07rF;O6w9LePz4KDJvb2K0K9mSZ6ewx z=)m7b>vkzavL{2sI3}ZP7s>Vu4aZK|Wv=_}GU;QCJGDuc7|Jx&Fh-fifMQ8eGR#z8 z*vJ)rRBX@i5nJs7)nGO(If~RBmPxiWC5JEsl*f+Ejpf}y-1tVTY-#m?>iSsqVG_Jb z_IQtk1~w)KC?-iVZwV6dZ&@20?uqfirm2PIxir)m3imtDfH?QecoiW(Ok7F_@aV?+ z`hCW>N)k}3%2=Zo_`KnKS%VivZo|OqArsW+?!@MD*97Ym`pD8HWTz|BYxzWb)`zf8 zR%umh2+6B$S_1QO+y&1xg%pI zA0!bJ1-sdKA;(9uz{9{@BD>dvoi;)TKtAmbjhnco?7}OlOt_vqzn!GxOLA z2BOtj%P_OqE^C+^U&^YlWXF_LMZ~Xe#Rg3f#H$y zMuz95os?Vc2m`=YQ&Z`M9ZNlwP~0W%Brg%l%&=a)u?DpW4bZ4Yg46rOnWX!&jsWi` zW$aOF+yS5G3P9tEkX*l=oHorJEXM&=&5N=ZaJ9%aZSO~MqO8)dsJ2*G;Ak{0D{8e?7 zAE%*g)=x&9W~37+)s@jxGiGi(0?r2H- zmg3pFEYt0%^&U2ZyY*hMC`fNzJCLu%QNvNKo0Zriw`&PHEAjSp00<{%kpEPz(oFaa z;{whS>?O`qILD|AjL%U#X5l2OrWH?Bw0F4}VF%}n82G$0G1>pBJ$AQcS8?Cy)EouJ z870HQSewf3%c>`F;w6AC$Nynme=oTv2gvWYj(Xp3?Y`c=XLkqdmvAHovVW@t-*p4` zTJDxMa>1~=*LfZkX4eNexlV?Q($;@! z2XP$ZfaqB45K8!Z_vPqUPT0 z6vvCKn=CJb5=&y?KU=@OAVy93tTh}3pQ$uy!Ds93;NSe4V16}f`|HCNc-P@byJofO zv17b_$~Jrdp?B~7hkKTP2e#hIi1%mU+FD7Nasm`$DJddQ@nm197rPc<8+wD6!6O`t|LbfN+nZ?#hlsLg>71n^9R(07_miDh~Bg@x>89QW(fo~ zBAVS;I+vErr){<3#sSgMo6UGIG6@Z5n&ob&4>b-G>w=r%fN2N3i`R-3j8T}*W0bSO@z>3g-ERCd(v%5$j!++%Y6`=Ph(iJ6pA6N1 zx(wqL&P*!74Jer6bh;?<60HQv^59e!!DBE~6JTvgZd7Sbf;dPP01Cvx1QsXa;=oUs zn1{V{7|K?tEpxMBNo^6|C8?E;3s#d3C%?=BL?*Em z#biT@!qx^ppIA3+mQ?$?w9X;hsmw(ZyIQh_dX`!i?#w9}Z3EL!`GaUK%^apGK#{go zlyrGmwKOIE2!#mn*L}lGg&VEQ;!lZdJ$|*lyNi@kaS^snmTv3XI-xY@IxZ*gSLR=F z$9G4G5};X?M4eBDmvS1i95WJ*(RU6={t2c+M%E>_*(lt*s%ezSapEbsche&2>$9iA zV>pxT>%8+CiWTLo6w~pPmKPf(mu^Xau_4Tzlch=|M}IMnzG!`#I^}h@ipisDNs}ph zX@iyB*;tHC8ti`gk-ZUiB<+R?!)%TptQ;Pon}AaSIMkC^!BSf0;YF5l#5RhR!uAR1 z+LD&G=y5fm96gw$0y)@@vL{RJvrnl6J1VgtR}(iAAdD@O4GiCbCx{Fv>A6*d=-jSJ zyrGAs7NfGyvdO4#j;E_wl^Aw9P+6gq^blLFO-E=DMfJEyriJFDIaWYP1y~h^%}FIv zK?7D39F(zXyVwO)Qw?+EYz%$n=~kJUo{v4nOhunB$o_L3Q@9pjl9o<4okA#aN*&BVh=ZsuH zjSB0A*~i9Y8&{gySc8DtX1f!OIxH7Jf9tYcCGw|eRdhiZC_wXj8_?a*lH!{2k~A0I zo7pIj7Om2=qqT6&s}fw6)oiZv;{45w9tTLWfg1#~Si&6vvOqML(J2^pcK zYRer$EUL$!&I8_}yE{YnMwhOdrjTM~Z$lFL@#4YeA^`^~MpI%=DpfQ9I}}s_VNZb- zVCP(a@l*nA*EB3Vq#lM$=RN4rcWZoFs3-=F7}jc;q>;0m*6=h`^F+;w-4%;H$m&UV z(I6oe(1mJgLlj=Z@l2l_YZrge_+P9IPae+}=ON&exSs9S;adh*0Zfp)px1>F@CEgbjmqyxAOmvKN z!y`rJu{{^7u=fNxjj4F+D-A8+*wWffVB)z~G%I?cdKg$igyW5sRoY1xvXyAEwXGal zs4PGce?93`*ZN+!j5*AtJEnHK-2|A%SoQU_@=g6zRX(dQzg`B6@^m)0Wx718 zYe^foXv4Xs*Np^7VIfcJzG-ptO|g~0ycRcxBC+M)^$ZqmeOa;ht3IvP{d+=JnV9BT z9hty|DyRe;eG;|UYtl6tIrxFKfg-n@#iIrQA)8~`*_h7^_oLDTZTzyV$BYnhGZwXPVTq#}as-Anj*W}pxRh3L|m^F_P9(CU{_3I@ZGrhX` z%I(PdIY*ir<1)t@Z3AHO5K`)9JhmPrt?3Zk;Le^;+ZPImE{FFYaOS-2DO$26WYKL^ zGlbL}-qp_T1ukQ&V#o7NZos0#_4iAn_w)Rgt!S>$atF7amW1lOD z>g|vmB^d5jFDl`TTvnK&miEmOX9SGPc4nDyn0?%?W|H)Pm3ILn&D4vR*yvd|?;VKK z=O12gALCJ31_)~e>Z>xH&gM~(%sp-<_IfthlvkQI!&+JK7GXsa5J+&&@MyI3FHD5q zQst`riCbOivUF)zS`ni_NGra?{;8p`lY&^+^f2@0JgSDAB7XlDv-@6n^&N0&>V&+@ zHXM!bQ_E&ZjT2V<=;+{R>2ka0xN-y4RYMI|Pm{y}RR+zX)7Vi+{OM0r{7-*EG3lTF zMETR<2V3otn97k64AAoz)mXHShOMP=dnuaYK?#c)pvDJe3$4m?6Ht=gS!Jp3hO+d| z%_;( ziALm9X455hPt{C1dj88(^$?_-7F4~ChDz1K=N4MnoFJbksS1K)amgN+Fq>voiN_G& zOP#_(vvqKY7S+m&*=`n&%O+Yb^|v=KRuB!DjkcrUB|wNx!mAuN6)1FWV|0@M8bSOQ z)CpV*K4Yql4Lwl2Z6(7s0&Y=WI;yWLGAiSYm`qnlrgK^jo7X%=|BW-x@cpFfYOu}Z zjo!THEW}k1@%6Ea!E@7kAEXtLNlNB2n;4^vklu>+Nobj4U==pBPn$g-<`G$X`bt+r z!dQ6DEx3&LvMSw%8Ubv51*1OBvU#te5fn~R3Cqct`LA18@({}A^Gs=BOfsr9DaUG# z2Hk+nv~?%A*UsqDb!a}6MoYOw7^Z;b`cxS=Chd2Ft?}e#!n!rsi?@lTEz^iQa%mnF zYXd1_Z=YHuZ>!^;#OSfWVy^y%3)>n+6O>(@?-EF>!yi^1*o;#LQ?rsqaY|PfLER7D zRcnO>)9Ex1mH4ZedkZ!#M!L;`=R$oPoCeGph0Y${JJPi6T_!IdRWojBjMb4L^ja>pRlG~*ee=5Aw3t>tTmLdz^Ij_Bm-Mf(KXISj z0ae+WISQmQCft{?SEf+lk^^Eagr=1o6PlvmtQOG?vHKC5=&{VhQVWp%7Sl5%DI@Vm zWBOf6A!TyGcU{49Lss6qW#m2aNaZNLq%CG)OEED#SOQju+^yP(>6l^`uqgRC!3IME zsdVpla?O%$#*)J73{A&GNZNS+xSP-P8K8wTKtCPUb)4-jDl%CV=X6^K+ zdUo2Z?xIc|Q8b_Dk2%XW)X-+!8fn`T5yJ;qf@>pK>m0XTl{cvk2q$;sGN#A-adr%E z(MGkTvr-yM<%^lvhKr+RAB|ORkH{vOZ#8w9VQ2znEuZ`GP^#3d}^ z1s>rt9V!|Yqvp?wMXo$KDH1ALB%5t(>FV@JtoVH^zd$;GF!d6{3tC9+IU9VE#gYo{ zQweX_@dnB7IMi=bKz!yAlj|7MHdJJ$!xB?yD8Ga#irUrJ5w47HK;iVJFOv+H*QyT4 zt*avN>3o&4xGOe{P2+C3D|T3x&-)Li0n6jFTF1PCs&*ZF=b=WTjDX%P(|FQaz9((Q z^*J1&oP4vIomsV^u2oNQRzyx^xrfy+?EUBnc%Vfx&{Ec9)P}cvtD3mcie$YWsQ}H; zB6J$D`x?URX38FzQ&aN@^)tM|(3{MvG)hXga%OAQ#N$(s#*J}4a@l#y4bILw>Gh~o8?D8WLMqI~@*Z_O5s!K8@|x%v zk1-6E7V<`bM~0dhJ2>14rUVoV*cRXc&PSxeFEWO)Ql(t5GeJ&XfWd(hwo7OxWHhE2 z%Hf=o;bG|DqT(>8%s?lTR?B1c>RN-=7Z}&J>POVGjX>Kq?^5n}HF#Z!EF~b4C^^5u z6uiR)2lgzb)J0j&i_Nt)=wLC8kldT4=NDyhg-(xa<=Q-hO%L$tLV<4FWhcb$k5U^G zAa;>L>jxaul zLmFvhlQcAps7@VAYSq`4tk))u-PKcD$+-fGTv1@?iXt1AKwu@3=(wx4hT1RQUb?*5TmX0iGcY-%tNBcYb->ORlB`|#f zUoW80Eq>`Md)JmW9MzY}F6#R%NsVRSSr|301s-q7&9G{-fY*UGrJiZgiQoQNLKrNy z4MzD=I`iFC>?0~D`tIUzI6_acNXKV)Brc+6a7gV@8-ICO` z?Oo5*N#^ytMXV5rWMC;x$hUJv3@J?r&n&*wy5Y@WS44N7It8hsv?=l6roLP0zDj3f}ff=XSI^vUc`&0f4xEeUU$KxuC{6Qdb)n5 zqZF@F5PP#6EE7clzGDRoi#JeZ0zYraW~%X^`PRaJ;L=XeA|kYm&pU*p(3^IU16_U5 z#(kg6Fxd=payGc^h%7jHd0`(k+@Gitwn}5Guvs(K2WrtQvgVd*Q%+ zu^7OmR2yhr(d!$R9*F7J?T1?MMfBt&#qJ5p{_BlIyXS3sMI;omHa=dVWsfM_Fn!g+e%l38P9)5~+i-`O$lbLNEz5DRGrX@c z)HI7G)T6IzN7HT4*hqWMlWvC36(PnZcWReIdLgA4A=&~Q?I*}izk`nTgIbXJgYl8X#$1dMBYXTMjmKA zCGz=3uBvdjL}Wn6PZWmbN>g5&I!zWZ_-F5-`{xJyFSh!xkGGHZxAwL_P)oRU*2}}K z*T#UpDlHFL7nO|@Bw%6XcN*yy*b z)MBlRbOd}JpPz0QcJpL0O8T-KDj=U`U>8O0HgRGz^oRvCChRCv2+T|0Jx=9@$_K?N z$A;bFtKt}TTh@ifxT7X|ba!qAtAw=A-hZ&OaKm6lEH`x6)^~nB|24nU5hW^Sb9>sZFQ%%G@NP%KyG)ltgnh%2!vtTlCkOn>ISYl z5EUY#Fvr+AzEX=6ucW}VPi_6gl2A+P_)b*gX;K78fgUu&nAgJ>vTSofxxz!=phCn8V+upv(r|ji7BPxB!i3Fe?bhqLy%E;qB=iEgH9wJEO)1~9E$Llh=uVGfqs4Ej8k7nt(} zV}Vd~C$r?J+~LTA7%OsuQcP5ybyUqH_#6Yje9pIs96LIi`c`coDvl>p){1Lt){!Fw zdnKV*p;L4UvHK~!eOT>_5(cgOh@eL!g$nvpO+}W>O({@}4W1K9fMrS;rdSzQu9^|u zIv;fEn-mxf65&R=GfjwSt*g4fm26MDe^X8=x-V_2rD~yqag60!3nR?hV8@g4T>x@5 zmaEzJzSfr_8eQ<+;pZ_ zu3u=HnPb;E(gboZLc7A*xS|ZEn7ld1;!zXFjq4PWDF5nA6LqgjZ+cub{Nt*{-Qz_P zI=$MVr;U0?t0=x$K6YsiFKK%YP6WzsHFD%#09-BGoR37GE{QqG;~?sWNE?4r7C&TG zfx4%izot%rJ~xYbHgnAWUH0kfJXNVn^mR!= zsk1!JZ`O)oj=-(@k80L}Zvf3dSw4%FIlh$CRt$cNdf<4j)ct_gglr5Ei>ZG+bIio0 zoMkPJnG5GJB?i=nD}%%NH_gzuB+#% zVu&flOY|H;-)o;&f-~||!Q6^}qUC=p^}Rh!%6Jr)u?)wEl65!X*{Q8MJoC*&wQ?F_ z@TW81G)xiU8ntlog&haM&puiN#xmB>O@S8feS=m+^$cc%n=&cTB4Il4>A_6~v#@?* zy}qA1k(r@^rLTS^t(mIf;Zj5U^oAWf%~g~2#Yb|q$fP!MqQao~c-R_~S{GfzWAG?y*IbH!`uz&{Q@-g3(u-#S+&n8i*F=k2yDG7GnT5P zvLdC`zl?Ei&5KVLL4m9!3bU_@`dPAKD*`~3Qq-c|n!V*Jn8GsrF>S|X z1x=9fi~Z}AglCF8Y6uT60=xO3I|#aSTefc3)tCNqTShC1urIZmg=A`{C9D@+hFuhp zw=T1E6ubevPXeMF;DhiS7YlW_Dg%vk*!GJ7S!M9S6&&Tb8<4@K za{K29pT?S(*x_VGSr(=Zh2=AvJ!&y!fK47U7~4L5tP?)zwuL&tmQYPsson z5pKTgwA4*z=fDVb=NMYLi~SXU{aDMmcvq|eatB~^HD9R5Y28E;_*}!6$7W(fspq|* zyaGN7B~>kD1K|if?KvrV(4x$`>RjqrbdH~|iXu+s?5WQV9(Kz>6#+3T!bma`9fhmjv}{L;bt0A zSazAe+J3kkXv4Yb%up@tuf6|Pf4%Lu`rGV2b(dpEY`7Apm?24V)FVyO5$N)4un=|w z#dm<&QA*#JthOj8;n?{PAFtbmU|cg8V5Qtcr_40IhQ@$cNeYYn*l@~VsLpIW?vG<6 z;Z(6FEU1geNqHl5Z#4`7?mf+xqy-r)3}cQ=m5rr&ExpCyX+%wFDu-RrVjvKQ??eg8 zIb{bF8(x_|sl#%-yJ6qeR7-T7_DPfCl7XtL!>=mGY^^!eCx4Z42}AYiypRwKERnUt zq@|_WF4YOqoJlvq32BH2(bv$b$v-y8*cdh$135xaN=uo6KAEI1Ep*&fq`PH~>UM>> zDp|A;gc0V5oKbO>{$g}#(Dsj@)>R6fCC|VSt zzo3O#4T@6t$T1Wr$$30PBpVl~%5MoZvMOF8ycUd5nBUS`e~c4|VGX}O`8|v$SG~=( zHlBitNc(1ps(#zO4NzP`G0oS?Y`!K#p2qpRf(-?eOA0$-6cxHVfgdG~g8fdUz1rn) z7m>KeP!{GEsN7?st&rCHs@+XW5;ZJ?)lX@7>SEQT^vm?x+!7ke(Wy}Kr!fk;n0%y& z7fKDN_$T$wD+E$E^8?@2><+={9QS~tBe4VHv4+3;&>x^Qds6u6BK5xdDJ%i}%Zs4j zL7zH)4-dF)SilM;?Nd=c7m#zR69g98>OsBWn6=T3N`Cx=UG27uFtYCXPeaQJ^dq3A zkan$i3arN3U)PE>6E#-mPmzHFi;=rokTDpVgN%~>%wQV)19-pqC1qi^9cSKk((A_vw z1$eWB4lzj|eE;K2>vzV(SCfIF}PHm5N^V*4kineqGTT4+abjw6srRCt} z(qbB@1mWbxiGp%`ajtSQ1!Hv6!K+&MBI9>oF6I*_laStHAE-F}=mBa0H$~_e3kzwE2k|oMUvw5;jiI z#XCPxhUCEp+R9#LlgmWW8yc2ogTtLF8wh{t{DD$I#}J0D@f@lc!r0PiF*NqmtHC{; z+eNY+S!n~%uM~Cy<@J){aUndO9qw?Dz!IithQTg+Qnqoc8?sTuld!?%Mn!$X(W9qw zpcqhvf)1QDbjQ(77i?ukdbafEq_9OeeDzw50;7^4OT?g8;C9i*Y9qKQC_@G0>e?5t zB9rN@e*FvMG0ZRv8S&O*wEZmH0Mpj8clkEtl`@=L>~<}Qi?jfX5DrGpa3$lm4;H-7 ze^n?fpS{{d>LGduv89?kn52U>*nT-o$gHclZeE}-rQME3R~<|!top%nIqk2|$Au+ln*Wk#|Q1E8tezGA0iGhF>R zwLmepMtD|*!>IzRo{c?y)t)k%LIayVt|FaYyUApmRw9)YbkNSrA_3rRc!yxO?19DcXT;m_Le zupEB3%Hhx2C~=wTds~;IpH9r2Ah<-0rAgB242|qGsK6tq0Pr(B><59@hLD~J^M6UgiN*Q!?Ri>60^ZN!NYd7!lUIC9@Q#5US8pG z+sq1h0VnI8BJVxam(Yz&SPKs#tckj*IDdB~fEA?!BiW^tQq=83PPJ+00vWoQU3JFJ zD$Q$>yy&Z{%HU{YqO^cvwG5^1*lTMDpyt~u;}j8qIBTdN<3J@<5%OT4%Mg;elMSusbrnC0)EE{Wf)}78icGk`#H^(J-pm?2Ld0Mk?)xcun4B0rIj3f zI!6+bAP!ucHrMo;9{pApI<*N(NX)wnjMTAIs(zzk6@=u|)+=6YoL(oRib669NV37| zS{-v(2{Pi*C7xO~bs~#&-5U+jy3E=V zN)Fse%a$c=8<9SM)5hYCFx*TSp;TlnH7afO5bLKrQL}i?asy?y#)_43jv1+rOE2;n zWL*g;AU#e;`Bn#vNd+gw&QZvezxeRUItOm7DFAZRGA? z2MKTqWv#t{vmxciCI3IHddF6yl_93D8!W1=_c2z7&ej%FirzzIj99xKd+N)r28wWV zie2(@bHtT@Ks$hvs$iOC2E;<^0bc18K zctwh*wMm*G(DTt@IcUU%|+z94@;w z;dR(H*c|EmQ{6mbYAdfMAnHH|4x(l)%#LN>f1onzV;`-$51q6i49j1E=l>}V0NJ;& z>Jh^b0_sQV$59*nmWN=T6^5jyn460^f)&urbZ(Lrp*1bOWJ@A3Yq1E`F($rpgF)$S zr!I5%zM#H>?hW8)RD+ptiQI34y#+L-T zp`PSR(8{;u6D3Ni1g)wFzrf9(4ux)2MzcykTul+r2Ra!PX_?eR54m)mUC-~4042~1 zhzXEt5_r|96siUCw;Phd_e>&Ae$r}3XyKHLpZS9P6QP(t7$3jx#>yo{ffuW01#WaC zb2Nc7jfV%vYLsdOPylGat8`{Lt?Ih|Zi_35NmlJudfCMUv4#pWn360E$U#e7yo2*e zHi+<_mO_moq2tfHQqYOfNGqvPv(=P8oys>llj?r6bm}eM^ zkHRnz-!xW_E&Cn-lKuj= z`w+HU5>h$6%OpOiQ#>oog~848-f)WaaX6tV!n3rB5JW<|m4zD_IGo=AH$GG0>_U53 z?ki_>@=AA4ql=U*)07)CQ>K$0Zw9_Axl%y~fU8z8k>R+;hblRHB-pDOFOhes#ZWOe zP~tDTM#L9cUUksiH16R9bpSbXE+$tw{71sMB)G2Z#5-F|$wr~0v>gU#zAo5gP`fbn zDN?%#Thucc84$Zsur)$c)vTke4TUFG%$TI|H13v`OT*5X0;A0mlg!o(5wRbKfK>Lq zbWYW{16D&R4v?H2P35*k{1EF`nJN!Dz6k2$IykxGC8LHMk?qrk6S>b#SK(Z zYm8KMogZhR=PX=fQ(j6I2S6>5`Npon!2(Uo(o)p z!6X}U^erb`SUS260&!_Cq7>k9-LgPiYnc9?ZbG#)WGV$H59B$v_CPP&rXB=?nscbK zuwG)1eUIYaN`P0VD~j73x_#k;D(P)D{xY%~7mIHWYP_xEFuS|IMgMk!i)_lObauG1 zh&EN;$+yHO$7Uip3Ho2wQ2KCzd?>Mic0fj|gR+O$b{nk{81k73&GFgstLg@!-<= z!e!>RH8g4BZa9%nS;iDVAtprw{LE8eLlR@+Q94q33Pel6of7tKoiB1s=B9+wEsW#O zM7^#9+b_lB7Ao-+&0B4ig3*n=HzT)zcE>m%7T+hpy;OTYBtQKaKEI3bb=P=Rv;|P%Ds|sA&rs<-IK)CfbI$H(UWM2)(=Sw`ej)91t({E*Q7Mv-j`$-G>ir z#RWhD#Rq7lvk7mo#D@=pvB*+U)D!rE9!G)QfJh&3F8EhDll=lmCDQF zsuN3&!=iiFIEb#uQL5s@@{7Px;<|ZY6(^*xs<|%~j)Fmst{&yWfoz}E^X zH`3u4U35g!XOqiWE^8Kae9|R^ zkW@ngB%M)s)_}c@Z+{4-AXj9g1XTkYbzV;?_D~NvO+32eR(QXl+lm(>?8qYgP94vS7XH(* zYsUS{M`*+2Ge5lX@qA$s(bbio4WewC}bZU9+ z@RV`-8H$9@iH0eUV{XUxbR(y<=#;Pms2xaxOOqOb;_6VE8p{QM6(F}@*NGg#~IMU>T7LaBaV?6JuOoh+zyArsj~PbWO9E0S~|d#wFc zPxWUp+9rP7j)sfl)htkwmN$d@n1#-RIwgyPT@XXaNsk>f4nL`74P-yLvezuN$7NQh zI)<=ypABEphDKQqgigN<^67kxC=J$+L_GU39Lf{5nlEwxS|kH-X4kzC_EF#VY=mY< z$pny-gib-ew zo`X_x3k|)fm}6#nZb_lyq77U$vrAFs*Wa=Ah=&oIxRi531Lqs$?`9Uh$CtnHuu zy*HMk`uySb_VLNi!M?9IQYv$YO6RCVFs<+gsm`0Es0Qr4V`48~fB3P}e93-L)|eRV zYL@=ANCMJ7tKj#UMwWgo(Zbz?G25inFq=$L4#NQxT$r4D*r?pU8oSTQC2}GWrBi@A zN5JtVdcjqM!SuDkpq<1ZwBFd+WUM5lsk<@{dRB@R?}@XT^rlFu5allrBjIcfY?{nA zs|j?Lm}WTrhSN*21@bi8sY0l26puNaUp#OvyrL*h9D1gZ?UwwaGSv`rhxpJ*77{=M z%oTOyV6(_QKc@zWQiByintFgynrs~k_Dzzv=iUbGqB1s<`%0H$Cw%NG*kgmBg{Vf^ zNSaCb!gC~5umlV-#TF;RY)G2Uf@S=PC^swYfcs$=>|!xt!`7zRi#M()aoA_V(;AF} zA{bBzK2++O$x@s!xG)$m5Ku-opm^B;s(;dh*pk|`c=?}1jl^ODx|HoCF+SXtv7%S} zmFwm;+^0u)$Ip8~!%!3#zDP&x$9WDLC>>d1XngZ2rU?toA%C&`a_jZ(Nq=Ym_+)E$ zcMGv;|HaPH_Vbg2qqlXDZoTHw!9innMF-B(@N61I7v z#W%$Y8zrW(3%{mMvML%X0=8mSR*FgB0VLE-whmYtj6XNUgoQapj1aj6ju|LriY=rt zGKYdg<&MV1C_EA=jFP!(?+T)@#1q1ab~oavG?a_p8Z!~PWa~XQF=`NQn3)dd69wNa z)VL-4qoE-2UMrC_yX3 zlvBK+x;xJRf#c;@0XmgeFa>JhiXvH1Yc2S%9nG&$G9w$>q!>YRok=K;b5YCpq9b1L ziP1Sm8Y`+KHEyU3o@(J(60MSr+9b}^Tm2@qO=#q^2}B0jD7_D3B8f@#s!QJ02O_i# ze=MoU2iw>OkECmi#J!KGcZ}wH8RytQ_yVXUlp;FSHO&>e)w9~*DOzG5DBr|w0Ts$R zsif7yg(_Ro705 zPQqU@zlw)a__6hc@V*s3g7SRj>^VxY$|+ZA0>fI>y9^QP%bxjVTR=&MJj>&j(*dfN zmvhSeg7H+uKObGclJ28%$ysCN)>T)cZ>!#=Z^suV^up+arrLxqtrLXmg#>z&Lm$0M zZj9$Jpv1X*jrlLD@Q`v!8}X%*^hq=qm2N%?Z^Qc`@f7~-%Km1&_m`5z8^0$uGGZs_ zmK>JN<+(<&b&QFn`MJ7hpa1$}ZZk1L96xi8tK+q~aEHK5Z$}3&jth)57U^0avx5`t|Q?$Om|*B`+DET2c-ijt`b)1dTwr z6;k9MW94KmlX&V3!AnQzBgNdeB-gCx{j&**?HL_nI#Q%lUdN0S*+P+^Iv5#ZioY0-j4L}=sWC-sHEzc$ z?M9z(<$podhx+rF%1up(qP zm(g@8NC6MNNLW##XealoteP*$ml^G??jRW=f_axv+= z;#@&z7!-Ogsa5Vcr7;#P=2$~=N2gf}>Uq#sE&Z-{UV#&oIhvzisDZT#;1Sclpc9$+KSyR4^f-3N8 zD~J(@l>!j;o%Whbluc;*FJwa9v2zP6THPKDj-uMbFIgq-&Rg*yH+i+ZkgD$#)*G{b z7f0N|vB!nG!7nf|y1hNww}C>`I!DaU9_XxqQYamdlN#w#RK6z?V{9VQqG&^=TY-X}vinp94y7Gv2mUn%O zOg9-Am=LCJOj`Tiu@XqSh6$eHJ~7Yov7F%Es`QS#%+gpm8$|0alzLdX&QM%sExniR z>2M&y9&SxXZ*N^m9>LS{k!#b5I&mAIMsWqplVZ_T$qO0ridW1u_+~8HiN>Of!lBQE5q(rGR zp2X*Mq9-A)Yh<6${axr%*dJ8~GkqydqcwPsbZYtFUy92GMhmc`3!9J+WoEVSkzO^> zUmuhLkX~Xbi8!ArB}zcaq$`jHJ;|_Aj+D~-k38C;=~dq8ngMi(5ka0nzGItO^@1SPaVEQNdhcseBm2BQQsziO~I0o$Q&JoKsr&u+HNkkC^D^1BHwB!Vx+6yat6^gcv zNMp^FrKm~i+Rd{vZNS7{I@y8Ld+|@u?;E@DG_POx5S#Xows*I;j<@@JTl+gNw~tTU zwsc?1#%PvURjZI)4I`E`XNoiI$9KP$muolj>ta9EuTfVa0bs2ZRds=rUYnom@&w8qQG-%fp63cz= zm?)b&Hbt7DqRaTfqFyhBi!S5?jN5?=8PhsdROun`YPLNq`>+}DYHTSl99t~VN6(%N za{!2qsqEZpo?;WELt2X@3XOY6Ebjo+wE#a<5XTiuem}kmC5H#=SJs^2e8uL?{W5!( z%)Z8Rq?eJ0d0TNcV&k`EMp)5&kEO}_E7P6r;RKhTTouY3l6MyhKKypsD!QFjxTUi+ z^1empkrJv(=qD?dyNrCS7sVdT^c|L-t3~BMcMpn7pJFkl4S{gGvoV=`aK|u+%z)wU zVplCSa%De2t}N`Gr?wBWi?8^3%fXgR4wYo2stc=UhI$Y0x8h=mEO)yI?wcq;#pZnq zNHfdYk4KyEM)qKvTtx4`+PuHFdH-0#KFYu%pgc_%dH`*;?T|N9W0flA9n{@LWkgF2 z_Qm!$ufKKAq)ZT__fhDb>vED}0#N$O8E|ttvD~_Z_H!JBRB$PB4?+=RAk_n@4`+;` zK5+uEbmm~T05;29WD|I9o!E~>hY41R@uv}MWnTUIS?PPA%#tAwND?OIR{$#l}YHNa?q}KjMOrB>GWvT-u9_mH?5Q{ zh+5utf=gn`jMZw22&Nh}&uaJmhn^+!zy|E$Id_-ekH`h~kqR6-j?+mpa(AR*ikkcw z8$C0;K8(vkXL2CUYKUhyFGAHnkG$DfqvFKO=HjZ5_F*Q1ggI6nuE#3R$AvtSQb)=s zA$l;7W;4HF588Nj*^V|Ajk07p3Q2&b?+>4L?zBEt(^j_d;hyq54AUM7+LQf8z0hC^14@j)xR|Mvd$ z{^C|DX^ivuKo8P=x)`PV;JDYQ&EK{s5>p_yWdKtbg?MYNrZqPxJd!4 zq!)$OVvO;jM6bL%Va`M5xM*!1;s%|9IlqC9gof9JFNhGu1$ITkB;q9Zy-^yU&oVKP z03HW$+SF^B7di-B&3dWRpd%Yu;dE>1%y?SWa*)7wfdc}_X%6dBM!^e{yU=K+3yY7y z#{goJ;%DfMYiF@wwPYd+($-2D(cWfgNA-QZ|6==ScV~aQgHZr`p-N(B?m6pl*?|zM z_`{3XyO;2$X!>5{WDNQH4@+Sv6tFY#ESY&0GnCCPd{94}`Q(&hG7Y zwFG-ki4(i)vR>UDj%->T_|2f<09soE5R(Q@5A}dZs13Uqdz9RJ2hm65TSYv0zi>$rMx3a%6IZfUhl+YnqfgDP_^b zRL-Q|!H7&KhsLyqm+5E`PY8PyB;)WkN7ofAm&xfI8>?JvgM=ojAt%Vx*IM0(7x+Ak zFiL*ejGHAePSRzZ=Lfw(uG$J%GQ-;&LRsDYSi$BFn})kcXP;2Xr6dH)o%yyc#b%-{ zkYe68?W+l~2GJf3S2YcVsL4FTQN(?iVYw)r zI6VSWEM-Y6MY(_cz#s4@?Un_mNI}T46@CVua)}x??Y?#(Hr5E)0I_!fd5b66m2OqV ztCRI;o_w5tuw-~U^Ky>pVuQ9{m=}h7j^{A8s5~dR{_4%ZW^82|+N|#+ZA>- zvu?wFlUEKZb+sc(^^xd?O#=Yb5&|YGR1N!#OC&;yl8B)nh!BDhrTT`V_Bb$!p2ow; S$;rv-Mmhl-p4(yomH`0v(K%KC literal 0 HcmV?d00001 From 12139f184f85d63a5005e9ae11013ea7bb8d09d2 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 17:07:45 +1100 Subject: [PATCH 013/224] imported latest ci-cd workflow --- .github/workflows/ci-cd.yaml | 392 ++++++++++++++++++++++++++-------- .github/workflows/fsli.tar.gz | Bin 28551 -> 0 bytes 2 files changed, 306 insertions(+), 86 deletions(-) delete mode 100644 .github/workflows/fsli.tar.gz diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index 6e93b4e..e13ce5c 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -9,30 +9,42 @@ name: CI/CD on: push: branches: [ main, develop ] - tags: [ '*' ] pull_request: branches: [ main, develop ] + release: + types: [published] repository_dispatch: - types: [create-release] + types: [create-post-release] + +env: + FSL_VERSION: 6.0.7.9 + FSL_HOME: ${{ github.workspace }}/fsl-install jobs: nipype-conv: runs-on: ubuntu-latest steps: + - name: Checkout uses: actions/checkout@v4 - - name: Revert version to most recent tag on upstream update + + - name: Revert version to most recent version tag on upstream update if: github.event_name == 'repository_dispatch' - run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - - name: Set up Python ${{ matrix.python-version }} + run: git checkout $(git tag -l | grep 'v.*' | tail -n 1 | awk -F post '{print $1}') + + - name: Set up Python uses: actions/setup-python@v5 + - name: Install build dependencies run: python -m pip install --upgrade pip + - name: Install requirements run: python -m pip install ./related-packages/fileformats -r ./nipype-auto-conv/requirements.txt + - name: Run automatic Nipype > Pydra conversion run: ./nipype-auto-conv/generate + - uses: actions/upload-artifact@v3 with: name: converted-nipype @@ -48,165 +60,282 @@ jobs: pydra: - 'pydra' - '--editable git+https://github.com/nipype/pydra.git#egg=pydra' + steps: + - name: Checkout uses: actions/checkout@v4 - - name: Revert version to most recent tag on upstream update + + - name: Revert version to most recent version tag on upstream update if: github.event_name == 'repository_dispatch' - run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + run: git checkout $(git tag -l | grep 'v.*' | tail -n 1 | awk -F post '{print $1}') + - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 with: name: converted-nipype path: pydra/tasks/fsl/auto + - name: Strip auto package from gitignore so it is included in package run: | sed -i '/\/pydra\/tasks\/fsl\/auto/d' .gitignore + sed -i '/^_version.py/d' .gitignore + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - name: Install build dependencies run: | python -m pip install --upgrade pip + - name: Install Pydra run: | pushd $HOME pip install ${{ matrix.pydra }} popd python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + - name: Install task package run: | - pip install "./related-packages/fileformats[dev]" "related-packages/fileformats-extras[dev]" + pip install ${{ matrix.pip-flags }} "./related-packages/fileformats[dev]" + pip install ${{ matrix.pip-flags }} "related-packages/fileformats-extras[dev]" pip install ${{ matrix.pip-flags }} ".[dev]" python -c "import pydra.tasks.fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import fileformats.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import fileformats.extras.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - fileformats-test: + test: + needs: [nipype-conv] runs-on: ubuntu-latest strategy: matrix: python-version: ['3.8', '3.11'] steps: - - uses: actions/checkout@v4 - - name: Revert version to most recent tag on upstream update - if: github.event_name == 'repository_dispatch' - run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') - - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - - name: Install build dependencies - run: | - python -m pip install --upgrade pip - - name: Install task package - run: | - pip install "./related-packages/fileformats[test]" "./related-packages/fileformats-extras[test]" - python -c "import fileformats.medimage_fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" - - name: Test fileformats with pytest - run: | - cd ./fileformats - pytest -sv --cov fileformats.medimage_fsl --cov fileformats.extras.medimage_fsl --cov-report xml . - test: - needs: [nipype-conv, fileformats-test] - runs-on: ubuntu-22.04 - strategy: - matrix: - python-version: ['3.8'] # '3.11' - steps: - name: Removed unnecessary tools to free space run: | sudo rm -rf /usr/share/dotnet sudo rm -rf "$AGENT_TOOLSDIRECTORY" - - name: Get Download cache Key - id: cache-key - run: echo "::set-output name=key::fsl-linux-ubuntu22_amd64-7.4.1" - - name: Cache FreeSurfer - uses: actions/cache@v2 + + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Install Minconda + uses: conda-incubator/setup-miniconda@v2 with: - path: $HOME/downloads/fsl - key: ${{ steps.cache-key.outputs.key }} - restore-keys: | - fsl-linux-ubuntu22_amd64-7.4.1 - - name: Download FreeSurfer - if: steps.cache-key.outputs.key != steps.cache-hit.outputs.key - run: | - mkdir -p $HOME/downloads/fsl - curl -s -o $HOME/downloads/fsl/fsl-linux-ubuntu22_amd64-7.4.1.tar.gz https://surfer.nmr.mgh.harvard.edu/pub/dist/fsl/7.4.1/fsl-linux-ubuntu22_amd64-7.4.1.tar.gz - shell: bash - - name: Install Freesurfer - env: - FREESURFER_LICENCE: ${{ secrets.FREESURFER_LICENCE }} - run: | - pushd $HOME/downloads/fsl - tar -zxpf fsl-linux-ubuntu22_amd64-7.4.1.tar.gz - mv fsl $HOME/ - popd - export FREESURFER_HOME=$HOME/fsl - source $FREESURFER_HOME/SetUpFreeSurfer.sh - echo $FREESURFER_LICENCE > $FREESURFER_HOME/license.txt - export PATH=$FREESURFER_HOME/bin:$PATH - - uses: actions/checkout@v4 - - name: Revert version to most recent tag on upstream update - if: github.event_name == 'repository_dispatch' - run: git checkout $(git tag -l | tail -n 1 | awk -F post '{print $1}') + auto-activate-base: true + activate-environment: "" + + - name: Install fsl Package + run: >- + conda install -c conda-forge -c https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ + ciftilib + cli11 + elc + fsl-add_module + fsl-armawrap + fsl-asl_mfree + fsl-avwutils + fsl-base + fsl-basil + fsl-basisfield + fsl-baycest + fsl-bet2 + fsl-bianca + fsl-biancadata + fsl-bint + fsl-cluster + fsl-copain + fsl-cprob + fsl-cudabasisfield-cuda-10 + fsl-cudimot + fsl-data_atlases + fsl-data_atlases_xtract + fsl-data_first_models_317_bin + fsl-data_first_models_336_bin + fsl-data_linearmni + fsl-data_omm + fsl-data_possum + fsl-data_standard + fsl-deface + fsl-discreteopt + fsl-dpm + fsl-dwssfp + fsl-easyfeat + fsl-eddy + fsl-eddy-cuda-10 + fsl-eddy_qc + fsl-fabber_core + fsl-fabber_models_asl + fsl-fabber_models_cest + fsl-fabber_models_dce + fsl-fabber_models_dsc + fsl-fabber_models_dualecho + fsl-fabber_models_dwi + fsl-fabber_models_pet + fsl-fabber_models_qbold + fsl-fabber_models_t1 + fsl-fast4 + fsl-fastpdlib + fsl-fdt + fsl-fdt-cuda-10 + fsl-feat5 + fsl-film + fsl-filmbabe + fsl-first + fsl-first_lib + fsl-flameo + fsl-flirt + fsl-fnirt + fsl-fugue + fsl-get_standard + fsl-giftiio + fsl-gps + fsl-gradunwarp + fsl-gui-bet + fsl-gui-desktop + fsl-installer + fsl-lesions + fsl-libgdc + fsl-libmeshutils + fsl-libvis + fsl-load_dicom + fsl-mcflirt + fsl-melodic + fsl-meshclass + fsl-misc_c + fsl-misc_scripts + fsl-misc_tcl + fsl-miscmaths + fsl-miscvis + fsl-mist + fsl-mm + fsl-mmorf-cuda-10 + fsl-msm + fsl-msmreglib + fsl-mvdisc + fsl-nets + fsl-newimage + fsl-newmesh + fsl-newnifti + fsl-newran + fsl-oxford_asl + fsl-possum + fsl-ptx2 + fsl-ptx2-cuda-10 + fsl-pyfeeds + fsl-pyfeeds-tests + fsl-pyfix + fsl-qboot + fsl-randomise + fsl-relax + fsl-shapemodel + fsl-siena + fsl-slicetimer + fsl-sub + fsl-sub-plugin-sge + fsl-sub-plugin-slurm + fsl-surface + fsl-susan + fsl-swe + fsl-tbss + fsl-tirl + fsl-topup + fsl-utils + fsl-vbm + fsl-verbena + fsl-vtkio + fsl-warpfns + fsl-wire + fsl-xtract + fsl-xtract_data + fsl-znzlib + fsl_mrs + fsl_sub + fsl_sub_plugin_sge + fsl_sub_plugin_slurm + - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 with: name: converted-nipype path: pydra/tasks/fsl/auto + + - name: Show the contents of the auto-generated tasks + run: tree pydra + - name: Strip auto package from gitignore so it is included in package run: | - sed -i '/\/src\/pydra\/tasks\/fsl\/auto/d' .gitignore + sed -i '/\/pydra\/tasks\/fsl\/auto/d' .gitignore + - name: Set up Python ${{ matrix.python-version }} uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} + - name: Install build dependencies run: | python -m pip install --upgrade pip + - name: Install task package run: | pip install "./related-packages/fileformats" "./related-packages/fileformats-extras" ".[test]" python -c "import pydra.tasks.fsl as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" python -c "import pydra as m; print(f'{m.__name__} {m.__version__} @ {m.__file__}')" + - name: Test with pytest - run: | - pytest -sv --doctest-modules ./pydra/tasks/fsl \ - --cov pydra.tasks.fsl --cov-report xml - - uses: codecov/codecov-action@v3 + run: >- + pytest -sv + ./pydra/tasks/fsl + ./related-packages/fileformats + ./related-packages/fileformats-extras + --cov pydra.tasks.fsl + --cov fileformats.medimage_fsl + --cov fileformats.extras.medimage_fsl + --cov-report xml + + - name: Upload to CodeCov + uses: codecov/codecov-action@v3 if: ${{ always() }} with: - files: coverage.xml,./fileformats/coverage.xml + files: coverage.xml name: pydra-fsl + deploy-fileformats: needs: [devcheck, test] runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' + - name: Install build tools run: python -m pip install build twine + - name: Build source and wheel distributions run: python -m build ./related-packages/fileformats + - name: Check distributions run: twine check ./related-packages/fileformats/dist/* + - name: Check for PyPI token on tag id: deployable - if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || github.event_name == 'repository_dispatch' + if: github.event_name == 'release' || github.event_name == 'repository_dispatch' env: PYPI_API_TOKEN: "${{ secrets.PYPI_FILEFORMATS_API_TOKEN }}" run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI if: steps.deployable.outputs.DEPLOY uses: pypa/gh-action-pypi-publish@release/v1 @@ -219,26 +348,33 @@ jobs: needs: [deploy-fileformats] runs-on: ubuntu-latest steps: + - uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' + - name: Install build tools run: python -m pip install build twine + - name: Build source and wheel distributions run: python -m build ./related-packages/fileformats-extras + - name: Check distributions run: twine check ./related-packages/fileformats-extras/dist/* + - name: Check for PyPI token on tag id: deployable - if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || github.event_name == 'repository_dispatch' + if: github.event_name == 'release' || github.event_name == 'repository_dispatch' env: PYPI_API_TOKEN: "${{ secrets.PYPI_FILEFORMATS_EXTRAS_API_TOKEN }}" run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI if: steps.deployable.outputs.DEPLOY uses: pypa/gh-action-pypi-publish@release/v1 @@ -248,50 +384,98 @@ jobs: packages-dir: ./related-packages/fileformats-extras/dist deploy: - needs: [deploy-fileformats-extras] + needs: [nipype-conv, test, deploy-fileformats, deploy-fileformats-extras] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v4 + + - name: Checkout repository + uses: actions/checkout@v4 with: submodules: recursive fetch-depth: 0 + + - name: Set up Git user + run: | + git config --local user.email "action@github.com" + git config --local user.name "GitHub Action" + + - name: Get latest version tag + id: latest_tag + run: | + git fetch --tags + echo "TAG=$(git tag -l | grep 'v.*' | tail -n 1 | awk -F post '{print $1}')" >> $GITHUB_OUTPUT + + - name: Revert to latest tag + if: github.event_name == 'repository_dispatch' + run: git checkout ${{ steps.latest_tag.outputs.TAG }} + - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 with: name: converted-nipype path: pydra/tasks/fsl/auto - - name: Tag release with a post-release based on Nipype and Nipype2Pydra versions - if: github.event_name == 'repository_dispatch' - run: | - TAG=$(git tag -l | tail -n 1 | awk -F post '{print $1}') - POST=$(python -c "from pydra.tasks.fsl.auto._version import *; print(post_release)") - git checkout $TAG - git add -f pydra/tasks/fsl/auto/_version.py - git commit -am"added auto-generated version to make new tag for package version" - git tag ${TAG}post${POST} + + - name: Show the contents of the auto-generated tasks + run: tree pydra + - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' + - name: Install build tools run: python -m pip install build twine + - name: Strip auto package from gitignore so it is included in package run: | sed -i '/\/pydra\/tasks\/fsl\/auto/d' .gitignore + cat .gitignore + + - name: Install task package to calculate post-release tag + run: | + pip install "./related-packages/fileformats" "./related-packages/fileformats-extras" ".[test]" + + - name: Generate post-release tag based on Nipype and Nipype2Pydra versions + id: post_release_tag + run: | + POST=$(python -c "from pydra.tasks.fsl.auto._version import *; print(post_release)") + echo "TAG=${{ steps.latest_tag.outputs.TAG }}post${POST}" >> $GITHUB_OUTPUT + + - name: Add auto directory to git repo + if: github.event_name == 'release' || github.event_name == 'repository_dispatch' + run: | + git add pydra/tasks/fsl/auto + git commit -am"added auto-generated version to make new tag for package version" + git status + + - name: Overwrite the tag of release event with latest commit (i.e. including the auto directory) + if: github.event_name == 'release' + run: | + git tag -d ${{ steps.latest_tag.outputs.TAG }}; + git tag ${{ steps.latest_tag.outputs.TAG }}; + + - name: Tag repo with the post-release + if: github.event_name == 'repository_dispatch' + run: git tag ${{ steps.post_release_tag.outputs.TAG }} + - name: Build source and wheel distributions run: python -m build . + - name: Check distributions run: twine check dist/* + - uses: actions/upload-artifact@v3 with: name: distributions path: dist/ + - name: Check for PyPI token on tag id: deployable - if: (github.event_name == 'push' && startsWith(github.ref, 'refs/tags')) || github.event_name == 'repository_dispatch' + if: github.event_name == 'release' || github.event_name == 'repository_dispatch' env: PYPI_API_TOKEN: "${{ secrets.PYPI_API_TOKEN }}" run: if [ -n "$PYPI_API_TOKEN" ]; then echo "DEPLOY=true" >> $GITHUB_OUTPUT; fi + - name: Upload to PyPI if: steps.deployable.outputs.DEPLOY uses: pypa/gh-action-pypi-publish@release/v1 @@ -299,6 +483,42 @@ jobs: user: __token__ password: ${{ secrets.PYPI_API_TOKEN }} + - name: Create post-release release for releases triggered by nipype2pydra dispatches + if: steps.deployable.outputs.DEPLOY && github.event_name == 'repository_dispatch' + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + with: + tag_name: ${{ steps.post_release_tag.outputs.TAG }} + release_name: Release ${{ steps.post_release_tag.outputs.TAG }} + draft: false + prerelease: false + + + report_progress: + needs: [deploy] + runs-on: ubuntu-latest + steps: + + - name: Generate progress report + id: generate-report + run: | + tools/report_progress.py outputs/progress-report.json + echo "progress_report=$(cat outputs/progress-report.json)" >> $GITHUB_OUTPUT + + - name: Report progress to Nipype2Pydra repo + if: github.event_name == 'release' || github.event_name == 'repository_dispatch' + run: >- + curl -XPOST -u "${{ env.POST_RELEASE_PAT }}" -H "Accept: application/vnd.github.everest-preview+json" + "https://api.github.com/repos/nipype/pydra-fsl/dispatches" + -d '{ + "event_type": "progress-report", + "client_payload": ${{ steps.generate-report.output.progress_report }} + }' + env: + PAT: ${{ env.PROGRESS_REPORT_PAT }} + + # Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. # Secrets are not accessible in the if: condition [0], so set an output variable [1] # [0] https://github.community/t/16928 diff --git a/.github/workflows/fsli.tar.gz b/.github/workflows/fsli.tar.gz deleted file mode 100644 index 5a3daa4ecb43e28fe1a9bf3e220a0fe25ae46927..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 28551 zcmV(?K-a$?iwFR65dCEU1MIz9ZzET_DCWJBoFqzs>=WPw2SE^&Tkcb&n=DCvwKb;q zmb=w%d2|~|?Vh$QaEfG6s%er%R~2<}?;hlL@8926Um zm$buk3H0CpuYCTa|LQ;fyPySQ*@8Kt({OvvX3%~#N~kD|2h2ks#4@Xh#1l$*xG3BMb`KmYqDpWL_JC1nitBrVGI_5bm2{^h2v(c&FG8f90rNfwU^{4vaCqj)V(CP`c*^u#`?{l7cCV_W?^IfoJCahYbb zHT4*a^fn%MvVPHf^tdzXmpAjIC%vuxC;!=3dC&k14H$S}F`}Vs(@Bg`c5x@HGa`5K$vy~@b2FK9C?%QQ8crnS! zqsPydji4FV_ukIFDdIowukXEho^Ji&yYcq+Bpbatx*GnRUG6^o;pf5gC)2?nzni~J zpIj!-pIp4Xd9o4Td^sIHynZ)$G+GS4{qo|6S9_N~%=U}755HXe@a^{HaQc1m!<&~s z|L{kC9>00=^XS``#o*iTZ+2(jJo)4GH-q@q(faV!-qT%b>uT}CbmJy|v$GgHI$ykf zv$q(%DX8ub-+uXMFulHf`{wB9KR)_y^25W)&!bo0U5vh+Tn^GN%^03jJ74ad{Gk|Z zeEIX?$=>?zw@2gAtI5?5CmT0Eyt$sd{p0>*_v(E2`>QSaY=5(*KYLsC&-0CyhtD>e zmSqW8|9!p6RyH0zTDsGK;^=*I{>@-~^xaXMK6&x-hwP`v#|PuZ`VYVV=KT5Ac073W zs@Okx6hHg!_Yc2&@%#O!3lHFzepWWtpERxs4&c`!NLHSHxool(GOV|I^y14O{(vL= zX8pTw&fm#so6mK%fhu9O^6TKPfByXSpWmMQyXF3W1PtJ_hn4&P@zeEx=KualKC7Ru zEsA_?kj~bU*<~=lDKE0w%IeB$aQy0f+I2ZwKucD{XeLeE|v?*@9i1jR5<=Vb(M z?%lh0a*-AR{J*?N>|%tcrDP|#x=4o?!7!c$gCsx<5tNxKiM67Y6>5je2UA#_&6Sm) zi^b!?B*EhFHMvfPixO&IrR7C%NMjBjM$dvQ4`#^~?Br#Y(peA(_b%gE3d6gns>AHl zJey6E8IBX%onyrPFzqmo%-ofO$v- zZW4-=7WiaPMKE5>hPVz;VMfy#0)~cb7)r+g<@iP~$3Tsdn}Auu(ypwm;248`f4nFc zdD8F8FoJoW&dR=Oz7ven%e0_xi&;9%MoE8?mPsB@ij@_qLWQ$zQm~u>CNVD6yR3-j zF+eZS@3OgiS1bneJR2rOq23kxU71{$S9v@)^~x*tuKtPhbAWr1G?zfYL6ZRd<}!G< zA>rIyVmzD1Xy5OB&_LPm81|aVNtQ`L&W<4-+`nJ5+Q#&$HZ9xBlc| zr5P+>e$t7X#na>=JPUei1oqPv9%pqL?vUw7Nl$#dJi`qdV4~|R>j;LsSla3zumBE$ zORlUOzWsjt2<8L}9$h9mVy1pN8)v7R56|E=oB((!=OBX9xC>vCyw&gH%=`T|lvx#w z3hXE@YJrCqekLW}Diz{s*nx6E4%|sP4~8rKemp2}D*?Xj0Va#!CxR8)=cnz6%eKN{ zh<)|@YLHkVd=z~dt%rz!cPdwIAmxJDVmg4X1G+Tvwj@M8N8B`8xw=SZ36z9e0xm^e zCmYjEQ@zIV?iPk=q_F;r?U!4xcTf5|`^P6+ySrN_I|uvy7duDW&rc4H-twgWoTalC z{7tUsaJj%GlDERYgzZic0(4+n(9(-!94{tioh%roc>-rWZJr@yzgzw>hY_yqgCE592CKdyMr zJ$}MEFFXZGWQ->f@ioom_0cYFFV$d`ra}@z>IArxh=RaPV9jjBEs-Lv@ZIsjKK~Rt zOwk8;Ch{qRD;{JEKs=XmIw2|p`dyK&gEY@^lF)F}*!rd)O$ER{fd7Etil@L0x?^1d z>Z^nwYbaoFr``!*6hO)3(0T#`n_z!i!4S4J5Ffe~1ddRU#XK3N<5UrXIIeEI*6r%D zz>>oEQJ3zTY>vZIdmGpI#rF4VosWNo_4TanD7jSMqw>16SC^pZz9tBDs;d(RD09Jc zt5*e}2xQd^_CK_cOtLwWt+YjSb3tvTplDyc)~mHrhdIM%HQ1G2fwn{-=Y^kqA6~?> z^CY;)uAojF0FEr;bJ}r49Wqgg1EHVO;#~I~t?cZ-JYd-Mf{m4(y~Bf}ldXL`YY$ic z@ET4X9DRKEXyx$eVDIpROFmwCvvst;v;Qsqda|;8baZeetvp@X-aCAy+I&X8wvKm> z`Pb|H7u!d>JNw)4>x-46?c?neDf#8f*8cI%^Me<(6W-JEn$c|r;g9Q&9-TgVHVr#^ zy%9v`7iDmsCpTO{Pe4`p@}XPd+dN5TRMt#SH~w@=e;-qo)!>`SB6+X?79ywZiz@^9a$Q{?)WHNyT#2*Hly6}cu_$c9K4Qy3Ory!Jka{=VP z8HWMCs_?i{;k7eevp}l+dbNB(3>_ba$<4}#m6cI4#!I>n&!#Cn?O&xMxOB(x9%-)L zel|MdPD@p6`W(Zy`X~uU}o$$z>eYUNx|m_ zyRY~5k7-!td{HuIh(b6(2L(_@JP1u|;wR^MGaX$YQmcKseny3b-rA-=aA-{v#Je=M z42#l&$qHM28pIxZWSRkaZ(qaJRuM2APw$eOt1KVsF+{=6I5^3H;%<$Y_G)*kw;~SCx)6}m z#v@^RgbQ!7`5X3#Qh_<&Q}{;h@qloG3}g!q6bn779l{{sV#E!JOofZ$9Xs_B+V;LY)hlp1JR?915eBM+w@w%` zhol~vIVspa=wW&NSSSe&;6a8d<%`=T5HzK_O}MRCz;Yvi0w=Vgok5Wqf%e^D{mfT^(@%de4( zrS(O&AC?$yk|iM`?47JA?d%Y!0Zf>%0Q(SX3)!#~7iHtL0Zn=uS)&;m%2gafW> zJZ29!@sgYapO(P-hC|;1%Q-6@$jtdp1?wdXL!g_ z?U@c)C(T^Ef~tQ&h~2z2&QAf0;MDAnEI>7h6s(U7u_u4;QUw9hBdFM<*4!Nie9h*7 zRN%L|Q;6Pna6MLY&n!NPNUx?(WjX@LrQ@5vk|4Lt(!Wg47da|RfRwvJ&4en0BrqPe zd@-8=LjkkK3lmG#+LJ7lE$_$BjkyHcXMd4cYtqS(&hQ1rPz8D>E!c8i-tMc3p%f@CGk? zsKdA|o{~J1kconY-IUVVkkp|l9UxX($@!Qz~hS?rliX4;p2c$rOgAh8XdaRyzVFG|2@`4d)B|V-vm58TxW7dNzh%!(|N1LC&%hkiF69T;_f72EL9W*D1Hro=94!rlG45UX4zH1Yp2v` zk^TbjWP!ORtuR*TdI~SfA(gLIfO~j0YDw2+Rw7%Q;3+9o*^6vJ$iBy%D%V^K9z9(b zf(MA8MM*Rq7EmSba|tNVfIPrLU=C-+}%-rw82e=PTmKpu&^ z%?Im`MjtlcZ>~QanN@{mIy}6N8ic~0%=6BYWYmvG@UAsVbJSH-*QsDO2~L3&2(S*I z9<0RXQ?Lzz0J%&j$$3KTn;zM5MHAHC@x{66?c{Psuqroe&ZDov@6L>RJe zt(XX{UT7H=gjFKXrSafLnpYts%|*f1%p7sj7T~ELDI61{EMb`CsA15Ruvmg3DP|f` z42uUUiY>mEhq)OX^J!wiDv0wcMiAPP9tb?HbqMVWI$_D9xB1#k=jENd7a0LG&!LCy93J{ zP6k`s@WLp-!9As!_(v`Wtlneqo2uvcA2w~SuEOZrE2=95r>Z6Ro{fV?XHF9x-4SrU zHk5?Npdwm6t+)%TpqhA3nI%N>w`CWjRc35=>w-Hh9hG)>tR7oT#H~4&xdktn~rg?(ewv?rjLLn4fhZyD?EvaOim~K(tOcLD=&q;xbM0iwnq)L!z z8<{3|_G3D+OyWsX&e@aRBKa#rZ&#TVS;*2}SLV=G{=t|6Me=nT&*JkWXG#f999&ba z>@vx7Ak6#lgA@!MQHuc!US>U9eBg6|)-MzKQQsf2GCB&ReWh%JOMYpwr%3`$xH6itZ< zPc(fu!tae@5BcbdcDuqv<;kVIBZN4-8Yy9j!?~wpd%@iemZ7c!cM11nklIa}Oh(fC zN+Vl+d%H5owp~kB6&J+|EmxSzTA+Md0=1%t$p`-`&S(8>)=$vXriJn;rR#vNRUz67 zpt1QP<=qRIfQd^ovZ$B{%$06L%j;2##&94_G+8uQviLEaaK<8PC%E zJQ4xGKe#grU#iBiQ{cMns{+d-5L8307;veDKeYNp7YJkICI{-4AY!k~fUZjtz_Mbb zLLfmr5Cx9c8{GWF5WuGV!*Rxde}q$Ksm@Yd1`WHfr- zjqb0k*2NKz0#E=^!WhWntY?6UAGu@%1opk7!FIRH2iF#vq}Cjz_61q#$OZJ*TsQFE zplvovA!LOY2rDI-Gjr}1I+ZIpci))@yj^4^EyqZ2iXm++`1Q>rL+ zRm0dqgx^=3MvVZ{S~Lq>9;7+RW6|kb=voSYwaaG*fDe(p4=(PnWt#u1D!Piv10< z;w*bEdKpeJS|M2LxI}V^pRo1*LtAsD4coOM zfmBT^3D+cv;c8~95uf~VlnzT<`WTZjE?QN@v$UiQWw~+ygO{gh^iWvJeiXbDwTe=6 z6v5M8)g@WgK*z9RzJnezLDg2>8^e(wUX`?F*00s)ceY_iD z(M#B&&ky!rZ0TQnTYKM_Ux#l`ULEZ7&vpe>U=Mf&Upi7nc&a#27Jz9`q5)%?cS!Dq zt0GuK@vmO9sKNtpQi*yY%=!-4!V59?8Ys&qMbca(0DZfzw#daL;pMPjr-ih`ECrjk zde=l$bgQIZM03w~%7X>b(Iof`I(V^jv<4_6PsnJvK$j=J?%>@U>n2_eTI81ldkPC8 z@7z{KnOA5_kffDa><)mD4A7jYB00U-a{jV zWcsg_O?H4S`QDmj*s6Q9KHCk77s|Ey5_XP_J=46#s0|e;R47hv!&DprSQt8 z-n4F~1Q}IGRZ`feT1gFxDj5-*7tv|^X1s5j6y+nhO@TxsX3+B*cJFx(Tqq+&PXUX# zdbF|r?4hqrQB2T*BOTvVi0&6^3&zG=KOobGBEBT_LEF|EW8})##oDc}hS^ecMoNsd zTefsv+fSxrJ+V69uix})&DV@Q)C6#>_Y35D;WWbp+G?90qSqcwfz^Oy=Pv^=^e&b+ z-Ltb18lfedVep{IA*p4#&0qt%$2W=aDs+=C(Di6WCRMXBSrLqarVl~`>=QuIJcVhM}{GPpn%XfZD~5XS5lI~CBu6?Fki38$JH67wK^FNw6->=4T! zYc=SSphMYM$Y|SI@}a0bgQ&?;_)+x8X#<};HWVC;CqaAhlY{36yZw{hW2dnF0zFmp zWEhvq2KiC6v2G*hAP`5YUeJ2f2_Ch*QZ(FAioH{hk_l7?vKHe5v|#o~(^x(CpYQH$ z@1KP2O{ok;B2R(4wilX_`P;i|Lzf%p$9^Sw}gfVsodmC6qGWnT@ zG53IOBW>?D6nj5lXV1%v@XRY_{C#pG-l(b__c-ClT-$-xMXS$}yWJ_*B)-6p5@F!z zmkBZOa~DAdwOJEpRA%zPGVrcE2Iv!;Um|_?;Cm1Z!2?~Em z=~NLOHW0H-PPIs&lL+4sxop)Y`d-;YZ40H;6cu&81nnVhS6?3@yMxlgnhRkZ-IJP; z7?pbF(;&U0!8NEV=x|l#g|BByV4&G+Z^yTY3u#DxvAzCiJ9VO5IjjtW_qR- znU5H~(rc<`NlY!fbIbGFb&6L7zL!NaHs1QxbJ(wGNjid{m9f+m#gpuCuA9pfau>|< z8)K;cO&-r+U_>k4v8uii2pSXsBNtb0)L?Xo2B*>Ia14LFn@AR3oe~Kuf*`NlO{`ep z9cKitmY-$CK)D3+vLj<35-63J3;@bE^1y&83SLxuEG&^J7Qxs|C~D1IshdFr-LIg} zucNQ9Px!-~!WZu5Yr-hwTZHl^~1xy6zzKKRa0Z=Lu8(}q6sFp~5p<*PosTR%V5em<#Emmh%3J|CT zv1+8=4NY7WLGZS)>V$3EaiE_Sfycq!**BB9tIcX?D#YyGmY5hl6c)@T#1=9ufIzUjq}8C}G3x;H%)-W-vgl1>AIefEe@Qzs7sfCpM5;o{^bR z3HryP>ijBP%IIESXA1Is6qK2b4uyfkJNp%>u4)jD--7O{Me_J3Ai2EP*)1d&t%%TF z4$0L(YSm#E=B1b9f;J4r)zY4Wk?fWqXJOk{{&b>B8qy12S=$|-qr6z&R2JMCAnNdD zqt+>uItv~w!D^Ze!)pyMHN7?Md(9?l`2K5Iy>-yTs5gnH15_e!s=K?DpKhGB@oK_0 z#r_6JAqu&NHt)>rW`jQ`!_snlOet25mdfL03_a#>6Quyb_@)pyHdoPTjzSlWHU=4S zWS8+|!Gdv?MbJI0O*dlG%OEC0jN$^el+zHYI8{TA;RoQs#T3mu(o4j03zkpUTL7w= zRikd@Vh+q>VtN(Y;dPOC1wxFSNrg*J8)QEbOq22=BZU-$Nl%DRThg)MA~7Nr+{634 zc`KfZ6-WGy_4RgL95Pq-8!5Y+ZzxwGM_JQ{Bb}E0ehaT#&+!LRG?}1hZ~avXy%%^S zoAglQY1s?kZ$=yA58nE?+D&!IL%ZoE0#F8~VCm}s-yvePtpx-C&qW)fL2b6MSqqLb zf&K6W^LmE&N(-$sgL`}5-0KAQ?%(UQD-|?YHUn*}iFBlT%-a;&DUyUNJsVM=8e25D z0gk9&X8q})+8e-F-F|3&MrKoD(yl@tG1ipRvBqGp&XOK-LwoUcI$g*x(H~U|a)rjD zBg*fzEohrRCKxO^b-BB3?KA^mq;3*KjQ4XAh5vP!4Vx-pX8tzPqn!n(~^y zS87|MHiLAEXkejPfcjo9LKL_ZA^zH;oR!No86?4FWFnzC&Gh>iKdDb8Y*GF{6eVtc zK6@JH*I?Va#4u4+)x6LW=H0S3EfnQ%jlHUZz_A9DM?Lww7KkyZvwLWnoLWj}!GG(u zK5FFiBu6%N>8NGjQphSboccztcUyS_S8(uofITTZ+@^ckzK+QkQ|{yXV&GG!^tHLX zgJ#=wqcC(sbYM&rC*%p6x&xvy)*IY59d-jB8$j+xUILk_i`~MMmY+J5Pj&6xbyv}S z@MEZdXB_C-@2C8gf(N}6>HjG76wbmuwv}01AQH;T0*y!o4NX%4(voeXW@V6)sc8>D z7qO468D2AVE!x`eP=l=^?r7OcXS)@3^zPIWk=Z=9k87`PB&^%iyRl))d?&aY*He_t z({ZA5x=j6>=^$ecFZ@Sj8`tokE(MmVnJWY?<|S}L$`KB@s8(rI_Y z?tOF}n0HY+8zt8*tkA9&QE{f)!F>{|NEK6#q(7z`iZNA37+6aDZ-302k%zMm?rnrE z80honunvyB3JM9RD_m`&8u0m6)p!Bv81XwsYcF-0Yg^C@cvIO|y<>G)4GV?vVG`N#aOR>K&PxJsJz2jM z(5kj+*%F#GExj(_pg=58u{J0c<8gW|yI_qmyD{z;7;-Dlnkwn71K9^pHc|MB8J`lA z`wibEq#(dJ9mtDVMezegF?bjNv%Eq-HRM(Zvr&{!Z`lWQIwWpFGBcpB5w=i+LhbPc z+i<3zm|3Gs3;OMhlqCp765)DGX#i9;vC+1Dx~8IUFx}|JtZgpb2Ez3ePso`K)^Ih1 zUUap)1aP8H7+^g;gge(05O|KE7OD6Gk@*mnp@=Y`&K)cHE=t|d?Kr?l)rLNy+H=Xu z!GS(vD~CjMNH$7bp@Sv_Bu;}%XV&G&d7@K7Y}7?91_vi7h{r^sg-+4Ikw#hbLSkXq z{YgA6C}LTW%wr6XNNrJA`l2HyJQ8=F%on%~<)iW^==lcb7O}pExjJ zdR#;UN>bYO#!U6UL$<#9W}3}VEokh61-vVF7kUk+zP(J5BV=Jc!Y11_#V1HJVP46> z-Y2fY^dxpDSl=K>XpDX`O&xj2e{_*q%!G+lK}*G5A_|VlL_iWn(2g0#b24e+NQEj5 z3w_`b?3=2%0sv+q{O8=V@}%xowW^dYgC*_kl)3Eu8;9xYd8mwmmPe05%~xhA);}hC z3d(~`M4_tmMH~9#XUiXRrK>`V6CsP@DlE55{t`%_qMC?NZw>5FqQ-Wd;nRP3^u}_W zabebYF_!g*_m>mL*38k`ZJYm8otoW?GkuYgC<6%?3>QBdsldUuR~3g2MpurjTXu>) zbk3Ae?Vb;Y+9QX}J4@AaBw5VdOevrY+=uY3axoBm&=QnTXG94;TGiWwpjR(slU~+- zaOP{N^p3>h_m zu?xka&1S`7$`^odOIgtDb3I}sB#%vWLf_nQa)82sDDA0=jwMsRrJ&U! z*{b;uOtpw5t%}pKDlCIz`zA(|B@xpCm5U4YFwD1H~dG zj`3c&h#Yj`44&78hFG7LHFL7LTRL$mA%aYp&pgS?8w~{$ILreJMUp8WW+-J$$msS0 zo;;m6kRpYE0+qFalrgY#a_hh$e;x*pa)GS^NJ|b0MpooA&2HMkjjFX=_@zZZp1_sf zYTsJRg6VCwESYO4;NBM{S ziKfK_?w?4ru1HcZRe56F>P%2}Soh9aPXAR+T?B3fd3xpqiop*>_cK?bf3;Se;_5ux zyNf%-F}A9K{66gkRrNfZ%N*e{O_Oa7>_dj3YNA{{;lxDjr-5#VFgP10Gj;CB%$xiz zyn$(?fd@UFmRx<5USpP3kQRQ#>WB%K?diPqw8;(_wIjr6_4YG^4BcOSVz80F?!1`u zaEEiC8@tPSXg&vKUH`p055D8@Tbu@e7|o?yt|}?u$y#P9%QvBagSCn_V_P&BDylXN zlpsm_%HW3#GTDfaj53kIAh&s_H(Csn;2sU=p5mRHM;0`h zY%h&u|8y}aQ#KW+)`}$-Bqt=Q^^CVFg+fOH3ffX@40b}s?C?=C2IyS`IT<(LZA^iY zBb|mt1O&0~(y4xQZWf=p#bP!@a|>m&!#-2iZO8LTXCrd41nvbEI2gyxtZ4(8W4%2Dk($W%6GP)$)I&ndp#di2D>skFPQ71VRA;bxGr zEk~*~=y_PpIb$1=)cSzurVkrUSM=+u%ZgWgRhy%Vh4(|JH9b$SZg{5Mme$Xl7fLOL zRf&4?7&Ch57yR_~x4Tj??szC0iS_+Kuu&_07rF;O6w9LePz4KDJvb2K0K9mSZ6ewx z=)m7b>vkzavL{2sI3}ZP7s>Vu4aZK|Wv=_}GU;QCJGDuc7|Jx&Fh-fifMQ8eGR#z8 z*vJ)rRBX@i5nJs7)nGO(If~RBmPxiWC5JEsl*f+Ejpf}y-1tVTY-#m?>iSsqVG_Jb z_IQtk1~w)KC?-iVZwV6dZ&@20?uqfirm2PIxir)m3imtDfH?QecoiW(Ok7F_@aV?+ z`hCW>N)k}3%2=Zo_`KnKS%VivZo|OqArsW+?!@MD*97Ym`pD8HWTz|BYxzWb)`zf8 zR%umh2+6B$S_1QO+y&1xg%pI zA0!bJ1-sdKA;(9uz{9{@BD>dvoi;)TKtAmbjhnco?7}OlOt_vqzn!GxOLA z2BOtj%P_OqE^C+^U&^YlWXF_LMZ~Xe#Rg3f#H$y zMuz95os?Vc2m`=YQ&Z`M9ZNlwP~0W%Brg%l%&=a)u?DpW4bZ4Yg46rOnWX!&jsWi` zW$aOF+yS5G3P9tEkX*l=oHorJEXM&=&5N=ZaJ9%aZSO~MqO8)dsJ2*G;Ak{0D{8e?7 zAE%*g)=x&9W~37+)s@jxGiGi(0?r2H- zmg3pFEYt0%^&U2ZyY*hMC`fNzJCLu%QNvNKo0Zriw`&PHEAjSp00<{%kpEPz(oFaa z;{whS>?O`qILD|AjL%U#X5l2OrWH?Bw0F4}VF%}n82G$0G1>pBJ$AQcS8?Cy)EouJ z870HQSewf3%c>`F;w6AC$Nynme=oTv2gvWYj(Xp3?Y`c=XLkqdmvAHovVW@t-*p4` zTJDxMa>1~=*LfZkX4eNexlV?Q($;@! z2XP$ZfaqB45K8!Z_vPqUPT0 z6vvCKn=CJb5=&y?KU=@OAVy93tTh}3pQ$uy!Ds93;NSe4V16}f`|HCNc-P@byJofO zv17b_$~Jrdp?B~7hkKTP2e#hIi1%mU+FD7Nasm`$DJddQ@nm197rPc<8+wD6!6O`t|LbfN+nZ?#hlsLg>71n^9R(07_miDh~Bg@x>89QW(fo~ zBAVS;I+vErr){<3#sSgMo6UGIG6@Z5n&ob&4>b-G>w=r%fN2N3i`R-3j8T}*W0bSO@z>3g-ERCd(v%5$j!++%Y6`=Ph(iJ6pA6N1 zx(wqL&P*!74Jer6bh;?<60HQv^59e!!DBE~6JTvgZd7Sbf;dPP01Cvx1QsXa;=oUs zn1{V{7|K?tEpxMBNo^6|C8?E;3s#d3C%?=BL?*Em z#biT@!qx^ppIA3+mQ?$?w9X;hsmw(ZyIQh_dX`!i?#w9}Z3EL!`GaUK%^apGK#{go zlyrGmwKOIE2!#mn*L}lGg&VEQ;!lZdJ$|*lyNi@kaS^snmTv3XI-xY@IxZ*gSLR=F z$9G4G5};X?M4eBDmvS1i95WJ*(RU6={t2c+M%E>_*(lt*s%ezSapEbsche&2>$9iA zV>pxT>%8+CiWTLo6w~pPmKPf(mu^Xau_4Tzlch=|M}IMnzG!`#I^}h@ipisDNs}ph zX@iyB*;tHC8ti`gk-ZUiB<+R?!)%TptQ;Pon}AaSIMkC^!BSf0;YF5l#5RhR!uAR1 z+LD&G=y5fm96gw$0y)@@vL{RJvrnl6J1VgtR}(iAAdD@O4GiCbCx{Fv>A6*d=-jSJ zyrGAs7NfGyvdO4#j;E_wl^Aw9P+6gq^blLFO-E=DMfJEyriJFDIaWYP1y~h^%}FIv zK?7D39F(zXyVwO)Qw?+EYz%$n=~kJUo{v4nOhunB$o_L3Q@9pjl9o<4okA#aN*&BVh=ZsuH zjSB0A*~i9Y8&{gySc8DtX1f!OIxH7Jf9tYcCGw|eRdhiZC_wXj8_?a*lH!{2k~A0I zo7pIj7Om2=qqT6&s}fw6)oiZv;{45w9tTLWfg1#~Si&6vvOqML(J2^pcK zYRer$EUL$!&I8_}yE{YnMwhOdrjTM~Z$lFL@#4YeA^`^~MpI%=DpfQ9I}}s_VNZb- zVCP(a@l*nA*EB3Vq#lM$=RN4rcWZoFs3-=F7}jc;q>;0m*6=h`^F+;w-4%;H$m&UV z(I6oe(1mJgLlj=Z@l2l_YZrge_+P9IPae+}=ON&exSs9S;adh*0Zfp)px1>F@CEgbjmqyxAOmvKN z!y`rJu{{^7u=fNxjj4F+D-A8+*wWffVB)z~G%I?cdKg$igyW5sRoY1xvXyAEwXGal zs4PGce?93`*ZN+!j5*AtJEnHK-2|A%SoQU_@=g6zRX(dQzg`B6@^m)0Wx718 zYe^foXv4Xs*Np^7VIfcJzG-ptO|g~0ycRcxBC+M)^$ZqmeOa;ht3IvP{d+=JnV9BT z9hty|DyRe;eG;|UYtl6tIrxFKfg-n@#iIrQA)8~`*_h7^_oLDTZTzyV$BYnhGZwXPVTq#}as-Anj*W}pxRh3L|m^F_P9(CU{_3I@ZGrhX` z%I(PdIY*ir<1)t@Z3AHO5K`)9JhmPrt?3Zk;Le^;+ZPImE{FFYaOS-2DO$26WYKL^ zGlbL}-qp_T1ukQ&V#o7NZos0#_4iAn_w)Rgt!S>$atF7amW1lOD z>g|vmB^d5jFDl`TTvnK&miEmOX9SGPc4nDyn0?%?W|H)Pm3ILn&D4vR*yvd|?;VKK z=O12gALCJ31_)~e>Z>xH&gM~(%sp-<_IfthlvkQI!&+JK7GXsa5J+&&@MyI3FHD5q zQst`riCbOivUF)zS`ni_NGra?{;8p`lY&^+^f2@0JgSDAB7XlDv-@6n^&N0&>V&+@ zHXM!bQ_E&ZjT2V<=;+{R>2ka0xN-y4RYMI|Pm{y}RR+zX)7Vi+{OM0r{7-*EG3lTF zMETR<2V3otn97k64AAoz)mXHShOMP=dnuaYK?#c)pvDJe3$4m?6Ht=gS!Jp3hO+d| z%_;( ziALm9X455hPt{C1dj88(^$?_-7F4~ChDz1K=N4MnoFJbksS1K)amgN+Fq>voiN_G& zOP#_(vvqKY7S+m&*=`n&%O+Yb^|v=KRuB!DjkcrUB|wNx!mAuN6)1FWV|0@M8bSOQ z)CpV*K4Yql4Lwl2Z6(7s0&Y=WI;yWLGAiSYm`qnlrgK^jo7X%=|BW-x@cpFfYOu}Z zjo!THEW}k1@%6Ea!E@7kAEXtLNlNB2n;4^vklu>+Nobj4U==pBPn$g-<`G$X`bt+r z!dQ6DEx3&LvMSw%8Ubv51*1OBvU#te5fn~R3Cqct`LA18@({}A^Gs=BOfsr9DaUG# z2Hk+nv~?%A*UsqDb!a}6MoYOw7^Z;b`cxS=Chd2Ft?}e#!n!rsi?@lTEz^iQa%mnF zYXd1_Z=YHuZ>!^;#OSfWVy^y%3)>n+6O>(@?-EF>!yi^1*o;#LQ?rsqaY|PfLER7D zRcnO>)9Ex1mH4ZedkZ!#M!L;`=R$oPoCeGph0Y${JJPi6T_!IdRWojBjMb4L^ja>pRlG~*ee=5Aw3t>tTmLdz^Ij_Bm-Mf(KXISj z0ae+WISQmQCft{?SEf+lk^^Eagr=1o6PlvmtQOG?vHKC5=&{VhQVWp%7Sl5%DI@Vm zWBOf6A!TyGcU{49Lss6qW#m2aNaZNLq%CG)OEED#SOQju+^yP(>6l^`uqgRC!3IME zsdVpla?O%$#*)J73{A&GNZNS+xSP-P8K8wTKtCPUb)4-jDl%CV=X6^K+ zdUo2Z?xIc|Q8b_Dk2%XW)X-+!8fn`T5yJ;qf@>pK>m0XTl{cvk2q$;sGN#A-adr%E z(MGkTvr-yM<%^lvhKr+RAB|ORkH{vOZ#8w9VQ2znEuZ`GP^#3d}^ z1s>rt9V!|Yqvp?wMXo$KDH1ALB%5t(>FV@JtoVH^zd$;GF!d6{3tC9+IU9VE#gYo{ zQweX_@dnB7IMi=bKz!yAlj|7MHdJJ$!xB?yD8Ga#irUrJ5w47HK;iVJFOv+H*QyT4 zt*avN>3o&4xGOe{P2+C3D|T3x&-)Li0n6jFTF1PCs&*ZF=b=WTjDX%P(|FQaz9((Q z^*J1&oP4vIomsV^u2oNQRzyx^xrfy+?EUBnc%Vfx&{Ec9)P}cvtD3mcie$YWsQ}H; zB6J$D`x?URX38FzQ&aN@^)tM|(3{MvG)hXga%OAQ#N$(s#*J}4a@l#y4bILw>Gh~o8?D8WLMqI~@*Z_O5s!K8@|x%v zk1-6E7V<`bM~0dhJ2>14rUVoV*cRXc&PSxeFEWO)Ql(t5GeJ&XfWd(hwo7OxWHhE2 z%Hf=o;bG|DqT(>8%s?lTR?B1c>RN-=7Z}&J>POVGjX>Kq?^5n}HF#Z!EF~b4C^^5u z6uiR)2lgzb)J0j&i_Nt)=wLC8kldT4=NDyhg-(xa<=Q-hO%L$tLV<4FWhcb$k5U^G zAa;>L>jxaul zLmFvhlQcAps7@VAYSq`4tk))u-PKcD$+-fGTv1@?iXt1AKwu@3=(wx4hT1RQUb?*5TmX0iGcY-%tNBcYb->ORlB`|#f zUoW80Eq>`Md)JmW9MzY}F6#R%NsVRSSr|301s-q7&9G{-fY*UGrJiZgiQoQNLKrNy z4MzD=I`iFC>?0~D`tIUzI6_acNXKV)Brc+6a7gV@8-ICO` z?Oo5*N#^ytMXV5rWMC;x$hUJv3@J?r&n&*wy5Y@WS44N7It8hsv?=l6roLP0zDj3f}ff=XSI^vUc`&0f4xEeUU$KxuC{6Qdb)n5 zqZF@F5PP#6EE7clzGDRoi#JeZ0zYraW~%X^`PRaJ;L=XeA|kYm&pU*p(3^IU16_U5 z#(kg6Fxd=payGc^h%7jHd0`(k+@Gitwn}5Guvs(K2WrtQvgVd*Q%+ zu^7OmR2yhr(d!$R9*F7J?T1?MMfBt&#qJ5p{_BlIyXS3sMI;omHa=dVWsfM_Fn!g+e%l38P9)5~+i-`O$lbLNEz5DRGrX@c z)HI7G)T6IzN7HT4*hqWMlWvC36(PnZcWReIdLgA4A=&~Q?I*}izk`nTgIbXJgYl8X#$1dMBYXTMjmKA zCGz=3uBvdjL}Wn6PZWmbN>g5&I!zWZ_-F5-`{xJyFSh!xkGGHZxAwL_P)oRU*2}}K z*T#UpDlHFL7nO|@Bw%6XcN*yy*b z)MBlRbOd}JpPz0QcJpL0O8T-KDj=U`U>8O0HgRGz^oRvCChRCv2+T|0Jx=9@$_K?N z$A;bFtKt}TTh@ifxT7X|ba!qAtAw=A-hZ&OaKm6lEH`x6)^~nB|24nU5hW^Sb9>sZFQ%%G@NP%KyG)ltgnh%2!vtTlCkOn>ISYl z5EUY#Fvr+AzEX=6ucW}VPi_6gl2A+P_)b*gX;K78fgUu&nAgJ>vTSofxxz!=phCn8V+upv(r|ji7BPxB!i3Fe?bhqLy%E;qB=iEgH9wJEO)1~9E$Llh=uVGfqs4Ej8k7nt(} zV}Vd~C$r?J+~LTA7%OsuQcP5ybyUqH_#6Yje9pIs96LIi`c`coDvl>p){1Lt){!Fw zdnKV*p;L4UvHK~!eOT>_5(cgOh@eL!g$nvpO+}W>O({@}4W1K9fMrS;rdSzQu9^|u zIv;fEn-mxf65&R=GfjwSt*g4fm26MDe^X8=x-V_2rD~yqag60!3nR?hV8@g4T>x@5 zmaEzJzSfr_8eQ<+;pZ_ zu3u=HnPb;E(gboZLc7A*xS|ZEn7ld1;!zXFjq4PWDF5nA6LqgjZ+cub{Nt*{-Qz_P zI=$MVr;U0?t0=x$K6YsiFKK%YP6WzsHFD%#09-BGoR37GE{QqG;~?sWNE?4r7C&TG zfx4%izot%rJ~xYbHgnAWUH0kfJXNVn^mR!= zsk1!JZ`O)oj=-(@k80L}Zvf3dSw4%FIlh$CRt$cNdf<4j)ct_gglr5Ei>ZG+bIio0 zoMkPJnG5GJB?i=nD}%%NH_gzuB+#% zVu&flOY|H;-)o;&f-~||!Q6^}qUC=p^}Rh!%6Jr)u?)wEl65!X*{Q8MJoC*&wQ?F_ z@TW81G)xiU8ntlog&haM&puiN#xmB>O@S8feS=m+^$cc%n=&cTB4Il4>A_6~v#@?* zy}qA1k(r@^rLTS^t(mIf;Zj5U^oAWf%~g~2#Yb|q$fP!MqQao~c-R_~S{GfzWAG?y*IbH!`uz&{Q@-g3(u-#S+&n8i*F=k2yDG7GnT5P zvLdC`zl?Ei&5KVLL4m9!3bU_@`dPAKD*`~3Qq-c|n!V*Jn8GsrF>S|X z1x=9fi~Z}AglCF8Y6uT60=xO3I|#aSTefc3)tCNqTShC1urIZmg=A`{C9D@+hFuhp zw=T1E6ubevPXeMF;DhiS7YlW_Dg%vk*!GJ7S!M9S6&&Tb8<4@K za{K29pT?S(*x_VGSr(=Zh2=AvJ!&y!fK47U7~4L5tP?)zwuL&tmQYPsson z5pKTgwA4*z=fDVb=NMYLi~SXU{aDMmcvq|eatB~^HD9R5Y28E;_*}!6$7W(fspq|* zyaGN7B~>kD1K|if?KvrV(4x$`>RjqrbdH~|iXu+s?5WQV9(Kz>6#+3T!bma`9fhmjv}{L;bt0A zSazAe+J3kkXv4Yb%up@tuf6|Pf4%Lu`rGV2b(dpEY`7Apm?24V)FVyO5$N)4un=|w z#dm<&QA*#JthOj8;n?{PAFtbmU|cg8V5Qtcr_40IhQ@$cNeYYn*l@~VsLpIW?vG<6 z;Z(6FEU1geNqHl5Z#4`7?mf+xqy-r)3}cQ=m5rr&ExpCyX+%wFDu-RrVjvKQ??eg8 zIb{bF8(x_|sl#%-yJ6qeR7-T7_DPfCl7XtL!>=mGY^^!eCx4Z42}AYiypRwKERnUt zq@|_WF4YOqoJlvq32BH2(bv$b$v-y8*cdh$135xaN=uo6KAEI1Ep*&fq`PH~>UM>> zDp|A;gc0V5oKbO>{$g}#(Dsj@)>R6fCC|VSt zzo3O#4T@6t$T1Wr$$30PBpVl~%5MoZvMOF8ycUd5nBUS`e~c4|VGX}O`8|v$SG~=( zHlBitNc(1ps(#zO4NzP`G0oS?Y`!K#p2qpRf(-?eOA0$-6cxHVfgdG~g8fdUz1rn) z7m>KeP!{GEsN7?st&rCHs@+XW5;ZJ?)lX@7>SEQT^vm?x+!7ke(Wy}Kr!fk;n0%y& z7fKDN_$T$wD+E$E^8?@2><+={9QS~tBe4VHv4+3;&>x^Qds6u6BK5xdDJ%i}%Zs4j zL7zH)4-dF)SilM;?Nd=c7m#zR69g98>OsBWn6=T3N`Cx=UG27uFtYCXPeaQJ^dq3A zkan$i3arN3U)PE>6E#-mPmzHFi;=rokTDpVgN%~>%wQV)19-pqC1qi^9cSKk((A_vw z1$eWB4lzj|eE;K2>vzV(SCfIF}PHm5N^V*4kineqGTT4+abjw6srRCt} z(qbB@1mWbxiGp%`ajtSQ1!Hv6!K+&MBI9>oF6I*_laStHAE-F}=mBa0H$~_e3kzwE2k|oMUvw5;jiI z#XCPxhUCEp+R9#LlgmWW8yc2ogTtLF8wh{t{DD$I#}J0D@f@lc!r0PiF*NqmtHC{; z+eNY+S!n~%uM~Cy<@J){aUndO9qw?Dz!IithQTg+Qnqoc8?sTuld!?%Mn!$X(W9qw zpcqhvf)1QDbjQ(77i?ukdbafEq_9OeeDzw50;7^4OT?g8;C9i*Y9qKQC_@G0>e?5t zB9rN@e*FvMG0ZRv8S&O*wEZmH0Mpj8clkEtl`@=L>~<}Qi?jfX5DrGpa3$lm4;H-7 ze^n?fpS{{d>LGduv89?kn52U>*nT-o$gHclZeE}-rQME3R~<|!top%nIqk2|$Au+ln*Wk#|Q1E8tezGA0iGhF>R zwLmepMtD|*!>IzRo{c?y)t)k%LIayVt|FaYyUApmRw9)YbkNSrA_3rRc!yxO?19DcXT;m_Le zupEB3%Hhx2C~=wTds~;IpH9r2Ah<-0rAgB242|qGsK6tq0Pr(B><59@hLD~J^M6UgiN*Q!?Ri>60^ZN!NYd7!lUIC9@Q#5US8pG z+sq1h0VnI8BJVxam(Yz&SPKs#tckj*IDdB~fEA?!BiW^tQq=83PPJ+00vWoQU3JFJ zD$Q$>yy&Z{%HU{YqO^cvwG5^1*lTMDpyt~u;}j8qIBTdN<3J@<5%OT4%Mg;elMSusbrnC0)EE{Wf)}78icGk`#H^(J-pm?2Ld0Mk?)xcun4B0rIj3f zI!6+bAP!ucHrMo;9{pApI<*N(NX)wnjMTAIs(zzk6@=u|)+=6YoL(oRib669NV37| zS{-v(2{Pi*C7xO~bs~#&-5U+jy3E=V zN)Fse%a$c=8<9SM)5hYCFx*TSp;TlnH7afO5bLKrQL}i?asy?y#)_43jv1+rOE2;n zWL*g;AU#e;`Bn#vNd+gw&QZvezxeRUItOm7DFAZRGA? z2MKTqWv#t{vmxciCI3IHddF6yl_93D8!W1=_c2z7&ej%FirzzIj99xKd+N)r28wWV zie2(@bHtT@Ks$hvs$iOC2E;<^0bc18K zctwh*wMm*G(DTt@IcUU%|+z94@;w z;dR(H*c|EmQ{6mbYAdfMAnHH|4x(l)%#LN>f1onzV;`-$51q6i49j1E=l>}V0NJ;& z>Jh^b0_sQV$59*nmWN=T6^5jyn460^f)&urbZ(Lrp*1bOWJ@A3Yq1E`F($rpgF)$S zr!I5%zM#H>?hW8)RD+ptiQI34y#+L-T zp`PSR(8{;u6D3Ni1g)wFzrf9(4ux)2MzcykTul+r2Ra!PX_?eR54m)mUC-~4042~1 zhzXEt5_r|96siUCw;Phd_e>&Ae$r}3XyKHLpZS9P6QP(t7$3jx#>yo{ffuW01#WaC zb2Nc7jfV%vYLsdOPylGat8`{Lt?Ih|Zi_35NmlJudfCMUv4#pWn360E$U#e7yo2*e zHi+<_mO_moq2tfHQqYOfNGqvPv(=P8oys>llj?r6bm}eM^ zkHRnz-!xW_E&Cn-lKuj= z`w+HU5>h$6%OpOiQ#>oog~848-f)WaaX6tV!n3rB5JW<|m4zD_IGo=AH$GG0>_U53 z?ki_>@=AA4ql=U*)07)CQ>K$0Zw9_Axl%y~fU8z8k>R+;hblRHB-pDOFOhes#ZWOe zP~tDTM#L9cUUksiH16R9bpSbXE+$tw{71sMB)G2Z#5-F|$wr~0v>gU#zAo5gP`fbn zDN?%#Thucc84$Zsur)$c)vTke4TUFG%$TI|H13v`OT*5X0;A0mlg!o(5wRbKfK>Lq zbWYW{16D&R4v?H2P35*k{1EF`nJN!Dz6k2$IykxGC8LHMk?qrk6S>b#SK(Z zYm8KMogZhR=PX=fQ(j6I2S6>5`Npon!2(Uo(o)p z!6X}U^erb`SUS260&!_Cq7>k9-LgPiYnc9?ZbG#)WGV$H59B$v_CPP&rXB=?nscbK zuwG)1eUIYaN`P0VD~j73x_#k;D(P)D{xY%~7mIHWYP_xEFuS|IMgMk!i)_lObauG1 zh&EN;$+yHO$7Uip3Ho2wQ2KCzd?>Mic0fj|gR+O$b{nk{81k73&GFgstLg@!-<= z!e!>RH8g4BZa9%nS;iDVAtprw{LE8eLlR@+Q94q33Pel6of7tKoiB1s=B9+wEsW#O zM7^#9+b_lB7Ao-+&0B4ig3*n=HzT)zcE>m%7T+hpy;OTYBtQKaKEI3bb=P=Rv;|P%Ds|sA&rs<-IK)CfbI$H(UWM2)(=Sw`ej)91t({E*Q7Mv-j`$-G>ir z#RWhD#Rq7lvk7mo#D@=pvB*+U)D!rE9!G)QfJh&3F8EhDll=lmCDQF zsuN3&!=iiFIEb#uQL5s@@{7Px;<|ZY6(^*xs<|%~j)Fmst{&yWfoz}E^X zH`3u4U35g!XOqiWE^8Kae9|R^ zkW@ngB%M)s)_}c@Z+{4-AXj9g1XTkYbzV;?_D~NvO+32eR(QXl+lm(>?8qYgP94vS7XH(* zYsUS{M`*+2Ge5lX@qA$s(bbio4WewC}bZU9+ z@RV`-8H$9@iH0eUV{XUxbR(y<=#;Pms2xaxOOqOb;_6VE8p{QM6(F}@*NGg#~IMU>T7LaBaV?6JuOoh+zyArsj~PbWO9E0S~|d#wFc zPxWUp+9rP7j)sfl)htkwmN$d@n1#-RIwgyPT@XXaNsk>f4nL`74P-yLvezuN$7NQh zI)<=ypABEphDKQqgigN<^67kxC=J$+L_GU39Lf{5nlEwxS|kH-X4kzC_EF#VY=mY< z$pny-gib-ew zo`X_x3k|)fm}6#nZb_lyq77U$vrAFs*Wa=Ah=&oIxRi531Lqs$?`9Uh$CtnHuu zy*HMk`uySb_VLNi!M?9IQYv$YO6RCVFs<+gsm`0Es0Qr4V`48~fB3P}e93-L)|eRV zYL@=ANCMJ7tKj#UMwWgo(Zbz?G25inFq=$L4#NQxT$r4D*r?pU8oSTQC2}GWrBi@A zN5JtVdcjqM!SuDkpq<1ZwBFd+WUM5lsk<@{dRB@R?}@XT^rlFu5allrBjIcfY?{nA zs|j?Lm}WTrhSN*21@bi8sY0l26puNaUp#OvyrL*h9D1gZ?UwwaGSv`rhxpJ*77{=M z%oTOyV6(_QKc@zWQiByintFgynrs~k_Dzzv=iUbGqB1s<`%0H$Cw%NG*kgmBg{Vf^ zNSaCb!gC~5umlV-#TF;RY)G2Uf@S=PC^swYfcs$=>|!xt!`7zRi#M()aoA_V(;AF} zA{bBzK2++O$x@s!xG)$m5Ku-opm^B;s(;dh*pk|`c=?}1jl^ODx|HoCF+SXtv7%S} zmFwm;+^0u)$Ip8~!%!3#zDP&x$9WDLC>>d1XngZ2rU?toA%C&`a_jZ(Nq=Ym_+)E$ zcMGv;|HaPH_Vbg2qqlXDZoTHw!9innMF-B(@N61I7v z#W%$Y8zrW(3%{mMvML%X0=8mSR*FgB0VLE-whmYtj6XNUgoQapj1aj6ju|LriY=rt zGKYdg<&MV1C_EA=jFP!(?+T)@#1q1ab~oavG?a_p8Z!~PWa~XQF=`NQn3)dd69wNa z)VL-4qoE-2UMrC_yX3 zlvBK+x;xJRf#c;@0XmgeFa>JhiXvH1Yc2S%9nG&$G9w$>q!>YRok=K;b5YCpq9b1L ziP1Sm8Y`+KHEyU3o@(J(60MSr+9b}^Tm2@qO=#q^2}B0jD7_D3B8f@#s!QJ02O_i# ze=MoU2iw>OkECmi#J!KGcZ}wH8RytQ_yVXUlp;FSHO&>e)w9~*DOzG5DBr|w0Ts$R zsif7yg(_Ro705 zPQqU@zlw)a__6hc@V*s3g7SRj>^VxY$|+ZA0>fI>y9^QP%bxjVTR=&MJj>&j(*dfN zmvhSeg7H+uKObGclJ28%$ysCN)>T)cZ>!#=Z^suV^up+arrLxqtrLXmg#>z&Lm$0M zZj9$Jpv1X*jrlLD@Q`v!8}X%*^hq=qm2N%?Z^Qc`@f7~-%Km1&_m`5z8^0$uGGZs_ zmK>JN<+(<&b&QFn`MJ7hpa1$}ZZk1L96xi8tK+q~aEHK5Z$}3&jth)57U^0avx5`t|Q?$Om|*B`+DET2c-ijt`b)1dTwr z6;k9MW94KmlX&V3!AnQzBgNdeB-gCx{j&**?HL_nI#Q%lUdN0S*+P+^Iv5#ZioY0-j4L}=sWC-sHEzc$ z?M9z(<$podhx+rF%1up(qP zm(g@8NC6MNNLW##XealoteP*$ml^G??jRW=f_axv+= z;#@&z7!-Ogsa5Vcr7;#P=2$~=N2gf}>Uq#sE&Z-{UV#&oIhvzisDZT#;1Sclpc9$+KSyR4^f-3N8 zD~J(@l>!j;o%Whbluc;*FJwa9v2zP6THPKDj-uMbFIgq-&Rg*yH+i+ZkgD$#)*G{b z7f0N|vB!nG!7nf|y1hNww}C>`I!DaU9_XxqQYamdlN#w#RK6z?V{9VQqG&^=TY-X}vinp94y7Gv2mUn%O zOg9-Am=LCJOj`Tiu@XqSh6$eHJ~7Yov7F%Es`QS#%+gpm8$|0alzLdX&QM%sExniR z>2M&y9&SxXZ*N^m9>LS{k!#b5I&mAIMsWqplVZ_T$qO0ridW1u_+~8HiN>Of!lBQE5q(rGR zp2X*Mq9-A)Yh<6${axr%*dJ8~GkqydqcwPsbZYtFUy92GMhmc`3!9J+WoEVSkzO^> zUmuhLkX~Xbi8!ArB}zcaq$`jHJ;|_Aj+D~-k38C;=~dq8ngMi(5ka0nzGItO^@1SPaVEQNdhcseBm2BQQsziO~I0o$Q&JoKsr&u+HNkkC^D^1BHwB!Vx+6yat6^gcv zNMp^FrKm~i+Rd{vZNS7{I@y8Ld+|@u?;E@DG_POx5S#Xows*I;j<@@JTl+gNw~tTU zwsc?1#%PvURjZI)4I`E`XNoiI$9KP$muolj>ta9EuTfVa0bs2ZRds=rUYnom@&w8qQG-%fp63cz= zm?)b&Hbt7DqRaTfqFyhBi!S5?jN5?=8PhsdROun`YPLNq`>+}DYHTSl99t~VN6(%N za{!2qsqEZpo?;WELt2X@3XOY6Ebjo+wE#a<5XTiuem}kmC5H#=SJs^2e8uL?{W5!( z%)Z8Rq?eJ0d0TNcV&k`EMp)5&kEO}_E7P6r;RKhTTouY3l6MyhKKypsD!QFjxTUi+ z^1empkrJv(=qD?dyNrCS7sVdT^c|L-t3~BMcMpn7pJFkl4S{gGvoV=`aK|u+%z)wU zVplCSa%De2t}N`Gr?wBWi?8^3%fXgR4wYo2stc=UhI$Y0x8h=mEO)yI?wcq;#pZnq zNHfdYk4KyEM)qKvTtx4`+PuHFdH-0#KFYu%pgc_%dH`*;?T|N9W0flA9n{@LWkgF2 z_Qm!$ufKKAq)ZT__fhDb>vED}0#N$O8E|ttvD~_Z_H!JBRB$PB4?+=RAk_n@4`+;` zK5+uEbmm~T05;29WD|I9o!E~>hY41R@uv}MWnTUIS?PPA%#tAwND?OIR{$#l}YHNa?q}KjMOrB>GWvT-u9_mH?5Q{ zh+5utf=gn`jMZw22&Nh}&uaJmhn^+!zy|E$Id_-ekH`h~kqR6-j?+mpa(AR*ikkcw z8$C0;K8(vkXL2CUYKUhyFGAHnkG$DfqvFKO=HjZ5_F*Q1ggI6nuE#3R$AvtSQb)=s zA$l;7W;4HF588Nj*^V|Ajk07p3Q2&b?+>4L?zBEt(^j_d;hyq54AUM7+LQf8z0hC^14@j)xR|Mvd$ z{^C|DX^ivuKo8P=x)`PV;JDYQ&EK{s5>p_yWdKtbg?MYNrZqPxJd!4 zq!)$OVvO;jM6bL%Va`M5xM*!1;s%|9IlqC9gof9JFNhGu1$ITkB;q9Zy-^yU&oVKP z03HW$+SF^B7di-B&3dWRpd%Yu;dE>1%y?SWa*)7wfdc}_X%6dBM!^e{yU=K+3yY7y z#{goJ;%DfMYiF@wwPYd+($-2D(cWfgNA-QZ|6==ScV~aQgHZr`p-N(B?m6pl*?|zM z_`{3XyO;2$X!>5{WDNQH4@+Sv6tFY#ESY&0GnCCPd{94}`Q(&hG7Y zwFG-ki4(i)vR>UDj%->T_|2f<09soE5R(Q@5A}dZs13Uqdz9RJ2hm65TSYv0zi>$rMx3a%6IZfUhl+YnqfgDP_^b zRL-Q|!H7&KhsLyqm+5E`PY8PyB;)WkN7ofAm&xfI8>?JvgM=ojAt%Vx*IM0(7x+Ak zFiL*ejGHAePSRzZ=Lfw(uG$J%GQ-;&LRsDYSi$BFn})kcXP;2Xr6dH)o%yyc#b%-{ zkYe68?W+l~2GJf3S2YcVsL4FTQN(?iVYw)r zI6VSWEM-Y6MY(_cz#s4@?Un_mNI}T46@CVua)}x??Y?#(Hr5E)0I_!fd5b66m2OqV ztCRI;o_w5tuw-~U^Ky>pVuQ9{m=}h7j^{A8s5~dR{_4%ZW^82|+N|#+ZA>- zvu?wFlUEKZb+sc(^^xd?O#=Yb5&|YGR1N!#OC&;yl8B)nh!BDhrTT`V_Bb$!p2ow; S$;rv-Mmhl-p4(yomH`0v(K%KC From 6f11a23bbd4a15eed3b46766f9520aa6302d0f59 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 17:18:22 +1100 Subject: [PATCH 014/224] added conda install to ci-cd --- .github/workflows/ci-cd.yaml | 145 +++++------------------------------ 1 file changed, 19 insertions(+), 126 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index e13ce5c..d9e829f 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -129,134 +129,27 @@ jobs: auto-activate-base: true activate-environment: "" - - name: Install fsl Package + - name: Install fsl Packages run: >- conda install -c conda-forge -c https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ - ciftilib - cli11 - elc - fsl-add_module - fsl-armawrap - fsl-asl_mfree - fsl-avwutils - fsl-base - fsl-basil - fsl-basisfield - fsl-baycest - fsl-bet2 - fsl-bianca - fsl-biancadata - fsl-bint - fsl-cluster - fsl-copain - fsl-cprob - fsl-cudabasisfield-cuda-10 - fsl-cudimot - fsl-data_atlases - fsl-data_atlases_xtract - fsl-data_first_models_317_bin - fsl-data_first_models_336_bin - fsl-data_linearmni - fsl-data_omm - fsl-data_possum - fsl-data_standard - fsl-deface - fsl-discreteopt - fsl-dpm - fsl-dwssfp - fsl-easyfeat - fsl-eddy - fsl-eddy-cuda-10 - fsl-eddy_qc - fsl-fabber_core - fsl-fabber_models_asl - fsl-fabber_models_cest - fsl-fabber_models_dce - fsl-fabber_models_dsc - fsl-fabber_models_dualecho - fsl-fabber_models_dwi - fsl-fabber_models_pet - fsl-fabber_models_qbold - fsl-fabber_models_t1 - fsl-fast4 - fsl-fastpdlib - fsl-fdt - fsl-fdt-cuda-10 - fsl-feat5 - fsl-film - fsl-filmbabe - fsl-first - fsl-first_lib - fsl-flameo - fsl-flirt - fsl-fnirt - fsl-fugue - fsl-get_standard - fsl-giftiio - fsl-gps - fsl-gradunwarp - fsl-gui-bet - fsl-gui-desktop - fsl-installer - fsl-lesions - fsl-libgdc - fsl-libmeshutils - fsl-libvis - fsl-load_dicom - fsl-mcflirt - fsl-melodic - fsl-meshclass - fsl-misc_c - fsl-misc_scripts - fsl-misc_tcl - fsl-miscmaths - fsl-miscvis - fsl-mist - fsl-mm - fsl-mmorf-cuda-10 - fsl-msm - fsl-msmreglib - fsl-mvdisc - fsl-nets - fsl-newimage - fsl-newmesh - fsl-newnifti - fsl-newran - fsl-oxford_asl - fsl-possum - fsl-ptx2 - fsl-ptx2-cuda-10 - fsl-pyfeeds - fsl-pyfeeds-tests - fsl-pyfix - fsl-qboot - fsl-randomise - fsl-relax - fsl-shapemodel - fsl-siena - fsl-slicetimer - fsl-sub - fsl-sub-plugin-sge - fsl-sub-plugin-slurm - fsl-surface - fsl-susan - fsl-swe - fsl-tbss - fsl-tirl - fsl-topup - fsl-utils - fsl-vbm - fsl-verbena - fsl-vtkio - fsl-warpfns - fsl-wire - fsl-xtract - fsl-xtract_data - fsl-znzlib - fsl_mrs - fsl_sub - fsl_sub_plugin_sge - fsl_sub_plugin_slurm + ciftilib cli11 elc fsl-add_module fsl-armawrap fsl-asl_mfree fsl-avwutils fsl-base + fsl-basil fsl-basisfield fsl-baycest fsl-bet2 fsl-bianca fsl-biancadata fsl-bint + fsl-cluster fsl-copain fsl-cprob fsl-cudabasisfield-cuda-10 fsl-cudimot fsl-data_atlases + fsl-data_atlases_xtract fsl-data_first_models_317_bin fsl-data_first_models_336_bin fsl-data_linearmni + fsl-data_omm fsl-data_possum fsl-data_standard fsl-deface fsl-discreteopt fsl-dpm fsl-dwssfp + fsl-easyfeat fsl-eddy fsl-eddy-cuda-10 fsl-eddy_qc fsl-fabber_core fsl-fabber_models_asl fsl-fabber_models_cest + fsl-fabber_models_dce fsl-fabber_models_dsc fsl-fabber_models_dualecho fsl-fabber_models_dwi + fsl-fabber_models_pet fsl-fabber_models_qbold fsl-fabber_models_t1 fsl-fast4 fsl-fastpdlib + fsl-fdt fsl-fdt-cuda-10 fsl-feat5 fsl-film fsl-filmbabe fsl-first fsl-first_lib fsl-flameo + fsl-flirt fsl-fnirt fsl-fugue fsl-get_standard fsl-giftiio fsl-gps fsl-gradunwarp fsl-gui-bet + fsl-gui-desktop fsl-installer fsl-lesions fsl-libgdc fsl-libmeshutils fsl-libvis fsl-load_dicom fsl-mcflirt + fsl-melodic fsl-meshclass fsl-misc_c fsl-misc_scripts fsl-misc_tcl fsl-miscmaths fsl-miscvis + fsl-mist fsl-mm fsl-mmorf-cuda-10 fsl-msm fsl-msmreglib fsl-mvdisc fsl-nets fsl-newimage + fsl-newmesh fsl-newnifti fsl-newran fsl-oxford_asl fsl-possum fsl-ptx2 fsl-ptx2-cuda-10 fsl-pyfeeds + fsl-pyfeeds-tests fsl-pyfix fsl-qboot fsl-randomise fsl-relax fsl-shapemodel fsl-siena fsl-slicetimer + fsl-sub fsl-sub-plugin-sge fsl-sub-plugin-slurm fsl-surface fsl-susan fsl-swe fsl-tbss fsl-tirl + fsl-topup fsl-utils fsl-vbm fsl-verbena fsl-vtkio fsl-warpfns fsl-wire fsl-xtract fsl-xtract_data + fsl-znzlib fsl_mrs fsl_sub fsl_sub_plugin_sge fsl_sub_plugin_slurm - name: Download tasks converted from Nipype uses: actions/download-artifact@v3 From 49e67801e1dd916a0b6d0434e74e8283bba4559e Mon Sep 17 00:00:00 2001 From: Tom Close Date: Fri, 22 Mar 2024 17:25:21 +1100 Subject: [PATCH 015/224] fixed up target branch for ci-cd --- .github/workflows/ci-cd.yaml | 4 ++-- .github/workflows/fsl_docker.yml | 25 ------------------------- 2 files changed, 2 insertions(+), 27 deletions(-) delete mode 100644 .github/workflows/fsl_docker.yml diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index d9e829f..2134d88 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -8,9 +8,9 @@ name: CI/CD on: push: - branches: [ main, develop ] + branches: [ master, develop ] pull_request: - branches: [ main, develop ] + branches: [ master, develop ] release: types: [published] repository_dispatch: diff --git a/.github/workflows/fsl_docker.yml b/.github/workflows/fsl_docker.yml deleted file mode 100644 index ff4265a..0000000 --- a/.github/workflows/fsl_docker.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: fsl_docker - -on: [push, pull_request] - -jobs: - build: - runs-on: ubuntu-latest - env: - DOCKER_IMAGE: djarecka/fsl_py:6.0.4 - - steps: - - uses: actions/checkout@v2 - with: - lfs: true - - name: Pull docker image - run: | - docker pull $DOCKER_IMAGE - # Have image running in background - docker run `bash <(curl -s https://codecov.io/env)` -itd --name fsl_cont -v `pwd`:/pydra_fsl $DOCKER_IMAGE - - name: Updating pydra - run: docker exec fsl_cont bash -c "pip install https://github.com/nipype/pydra/tarball/master && python -c 'import pydra; print(pydra.__version__)'" - - name: Run pytest - run: docker exec fsl_cont bash -c "pytest --color=yes -vs /pydra_fsl/pydra/tasks/fsl" - - name: removing container - run: docker rm -f fsl_cont From dd23472286d6f0db3b9934cf7001c8dce76dea85 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Sat, 23 Mar 2024 00:42:11 +1100 Subject: [PATCH 016/224] added melodicIca back into fileformats --- .../fileformats/fileformats/medimage_fsl/__init__.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py index 36da2c8..8ec8dec 100644 --- a/related-packages/fileformats/fileformats/medimage_fsl/__init__.py +++ b/related-packages/fileformats/fileformats/medimage_fsl/__init__.py @@ -5,3 +5,7 @@ class Con(File): ext = ".con" binary = True + + +class MelodicIca(Directory): + """Directory containing output from Melodic ICA""" From 26a0ce013c99ea329a6feafaa8bc989a3a8b26b7 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Sun, 24 Mar 2024 21:17:22 +1100 Subject: [PATCH 017/224] removed cuda packages and tirl from ci-cd --- .github/workflows/ci-cd.yaml | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index 2134d88..8b225eb 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -134,20 +134,20 @@ jobs: conda install -c conda-forge -c https://fsl.fmrib.ox.ac.uk/fsldownloads/fslconda/public/ ciftilib cli11 elc fsl-add_module fsl-armawrap fsl-asl_mfree fsl-avwutils fsl-base fsl-basil fsl-basisfield fsl-baycest fsl-bet2 fsl-bianca fsl-biancadata fsl-bint - fsl-cluster fsl-copain fsl-cprob fsl-cudabasisfield-cuda-10 fsl-cudimot fsl-data_atlases + fsl-cluster fsl-copain fsl-cprob fsl-cudimot fsl-data_atlases fsl-data_atlases_xtract fsl-data_first_models_317_bin fsl-data_first_models_336_bin fsl-data_linearmni fsl-data_omm fsl-data_possum fsl-data_standard fsl-deface fsl-discreteopt fsl-dpm fsl-dwssfp - fsl-easyfeat fsl-eddy fsl-eddy-cuda-10 fsl-eddy_qc fsl-fabber_core fsl-fabber_models_asl fsl-fabber_models_cest + fsl-easyfeat fsl-eddy fsl-eddy_qc fsl-fabber_core fsl-fabber_models_asl fsl-fabber_models_cest fsl-fabber_models_dce fsl-fabber_models_dsc fsl-fabber_models_dualecho fsl-fabber_models_dwi fsl-fabber_models_pet fsl-fabber_models_qbold fsl-fabber_models_t1 fsl-fast4 fsl-fastpdlib - fsl-fdt fsl-fdt-cuda-10 fsl-feat5 fsl-film fsl-filmbabe fsl-first fsl-first_lib fsl-flameo + fsl-fdt fsl-feat5 fsl-film fsl-filmbabe fsl-first fsl-first_lib fsl-flameo fsl-flirt fsl-fnirt fsl-fugue fsl-get_standard fsl-giftiio fsl-gps fsl-gradunwarp fsl-gui-bet fsl-gui-desktop fsl-installer fsl-lesions fsl-libgdc fsl-libmeshutils fsl-libvis fsl-load_dicom fsl-mcflirt fsl-melodic fsl-meshclass fsl-misc_c fsl-misc_scripts fsl-misc_tcl fsl-miscmaths fsl-miscvis - fsl-mist fsl-mm fsl-mmorf-cuda-10 fsl-msm fsl-msmreglib fsl-mvdisc fsl-nets fsl-newimage - fsl-newmesh fsl-newnifti fsl-newran fsl-oxford_asl fsl-possum fsl-ptx2 fsl-ptx2-cuda-10 fsl-pyfeeds + fsl-mist fsl-mm fsl-msm fsl-msmreglib fsl-mvdisc fsl-nets fsl-newimage + fsl-newmesh fsl-newnifti fsl-newran fsl-oxford_asl fsl-possum fsl-ptx2 fsl-pyfeeds fsl-pyfeeds-tests fsl-pyfix fsl-qboot fsl-randomise fsl-relax fsl-shapemodel fsl-siena fsl-slicetimer - fsl-sub fsl-sub-plugin-sge fsl-sub-plugin-slurm fsl-surface fsl-susan fsl-swe fsl-tbss fsl-tirl + fsl-sub fsl-sub-plugin-sge fsl-sub-plugin-slurm fsl-surface fsl-susan fsl-swe fsl-tbss fsl-topup fsl-utils fsl-vbm fsl-verbena fsl-vtkio fsl-warpfns fsl-wire fsl-xtract fsl-xtract_data fsl-znzlib fsl_mrs fsl_sub fsl_sub_plugin_sge fsl_sub_plugin_slurm From 9e577260c60cc5f5a866e1b4667b7ed8c05f4e0b Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 09:46:29 +1100 Subject: [PATCH 018/224] getting conda install in ci-cd to work --- .github/workflows/ci-cd.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index 8b225eb..17b0fe7 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -141,7 +141,7 @@ jobs: fsl-fabber_models_dce fsl-fabber_models_dsc fsl-fabber_models_dualecho fsl-fabber_models_dwi fsl-fabber_models_pet fsl-fabber_models_qbold fsl-fabber_models_t1 fsl-fast4 fsl-fastpdlib fsl-fdt fsl-feat5 fsl-film fsl-filmbabe fsl-first fsl-first_lib fsl-flameo - fsl-flirt fsl-fnirt fsl-fugue fsl-get_standard fsl-giftiio fsl-gps fsl-gradunwarp fsl-gui-bet + fsl-flirt fsl-fnirt fsl-fugue fsl-get_standard fsl-giftiio fsl-gps fsl-gui-bet fsl-gui-desktop fsl-installer fsl-lesions fsl-libgdc fsl-libmeshutils fsl-libvis fsl-load_dicom fsl-mcflirt fsl-melodic fsl-meshclass fsl-misc_c fsl-misc_scripts fsl-misc_tcl fsl-miscmaths fsl-miscvis fsl-mist fsl-mm fsl-msm fsl-msmreglib fsl-mvdisc fsl-nets fsl-newimage From d8d855695fd4c7350694ec8d2bc5c44ea6b4acb4 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 10:02:17 +1100 Subject: [PATCH 019/224] removed other troublesome packages in ci-cd install --- .github/workflows/ci-cd.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index 17b0fe7..a144723 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -141,12 +141,12 @@ jobs: fsl-fabber_models_dce fsl-fabber_models_dsc fsl-fabber_models_dualecho fsl-fabber_models_dwi fsl-fabber_models_pet fsl-fabber_models_qbold fsl-fabber_models_t1 fsl-fast4 fsl-fastpdlib fsl-fdt fsl-feat5 fsl-film fsl-filmbabe fsl-first fsl-first_lib fsl-flameo - fsl-flirt fsl-fnirt fsl-fugue fsl-get_standard fsl-giftiio fsl-gps fsl-gui-bet + fsl-flirt fsl-fnirt fsl-fugue fsl-get_standard fsl-giftiio fsl-gps fsl-gui-desktop fsl-installer fsl-lesions fsl-libgdc fsl-libmeshutils fsl-libvis fsl-load_dicom fsl-mcflirt fsl-melodic fsl-meshclass fsl-misc_c fsl-misc_scripts fsl-misc_tcl fsl-miscmaths fsl-miscvis fsl-mist fsl-mm fsl-msm fsl-msmreglib fsl-mvdisc fsl-nets fsl-newimage fsl-newmesh fsl-newnifti fsl-newran fsl-oxford_asl fsl-possum fsl-ptx2 fsl-pyfeeds - fsl-pyfeeds-tests fsl-pyfix fsl-qboot fsl-randomise fsl-relax fsl-shapemodel fsl-siena fsl-slicetimer + fsl-pyfeeds-tests fsl-qboot fsl-randomise fsl-relax fsl-shapemodel fsl-siena fsl-slicetimer fsl-sub fsl-sub-plugin-sge fsl-sub-plugin-slurm fsl-surface fsl-susan fsl-swe fsl-tbss fsl-topup fsl-utils fsl-vbm fsl-verbena fsl-vtkio fsl-warpfns fsl-wire fsl-xtract fsl-xtract_data fsl-znzlib fsl_mrs fsl_sub fsl_sub_plugin_sge fsl_sub_plugin_slurm From 5eecf2e52fd68218888d7f51132ed1eb60d5935e Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 10:43:59 +1100 Subject: [PATCH 020/224] fixed up report progress --- .github/workflows/ci-cd.yaml | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index a144723..f6d639d 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -45,7 +45,7 @@ jobs: - name: Run automatic Nipype > Pydra conversion run: ./nipype-auto-conv/generate - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: converted-nipype path: pydra/tasks/fsl/auto @@ -71,7 +71,7 @@ jobs: run: git checkout $(git tag -l | grep 'v.*' | tail -n 1 | awk -F post '{print $1}') - name: Download tasks converted from Nipype - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: converted-nipype path: pydra/tasks/fsl/auto @@ -152,7 +152,7 @@ jobs: fsl-znzlib fsl_mrs fsl_sub fsl_sub_plugin_sge fsl_sub_plugin_slurm - name: Download tasks converted from Nipype - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: converted-nipype path: pydra/tasks/fsl/auto @@ -303,7 +303,7 @@ jobs: run: git checkout ${{ steps.latest_tag.outputs.TAG }} - name: Download tasks converted from Nipype - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: converted-nipype path: pydra/tasks/fsl/auto @@ -357,7 +357,7 @@ jobs: - name: Check distributions run: twine check dist/* - - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v4 with: name: distributions path: dist/ @@ -393,6 +393,9 @@ jobs: runs-on: ubuntu-latest steps: + - name: Checkout + uses: actions/checkout@v4 + - name: Generate progress report id: generate-report run: | @@ -402,14 +405,14 @@ jobs: - name: Report progress to Nipype2Pydra repo if: github.event_name == 'release' || github.event_name == 'repository_dispatch' run: >- - curl -XPOST -u "${{ env.POST_RELEASE_PAT }}" -H "Accept: application/vnd.github.everest-preview+json" + curl -XPOST -u "${{ env.REPORT_PROGRESS_PAT }}" -H "Accept: application/vnd.github.everest-preview+json" "https://api.github.com/repos/nipype/pydra-fsl/dispatches" -d '{ "event_type": "progress-report", "client_payload": ${{ steps.generate-report.output.progress_report }} }' env: - PAT: ${{ env.PROGRESS_REPORT_PAT }} + PAT: ${{ env.REPORT_PROGRESS_PAT }} # Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. From c09bb53bfa2f7f6fd970f470dcfc3b5f002614e9 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 11:50:56 +1100 Subject: [PATCH 021/224] added report progress tool --- tools/report_progress.py | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) create mode 100755 tools/report_progress.py diff --git a/tools/report_progress.py b/tools/report_progress.py new file mode 100755 index 0000000..10935f0 --- /dev/null +++ b/tools/report_progress.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python3 +from pathlib import Path +import json +import yaml +import click + +TOOLKIT_NAME = "FSL" + + +@click.command +@click.argument( + "out_json_path", + type=click.Path(path_type=Path), + help="The output path to save the report", +) +def report_progress(out_json_path: Path): + + out_json_path.parent.mkdir(exist_ok=True, parents=True) + + SPECS_DIR = Path(__file__).parent / "nipype-auto-conv" / "specs" + + report = {"name": TOOLKIT_NAME, "tasks": {}} + + for spec_path in SPECS_DIR.glob("*.yaml"): + with open(spec_path) as f: + spec = yaml.load(f, Loader=yaml.SafeLoader) + + report["tasks"][spec["task_name"]] = { + n: not s["xfail"] for n, s in spec["tests"].items() + } + + with open(out_json_path, "w") as f: + json.dump(report, f) From 643bcb48aa589c404e378d65dcae94432e808d2d Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 12:16:11 +1100 Subject: [PATCH 022/224] disable report progress job --- .github/workflows/ci-cd.yaml | 50 ++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/ci-cd.yaml b/.github/workflows/ci-cd.yaml index f6d639d..94c54f8 100644 --- a/.github/workflows/ci-cd.yaml +++ b/.github/workflows/ci-cd.yaml @@ -388,31 +388,31 @@ jobs: prerelease: false - report_progress: - needs: [deploy] - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v4 - - - name: Generate progress report - id: generate-report - run: | - tools/report_progress.py outputs/progress-report.json - echo "progress_report=$(cat outputs/progress-report.json)" >> $GITHUB_OUTPUT - - - name: Report progress to Nipype2Pydra repo - if: github.event_name == 'release' || github.event_name == 'repository_dispatch' - run: >- - curl -XPOST -u "${{ env.REPORT_PROGRESS_PAT }}" -H "Accept: application/vnd.github.everest-preview+json" - "https://api.github.com/repos/nipype/pydra-fsl/dispatches" - -d '{ - "event_type": "progress-report", - "client_payload": ${{ steps.generate-report.output.progress_report }} - }' - env: - PAT: ${{ env.REPORT_PROGRESS_PAT }} + # report_progress: + # needs: [deploy] + # runs-on: ubuntu-latest + # steps: + + # - name: Checkout + # uses: actions/checkout@v4 + + # - name: Generate progress report + # id: generate-report + # run: | + # tools/report_progress.py outputs/progress-report.json + # echo "progress_report=$(cat outputs/progress-report.json)" >> $GITHUB_OUTPUT + + # - name: Report progress to Nipype2Pydra repo + # if: github.event_name == 'release' || github.event_name == 'repository_dispatch' + # run: >- + # curl -XPOST -u "${{ env.REPORT_PROGRESS_PAT }}" -H "Accept: application/vnd.github.everest-preview+json" + # "https://api.github.com/repos/nipype/pydra-fsl/dispatches" + # -d '{ + # "event_type": "progress-report", + # "client_payload": ${{ steps.generate-report.output.progress_report }} + # }' + # env: + # PAT: ${{ env.REPORT_PROGRESS_PAT }} # Deploy on tags if PYPI_API_TOKEN is defined in the repository secrets. From 5b56c6fa5d08d1f72a74219a63b358261199152d Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:20:58 +1100 Subject: [PATCH 023/224] MNT: Initial project setup --- .editorconfig | 20 ++++ .gitignore | 36 ++++++- LICENSE | 190 +++++++++++++++++++++++++++++++++++- README.md | 53 ++++++++++ hatch.toml | 31 ++++++ pydra/tasks/fsl/__init__.py | 1 + pyproject.toml | 100 +++++++++++-------- 7 files changed, 389 insertions(+), 42 deletions(-) create mode 100644 .editorconfig create mode 100644 README.md create mode 100644 hatch.toml diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..6aabaf9 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,20 @@ +# EditorConfig + +root = true + +[*] +indent_style = space +indent_size = 4 +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.md] +trim_trailing_whitespace = false + +[*.toml] +indent_size = 2 + +[*.yaml] +indent_size = 2 diff --git a/.gitignore b/.gitignore index a6fcb00..45857c9 100644 --- a/.gitignore +++ b/.gitignore @@ -50,6 +50,7 @@ coverage.xml *.py,cover .hypothesis/ .pytest_cache/ +cover/ # Translations *.mo @@ -72,6 +73,7 @@ instance/ docs/_build/ # PyBuilder +.pybuilder/ target/ # Jupyter Notebook @@ -83,6 +85,9 @@ ipython_config.py # pyenv .python-version +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version # pipenv # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. @@ -92,6 +97,22 @@ ipython_config.py #Pipfile.lock # PEP 582; used by e.g. github.com/David-OConnor/pyflow +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ # Celery stuff @@ -140,9 +161,22 @@ dmypy.json # Mac garbarge .DS_store +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# JetBrains +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +.fleet/ + # Generated files /pydra/tasks/fsl/_version.py /related-packages/fileformats/fileformats/medimage_fsl/_version.py /related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py /pydra/tasks/fsl/auto -/pydra/tasks/fsl/_version.py +/pydra/tasks/fsl/_version.py \ No newline at end of file diff --git a/LICENSE b/LICENSE index e00bcb3..261eeb9 100644 --- a/LICENSE +++ b/LICENSE @@ -1,4 +1,192 @@ - Copyright 2021 Nipype developers + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright [yyyy] [name of copyright owner] Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/README.md b/README.md new file mode 100644 index 0000000..c35e630 --- /dev/null +++ b/README.md @@ -0,0 +1,53 @@ +# pydra-tasks-fsl + +[![PyPI - Version][pypi-version]][pypi-project] +[![PyPI - Python Version][pypi-pyversions]][pypi-project] + +----- + +Pydra tasks for FSL. + +[Pydra][pydra] is a dataflow engine which provides +a set of lightweight abstractions for DAG +construction, manipulation, and distributed execution. + +[FSL][fsl] is a comprehensive library of analysis tools +for FMRI, MRI and DTI brain imaging data. + +## Installation + +```console +pip install pydra-tasks-fsl +``` + +## Development + +This project is managed with [Hatch][hatch]: + +```console +pipx install hatch +``` + +To run the test suite: + +```console +hatch run test:no-cov +``` + +To fix linting issues: + +```console +hatch run lint:fix +``` + +## License + +`pydra-tasks-fsl` is distributed under the terms of the [Apache License 2.0][license] license. + +[pypi-project]: https://pypi.org/project/pydra-tasks-fsl +[pypi-version]: https://img.shields.io/pypi/v/pydra-tasks-fsl.svg +[pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-tasks-fsl.svg +[pydra]: https://pydra.readthedocs.io/ +[fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL +[hatch]: https://hatch.pypa.io/ +[license]: https://spdx.org/licenses/Apache-2.0.html diff --git a/hatch.toml b/hatch.toml new file mode 100644 index 0000000..4f7f474 --- /dev/null +++ b/hatch.toml @@ -0,0 +1,31 @@ +[build.targets.wheel] +only-include = ["pydra/tasks/fsl"] + +[envs.default] +dependencies = [ + "pytest", + "pytest-cov", +] +[envs.default.scripts] +cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=pydra --cov=tests {args}" +no-cov = "cov --no-cov {args}" + +[[envs.test.matrix]] +python = ["37", "38", "39", "310", "311"] + +[envs.lint] +detached = true +dependencies = [ + "black", + "isort", + "tomli", +] +[envs.lint.scripts] +all = [ + "black --check --diff {args:.}", + "isort --check --diff {args:.}", +] +fix = [ + "black --quiet {args:.}", + "isort --quiet {args:.}", +] diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index de9520f..dc03b8a 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -5,6 +5,7 @@ >>> import pydra.engine >>> import pydra.tasks.fsl """ + from warnings import warn from pathlib import Path diff --git a/pyproject.toml b/pyproject.toml index a668cff..3142085 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -8,53 +8,60 @@ description = "Pydra tasks package for fsl" readme = "README.rst" requires-python = ">=3.8" dependencies = [ - "pydra >=0.22", - "fileformats >=0.8.3", - "fileformats-datascience >=0.1", - "fileformats-medimage >=0.4.1", - "fileformats-medimage-fsl" + "pydra >=0.22", + "fileformats >=0.8.3", + "fileformats-datascience >=0.1", + "fileformats-medimage >=0.4.1", + "fileformats-medimage-fsl", +] +license = { file = "LICENSE" } +authors = [ + { name = "Nipype developers", email = "neuroimaging@python.org" }, + { name = "Ghislain Vaillant", email = "ghislain.vaillant@icm-institute.org" }, +] +maintainers = [ + { name = "Nipype developers", email = "neuroimaging@python.org" }, + { name = "Ghislain Vaillant", email = "ghislain.vaillant@icm-institute.org" }, ] -license = {file = "LICENSE"} -authors = [{name = "Nipype developers", email = "neuroimaging@python.org"}] -maintainers = [{name = "Nipype developers", email = "neuroimaging@python.org"}] keywords = ["pydra"] classifiers = [ - "Development Status :: 2 - Pre-Alpha", - "Environment :: Console", - "Intended Audience :: Science/Research", - "License :: OSI Approved :: Apache Software License", - "Operating System :: MacOS :: MacOS X", - "Operating System :: POSIX :: Linux", - "Programming Language :: Python :: 3", - "Topic :: Scientific/Engineering", + "Development Status :: 3 - Alpha", + "Intended Audience :: Science/Research", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.7", + "Programming Language :: Python :: 3.8", + "Programming Language :: Python :: 3.9", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Topic :: Scientific/Engineering", + "Topic :: Software Development :: Libraries", ] dynamic = ["version"] [project.optional-dependencies] -dev = [ - "black", - "pre-commit", -] +dev = ["black", "pre-commit"] doc = [ - "packaging", - "sphinx >=2.1.2", - "sphinx_rtd_theme", - "sphinxcontrib-apidoc ~=0.3.0", - "sphinxcontrib-napoleon", - "sphinxcontrib-versioning", + "packaging", + "sphinx >=2.1.2", + "sphinx_rtd_theme", + "sphinxcontrib-apidoc ~=0.3.0", + "sphinxcontrib-napoleon", + "sphinxcontrib-versioning", ] test = [ - "nipype2pydra", - "pytest >= 4.4.0", - "pytest-cov", - "pytest-env", - "pytest-xdist", - "pytest-rerunfailures", - "codecov", - "fileformats-extras", - "fileformats-datascience-extras", - "fileformats-medimage-extras", - "fileformats-medimage-fsl-extras" + "nipype2pydra", + "pytest >= 4.4.0", + "pytest-cov", + "pytest-env", + "pytest-xdist", + "pytest-rerunfailures", + "codecov", + "fileformats-extras", + "fileformats-datascience-extras", + "fileformats-medimage-extras", + "fileformats-medimage-fsl-extras", ] [tool.hatch.version] @@ -76,9 +83,22 @@ ignore-words = ".codespell-ignorewords" [tool.flake8] doctests = true -per-file-ignores = [ - "__init__.py:F401,F403" -] +per-file-ignores = ["__init__.py:F401,F403"] max-line-length = 88 select = "C,E,F,W,B,B950" extend-ignore = ['E203', 'E501', 'E129', 'W503'] + +[project.urls] +Documentation = "https://github.com/nipype/pydra-tasks-fsl#readme" +Issues = "https://github.com/nipype/pydra-tasks-fsl/issues" +Source = "https://github.com/nipype/pydra-tasks-fsl" + +[tool.coverage.run] +branch = true +parallel = true + +[tool.coverage.report] + +minversion = "6.0" +# addopts = ["--doctest-modules", "--doctest-continue-on-failure"] +testpaths = ["pydra"] From 563ac8bee0144a4db4573952b73c529b87090567 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:15 +1100 Subject: [PATCH 024/224] NEW: Add task definition for FLIRT --- pydra/tasks/fsl/flirt.py | 109 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 109 insertions(+) create mode 100644 pydra/tasks/fsl/flirt.py diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py new file mode 100644 index 0000000..02296cc --- /dev/null +++ b/pydra/tasks/fsl/flirt.py @@ -0,0 +1,109 @@ +""" +FLIRT +===== + +Examples +-------- + +Register two images together: + +>>> task = FLIRT( +... input_image="invol", +... reference_image="refvol", +... output_image="outvol", +... output_transformation="invol2refvol.mat", +... degrees_of_freedom=6, +... ) +>>> task.cmdline +'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -dof 6' + +Apply a saved transformation to another image: + +>>> task = FLIRT( +... input_image="newvol", +... reference_image="refvol", +... output_image="outvol", +... input_transformation="invol2refvol.mat", +... apply_transformation=True, +... ) +>>> task.cmdline +'flirt -in newvol -ref refvol -out outvol -init invol2refvol.mat -applyxfm' + +Perform a single slice registration: + +>>> task = FLIRT( +... input_image="inslice", +... reference_image="refslice", +... output_image="outslice", +... output_transformation="i2r.mat", +... use_2d_rigid_body_transformation=True, +... ) +>>> task.cmdline +'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -2D' +""" +import os + +import attrs + +import pydra + +__all__ = ["FLIRT"] + + +@attrs.define(slots=False, kw_only=True) +class FLIRTSpec(pydra.specs.ShellSpec): + """Specifications for FSL FLIRT.""" + + input_image: os.PathLike = attrs.field( + metadata={"help_string": "input volume", "argstr": "-in"} + ) + + reference_image: os.PathLike = attrs.field( + metadata={"help_string": "reference volume", "argstr": "-ref"} + ) + + output_image: os.PathLike = attrs.field( + metadata={"help_string": "output volume", "argstr": "-out"} + ) + + input_transformation: os.PathLike = attrs.field( + metadata={"help_string": "input transformation as 4x4 matrix", "argstr": "-init"} + ) + + output_transformation: os.PathLike = attrs.field( + metadata={ + "help_string": "output transformation as 4x4 matrix", + "argstr": "-omat", + } + ) + + degrees_of_freedom: int = attrs.field( + metadata={ + "help_string": "degrees of freedom (default: 12)", + "argstr": "-dof", + "allowed_values": {3, 6, 7, 9, 12}, + } + ) + + apply_transformation: bool = attrs.field( + metadata={ + "help_string": "apply transformation without optimization", + "argstr": "-applyxfm", + "requires": {"input_transformation"}, + } + ) + + use_2d_rigid_body_transformation: bool = attrs.field( + metadata={ + "help_string": "use rigid body transformation in 2D (ignores DOF)", + "argstr": "-2D", + } + ) + + +class FLIRT(pydra.engine.ShellCommandTask): + """Task definition for FSL FLIRT.""" + + input_spec = pydra.specs.SpecInfo(name="FLIRTInput", bases=(FLIRTSpec,)) + + executable = "flirt" From d09701429899f498e64f1269a6f6dce108b8f95f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 025/224] NEW: Add task definition for fslmerge --- pydra/tasks/fsl/fslmerge.py | 81 +++++++++++++++++++++++++++++++++++++ 1 file changed, 81 insertions(+) create mode 100644 pydra/tasks/fsl/fslmerge.py diff --git a/pydra/tasks/fsl/fslmerge.py b/pydra/tasks/fsl/fslmerge.py new file mode 100644 index 0000000..2f27a80 --- /dev/null +++ b/pydra/tasks/fsl/fslmerge.py @@ -0,0 +1,81 @@ +""" +FSLMerge +======== + +Examples +-------- + +>>> task = FSLMerge( +... dimension="t", +... input_images=["vol1.nii", "vol2.nii"], +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fslmerge -t ...merged vol1.nii vol2.nii' +""" + +__all__ = ["FSLMerge"] + +import os +import typing as ty + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLMergeSpec(pydra.specs.ShellSpec): + """Specifications for FSLMerge.""" + + dimension: str = attrs.field( + metadata={ + "help_string": "merge dimension", + "mandatory": True, + "argstr": "-{dimension}", + "allowed_values": {"t", "x", "y", "z", "a", "tr"}, + "xor": {"volume_index"}, + } + ) + + volume_index: int = attrs.field( + metadata={ + "help_string": "merge volume N from each input file", + "mandatory": True, + "argstr": "-n", + "xor": {"dimension"}, + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "merged", + } + ) + + input_images: ty.Iterable[os.PathLike] = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "...", + } + ) + + repetition_time: float = attrs.field( + metadata={ + "help_string": "specify TR value in seconds (default is 1.0)", + "argstr": "", + } + ) + + +class FSLMerge(pydra.engine.ShellCommandTask): + """Task definition for FSLMerge.""" + + input_spec = pydra.specs.SpecInfo( + name="FSLMergeInput", + bases=(FSLMergeSpec,), + ) + + executable = "fslmerge" From 2abdc69490a9d6101e2c9143590d977ab65b81af Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 026/224] STY: Fix formatting --- pydra/tasks/fsl/flirt.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 02296cc..8c02b5f 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -67,7 +67,10 @@ class FLIRTSpec(pydra.specs.ShellSpec): ) input_transformation: os.PathLike = attrs.field( - metadata={"help_string": "input transformation as 4x4 matrix", "argstr": "-init"} + metadata={ + "help_string": "input transformation as 4x4 matrix", + "argstr": "-init", + } ) output_transformation: os.PathLike = attrs.field( From cec9d8d3c7a83a8d32f1c3db293a0e6b0b96d90c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 027/224] STY: Fix docstrings --- pydra/tasks/fsl/fslmerge.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pydra/tasks/fsl/fslmerge.py b/pydra/tasks/fsl/fslmerge.py index 2f27a80..683242e 100644 --- a/pydra/tasks/fsl/fslmerge.py +++ b/pydra/tasks/fsl/fslmerge.py @@ -13,8 +13,6 @@ 'fslmerge -t ...merged vol1.nii vol2.nii' """ -__all__ = ["FSLMerge"] - import os import typing as ty @@ -22,10 +20,12 @@ import pydra +__all__ = ["FSLMerge"] + @attrs.define(slots=False, kw_only=True) class FSLMergeSpec(pydra.specs.ShellSpec): - """Specifications for FSLMerge.""" + """Specifications for fslmerge.""" dimension: str = attrs.field( metadata={ @@ -71,7 +71,7 @@ class FSLMergeSpec(pydra.specs.ShellSpec): class FSLMerge(pydra.engine.ShellCommandTask): - """Task definition for FSLMerge.""" + """Task definition for fslmerge.""" input_spec = pydra.specs.SpecInfo( name="FSLMergeInput", From e21b4cd3b22ef4b41f1ac740692b7547c7b980f8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 028/224] CI: Add workflow to test the codebase --- .github/dependabot.yaml | 6 ++++++ .github/workflows/test.yaml | 41 +++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) create mode 100644 .github/dependabot.yaml create mode 100644 .github/workflows/test.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..ca79ca5 --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,6 @@ +version: 2 +updates: + - package-ecosystem: github-actions + directory: / + schedule: + interval: weekly diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..4eb0a69 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,41 @@ +name: test + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +permission: + content: read + +jobs: + lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: Install Hatch + run: pipx install hatch + - name: Lint codebase + run: hatch run lint:all + + test: + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, macos-latest] + python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + runs-on: ${{ matrix.os }} + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install Hatch + run: pipx install hatch + - name: Test codebase + run: hatch run +python=${{ matrix.python-version }} test:cov From 955cd1e2a71429c84698290012a06260032ecb1c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 029/224] CI: Fix permission -> permissions --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 4eb0a69..fef3313 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -7,7 +7,7 @@ on: branches: [ main ] workflow_dispatch: -permission: +permissions: content: read jobs: From fefdcd40b81e5ada85f08dc0d789a99b010606b3 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 030/224] CI: Fix content -> contents --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index fef3313..6b52a9a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -8,7 +8,7 @@ on: workflow_dispatch: permissions: - content: read + contents: read jobs: lint: From d235fd61091be814742f262276f608fbf66f193a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 031/224] MNT: Fix matrix definition --- hatch.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hatch.toml b/hatch.toml index 4f7f474..456f42c 100644 --- a/hatch.toml +++ b/hatch.toml @@ -11,7 +11,7 @@ cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=pydra no-cov = "cov --no-cov {args}" [[envs.test.matrix]] -python = ["37", "38", "39", "310", "311"] +python = ["3.7", "3.8", "3.9", "3.10", "3.11"] [envs.lint] detached = true From 7e80e2f4d3a6db52062ad0c16436fc12dc47ad70 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:26 +1100 Subject: [PATCH 032/224] STY: Rename input and output transformations to matrix --- pydra/tasks/fsl/flirt.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 8c02b5f..6c19c75 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -11,7 +11,7 @@ ... input_image="invol", ... reference_image="refvol", ... output_image="outvol", -... output_transformation="invol2refvol.mat", +... output_matrix="invol2refvol.mat", ... degrees_of_freedom=6, ... ) >>> task.cmdline @@ -23,7 +23,7 @@ ... input_image="newvol", ... reference_image="refvol", ... output_image="outvol", -... input_transformation="invol2refvol.mat", +... input_matrix="invol2refvol.mat", ... apply_transformation=True, ... ) >>> task.cmdline @@ -35,7 +35,7 @@ ... input_image="inslice", ... reference_image="refslice", ... output_image="outslice", -... output_transformation="i2r.mat", +... output_matrix="i2r.mat", ... use_2d_rigid_body_transformation=True, ... ) >>> task.cmdline @@ -66,14 +66,14 @@ class FLIRTSpec(pydra.specs.ShellSpec): metadata={"help_string": "output volume", "argstr": "-out"} ) - input_transformation: os.PathLike = attrs.field( + input_matrix: os.PathLike = attrs.field( metadata={ "help_string": "input transformation as 4x4 matrix", "argstr": "-init", } ) - output_transformation: os.PathLike = attrs.field( + output_matrix: os.PathLike = attrs.field( metadata={ "help_string": "output transformation as 4x4 matrix", "argstr": "-omat", @@ -92,7 +92,7 @@ class FLIRTSpec(pydra.specs.ShellSpec): metadata={ "help_string": "apply transformation without optimization", "argstr": "-applyxfm", - "requires": {"input_transformation"}, + "requires": {"input_matrix"}, } ) From b898fbacfc80ec6c622a248871d87ba0e22502e8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:37 +1100 Subject: [PATCH 033/224] NEW: Add task definition for BET --- pydra/tasks/fsl/bet.py | 114 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 pydra/tasks/fsl/bet.py diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py new file mode 100644 index 0000000..5e91881 --- /dev/null +++ b/pydra/tasks/fsl/bet.py @@ -0,0 +1,114 @@ +""" +BET +=== +""" + +import os +import typing as ty + +import attrs + +import pydra + +__all__ = ["BET"] + + +class BETSpec: + """Specifications for BET.""" + + input_image_file: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + output_image_file: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image_file}_bet", + "requires": {"input_image_file"}, + } + ) + + generate_brain_surface_outline: bool = attrs.field( + metadata={"help_string": "generate brain surface outline", "argstr": "-o"} + ) + + generate_brain_mask: bool = attrs.field( + metadata={"help_string": "generate binary brain mask", "argstr": "-m"} + ) + + generate_skull_image: bool = attrs.field( + metadata={"help_string": "generate approximate skull image", "argstr": "-s"} + ) + + no_segmented_brain_image: bool = attrs.field( + metadata={ + "help_string": "do not generate the segmented brain image", + "argstr": "-n", + } + ) + + fractional_intensity_threshold: float = attrs.field( + metadata={ + "help_string": ( + "Fractional intensity threshold (between 0 and 1). Default is 0.5. " + "Smaller values give larger brain outline estimates." + ), + "argstr": "-f", + } + ) + + vertical_gradient: float = attrs.field( + metadata={ + "help_string": ( + "Vertical gradient in fractional intensity threshold (between -1 and 1)." + " Default is 0. Positive values give larger brain outlines." + ), + "argstr": "-g", + } + ) + + head_radius: float = attrs.field( + metadata={ + "help_string": ( + "Head radius (in millimeters)." + " Initial surface sphere is set to half of this value." + ), + "argstr": "-r", + } + ) + + center_of_gravity: ty.Tuple[int, int, int] = attrs.field( + metadata={ + "help_string": ( + "centre-of-gravity (in voxel coordinates) of initial mesh surface" + ), + "argstr": "-c", + } + ) + + apply_thresholding: bool = attrs.field( + metadata={ + "help_string": "apply thresholding to segmented brain image and mask", + "argstr": "-t", + } + ) + + generate_brain_surface_mesh: bool = attrs.field( + metadata={ + "help_string": "generate brain surface as mesh in .vtk format", + "argstr": "-e", + } + ) + + +class BET: + """Task definition for BET.""" + + input_spec = pydra.specs.SpecInfo(name="BETInput", bases=(BETSpec,)) + + executable = "bet" From 0ffdd6477ff3e9c358b0979706c8e1a78b8d9ea4 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:37 +1100 Subject: [PATCH 034/224] DOC: Add module docstring to BET --- pydra/tasks/fsl/bet.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 5e91881..51ae6b2 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -1,6 +1,10 @@ """ BET === + +BET (Brain Extraction Tool) removes non-brain tissues from whole-head images. +It can also estimate the inner and outer skull surfaces, and outer scalp surface, +when provided with good quality T1 and T2 input images. """ import os From 9afccc7e17442cd198aa906daeb891864fa8d893 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:37 +1100 Subject: [PATCH 035/224] DOC: Add description to FLIRT docstring --- pydra/tasks/fsl/flirt.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 6c19c75..36d5cf1 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -2,6 +2,9 @@ FLIRT ===== +FLIRT (FMRIB's Linear Image Registration Tool) is a robust and accurate tool +for affine registration of intra- and inter-modal brain images. + Examples -------- @@ -52,7 +55,7 @@ @attrs.define(slots=False, kw_only=True) class FLIRTSpec(pydra.specs.ShellSpec): - """Specifications for FSL FLIRT.""" + """Specifications for FLIRT.""" input_image: os.PathLike = attrs.field( metadata={"help_string": "input volume", "argstr": "-in"} @@ -105,7 +108,7 @@ class FLIRTSpec(pydra.specs.ShellSpec): class FLIRT(pydra.engine.ShellCommandTask): - """Task definition for FSL FLIRT.""" + """Task definition for FLIRT.""" input_spec = pydra.specs.SpecInfo(name="FLIRTInput", bases=(FLIRTSpec,)) From 7090bec5a5409a97c00d3121312d6d8842eed338 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:47 +1100 Subject: [PATCH 036/224] NEW: Add task definition for FNIRT --- pydra/tasks/fsl/fnirt.py | 43 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 pydra/tasks/fsl/fnirt.py diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py new file mode 100644 index 0000000..d4d99df --- /dev/null +++ b/pydra/tasks/fsl/fnirt.py @@ -0,0 +1,43 @@ +""" +FNIRT +===== + +FNIRT (FSL Non-linear Image Registration Tool) performs non-linear registration of brain images. + +Examples +-------- + +Register two images together: + +>>> task = FNIRT( +... reference_image="template.nii", +... input_image="input.nii", +... ) +>>> task.cmdline +'fnirt --ref template.nii --in input.nii' +""" +import os + +import attrs +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FNIRTSpec(pydra.specs.ShellSpec): + """Task specifications for FNIRT.""" + + reference_image: os.PathLike = attrs.field( + metadata={"help_string": "reference image", "argstr": "--ref"} + ) + + input_image: os.PathLike = attrs.field( + metadata={"help_string": "input image", "argstr": "--in"} + ) + + +class FNIRT(pydra.engine.ShellCommandTask): + """Task definition for FNIRT.""" + + input_spec = pydra.specs.SpecInfo(name="FNIRTInput", bases=(FNIRTSpec,)) + + executable = "fnirt" From 1e557a0d7471eb4cbef12ff3f39b34f68a43b0da Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:47 +1100 Subject: [PATCH 037/224] FIX: Add public name declarations for fnirt module --- pydra/tasks/fsl/fnirt.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index d4d99df..7ea2f95 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -21,6 +21,8 @@ import attrs import pydra +__all__ = ["FNIRT"] + @attrs.define(slots=False, kw_only=True) class FNIRTSpec(pydra.specs.ShellSpec): From 8a7b1b01d7bb71fbaf801a823be622365b72edfe Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:47 +1100 Subject: [PATCH 038/224] FIX: Imports of fnirt module --- pydra/tasks/fsl/fnirt.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index 7ea2f95..157ae0b 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -19,6 +19,7 @@ import os import attrs + import pydra __all__ = ["FNIRT"] From 8357bc362bd589ff49c586acfe6de80a9090f242 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:47 +1100 Subject: [PATCH 039/224] FIX: Use consistent image parameter naming convention --- pydra/tasks/fsl/bet.py | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 51ae6b2..9e81a80 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -20,7 +20,7 @@ class BETSpec: """Specifications for BET.""" - input_image_file: os.PathLike = attrs.field( + input_image: os.PathLike = attrs.field( metadata={ "help_string": "input image", "mandatory": True, @@ -28,12 +28,11 @@ class BETSpec: } ) - output_image_file: str = attrs.field( + output_image: str = attrs.field( metadata={ "help_string": "output image", "argstr": "", - "output_file_template": "{input_image_file}_bet", - "requires": {"input_image_file"}, + "output_file_template": "{input_image}_bet", } ) From 94f656f50ac7a4fb1274353a68476a223679504c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:21:47 +1100 Subject: [PATCH 040/224] MNT: Restrict coverage version --- hatch.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/hatch.toml b/hatch.toml index 456f42c..598c213 100644 --- a/hatch.toml +++ b/hatch.toml @@ -3,6 +3,7 @@ only-include = ["pydra/tasks/fsl"] [envs.default] dependencies = [ + "coverage[toml] <7", "pytest", "pytest-cov", ] From 9d24b13c419dab031311ac281b7ef106453a6a9d Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:02 +1100 Subject: [PATCH 041/224] MNT: Exclude .hatch folder from tracking --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 45857c9..3cd7ac8 100644 --- a/.gitignore +++ b/.gitignore @@ -111,6 +111,8 @@ ipython_config.py # in version control. # https://pdm.fming.dev/#use-with-ide .pdm.toml +# Hatch +.hatch/ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm __pypackages__/ From 4ad2b953b35f9614efded587039eeb830a68c7ff Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:02 +1100 Subject: [PATCH 042/224] CI: Add concurrency settings --- .github/workflows/test.yaml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 6b52a9a..0f6ea49 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -10,6 +10,10 @@ on: permissions: contents: read +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + jobs: lint: runs-on: ubuntu-latest From 79c98584d24dfc94899e790e30e4d207de8d8d4b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:02 +1100 Subject: [PATCH 043/224] CI: Run tests on updates --- .github/workflows/test.yaml | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 0f6ea49..991d4f6 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -2,9 +2,15 @@ name: test on: push: - branches: [ main ] + paths: + - '.github/workflows/test.yaml' + - 'pydra/**' + - 'tests/**' pull_request: - branches: [ main ] + paths: + - '.github/workflows/test.yaml' + - 'pydra/**' + - 'tests/**' workflow_dispatch: permissions: From faec14885779e580ef9fdff5b3bc0377dde87d18 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:16 +1100 Subject: [PATCH 044/224] NEW: Add interfaces for eddy --- pydra/tasks/fsl/eddy.py | 337 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 337 insertions(+) create mode 100644 pydra/tasks/fsl/eddy.py diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py new file mode 100644 index 0000000..80b32c7 --- /dev/null +++ b/pydra/tasks/fsl/eddy.py @@ -0,0 +1,337 @@ +""" +eddy +==== + +Correct for artifacts induced by Eddy currents and subject motion. +""" + +import os + +import attrs + +import pydra + +__all__ = ["Eddy"] + + +@attrs.define(slots=False, kw_only=True) +class EddySpec(pydra.specs.ShellSpec): + """Specifications for eddy.""" + + # Parameters that specify input files. + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": ( + "input image as a 4D volume of all images acquired in the diffusion protocol" + ), + "mandatory": True, + "argstr": "--imain", + } + ) + + mask_image: os.PathLike = attrs.field( + metadata={ + "help_string": "brain mask as a single volume image", + "mandatory": True, + "argstr": "--mask", + } + ) + + acqp_file: os.PathLike = attrs.field( + metadata={ + "help_string": "acquisition parameters for the diffusion protocol", + "mandatory": True, + "argstr": "--acqp", + } + ) + + index_file: os.PathLike = attrs.field( + metadata={ + "help_string": "mapping from volume index to acquisition parameters", + "mandatory": True, + "argstr": "--index", + } + ) + + bvec_file: os.PathLike = attrs.field( + metadata={ + "help_string": "diffusion directions", + "mandatory": True, + "argstr": "--bvecs", + } + ) + + bval_file: os.PathLike = attrs.field( + metadata={ + "help_string": "diffusion weighting", + "mandatory": True, + "argstr": "--bvals", + } + ) + + topup_file: os.PathLike = attrs.field( + metadata={ + "help_string": "topup output file", + "mandatory": True, + "argstr": "--topup", + "xor": {"fmap_file"}, + } + ) + + fmap_file: os.PathLike = attrs.field( + metadata={ + "help_string": "fieldmap file", + "mandatory": True, + "argstr": "--field", + "xor": {"topup_file"}, + } + ) + + fmap_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "rigid-body transformation matrix from fieldmap to first input volume", + "argstr": "--field_mat", + "requires": {"fmap_file"}, + } + ) + + # Parameters specifying names of output-files. + output_basename: str = attrs.field( + default="eddy", + metadata={ + "help_string": "basename for output files", + "argstr": "--out", + }, + ) + + # Parameters specifying how eddy should be run. + first_level_model: str = attrs.field( + default="quadratic", + metadata={ + "help_string": "model for the magnetic field generated by Eddy currents", + "argstr": "--flm", + "allowed_values": {"linear", "quadratic", "cubic"}, + }, + ) + + second_level_model: str = attrs.field( + default="none", + metadata={ + "help_string": "model for how diffusion gradients generate Eddy currents", + "argstr": "--slm", + "allowed_values": {"none", "linear", "quadratic"}, + }, + ) + + fwhm: float = attrs.field( + metadata={ + "help_string": ( + "filter width used for pre-conditionning data prior to estimating distortions" + ), + "argstr": "--fwhm", + } + ) + + num_iterations: int = attrs.field( + default=5, + metadata={ + "help_string": "number of iterations for eddy", + "argstr": "--niter", + }, + ) + + fill_empty_planes: bool = attrs.field( + metadata={ + "help_string": "detect and fill empty planes", + "argstr": "--fep", + } + ) + + interpolation: str = attrs.field( + default="spline", + metadata={ + "help_string": "interpolation method for the estimation phase", + "argstr": "--interp", + "allowed_values": {"spline", "trilinear"}, + }, + ) + + resampling: str = attrs.field( + default="jac", + metadata={ + "help_string": "final resampling strategy", + "argstr": "--resamp", + "allowed_values": {"jac", "lsr"}, + }, + ) + + num_voxels: int = attrs.field( + default=1000, + metadata={ + "help_string": "number of voxels to use for GP hyperparameter estimation", + "argstr": "--nvoxhp", + }, + ) + + fudge_factor: int = attrs.field( + default=10, + metadata={ + "help_string": "fudge factor for Q-space smoothing during estimation", + "argstr": "--ff", + }, + ) + + # Parameters for outlier replacement (ol) + replace_outliers: bool = attrs.field( + metadata={"help_string": "replace outliers", "argstr": "--repol"} + ) + + ol_num_std: int = attrs.field( + metadata={ + "help_string": "number of std off to qualify as outlier", + "argstr": "--ol_nstd", + "requires": {"replace_outliers"}, + } + ) + + ol_num_voxels: int = attrs.field( + metadata={ + "help_string": "minimum number of voxels in a slice to qualify for outlier detection", + "argstr": "--ol_nvox", + "requires": {"replace_outliers"}, + } + ) + + ol_type: str = attrs.field( + metadata={ + "help_string": "type of outliers detected", + "argstr": "--ol_type", + "allowed_values": {"both", "gw", "sw"}, + "requires": {"replace_outliers"}, + } + ) + + ol_pos: bool = attrs.field( + metadata={ + "help_string": "consider both positive and negative outliers", + "argstr": "--ol_pos", + "requires": {"replace_outliers"}, + } + ) + + ol_sqr: bool = attrs.field( + metadata={ + "help_string": "consider outliers among sum-of-square differences", + "argstr": "--ol_sqr", + "requires": {"replace_outliers"}, + } + ) + + multiband_factor: int = attrs.field( + metadata={ + "help_string": "multiband factor", + "argstr": "--mb", + } + ) + + multiband_offset: int = attrs.field( + metadata={ + "help_string": "multiband slice offset", + "argstr": "--mb_offs", + "requires": {"multiband_factor"}, + } + ) + + # Parameters for intra-volume movement correction (s2v) + temporal_order: int = attrs.field( + default=0, + metadata={ + "help_string": "temporal order of movement", + "argstr": "--mporder", + }, + ) + + s2v_num_iterations: int = attrs.field( + metadata={ + "help_string": "number of iterations for s2v movement estimation", + "argstr": "--s2v_niter", + } + ) + + s2v_lambda: float = attrs.field( + metadata={ + "help_string": "weighting of regularization for s2v movement estimation", + "argstr": "--s2v_lambda", + } + ) + + s2v_interpolation: str = attrs.field( + metadata={ + "help_string": "interpolation method for s2v movement estimation.", + "argstr": "--s2v_interp", + } + ) + + slice_grouping_file: os.PathLike = attrs.field( + metadata={ + "help_string": "file containing slice grouping information", + "argstr": "--slspec", + "xor": {"slice_timing_file"}, + } + ) + + slice_timing_file: os.PathLike = attrs.field( + metadata={ + "help_string": "file containing slice timing information", + "argstr": "--json", + "xor": {"slice_grouping_file"}, + } + ) + + # Parameters for move-by-susceptibility correction (mbs) + estimate_move_by_susceptibility: bool = attrs.field( + metadata={ + "help_string": "estimate susceptibility-induced field changes due to subject motion", + "argstr": "--estimate_move_by_susceptibility", + } + ) + + mbs_num_iterations: int = attrs.field( + metadata={ + "help_string": "number of iterations for MBS field estimation", + "argstr": "--mbs_niter", + "requires": {"estimate_move_by_susceptibility"}, + } + ) + + mbs_lambda: int = attrs.field( + metadata={ + "help_string": "weighting of regularization for MBS field estimation", + "argstr": "--mbs_lambda", + "requires": {"estimate_move_by_susceptibility"}, + } + ) + + mbs_knot_spacing: int = attrs.field( + metadata={ + "help_string": "knot-spacing for MBS field estimation", + "argstr": "--mbs_ksp", + "requires": {"estimate_move_by_susceptibility"}, + } + ) + + # Miscellaneous parameters. + data_is_shelled: bool = attrs.field( + metadata={ + "help_string": "bypass checks for data shelling", + "argstr": "--data_is_shelled", + } + ) + + +class Eddy(pydra.engine.ShellCommandTask): + """Task definition for eddy.""" + + input_spec = pydra.specs.SpecInfo(name="EddyInput", bases=(EddySpec,)) + + executable = "eddy" From 2bfb1fb0831d6538e9f0e0f24fac49c9ad2f845c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:16 +1100 Subject: [PATCH 045/224] ENH: Remove deprecated options --- pydra/tasks/fsl/eddy.py | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 80b32c7..88ef58e 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -211,22 +211,6 @@ class EddySpec(pydra.specs.ShellSpec): } ) - ol_pos: bool = attrs.field( - metadata={ - "help_string": "consider both positive and negative outliers", - "argstr": "--ol_pos", - "requires": {"replace_outliers"}, - } - ) - - ol_sqr: bool = attrs.field( - metadata={ - "help_string": "consider outliers among sum-of-square differences", - "argstr": "--ol_sqr", - "requires": {"replace_outliers"}, - } - ) - multiband_factor: int = attrs.field( metadata={ "help_string": "multiband factor", From 816d49d5657911e9a2f3438f6dd1ef7bfd75b6da Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:16 +1100 Subject: [PATCH 046/224] ENH: Add option to disable peas --- pydra/tasks/fsl/eddy.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 88ef58e..9c4826c 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -95,6 +95,13 @@ class EddySpec(pydra.specs.ShellSpec): } ) + no_peas: bool = attrs.field( + metadata={ + "help_string": "do not perform post-Eddy alignment of shells", + "argstr": "--dont_peas", + } + ) + # Parameters specifying names of output-files. output_basename: str = attrs.field( default="eddy", From 363e831a6e16d1fc583ca315a98c04f746fd3923 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:16 +1100 Subject: [PATCH 047/224] ENH: Add option for random seed --- pydra/tasks/fsl/eddy.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 9c4826c..1b6584f 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -237,7 +237,7 @@ class EddySpec(pydra.specs.ShellSpec): temporal_order: int = attrs.field( default=0, metadata={ - "help_string": "temporal order of movement", + "help_string": "order of movement model", "argstr": "--mporder", }, ) @@ -319,6 +319,13 @@ class EddySpec(pydra.specs.ShellSpec): } ) + random_seed: int = attrs.field( + metadata={ + "help_string": "random seed for voxel selection", + "argstr": "--initrand", + } + ) + class Eddy(pydra.engine.ShellCommandTask): """Task definition for eddy.""" From 85bea4f62998c8c8e54a9022be8607ab11dcea99 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:16 +1100 Subject: [PATCH 048/224] ENH: Add default value to FWHM option --- pydra/tasks/fsl/eddy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 1b6584f..cfcc334 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -131,6 +131,7 @@ class EddySpec(pydra.specs.ShellSpec): ) fwhm: float = attrs.field( + default=0, metadata={ "help_string": ( "filter width used for pre-conditionning data prior to estimating distortions" From 218fd61e5931c84cd9cee95af740a584e4c35cd3 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:16 +1100 Subject: [PATCH 049/224] FIX: Add missing enum value for FLM --- pydra/tasks/fsl/eddy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index cfcc334..c5695a9 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -117,7 +117,7 @@ class EddySpec(pydra.specs.ShellSpec): metadata={ "help_string": "model for the magnetic field generated by Eddy currents", "argstr": "--flm", - "allowed_values": {"linear", "quadratic", "cubic"}, + "allowed_values": {"movement", "linear", "quadratic", "cubic"}, }, ) @@ -137,7 +137,7 @@ class EddySpec(pydra.specs.ShellSpec): "filter width used for pre-conditionning data prior to estimating distortions" ), "argstr": "--fwhm", - } + }, ) num_iterations: int = attrs.field( From 2e25c1f7f468d2a504cfe8a1704d924675398e4c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 050/224] FIX: Rename mporder option --- pydra/tasks/fsl/eddy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index c5695a9..dbe0701 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -235,10 +235,10 @@ class EddySpec(pydra.specs.ShellSpec): ) # Parameters for intra-volume movement correction (s2v) - temporal_order: int = attrs.field( + movement_prediction_order: int = attrs.field( default=0, metadata={ - "help_string": "order of movement model", + "help_string": "order of movement prediction model", "argstr": "--mporder", }, ) From 0f8dcde284304704d74d877ed98524ecf5c7ea9d Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 051/224] ENH: Add write options --- pydra/tasks/fsl/eddy.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index dbe0701..286a941 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -327,6 +327,20 @@ class EddySpec(pydra.specs.ShellSpec): } ) + write_cnr_maps: bool = attrs.field( + metadata={ + "help_string": "write shell-wise CNR maps", + "argstr": "--cnr_maps", + } + ) + + write_residuals: bool = attrs.field( + metadata={ + "help_string": "write residuals for all scans", + "argstr": "--residuals", + } + ) + class Eddy(pydra.engine.ShellCommandTask): """Task definition for eddy.""" From ee580e177a1aaf72af59dba8c18889fceffa80e2 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 052/224] ENH: Define output spec for eddy --- pydra/tasks/fsl/eddy.py | 80 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 286a941..a44defb 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -342,9 +342,89 @@ class EddySpec(pydra.specs.ShellSpec): ) +class EddyOutSpec(pydra.specs.ShellOutSpec): + """Output specification for eddy.""" + + corrected_image: str = attrs.field( + metadata={ + "help_string": "input image corrected for distortions", + "output_file_template": "{output_basename}.nii.gz", + } + ) + + parameter_file: str = attrs.field( + metadata={ + "help_string": "registration parameters for movement and EC", + "output_file_template": "{output_basename}.eddy_parameters", + } + ) + + rotated_bvec_file: str = attrs.field( + metadata={ + "help_string": "rotated b-vecs", + "output_file_template": "{output_basename}.eddy_rotated_bvecs", + } + ) + + movement_rms_matrix: str = attrs.field( + metadata={ + "help_string": "movement induced RMS", + "output_file_template": "{output_basename}.eddy_movement_rms", + } + ) + + restricted_movement_rms_matrix: str = attrs.field( + metadata={ + "help_string": "movement induced RMS without translation in the PE direction", + "output_file_template": "{output_basename}.eddy_restricted_movement_rms", + } + ) + + displacement_fields_image: str = attrs.field( + metadata={ + "help_string": "displacement fields in millimeters", + "output_file_template": "{output_basename}.eddy_displacement_fields", + } + ) + + outlier_free_image: str = attrs.field( + metadata={ + "help_string": "input image with outliers replaced by predictions", + "output_file_template": "{output_basename}.eddy_outlier_free_data", + "requires": {"replace_outliers"}, + } + ) + + movement_over_time_file: str = attrs.field( + metadata={ + "help_string": "movement parameters per time-point (slice or group)", + "output_file_template": "{output_basename}.eddy_movement_over_time", + "requires": {"movement_prediction_order"}, + } + ) + + cnr_maps_image: str = attrs.field( + metadata={ + "help_string": "path to optional CNR maps image", + "output_file_template": "{output_basename}.eddy_cnr_maps", + "requires": {"write_cnr_maps"}, + } + ) + + residuals_image: str = attrs.field( + metadata={ + "help_string": "path to optional residuals image", + "output_file_template": "{output_basename}.eddy_residuals", + "requires": {"write_residuals"}, + } + ) + + class Eddy(pydra.engine.ShellCommandTask): """Task definition for eddy.""" input_spec = pydra.specs.SpecInfo(name="EddyInput", bases=(EddySpec,)) + output_spec = pydra.specs.SpecInfo(name="EddyOutput", bases=(EddyOutSpec,)) + executable = "eddy" From 2c9b429d93499845a42ced5f5e9a08c22f481b4b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 053/224] REF: ol -> outlier --- pydra/tasks/fsl/eddy.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index a44defb..448ddcf 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -194,7 +194,7 @@ class EddySpec(pydra.specs.ShellSpec): metadata={"help_string": "replace outliers", "argstr": "--repol"} ) - ol_num_std: int = attrs.field( + outlier_num_std: int = attrs.field( metadata={ "help_string": "number of std off to qualify as outlier", "argstr": "--ol_nstd", @@ -202,7 +202,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - ol_num_voxels: int = attrs.field( + outlier_num_voxels: int = attrs.field( metadata={ "help_string": "minimum number of voxels in a slice to qualify for outlier detection", "argstr": "--ol_nvox", @@ -210,7 +210,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - ol_type: str = attrs.field( + outlier_type: str = attrs.field( metadata={ "help_string": "type of outliers detected", "argstr": "--ol_type", From 40ebae48d6c886b4eb338e404d009b750dbc1f65 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 054/224] ENH: Add allowed values for slice-to-volume interpolation --- pydra/tasks/fsl/eddy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 448ddcf..322c5b5 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -261,6 +261,7 @@ class EddySpec(pydra.specs.ShellSpec): metadata={ "help_string": "interpolation method for s2v movement estimation.", "argstr": "--s2v_interp", + "allowed_values": {"spline", "trilinear"}, } ) From f4749317fcfa18b46820d6164aeaf1c2dea999b8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 055/224] REF: acqp -> acquisition_parameters --- pydra/tasks/fsl/eddy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 322c5b5..8ff2c83 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -37,7 +37,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - acqp_file: os.PathLike = attrs.field( + acquisition_parameters_file: os.PathLike = attrs.field( metadata={ "help_string": "acquisition parameters for the diffusion protocol", "mandatory": True, From 953cd071517e077568355e9218e268c39cdf1cab Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 056/224] REF: fmap -> fieldmap --- pydra/tasks/fsl/eddy.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 8ff2c83..6effdf9 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -74,11 +74,11 @@ class EddySpec(pydra.specs.ShellSpec): "help_string": "topup output file", "mandatory": True, "argstr": "--topup", - "xor": {"fmap_file"}, + "xor": {"fieldmap_image"}, } ) - fmap_file: os.PathLike = attrs.field( + fieldmap_image: os.PathLike = attrs.field( metadata={ "help_string": "fieldmap file", "mandatory": True, @@ -87,11 +87,11 @@ class EddySpec(pydra.specs.ShellSpec): } ) - fmap_matrix: os.PathLike = attrs.field( + fieldmap_matrix: os.PathLike = attrs.field( metadata={ "help_string": "rigid-body transformation matrix from fieldmap to first input volume", "argstr": "--field_mat", - "requires": {"fmap_file"}, + "requires": {"fieldmap_image"}, } ) From 83f167a0126e90d57440a1f5fd8ca5ac340e8997 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:17 +1100 Subject: [PATCH 057/224] REF: std -> stdevs --- pydra/tasks/fsl/eddy.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 6effdf9..d2ca89a 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -194,9 +194,9 @@ class EddySpec(pydra.specs.ShellSpec): metadata={"help_string": "replace outliers", "argstr": "--repol"} ) - outlier_num_std: int = attrs.field( + outlier_num_stdevs: int = attrs.field( metadata={ - "help_string": "number of std off to qualify as outlier", + "help_string": "number of times off the standard deviation to qualify as outlier", "argstr": "--ol_nstd", "requires": {"replace_outliers"}, } From 01e6d4c1e832300e65b8f01b67e3a2682c7f2be1 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:31 +1100 Subject: [PATCH 058/224] NEW: Add task definition for convert_xfm --- pydra/tasks/fsl/convert_xfm.py | 71 ++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 pydra/tasks/fsl/convert_xfm.py diff --git a/pydra/tasks/fsl/convert_xfm.py b/pydra/tasks/fsl/convert_xfm.py new file mode 100644 index 0000000..d47fd47 --- /dev/null +++ b/pydra/tasks/fsl/convert_xfm.py @@ -0,0 +1,71 @@ +""" +ConvertXFM +========== + +Examples +-------- + +>>> task = ConvertXFM(input_matrix="input.mat", inverse=True) +>>> task.cmdline # doctest: +ELLIPSIS +'convert_xfm -omat ...input_cxfm.mat -inverse input.mat' + +>>> task = ConvertXFM( +... input_matrix="AtoB.mat", +... concat_matrix="BtoC.mat", +... output_matrix="AtoC.mat", +... ) +>>> task.cmdline +'convert_xfm -omat AtoC.mat -concat BtoC.mat AtoB.mat' +""" +import os + +import attrs + +import pydra + +__all__ = ["ConvertXFM"] + + +@attrs.define(slots=False, kw_only=True) +class ConvertXFMSpec(pydra.specs.ShellSpec): + """Specifications for convert_xfm.""" + + input_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "input matrix in 4x4 ASCII format", + "mandatory": True, + "argstr": "", + "position": -1, + } + ) + + output_matrix: str = attrs.field( + metadata={ + "help_string": "output matrix in 4x4 ASCII format", + "argstr": "-omat", + "output_file_template": "{input_matrix}_cxfm", + "requires": {"input_matrix"}, + } + ) + + concat_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "concatenate this matrix with input matrix", + "argstr": "-concat", + } + ) + + inverse: bool = attrs.field( + metadata={ + "help_string": "return inverse of computed matrix", + "argstr": "-inverse", + } + ) + + +class ConvertXFM(pydra.engine.ShellCommandTask): + """Task definition for convert_xfm.""" + + input_spec = pydra.specs.SpecInfo(name="ConvertXFMInput", bases=(ConvertXFMSpec,)) + + executable = "convert_xfm" From 8a97a4acb35c83300cc6322d6dff73840549a87e Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:46 +1100 Subject: [PATCH 059/224] NEW: Add task definition for fslroi --- pydra/tasks/fsl/fslroi.py | 132 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 pydra/tasks/fsl/fslroi.py diff --git a/pydra/tasks/fsl/fslroi.py b/pydra/tasks/fsl/fslroi.py new file mode 100644 index 0000000..f1fa837 --- /dev/null +++ b/pydra/tasks/fsl/fslroi.py @@ -0,0 +1,132 @@ +""" +FSLROI +====== + +Manual cropping to a region-of-interest (ROI) for structural brain images. + +Examples +-------- + +Extract a 16-voxel cube starting at position (10, 20, 30): +>>> task = FSLROI( +... input_image="image.nii", +... min_x=10, +... min_y=20, +... min_z=30, +... size_x=16, +... size_y=16, +... size_z=16, +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fslroi image.nii ...image_roi.nii 10 16 20 16 30 16' + +Extract a temporal window starting at 5 onwards: +>>> task = FSLROI( +... input_image="input.nii", +... output_image="output.nii", +... min_t=5, +... size_t=-1, +... ) +>>> task.cmdline +'fslroi input.nii output.nii 5 -1' +""" +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLROISpec(pydra.specs.ShellSpec): + """Specifications for fslroi.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image}_roi", + } + ) + + min_x: int = attrs.field( + metadata={ + "help_string": "start of ROI in x-dimension (0-based indexing)", + "argstr": "", + } + ) + + size_x: int = attrs.field( + # default=-1, + metadata={ + "help_string": "size of ROI in x-dimension (-1 for maximum)", + "argstr": "", + "requires": {"min_x"}, + } + ) + + min_y: int = attrs.field( + metadata={ + "help_string": "start of ROI in y-dimension (0-based indexing)", + "argstr": "", + "requires": {"min_x"}, + } + ) + + size_y: int = attrs.field( + # default=-1, + metadata={ + "help_string": "size of ROI in y-dimension (-1 for maximum)", + "argstr": "", + "requires": {"min_y"}, + } + ) + + min_z: int = attrs.field( + metadata={ + "help_string": "start of ROI in z-dimension (0-based indexing)", + "argstr": "", + "requires": {"min_x"}, + } + ) + + size_z: int = attrs.field( + # default=-1, + metadata={ + "help_string": "size of ROI in z-dimension (-1 for maximum)", + "argstr": "", + "requires": {"min_z"}, + } + ) + + min_t: int = attrs.field( + metadata={ + "help_string": "start of ROI in t-dimension (0-based indexing)", + "argstr": "", + } + ) + + size_t: int = attrs.field( + # default=-1, + metadata={ + "help_string": "size of ROI in t-dimension (-1 for maximum)", + "argstr": "", + "requires": {"min_t"}, + }, + ) + + +class FSLROI(pydra.engine.ShellCommandTask): + """Task definition for fslroi.""" + + input_spec = pydra.engine.specs.SpecInfo(name="FSLROIInput", bases=(FSLROISpec,)) + + executable = "fslroi" From a215ea438bcc58bf6161ed8015afa5afb8b32bb3 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:46 +1100 Subject: [PATCH 060/224] MNT: Restrict linting to pydra folder --- hatch.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/hatch.toml b/hatch.toml index 598c213..b780bdf 100644 --- a/hatch.toml +++ b/hatch.toml @@ -23,10 +23,10 @@ dependencies = [ ] [envs.lint.scripts] all = [ - "black --check --diff {args:.}", - "isort --check --diff {args:.}", + "black --check --diff {args:pydra}", + "isort --check --diff {args:pydra}", ] fix = [ - "black --quiet {args:.}", - "isort --quiet {args:.}", + "black --quiet {args:pydra}", + "isort --quiet {args:pydra}", ] From 38d81367f3b42885a53d0da44e5b87257f4e2db8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:22:59 +1100 Subject: [PATCH 061/224] NEW: Add task definition for robustfov --- pydra/tasks/fsl/robustfov.py | 65 ++++++++++++++++++++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 pydra/tasks/fsl/robustfov.py diff --git a/pydra/tasks/fsl/robustfov.py b/pydra/tasks/fsl/robustfov.py new file mode 100644 index 0000000..200e98d --- /dev/null +++ b/pydra/tasks/fsl/robustfov.py @@ -0,0 +1,65 @@ +""" +RobustFOV +========= + +Automatic FOV reduction to remove the neck and lower part of the head +from structural brain images. + +Examples +-------- + +>>> task = RobustFOV(input_image="image.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'robustfov -i image.nii -r ...image_rfov.nii -b 170 -m ...image_rfov.mat' +""" +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class RobustFOVSpec(pydra.specs.ShellSpec): + """Specifications for robustfov.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "-i", + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image with reduced FOV", + "argstr": "-r", + "output_file_template": "{input_image}_rfov", + } + ) + + brain_size: int = attrs.field( + default=170, + metadata={ + "help_string": "size of the brain in z-axis", + "argstr": "-b", + }, + ) + + output_matrix: str = attrs.field( + metadata={ + "help_string": "output transformation matrix", + "argstr": "-m", + "output_file_template": "{input_image}_rfov.mat", + "keep_extension": False, + } + ) + + +class RobustFOV(pydra.engine.ShellCommandTask): + """Task definition for robustfov.""" + + input_spec = pydra.specs.SpecInfo(name="RobustFOVInput", bases=(RobustFOVSpec,)) + + executable = "robustfov" From bebe20a0b3a9b113e7b9873856bcbe451f8af74b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:21 +1100 Subject: [PATCH 062/224] NEW: Add task definition for fslreorient2std --- pydra/tasks/fsl/fslreorient2std.py | 63 ++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) create mode 100644 pydra/tasks/fsl/fslreorient2std.py diff --git a/pydra/tasks/fsl/fslreorient2std.py b/pydra/tasks/fsl/fslreorient2std.py new file mode 100644 index 0000000..617b161 --- /dev/null +++ b/pydra/tasks/fsl/fslreorient2std.py @@ -0,0 +1,63 @@ +""" +fslreorient2std +=============== + +Change orientation of the image to match the one used +for standard template images (MNI152). + +Examples +-------- + +>>> task = FSLReorient2Std(input_image="image.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'fslreorient2std -m ...image_r2std.mat image.nii ...image_r2std.nii' +""" +import os + +import attrs + +import pydra + +__all__ = ["FSLReorient2Std"] + + +@attrs.define(slots=False, kw_only=True) +class FSLReorient2StdSpec(pydra.specs.ShellSpec): + """Specificiations for fslreorient2std.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + "position": -2, + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output reoriented image", + "argstr": "", + "position": -1, + "output_file_template": "{input_image}_r2std", + } + ) + + output_matrix: str = attrs.field( + metadata={ + "help_string": "output transformation matrix", + "argstr": "-m", + "output_file_template": "{input_image}_r2std.mat", + "keep_extension": False, + } + ) + + +class FSLReorient2Std(pydra.engine.ShellCommandTask): + """Task definition for fslreorient2std.""" + + input_spec = pydra.specs.SpecInfo( + name="FSLReorient2StdInput", bases=(FSLReorient2StdSpec,) + ) + + executable = "fslreorient2std" From bf7a504bbb0c64e2311caf7fa29aec6739a1d006 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:21 +1100 Subject: [PATCH 063/224] ENH: Add output specifications for BET --- pydra/tasks/fsl/bet.py | 57 +++++++++++++++++++++++++++++++++--------- 1 file changed, 45 insertions(+), 12 deletions(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 9e81a80..83f1157 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -36,22 +36,22 @@ class BETSpec: } ) - generate_brain_surface_outline: bool = attrs.field( - metadata={"help_string": "generate brain surface outline", "argstr": "-o"} + save_brain_surface_outline: bool = attrs.field( + metadata={"help_string": "save brain surface outline", "argstr": "-o"} ) - generate_brain_mask: bool = attrs.field( - metadata={"help_string": "generate binary brain mask", "argstr": "-m"} + save_brain_mask: bool = attrs.field( + metadata={"help_string": "save binary brain mask", "argstr": "-m"} ) - generate_skull_image: bool = attrs.field( - metadata={"help_string": "generate approximate skull image", "argstr": "-s"} + save_skull_image: bool = attrs.field( + metadata={"help_string": "save approximate skull image", "argstr": "-s"} ) - no_segmented_brain_image: bool = attrs.field( + save_brain_surface_mesh: bool = attrs.field( metadata={ - "help_string": "do not generate the segmented brain image", - "argstr": "-n", + "help_string": "save brain surface as mesh in .vtk format", + "argstr": "-e", } ) @@ -101,10 +101,41 @@ class BETSpec: } ) - generate_brain_surface_mesh: bool = attrs.field( + +@attrs.define(slots=False, kw_only=True) +class BETOutSpec(pydra.specs.ShellOutSpec): + """Output specifications for BET.""" + + brain_surface_outline: str = attrs.field( metadata={ - "help_string": "generate brain surface as mesh in .vtk format", - "argstr": "-e", + "help_string": "brain surface outline", + "output_file_template": "{output_image}_overlay", + "requires": {"save_brain_surface_outline"}, + } + ) + + brain_mask: str = attrs.field( + metadata={ + "help_string": "brain mask", + "output_file_template": "{output_image}_mask", + "requires": {"save_brain_mask"}, + } + ) + + skull_image: str = attrs.field( + metadata={ + "help_string": "skull image", + "output_file_template": "{output_image}_skull", + "requires": {"save_skull_image"}, + } + ) + + brain_surface_mesh: str = attrs.field( + metadata={ + "help_string": "brain surface mesh", + "output_file_template": "{output_image}_mesh.vtk", + "keep_extension": False, + "requires": {"save_brain_surface_mesh"}, } ) @@ -114,4 +145,6 @@ class BET: input_spec = pydra.specs.SpecInfo(name="BETInput", bases=(BETSpec,)) + output_spec = pydra.specs.SpecInfo(name="BETOutput", bases=(BETOutSpec,)) + executable = "bet" From e2d5819a9a217985421425c0f06567691afec467 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:34 +1100 Subject: [PATCH 064/224] DOC: List available interfaces --- README.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/README.md b/README.md index c35e630..42f73ca 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,21 @@ construction, manipulation, and distributed execution. [FSL][fsl] is a comprehensive library of analysis tools for FMRI, MRI and DTI brain imaging data. +## Available interfaces + +- bet + - bet + - robustfov +- flirt + - convert_xfm + - flirt +- fnirt + - fnirt +- utils + - fslmerge + - fslreorient2std + - fslroi + ## Installation ```console @@ -45,9 +60,15 @@ hatch run lint:fix `pydra-tasks-fsl` is distributed under the terms of the [Apache License 2.0][license] license. [pypi-project]: https://pypi.org/project/pydra-tasks-fsl + [pypi-version]: https://img.shields.io/pypi/v/pydra-tasks-fsl.svg + [pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-tasks-fsl.svg + [pydra]: https://pydra.readthedocs.io/ + [fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL + [hatch]: https://hatch.pypa.io/ + [license]: https://spdx.org/licenses/Apache-2.0.html From 295afb8240e84d1019c7d67292d71c4dca33c528 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:34 +1100 Subject: [PATCH 065/224] DOC: Add table of contents --- README.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/README.md b/README.md index 42f73ca..6936343 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,13 @@ construction, manipulation, and distributed execution. [FSL][fsl] is a comprehensive library of analysis tools for FMRI, MRI and DTI brain imaging data. +**Table of contents** + +- [Available interfaces](#available-interfaces) +- [Installation](#installation) +- [Development](#development) +- [License](#license) + ## Available interfaces - bet From ffa1f2682a8c47521ed3a70a9744dcb07bf44bfd Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:35 +1100 Subject: [PATCH 066/224] DOC: Adjust license section --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6936343..a2fd111 100644 --- a/README.md +++ b/README.md @@ -64,7 +64,7 @@ hatch run lint:fix ## License -`pydra-tasks-fsl` is distributed under the terms of the [Apache License 2.0][license] license. +`pydra-tasks-fsl` is distributed under the terms of the [Apache License, Version 2.0][license]. [pypi-project]: https://pypi.org/project/pydra-tasks-fsl From 179caca2f3544c5f8de0faeaef8b158a47b91beb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:35 +1100 Subject: [PATCH 067/224] DOC: Add reference to FSL installation and licensing --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index a2fd111..bfe3e2f 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,10 @@ for FMRI, MRI and DTI brain imaging data. pip install pydra-tasks-fsl ``` +A separate installation of FSL is required to use this package. +Please review the FSL [installation instructions][fsl-install] +and [licensing details][fsl-license]. + ## Development This project is managed with [Hatch][hatch]: @@ -76,6 +80,10 @@ hatch run lint:fix [fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL +[fsl-install]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FslInstallation + +[fsl-license]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Licence + [hatch]: https://hatch.pypa.io/ [license]: https://spdx.org/licenses/Apache-2.0.html From 2963422ac2cec0f4b073ddeadb1d706504c66368 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:35 +1100 Subject: [PATCH 068/224] ENH: Set default output files for FLIRT --- pydra/tasks/fsl/flirt.py | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 36d5cf1..6fc11e5 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -25,12 +25,11 @@ >>> task = FLIRT( ... input_image="newvol", ... reference_image="refvol", -... output_image="outvol", ... input_matrix="invol2refvol.mat", ... apply_transformation=True, ... ) >>> task.cmdline -'flirt -in newvol -ref refvol -out outvol -init invol2refvol.mat -applyxfm' +'flirt -in newvol -ref refvol -out ...newvol_flirt -init invol2refvol.mat -omat ...newvol_flirt.mat -applyxfm' Perform a single slice registration: @@ -65,8 +64,12 @@ class FLIRTSpec(pydra.specs.ShellSpec): metadata={"help_string": "reference volume", "argstr": "-ref"} ) - output_image: os.PathLike = attrs.field( - metadata={"help_string": "output volume", "argstr": "-out"} + output_image: str = attrs.field( + metadata={ + "help_string": "output volume", + "argstr": "-out", + "output_file_template": "{input_image}_flirt", + } ) input_matrix: os.PathLike = attrs.field( @@ -76,10 +79,12 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) - output_matrix: os.PathLike = attrs.field( + output_matrix: str = attrs.field( metadata={ "help_string": "output transformation as 4x4 matrix", "argstr": "-omat", + "output_file_template": "{input_image}_flirt.mat", + "keep_extension": False, } ) From 6696a3543c95a072dd9946681bbbb24e70a0f1cd Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:23:35 +1100 Subject: [PATCH 069/224] FIX: Make dof and 2D registration parameters mutually exclusive --- pydra/tasks/fsl/flirt.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 6fc11e5..b625c9d 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -38,7 +38,7 @@ ... reference_image="refslice", ... output_image="outslice", ... output_matrix="i2r.mat", -... use_2d_rigid_body_transformation=True, +... use_2d_registration=True, ... ) >>> task.cmdline 'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -2D' @@ -90,9 +90,10 @@ class FLIRTSpec(pydra.specs.ShellSpec): degrees_of_freedom: int = attrs.field( metadata={ - "help_string": "degrees of freedom (default: 12)", + "help_string": "degrees of freedom for the registration model", "argstr": "-dof", "allowed_values": {3, 6, 7, 9, 12}, + "xor": {"use_2d_registration"}, } ) @@ -104,10 +105,11 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) - use_2d_rigid_body_transformation: bool = attrs.field( + use_2d_registration: bool = attrs.field( metadata={ - "help_string": "use rigid body transformation in 2D (ignores DOF)", + "help_string": "use rigid-body registration model in 2D", "argstr": "-2D", + "xor": {"degrees_of_freedom"}, } ) From 9a589f6d8a71c3e69c67159b165a6a1fd8fcae04 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:18 +1100 Subject: [PATCH 070/224] ENH: Add verbose logging for FLIRT --- pydra/tasks/fsl/flirt.py | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index b625c9d..070947c 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -38,11 +38,13 @@ ... reference_image="refslice", ... output_image="outslice", ... output_matrix="i2r.mat", -... use_2d_registration=True, +... use_2d_rigid_body_transformation=True, +... verbose=True, ... ) >>> task.cmdline -'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -2D' +'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -2D -v' """ + import os import attrs @@ -113,6 +115,14 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) + verbose: bool = attrs.field( + default=False, + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + }, + ) + class FLIRT(pydra.engine.ShellCommandTask): """Task definition for FLIRT.""" From 63aac6034bc515f216e816a465d3de52038e7284 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:20 +1100 Subject: [PATCH 071/224] ENH: Add output_datatype parameter to FLIRT --- pydra/tasks/fsl/flirt.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 070947c..746b826 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -74,6 +74,20 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) + output_datatype: str = attrs.field( + metadata={ + "help_string": "output datatype", + "argstr": "-datatype", + "allowed_values": { + "char", + "short", + "int", + "float", + "double", + }, + } + ) + input_matrix: os.PathLike = attrs.field( metadata={ "help_string": "input transformation as 4x4 matrix", From e201421aa983f3a6fa7769d002e6efb6c79e77f9 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:34 +1100 Subject: [PATCH 072/224] ENH: Add cost function parameter to FLIRT --- pydra/tasks/fsl/flirt.py | 26 ++++++++++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 746b826..b072e5c 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -15,10 +15,11 @@ ... reference_image="refvol", ... output_image="outvol", ... output_matrix="invol2refvol.mat", +... cost_function="mutualinfo", ... degrees_of_freedom=6, ... ) >>> task.cmdline -'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -dof 6' +'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -cost mutualinfo -dof 6' Apply a saved transformation to another image: @@ -29,7 +30,7 @@ ... apply_transformation=True, ... ) >>> task.cmdline -'flirt -in newvol -ref refvol -out ...newvol_flirt -init invol2refvol.mat -omat ...newvol_flirt.mat -applyxfm' +'flirt -in newvol -ref refvol -out outvol -init invol2refvol.mat -cost corratio -applyxfm' Perform a single slice registration: @@ -42,7 +43,11 @@ ... verbose=True, ... ) >>> task.cmdline +<<<<<<< HEAD 'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -2D -v' +======= +'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -cost corratio -2D' +>>>>>>> 319197b (ENH: Add cost function parameter to FLIRT) """ import os @@ -104,6 +109,23 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) + cost_function: str = attrs.field( + default="corratio", + metadata={ + "help_string": "cost function", + "argstr": "-cost", + "allowed_values": { + "mutualinfo", + "corratio", + "normcorr", + "normmi", + "leastsq", + "labeldiff", + "bbr", + }, + }, + ) + degrees_of_freedom: int = attrs.field( metadata={ "help_string": "degrees of freedom for the registration model", From f4afad7f82198b1fa5b91c42f37b20f559bfe9d1 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:51 +1100 Subject: [PATCH 073/224] NEW: Add task definition for FAST --- pydra/tasks/fsl/__init__.py | 49 ++++----- pydra/tasks/fsl/fast.py | 202 ++++++++++++++++++++++++++++++++++++ 2 files changed, 222 insertions(+), 29 deletions(-) create mode 100644 pydra/tasks/fsl/fast.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index dc03b8a..c8884de 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -6,33 +6,24 @@ >>> import pydra.tasks.fsl """ -from warnings import warn -from pathlib import Path +from .bet import BET +from .convert_xfm import ConvertXFM +from .fast import FAST +from .flirt import FLIRT +from .fnirt import FNIRT +from .fslmerge import FSLMerge +from .fslreorient2std import FSLReorient2Std +from .fslroi import FSLROI +from .robustfov import RobustFOV -pkg_path = Path(__file__).parent.parent - -try: - from ._version import __version__ -except ImportError: - raise RuntimeError( - "pydra-fsl has not been properly installed, please run " - f"`pip install -e {str(pkg_path)}` to install a development version" - ) -if "nipype" not in __version__: - try: - from .auto._version import nipype_version, nipype2pydra_version - except ImportError: - warn( - "Nipype interfaces haven't been automatically converted from their specs in " - f"`nipype-auto-conv`. Please run `{str(pkg_path / 'nipype-auto-conv' / 'generate')}` " - "to generated the converted Nipype interfaces in pydra.tasks.fsl.auto" - ) - else: - n_ver = nipype_version.replace(".", "_") - n2p_ver = nipype2pydra_version.replace(".", "_") - __version__ += ( - "_" if "+" in __version__ else "+" - ) + f"nipype{n_ver}_nipype2pydra{n2p_ver}" - - -__all__ = ["__version__"] +__all__ = [ + "BET", + "ConvertXFM", + "FAST", + "FLIRT", + "FNIRT", + "FSLMerge", + "FSLReorient2Std", + "FSLROI", + "RobustFOV", +] diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py new file mode 100644 index 0000000..66393eb --- /dev/null +++ b/pydra/tasks/fsl/fast.py @@ -0,0 +1,202 @@ +""" +FAST +==== +""" +import os +import typing as ty + +import attrs + +import pydra + +__all__ = ["FAST"] + + +@attrs.define(slots=False, kw_only=True) +class FASTSpec(pydra.specs.ShellSpec): + """Specifications for FAST.""" + + # Input parameters. + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image (single-channel mode)", + "mandatory": True, + "argstr": "", + "position": -1, + } + ) + + image_type: int = attrs.field( + default=1, + metadata={ + "help_string": "type of input image(s) (1: T1, 2: T2, 3: PD)", + "argstr": "-t", + "allowed_values": {1, 2, 3}, + }, + ) + + # Output parameters. + output_basename: str = attrs.field( + default="fast", + metadata={ + "help_string": "basename used for output files", + "argstr": "-o", + }, + ) + + num_classes: int = attrs.field( + default=3, + metadata={ + "help_string": "number of tissue-type classes", + "argstr": "-n", + }, + ) + + save_probability_maps: bool = attrs.field( + metadata={ + "help_string": "save probability map for each class", + "argstr": "-p", + } + ) + + save_bias_field_image: bool = attrs.field( + metadata={ + "help_string": "save estimated bias field", + "argstr": "-b", + } + ) + + save_bias_corrected_image: bool = attrs.field( + metadata={ + "help_string": "save restored image after bias field correction", + "argstr": "-B", + } + ) + + save_segmentation_masks: bool = attrs.field( + metadata={ + "help_string": "save segmentation mask for each class", + "argstr": "-g", + } + ) + + # Advanced parameters. + main_mrf_parameter: float = attrs.field( + default=0.1, + metadata={ + "help_string": "", + "argstr": "-H", + }, + ) + + bias_field_iterations: int = attrs.field( + default=4, + metadata={ + "help_string": "number of iterations for bias field removal", + "argstr": "-I", + }, + ) + + bias_field_smoothing: float = attrs.field( + default=20, + metadata={ + "help_string": "bias field smoothing (FWHM in millimeters)", + "argstr": "-l", + }, + ) + + no_partial_volume_estimation: bool = attrs.field( + metadata={ + "help_string": "do not perform partial volume estimation", + "argstr": "--nopve", + } + ) + + +class FASTOutSpec(pydra.specs.ShellOutSpec): + """Ouput specifications for FAST.""" + + @staticmethod + def get_segmentation_image(output_basename: str) -> str: + return f"{output_basename}_seg" + + @staticmethod + def get_segmentation_masks(output_basename: str, num_classes: int) -> ty.List[str]: + return [f"{output_basename}_seg_{i}" for i in range(num_classes)] + + @staticmethod + def get_probability_maps(output_basename: str, num_classes: int) -> ty.List[str]: + return [f"{output_basename}_prob_{i}" for i in range(num_classes)] + + @staticmethod + def get_partial_volume_maps(output_basename: str, num_classes: int) -> ty.List[str]: + return [f"{output_basename}_pve_{i}" for i in range(num_classes)] + + @staticmethod + def get_bias_field_image(output_basename: str) -> str: + return f"{output_basename}_bias" + + @staticmethod + def get_bias_corrected_image(output_basename: str) -> str: + return f"{output_basename}_restore" + + segmentation_image: str = attrs.field( + metadata={ + "help_string": "segmentation image with each voxel assigned a class", + "mandatory": True, + "callable": get_segmentation_image, + } + ) + + segmentation_masks: ty.List[str] = attrs.field( + metadata={ + "help_string": ( + "one segmentation mask per class, each voxel is assigned a value of " + "1 if belonging to the class 0 otherwise." + ), + "requires": {"save_segmentation_masks"}, + "callable": get_segmentation_masks, + } + ) + + probability_maps: ty.List[str] = attrs.field( + metadata={ + "help_string": "posterior probablity mapping for each class", + "requires": {"save_probability_maps"}, + "callable": get_probability_maps, + } + ) + + partial_volume_maps: ty.List[str] = attrs.field( + metadata={ + "help_string": "partial volume mapping for each class", + "requires": {("no_partial_volume_estimation", False)}, + "callable": get_partial_volume_maps, + } + ) + + bias_field_image: str = attrs.field( + metadata={ + "help_string": "estimated bias field", + "requires": {"save_bias_field_image"}, + "callable": get_bias_field_image, + } + ) + + bias_corrected_image: str = attrs.field( + metadata={ + "help_string": "restored input image after bias field correction", + "requires": {"save_bias_corrected_image"}, + "callable": get_bias_corrected_image, + } + ) + + +class FAST(pydra.engine.ShellCommandTask): + """Task definition for FAST.""" + + input_spec = pydra.specs.SpecInfo(name="FASTInput", bases=(FASTSpec,)) + + output_spec = pydra.specs.SpecInfo(name="FASTOuput", bases=(FASTOutSpec,)) + + executable = "fast" From 37a8bfc53f62ee4c3210e30a46d4531d7983d0dc Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:51 +1100 Subject: [PATCH 074/224] DOC: Add FAST to available interfaces --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index bfe3e2f..db8920f 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ for FMRI, MRI and DTI brain imaging data. - bet - bet - robustfov +- fast - flirt - convert_xfm - flirt From fd6b17a7d7fb706085452e03d1d18d62e2ab4ca2 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:51 +1100 Subject: [PATCH 075/224] DOC: Add Eddy to available interfaces --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index db8920f..59db780 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ for FMRI, MRI and DTI brain imaging data. - bet - bet - robustfov +- eddy - fast - flirt - convert_xfm From 58d7dd613b6d7e00e3d364dab3d2dd81cde2562b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:24:51 +1100 Subject: [PATCH 076/224] ENH: Add verbose parameter to main interfaces --- pydra/tasks/fsl/bet.py | 7 +++++++ pydra/tasks/fsl/eddy.py | 7 +++++++ pydra/tasks/fsl/fast.py | 7 +++++++ pydra/tasks/fsl/flirt.py | 3 +-- pydra/tasks/fsl/fnirt.py | 7 +++++++ 5 files changed, 29 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 83f1157..a758887 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -101,6 +101,13 @@ class BETSpec: } ) + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + } + ) + @attrs.define(slots=False, kw_only=True) class BETOutSpec(pydra.specs.ShellOutSpec): diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index d2ca89a..ca6e3ae 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -420,6 +420,13 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): } ) + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + } + ) + class Eddy(pydra.engine.ShellCommandTask): """Task definition for eddy.""" diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py index 66393eb..d7ecd55 100644 --- a/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/fast.py @@ -112,6 +112,13 @@ class FASTSpec(pydra.specs.ShellSpec): } ) + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + } + ) + class FASTOutSpec(pydra.specs.ShellOutSpec): """Ouput specifications for FAST.""" diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index b072e5c..2c0c868 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -152,11 +152,10 @@ class FLIRTSpec(pydra.specs.ShellSpec): ) verbose: bool = attrs.field( - default=False, metadata={ "help_string": "enable verbose logging", "argstr": "-v", - }, + } ) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index 157ae0b..92c7d18 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -37,6 +37,13 @@ class FNIRTSpec(pydra.specs.ShellSpec): metadata={"help_string": "input image", "argstr": "--in"} ) + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + } + ) + class FNIRT(pydra.engine.ShellCommandTask): """Task definition for FNIRT.""" From 9b4630e8198efdfae137813befda6fba660e0b82 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:25:25 +1100 Subject: [PATCH 077/224] MNT: Rename project to pydra-fsl --- README.md | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 59db780..32107fb 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# pydra-tasks-fsl +# pydra-fsl [![PyPI - Version][pypi-version]][pypi-project] [![PyPI - Python Version][pypi-pyversions]][pypi-project] diff --git a/pyproject.toml b/pyproject.toml index 3142085..ed310fb 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,7 @@ dependencies = [ "fileformats-medimage-fsl", ] license = { file = "LICENSE" } +keywords = ["pydra", "neuroimaging", "fsl"] authors = [ { name = "Nipype developers", email = "neuroimaging@python.org" }, { name = "Ghislain Vaillant", email = "ghislain.vaillant@icm-institute.org" }, @@ -23,7 +24,6 @@ maintainers = [ { name = "Nipype developers", email = "neuroimaging@python.org" }, { name = "Ghislain Vaillant", email = "ghislain.vaillant@icm-institute.org" }, ] -keywords = ["pydra"] classifiers = [ "Development Status :: 3 - Alpha", "Intended Audience :: Science/Research", From 4634ef5e915341d6ca1c387f37ef3cb5fbc0bd66 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:25:25 +1100 Subject: [PATCH 078/224] CI: Add publish workflow Publish package to PyPI on GitHub release. --- .github/workflows/publish.yaml | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 .github/workflows/publish.yaml diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml new file mode 100644 index 0000000..e355d3c --- /dev/null +++ b/.github/workflows/publish.yaml @@ -0,0 +1,27 @@ +name: publish + +on: + release: + types: [ published ] + +permissions: + contents: read + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +jobs: + publish: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: Build distribution + run: pipx run build + - name: Publish to PyPI + uses: pypa/gh-action-pypi-publish@release/v1 + with: + password: ${{ secrets.PYPI_API_TOKEN }} From 98c2e664655682154b941c0f9ecf6b2dff615042 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:25:50 +1100 Subject: [PATCH 079/224] DOC: Fix install command --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 32107fb..5435ad9 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ for FMRI, MRI and DTI brain imaging data. ## Installation ```console -pip install pydra-tasks-fsl +pip install pydra-fsl ``` A separate installation of FSL is required to use this package. From e972ea4d5ef684842ff3db6d394bcec5b8417f73 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:25:50 +1100 Subject: [PATCH 080/224] DOC: Fix badge URLs --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 5435ad9..3edaf1b 100644 --- a/README.md +++ b/README.md @@ -72,11 +72,11 @@ hatch run lint:fix `pydra-tasks-fsl` is distributed under the terms of the [Apache License, Version 2.0][license]. -[pypi-project]: https://pypi.org/project/pydra-tasks-fsl +[pypi-project]: https://pypi.org/project/pydra-fsl -[pypi-version]: https://img.shields.io/pypi/v/pydra-tasks-fsl.svg +[pypi-version]: https://img.shields.io/pypi/v/pydra-fsl.svg -[pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-tasks-fsl.svg +[pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-fsl.svg [pydra]: https://pydra.readthedocs.io/ From 353c9225419f4a1d482eb2c28906a7df13842035 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:26:16 +1100 Subject: [PATCH 081/224] DOC: Fix licensing paragraph --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3edaf1b..9c9d7e6 100644 --- a/README.md +++ b/README.md @@ -70,7 +70,7 @@ hatch run lint:fix ## License -`pydra-tasks-fsl` is distributed under the terms of the [Apache License, Version 2.0][license]. +`pydra-fsl` is distributed under the terms of the [Apache License, Version 2.0][license]. [pypi-project]: https://pypi.org/project/pydra-fsl From 505142feb9ec56d9c3d8e576e2d2da9ad1d8fdcb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:26:46 +1100 Subject: [PATCH 082/224] ENH: Add interpolation parameter for FLIRT --- pydra/tasks/fsl/flirt.py | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 2c0c868..92b9dcc 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -19,7 +19,8 @@ ... degrees_of_freedom=6, ... ) >>> task.cmdline -'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -cost mutualinfo -dof 6' +'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -cost mutualinfo \ +-interp trilinear -dof 6' Apply a saved transformation to another image: @@ -30,7 +31,8 @@ ... apply_transformation=True, ... ) >>> task.cmdline -'flirt -in newvol -ref refvol -out outvol -init invol2refvol.mat -cost corratio -applyxfm' +'flirt -in newvol -ref refvol -out ...newvol_flirt -init invol2refvol.mat \ +-omat ...newvol_flirt.mat -cost corratio -interp trilinear -applyxfm' Perform a single slice registration: @@ -39,6 +41,7 @@ ... reference_image="refslice", ... output_image="outslice", ... output_matrix="i2r.mat", +<<<<<<< HEAD ... use_2d_rigid_body_transformation=True, ... verbose=True, ... ) @@ -48,6 +51,15 @@ ======= 'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -cost corratio -2D' >>>>>>> 319197b (ENH: Add cost function parameter to FLIRT) +======= +... interpolation="nearestneighbour", +... use_2d_registration=True, +... verbose=True, +... ) +>>> task.cmdline +'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -cost corratio \ +-interp nearestneighbour -2D -v' +>>>>>>> 84ff031 (ENH: Add interpolation parameter for FLIRT) """ import os @@ -126,6 +138,20 @@ class FLIRTSpec(pydra.specs.ShellSpec): }, ) + interpolation: str = attrs.field( + default="trilinear", + metadata={ + "help_string": "interpolation method", + "argstr": "-interp", + "allowed_values": { + "trilinear", + "nearestneighbour", + "sinc", + "spline", + }, + }, + ) + degrees_of_freedom: int = attrs.field( metadata={ "help_string": "degrees of freedom for the registration model", From d325128c2fdbb8371655150fcff4b9556618dd98 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:26:48 +1100 Subject: [PATCH 083/224] DOC: Add badge for downloads --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 9c9d7e6..c702a5d 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,9 @@ [![PyPI - Version][pypi-version]][pypi-project] [![PyPI - Python Version][pypi-pyversions]][pypi-project] +[![PyPI - Downloads][pypi-downloads]][pypi-project] ------ +---- Pydra tasks for FSL. @@ -78,6 +79,8 @@ hatch run lint:fix [pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-fsl.svg +[pypi-downloads]: https://static.pepy.tech/badge/pydra-fsl + [pydra]: https://pydra.readthedocs.io/ [fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL From 5eba6a5e4e7193649400c45fb16ae81b090532b2 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:26:48 +1100 Subject: [PATCH 084/224] FIX: Make BET derive from ShellCommandTask --- pydra/tasks/fsl/bet.py | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index a758887..015c9a0 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -7,6 +7,8 @@ when provided with good quality T1 and T2 input images. """ +__all__ = ["BET"] + import os import typing as ty @@ -14,9 +16,8 @@ import pydra -__all__ = ["BET"] - +@attrs.define(slots=False, kw_only=True) class BETSpec: """Specifications for BET.""" @@ -147,11 +148,11 @@ class BETOutSpec(pydra.specs.ShellOutSpec): ) -class BET: +class BET(pydra.engine.ShellCommandTask): """Task definition for BET.""" + executable = "bet" + input_spec = pydra.specs.SpecInfo(name="BETInput", bases=(BETSpec,)) output_spec = pydra.specs.SpecInfo(name="BETOutput", bases=(BETOutSpec,)) - - executable = "bet" From 4639c07b3732733012b62d09e5dd7cbea3210463 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:28:33 +1100 Subject: [PATCH 085/224] REF: Normalize modules layout --- pydra/tasks/fsl/__init__.py | 21 +++++++++++---------- pydra/tasks/fsl/bet.py | 6 +++--- pydra/tasks/fsl/convert_xfm.py | 9 +++++---- pydra/tasks/fsl/eddy.py | 8 ++++---- pydra/tasks/fsl/fast.py | 16 ++++++++++------ pydra/tasks/fsl/flirt.py | 26 +++++++------------------- pydra/tasks/fsl/fnirt.py | 15 ++++++++------- pydra/tasks/fsl/fslmerge.py | 11 ++++------- pydra/tasks/fsl/fslreorient2std.py | 11 ++++++----- pydra/tasks/fsl/fslroi.py | 7 +++++-- pydra/tasks/fsl/robustfov.py | 7 +++++-- 11 files changed, 68 insertions(+), 69 deletions(-) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index c8884de..7cc461b 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -6,16 +6,6 @@ >>> import pydra.tasks.fsl """ -from .bet import BET -from .convert_xfm import ConvertXFM -from .fast import FAST -from .flirt import FLIRT -from .fnirt import FNIRT -from .fslmerge import FSLMerge -from .fslreorient2std import FSLReorient2Std -from .fslroi import FSLROI -from .robustfov import RobustFOV - __all__ = [ "BET", "ConvertXFM", @@ -27,3 +17,14 @@ "FSLROI", "RobustFOV", ] + +from .bet import BET +from .convert_xfm import ConvertXFM +from .eddy import Eddy +from .fast import FAST +from .flirt import FLIRT +from .fnirt import FNIRT +from .fslmerge import FSLMerge +from .fslreorient2std import FSLReorient2Std +from .fslroi import FSLROI +from .robustfov import RobustFOV diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 015c9a0..ee8a19c 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -1,8 +1,8 @@ """ -BET -=== +Brain Extraction Tool (BET) +=========================== -BET (Brain Extraction Tool) removes non-brain tissues from whole-head images. +BET removes non-brain tissues from whole-head images. It can also estimate the inner and outer skull surfaces, and outer scalp surface, when provided with good quality T1 and T2 input images. """ diff --git a/pydra/tasks/fsl/convert_xfm.py b/pydra/tasks/fsl/convert_xfm.py index d47fd47..8e5dcb6 100644 --- a/pydra/tasks/fsl/convert_xfm.py +++ b/pydra/tasks/fsl/convert_xfm.py @@ -17,14 +17,15 @@ >>> task.cmdline 'convert_xfm -omat AtoC.mat -concat BtoC.mat AtoB.mat' """ + +__all__ = ["ConvertXFM"] + import os import attrs import pydra -__all__ = ["ConvertXFM"] - @attrs.define(slots=False, kw_only=True) class ConvertXFMSpec(pydra.specs.ShellSpec): @@ -66,6 +67,6 @@ class ConvertXFMSpec(pydra.specs.ShellSpec): class ConvertXFM(pydra.engine.ShellCommandTask): """Task definition for convert_xfm.""" - input_spec = pydra.specs.SpecInfo(name="ConvertXFMInput", bases=(ConvertXFMSpec,)) - executable = "convert_xfm" + + input_spec = pydra.specs.SpecInfo(name="ConvertXFMInput", bases=(ConvertXFMSpec,)) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index ca6e3ae..55624d4 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -5,14 +5,14 @@ Correct for artifacts induced by Eddy currents and subject motion. """ +__all__ = ["Eddy"] + import os import attrs import pydra -__all__ = ["Eddy"] - @attrs.define(slots=False, kw_only=True) class EddySpec(pydra.specs.ShellSpec): @@ -431,8 +431,8 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): class Eddy(pydra.engine.ShellCommandTask): """Task definition for eddy.""" + executable = "eddy" + input_spec = pydra.specs.SpecInfo(name="EddyInput", bases=(EddySpec,)) output_spec = pydra.specs.SpecInfo(name="EddyOutput", bases=(EddyOutSpec,)) - - executable = "eddy" diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py index d7ecd55..215fc1b 100644 --- a/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/fast.py @@ -1,7 +1,13 @@ """ -FAST -==== +FMRIB's Automated Segmentation Tool (FAST) +========================================== + +FAST performs automtic segmentation of 3D images of the brain +using hidden Markov random field model and the expectation-maximization algorithm. """ + +__all__ = ["FAST"] + import os import typing as ty @@ -9,8 +15,6 @@ import pydra -__all__ = ["FAST"] - @attrs.define(slots=False, kw_only=True) class FASTSpec(pydra.specs.ShellSpec): @@ -202,8 +206,8 @@ def get_bias_corrected_image(output_basename: str) -> str: class FAST(pydra.engine.ShellCommandTask): """Task definition for FAST.""" + executable = "fast" + input_spec = pydra.specs.SpecInfo(name="FASTInput", bases=(FASTSpec,)) output_spec = pydra.specs.SpecInfo(name="FASTOuput", bases=(FASTOutSpec,)) - - executable = "fast" diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt.py index 92b9dcc..9846eb6 100644 --- a/pydra/tasks/fsl/flirt.py +++ b/pydra/tasks/fsl/flirt.py @@ -1,8 +1,8 @@ """ -FLIRT -===== +FMRIB's Linear Image Registration Tool (FLIRT) +============================================== -FLIRT (FMRIB's Linear Image Registration Tool) is a robust and accurate tool +FLIRT is a robust and accurate tool for affine registration of intra- and inter-modal brain images. Examples @@ -41,17 +41,6 @@ ... reference_image="refslice", ... output_image="outslice", ... output_matrix="i2r.mat", -<<<<<<< HEAD -... use_2d_rigid_body_transformation=True, -... verbose=True, -... ) ->>> task.cmdline -<<<<<<< HEAD -'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -2D -v' -======= -'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -cost corratio -2D' ->>>>>>> 319197b (ENH: Add cost function parameter to FLIRT) -======= ... interpolation="nearestneighbour", ... use_2d_registration=True, ... verbose=True, @@ -59,17 +48,16 @@ >>> task.cmdline 'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -cost corratio \ -interp nearestneighbour -2D -v' ->>>>>>> 84ff031 (ENH: Add interpolation parameter for FLIRT) """ +__all__ = ["FLIRT"] + import os import attrs import pydra -__all__ = ["FLIRT"] - @attrs.define(slots=False, kw_only=True) class FLIRTSpec(pydra.specs.ShellSpec): @@ -188,6 +176,6 @@ class FLIRTSpec(pydra.specs.ShellSpec): class FLIRT(pydra.engine.ShellCommandTask): """Task definition for FLIRT.""" - input_spec = pydra.specs.SpecInfo(name="FLIRTInput", bases=(FLIRTSpec,)) - executable = "flirt" + + input_spec = pydra.specs.SpecInfo(name="FLIRTInput", bases=(FLIRTSpec,)) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index 92c7d18..62559c3 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -1,8 +1,8 @@ """ -FNIRT -===== +FSL Non-linear Image Registration Tool (FNIRT) +============================================== -FNIRT (FSL Non-linear Image Registration Tool) performs non-linear registration of brain images. +FNIRT performs non-linear registration of brain images. Examples -------- @@ -16,14 +16,15 @@ >>> task.cmdline 'fnirt --ref template.nii --in input.nii' """ + +__all__ = ["FNIRT"] + import os import attrs import pydra -__all__ = ["FNIRT"] - @attrs.define(slots=False, kw_only=True) class FNIRTSpec(pydra.specs.ShellSpec): @@ -48,6 +49,6 @@ class FNIRTSpec(pydra.specs.ShellSpec): class FNIRT(pydra.engine.ShellCommandTask): """Task definition for FNIRT.""" - input_spec = pydra.specs.SpecInfo(name="FNIRTInput", bases=(FNIRTSpec,)) - executable = "fnirt" + + input_spec = pydra.specs.SpecInfo(name="FNIRTInput", bases=(FNIRTSpec,)) diff --git a/pydra/tasks/fsl/fslmerge.py b/pydra/tasks/fsl/fslmerge.py index 683242e..cf3ce4f 100644 --- a/pydra/tasks/fsl/fslmerge.py +++ b/pydra/tasks/fsl/fslmerge.py @@ -13,6 +13,8 @@ 'fslmerge -t ...merged vol1.nii vol2.nii' """ +__all__ = ["FSLMerge"] + import os import typing as ty @@ -20,8 +22,6 @@ import pydra -__all__ = ["FSLMerge"] - @attrs.define(slots=False, kw_only=True) class FSLMergeSpec(pydra.specs.ShellSpec): @@ -73,9 +73,6 @@ class FSLMergeSpec(pydra.specs.ShellSpec): class FSLMerge(pydra.engine.ShellCommandTask): """Task definition for fslmerge.""" - input_spec = pydra.specs.SpecInfo( - name="FSLMergeInput", - bases=(FSLMergeSpec,), - ) - executable = "fslmerge" + + input_spec = pydra.specs.SpecInfo(name="FSLMergeInput", bases=(FSLMergeSpec,)) diff --git a/pydra/tasks/fsl/fslreorient2std.py b/pydra/tasks/fsl/fslreorient2std.py index 617b161..c35a914 100644 --- a/pydra/tasks/fsl/fslreorient2std.py +++ b/pydra/tasks/fsl/fslreorient2std.py @@ -1,5 +1,5 @@ """ -fslreorient2std +FSLReorient2Std =============== Change orientation of the image to match the one used @@ -12,14 +12,15 @@ >>> task.cmdline # doctest: +ELLIPSIS 'fslreorient2std -m ...image_r2std.mat image.nii ...image_r2std.nii' """ + +__all__ = ["FSLReorient2Std"] + import os import attrs import pydra -__all__ = ["FSLReorient2Std"] - @attrs.define(slots=False, kw_only=True) class FSLReorient2StdSpec(pydra.specs.ShellSpec): @@ -56,8 +57,8 @@ class FSLReorient2StdSpec(pydra.specs.ShellSpec): class FSLReorient2Std(pydra.engine.ShellCommandTask): """Task definition for fslreorient2std.""" + executable = "fslreorient2std" + input_spec = pydra.specs.SpecInfo( name="FSLReorient2StdInput", bases=(FSLReorient2StdSpec,) ) - - executable = "fslreorient2std" diff --git a/pydra/tasks/fsl/fslroi.py b/pydra/tasks/fsl/fslroi.py index f1fa837..2989f04 100644 --- a/pydra/tasks/fsl/fslroi.py +++ b/pydra/tasks/fsl/fslroi.py @@ -30,6 +30,9 @@ >>> task.cmdline 'fslroi input.nii output.nii 5 -1' """ + +__all__ = ["FSLROI"] + import os import attrs @@ -127,6 +130,6 @@ class FSLROISpec(pydra.specs.ShellSpec): class FSLROI(pydra.engine.ShellCommandTask): """Task definition for fslroi.""" - input_spec = pydra.engine.specs.SpecInfo(name="FSLROIInput", bases=(FSLROISpec,)) - executable = "fslroi" + + input_spec = pydra.engine.specs.SpecInfo(name="FSLROIInput", bases=(FSLROISpec,)) diff --git a/pydra/tasks/fsl/robustfov.py b/pydra/tasks/fsl/robustfov.py index 200e98d..8dababc 100644 --- a/pydra/tasks/fsl/robustfov.py +++ b/pydra/tasks/fsl/robustfov.py @@ -12,6 +12,9 @@ >>> task.cmdline # doctest: +ELLIPSIS 'robustfov -i image.nii -r ...image_rfov.nii -b 170 -m ...image_rfov.mat' """ + +__all__ = ["RobustFOV"] + import os import attrs @@ -60,6 +63,6 @@ class RobustFOVSpec(pydra.specs.ShellSpec): class RobustFOV(pydra.engine.ShellCommandTask): """Task definition for robustfov.""" - input_spec = pydra.specs.SpecInfo(name="RobustFOVInput", bases=(RobustFOVSpec,)) - executable = "robustfov" + + input_spec = pydra.specs.SpecInfo(name="RobustFOVInput", bases=(RobustFOVSpec,)) From aec9c6d4fa4569b66e9079a329c712a584485011 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:28:52 +1100 Subject: [PATCH 086/224] ENH: Add templated output parameters --- pydra/tasks/fsl/fnirt.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index 62559c3..77bc8e6 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -38,6 +38,31 @@ class FNIRTSpec(pydra.specs.ShellSpec): metadata={"help_string": "input image", "argstr": "--in"} ) + output_field_coefficients_file: str = attrs.field( + metadata={ + "help_string": "output file containing the field coefficients", + "argstr": "--cout", + "output_file_template": "{input_image}_fnirt_coeff", + "keep_extension": False, + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "--iout", + "output_file_template": "{input_image}_fnirt", + } + ) + + output_field_image: str = attrs.field( + metadata={ + "help_string": "output deformation field", + "argstr": "--fout", + "output_file_template": "{input_image}_fnirt_field", + } + ) + verbose: bool = attrs.field( metadata={ "help_string": "enable verbose logging", From d0f3ba7ffb1b6eb14c8d9b124faaee7c20130cb7 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:28:53 +1100 Subject: [PATCH 087/224] ENH: Add mask for input and reference spaces --- pydra/tasks/fsl/fnirt.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index 77bc8e6..06130b6 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -63,6 +63,20 @@ class FNIRTSpec(pydra.specs.ShellSpec): } ) + reference_mask: os.PathLike = attrs.field( + metadata={ + "help_string": "mask in reference space", + "argstr": "--applyrefmask --refmask", + } + ) + + input_mask: os.PathLike = attrs.field( + metadata={ + "help_string": "mask in input image space", + "argstr": "--applyinmask --inmask", + } + ) + verbose: bool = attrs.field( metadata={ "help_string": "enable verbose logging", From 9812a09a31361f0cc653605532b13587da681f95 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:28:53 +1100 Subject: [PATCH 088/224] FIX: FNIRT doctest --- pydra/tasks/fsl/fnirt.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt.py index 06130b6..bbba5e7 100644 --- a/pydra/tasks/fsl/fnirt.py +++ b/pydra/tasks/fsl/fnirt.py @@ -13,8 +13,9 @@ ... reference_image="template.nii", ... input_image="input.nii", ... ) ->>> task.cmdline -'fnirt --ref template.nii --in input.nii' +>>> task.cmdline # doctest: +ELLIPSIS +'fnirt --ref template.nii --in input.nii --cout .../input_fnirt_coeff \ +--iout .../input_fnirt.nii --fout .../input_fnirt_field.nii' """ __all__ = ["FNIRT"] From 8e2ecd040328df3607de59b7f89ba2e5a77a6061 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:28:53 +1100 Subject: [PATCH 089/224] FIX: Make BETSpec derive ShellSpec --- pydra/tasks/fsl/bet.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index ee8a19c..600eee8 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -18,7 +18,7 @@ @attrs.define(slots=False, kw_only=True) -class BETSpec: +class BETSpec(pydra.specs.ShellSpec): """Specifications for BET.""" input_image: os.PathLike = attrs.field( From 7c4b045a9a7fdbacaf9899bcc609c22c438fa781 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:29:07 +1100 Subject: [PATCH 090/224] FIX: Use lists for requires metadata in ShellOutSpec --- pydra/tasks/fsl/bet.py | 8 ++++---- pydra/tasks/fsl/eddy.py | 8 ++++---- pydra/tasks/fsl/fast.py | 10 +++++----- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 600eee8..5dc5060 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -118,7 +118,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "brain surface outline", "output_file_template": "{output_image}_overlay", - "requires": {"save_brain_surface_outline"}, + "requires": ["save_brain_surface_outline"], } ) @@ -126,7 +126,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "brain mask", "output_file_template": "{output_image}_mask", - "requires": {"save_brain_mask"}, + "requires": ["save_brain_mask"], } ) @@ -134,7 +134,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "skull image", "output_file_template": "{output_image}_skull", - "requires": {"save_skull_image"}, + "requires": ["save_skull_image"], } ) @@ -143,7 +143,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): "help_string": "brain surface mesh", "output_file_template": "{output_image}_mesh.vtk", "keep_extension": False, - "requires": {"save_brain_surface_mesh"}, + "requires": ["save_brain_surface_mesh"], } ) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 55624d4..675441e 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -392,7 +392,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "input image with outliers replaced by predictions", "output_file_template": "{output_basename}.eddy_outlier_free_data", - "requires": {"replace_outliers"}, + "requires": ["replace_outliers"], } ) @@ -400,7 +400,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "movement parameters per time-point (slice or group)", "output_file_template": "{output_basename}.eddy_movement_over_time", - "requires": {"movement_prediction_order"}, + "requires": ["movement_prediction_order"], } ) @@ -408,7 +408,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "path to optional CNR maps image", "output_file_template": "{output_basename}.eddy_cnr_maps", - "requires": {"write_cnr_maps"}, + "requires": ["write_cnr_maps"], } ) @@ -416,7 +416,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): metadata={ "help_string": "path to optional residuals image", "output_file_template": "{output_basename}.eddy_residuals", - "requires": {"write_residuals"}, + "requires": ["write_residuals"], } ) diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py index 215fc1b..a7f9afc 100644 --- a/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/fast.py @@ -165,7 +165,7 @@ def get_bias_corrected_image(output_basename: str) -> str: "one segmentation mask per class, each voxel is assigned a value of " "1 if belonging to the class 0 otherwise." ), - "requires": {"save_segmentation_masks"}, + "requires": ["save_segmentation_masks"], "callable": get_segmentation_masks, } ) @@ -173,7 +173,7 @@ def get_bias_corrected_image(output_basename: str) -> str: probability_maps: ty.List[str] = attrs.field( metadata={ "help_string": "posterior probablity mapping for each class", - "requires": {"save_probability_maps"}, + "requires": ["save_probability_maps"], "callable": get_probability_maps, } ) @@ -181,7 +181,7 @@ def get_bias_corrected_image(output_basename: str) -> str: partial_volume_maps: ty.List[str] = attrs.field( metadata={ "help_string": "partial volume mapping for each class", - "requires": {("no_partial_volume_estimation", False)}, + "requires": [("no_partial_volume_estimation", False)], "callable": get_partial_volume_maps, } ) @@ -189,7 +189,7 @@ def get_bias_corrected_image(output_basename: str) -> str: bias_field_image: str = attrs.field( metadata={ "help_string": "estimated bias field", - "requires": {"save_bias_field_image"}, + "requires": ["save_bias_field_image"], "callable": get_bias_field_image, } ) @@ -197,7 +197,7 @@ def get_bias_corrected_image(output_basename: str) -> str: bias_corrected_image: str = attrs.field( metadata={ "help_string": "restored input image after bias field correction", - "requires": {"save_bias_corrected_image"}, + "requires": ["save_bias_corrected_image"], "callable": get_bias_corrected_image, } ) From a23f9510f398ca293c8a0fcf99b7ce8aa04fe3f8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:29:07 +1100 Subject: [PATCH 091/224] FIX: Move verbose and save flags for Eddy --- pydra/tasks/fsl/eddy.py | 46 ++++++++++++++++++++--------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/pydra/tasks/fsl/eddy.py b/pydra/tasks/fsl/eddy.py index 675441e..fa84168 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/pydra/tasks/fsl/eddy.py @@ -328,67 +328,74 @@ class EddySpec(pydra.specs.ShellSpec): } ) - write_cnr_maps: bool = attrs.field( + save_cnr_maps: bool = attrs.field( metadata={ - "help_string": "write shell-wise CNR maps", + "help_string": "save shell-wise CNR maps", "argstr": "--cnr_maps", } ) - write_residuals: bool = attrs.field( + save_residuals: bool = attrs.field( metadata={ - "help_string": "write residuals for all scans", + "help_string": "save residuals for all scans", "argstr": "--residuals", } ) + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + } + ) + class EddyOutSpec(pydra.specs.ShellOutSpec): """Output specification for eddy.""" - corrected_image: str = attrs.field( + corrected_image: pydra.specs.File = attrs.field( metadata={ "help_string": "input image corrected for distortions", "output_file_template": "{output_basename}.nii.gz", } ) - parameter_file: str = attrs.field( + parameters_file: pydra.specs.File = attrs.field( metadata={ "help_string": "registration parameters for movement and EC", "output_file_template": "{output_basename}.eddy_parameters", } ) - rotated_bvec_file: str = attrs.field( + rotated_bvec_file: pydra.specs.File = attrs.field( metadata={ "help_string": "rotated b-vecs", "output_file_template": "{output_basename}.eddy_rotated_bvecs", } ) - movement_rms_matrix: str = attrs.field( + movement_rms_matrix: pydra.specs.File = attrs.field( metadata={ "help_string": "movement induced RMS", "output_file_template": "{output_basename}.eddy_movement_rms", } ) - restricted_movement_rms_matrix: str = attrs.field( + restricted_movement_rms_matrix: pydra.specs.File = attrs.field( metadata={ "help_string": "movement induced RMS without translation in the PE direction", "output_file_template": "{output_basename}.eddy_restricted_movement_rms", } ) - displacement_fields_image: str = attrs.field( + displacement_fields_image: pydra.specs.File = attrs.field( metadata={ "help_string": "displacement fields in millimeters", "output_file_template": "{output_basename}.eddy_displacement_fields", } ) - outlier_free_image: str = attrs.field( + outlier_free_image: pydra.specs.File = attrs.field( metadata={ "help_string": "input image with outliers replaced by predictions", "output_file_template": "{output_basename}.eddy_outlier_free_data", @@ -396,7 +403,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): } ) - movement_over_time_file: str = attrs.field( + movement_over_time_file: pydra.specs.File = attrs.field( metadata={ "help_string": "movement parameters per time-point (slice or group)", "output_file_template": "{output_basename}.eddy_movement_over_time", @@ -404,26 +411,19 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): } ) - cnr_maps_image: str = attrs.field( + cnr_maps_image: pydra.specs.File = attrs.field( metadata={ "help_string": "path to optional CNR maps image", "output_file_template": "{output_basename}.eddy_cnr_maps", - "requires": ["write_cnr_maps"], + "requires": ["save_cnr_maps"], } ) - residuals_image: str = attrs.field( + residuals_image: pydra.specs.File = attrs.field( metadata={ "help_string": "path to optional residuals image", "output_file_template": "{output_basename}.eddy_residuals", - "requires": ["write_residuals"], - } - ) - - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "-v", + "requires": ["save_residuals"], } ) From 169ad61b8eaf99b93d59872cedf45258f0d06189 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:29:07 +1100 Subject: [PATCH 092/224] FIX: Use pydra.specs.File in BET output spec --- pydra/tasks/fsl/bet.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet.py index 5dc5060..e33d10d 100644 --- a/pydra/tasks/fsl/bet.py +++ b/pydra/tasks/fsl/bet.py @@ -114,7 +114,7 @@ class BETSpec(pydra.specs.ShellSpec): class BETOutSpec(pydra.specs.ShellOutSpec): """Output specifications for BET.""" - brain_surface_outline: str = attrs.field( + brain_surface_outline: pydra.specs.File = attrs.field( metadata={ "help_string": "brain surface outline", "output_file_template": "{output_image}_overlay", @@ -122,7 +122,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): } ) - brain_mask: str = attrs.field( + brain_mask: pydra.specs.File = attrs.field( metadata={ "help_string": "brain mask", "output_file_template": "{output_image}_mask", @@ -130,7 +130,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): } ) - skull_image: str = attrs.field( + skull_image: pydra.specs.File = attrs.field( metadata={ "help_string": "skull image", "output_file_template": "{output_image}_skull", @@ -138,7 +138,7 @@ class BETOutSpec(pydra.specs.ShellOutSpec): } ) - brain_surface_mesh: str = attrs.field( + brain_surface_mesh: pydra.specs.File = attrs.field( metadata={ "help_string": "brain surface mesh", "output_file_template": "{output_image}_mesh.vtk", From ebe6661c36026ffc027ab460dfc463647a746a6b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:29:38 +1100 Subject: [PATCH 093/224] FIX: Add missing attrs.define to FAST output spec --- pydra/tasks/fsl/fast.py | 1 + 1 file changed, 1 insertion(+) diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py index a7f9afc..8ede772 100644 --- a/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/fast.py @@ -124,6 +124,7 @@ class FASTSpec(pydra.specs.ShellSpec): ) +@attrs.define(slots=False, kw_only=True) class FASTOutSpec(pydra.specs.ShellOutSpec): """Ouput specifications for FAST.""" From 0c2991cad3ef3931a6f6073d5ff12e7389556621 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:29:38 +1100 Subject: [PATCH 094/224] MNT: Run lint:fix --- pydra/tasks/fsl/fast.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py index 8ede772..ebd04b1 100644 --- a/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/fast.py @@ -124,7 +124,7 @@ class FASTSpec(pydra.specs.ShellSpec): ) -@attrs.define(slots=False, kw_only=True) +@attrs.define(slots=False, kw_only=True) class FASTOutSpec(pydra.specs.ShellOutSpec): """Ouput specifications for FAST.""" From 7ae9606aec6e86a6be1ce2059cc1fd103dab2439 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:29:38 +1100 Subject: [PATCH 095/224] FIX: Move callables out of FAST output spec --- pydra/tasks/fsl/fast.py | 55 ++++++++++++++++++++--------------------- 1 file changed, 27 insertions(+), 28 deletions(-) diff --git a/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/fast.py index ebd04b1..9b4957d 100644 --- a/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/fast.py @@ -9,7 +9,6 @@ __all__ = ["FAST"] import os -import typing as ty import attrs @@ -124,35 +123,35 @@ class FASTSpec(pydra.specs.ShellSpec): ) -@attrs.define(slots=False, kw_only=True) -class FASTOutSpec(pydra.specs.ShellOutSpec): - """Ouput specifications for FAST.""" +def get_segmentation_image(output_basename): + return f"{output_basename}_seg" + + +def get_segmentation_masks(output_basename, num_classes): + return [f"{output_basename}_seg_{i}" for i in range(num_classes)] + - @staticmethod - def get_segmentation_image(output_basename: str) -> str: - return f"{output_basename}_seg" +def get_probability_maps(output_basename, num_classes): + return [f"{output_basename}_prob_{i}" for i in range(num_classes)] - @staticmethod - def get_segmentation_masks(output_basename: str, num_classes: int) -> ty.List[str]: - return [f"{output_basename}_seg_{i}" for i in range(num_classes)] - @staticmethod - def get_probability_maps(output_basename: str, num_classes: int) -> ty.List[str]: - return [f"{output_basename}_prob_{i}" for i in range(num_classes)] +def get_partial_volume_maps(output_basename, num_classes): + return [f"{output_basename}_pve_{i}" for i in range(num_classes)] - @staticmethod - def get_partial_volume_maps(output_basename: str, num_classes: int) -> ty.List[str]: - return [f"{output_basename}_pve_{i}" for i in range(num_classes)] - @staticmethod - def get_bias_field_image(output_basename: str) -> str: - return f"{output_basename}_bias" +def get_bias_field_image(output_basename): + return f"{output_basename}_bias" - @staticmethod - def get_bias_corrected_image(output_basename: str) -> str: - return f"{output_basename}_restore" - segmentation_image: str = attrs.field( +def get_bias_corrected_image(output_basename): + return f"{output_basename}_restore" + + +@attrs.define(slots=False, kw_only=True) +class FASTOutSpec(pydra.specs.ShellOutSpec): + """Ouput specifications for FAST.""" + + segmentation_image: pydra.specs.File = attrs.field( metadata={ "help_string": "segmentation image with each voxel assigned a class", "mandatory": True, @@ -160,7 +159,7 @@ def get_bias_corrected_image(output_basename: str) -> str: } ) - segmentation_masks: ty.List[str] = attrs.field( + segmentation_masks: pydra.specs.MultiOutputFile = attrs.field( metadata={ "help_string": ( "one segmentation mask per class, each voxel is assigned a value of " @@ -171,7 +170,7 @@ def get_bias_corrected_image(output_basename: str) -> str: } ) - probability_maps: ty.List[str] = attrs.field( + probability_maps: pydra.specs.MultiOutputFile = attrs.field( metadata={ "help_string": "posterior probablity mapping for each class", "requires": ["save_probability_maps"], @@ -179,7 +178,7 @@ def get_bias_corrected_image(output_basename: str) -> str: } ) - partial_volume_maps: ty.List[str] = attrs.field( + partial_volume_maps: pydra.specs.MultiOutputFile = attrs.field( metadata={ "help_string": "partial volume mapping for each class", "requires": [("no_partial_volume_estimation", False)], @@ -187,7 +186,7 @@ def get_bias_corrected_image(output_basename: str) -> str: } ) - bias_field_image: str = attrs.field( + bias_field_image: pydra.specs.File = attrs.field( metadata={ "help_string": "estimated bias field", "requires": ["save_bias_field_image"], @@ -195,7 +194,7 @@ def get_bias_corrected_image(output_basename: str) -> str: } ) - bias_corrected_image: str = attrs.field( + bias_corrected_image: pydra.specs.File = attrs.field( metadata={ "help_string": "restored input image after bias field correction", "requires": ["save_bias_corrected_image"], From 8a45ea41835e91ffea10bf646bd7ff2e1d046d28 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 096/224] MNT: Bump version to 0.0.6 --- pyproject.toml | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/pyproject.toml b/pyproject.toml index ed310fb..9c2e1f6 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,17 +4,11 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -description = "Pydra tasks package for fsl" -readme = "README.rst" -requires-python = ">=3.8" -dependencies = [ - "pydra >=0.22", - "fileformats >=0.8.3", - "fileformats-datascience >=0.1", - "fileformats-medimage >=0.4.1", - "fileformats-medimage-fsl", -] -license = { file = "LICENSE" } +version = "0.0.6" +description = "Pydra tasks for FSL" +readme = "README.md" +requires-python = ">=3.7" +license = "Apache-2.0" keywords = ["pydra", "neuroimaging", "fsl"] authors = [ { name = "Nipype developers", email = "neuroimaging@python.org" }, From 25fb1e21ff3efc9d8fd31eb2657e5bd13d10e3d8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 097/224] NEW: Add task definition for fslmaths' mul --- pydra/tasks/fsl/__init__.py | 2 + pydra/tasks/fsl/fslmaths.py | 111 ++++++++++++++++++++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 pydra/tasks/fsl/fslmaths.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 7cc461b..5f9dd4e 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -16,8 +16,10 @@ "FSLReorient2Std", "FSLROI", "RobustFOV", + "fslmaths", ] +from . import fslmaths from .bet import BET from .convert_xfm import ConvertXFM from .eddy import Eddy diff --git a/pydra/tasks/fsl/fslmaths.py b/pydra/tasks/fsl/fslmaths.py new file mode 100644 index 0000000..0676568 --- /dev/null +++ b/pydra/tasks/fsl/fslmaths.py @@ -0,0 +1,111 @@ +""" +fslmaths +======== + +Examples +-------- + +Convert input image to float: + +>>> task = FSLMaths(input_image="input.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'fslmaths input.nii .../input_fslmaths.nii -odt float' + +Apply mask to input image: + +>>> task = Mul( +... input_image="input.nii", +... other_image="mask.nii", +... output_image="output.nii", +... ) +>>> task.cmdline +'fslmaths input.nii -mul mask.nii output.nii -odt float' +""" + +__all__ = ["FSLMaths", "Mul"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLMathsSpec(pydra.specs.ShellSpec): + """Specifications for fslmaths.""" + + _ALLOWED_DATATYPES = {"char", "short", "int", "float", "double", "input"} + + datatype: str = attrs.field( + metadata={ + "help_string": "datatype used for internal computation", + "argstr": "-dt", + "position": 1, + "allowed_values": _ALLOWED_DATATYPES, + } + ) + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + "position": 2, + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "position": -2, + "output_file_template": "{input_image}_fslmaths", + } + ) + + output_datatype: str = attrs.field( + default="float", + metadata={ + "help_string": "datatype used for output serialization", + "argstr": "-odt", + "position": -1, + "allowed_values": _ALLOWED_DATATYPES, + }, + ) + + +class FSLMaths(pydra.engine.ShellCommandTask): + """Task definition for fslmaths.""" + + executable = "fslmaths" + + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLMathsSpec,)) + + +@attrs.define(slots=False, kw_only=True) +class MulSpec(pydra.specs.ShellSpec): + """Specifications for fslmaths' mul.""" + + operation: str = attrs.field( + default="mul", + metadata={ + "help_string": "operation (image multiplication)", + "argstr": "-{operation}", + "allowed_values": {"mul"}, + }, + ) + + other_image: os.PathLike = attrs.field( + metadata={ + "help_string": "other image used as operand", + "argstr": "", + "requires": {"operation"}, + } + ) + + +class Mul(FSLMaths): + """Task definition for fslmaths' mul.""" + + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLMathsSpec, MulSpec)) From 64f17c1d6815642cea7649b557e70539ff146cea Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 098/224] MNT: Bump version to 0.0.7 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 9c2e1f6..30df39c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.6" +version = "0.0.7" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From f5e2ecd23403ca45ee740bfafe1fb1784d05cff5 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 099/224] FIX: Drop redundant requires in ConvertXFM --- pydra/tasks/fsl/convert_xfm.py | 1 - 1 file changed, 1 deletion(-) diff --git a/pydra/tasks/fsl/convert_xfm.py b/pydra/tasks/fsl/convert_xfm.py index 8e5dcb6..0a18160 100644 --- a/pydra/tasks/fsl/convert_xfm.py +++ b/pydra/tasks/fsl/convert_xfm.py @@ -45,7 +45,6 @@ class ConvertXFMSpec(pydra.specs.ShellSpec): "help_string": "output matrix in 4x4 ASCII format", "argstr": "-omat", "output_file_template": "{input_matrix}_cxfm", - "requires": {"input_matrix"}, } ) From 126979884010b2bc7d27383733a08f224060c499 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 100/224] DOC: Add fslmaths to available interfaces --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c702a5d..6a6282c 100644 --- a/README.md +++ b/README.md @@ -35,6 +35,7 @@ for FMRI, MRI and DTI brain imaging data. - fnirt - fnirt - utils + - fslmaths - fslmerge - fslreorient2std - fslroi From 349d20f03a95734887be040805b532b30d9da6ba Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 101/224] DOC: Add status badge for test workflow --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 6a6282c..91a2b71 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![PyPI - Version][pypi-version]][pypi-project] [![PyPI - Python Version][pypi-pyversions]][pypi-project] [![PyPI - Downloads][pypi-downloads]][pypi-project] +![][status-test] ---- @@ -82,6 +83,8 @@ hatch run lint:fix [pypi-downloads]: https://static.pepy.tech/badge/pydra-fsl +[status-test]: https://github.com/aramis-lab/pydra-fsl/actions/workflows/test.yaml/badge.svg + [pydra]: https://pydra.readthedocs.io/ [fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL From 6ffc076041a0db49613189523e268df24c0c72dd Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 102/224] NEW: Add ConvertXFM and InvertXFM interfaces --- pydra/tasks/fsl/__init__.py | 4 ++++ pydra/tasks/fsl/concat_xfm.py | 44 ++++++++++++++++++++++++++++++++++ pydra/tasks/fsl/convert_xfm.py | 11 ++++++--- pydra/tasks/fsl/invert_xfm.py | 38 +++++++++++++++++++++++++++++ 4 files changed, 94 insertions(+), 3 deletions(-) create mode 100644 pydra/tasks/fsl/concat_xfm.py create mode 100644 pydra/tasks/fsl/invert_xfm.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 5f9dd4e..ef9c539 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -8,6 +8,7 @@ __all__ = [ "BET", + "ConcatXFM", "ConvertXFM", "FAST", "FLIRT", @@ -15,12 +16,14 @@ "FSLMerge", "FSLReorient2Std", "FSLROI", + "InvertXFM", "RobustFOV", "fslmaths", ] from . import fslmaths from .bet import BET +from .concat_xfm import ConcatXFM from .convert_xfm import ConvertXFM from .eddy import Eddy from .fast import FAST @@ -29,4 +32,5 @@ from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI +from .invert_xfm import InvertXFM from .robustfov import RobustFOV diff --git a/pydra/tasks/fsl/concat_xfm.py b/pydra/tasks/fsl/concat_xfm.py new file mode 100644 index 0000000..36126b1 --- /dev/null +++ b/pydra/tasks/fsl/concat_xfm.py @@ -0,0 +1,44 @@ +""" +ConcatXFM +========= + +Examples +-------- + +>>> task = ConcatXFM( +... input_matrix="AtoB.mat", +... concat_matrix="BtoC.mat", +... output_matrix="AtoC.mat", +... ) +>>> task.cmdline +'convert_xfm -omat AtoC.mat -concat BtoC.mat AtoB.mat' +""" + +__all__ = ["ConcatXFM"] + +import os + +import attrs + +import pydra + +from .convert_xfm import BaseConvertXFMSpec, ConvertXFM + + +@attrs.define(slots=False, kw_only=True) +class ConcatXFMSpec(BaseConvertXFMSpec): + """Specifications for concat_xfm.""" + + concat_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "concatenate this matrix with input matrix", + "mandatory": True, + "argstr": "-concat", + } + ) + + +class ConcatXFM(ConvertXFM): + """Task definition for concat_xfm.""" + + input_spec = pydra.specs.SpecInfo(name="ConcatXFMInput", bases=(ConcatXFMSpec,)) diff --git a/pydra/tasks/fsl/convert_xfm.py b/pydra/tasks/fsl/convert_xfm.py index 0a18160..92d1b7a 100644 --- a/pydra/tasks/fsl/convert_xfm.py +++ b/pydra/tasks/fsl/convert_xfm.py @@ -18,7 +18,7 @@ 'convert_xfm -omat AtoC.mat -concat BtoC.mat AtoB.mat' """ -__all__ = ["ConvertXFM"] +__all__ = ["ConvertXFM", "BaseConvertXFMSpec"] import os @@ -28,8 +28,8 @@ @attrs.define(slots=False, kw_only=True) -class ConvertXFMSpec(pydra.specs.ShellSpec): - """Specifications for convert_xfm.""" +class BaseConvertXFMSpec(pydra.specs.ShellSpec): + """Base specifications for all tasks using convert_xfm.""" input_matrix: os.PathLike = attrs.field( metadata={ @@ -48,6 +48,11 @@ class ConvertXFMSpec(pydra.specs.ShellSpec): } ) + +@attrs.define(slots=False, kw_only=True) +class ConvertXFMSpec(BaseConvertXFMSpec): + """Specifications for convert_xfm.""" + concat_matrix: os.PathLike = attrs.field( metadata={ "help_string": "concatenate this matrix with input matrix", diff --git a/pydra/tasks/fsl/invert_xfm.py b/pydra/tasks/fsl/invert_xfm.py new file mode 100644 index 0000000..a1c8a1b --- /dev/null +++ b/pydra/tasks/fsl/invert_xfm.py @@ -0,0 +1,38 @@ +""" +InvertXFM +========= + +Examples +-------- + +>>> task = InvertXFM(input_matrix="AtoB.mat", output_matrix="BtoA.mat") +>>> task.cmdline +'convert_xfm -omat BtoA.mat -inverse AtoB.mat' +""" + +__all__ = ["InvertXFM"] + +import attrs + +import pydra + +from .convert_xfm import BaseConvertXFMSpec, ConvertXFM + + +@attrs.define(slots=False, kw_only=True) +class InvertXFMSpec(BaseConvertXFMSpec): + """Specifications for invert_xfm.""" + + inverse: bool = attrs.field( + default=True, + metadata={ + "help_string": "return inverse of computed matrix", + "argstr": "-inverse", + }, + ) + + +class InvertXFM(ConvertXFM): + """Task definition for concat_xfm.""" + + input_spec = pydra.specs.SpecInfo(name="InvertXFMInput", bases=(InvertXFMSpec,)) From 9281a82ef4916573443fe3d3b642bdce6eedf34f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:04 +1100 Subject: [PATCH 103/224] NEW: Add interface for ApplyXFM --- pydra/tasks/fsl/__init__.py | 2 + pydra/tasks/fsl/apply_xfm.py | 128 +++++++++++++++++++++++++++++++++++ 2 files changed, 130 insertions(+) create mode 100644 pydra/tasks/fsl/apply_xfm.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index ef9c539..2f2240f 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -7,6 +7,7 @@ """ __all__ = [ + "ApplyXFM", "BET", "ConcatXFM", "ConvertXFM", @@ -22,6 +23,7 @@ ] from . import fslmaths +from .apply_xfm import ApplyXFM from .bet import BET from .concat_xfm import ConcatXFM from .convert_xfm import ConvertXFM diff --git a/pydra/tasks/fsl/apply_xfm.py b/pydra/tasks/fsl/apply_xfm.py new file mode 100644 index 0000000..17b969d --- /dev/null +++ b/pydra/tasks/fsl/apply_xfm.py @@ -0,0 +1,128 @@ +""" +ApplyXFM +======== + +Examples +-------- + +>>> task = ApplyXFM( +... input_image="input.nii", +... reference_image="reference.nii", +... input_matrix="affine.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'flirt -in input.nii -ref reference.nii -init affine.mat -out .../input_axfm.nii \ +-applyxfm -interp trilinear' + +>>> task = ApplyXFM( +... input_image="input.nii", +... reference_image="reference.nii", +... input_matrix="affine.mat", +... isotropic_resolution=1, +... padding_size=5, +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'flirt -in input.nii -ref reference.nii -init affine.mat -out .../input_axfm.nii \ +-applyisoxfm 1 -interp trilinear -paddingsize 5' + +""" + +__all__ = ["ApplyXFM"] + +import os + +import attrs + +import pydra + +from .flirt import FLIRT + + +@attrs.define(slots=False, kw_only=True) +class ApplyXFMSpec(pydra.specs.ShellSpec): + """Specifications for ApplyXFM.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "-in", + } + ) + + reference_image: os.PathLike = attrs.field( + metadata={ + "help_string": "reference image", + "mandatory": True, + "argstr": "-ref", + } + ) + + input_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "input transformation matrix", + "mandatory": True, + "argstr": "-init", + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "-out", + "output_file_template": "{input_image}_axfm", + } + ) + + output_datatype: str = attrs.field( + metadata={ + "help_string": "output datatype", + "argstr": "-datatype", + "allowed_values": { + "char", + "short", + "int", + "float", + "double", + }, + } + ) + + isotropic_resolution: float = attrs.field( + default=0.0, + metadata={ + "help_string": "force resampling to isotropic resolution", + "formatter": lambda isotropic_resolution: ( + f"-applyisoxfm {isotropic_resolution}" + if isotropic_resolution + else "-applyxfm" + ), + }, + ) + + interpolation: str = attrs.field( + default="trilinear", + metadata={ + "help_string": "interpolation method", + "argstr": "-interp", + "allowed_values": { + "trilinear", + "nearestneighbour", + "spline", + "sinc", + }, + }, + ) + + padding_size: float = attrs.field( + metadata={ + "help_string": "padding size in voxels", + "argstr": "-paddingsize", + } + ) + + +class ApplyXFM(FLIRT): + """Task definition for ApplyXFM.""" + + input_spec = pydra.specs.SpecInfo(name="ApplyXFMInput", bases=(ApplyXFMSpec,)) From 2aa203c5597cf2c253be73ae151103a08aae4e9c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 104/224] REF: Move FLIRT interface and utilities to their own subpackage --- pydra/tasks/fsl/__init__.py | 16 +++++----------- pydra/tasks/fsl/flirt/__init__.py | 13 +++++++++++++ pydra/tasks/fsl/{ => flirt}/apply_xfm.py | 0 pydra/tasks/fsl/{ => flirt}/concat_xfm.py | 0 pydra/tasks/fsl/{ => flirt}/convert_xfm.py | 0 pydra/tasks/fsl/{ => flirt}/flirt.py | 0 pydra/tasks/fsl/{ => flirt}/invert_xfm.py | 0 7 files changed, 18 insertions(+), 11 deletions(-) create mode 100644 pydra/tasks/fsl/flirt/__init__.py rename pydra/tasks/fsl/{ => flirt}/apply_xfm.py (100%) rename pydra/tasks/fsl/{ => flirt}/concat_xfm.py (100%) rename pydra/tasks/fsl/{ => flirt}/convert_xfm.py (100%) rename pydra/tasks/fsl/{ => flirt}/flirt.py (100%) rename pydra/tasks/fsl/{ => flirt}/invert_xfm.py (100%) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 2f2240f..158a269 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -7,32 +7,26 @@ """ __all__ = [ - "ApplyXFM", "BET", - "ConcatXFM", - "ConvertXFM", + "Eddy", "FAST", - "FLIRT", "FNIRT", "FSLMerge", "FSLReorient2Std", "FSLROI", - "InvertXFM", "RobustFOV", + "flirt", "fslmaths", ] -from . import fslmaths -from .apply_xfm import ApplyXFM +from . import flirt, fslmaths from .bet import BET -from .concat_xfm import ConcatXFM -from .convert_xfm import ConvertXFM from .eddy import Eddy from .fast import FAST -from .flirt import FLIRT from .fnirt import FNIRT from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI -from .invert_xfm import InvertXFM from .robustfov import RobustFOV + +__all__ += flirt.__all__ diff --git a/pydra/tasks/fsl/flirt/__init__.py b/pydra/tasks/fsl/flirt/__init__.py new file mode 100644 index 0000000..1024e23 --- /dev/null +++ b/pydra/tasks/fsl/flirt/__init__.py @@ -0,0 +1,13 @@ +__all__ = [ + "FLIRT", + "ApplyXFM", + "ConcatXFM", + "ConvertXFM", + "InvertXFM", +] + +from .apply_xfm import ApplyXFM +from .concat_xfm import ConcatXFM +from .convert_xfm import ConvertXFM +from .flirt import FLIRT +from .invert_xfm import InvertXFM diff --git a/pydra/tasks/fsl/apply_xfm.py b/pydra/tasks/fsl/flirt/apply_xfm.py similarity index 100% rename from pydra/tasks/fsl/apply_xfm.py rename to pydra/tasks/fsl/flirt/apply_xfm.py diff --git a/pydra/tasks/fsl/concat_xfm.py b/pydra/tasks/fsl/flirt/concat_xfm.py similarity index 100% rename from pydra/tasks/fsl/concat_xfm.py rename to pydra/tasks/fsl/flirt/concat_xfm.py diff --git a/pydra/tasks/fsl/convert_xfm.py b/pydra/tasks/fsl/flirt/convert_xfm.py similarity index 100% rename from pydra/tasks/fsl/convert_xfm.py rename to pydra/tasks/fsl/flirt/convert_xfm.py diff --git a/pydra/tasks/fsl/flirt.py b/pydra/tasks/fsl/flirt/flirt.py similarity index 100% rename from pydra/tasks/fsl/flirt.py rename to pydra/tasks/fsl/flirt/flirt.py diff --git a/pydra/tasks/fsl/invert_xfm.py b/pydra/tasks/fsl/flirt/invert_xfm.py similarity index 100% rename from pydra/tasks/fsl/invert_xfm.py rename to pydra/tasks/fsl/flirt/invert_xfm.py From 3d0162010ad31dee33b69535868c434af4270391 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 105/224] ENH: Remove apply_transformation from FLIRT Should use dedicated ApplyXFM interface instead. --- pydra/tasks/fsl/flirt/flirt.py | 20 -------------------- 1 file changed, 20 deletions(-) diff --git a/pydra/tasks/fsl/flirt/flirt.py b/pydra/tasks/fsl/flirt/flirt.py index 9846eb6..69a4f86 100644 --- a/pydra/tasks/fsl/flirt/flirt.py +++ b/pydra/tasks/fsl/flirt/flirt.py @@ -22,18 +22,6 @@ 'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -cost mutualinfo \ -interp trilinear -dof 6' -Apply a saved transformation to another image: - ->>> task = FLIRT( -... input_image="newvol", -... reference_image="refvol", -... input_matrix="invol2refvol.mat", -... apply_transformation=True, -... ) ->>> task.cmdline -'flirt -in newvol -ref refvol -out ...newvol_flirt -init invol2refvol.mat \ --omat ...newvol_flirt.mat -cost corratio -interp trilinear -applyxfm' - Perform a single slice registration: >>> task = FLIRT( @@ -149,14 +137,6 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) - apply_transformation: bool = attrs.field( - metadata={ - "help_string": "apply transformation without optimization", - "argstr": "-applyxfm", - "requires": {"input_matrix"}, - } - ) - use_2d_registration: bool = attrs.field( metadata={ "help_string": "use rigid-body registration model in 2D", From 01c8d3e3b07896e1703ab7159327de22f73c1cfb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 106/224] REF: Extract common FLIRT specs out --- pydra/tasks/fsl/flirt/apply_xfm.py | 22 +++----- pydra/tasks/fsl/flirt/flirt.py | 85 ++++++++++++------------------ pydra/tasks/fsl/flirt/specs.py | 50 ++++++++++++++++++ 3 files changed, 89 insertions(+), 68 deletions(-) create mode 100644 pydra/tasks/fsl/flirt/specs.py diff --git a/pydra/tasks/fsl/flirt/apply_xfm.py b/pydra/tasks/fsl/flirt/apply_xfm.py index 17b969d..9fa4eee 100644 --- a/pydra/tasks/fsl/flirt/apply_xfm.py +++ b/pydra/tasks/fsl/flirt/apply_xfm.py @@ -23,7 +23,7 @@ ... ) >>> task.cmdline # doctest: +ELLIPSIS 'flirt -in input.nii -ref reference.nii -init affine.mat -out .../input_axfm.nii \ --applyisoxfm 1 -interp trilinear -paddingsize 5' +-applyisoxfm 1 -paddingsize 5 -interp trilinear' """ @@ -35,6 +35,7 @@ import pydra +from . import specs from .flirt import FLIRT @@ -100,20 +101,6 @@ class ApplyXFMSpec(pydra.specs.ShellSpec): }, ) - interpolation: str = attrs.field( - default="trilinear", - metadata={ - "help_string": "interpolation method", - "argstr": "-interp", - "allowed_values": { - "trilinear", - "nearestneighbour", - "spline", - "sinc", - }, - }, - ) - padding_size: float = attrs.field( metadata={ "help_string": "padding size in voxels", @@ -125,4 +112,7 @@ class ApplyXFMSpec(pydra.specs.ShellSpec): class ApplyXFM(FLIRT): """Task definition for ApplyXFM.""" - input_spec = pydra.specs.SpecInfo(name="ApplyXFMInput", bases=(ApplyXFMSpec,)) + input_spec = pydra.specs.SpecInfo( + name="ApplyXFMInput", + bases=(ApplyXFMSpec, specs.InterpolationSpec), + ) diff --git a/pydra/tasks/fsl/flirt/flirt.py b/pydra/tasks/fsl/flirt/flirt.py index 69a4f86..4bd1dda 100644 --- a/pydra/tasks/fsl/flirt/flirt.py +++ b/pydra/tasks/fsl/flirt/flirt.py @@ -19,8 +19,8 @@ ... degrees_of_freedom=6, ... ) >>> task.cmdline -'flirt -in invol -ref refvol -out outvol -omat invol2refvol.mat -cost mutualinfo \ --interp trilinear -dof 6' +'flirt -in invol -ref refvol -omat invol2refvol.mat -out outvol \ +-dof 6 -cost mutualinfo -bins 256 -interp trilinear' Perform a single slice registration: @@ -31,11 +31,10 @@ ... output_matrix="i2r.mat", ... interpolation="nearestneighbour", ... use_2d_registration=True, -... verbose=True, ... ) >>> task.cmdline -'flirt -in inslice -ref refslice -out outslice -omat i2r.mat -cost corratio \ --interp nearestneighbour -2D -v' +'flirt -in inslice -ref refslice -omat i2r.mat -out outslice -2D \ +-cost corratio -bins 256 -interp nearestneighbour' """ __all__ = ["FLIRT"] @@ -46,86 +45,65 @@ import pydra +from . import specs + @attrs.define(slots=False, kw_only=True) class FLIRTSpec(pydra.specs.ShellSpec): """Specifications for FLIRT.""" input_image: os.PathLike = attrs.field( - metadata={"help_string": "input volume", "argstr": "-in"} - ) - - reference_image: os.PathLike = attrs.field( - metadata={"help_string": "reference volume", "argstr": "-ref"} - ) - - output_image: str = attrs.field( metadata={ - "help_string": "output volume", - "argstr": "-out", - "output_file_template": "{input_image}_flirt", + "help_string": "input image", + "mandatory": True, + "argstr": "-in", } ) - output_datatype: str = attrs.field( + reference_image: os.PathLike = attrs.field( metadata={ - "help_string": "output datatype", - "argstr": "-datatype", - "allowed_values": { - "char", - "short", - "int", - "float", - "double", - }, + "help_string": "reference image", + "mandatory": True, + "argstr": "-ref", } ) input_matrix: os.PathLike = attrs.field( metadata={ - "help_string": "input transformation as 4x4 matrix", + "help_string": "input transformation matrix", "argstr": "-init", } ) output_matrix: str = attrs.field( metadata={ - "help_string": "output transformation as 4x4 matrix", + "help_string": "output transformation matrix", "argstr": "-omat", "output_file_template": "{input_image}_flirt.mat", "keep_extension": False, } ) - cost_function: str = attrs.field( - default="corratio", + output_image: str = attrs.field( metadata={ - "help_string": "cost function", - "argstr": "-cost", - "allowed_values": { - "mutualinfo", - "corratio", - "normcorr", - "normmi", - "leastsq", - "labeldiff", - "bbr", - }, - }, + "help_string": "output volume", + "argstr": "-out", + "output_file_template": "{input_image}_flirt", + } ) - interpolation: str = attrs.field( - default="trilinear", + output_datatype: str = attrs.field( metadata={ - "help_string": "interpolation method", - "argstr": "-interp", + "help_string": "output datatype", + "argstr": "-datatype", "allowed_values": { - "trilinear", - "nearestneighbour", - "sinc", - "spline", + "char", + "short", + "int", + "float", + "double", }, - }, + } ) degrees_of_freedom: int = attrs.field( @@ -158,4 +136,7 @@ class FLIRT(pydra.engine.ShellCommandTask): executable = "flirt" - input_spec = pydra.specs.SpecInfo(name="FLIRTInput", bases=(FLIRTSpec,)) + input_spec = pydra.specs.SpecInfo( + name="FLIRTInput", + bases=(FLIRTSpec, specs.CostFunctionSpec, specs.InterpolationSpec), + ) diff --git a/pydra/tasks/fsl/flirt/specs.py b/pydra/tasks/fsl/flirt/specs.py new file mode 100644 index 0000000..c7ab0ca --- /dev/null +++ b/pydra/tasks/fsl/flirt/specs.py @@ -0,0 +1,50 @@ +"""Common specifications for FLIRT.""" + +__all__ = ["CostFunctionSpec", "InterpolationSpec"] + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class CostFunctionSpec(pydra.specs.ShellSpec): + cost_function: str = attrs.field( + default="corratio", + metadata={ + "help_string": "cost function", + "argstr": "-cost", + "allowed_values": { + "corratio", + "mutualinfo", + "normmi", + "normcorr", + "leastsq", + }, + }, + ) + + num_bins: int = attrs.field( + default=256, + metadata={ + "help_string": "number of histogram bins", + "argstr": "-bins", + }, + ) + + +@attrs.define(slots=False, kw_only=True) +class InterpolationSpec(pydra.specs.ShellSpec): + interpolation: str = attrs.field( + default="trilinear", + metadata={ + "help_string": "interpolation method", + "argstr": "-interp", + "allowed_values": { + "trilinear", + "nearestneighbour", + "spline", + "sinc", + }, + }, + ) From edf50548c9ce72cbda8b2b538eb06cf3de87cfe6 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 107/224] ENH: Add search specifications for FLIRT --- pydra/tasks/fsl/flirt/flirt.py | 13 +++++++--- pydra/tasks/fsl/flirt/specs.py | 45 ++++++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+), 3 deletions(-) diff --git a/pydra/tasks/fsl/flirt/flirt.py b/pydra/tasks/fsl/flirt/flirt.py index 4bd1dda..0466d62 100644 --- a/pydra/tasks/fsl/flirt/flirt.py +++ b/pydra/tasks/fsl/flirt/flirt.py @@ -20,7 +20,8 @@ ... ) >>> task.cmdline 'flirt -in invol -ref refvol -omat invol2refvol.mat -out outvol \ --dof 6 -cost mutualinfo -bins 256 -interp trilinear' +-dof 6 -searchrx -90 90 -searchry -90 90 -searchrz -90 90 \ +-cost mutualinfo -bins 256 -interp trilinear' Perform a single slice registration: @@ -31,10 +32,11 @@ ... output_matrix="i2r.mat", ... interpolation="nearestneighbour", ... use_2d_registration=True, +... no_search=True, ... ) >>> task.cmdline 'flirt -in inslice -ref refslice -omat i2r.mat -out outslice -2D \ --cost corratio -bins 256 -interp nearestneighbour' +-nosearch -cost corratio -bins 256 -interp nearestneighbour' """ __all__ = ["FLIRT"] @@ -138,5 +140,10 @@ class FLIRT(pydra.engine.ShellCommandTask): input_spec = pydra.specs.SpecInfo( name="FLIRTInput", - bases=(FLIRTSpec, specs.CostFunctionSpec, specs.InterpolationSpec), + bases=( + FLIRTSpec, + specs.SearchSpec, + specs.CostFunctionSpec, + specs.InterpolationSpec, + ), ) diff --git a/pydra/tasks/fsl/flirt/specs.py b/pydra/tasks/fsl/flirt/specs.py index c7ab0ca..52a987a 100644 --- a/pydra/tasks/fsl/flirt/specs.py +++ b/pydra/tasks/fsl/flirt/specs.py @@ -2,6 +2,8 @@ __all__ = ["CostFunctionSpec", "InterpolationSpec"] +import typing as ty + import attrs import pydra @@ -48,3 +50,46 @@ class InterpolationSpec(pydra.specs.ShellSpec): }, }, ) + + +@attrs.define(slots=False, kw_only=True) +class SearchSpec(pydra.specs.ShellSpec): + # TODO: Change to Tuple[int, int] with pydra >=0.23 + SearchRange = ty.List[int] + + no_search: bool = attrs.field( + metadata={ + "help_string": "set all angular search ranges to 0", + "argstr": "-nosearch", + } + ) + + search_range_x: SearchRange = attrs.field( + default=[-90, 90], + metadata={ + "help_string": "range of search angles in x", + "formatter": lambda field, no_search: ( + "" if no_search else f"-searchrx {field[0]} {field[1]}" + ), + }, + ) + + search_range_y: SearchRange = attrs.field( + default=[-90, 90], + metadata={ + "help_string": "range of search angles in y", + "formatter": lambda field, no_search: ( + "" if no_search else f"-searchry {field[0]} {field[1]}" + ), + }, + ) + + search_range_z: SearchRange = attrs.field( + default=[-90, 90], + metadata={ + "help_string": "range of search angles in z", + "formatter": lambda field, no_search: ( + "" if no_search else f"-searchrz {field[0]} {field[1]}" + ), + }, + ) From 140d0a1fcb2fad6d7500bfe3aa25e4feb07c637d Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 108/224] ENH: Add weighting image spec for FLIRT --- pydra/tasks/fsl/flirt/flirt.py | 1 + pydra/tasks/fsl/flirt/specs.py | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pydra/tasks/fsl/flirt/flirt.py b/pydra/tasks/fsl/flirt/flirt.py index 0466d62..54d2716 100644 --- a/pydra/tasks/fsl/flirt/flirt.py +++ b/pydra/tasks/fsl/flirt/flirt.py @@ -145,5 +145,6 @@ class FLIRT(pydra.engine.ShellCommandTask): specs.SearchSpec, specs.CostFunctionSpec, specs.InterpolationSpec, + specs.WeightingSpec, ), ) diff --git a/pydra/tasks/fsl/flirt/specs.py b/pydra/tasks/fsl/flirt/specs.py index 52a987a..f359e4f 100644 --- a/pydra/tasks/fsl/flirt/specs.py +++ b/pydra/tasks/fsl/flirt/specs.py @@ -2,6 +2,7 @@ __all__ = ["CostFunctionSpec", "InterpolationSpec"] +import os import typing as ty import attrs @@ -93,3 +94,20 @@ class SearchSpec(pydra.specs.ShellSpec): ), }, ) + + +@attrs.define(slots=False, kw_only=True) +class WeightingSpec(pydra.specs.ShellSpec): + reference_weighting_image: os.PathLike = attrs.field( + metadata={ + "help_string": "weights for reference image", + "argstr": "-refweight", + } + ) + + input_weighting_image: os.PathLike = attrs.field( + metadata={ + "help_string": "weights for input image", + "argstr": "-inweight", + } + ) From cbed3489e1dcc8dc0c90743e3a7c2042af3b7521 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 109/224] REF: Update exported symbols by flirt.specs module --- pydra/tasks/fsl/flirt/specs.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/flirt/specs.py b/pydra/tasks/fsl/flirt/specs.py index f359e4f..0f32d98 100644 --- a/pydra/tasks/fsl/flirt/specs.py +++ b/pydra/tasks/fsl/flirt/specs.py @@ -1,6 +1,11 @@ """Common specifications for FLIRT.""" -__all__ = ["CostFunctionSpec", "InterpolationSpec"] +__all__ = [ + "CostFunctionSpec", + "InterpolationSpec", + "SearchSpec", + "WeightingSpec", +] import os import typing as ty From 1f4cc7d1778da04604ae42bde56e3bee1c5801be Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:19 +1100 Subject: [PATCH 110/224] REF: Simplify Mul interface from fslmaths --- pydra/tasks/fsl/fslmaths.py | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/pydra/tasks/fsl/fslmaths.py b/pydra/tasks/fsl/fslmaths.py index 0676568..db1b498 100644 --- a/pydra/tasks/fsl/fslmaths.py +++ b/pydra/tasks/fsl/fslmaths.py @@ -87,20 +87,10 @@ class FSLMaths(pydra.engine.ShellCommandTask): class MulSpec(pydra.specs.ShellSpec): """Specifications for fslmaths' mul.""" - operation: str = attrs.field( - default="mul", - metadata={ - "help_string": "operation (image multiplication)", - "argstr": "-{operation}", - "allowed_values": {"mul"}, - }, - ) - other_image: os.PathLike = attrs.field( metadata={ - "help_string": "other image used as operand", - "argstr": "", - "requires": {"operation"}, + "help_string": "multiply input with other image", + "argstr": "-mul", } ) From 9c4d9b095d1fb3289c0c9ce2ed91ee14042c5368 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:38 +1100 Subject: [PATCH 111/224] MNT: Update test paths --- hatch.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hatch.toml b/hatch.toml index b780bdf..e289fb6 100644 --- a/hatch.toml +++ b/hatch.toml @@ -8,7 +8,7 @@ dependencies = [ "pytest-cov", ] [envs.default.scripts] -cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=pydra --cov=tests {args}" +cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=pydra {args}" no-cov = "cov --no-cov {args}" [[envs.test.matrix]] From 60d24fa41b0d32ed31d99b760c0c892714a70371 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 112/224] DOC: Update list of available interfaces --- README.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 91a2b71..0e09245 100644 --- a/README.md +++ b/README.md @@ -31,8 +31,11 @@ for FMRI, MRI and DTI brain imaging data. - eddy - fast - flirt - - convert_xfm - flirt + - apply_xfm + - concat_xfm + - convert_xfm + - invert_xfm - fnirt - fnirt - utils From 8c0fce037562c716ae14a225d93c95897c3a7290 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 113/224] REF: Move BET interfaces and utils to own subpackage --- pydra/tasks/fsl/__init__.py | 8 ++------ pydra/tasks/fsl/bet/__init__.py | 4 ++++ pydra/tasks/fsl/{ => bet}/bet.py | 0 pydra/tasks/fsl/{ => bet}/robustfov.py | 0 4 files changed, 6 insertions(+), 6 deletions(-) create mode 100644 pydra/tasks/fsl/bet/__init__.py rename pydra/tasks/fsl/{ => bet}/bet.py (100%) rename pydra/tasks/fsl/{ => bet}/robustfov.py (100%) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 158a269..c5f20e3 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -7,26 +7,22 @@ """ __all__ = [ - "BET", "Eddy", "FAST", "FNIRT", "FSLMerge", "FSLReorient2Std", "FSLROI", - "RobustFOV", - "flirt", "fslmaths", ] -from . import flirt, fslmaths -from .bet import BET +from . import bet, flirt, fslmaths from .eddy import Eddy from .fast import FAST from .fnirt import FNIRT from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI -from .robustfov import RobustFOV +__all__ += bet.__all__ __all__ += flirt.__all__ diff --git a/pydra/tasks/fsl/bet/__init__.py b/pydra/tasks/fsl/bet/__init__.py new file mode 100644 index 0000000..003365b --- /dev/null +++ b/pydra/tasks/fsl/bet/__init__.py @@ -0,0 +1,4 @@ +__all__ = ["BET", "RobustFOV"] + +from .bet import BET +from .robustfov import RobustFOV diff --git a/pydra/tasks/fsl/bet.py b/pydra/tasks/fsl/bet/bet.py similarity index 100% rename from pydra/tasks/fsl/bet.py rename to pydra/tasks/fsl/bet/bet.py diff --git a/pydra/tasks/fsl/robustfov.py b/pydra/tasks/fsl/bet/robustfov.py similarity index 100% rename from pydra/tasks/fsl/robustfov.py rename to pydra/tasks/fsl/bet/robustfov.py From d54e674d3a3ada19b73b17e8f80066a892db4337 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 114/224] ENH: Add specifications for BET variations --- pydra/tasks/fsl/bet/bet.py | 57 +++++++++++++++++++++++++++++++++++++- 1 file changed, 56 insertions(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/bet/bet.py b/pydra/tasks/fsl/bet/bet.py index e33d10d..69dd340 100644 --- a/pydra/tasks/fsl/bet/bet.py +++ b/pydra/tasks/fsl/bet/bet.py @@ -110,6 +110,59 @@ class BETSpec(pydra.specs.ShellSpec): ) +@attrs.define(slots=False, kw_only=True) +class BETVariationsSpec(pydra.specs.ShellSpec): + """Specifications for BET variations.""" + + _xor = { + "with_robust_brain_center_estimation", + "with_eye_and_optic_nerve_cleanup", + "with_bias_field_and_neck_cleanup", + "with_small_fov_in_z", + "with_4d_fmri_data", + } + + with_robust_brain_center_estimation: bool = attrs.field( + metadata={ + "help_string": "iterate BET several times to improve robustness", + "argstr": "-R", + "xor": _xor, + } + ) + + with_eye_and_optic_nerve_cleanup: bool = attrs.field( + metadata={ + "help_string": "remove eye and optic nerve", + "argstr": "-S", + "xor": _xor | {"save_brain_surface_outline"}, + } + ) + + with_bias_field_and_neck_cleanup: bool = attrs.field( + metadata={ + "help_string": "remove bias field and neck", + "argstr": "-B", + "xor": _xor, + } + ) + + with_small_fov_in_z: bool = attrs.field( + metadata={ + "help_string": "improve BET for very small FOV in Z", + "argstr": "-Z", + "xor": _xor, + } + ) + + with_4d_fmri_data: bool = attrs.field( + metadata={ + "help_string": "apply BET to 4D FMRI data", + "argstr": "-F", + "xor": _xor | {"fractional_intensity_threshold"}, + } + ) + + @attrs.define(slots=False, kw_only=True) class BETOutSpec(pydra.specs.ShellOutSpec): """Output specifications for BET.""" @@ -153,6 +206,8 @@ class BET(pydra.engine.ShellCommandTask): executable = "bet" - input_spec = pydra.specs.SpecInfo(name="BETInput", bases=(BETSpec,)) + input_spec = pydra.specs.SpecInfo( + name="BETInput", bases=(BETSpec, BETVariationsSpec) + ) output_spec = pydra.specs.SpecInfo(name="BETOutput", bases=(BETOutSpec,)) From e602e06008de3dbd7c2b2c5a36a8c742c3dad692 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 115/224] NEW: Add task definition for SUSAN --- pydra/tasks/fsl/__init__.py | 2 + pydra/tasks/fsl/susan.py | 106 ++++++++++++++++++++++++++++++++++++ 2 files changed, 108 insertions(+) create mode 100644 pydra/tasks/fsl/susan.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index c5f20e3..8f38253 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -13,6 +13,7 @@ "FSLMerge", "FSLReorient2Std", "FSLROI", + "SUSAN", "fslmaths", ] @@ -23,6 +24,7 @@ from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI +from .susan import SUSAN __all__ += bet.__all__ __all__ += flirt.__all__ diff --git a/pydra/tasks/fsl/susan.py b/pydra/tasks/fsl/susan.py new file mode 100644 index 0000000..3e8eb01 --- /dev/null +++ b/pydra/tasks/fsl/susan.py @@ -0,0 +1,106 @@ +""" +SUSAN +===== + +Structure-preserving noise reduction. + +Examples +-------- + +>>> task = SUSAN(input_image="input.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'susan input.nii 3.0 3 1 0 .../input_susan.nii' + +>>> task = SUSAN( +... input_image="input.nii", +... output_image="output.nii", +... use_median=False, +... usans=[("usan1.nii", 1.0), ("usan2.nii", -1.0)], +... ) +>>> task.cmdline +'susan input.nii 3.0 3 0 2 usan1.nii 1.0 usan2.nii -1.0 output.nii' +""" + +__all__ = ["SUSAN"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class SUSANSpec(pydra.specs.ShellSpec): + """Specifications for SUSAN.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "position": -1, + "output_file_template": "{input_image}_susan", + } + ) + + brightness_threshold: float = attrs.field( + default=0.0, + metadata={ + "help_string": "brightness threshold", + "argstr": "", + }, + ) + + smoothing: float = attrs.field( + default=3.0, + metadata={ + "help_string": "spatial smoothing in millimeters", + "argstr": "", + }, + ) + + dimensionality: int = attrs.field( + default=3, + metadata={ + "help_string": "perform smoothing in 2D or 3D", + "argstr": "", + "allowed_values": {2, 3}, + }, + ) + + use_median: bool = attrs.field( + default=True, + metadata={ + "help_string": "use median when no neighborhood is found", + "formatter": lambda field: f"{int(field)}", + }, + ) + + # TODO: Replace with factory=list. + usans: list = attrs.field( + metadata={ + "help_string": "find smoothing area from secondary images (up to 2)", + "formatter": lambda field: ( + " ".join( + [f"{len(field or [])}"] + + [f"{usan} {bt}" for usan, bt in field or []] + ) + ), + }, + ) + + +class SUSAN(pydra.engine.ShellCommandTask): + """Task definition for SUSAN.""" + + executable = "susan" + + input_spec = pydra.specs.SpecInfo(name="SUSANInput", bases=(SUSANSpec,)) From b9e781210da12c9c0f161935ab0d9f6167ad1d44 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 116/224] DOC: Add susan to available interfaces --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0e09245..61acd5e 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ for FMRI, MRI and DTI brain imaging data. - convert_xfm - invert_xfm - fnirt - - fnirt +- susan - utils - fslmaths - fslmerge From cfdf5647098555974ac43360f1ce268c77149857 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 117/224] MNT: Bump version to 0.0.8 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 30df39c..1407e15 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.7" +version = "0.0.8" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 6577fa9c6bb843991d23a26875f0e01b0b2ba8cf Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 118/224] FIX: Reorganize module imports --- pydra/tasks/fsl/__init__.py | 18 +++--------------- pydra/tasks/fsl/bet/__init__.py | 2 -- pydra/tasks/fsl/flirt/__init__.py | 8 -------- 3 files changed, 3 insertions(+), 25 deletions(-) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 8f38253..fbe36d3 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -6,25 +6,13 @@ >>> import pydra.tasks.fsl """ -__all__ = [ - "Eddy", - "FAST", - "FNIRT", - "FSLMerge", - "FSLReorient2Std", - "FSLROI", - "SUSAN", - "fslmaths", -] - -from . import bet, flirt, fslmaths +from . import fslmaths +from .bet import BET, RobustFOV from .eddy import Eddy from .fast import FAST +from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM from .fnirt import FNIRT from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI from .susan import SUSAN - -__all__ += bet.__all__ -__all__ += flirt.__all__ diff --git a/pydra/tasks/fsl/bet/__init__.py b/pydra/tasks/fsl/bet/__init__.py index 003365b..b721e03 100644 --- a/pydra/tasks/fsl/bet/__init__.py +++ b/pydra/tasks/fsl/bet/__init__.py @@ -1,4 +1,2 @@ -__all__ = ["BET", "RobustFOV"] - from .bet import BET from .robustfov import RobustFOV diff --git a/pydra/tasks/fsl/flirt/__init__.py b/pydra/tasks/fsl/flirt/__init__.py index 1024e23..ba14c83 100644 --- a/pydra/tasks/fsl/flirt/__init__.py +++ b/pydra/tasks/fsl/flirt/__init__.py @@ -1,11 +1,3 @@ -__all__ = [ - "FLIRT", - "ApplyXFM", - "ConcatXFM", - "ConvertXFM", - "InvertXFM", -] - from .apply_xfm import ApplyXFM from .concat_xfm import ConcatXFM from .convert_xfm import ConvertXFM From a542fb1efaeca32d3caf588b4d8ba01f5d8b84b0 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 119/224] MNT: Bump version to 0.0.9 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1407e15..7732931 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.8" +version = "0.0.9" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 2f8263c373495e74edb11ce613c22f061f85008b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 120/224] NEW: Add task definition for applywarp --- pydra/tasks/fsl/__init__.py | 2 +- pydra/tasks/fsl/fnirt/__init__.py | 2 + pydra/tasks/fsl/fnirt/applywarp.py | 156 +++++++++++++++++++++++++++ pydra/tasks/fsl/{ => fnirt}/fnirt.py | 0 4 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/fnirt/__init__.py create mode 100644 pydra/tasks/fsl/fnirt/applywarp.py rename pydra/tasks/fsl/{ => fnirt}/fnirt.py (100%) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index fbe36d3..5545b83 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -11,7 +11,7 @@ from .eddy import Eddy from .fast import FAST from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM -from .fnirt import FNIRT +from .fnirt import FNIRT, ApplyWarp from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI diff --git a/pydra/tasks/fsl/fnirt/__init__.py b/pydra/tasks/fsl/fnirt/__init__.py new file mode 100644 index 0000000..83e481b --- /dev/null +++ b/pydra/tasks/fsl/fnirt/__init__.py @@ -0,0 +1,2 @@ +from .applywarp import ApplyWarp +from .fnirt import FNIRT diff --git a/pydra/tasks/fsl/fnirt/applywarp.py b/pydra/tasks/fsl/fnirt/applywarp.py new file mode 100644 index 0000000..ca216b8 --- /dev/null +++ b/pydra/tasks/fsl/fnirt/applywarp.py @@ -0,0 +1,156 @@ +""" +ApplyWarp +========= + +Examples +-------- + +>>> task = ApplyWarp( +... input_image="invol.nii", +... reference_image="refvol.nii", +... warp_image="warpvol.nii", +... warp_field_as="abs", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'applywarp --in invol.nii --ref refvol.nii --out .../invol_warped.nii \ +--warp warpvol.nii --abs --interp trilinear' + +>>> task = ApplyWarp( +... input_image="invol.nii", +... reference_image="refvol.nii", +... output_image="outvol.nii", +... use_sqform=True, +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'applywarp --in invol.nii --ref refvol.nii --out outvol.nii \ +--interp trilinear --usesqform' +""" + +__all__ = ["ApplyWarp"] + +import os +import typing as ty + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class ApplyWarpSpec(pydra.specs.ShellSpec): + """Specifications for applywarp.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image to warp", + "mandatory": True, + "argstr": "--in", + } + ) + + reference_image: os.PathLike = attrs.field( + metadata={ + "help_string": "reference image", + "mandatory": True, + "argstr": "--ref", + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output warped image", + "argstr": "--out", + "output_file_template": "{input_image}_warped", + } + ) + + warp_image: os.PathLike = attrs.field( + metadata={ + "help_string": "deformation field or coefficients", + "argstr": "--warp", + } + ) + + warp_field_as: str = attrs.field( + metadata={ + "help_string": "treat deformation field as absolute (abs) or relative (rel)", + "argstr": "--{warp_field_as}", + "allowed_values": {"abs", "rel"}, + "requires": {"warp_image"}, + } + ) + + output_datatype: str = attrs.field( + metadata={ + "help_string": "force output datatype", + "argstr": "--datatype", + "allowed_values": {"char", "short", "int", "float", "double"}, + } + ) + + supersampling_level: ty.Union[str, int] = attrs.field( + metadata={ + "help_string": "level of intermediate supersampling", + "argstr": "--super --superlevel", + } + ) + + pre_affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "pre-affine matrix", + "argstr": "--premat", + } + ) + + post_affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "post-affine matrix", + "argstr": "--postmat", + } + ) + + reference_mask: os.PathLike = attrs.field( + metadata={ + "help_string": "mask image in reference space", + "argstr": "--mask", + } + ) + + interpolation: str = attrs.field( + default="trilinear", + metadata={ + "help_string": "interpolation method", + "argstr": "--interp", + "allowed_values": {"nn", "trilinear", "sinc", "spline"}, + }, + ) + + padding_size: float = attrs.field( + metadata={ + "help_string": "padding size in voxels", + "argstr": "--paddingsize", + } + ) + + use_sqform: bool = attrs.field( + metadata={ + "help_string": "use sform and qform from reference and input images", + "argstr": "--usesqform", + "requires": {"input_image", "reference_image"}, + } + ) + + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "--verbose", + } + ) + + +class ApplyWarp(pydra.engine.ShellCommandTask): + """Task definition for applywarp.""" + + executable = "applywarp" + + input_spec = pydra.specs.SpecInfo(name="ApplyWarpInput", bases=(ApplyWarpSpec,)) diff --git a/pydra/tasks/fsl/fnirt.py b/pydra/tasks/fsl/fnirt/fnirt.py similarity index 100% rename from pydra/tasks/fsl/fnirt.py rename to pydra/tasks/fsl/fnirt/fnirt.py From 368827768dfff52bb7fb147a98b270ba399e5350 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 121/224] NEW: Add task definition for convertwarp --- pydra/tasks/fsl/__init__.py | 2 +- pydra/tasks/fsl/fnirt/__init__.py | 1 + pydra/tasks/fsl/fnirt/convertwarp.py | 179 +++++++++++++++++++++++++++ 3 files changed, 181 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/fnirt/convertwarp.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 5545b83..b5260c8 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -11,7 +11,7 @@ from .eddy import Eddy from .fast import FAST from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM -from .fnirt import FNIRT, ApplyWarp +from .fnirt import FNIRT, ApplyWarp, ConvertWarp from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI diff --git a/pydra/tasks/fsl/fnirt/__init__.py b/pydra/tasks/fsl/fnirt/__init__.py index 83e481b..f83d526 100644 --- a/pydra/tasks/fsl/fnirt/__init__.py +++ b/pydra/tasks/fsl/fnirt/__init__.py @@ -1,2 +1,3 @@ from .applywarp import ApplyWarp +from .convertwarp import ConvertWarp from .fnirt import FNIRT diff --git a/pydra/tasks/fsl/fnirt/convertwarp.py b/pydra/tasks/fsl/fnirt/convertwarp.py new file mode 100644 index 0000000..a0358b4 --- /dev/null +++ b/pydra/tasks/fsl/fnirt/convertwarp.py @@ -0,0 +1,179 @@ +""" +ConvertWarp +=========== + +Examples +-------- + +>>> task = ConvertWarp( +... reference_image="refvol.nii", +... pre_affine_matrix="affine.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'convertwarp --ref refvol.nii --out .../refvol_warp.nii --premat affine.mat \ +--jacobian .../refvol_jac.nii' + +>>> task = ConvertWarp( +... reference_image="refvol.nii", +... output_warp_image="outwarp.nii", +... pre_affine_matrix="pre.mat", +... warp_image1="warp1.nii", +... warp_image2="warp2.nii", +... post_affine_matrix="post.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'convertwarp --ref refvol.nii --out outwarp.nii --premat pre.mat \ +--warp1 warp1.nii --warp2 warp2.nii --postmat post.mat --jacobian \ +.../refvol_jac.nii' + +>>> task = ConvertWarp( +... reference_image="refvol.nii", +... shiftmap_image="shiftmap.nii", +... shift_direction="y-", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'convertwarp --ref refvol.nii --out .../refvol_warp.nii --shiftmap shiftmap.nii \ +--shiftdir y- --jacobian .../refvol_jac.nii' +""" + +__all__ = ["ConvertWarp"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class ConvertWarpSpec(pydra.specs.ShellSpec): + """Specifications for convertwrap.""" + + reference_image: os.PathLike = attrs.field( + metadata={ + "help_string": "reference image", + "mandatory": True, + "argstr": "--ref", + } + ) + + output_warp_image: str = attrs.field( + metadata={ + "help_string": "output deformation field image", + "argstr": "--out", + "output_file_template": "{reference_image}_warp", + } + ) + + pre_affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "pre-affine matrix", + "argstr": "--premat", + } + ) + + warp_image1: os.PathLike = attrs.field( + metadata={ + "help_string": "initial warp following pre-affine", + "argstr": "--warp1", + } + ) + + mid_affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "mid-warp affine matrix", + "argstr": "--midmat", + } + ) + + warp_image2: os.PathLike = attrs.field( + metadata={ + "help_string": "secondary warp preceding post-affine", + "argstr": "--warp2", + } + ) + + post_affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "post-affine matrix", + "argstr": "--postmat", + } + ) + + shiftmap_image: os.PathLike = attrs.field( + metadata={ + "help_string": "shiftmap image (applied first)", + "argstr": "--shiftmap", + } + ) + + shift_direction: str = attrs.field( + metadata={ + "help_string": "direction to apply shiftmap", + "argstr": "--shiftdir", + "requires": {"shiftmap_image"}, + "allowed_values": {"x", "y", "z", "x-", "y-", "z-"}, + } + ) + + output_jacobian_image: str = attrs.field( + metadata={ + "help_string": "constrain the limits of the Jacobian of the deformation field", + "argstr": "--jacobian", + "output_file_template": "{reference_image}_jac", + } + ) + + constrain_jacobian: bool = attrs.field( + metadata={ + "help_string": "constrain the Jacobian of the deformation field", + "argstr": "--constrainj", + } + ) + + min_jacobian: float = attrs.field( + metadata={ + "help_string": "minimum Jacobian value", + "argstr": "--jmin", + "requires": {"constain_jacobian"}, + } + ) + + max_jacobian: float = attrs.field( + metadata={ + "help_string": "maximum Jacobian value", + "argstr": "--jmax", + "requires": {"constain_jacobian"}, + } + ) + + warp_field_as: str = attrs.field( + metadata={ + "help_string": "treat deformation field as absolute (abs) or relative (rel)", + "argstr": "--{input_warp_field_as}", + "allowed_values": {"abs", "rel"}, + } + ) + + output_warp_field_as: str = attrs.field( + metadata={ + "help_string": "save output deformation field as absolute (abs) or relative (rel)", + "argstr": "--{output_warp_field_as}out", + "allowed_values": {"abs", "rel"}, + } + ) + + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "--verbose", + } + ) + + +class ConvertWarp(pydra.engine.ShellCommandTask): + """Task definition for convertwarp.""" + + executable = "convertwarp" + + input_spec = pydra.specs.SpecInfo(name="ConvertWarpInput", bases=(ConvertWarpSpec,)) From 25326e1972cafe017e610c9397ef9f00dbdf3b2c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 122/224] NEW: Add task definition for invwarp --- pydra/tasks/fsl/__init__.py | 2 +- pydra/tasks/fsl/fnirt/__init__.py | 1 + pydra/tasks/fsl/fnirt/invwarp.py | 108 ++++++++++++++++++++++++++++++ 3 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/fnirt/invwarp.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index b5260c8..6873450 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -11,7 +11,7 @@ from .eddy import Eddy from .fast import FAST from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM -from .fnirt import FNIRT, ApplyWarp, ConvertWarp +from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI diff --git a/pydra/tasks/fsl/fnirt/__init__.py b/pydra/tasks/fsl/fnirt/__init__.py index f83d526..92ea466 100644 --- a/pydra/tasks/fsl/fnirt/__init__.py +++ b/pydra/tasks/fsl/fnirt/__init__.py @@ -1,3 +1,4 @@ from .applywarp import ApplyWarp from .convertwarp import ConvertWarp from .fnirt import FNIRT +from .invwarp import InvWarp diff --git a/pydra/tasks/fsl/fnirt/invwarp.py b/pydra/tasks/fsl/fnirt/invwarp.py new file mode 100644 index 0000000..db3597b --- /dev/null +++ b/pydra/tasks/fsl/fnirt/invwarp.py @@ -0,0 +1,108 @@ +""" +InvWarp +======= + +Examples +-------- + +>>> task = InvWarp( +... input_warp_image="warpvol.nii", +... reference_image= "refvol.nii", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'invwarp --warp warpvol.nii --ref refvol.nii --out .../warpvol_invwarp.nii' + +>>> task = InvWarp( +... input_warp_image="warpvol.nii", +... reference_image= "refvol.nii", +... output_warp_image="invwarpvol.nii", +... no_jacobian_constraints=True, +... ) +>>> task.cmdline +'invwarp --warp warpvol.nii --ref refvol.nii --out invwarpvol.nii --noconstraint' + +""" + +__all__ = ["InvWarp"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class InvWarpSpec(pydra.specs.ShellSpec): + """Specifications for invwarp.""" + + input_warp_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input warp image", + "mandatory": True, + "argstr": "--warp", + } + ) + + reference_image: os.PathLike = attrs.field( + metadata={ + "help_string": "reference image", + "mandatory": True, + "argstr": "--ref", + } + ) + + output_warp_image: str = attrs.field( + metadata={ + "help_string": "output inverse warp image", + "argstr": "--out", + "output_file_template": "{input_warp_image}_invwarp", + } + ) + + warp_field_as: str = attrs.field( + metadata={ + "help_string": "treat deformation field as absolute (abs) or relative (rel)", + "argstr": "--{warp_field_as}", + "allowed_values": {"abs", "rel"}, + "requires": {"warp_image"}, + } + ) + + no_jacobian_constraints: bool = attrs.field( + metadata={ + "help_string": "do not constrain the Jacobian of the deformation field", + "argstr": "--noconstraint", + } + ) + + min_jacobian: float = attrs.field( + metadata={ + "help_string": "minimum Jacobian value", + "argstr": "--jmin", + "xor": {"no_jacobian_constraints"}, + } + ) + + max_jacobian: float = attrs.field( + metadata={ + "help_string": "maximum Jacobian value", + "argstr": "--jmax", + "xor": {"no_jacobian_constraints"}, + } + ) + + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "--verbose", + } + ) + + +class InvWarp(pydra.engine.ShellCommandTask): + """Task definition for invwarp.""" + + executable = "invwarp" + + input_spec = pydra.specs.SpecInfo(name="InvWarpInput", bases=(InvWarpSpec,)) From 8655e0c7a3c8717f34a2b26dde41b96101440f41 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 123/224] DOC: Update list of available tasks --- README.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 61acd5e..4b8880f 100644 --- a/README.md +++ b/README.md @@ -18,12 +18,12 @@ for FMRI, MRI and DTI brain imaging data. **Table of contents** -- [Available interfaces](#available-interfaces) +- [Available tasks](#available-tasks) - [Installation](#installation) - [Development](#development) - [License](#license) -## Available interfaces +## Available tasks - bet - bet @@ -37,6 +37,10 @@ for FMRI, MRI and DTI brain imaging data. - convert_xfm - invert_xfm - fnirt + - fnirt + - applywarp + - convertwarp + - invwarp - susan - utils - fslmaths From c220538b926ade76eef7c166b98d1e8a6f5ab123 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 124/224] REF: Use consistent naming for xfm utils --- pydra/tasks/fsl/flirt/__init__.py | 8 ++++---- pydra/tasks/fsl/flirt/{apply_xfm.py => applyxfm.py} | 0 pydra/tasks/fsl/flirt/{concat_xfm.py => concatxfm.py} | 2 +- pydra/tasks/fsl/flirt/{convert_xfm.py => convertxfm.py} | 0 pydra/tasks/fsl/flirt/{invert_xfm.py => invertxfm.py} | 2 +- 5 files changed, 6 insertions(+), 6 deletions(-) rename pydra/tasks/fsl/flirt/{apply_xfm.py => applyxfm.py} (100%) rename pydra/tasks/fsl/flirt/{concat_xfm.py => concatxfm.py} (93%) rename pydra/tasks/fsl/flirt/{convert_xfm.py => convertxfm.py} (100%) rename pydra/tasks/fsl/flirt/{invert_xfm.py => invertxfm.py} (92%) diff --git a/pydra/tasks/fsl/flirt/__init__.py b/pydra/tasks/fsl/flirt/__init__.py index ba14c83..fed9a64 100644 --- a/pydra/tasks/fsl/flirt/__init__.py +++ b/pydra/tasks/fsl/flirt/__init__.py @@ -1,5 +1,5 @@ -from .apply_xfm import ApplyXFM -from .concat_xfm import ConcatXFM -from .convert_xfm import ConvertXFM +from .applyxfm import ApplyXFM +from .concatxfm import ConcatXFM +from .convertxfm import ConvertXFM from .flirt import FLIRT -from .invert_xfm import InvertXFM +from .invertxfm import InvertXFM diff --git a/pydra/tasks/fsl/flirt/apply_xfm.py b/pydra/tasks/fsl/flirt/applyxfm.py similarity index 100% rename from pydra/tasks/fsl/flirt/apply_xfm.py rename to pydra/tasks/fsl/flirt/applyxfm.py diff --git a/pydra/tasks/fsl/flirt/concat_xfm.py b/pydra/tasks/fsl/flirt/concatxfm.py similarity index 93% rename from pydra/tasks/fsl/flirt/concat_xfm.py rename to pydra/tasks/fsl/flirt/concatxfm.py index 36126b1..9f800c9 100644 --- a/pydra/tasks/fsl/flirt/concat_xfm.py +++ b/pydra/tasks/fsl/flirt/concatxfm.py @@ -22,7 +22,7 @@ import pydra -from .convert_xfm import BaseConvertXFMSpec, ConvertXFM +from .convertxfm import BaseConvertXFMSpec, ConvertXFM @attrs.define(slots=False, kw_only=True) diff --git a/pydra/tasks/fsl/flirt/convert_xfm.py b/pydra/tasks/fsl/flirt/convertxfm.py similarity index 100% rename from pydra/tasks/fsl/flirt/convert_xfm.py rename to pydra/tasks/fsl/flirt/convertxfm.py diff --git a/pydra/tasks/fsl/flirt/invert_xfm.py b/pydra/tasks/fsl/flirt/invertxfm.py similarity index 92% rename from pydra/tasks/fsl/flirt/invert_xfm.py rename to pydra/tasks/fsl/flirt/invertxfm.py index a1c8a1b..0b71ab8 100644 --- a/pydra/tasks/fsl/flirt/invert_xfm.py +++ b/pydra/tasks/fsl/flirt/invertxfm.py @@ -16,7 +16,7 @@ import pydra -from .convert_xfm import BaseConvertXFMSpec, ConvertXFM +from .convertxfm import BaseConvertXFMSpec, ConvertXFM @attrs.define(slots=False, kw_only=True) From 635f4611fe18e7c253e3c7e5e03b0285792f3cdd Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 125/224] DOC: Display available tasks in a table --- README.md | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 4b8880f..3798e17 100644 --- a/README.md +++ b/README.md @@ -25,28 +25,15 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -- bet - - bet - - robustfov -- eddy -- fast -- flirt - - flirt - - apply_xfm - - concat_xfm - - convert_xfm - - invert_xfm -- fnirt - - fnirt - - applywarp - - convertwarp - - invwarp -- susan -- utils - - fslmaths - - fslmerge - - fslreorient2std - - fslroi +| Module | Tasks | +|--------|---------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, {Apply,Concat,Convert,Invert}XFM | +| fnirt | FNIRT, {Apply,Convert,Inv}Warp | +| susan | SUSAN | +| utils | fslmaths, fslmerge, fslreorient2std, fslroi | ## Installation From 3ab15b93b2162d2d6b5d97b71b66b404b3958e78 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 126/224] DOC: Improve layout of tasks table --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 3798e17..6d6b4c8 100644 --- a/README.md +++ b/README.md @@ -25,15 +25,15 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|---------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, {Apply,Concat,Convert,Invert}XFM | -| fnirt | FNIRT, {Apply,Convert,Inv}Warp | -| susan | SUSAN | -| utils | fslmaths, fslmerge, fslreorient2std, fslroi | +| Module | Tasks | +|--------|---------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM | +| fnirt | FNIRT, ApplyWarp, ConvertWarp, InvWarp | +| susan | SUSAN | +| utils | fslmaths, fslmerge, fslreorient2std, fslroi | ## Installation From f92af4003eb5d20f61fee76766b4b214088f6bea Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 127/224] MNT: Bump version to 0.0.10 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 7732931..1f6e835 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.9" +version = "0.0.10" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From ae08ff63e091270e519770b4795689681fc0daf9 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 128/224] REF: Move FSL utils to own subpackage --- pydra/tasks/fsl/__init__.py | 5 +---- pydra/tasks/fsl/utils/__init__.py | 4 ++++ pydra/tasks/fsl/{ => utils}/fslmaths.py | 0 pydra/tasks/fsl/{ => utils}/fslmerge.py | 0 pydra/tasks/fsl/{ => utils}/fslreorient2std.py | 0 pydra/tasks/fsl/{ => utils}/fslroi.py | 0 6 files changed, 5 insertions(+), 4 deletions(-) create mode 100644 pydra/tasks/fsl/utils/__init__.py rename pydra/tasks/fsl/{ => utils}/fslmaths.py (100%) rename pydra/tasks/fsl/{ => utils}/fslmerge.py (100%) rename pydra/tasks/fsl/{ => utils}/fslreorient2std.py (100%) rename pydra/tasks/fsl/{ => utils}/fslroi.py (100%) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 6873450..ec112bd 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -6,13 +6,10 @@ >>> import pydra.tasks.fsl """ -from . import fslmaths from .bet import BET, RobustFOV from .eddy import Eddy from .fast import FAST from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp -from .fslmerge import FSLMerge -from .fslreorient2std import FSLReorient2Std -from .fslroi import FSLROI from .susan import SUSAN +from .utils import FSLROI, FSLMerge, FSLReorient2Std, fslmaths diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py new file mode 100644 index 0000000..c234d3f --- /dev/null +++ b/pydra/tasks/fsl/utils/__init__.py @@ -0,0 +1,4 @@ +from . import fslmaths +from .fslmerge import FSLMerge +from .fslreorient2std import FSLReorient2Std +from .fslroi import FSLROI diff --git a/pydra/tasks/fsl/fslmaths.py b/pydra/tasks/fsl/utils/fslmaths.py similarity index 100% rename from pydra/tasks/fsl/fslmaths.py rename to pydra/tasks/fsl/utils/fslmaths.py diff --git a/pydra/tasks/fsl/fslmerge.py b/pydra/tasks/fsl/utils/fslmerge.py similarity index 100% rename from pydra/tasks/fsl/fslmerge.py rename to pydra/tasks/fsl/utils/fslmerge.py diff --git a/pydra/tasks/fsl/fslreorient2std.py b/pydra/tasks/fsl/utils/fslreorient2std.py similarity index 100% rename from pydra/tasks/fsl/fslreorient2std.py rename to pydra/tasks/fsl/utils/fslreorient2std.py diff --git a/pydra/tasks/fsl/fslroi.py b/pydra/tasks/fsl/utils/fslroi.py similarity index 100% rename from pydra/tasks/fsl/fslroi.py rename to pydra/tasks/fsl/utils/fslroi.py From a37f1f529203f48310b24a3ed5aba5cc87b2a634 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 129/224] NEW: Add task definition for FSLInfo --- pydra/tasks/fsl/__init__.py | 2 +- pydra/tasks/fsl/utils/__init__.py | 1 + pydra/tasks/fsl/utils/fslinfo.py | 154 ++++++++++++++++++++++++++++++ 3 files changed, 156 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/utils/fslinfo.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index ec112bd..cc1baa0 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -12,4 +12,4 @@ from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp from .susan import SUSAN -from .utils import FSLROI, FSLMerge, FSLReorient2Std, fslmaths +from .utils import FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, fslmaths diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py index c234d3f..6935ade 100644 --- a/pydra/tasks/fsl/utils/__init__.py +++ b/pydra/tasks/fsl/utils/__init__.py @@ -1,4 +1,5 @@ from . import fslmaths +from .fslinfo import FSLInfo from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI diff --git a/pydra/tasks/fsl/utils/fslinfo.py b/pydra/tasks/fsl/utils/fslinfo.py new file mode 100644 index 0000000..9877289 --- /dev/null +++ b/pydra/tasks/fsl/utils/fslinfo.py @@ -0,0 +1,154 @@ +""" +FSLInfo +======= +""" + +__all__ = ["FSLInfo"] + +import os +import re + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLInfoSpec(pydra.specs.ShellSpec): + """Specifications for fslinfo.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + +@attrs.define(slots=False, kw_only=True) +class FSLInfoOutSpec(pydra.specs.ShellOutSpec): + """Output specifications for fslinfo.""" + + data_type: str = attrs.field( + metadata={ + "help_string": "data type string", + "callable": lambda stdout: re.search(r"data_type\s*(.*)", stdout).group(1), + } + ) + + dim1: int = attrs.field( + metadata={ + "help_string": "array size in 1st dimension", + "callable": lambda stdout: int( + re.search(r"\sdim1\s*(.*)", stdout).group(1) + ), + } + ) + + dim2: int = attrs.field( + metadata={ + "help_string": "array size in 2nd dimension", + "callable": lambda stdout: int( + re.search(r"\sdim2\s*(.*)", stdout).group(1) + ), + } + ) + + dim3: int = attrs.field( + metadata={ + "help_string": "array size in 3rd dimension", + "callable": lambda stdout: int( + re.search(r"\sdim3\s*(.*)", stdout).group(1) + ), + } + ) + + dim4: int = attrs.field( + metadata={ + "help_string": "array size in 4th dimension", + "callable": lambda stdout: int( + re.search(r"\sdim4\s*(.*)", stdout).group(1) + ), + } + ) + + datatype: int = attrs.field( + metadata={ + "help_string": "data type code", + "callable": lambda stdout: int( + re.search(r"datatype\s*(.*)", stdout).group(1) + ), + } + ) + + pixdim1: float = attrs.field( + metadata={ + "help_string": "pixel spacing in 1st dimension", + "callable": lambda stdout: float( + re.search(r"pixdim1\s*(.*)", stdout).group(1) + ), + } + ) + + pixdim2: float = attrs.field( + metadata={ + "help_string": "pixel spacing in 2nd dimension", + "callable": lambda stdout: float( + re.search(r"pixdim2\s*(.*)", stdout).group(1) + ), + } + ) + + pixdim3: float = attrs.field( + metadata={ + "help_string": "pixel spacing in 3rd dimension", + "callable": lambda stdout: float( + re.search(r"pixdim3\s*(.*)", stdout).group(1) + ), + } + ) + + pixedim4: float = attrs.field( + metadata={ + "help_string": "pixel spacing in 4th dimension", + "callable": lambda stdout: float( + re.search(r"pixdim4\s*(.*)", stdout).group(1) + ), + } + ) + + cal_max: float = attrs.field( + metadata={ + "help_string": "maximum display intensity", + "callable": lambda stdout: float( + re.search(r"cal_max\s*(.*)", stdout).group(1) + ), + } + ) + + cal_min: float = attrs.field( + metadata={ + "help_string": "minimum display intensity", + "callable": lambda stdout: float( + re.search(r"cal_min\s*(.*)", stdout).group(1) + ), + } + ) + + file_type: str = attrs.field( + metadata={ + "help_string": "NIfTI file type", + "callable": lambda stdout: re.search(r"file_type\s*(.*)", stdout).group(1), + } + ) + + +class FSLInfo(pydra.engine.ShellCommandTask): + """ """ + + executable = "fslinfo" + + input_spec = pydra.specs.SpecInfo(name="FSLInfoInput", bases=(FSLInfoSpec,)) + + output_spec = pydra.specs.SpecInfo(name="FSLInfoOutput", bases=(FSLInfoOutSpec,)) From 79c5c35dd018420f07eadba6d0459b4aaea9fdef Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 130/224] NEW: Add task definition for fslsplit --- pydra/tasks/fsl/__init__.py | 3 +- pydra/tasks/fsl/utils/__init__.py | 1 + pydra/tasks/fsl/utils/fslsplit.py | 81 +++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/utils/fslsplit.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index cc1baa0..83eb119 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -12,4 +12,5 @@ from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp from .susan import SUSAN -from .utils import FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, fslmaths +from .utils import (FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSplit, + fslmaths) diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py index 6935ade..307fb5f 100644 --- a/pydra/tasks/fsl/utils/__init__.py +++ b/pydra/tasks/fsl/utils/__init__.py @@ -3,3 +3,4 @@ from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI +from .fslsplit import FSLSplit diff --git a/pydra/tasks/fsl/utils/fslsplit.py b/pydra/tasks/fsl/utils/fslsplit.py new file mode 100644 index 0000000..699e002 --- /dev/null +++ b/pydra/tasks/fsl/utils/fslsplit.py @@ -0,0 +1,81 @@ +""" +FSLSplit +======== + +Examples +-------- +>>> task = FSLSplit(input_image="input.nii") +>>> task.cmdline +'fslsplit input.nii vol -t' + +>>> task = FSLSplit( +... input_image="volume.nii", +... output_basename="slice", +... direction="z", +... ) +>>> task.cmdline +'fslsplit volume.nii slice -z' +""" + +__all__ = ["FSLSplit"] + +import os +import pathlib + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLSplitSpec(pydra.specs.ShellSpec): + """Specifications for fslsplit.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + output_basename: str = attrs.field( + default="vol", + metadata={ + "help_string": "output basename", + "argstr": "", + }, + ) + + direction: str = attrs.field( + default="t", + metadata={ + "help_string": "split direction (x, y, z or t)", + "argstr": "-{direction}", + "allowed_values": {"x", "y", "z", "t"}, + }, + ) + + +@attrs.define(slots=False, kw_only=True) +class FSLSplitOutSpec(pydra.specs.ShellOutSpec): + """Output specifications for fslsplit.""" + + output_images: pydra.specs.MultiOutputFile = attrs.field( + metadata={ + "help_string": "output splitted images", + "callable": lambda output_basename: ( + sorted(pathlib.Path(pathlib.Path.cwd()).glob(f"{output_basename}*.*")) + ), + } + ) + + +class FSLSplit(pydra.engine.ShellCommandTask): + """Task definition for fslsplit.""" + + executable = "fslsplit" + + input_spec = pydra.specs.SpecInfo(name="FSLSplitInput", bases=(FSLSplitSpec,)) + + output_spec = pydra.specs.SpecInfo(name="FSLSplitOutput", bases=(FSLSplitOutSpec,)) From 4dcefd616be44b93a69cec854b3d60760d45b16a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 131/224] DOC: Update available tasks --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 6d6b4c8..6ff71f2 100644 --- a/README.md +++ b/README.md @@ -25,15 +25,15 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|---------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM | -| fnirt | FNIRT, ApplyWarp, ConvertWarp, InvWarp | -| susan | SUSAN | -| utils | fslmaths, fslmerge, fslreorient2std, fslroi | +| Module | Tasks | +|--------|----------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM | +| fnirt | FNIRT, ApplyWarp, ConvertWarp, InvWarp | +| susan | SUSAN | +| utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSplit | ## Installation From 19a84cc314d55d0d04f023686447466408ad5a66 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:30:53 +1100 Subject: [PATCH 132/224] MNT: Bump version to 0.0.11 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1f6e835..c3cc055 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.10" +version = "0.0.11" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 8515173179a0ed2d3850b404eedb91960fd3dfb5 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 133/224] MNT: Enable black profile for isort --- pyproject.toml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index c3cc055..4ee3095 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -93,6 +93,10 @@ parallel = true [tool.coverage.report] +[tool.isort] +profile = "black" + +[tool.pytest.ini_options] minversion = "6.0" # addopts = ["--doctest-modules", "--doctest-continue-on-failure"] testpaths = ["pydra"] From ac22579f1edb6a94eec950f788d58abc2f4f875b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 134/224] NEW: Add task definition for fslslice --- pydra/tasks/fsl/__init__.py | 11 ++++-- pydra/tasks/fsl/utils/__init__.py | 2 +- pydra/tasks/fsl/utils/fslsplit.py | 56 ++++++++++++++++++++++++------- 3 files changed, 54 insertions(+), 15 deletions(-) diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 83eb119..04efce2 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -12,5 +12,12 @@ from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp from .susan import SUSAN -from .utils import (FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSplit, - fslmaths) +from .utils import ( + FSLROI, + FSLInfo, + FSLMerge, + FSLReorient2Std, + FSLSlice, + FSLSplit, + fslmaths, +) diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py index 307fb5f..59035f3 100644 --- a/pydra/tasks/fsl/utils/__init__.py +++ b/pydra/tasks/fsl/utils/__init__.py @@ -3,4 +3,4 @@ from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI -from .fslsplit import FSLSplit +from .fslsplit import FSLSlice, FSLSplit diff --git a/pydra/tasks/fsl/utils/fslsplit.py b/pydra/tasks/fsl/utils/fslsplit.py index 699e002..1233a37 100644 --- a/pydra/tasks/fsl/utils/fslsplit.py +++ b/pydra/tasks/fsl/utils/fslsplit.py @@ -4,20 +4,19 @@ Examples -------- ->>> task = FSLSplit(input_image="input.nii") +>>> task = FSLSplit(input_image="input.nii.gz") >>> task.cmdline -'fslsplit input.nii vol -t' +'fslsplit input.nii.gz input -t' ->>> task = FSLSplit( +>>> task = FSLSlice( ... input_image="volume.nii", ... output_basename="slice", -... direction="z", ... ) >>> task.cmdline 'fslsplit volume.nii slice -z' """ -__all__ = ["FSLSplit"] +__all__ = ["FSLSplit", "FSLSlice"] import os import pathlib @@ -27,6 +26,16 @@ import pydra +def _get_output_basename(output_basename, input_image): + return output_basename or pathlib.PurePath(input_image).name.split(".", 1)[0] + + +def _get_output_images(output_basename, input_image): + output_basename = _get_output_basename(output_basename, input_image) + + return sorted(pathlib.Path.cwd().glob(f"{output_basename}*.*")) + + @attrs.define(slots=False, kw_only=True) class FSLSplitSpec(pydra.specs.ShellSpec): """Specifications for fslsplit.""" @@ -40,11 +49,10 @@ class FSLSplitSpec(pydra.specs.ShellSpec): ) output_basename: str = attrs.field( - default="vol", metadata={ "help_string": "output basename", - "argstr": "", - }, + "formatter": _get_output_basename, + } ) direction: str = attrs.field( @@ -63,10 +71,8 @@ class FSLSplitOutSpec(pydra.specs.ShellOutSpec): output_images: pydra.specs.MultiOutputFile = attrs.field( metadata={ - "help_string": "output splitted images", - "callable": lambda output_basename: ( - sorted(pathlib.Path(pathlib.Path.cwd()).glob(f"{output_basename}*.*")) - ), + "help_string": "output images", + "callable": _get_output_images, } ) @@ -79,3 +85,29 @@ class FSLSplit(pydra.engine.ShellCommandTask): input_spec = pydra.specs.SpecInfo(name="FSLSplitInput", bases=(FSLSplitSpec,)) output_spec = pydra.specs.SpecInfo(name="FSLSplitOutput", bases=(FSLSplitOutSpec,)) + + +@attrs.define(slots=False, kw_only=True) +class FSLSliceSpec(FSLSplitSpec): + """Specifications for fslslice.""" + + direction: str = attrs.field( + default="z", + metadata={ + "help_string": "split direction (z)", + "argstr": "-{direction}", + "allowed_values": {"z"}, + }, + ) + + +class FSLSliceOutSpec(FSLSplitOutSpec): + """Output specifications for fslslice.""" + + +class FSLSlice(FSLSplit): + """Task definition for fslslice.""" + + input_spec = pydra.specs.SpecInfo(name="FSLSliceInput", bases=(FSLSliceSpec,)) + + output_spec = pydra.specs.SpecInfo(name="FSLSliceOutput", bases=(FSLSliceOutSpec,)) From b1147bed688b3a2dc6d9513c18f2a436017a698e Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 135/224] NEW: Add task definition for fugue --- README.md | 1 + pydra/tasks/fsl/__init__.py | 1 + pydra/tasks/fsl/fugue.py | 242 ++++++++++++++++++++++++++++++++++++ 3 files changed, 244 insertions(+) create mode 100644 pydra/tasks/fsl/fugue.py diff --git a/README.md b/README.md index 6ff71f2..d41d23c 100644 --- a/README.md +++ b/README.md @@ -32,6 +32,7 @@ for FMRI, MRI and DTI brain imaging data. | fast | FAST | | flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM | | fnirt | FNIRT, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | | susan | SUSAN | | utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSplit | diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 04efce2..2f3e08d 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -11,6 +11,7 @@ from .fast import FAST from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp +from .fugue import FUGUE from .susan import SUSAN from .utils import ( FSLROI, diff --git a/pydra/tasks/fsl/fugue.py b/pydra/tasks/fsl/fugue.py new file mode 100644 index 0000000..2910b44 --- /dev/null +++ b/pydra/tasks/fsl/fugue.py @@ -0,0 +1,242 @@ +""" +FUGUE +===== + +>>> task = FUGUE( +... input_image="epi.nii", +... input_phasemap="phasemap.nii", +... dwell_to_asym_time_ratio=0.3, +... output_inverse_warpfield="unwarped.nii", +... ) +>>> task.cmdline +'fugue --in epi.nii --unwarp unwarped.nii --phasemap phasemap.nii --dwelltoasym 0.3' + +>>> task = FUGUE( +... input_image="unwarped.nii", +... input_phasemap="phasemap.nii", +... dwell_to_asym_time_ratio=0.3, +... output_warpfield="warped.nii", +... ) +>>> task.cmdline +'fugue --in unwarped.nii --warp warped.nii --phasemap phasemap.nii --dwelltoasym 0.3' + +>>> task = FUGUE( +... input_phasemap="phasemap.nii", +... output_shiftmap="shiftmap.nii", +... ) +>>> task.cmdline +'fugue --phasemap phasemap.nii --saveshift shiftmap.nii' +""" + +__all__ = ["FUGUE"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FUGUESpec(pydra.specs.ShellSpec): + """Specifications for fugue.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "argstr": "--in", + } + ) + + output_warpfield: os.PathLike = attrs.field( + metadata={ + "help_string": "output warpfield image", + "argstr": "--warp", + } + ) + + output_inverse_warpfield: os.PathLike = attrs.field( + metadata={ + "help_string": "output inverse warpfield image", + "argstr": "--unwarp", + } + ) + + input_phasemap: os.PathLike = attrs.field( + metadata={ + "help_string": "input phase image", + "argstr": "--phasemap", + } + ) + + dwell_to_asym_time_ratio: float = attrs.field( + metadata={ + "help_string": "dwell to asymmetric echo time ratio", + "argstr": "--dwelltoasym", + } + ) + + dwell_time: float = attrs.field( + metadata={ + "help_string": "EPI dwell time in seconds", + "argstr": "--dwell", + } + ) + + asym_time: float = attrs.field( + metadata={ + "help_string": "asymmetric spin echo time in seconds", + "argstr": "--asym", + } + ) + + input_fieldmap: os.PathLike = attrs.field( + metadata={ + "help_string": "load fieldmap image", + "argstr": "--loadfmap", + } + ) + + output_fieldmap: os.PathLike = attrs.field( + metadata={ + "help_string": "save fieldmap image", + "argstr": "--savefmap", + } + ) + + input_shiftmap: os.PathLike = attrs.field( + metadata={ + "help_string": "load pixel shift image", + "argstr": "--loadshift", + } + ) + + output_shiftmap: os.PathLike = attrs.field( + metadata={ + "help_string": "save pixel shift image", + "argstr": "--saveshift", + } + ) + + sigma2d: float = attrs.field( + metadata={ + "help_string": "apply 2D Gaussian smoothing of sigma in millimeter", + "argstr": "--smooth2", + } + ) + + sigma3d: float = attrs.field( + metadata={ + "help_string": "apply 3D Gaussian smoothing of sigma in millimeter", + "argstr": "--smooth3", + } + ) + + polynomial_order: int = attrs.field( + metadata={ + "help_string": "order of polynomial fitting", + "argstr": "--poly", + } + ) + + sinusoidal_order: int = attrs.field( + metadata={ + "help_string": "order of sinusoidal (Fourier) fitting", + "argstr": "--fourier", + } + ) + + direction: str = attrs.field( + metadata={ + "help_string": "unwarping direction", + "argstr": "--unwarpdir", + "allowed_values": {"x", "y", "z", "x-", "y-", "z-"}, + } + ) + + input_mask: os.PathLike = attrs.field( + metadata={ + "help_string": "mask for input image", + "argstr": "--mask", + } + ) + + output_unmasked_fieldmap: os.PathLike = attrs.field( + metadata={ + "help_string": "save unmasked fieldmap", + "argstr": "--unmaskfmap", + "requires": {"output_fieldmap"}, + } + ) + + output_unmasked_shiftmap: os.PathLike = attrs.field( + metadata={ + "help_string": "save unmasked shiftmap", + "argstr": "--unmaskshift", + "requires": {"output_shiftmap"}, + } + ) + + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "--verbose", + } + ) + + +@attrs.define(slots=False, kw_only=True) +class FUGUEOutSpec(pydra.specs.ShellOutSpec): + """Output specifications for fugue.""" + + output_warpfield: str = attrs.field( + metadata={ + "help_string": "output warpfield image", + "output_file_template": "{output_warpfield}", + } + ) + + output_inverse_warpfield: str = attrs.field( + metadata={ + "help_string": "output inverse warpfield image", + "output_file_template": "{output_inverse_warpfield}", + } + ) + + output_fieldmap: str = attrs.field( + metadata={ + "help_string": "output fieldmap image", + "output_file_template": "{output_fieldmap}", + } + ) + + output_shiftmap: str = attrs.field( + metadata={ + "help_string": "output shiftmap image", + "output_file_template": "{output_shiftmap}", + } + ) + + output_unmasked_fieldmap: str = attrs.field( + metadata={ + "help_string": "output unmasked fieldmap", + "output_file_template": "{output_unmasked_fieldmap}", + } + ) + + output_unmasked_shiftmap: str = attrs.field( + metadata={ + "help_string": "output unmasked shiftmap", + "output_file_template": "{output_unmasked_shiftmap}", + } + ) + + +class FUGUE(pydra.engine.ShellCommandTask): + """Task definition for fugue.""" + + executable = "fugue" + + input_spec = pydra.specs.SpecInfo(name="FUGUEInput", bases=(FUGUESpec,)) + + output_spec = pydra.specs.SpecInfo(name="FUGUEOutput", bases=(FUGUEOutSpec,)) From fd5dcbd1b34741995d337c6257a66f945deed6cd Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 136/224] NEW: Add task definition for fnirtfileutils --- pydra/tasks/fsl/__init__.py | 2 +- pydra/tasks/fsl/fnirt/__init__.py | 1 + pydra/tasks/fsl/fnirt/fnirtfileutils.py | 126 ++++++++++++++++++++++++ 3 files changed, 128 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/fnirt/fnirtfileutils.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 2f3e08d..bac4c20 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -10,7 +10,7 @@ from .eddy import Eddy from .fast import FAST from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM -from .fnirt import FNIRT, ApplyWarp, ConvertWarp, InvWarp +from .fnirt import FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp from .fugue import FUGUE from .susan import SUSAN from .utils import ( diff --git a/pydra/tasks/fsl/fnirt/__init__.py b/pydra/tasks/fsl/fnirt/__init__.py index 92ea466..6424d60 100644 --- a/pydra/tasks/fsl/fnirt/__init__.py +++ b/pydra/tasks/fsl/fnirt/__init__.py @@ -1,4 +1,5 @@ from .applywarp import ApplyWarp from .convertwarp import ConvertWarp from .fnirt import FNIRT +from .fnirtfileutils import FNIRTFileUtils from .invwarp import InvWarp diff --git a/pydra/tasks/fsl/fnirt/fnirtfileutils.py b/pydra/tasks/fsl/fnirt/fnirtfileutils.py new file mode 100644 index 0000000..2e0b172 --- /dev/null +++ b/pydra/tasks/fsl/fnirt/fnirtfileutils.py @@ -0,0 +1,126 @@ +""" +FNIRTFileUtils +============== + +Examples +-------- + +>>> task = FNIRTFileUtils( +... input_image="input.nii", +... reference_image="reference.nii", +... output_image="output.nii", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fnirtfileutils --in input.nii --ref reference.nii --out output.nii \ +--outformat field ...' + +>>> task = FNIRTFileUtils( +... input_image="input.nii", +... reference_image="reference.nii", +... output_jacobian_image="jacobian.nii", +... with_affine_transform=True, +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fnirtfileutils --in input.nii --ref reference.nii ... --jac jacobian.nii \ +... --withaff' +""" + +__all__ = ["FNIRTFileUtils"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FNIRTFileUtilsSpec(pydra.specs.ShellSpec): + """Specifications for fnirtfileutils.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image with FNIRT coefficients", + "argstr": "--in", + } + ) + + reference_image: os.PathLike = attrs.field( + metadata={ + "help_string": "reference image", + "argstr": "--ref", + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output field or coefficient image", + "argstr": "--out", + "output_file_template": "{input_image}_warp", + } + ) + + output_format: str = attrs.field( + default="field", + metadata={ + "help_string": "output format (field or spline)", + "argstr": "--outformat", + "allowed_values": {"field", "spline"}, + }, + ) + + warp_resolution: float = attrs.field( + metadata={ + "help_string": "warp resolution in millimeters", + "argstr": "--warpres", + # "requires": {("output_format", "spline")}, # TODO + } + ) + + knot_spacing: float = attrs.field( + metadata={ + "help_string": "knot spacing in voxels", + "argstr": "--knotspace", + # "requires": {("output_format", "spline")}, # TODO + } + ) + + output_jacobian_image: str = attrs.field( + metadata={ + "help_string": "output jacobian determinant map", + "argstr": "--jac", + "output_file_template": "{input_image}_jac", + } + ) + + output_jacobian_matrix: str = attrs.field( + metadata={ + "help_string": "output jacobian matrix map", + "argstr": "--matjac", + "output_file_template": "{input_image}_matjac", + } + ) + + with_affine_transform: bool = attrs.field( + metadata={ + "help_string": "include affine transform in field and jacobian images", + "argstr": "--withaff", + } + ) + + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "--verbose", + } + ) + + +class FNIRTFileUtils(pydra.engine.ShellCommandTask): + """Task definition for fnirtfileutils.""" + + executable = "fnirtfileutils" + + input_spec = pydra.specs.SpecInfo( + name="FNIRTFileUtilsInput", bases=(FNIRTFileUtilsSpec,) + ) From 426c77569bd702739f9c7d210beb9f8979b95214 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 137/224] NEW: Add tasks for coordinates transformation --- pydra/tasks/fsl/__init__.py | 11 +++- pydra/tasks/fsl/flirt/__init__.py | 3 ++ pydra/tasks/fsl/flirt/img2imgcoord.py | 65 ++++++++++++++++++++++++ pydra/tasks/fsl/flirt/img2stdcoord.py | 64 ++++++++++++++++++++++++ pydra/tasks/fsl/flirt/specs.py | 72 +++++++++++++++++++++++++++ pydra/tasks/fsl/flirt/std2imgcoord.py | 64 ++++++++++++++++++++++++ 6 files changed, 278 insertions(+), 1 deletion(-) create mode 100644 pydra/tasks/fsl/flirt/img2imgcoord.py create mode 100644 pydra/tasks/fsl/flirt/img2stdcoord.py create mode 100644 pydra/tasks/fsl/flirt/std2imgcoord.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index bac4c20..c0415ee 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -9,7 +9,16 @@ from .bet import BET, RobustFOV from .eddy import Eddy from .fast import FAST -from .flirt import FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM +from .flirt import ( + FLIRT, + ApplyXFM, + ConcatXFM, + ConvertXFM, + Img2ImgCoord, + Img2StdCoord, + InvertXFM, + Std2ImgCoord, +) from .fnirt import FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp from .fugue import FUGUE from .susan import SUSAN diff --git a/pydra/tasks/fsl/flirt/__init__.py b/pydra/tasks/fsl/flirt/__init__.py index fed9a64..472cac4 100644 --- a/pydra/tasks/fsl/flirt/__init__.py +++ b/pydra/tasks/fsl/flirt/__init__.py @@ -2,4 +2,7 @@ from .concatxfm import ConcatXFM from .convertxfm import ConvertXFM from .flirt import FLIRT +from .img2imgcoord import Img2ImgCoord +from .img2stdcoord import Img2StdCoord from .invertxfm import InvertXFM +from .std2imgcoord import Std2ImgCoord diff --git a/pydra/tasks/fsl/flirt/img2imgcoord.py b/pydra/tasks/fsl/flirt/img2imgcoord.py new file mode 100644 index 0000000..5bd4e38 --- /dev/null +++ b/pydra/tasks/fsl/flirt/img2imgcoord.py @@ -0,0 +1,65 @@ +""" +Img2ImgCoord +============ + +Examples +-------- + +>>> task = Img2ImgCoord( +... input_coordinates="coordinates.txt", +... source_image="source.nii", +... destination_image="target.nii", +... affine_matrix="affine.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'img2imgcoord -xfm affine.mat ... -src source.nii -dest target.nii coordinates.txt' +""" + +__all__ = ["Img2ImgCoord"] + +import os + +import attrs + +import pydra + +from . import specs + + +@attrs.define(slots=False, kw_only=True) +class Img2ImgCoordSpec(specs.BaseCoordSpec): + """Specifications for img2imgcoord.""" + + source_image: os.PathLike = attrs.field( + metadata={ + "help_string": "source image", + "mandatory": True, + "argstr": "-src", + } + ) + + destination_image: os.PathLike = attrs.field( + metadata={ + "help_string": "destination image", + "mandatory": True, + "argstr": "-dest", + } + ) + + +class Img2ImgCoordOutSpec(specs.CoordOutSpec): + """Output specifications for img2imgcoord.""" + + +class Img2ImgCoord(pydra.engine.ShellCommandTask): + """Task definition for img2imgcoord.""" + + executable = "img2imgcoord" + + input_spec = pydra.specs.SpecInfo( + name="Img2ImgCoordInput", bases=(Img2ImgCoordSpec, specs.VerboseSpec) + ) + + output_spec = pydra.specs.SpecInfo( + name="Img2ImgCoordOutput", bases=(Img2ImgCoordOutSpec,) + ) diff --git a/pydra/tasks/fsl/flirt/img2stdcoord.py b/pydra/tasks/fsl/flirt/img2stdcoord.py new file mode 100644 index 0000000..8ef252a --- /dev/null +++ b/pydra/tasks/fsl/flirt/img2stdcoord.py @@ -0,0 +1,64 @@ +""" +Img2StdCoord +============ + +Examples +-------- + +>>> task = Img2StdCoord( +... input_coordinates="coordinates.txt", +... input_image="input.nii", +... standard_image="standard.nii", +... affine_matrix="affine.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'img2stdcoord -xfm affine.mat ... -img input.nii -std standard.nii coordinates.txt' +""" + +__all__ = ["Img2StdCoord"] + +import os + +import attrs + +import pydra + +from . import specs + + +@attrs.define(slots=False, kw_only=True) +class Img2StdCoordSpec(specs.BaseCoordSpec): + """Specifications for img2stdcoord.""" + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "-img", + } + ) + + standard_image: os.PathLike = attrs.field( + metadata={ + "help_string": "standard-space image", + "argstr": "-std", + } + ) + + +class Img2StdCoordOutSpec(specs.CoordOutSpec): + """Output specifications for img2stdcoord.""" + + +class Img2StdCoord(pydra.engine.ShellCommandTask): + """Task definition for img2stdcoord.""" + + executable = "img2stdcoord" + + input_spec = pydra.specs.SpecInfo( + name="Img2StdCoordInput", bases=(Img2StdCoordSpec, specs.VerboseSpec) + ) + + output_spec = pydra.specs.SpecInfo( + name="Img2StdCoordOutput", bases=(Img2StdCoordOutSpec,) + ) diff --git a/pydra/tasks/fsl/flirt/specs.py b/pydra/tasks/fsl/flirt/specs.py index 0f32d98..fe1afe6 100644 --- a/pydra/tasks/fsl/flirt/specs.py +++ b/pydra/tasks/fsl/flirt/specs.py @@ -8,6 +8,7 @@ ] import os +import pathlib import typing as ty import attrs @@ -116,3 +117,74 @@ class WeightingSpec(pydra.specs.ShellSpec): "argstr": "-inweight", } ) + + +@attrs.define(slots=False, kw_only=True) +class VerboseSpec(pydra.specs.ShellSpec): + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "-v", + } + ) + + +@attrs.define(slots=False, kw_only=True) +class BaseCoordSpec(pydra.specs.ShellSpec): + input_coordinates: os.PathLike = attrs.field( + metadata={ + "help_string": "input coordinates", + "mandatory": True, + "argstr": "", + "position": -1, + } + ) + + output_coordinates: str = attrs.field( + metadata={ + "help_string": "output coordinates", + "output_file_template": "{input_coordinates}_out", + } + ) + + affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "affine transformation matrix", + "argstr": "-xfm", + } + ) + + input_warpfield: os.PathLike = attrs.field( + metadata={ + "help_string": "input warpfield image", + "argstr": "-warp", + } + ) + + unit: str = attrs.field( + default="vox", + metadata={ + "help_string": "unit of coordinates: voxels (vox) or millimeters (mm)", + "argstr": "-{unit}", + "allowed_values": {"vox", "mm"}, + }, + ) + + +def _get_output_coordinates(output_coordinates: str, stdout): + output_coordinates = pathlib.Path.cwd() / output_coordinates + + with open(output_coordinates, mode="w") as f: + f.write(stdout) + + return output_coordinates + + +@attrs.define(slots=False, kw_only=True) +class CoordOutSpec(pydra.specs.ShellOutSpec): + output_coordinates: os.PathLike = attrs.field( + metadata={ + "help_string": "output coordinates", + "callable": _get_output_coordinates, + } + ) diff --git a/pydra/tasks/fsl/flirt/std2imgcoord.py b/pydra/tasks/fsl/flirt/std2imgcoord.py new file mode 100644 index 0000000..645aa83 --- /dev/null +++ b/pydra/tasks/fsl/flirt/std2imgcoord.py @@ -0,0 +1,64 @@ +""" +Std2ImgCoord +============ + +Examples +-------- + +>>> task = Std2ImgCoord( +... input_coordinates="coordinates.txt", +... input_image="input.nii", +... standard_image="standard.nii", +... affine_matrix="affine.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'std2imgcoord -xfm affine.mat ... -std standard.nii -img input.nii coordinates.txt' +""" + +__all__ = ["Std2ImgCoord"] + +import os + +import attrs + +import pydra + +from . import specs + + +@attrs.define(slots=False, kw_only=True) +class Std2ImgCoordSpec(specs.BaseCoordSpec): + """Specifications for std2imgcoord.""" + + standard_image: os.PathLike = attrs.field( + metadata={ + "help_string": "standard-space image", + "argstr": "-std", + } + ) + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "-img", + } + ) + + +class Std2ImgCoordOutSpec(specs.CoordOutSpec): + """Output specifications for std2imgcoord.""" + + +class Std2ImgCoord(pydra.engine.ShellCommandTask): + """Task definition for std2imgcoord.""" + + executable = "std2imgcoord" + + input_spec = pydra.specs.SpecInfo( + name="Std2ImgCoordSpecInput", bases=(Std2ImgCoordSpec, specs.VerboseSpec) + ) + + output_spec = pydra.specs.SpecInfo( + name="Std2ImgCoordSpecOutput", bases=(Std2ImgCoordOutSpec,) + ) From 56ff4ab22613dcbfe45481bccbc6d1827f83ca47 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 138/224] REF: Introduce standalone verbose spec in fnirt --- pydra/tasks/fsl/fnirt/applywarp.py | 14 ++++++-------- pydra/tasks/fsl/fnirt/convertwarp.py | 14 ++++++-------- pydra/tasks/fsl/fnirt/fnirt.py | 14 ++++++-------- pydra/tasks/fsl/fnirt/fnirtfileutils.py | 12 ++++-------- pydra/tasks/fsl/fnirt/invwarp.py | 14 ++++++-------- pydra/tasks/fsl/fnirt/specs.py | 13 +++++++++++++ 6 files changed, 41 insertions(+), 40 deletions(-) create mode 100644 pydra/tasks/fsl/fnirt/specs.py diff --git a/pydra/tasks/fsl/fnirt/applywarp.py b/pydra/tasks/fsl/fnirt/applywarp.py index ca216b8..b772ddd 100644 --- a/pydra/tasks/fsl/fnirt/applywarp.py +++ b/pydra/tasks/fsl/fnirt/applywarp.py @@ -35,6 +35,8 @@ import pydra +from . import specs + @attrs.define(slots=False, kw_only=True) class ApplyWarpSpec(pydra.specs.ShellSpec): @@ -140,17 +142,13 @@ class ApplyWarpSpec(pydra.specs.ShellSpec): } ) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "--verbose", - } - ) - class ApplyWarp(pydra.engine.ShellCommandTask): """Task definition for applywarp.""" executable = "applywarp" - input_spec = pydra.specs.SpecInfo(name="ApplyWarpInput", bases=(ApplyWarpSpec,)) + input_spec = pydra.specs.SpecInfo( + name="ApplyWarpInput", + bases=(ApplyWarpSpec, specs.VerboseSpec), + ) diff --git a/pydra/tasks/fsl/fnirt/convertwarp.py b/pydra/tasks/fsl/fnirt/convertwarp.py index a0358b4..90c7d46 100644 --- a/pydra/tasks/fsl/fnirt/convertwarp.py +++ b/pydra/tasks/fsl/fnirt/convertwarp.py @@ -44,6 +44,8 @@ import pydra +from . import specs + @attrs.define(slots=False, kw_only=True) class ConvertWarpSpec(pydra.specs.ShellSpec): @@ -163,17 +165,13 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): } ) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "--verbose", - } - ) - class ConvertWarp(pydra.engine.ShellCommandTask): """Task definition for convertwarp.""" executable = "convertwarp" - input_spec = pydra.specs.SpecInfo(name="ConvertWarpInput", bases=(ConvertWarpSpec,)) + input_spec = pydra.specs.SpecInfo( + name="ConvertWarpInput", + bases=(ConvertWarpSpec, specs.VerboseSpec), + ) diff --git a/pydra/tasks/fsl/fnirt/fnirt.py b/pydra/tasks/fsl/fnirt/fnirt.py index bbba5e7..51f1b29 100644 --- a/pydra/tasks/fsl/fnirt/fnirt.py +++ b/pydra/tasks/fsl/fnirt/fnirt.py @@ -26,6 +26,8 @@ import pydra +from . import specs + @attrs.define(slots=False, kw_only=True) class FNIRTSpec(pydra.specs.ShellSpec): @@ -78,17 +80,13 @@ class FNIRTSpec(pydra.specs.ShellSpec): } ) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "-v", - } - ) - class FNIRT(pydra.engine.ShellCommandTask): """Task definition for FNIRT.""" executable = "fnirt" - input_spec = pydra.specs.SpecInfo(name="FNIRTInput", bases=(FNIRTSpec,)) + input_spec = pydra.specs.SpecInfo( + name="FNIRTInput", + bases=(FNIRTSpec, specs.VerboseSpec), + ) diff --git a/pydra/tasks/fsl/fnirt/fnirtfileutils.py b/pydra/tasks/fsl/fnirt/fnirtfileutils.py index 2e0b172..78255b4 100644 --- a/pydra/tasks/fsl/fnirt/fnirtfileutils.py +++ b/pydra/tasks/fsl/fnirt/fnirtfileutils.py @@ -33,6 +33,8 @@ import pydra +from . import specs + @attrs.define(slots=False, kw_only=True) class FNIRTFileUtilsSpec(pydra.specs.ShellSpec): @@ -108,13 +110,6 @@ class FNIRTFileUtilsSpec(pydra.specs.ShellSpec): } ) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "--verbose", - } - ) - class FNIRTFileUtils(pydra.engine.ShellCommandTask): """Task definition for fnirtfileutils.""" @@ -122,5 +117,6 @@ class FNIRTFileUtils(pydra.engine.ShellCommandTask): executable = "fnirtfileutils" input_spec = pydra.specs.SpecInfo( - name="FNIRTFileUtilsInput", bases=(FNIRTFileUtilsSpec,) + name="FNIRTFileUtilsInput", + bases=(FNIRTFileUtilsSpec, specs.VerboseSpec), ) diff --git a/pydra/tasks/fsl/fnirt/invwarp.py b/pydra/tasks/fsl/fnirt/invwarp.py index db3597b..2f4f480 100644 --- a/pydra/tasks/fsl/fnirt/invwarp.py +++ b/pydra/tasks/fsl/fnirt/invwarp.py @@ -31,6 +31,8 @@ import pydra +from . import specs + @attrs.define(slots=False, kw_only=True) class InvWarpSpec(pydra.specs.ShellSpec): @@ -92,17 +94,13 @@ class InvWarpSpec(pydra.specs.ShellSpec): } ) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "--verbose", - } - ) - class InvWarp(pydra.engine.ShellCommandTask): """Task definition for invwarp.""" executable = "invwarp" - input_spec = pydra.specs.SpecInfo(name="InvWarpInput", bases=(InvWarpSpec,)) + input_spec = pydra.specs.SpecInfo( + name="InvWarpInput", + bases=(InvWarpSpec, specs.VerboseSpec), + ) diff --git a/pydra/tasks/fsl/fnirt/specs.py b/pydra/tasks/fsl/fnirt/specs.py new file mode 100644 index 0000000..7598831 --- /dev/null +++ b/pydra/tasks/fsl/fnirt/specs.py @@ -0,0 +1,13 @@ +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class VerboseSpec(pydra.specs.ShellSpec): + verbose: bool = attrs.field( + metadata={ + "help_string": "enable verbose logging", + "argstr": "--verbose", + } + ) From 47dbb3fc61d6d8a69c695cd07c8974838db20b52 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 139/224] ENH: Improve naming consistency of warp utils --- pydra/tasks/fsl/fnirt/applywarp.py | 23 +++++++++--------- pydra/tasks/fsl/fnirt/convertwarp.py | 36 ++++++++++++++-------------- pydra/tasks/fsl/fnirt/invwarp.py | 20 ++++++++-------- 3 files changed, 39 insertions(+), 40 deletions(-) diff --git a/pydra/tasks/fsl/fnirt/applywarp.py b/pydra/tasks/fsl/fnirt/applywarp.py index b772ddd..e83189e 100644 --- a/pydra/tasks/fsl/fnirt/applywarp.py +++ b/pydra/tasks/fsl/fnirt/applywarp.py @@ -8,12 +8,12 @@ >>> task = ApplyWarp( ... input_image="invol.nii", ... reference_image="refvol.nii", -... warp_image="warpvol.nii", -... warp_field_as="abs", +... input_warpfield="warpvol.nii", +... warpfield_as="abs", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'applywarp --in invol.nii --ref refvol.nii --out .../invol_warped.nii \ ---warp warpvol.nii --abs --interp trilinear' +'applywarp --in invol.nii --ref refvol.nii --out ...invol_warped.nii \ +--warp warpvol.nii --abs ...' >>> task = ApplyWarp( ... input_image="invol.nii", @@ -22,8 +22,7 @@ ... use_sqform=True, ... ) >>> task.cmdline # doctest: +ELLIPSIS -'applywarp --in invol.nii --ref refvol.nii --out outvol.nii \ ---interp trilinear --usesqform' +'applywarp --in invol.nii --ref refvol.nii --out outvol.nii ... --usesqform' """ __all__ = ["ApplyWarp"] @@ -44,7 +43,7 @@ class ApplyWarpSpec(pydra.specs.ShellSpec): input_image: os.PathLike = attrs.field( metadata={ - "help_string": "input image to warp", + "help_string": "input image", "mandatory": True, "argstr": "--in", } @@ -60,25 +59,25 @@ class ApplyWarpSpec(pydra.specs.ShellSpec): output_image: str = attrs.field( metadata={ - "help_string": "output warped image", + "help_string": "output image", "argstr": "--out", "output_file_template": "{input_image}_warped", } ) - warp_image: os.PathLike = attrs.field( + input_warpfield: os.PathLike = attrs.field( metadata={ "help_string": "deformation field or coefficients", "argstr": "--warp", } ) - warp_field_as: str = attrs.field( + warpfield_as: str = attrs.field( metadata={ "help_string": "treat deformation field as absolute (abs) or relative (rel)", - "argstr": "--{warp_field_as}", + "argstr": "--{warpfield_as}", "allowed_values": {"abs", "rel"}, - "requires": {"warp_image"}, + "requires": {"input_warpfield"}, } ) diff --git a/pydra/tasks/fsl/fnirt/convertwarp.py b/pydra/tasks/fsl/fnirt/convertwarp.py index 90c7d46..aa0d911 100644 --- a/pydra/tasks/fsl/fnirt/convertwarp.py +++ b/pydra/tasks/fsl/fnirt/convertwarp.py @@ -10,25 +10,25 @@ ... pre_affine_matrix="affine.mat", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'convertwarp --ref refvol.nii --out .../refvol_warp.nii --premat affine.mat \ ---jacobian .../refvol_jac.nii' +'convertwarp --ref refvol.nii --out ...refvol_warp.nii --premat affine.mat \ +--jacobian ...refvol_jac.nii' >>> task = ConvertWarp( ... reference_image="refvol.nii", -... output_warp_image="outwarp.nii", +... output_warpfield="outwarp.nii", ... pre_affine_matrix="pre.mat", -... warp_image1="warp1.nii", -... warp_image2="warp2.nii", +... pre_warpfield="warp1.nii", +... post_warpfield="warp2.nii", ... post_affine_matrix="post.mat", ... ) >>> task.cmdline # doctest: +ELLIPSIS 'convertwarp --ref refvol.nii --out outwarp.nii --premat pre.mat \ --warp1 warp1.nii --warp2 warp2.nii --postmat post.mat --jacobian \ -.../refvol_jac.nii' +...refvol_jac.nii' >>> task = ConvertWarp( ... reference_image="refvol.nii", -... shiftmap_image="shiftmap.nii", +... input_shiftmap="shiftmap.nii", ... shift_direction="y-", ... ) >>> task.cmdline # doctest: +ELLIPSIS @@ -59,7 +59,7 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): } ) - output_warp_image: str = attrs.field( + output_warpfield: str = attrs.field( metadata={ "help_string": "output deformation field image", "argstr": "--out", @@ -74,9 +74,9 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): } ) - warp_image1: os.PathLike = attrs.field( + pre_warpfield: os.PathLike = attrs.field( metadata={ - "help_string": "initial warp following pre-affine", + "help_string": "warp following pre-affine transform", "argstr": "--warp1", } ) @@ -88,9 +88,9 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): } ) - warp_image2: os.PathLike = attrs.field( + post_warpfield: os.PathLike = attrs.field( metadata={ - "help_string": "secondary warp preceding post-affine", + "help_string": "warp preceding post-affine transform", "argstr": "--warp2", } ) @@ -102,7 +102,7 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): } ) - shiftmap_image: os.PathLike = attrs.field( + input_shiftmap: os.PathLike = attrs.field( metadata={ "help_string": "shiftmap image (applied first)", "argstr": "--shiftmap", @@ -113,7 +113,7 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): metadata={ "help_string": "direction to apply shiftmap", "argstr": "--shiftdir", - "requires": {"shiftmap_image"}, + "requires": {"input_shiftmap"}, "allowed_values": {"x", "y", "z", "x-", "y-", "z-"}, } ) @@ -149,18 +149,18 @@ class ConvertWarpSpec(pydra.specs.ShellSpec): } ) - warp_field_as: str = attrs.field( + warpfield_as: str = attrs.field( metadata={ "help_string": "treat deformation field as absolute (abs) or relative (rel)", - "argstr": "--{input_warp_field_as}", + "argstr": "--{warpfield_as}", "allowed_values": {"abs", "rel"}, } ) - output_warp_field_as: str = attrs.field( + output_warpfield_as: str = attrs.field( metadata={ "help_string": "save output deformation field as absolute (abs) or relative (rel)", - "argstr": "--{output_warp_field_as}out", + "argstr": "--{output_warpfield_as}out", "allowed_values": {"abs", "rel"}, } ) diff --git a/pydra/tasks/fsl/fnirt/invwarp.py b/pydra/tasks/fsl/fnirt/invwarp.py index 2f4f480..8cc395f 100644 --- a/pydra/tasks/fsl/fnirt/invwarp.py +++ b/pydra/tasks/fsl/fnirt/invwarp.py @@ -6,16 +6,16 @@ -------- >>> task = InvWarp( -... input_warp_image="warpvol.nii", +... input_warpfield="warpvol.nii", ... reference_image= "refvol.nii", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'invwarp --warp warpvol.nii --ref refvol.nii --out .../warpvol_invwarp.nii' +'invwarp --warp warpvol.nii --ref refvol.nii --out ...warpvol_invwarp.nii' >>> task = InvWarp( -... input_warp_image="warpvol.nii", +... input_warpfield="warpvol.nii", ... reference_image= "refvol.nii", -... output_warp_image="invwarpvol.nii", +... output_warpfield="invwarpvol.nii", ... no_jacobian_constraints=True, ... ) >>> task.cmdline @@ -38,7 +38,7 @@ class InvWarpSpec(pydra.specs.ShellSpec): """Specifications for invwarp.""" - input_warp_image: os.PathLike = attrs.field( + input_warpfield: os.PathLike = attrs.field( metadata={ "help_string": "input warp image", "mandatory": True, @@ -54,20 +54,20 @@ class InvWarpSpec(pydra.specs.ShellSpec): } ) - output_warp_image: str = attrs.field( + output_warpfield: str = attrs.field( metadata={ "help_string": "output inverse warp image", "argstr": "--out", - "output_file_template": "{input_warp_image}_invwarp", + "output_file_template": "{input_warpfield}_invwarp", } ) - warp_field_as: str = attrs.field( + warpfield_as: str = attrs.field( metadata={ "help_string": "treat deformation field as absolute (abs) or relative (rel)", - "argstr": "--{warp_field_as}", + "argstr": "--{warpfield_as}", "allowed_values": {"abs", "rel"}, - "requires": {"warp_image"}, + "requires": {"input_warpfield"}, } ) From 98dd4e84ccb10fc4e03ee90553d368d6914238a1 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 140/224] ENH: Add extra parameters for FNIRT --- pydra/tasks/fsl/fnirt/fnirt.py | 197 +++++++++++++++++++++++++++++++-- 1 file changed, 186 insertions(+), 11 deletions(-) diff --git a/pydra/tasks/fsl/fnirt/fnirt.py b/pydra/tasks/fsl/fnirt/fnirt.py index 51f1b29..258277c 100644 --- a/pydra/tasks/fsl/fnirt/fnirt.py +++ b/pydra/tasks/fsl/fnirt/fnirt.py @@ -7,20 +7,31 @@ Examples -------- -Register two images together: +>>> task = FNIRT( +... reference_image="template.nii", +... input_image="input.nii", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fnirt --ref template.nii --in input.nii --cout ...input_warpcoef.nii \ +--iout ...input_warped.nii --fout ...input_warpfield.nii \ +--jout ...input_jac.nii ...' >>> task = FNIRT( ... reference_image="template.nii", ... input_image="input.nii", +... subsampling=[4, 2, 1], +... warp_resolution=[8, 8, 8], +... input_fwhm=[8, 4, 2], ... ) >>> task.cmdline # doctest: +ELLIPSIS -'fnirt --ref template.nii --in input.nii --cout .../input_fnirt_coeff \ ---iout .../input_fnirt.nii --fout .../input_fnirt_field.nii' +'fnirt --ref template.nii --in input.nii ... --subsamp 4,2,1 \ +--warpres 8,8,8 ... --infwhm 8,4,2 ...' """ __all__ = ["FNIRT"] import os +import typing as ty import attrs @@ -29,24 +40,49 @@ from . import specs +def _format_list(field: list): + return f"{','.join(map(str, field))}" + + @attrs.define(slots=False, kw_only=True) class FNIRTSpec(pydra.specs.ShellSpec): """Task specifications for FNIRT.""" reference_image: os.PathLike = attrs.field( - metadata={"help_string": "reference image", "argstr": "--ref"} + metadata={ + "help_string": "reference image", + "mandatory": True, + "argstr": "--ref", + } ) input_image: os.PathLike = attrs.field( - metadata={"help_string": "input image", "argstr": "--in"} + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "--in", + } ) - output_field_coefficients_file: str = attrs.field( + affine_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "affine matrix", + "argstr": "--aff", + } + ) + + input_warpfield: os.PathLike = attrs.field( + metadata={ + "help_string": "input warpfield", + "argstr": "--inwarp", + } + ) + + output_warpcoef: str = attrs.field( metadata={ "help_string": "output file containing the field coefficients", "argstr": "--cout", - "output_file_template": "{input_image}_fnirt_coeff", - "keep_extension": False, + "output_file_template": "{input_image}_warpcoef", } ) @@ -54,15 +90,23 @@ class FNIRTSpec(pydra.specs.ShellSpec): metadata={ "help_string": "output image", "argstr": "--iout", - "output_file_template": "{input_image}_fnirt", + "output_file_template": "{input_image}_warped", } ) - output_field_image: str = attrs.field( + output_warpfield: str = attrs.field( metadata={ "help_string": "output deformation field", "argstr": "--fout", - "output_file_template": "{input_image}_fnirt_field", + "output_file_template": "{input_image}_warpfield", + } + ) + + output_jacobian_image: str = attrs.field( + metadata={ + "help_string": "output Jacobian determinant map", + "argstr": "--jout", + "output_file_template": "{input_image}_jac", } ) @@ -80,6 +124,137 @@ class FNIRTSpec(pydra.specs.ShellSpec): } ) + max_iterations: ty.Iterable[int] = attrs.field( + default=(5, 5, 5, 5), + metadata={ + "help_string": "maximum number of non-linear iterations", + "formatter": lambda field: f"--miter {_format_list(field)}", + }, + ) + + subsampling: ty.Iterable[int] = attrs.field( + default=(4, 2, 1, 1), + metadata={ + "help_string": "sub-sampling scheme", + "formatter": lambda field: f"--subsamp {_format_list(field)}", + }, + ) + + warp_resolution: ty.Tuple[float, float, float] = attrs.field( + default=(10, 10, 10), + metadata={ + "help_string": "resolution of warp basis in x, y and z (in millimeters)", + "formatter": lambda field: f"--warpres {_format_list(field)}", + }, + ) + + spline_order: int = attrs.field( + default=3, + metadata={ + "help_string": "use quadratic (2) or cubic (3) splines", + "argstr": "--splineorder", + "allowed_values": {2, 3}, + }, + ) + + input_fwhm: ty.Iterable[float] = attrs.field( + default=(6.0, 4.0, 2.0, 2.0), + metadata={ + "help_string": "FWHM for Gaussian kernel applied to input image (in millimeters)", + "formatter": lambda field: f"--infwhm {_format_list(field)}", + }, + ) + + reference_fwhm: ty.Iterable[float] = attrs.field( + default=(4.0, 2.0, 0.0, 0.0), + metadata={ + "help_string": "FWHM for Gaussian kernel applied to reference image (in millimeters)", + "formatter": lambda field: f"--reffwhm {_format_list(field)}", + }, + ) + + warp_model: str = attrs.field( + default="bending_energy", + metadata={ + "help_string": "model for warpfield regularisation", + "argstr": "--regmod", + "allowed_values": {"bending_energy", "membrane_energy"}, + }, + ) + + warp_lambda: float = attrs.field( + metadata={ + "help_string": "weight of warpfield regularisation", + "argstr": "--lambda", + } + ) + + jacobian_range: ty.Tuple[float, float] = attrs.field( + default=(1e-2, 1e2), + metadata={ + "help_string": "range of Jacobian determinants", + "formatter": lambda field: f"--jacrange {_format_list(field)}", + }, + ) + + intensity_model: str = attrs.field( + default="global_non_linear_with_bias", + metadata={ + "help_string": "model for intensity mapping", + "argstr": "--intmod", + "allowed_values": { + "none", + "global_linear", + "global_non_linear", + "local_linear", + "global_non_linear_with_bias", + "local_non_linear", + }, + }, + ) + + intensity_order: int = attrs.field( + default=5, + metadata={ + "help_string": "polynomial order for intensity mapping", + "argstr": "--intorder", + }, + ) + + bias_resolution: ty.Tuple[int, int, int] = attrs.field( + default=(50, 50, 50), + metadata={ + "help_string": "resolution for bias field modelling (in millimeters)", + "formatter": lambda field: f"--biasres {_format_list(field)}", + }, + ) + + bias_lambda: float = attrs.field( + default=10000, + metadata={ + "help_string": "regularisation parameter for bias field modelling", + "argstr": "--biaslambda", + }, + ) + + precision: str = attrs.field( + default="double", + metadata={ + "help_string": "numerical precision for Hessian computation (float or double)", + "argstr": "--numprec", + "allowed_values": {"float", "double"}, + }, + ) + + interpolation: str = attrs.field( + default="linear", + metadata={ + "help_string": "interpolation model (linear or spline)", + "argstr": "--interp", + "allowed_values": {"linear", "spline"}, + }, + ) + class FNIRT(pydra.engine.ShellCommandTask): """Task definition for FNIRT.""" From 318119e3da6157c7554d1092d20f9212a635f68b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 141/224] ENH: Improve consistency between FNIRT and fnirtfileutils --- pydra/tasks/fsl/fnirt/fnirtfileutils.py | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/pydra/tasks/fsl/fnirt/fnirtfileutils.py b/pydra/tasks/fsl/fnirt/fnirtfileutils.py index 78255b4..e32c2a4 100644 --- a/pydra/tasks/fsl/fnirt/fnirtfileutils.py +++ b/pydra/tasks/fsl/fnirt/fnirtfileutils.py @@ -8,10 +8,9 @@ >>> task = FNIRTFileUtils( ... input_image="input.nii", ... reference_image="reference.nii", -... output_image="output.nii", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'fnirtfileutils --in input.nii --ref reference.nii --out output.nii \ +'fnirtfileutils --in input.nii --ref reference.nii --out ...input_field.nii \ --outformat field ...' >>> task = FNIRTFileUtils( @@ -58,7 +57,7 @@ class FNIRTFileUtilsSpec(pydra.specs.ShellSpec): metadata={ "help_string": "output field or coefficient image", "argstr": "--out", - "output_file_template": "{input_image}_warp", + "output_file_template": "{input_image}_{output_format}", } ) @@ -89,7 +88,7 @@ class FNIRTFileUtilsSpec(pydra.specs.ShellSpec): output_jacobian_image: str = attrs.field( metadata={ - "help_string": "output jacobian determinant map", + "help_string": "output Jacobian determinant map", "argstr": "--jac", "output_file_template": "{input_image}_jac", } @@ -97,7 +96,7 @@ class FNIRTFileUtilsSpec(pydra.specs.ShellSpec): output_jacobian_matrix: str = attrs.field( metadata={ - "help_string": "output jacobian matrix map", + "help_string": "output Jacobian matrix map", "argstr": "--matjac", "output_file_template": "{input_image}_matjac", } From 15d330da99c9274763bfb62fb3d00c96ba1e296f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 142/224] FIX: Default values and typing of some FNIRT parameters --- pydra/tasks/fsl/fnirt/fnirt.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pydra/tasks/fsl/fnirt/fnirt.py b/pydra/tasks/fsl/fnirt/fnirt.py index 258277c..9ab7bb5 100644 --- a/pydra/tasks/fsl/fnirt/fnirt.py +++ b/pydra/tasks/fsl/fnirt/fnirt.py @@ -182,7 +182,8 @@ class FNIRTSpec(pydra.specs.ShellSpec): }, ) - warp_lambda: float = attrs.field( + warp_lambda: ty.Iterable[float] = attrs.field( + default=(300, 75, 30, 30), metadata={ "help_string": "weight of warpfield regularisation", "argstr": "--lambda", @@ -221,7 +222,7 @@ class FNIRTSpec(pydra.specs.ShellSpec): }, ) - bias_resolution: ty.Tuple[int, int, int] = attrs.field( + bias_resolution: ty.Tuple[float, float, float] = attrs.field( default=(50, 50, 50), metadata={ "help_string": "resolution for bias field modelling (in millimeters)", From 018995df9aaa6bdf116e61a1079495e77f2dc038 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 143/224] MNT: lint fix --- pydra/tasks/fsl/fnirt/fnirt.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydra/tasks/fsl/fnirt/fnirt.py b/pydra/tasks/fsl/fnirt/fnirt.py index 9ab7bb5..0e4bc01 100644 --- a/pydra/tasks/fsl/fnirt/fnirt.py +++ b/pydra/tasks/fsl/fnirt/fnirt.py @@ -187,7 +187,7 @@ class FNIRTSpec(pydra.specs.ShellSpec): metadata={ "help_string": "weight of warpfield regularisation", "argstr": "--lambda", - } + }, ) jacobian_range: ty.Tuple[float, float] = attrs.field( From a8660e329fbbe7fd33bc62904305385997171c98 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 144/224] DOC: Update list of available interfaces --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index d41d23c..bba3f8f 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|----------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM | -| fnirt | FNIRT, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | -| susan | SUSAN | -| utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSplit | +| Module | Tasks | +|--------|---------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | +| susan | SUSAN | +| utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit | ## Installation From 68939793f8baad71262c96f68390a770c5fb6580 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 145/224] MNT: Bump version to 0.0.12 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 4ee3095..6df4fae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.11" +version = "0.0.12" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 9a4e7d3d9c4f5504bc378203032bf6028b66a04f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 146/224] NEW: Add task definition for fslswapdim --- pydra/tasks/fsl/__init__.py | 1 + pydra/tasks/fsl/utils/__init__.py | 1 + pydra/tasks/fsl/utils/fslswapdim.py | 92 +++++++++++++++++++++++++++++ 3 files changed, 94 insertions(+) create mode 100644 pydra/tasks/fsl/utils/fslswapdim.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index c0415ee..6803c9c 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -29,5 +29,6 @@ FSLReorient2Std, FSLSlice, FSLSplit, + FSLSwapDim, fslmaths, ) diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py index 59035f3..9b341e8 100644 --- a/pydra/tasks/fsl/utils/__init__.py +++ b/pydra/tasks/fsl/utils/__init__.py @@ -4,3 +4,4 @@ from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI from .fslsplit import FSLSlice, FSLSplit +from .fslswapdim import FSLSwapDim diff --git a/pydra/tasks/fsl/utils/fslswapdim.py b/pydra/tasks/fsl/utils/fslswapdim.py new file mode 100644 index 0000000..b04fc6a --- /dev/null +++ b/pydra/tasks/fsl/utils/fslswapdim.py @@ -0,0 +1,92 @@ +""" +FSLSwapDim +========== + +Examples +-------- + +>>> task = FSLSwapDim( +... input_image="input.nii", +... x="y", +... y="x", +... z="-z", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fslswapdim input.nii y x -z ...input_swapped.nii' + +>>> task = FSLSwapDim( +... input_image="input.nii", +... output_image="output.nii", +... x="RL", +... y="PA", +... z="IS", +... ) +>>> task.cmdline +'fslswapdim input.nii RL PA IS output.nii' +""" + +__all__ = ["FSLSwapDim"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLSwapDimSpec(pydra.specs.ShellSpec): + """Specifications for fslswapdim.""" + + ALLOWED_AXES = {"-x", "x", "y", "-y", "z", "-z", "RL", "LR", "AP", "PA", "SI", "IS"} + + input_image: os.PathLike = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + x: str = attrs.field( + metadata={ + "help_string": "new x-axis", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_AXES, + } + ) + + y: str = attrs.field( + metadata={ + "help_string": "new y-axis", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_AXES, + } + ) + + z: str = attrs.field( + metadata={ + "help_string": "new z-axis", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_AXES, + } + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image}_swapped", + } + ) + + +class FSLSwapDim(pydra.engine.ShellCommandTask): + """Task definition for fslswapdim.""" + + executable = "fslswapdim" + + input_spec = pydra.specs.SpecInfo(name="FSLSwapDimInput", bases=(FSLSwapDimSpec,)) From 4539eea9c6829733dbf35ec9126f8b4da505a41f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 147/224] DOC: Update list of available interfaces --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index bba3f8f..9f90ee2 100644 --- a/README.md +++ b/README.md @@ -34,7 +34,7 @@ for FMRI, MRI and DTI brain imaging data. | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | | fugue | FUGUE | | susan | SUSAN | -| utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit | +| utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | ## Installation From 6a639acf5e4c028cc7520d329e7e44ee601c6c4c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 148/224] REF: Rename axis parameters --- pydra/tasks/fsl/utils/fslswapdim.py | 33 ++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/pydra/tasks/fsl/utils/fslswapdim.py b/pydra/tasks/fsl/utils/fslswapdim.py index b04fc6a..4439741 100644 --- a/pydra/tasks/fsl/utils/fslswapdim.py +++ b/pydra/tasks/fsl/utils/fslswapdim.py @@ -7,9 +7,9 @@ >>> task = FSLSwapDim( ... input_image="input.nii", -... x="y", -... y="x", -... z="-z", +... new_x="y", +... new_y="x", +... new_z="-z", ... ) >>> task.cmdline # doctest: +ELLIPSIS 'fslswapdim input.nii y x -z ...input_swapped.nii' @@ -17,9 +17,9 @@ >>> task = FSLSwapDim( ... input_image="input.nii", ... output_image="output.nii", -... x="RL", -... y="PA", -... z="IS", +... new_x="RL", +... new_y="PA", +... new_z="IS", ... ) >>> task.cmdline 'fslswapdim input.nii RL PA IS output.nii' @@ -38,7 +38,20 @@ class FSLSwapDimSpec(pydra.specs.ShellSpec): """Specifications for fslswapdim.""" - ALLOWED_AXES = {"-x", "x", "y", "-y", "z", "-z", "RL", "LR", "AP", "PA", "SI", "IS"} + ALLOWED_AXES = { + "x", + "-x", + "y", + "-y", + "z", + "-z", + "LR", + "RL", + "AP", + "PA", + "SI", + "IS", + } input_image: os.PathLike = attrs.field( metadata={ @@ -48,7 +61,7 @@ class FSLSwapDimSpec(pydra.specs.ShellSpec): } ) - x: str = attrs.field( + new_x: str = attrs.field( metadata={ "help_string": "new x-axis", "mandatory": True, @@ -57,7 +70,7 @@ class FSLSwapDimSpec(pydra.specs.ShellSpec): } ) - y: str = attrs.field( + new_y: str = attrs.field( metadata={ "help_string": "new y-axis", "mandatory": True, @@ -66,7 +79,7 @@ class FSLSwapDimSpec(pydra.specs.ShellSpec): } ) - z: str = attrs.field( + new_z: str = attrs.field( metadata={ "help_string": "new z-axis", "mandatory": True, From be98b4dccdc1f1b708c32a3cfa56caab5e6f7373 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 149/224] NEW: Add task definition for fslchfiletype --- pydra/tasks/fsl/__init__.py | 1 + pydra/tasks/fsl/utils/__init__.py | 1 + pydra/tasks/fsl/utils/fslchfiletype.py | 122 +++++++++++++++++++++++++ 3 files changed, 124 insertions(+) create mode 100644 pydra/tasks/fsl/utils/fslchfiletype.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py index 6803c9c..817a75b 100644 --- a/pydra/tasks/fsl/__init__.py +++ b/pydra/tasks/fsl/__init__.py @@ -24,6 +24,7 @@ from .susan import SUSAN from .utils import ( FSLROI, + FSLChFileType, FSLInfo, FSLMerge, FSLReorient2Std, diff --git a/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/utils/__init__.py index 9b341e8..beec0ba 100644 --- a/pydra/tasks/fsl/utils/__init__.py +++ b/pydra/tasks/fsl/utils/__init__.py @@ -1,4 +1,5 @@ from . import fslmaths +from .fslchfiletype import FSLChFileType from .fslinfo import FSLInfo from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std diff --git a/pydra/tasks/fsl/utils/fslchfiletype.py b/pydra/tasks/fsl/utils/fslchfiletype.py new file mode 100644 index 0000000..3f8a17a --- /dev/null +++ b/pydra/tasks/fsl/utils/fslchfiletype.py @@ -0,0 +1,122 @@ +""" +FSLChFileType +============= + +Examples +-------- + +>>> task = FSLChFileType( +... filetype="NIFTI2_GZ", +... input_image="input.nii", +... output_basename="output", +... ) +>>> task.cmdline +'fslchfiletype NIFTI2_GZ input.nii output' +""" + +__all__ = ["FSLChFileType"] + +import pathlib + +import attrs + +import pydra + +ALLOWED_FILETYPES = { + "ANALYZE", + "ANALYZE_GZ", + "NIFTI", + "NIFTI_GZ", + "NIFTI_STD::PAIR", + "NIFTI_STD::PAIR_GZ", + "NIFTI2", + "NIFTI2_GZ", + "NIFTI2_STD::PAIR", + "NIFTI2_STD::PAIR_GZ", +} + + +def _get_output_basename(output_basename, input_image): + return output_basename or pathlib.PurePath(input_image).name.split(".", 1)[0] + + +def _get_output_image(output_basename, input_image, filetype): + output_basename = _get_output_basename(output_basename, input_image) + + extension = "img" if any(pat in filetype for pat in ["ANALYZE", "PAIR"]) else "nii" + if "GZ" in filetype: + extension += ".gz" + + return pathlib.Path.cwd() / f"{output_basename}.{extension}" + + +def _get_output_header(output_basename, input_image, filetype): + output_basename = _get_output_basename(output_basename, input_image) + + if any(pat in filetype for pat in ["ANALYZE", "PAIR"]): + extension = "hdr.gz" if "GZ" in filetype else "hdr" + return pathlib.Path.cwd() / f"{output_basename}.{extension}" + else: + return None + + +@attrs.define(slots=False, kw_only=True) +class FSLChFileTypeSpec(pydra.specs.ShellSpec): + """Specifications for fslchfiletype.""" + + filetype: str = attrs.field( + metadata={ + "help_string": "change to this file type", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_FILETYPES, + } + ) + + input_image: str = attrs.field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + } + ) + + output_basename: str = attrs.field( + metadata={ + "help_string": "output basename", + "formatter": _get_output_basename, + } + ) + + +@attrs.define(slots=False, kw_only=True) +class FSLChFileTypeOutSpec(pydra.specs.ShellOutSpec): + """Output specifications for fslchfiletype.""" + + output_image: pydra.specs.File = attrs.field( + metadata={ + "help_string": "output image", + "callable": _get_output_image, + } + ) + + output_header: pydra.specs.File = attrs.field( + metadata={ + "help_string": "output header for filetypes which support it", + "callable": _get_output_header, + } + ) + + +class FSLChFileType(pydra.engine.ShellCommandTask): + """Task definition for fslchfiletype.""" + + executable = "fslchfiletype" + + input_spec = pydra.specs.SpecInfo( + name="FSLChFileTypeInput", bases=(FSLChFileTypeSpec,) + ) + + output_spec = pydra.specs.SpecInfo( + name="FSLChFileTypeOutput", bases=(FSLChFileTypeOutSpec,) + ) From 7d7892c5a67d6aa5f4f104638876bad31988c1fa Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 150/224] DOC: Update list of available interfaces --- README.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9f90ee2..d7fcc69 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|---------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | -| susan | SUSAN | -| utils | fslmaths, FSLROI, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | +| Module | Tasks | +|--------|-----------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | +| susan | SUSAN | +| utils | fslmaths, FSLROI, FSLChFileType, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | ## Installation From 67b31e8b6760e81a95c2dc577106470a8577ec34 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:31:17 +1100 Subject: [PATCH 151/224] MNT: Bump version to 0.0.13 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6df4fae..dd55d58 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.12" +version = "0.0.13" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 599a696a3d87fa817a88bad4ee1f8860fbc9c087 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:32:59 +1100 Subject: [PATCH 152/224] MNT: Move to src layout --- .github/workflows/test.yaml | 12 ++--- hatch.toml | 22 ++++------ {pydra => src/pydra}/tasks/fsl/__init__.py | 0 .../pydra}/tasks/fsl/bet/__init__.py | 0 {pydra => src/pydra}/tasks/fsl/bet/bet.py | 21 +++------ .../pydra}/tasks/fsl/bet/robustfov.py | 0 {pydra => src/pydra}/tasks/fsl/eddy.py | 12 ++--- {pydra => src/pydra}/tasks/fsl/fast.py | 0 .../pydra}/tasks/fsl/flirt/__init__.py | 0 .../pydra}/tasks/fsl/flirt/applyxfm.py | 4 +- .../pydra}/tasks/fsl/flirt/concatxfm.py | 0 .../pydra}/tasks/fsl/flirt/convertxfm.py | 0 {pydra => src/pydra}/tasks/fsl/flirt/flirt.py | 0 .../pydra}/tasks/fsl/flirt/img2imgcoord.py | 8 +--- .../pydra}/tasks/fsl/flirt/img2stdcoord.py | 8 +--- .../pydra}/tasks/fsl/flirt/invertxfm.py | 0 {pydra => src/pydra}/tasks/fsl/flirt/specs.py | 12 ++--- .../pydra}/tasks/fsl/flirt/std2imgcoord.py | 8 +--- .../pydra}/tasks/fsl/fnirt/__init__.py | 0 .../pydra}/tasks/fsl/fnirt/applywarp.py | 0 .../pydra}/tasks/fsl/fnirt/convertwarp.py | 0 {pydra => src/pydra}/tasks/fsl/fnirt/fnirt.py | 0 .../pydra}/tasks/fsl/fnirt/fnirtfileutils.py | 0 .../pydra}/tasks/fsl/fnirt/invwarp.py | 0 {pydra => src/pydra}/tasks/fsl/fnirt/specs.py | 0 {pydra => src/pydra}/tasks/fsl/fugue.py | 0 {pydra => src/pydra}/tasks/fsl/latest.py | 0 {pydra => src/pydra}/tasks/fsl/susan.py | 5 +-- .../pydra}/tasks/fsl/utils/__init__.py | 0 .../pydra}/tasks/fsl/utils/fslchfiletype.py | 8 +--- .../pydra}/tasks/fsl/utils/fslinfo.py | 44 +++++-------------- .../pydra}/tasks/fsl/utils/fslmaths.py | 0 .../pydra}/tasks/fsl/utils/fslmerge.py | 0 .../pydra}/tasks/fsl/utils/fslreorient2std.py | 4 +- .../pydra}/tasks/fsl/utils/fslroi.py | 0 .../pydra}/tasks/fsl/utils/fslsplit.py | 0 .../pydra}/tasks/fsl/utils/fslswapdim.py | 0 .../pydra}/tasks/fsl/v1_0/__init__.py | 0 38 files changed, 45 insertions(+), 123 deletions(-) rename {pydra => src/pydra}/tasks/fsl/__init__.py (100%) rename {pydra => src/pydra}/tasks/fsl/bet/__init__.py (100%) rename {pydra => src/pydra}/tasks/fsl/bet/bet.py (88%) rename {pydra => src/pydra}/tasks/fsl/bet/robustfov.py (100%) rename {pydra => src/pydra}/tasks/fsl/eddy.py (96%) rename {pydra => src/pydra}/tasks/fsl/fast.py (100%) rename {pydra => src/pydra}/tasks/fsl/flirt/__init__.py (100%) rename {pydra => src/pydra}/tasks/fsl/flirt/applyxfm.py (95%) rename {pydra => src/pydra}/tasks/fsl/flirt/concatxfm.py (100%) rename {pydra => src/pydra}/tasks/fsl/flirt/convertxfm.py (100%) rename {pydra => src/pydra}/tasks/fsl/flirt/flirt.py (100%) rename {pydra => src/pydra}/tasks/fsl/flirt/img2imgcoord.py (83%) rename {pydra => src/pydra}/tasks/fsl/flirt/img2stdcoord.py (83%) rename {pydra => src/pydra}/tasks/fsl/flirt/invertxfm.py (100%) rename {pydra => src/pydra}/tasks/fsl/flirt/specs.py (91%) rename {pydra => src/pydra}/tasks/fsl/flirt/std2imgcoord.py (82%) rename {pydra => src/pydra}/tasks/fsl/fnirt/__init__.py (100%) rename {pydra => src/pydra}/tasks/fsl/fnirt/applywarp.py (100%) rename {pydra => src/pydra}/tasks/fsl/fnirt/convertwarp.py (100%) rename {pydra => src/pydra}/tasks/fsl/fnirt/fnirt.py (100%) rename {pydra => src/pydra}/tasks/fsl/fnirt/fnirtfileutils.py (100%) rename {pydra => src/pydra}/tasks/fsl/fnirt/invwarp.py (100%) rename {pydra => src/pydra}/tasks/fsl/fnirt/specs.py (100%) rename {pydra => src/pydra}/tasks/fsl/fugue.py (100%) rename {pydra => src/pydra}/tasks/fsl/latest.py (100%) rename {pydra => src/pydra}/tasks/fsl/susan.py (93%) rename {pydra => src/pydra}/tasks/fsl/utils/__init__.py (100%) rename {pydra => src/pydra}/tasks/fsl/utils/fslchfiletype.py (92%) rename {pydra => src/pydra}/tasks/fsl/utils/fslinfo.py (65%) rename {pydra => src/pydra}/tasks/fsl/utils/fslmaths.py (100%) rename {pydra => src/pydra}/tasks/fsl/utils/fslmerge.py (100%) rename {pydra => src/pydra}/tasks/fsl/utils/fslreorient2std.py (92%) rename {pydra => src/pydra}/tasks/fsl/utils/fslroi.py (100%) rename {pydra => src/pydra}/tasks/fsl/utils/fslsplit.py (100%) rename {pydra => src/pydra}/tasks/fsl/utils/fslswapdim.py (100%) rename {pydra => src/pydra}/tasks/fsl/v1_0/__init__.py (100%) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 991d4f6..3eef824 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -2,15 +2,9 @@ name: test on: push: - paths: - - '.github/workflows/test.yaml' - - 'pydra/**' - - 'tests/**' + branches: [ main ] pull_request: - paths: - - '.github/workflows/test.yaml' - - 'pydra/**' - - 'tests/**' + branches: [ main ] workflow_dispatch: permissions: @@ -48,4 +42,4 @@ jobs: - name: Install Hatch run: pipx install hatch - name: Test codebase - run: hatch run +python=${{ matrix.python-version }} test:cov + run: hatch run test diff --git a/hatch.toml b/hatch.toml index e289fb6..4a713c3 100644 --- a/hatch.toml +++ b/hatch.toml @@ -1,17 +1,13 @@ [build.targets.wheel] -only-include = ["pydra/tasks/fsl"] +only-include = ["src/pydra/tasks/fsl"] +sources = ["src"] [envs.default] -dependencies = [ - "coverage[toml] <7", - "pytest", - "pytest-cov", -] +dependencies = ["pytest"] [envs.default.scripts] -cov = "pytest --cov-report=term-missing --cov-config=pyproject.toml --cov=pydra {args}" -no-cov = "cov --no-cov {args}" +test = "pytest {args:src}" -[[envs.test.matrix]] +[[envs.all.matrix]] python = ["3.7", "3.8", "3.9", "3.10", "3.11"] [envs.lint] @@ -23,10 +19,10 @@ dependencies = [ ] [envs.lint.scripts] all = [ - "black --check --diff {args:pydra}", - "isort --check --diff {args:pydra}", + "black --check --diff {args:src}", + "isort --check --diff {args:src}", ] fix = [ - "black --quiet {args:pydra}", - "isort --quiet {args:pydra}", + "black --quiet {args:src}", + "isort --quiet {args:src}", ] diff --git a/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py similarity index 100% rename from pydra/tasks/fsl/__init__.py rename to src/pydra/tasks/fsl/__init__.py diff --git a/pydra/tasks/fsl/bet/__init__.py b/src/pydra/tasks/fsl/bet/__init__.py similarity index 100% rename from pydra/tasks/fsl/bet/__init__.py rename to src/pydra/tasks/fsl/bet/__init__.py diff --git a/pydra/tasks/fsl/bet/bet.py b/src/pydra/tasks/fsl/bet/bet.py similarity index 88% rename from pydra/tasks/fsl/bet/bet.py rename to src/pydra/tasks/fsl/bet/bet.py index 69dd340..9ef954f 100644 --- a/pydra/tasks/fsl/bet/bet.py +++ b/src/pydra/tasks/fsl/bet/bet.py @@ -41,13 +41,9 @@ class BETSpec(pydra.specs.ShellSpec): metadata={"help_string": "save brain surface outline", "argstr": "-o"} ) - save_brain_mask: bool = attrs.field( - metadata={"help_string": "save binary brain mask", "argstr": "-m"} - ) + save_brain_mask: bool = attrs.field(metadata={"help_string": "save binary brain mask", "argstr": "-m"}) - save_skull_image: bool = attrs.field( - metadata={"help_string": "save approximate skull image", "argstr": "-s"} - ) + save_skull_image: bool = attrs.field(metadata={"help_string": "save approximate skull image", "argstr": "-s"}) save_brain_surface_mesh: bool = attrs.field( metadata={ @@ -78,19 +74,14 @@ class BETSpec(pydra.specs.ShellSpec): head_radius: float = attrs.field( metadata={ - "help_string": ( - "Head radius (in millimeters)." - " Initial surface sphere is set to half of this value." - ), + "help_string": ("Head radius (in millimeters)." " Initial surface sphere is set to half of this value."), "argstr": "-r", } ) center_of_gravity: ty.Tuple[int, int, int] = attrs.field( metadata={ - "help_string": ( - "centre-of-gravity (in voxel coordinates) of initial mesh surface" - ), + "help_string": ("centre-of-gravity (in voxel coordinates) of initial mesh surface"), "argstr": "-c", } ) @@ -206,8 +197,6 @@ class BET(pydra.engine.ShellCommandTask): executable = "bet" - input_spec = pydra.specs.SpecInfo( - name="BETInput", bases=(BETSpec, BETVariationsSpec) - ) + input_spec = pydra.specs.SpecInfo(name="BETInput", bases=(BETSpec, BETVariationsSpec)) output_spec = pydra.specs.SpecInfo(name="BETOutput", bases=(BETOutSpec,)) diff --git a/pydra/tasks/fsl/bet/robustfov.py b/src/pydra/tasks/fsl/bet/robustfov.py similarity index 100% rename from pydra/tasks/fsl/bet/robustfov.py rename to src/pydra/tasks/fsl/bet/robustfov.py diff --git a/pydra/tasks/fsl/eddy.py b/src/pydra/tasks/fsl/eddy.py similarity index 96% rename from pydra/tasks/fsl/eddy.py rename to src/pydra/tasks/fsl/eddy.py index fa84168..8944cfd 100644 --- a/pydra/tasks/fsl/eddy.py +++ b/src/pydra/tasks/fsl/eddy.py @@ -21,9 +21,7 @@ class EddySpec(pydra.specs.ShellSpec): # Parameters that specify input files. input_image: os.PathLike = attrs.field( metadata={ - "help_string": ( - "input image as a 4D volume of all images acquired in the diffusion protocol" - ), + "help_string": ("input image as a 4D volume of all images acquired in the diffusion protocol"), "mandatory": True, "argstr": "--imain", } @@ -133,9 +131,7 @@ class EddySpec(pydra.specs.ShellSpec): fwhm: float = attrs.field( default=0, metadata={ - "help_string": ( - "filter width used for pre-conditionning data prior to estimating distortions" - ), + "help_string": ("filter width used for pre-conditionning data prior to estimating distortions"), "argstr": "--fwhm", }, ) @@ -190,9 +186,7 @@ class EddySpec(pydra.specs.ShellSpec): ) # Parameters for outlier replacement (ol) - replace_outliers: bool = attrs.field( - metadata={"help_string": "replace outliers", "argstr": "--repol"} - ) + replace_outliers: bool = attrs.field(metadata={"help_string": "replace outliers", "argstr": "--repol"}) outlier_num_stdevs: int = attrs.field( metadata={ diff --git a/pydra/tasks/fsl/fast.py b/src/pydra/tasks/fsl/fast.py similarity index 100% rename from pydra/tasks/fsl/fast.py rename to src/pydra/tasks/fsl/fast.py diff --git a/pydra/tasks/fsl/flirt/__init__.py b/src/pydra/tasks/fsl/flirt/__init__.py similarity index 100% rename from pydra/tasks/fsl/flirt/__init__.py rename to src/pydra/tasks/fsl/flirt/__init__.py diff --git a/pydra/tasks/fsl/flirt/applyxfm.py b/src/pydra/tasks/fsl/flirt/applyxfm.py similarity index 95% rename from pydra/tasks/fsl/flirt/applyxfm.py rename to src/pydra/tasks/fsl/flirt/applyxfm.py index 9fa4eee..604f8cd 100644 --- a/pydra/tasks/fsl/flirt/applyxfm.py +++ b/src/pydra/tasks/fsl/flirt/applyxfm.py @@ -94,9 +94,7 @@ class ApplyXFMSpec(pydra.specs.ShellSpec): metadata={ "help_string": "force resampling to isotropic resolution", "formatter": lambda isotropic_resolution: ( - f"-applyisoxfm {isotropic_resolution}" - if isotropic_resolution - else "-applyxfm" + f"-applyisoxfm {isotropic_resolution}" if isotropic_resolution else "-applyxfm" ), }, ) diff --git a/pydra/tasks/fsl/flirt/concatxfm.py b/src/pydra/tasks/fsl/flirt/concatxfm.py similarity index 100% rename from pydra/tasks/fsl/flirt/concatxfm.py rename to src/pydra/tasks/fsl/flirt/concatxfm.py diff --git a/pydra/tasks/fsl/flirt/convertxfm.py b/src/pydra/tasks/fsl/flirt/convertxfm.py similarity index 100% rename from pydra/tasks/fsl/flirt/convertxfm.py rename to src/pydra/tasks/fsl/flirt/convertxfm.py diff --git a/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py similarity index 100% rename from pydra/tasks/fsl/flirt/flirt.py rename to src/pydra/tasks/fsl/flirt/flirt.py diff --git a/pydra/tasks/fsl/flirt/img2imgcoord.py b/src/pydra/tasks/fsl/flirt/img2imgcoord.py similarity index 83% rename from pydra/tasks/fsl/flirt/img2imgcoord.py rename to src/pydra/tasks/fsl/flirt/img2imgcoord.py index 5bd4e38..428f431 100644 --- a/pydra/tasks/fsl/flirt/img2imgcoord.py +++ b/src/pydra/tasks/fsl/flirt/img2imgcoord.py @@ -56,10 +56,6 @@ class Img2ImgCoord(pydra.engine.ShellCommandTask): executable = "img2imgcoord" - input_spec = pydra.specs.SpecInfo( - name="Img2ImgCoordInput", bases=(Img2ImgCoordSpec, specs.VerboseSpec) - ) + input_spec = pydra.specs.SpecInfo(name="Img2ImgCoordInput", bases=(Img2ImgCoordSpec, specs.VerboseSpec)) - output_spec = pydra.specs.SpecInfo( - name="Img2ImgCoordOutput", bases=(Img2ImgCoordOutSpec,) - ) + output_spec = pydra.specs.SpecInfo(name="Img2ImgCoordOutput", bases=(Img2ImgCoordOutSpec,)) diff --git a/pydra/tasks/fsl/flirt/img2stdcoord.py b/src/pydra/tasks/fsl/flirt/img2stdcoord.py similarity index 83% rename from pydra/tasks/fsl/flirt/img2stdcoord.py rename to src/pydra/tasks/fsl/flirt/img2stdcoord.py index 8ef252a..f63565c 100644 --- a/pydra/tasks/fsl/flirt/img2stdcoord.py +++ b/src/pydra/tasks/fsl/flirt/img2stdcoord.py @@ -55,10 +55,6 @@ class Img2StdCoord(pydra.engine.ShellCommandTask): executable = "img2stdcoord" - input_spec = pydra.specs.SpecInfo( - name="Img2StdCoordInput", bases=(Img2StdCoordSpec, specs.VerboseSpec) - ) + input_spec = pydra.specs.SpecInfo(name="Img2StdCoordInput", bases=(Img2StdCoordSpec, specs.VerboseSpec)) - output_spec = pydra.specs.SpecInfo( - name="Img2StdCoordOutput", bases=(Img2StdCoordOutSpec,) - ) + output_spec = pydra.specs.SpecInfo(name="Img2StdCoordOutput", bases=(Img2StdCoordOutSpec,)) diff --git a/pydra/tasks/fsl/flirt/invertxfm.py b/src/pydra/tasks/fsl/flirt/invertxfm.py similarity index 100% rename from pydra/tasks/fsl/flirt/invertxfm.py rename to src/pydra/tasks/fsl/flirt/invertxfm.py diff --git a/pydra/tasks/fsl/flirt/specs.py b/src/pydra/tasks/fsl/flirt/specs.py similarity index 91% rename from pydra/tasks/fsl/flirt/specs.py rename to src/pydra/tasks/fsl/flirt/specs.py index fe1afe6..63ec506 100644 --- a/pydra/tasks/fsl/flirt/specs.py +++ b/src/pydra/tasks/fsl/flirt/specs.py @@ -75,9 +75,7 @@ class SearchSpec(pydra.specs.ShellSpec): default=[-90, 90], metadata={ "help_string": "range of search angles in x", - "formatter": lambda field, no_search: ( - "" if no_search else f"-searchrx {field[0]} {field[1]}" - ), + "formatter": lambda field, no_search: ("" if no_search else f"-searchrx {field[0]} {field[1]}"), }, ) @@ -85,9 +83,7 @@ class SearchSpec(pydra.specs.ShellSpec): default=[-90, 90], metadata={ "help_string": "range of search angles in y", - "formatter": lambda field, no_search: ( - "" if no_search else f"-searchry {field[0]} {field[1]}" - ), + "formatter": lambda field, no_search: ("" if no_search else f"-searchry {field[0]} {field[1]}"), }, ) @@ -95,9 +91,7 @@ class SearchSpec(pydra.specs.ShellSpec): default=[-90, 90], metadata={ "help_string": "range of search angles in z", - "formatter": lambda field, no_search: ( - "" if no_search else f"-searchrz {field[0]} {field[1]}" - ), + "formatter": lambda field, no_search: ("" if no_search else f"-searchrz {field[0]} {field[1]}"), }, ) diff --git a/pydra/tasks/fsl/flirt/std2imgcoord.py b/src/pydra/tasks/fsl/flirt/std2imgcoord.py similarity index 82% rename from pydra/tasks/fsl/flirt/std2imgcoord.py rename to src/pydra/tasks/fsl/flirt/std2imgcoord.py index 645aa83..a13cdf6 100644 --- a/pydra/tasks/fsl/flirt/std2imgcoord.py +++ b/src/pydra/tasks/fsl/flirt/std2imgcoord.py @@ -55,10 +55,6 @@ class Std2ImgCoord(pydra.engine.ShellCommandTask): executable = "std2imgcoord" - input_spec = pydra.specs.SpecInfo( - name="Std2ImgCoordSpecInput", bases=(Std2ImgCoordSpec, specs.VerboseSpec) - ) + input_spec = pydra.specs.SpecInfo(name="Std2ImgCoordSpecInput", bases=(Std2ImgCoordSpec, specs.VerboseSpec)) - output_spec = pydra.specs.SpecInfo( - name="Std2ImgCoordSpecOutput", bases=(Std2ImgCoordOutSpec,) - ) + output_spec = pydra.specs.SpecInfo(name="Std2ImgCoordSpecOutput", bases=(Std2ImgCoordOutSpec,)) diff --git a/pydra/tasks/fsl/fnirt/__init__.py b/src/pydra/tasks/fsl/fnirt/__init__.py similarity index 100% rename from pydra/tasks/fsl/fnirt/__init__.py rename to src/pydra/tasks/fsl/fnirt/__init__.py diff --git a/pydra/tasks/fsl/fnirt/applywarp.py b/src/pydra/tasks/fsl/fnirt/applywarp.py similarity index 100% rename from pydra/tasks/fsl/fnirt/applywarp.py rename to src/pydra/tasks/fsl/fnirt/applywarp.py diff --git a/pydra/tasks/fsl/fnirt/convertwarp.py b/src/pydra/tasks/fsl/fnirt/convertwarp.py similarity index 100% rename from pydra/tasks/fsl/fnirt/convertwarp.py rename to src/pydra/tasks/fsl/fnirt/convertwarp.py diff --git a/pydra/tasks/fsl/fnirt/fnirt.py b/src/pydra/tasks/fsl/fnirt/fnirt.py similarity index 100% rename from pydra/tasks/fsl/fnirt/fnirt.py rename to src/pydra/tasks/fsl/fnirt/fnirt.py diff --git a/pydra/tasks/fsl/fnirt/fnirtfileutils.py b/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py similarity index 100% rename from pydra/tasks/fsl/fnirt/fnirtfileutils.py rename to src/pydra/tasks/fsl/fnirt/fnirtfileutils.py diff --git a/pydra/tasks/fsl/fnirt/invwarp.py b/src/pydra/tasks/fsl/fnirt/invwarp.py similarity index 100% rename from pydra/tasks/fsl/fnirt/invwarp.py rename to src/pydra/tasks/fsl/fnirt/invwarp.py diff --git a/pydra/tasks/fsl/fnirt/specs.py b/src/pydra/tasks/fsl/fnirt/specs.py similarity index 100% rename from pydra/tasks/fsl/fnirt/specs.py rename to src/pydra/tasks/fsl/fnirt/specs.py diff --git a/pydra/tasks/fsl/fugue.py b/src/pydra/tasks/fsl/fugue.py similarity index 100% rename from pydra/tasks/fsl/fugue.py rename to src/pydra/tasks/fsl/fugue.py diff --git a/pydra/tasks/fsl/latest.py b/src/pydra/tasks/fsl/latest.py similarity index 100% rename from pydra/tasks/fsl/latest.py rename to src/pydra/tasks/fsl/latest.py diff --git a/pydra/tasks/fsl/susan.py b/src/pydra/tasks/fsl/susan.py similarity index 93% rename from pydra/tasks/fsl/susan.py rename to src/pydra/tasks/fsl/susan.py index 3e8eb01..de6ee2b 100644 --- a/pydra/tasks/fsl/susan.py +++ b/src/pydra/tasks/fsl/susan.py @@ -89,10 +89,7 @@ class SUSANSpec(pydra.specs.ShellSpec): metadata={ "help_string": "find smoothing area from secondary images (up to 2)", "formatter": lambda field: ( - " ".join( - [f"{len(field or [])}"] - + [f"{usan} {bt}" for usan, bt in field or []] - ) + " ".join([f"{len(field or [])}"] + [f"{usan} {bt}" for usan, bt in field or []]) ), }, ) diff --git a/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py similarity index 100% rename from pydra/tasks/fsl/utils/__init__.py rename to src/pydra/tasks/fsl/utils/__init__.py diff --git a/pydra/tasks/fsl/utils/fslchfiletype.py b/src/pydra/tasks/fsl/utils/fslchfiletype.py similarity index 92% rename from pydra/tasks/fsl/utils/fslchfiletype.py rename to src/pydra/tasks/fsl/utils/fslchfiletype.py index 3f8a17a..d0039d6 100644 --- a/pydra/tasks/fsl/utils/fslchfiletype.py +++ b/src/pydra/tasks/fsl/utils/fslchfiletype.py @@ -113,10 +113,6 @@ class FSLChFileType(pydra.engine.ShellCommandTask): executable = "fslchfiletype" - input_spec = pydra.specs.SpecInfo( - name="FSLChFileTypeInput", bases=(FSLChFileTypeSpec,) - ) + input_spec = pydra.specs.SpecInfo(name="FSLChFileTypeInput", bases=(FSLChFileTypeSpec,)) - output_spec = pydra.specs.SpecInfo( - name="FSLChFileTypeOutput", bases=(FSLChFileTypeOutSpec,) - ) + output_spec = pydra.specs.SpecInfo(name="FSLChFileTypeOutput", bases=(FSLChFileTypeOutSpec,)) diff --git a/pydra/tasks/fsl/utils/fslinfo.py b/src/pydra/tasks/fsl/utils/fslinfo.py similarity index 65% rename from pydra/tasks/fsl/utils/fslinfo.py rename to src/pydra/tasks/fsl/utils/fslinfo.py index 9877289..604c850 100644 --- a/pydra/tasks/fsl/utils/fslinfo.py +++ b/src/pydra/tasks/fsl/utils/fslinfo.py @@ -40,99 +40,77 @@ class FSLInfoOutSpec(pydra.specs.ShellOutSpec): dim1: int = attrs.field( metadata={ "help_string": "array size in 1st dimension", - "callable": lambda stdout: int( - re.search(r"\sdim1\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: int(re.search(r"\sdim1\s*(.*)", stdout).group(1)), } ) dim2: int = attrs.field( metadata={ "help_string": "array size in 2nd dimension", - "callable": lambda stdout: int( - re.search(r"\sdim2\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: int(re.search(r"\sdim2\s*(.*)", stdout).group(1)), } ) dim3: int = attrs.field( metadata={ "help_string": "array size in 3rd dimension", - "callable": lambda stdout: int( - re.search(r"\sdim3\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: int(re.search(r"\sdim3\s*(.*)", stdout).group(1)), } ) dim4: int = attrs.field( metadata={ "help_string": "array size in 4th dimension", - "callable": lambda stdout: int( - re.search(r"\sdim4\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: int(re.search(r"\sdim4\s*(.*)", stdout).group(1)), } ) datatype: int = attrs.field( metadata={ "help_string": "data type code", - "callable": lambda stdout: int( - re.search(r"datatype\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: int(re.search(r"datatype\s*(.*)", stdout).group(1)), } ) pixdim1: float = attrs.field( metadata={ "help_string": "pixel spacing in 1st dimension", - "callable": lambda stdout: float( - re.search(r"pixdim1\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: float(re.search(r"pixdim1\s*(.*)", stdout).group(1)), } ) pixdim2: float = attrs.field( metadata={ "help_string": "pixel spacing in 2nd dimension", - "callable": lambda stdout: float( - re.search(r"pixdim2\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: float(re.search(r"pixdim2\s*(.*)", stdout).group(1)), } ) pixdim3: float = attrs.field( metadata={ "help_string": "pixel spacing in 3rd dimension", - "callable": lambda stdout: float( - re.search(r"pixdim3\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: float(re.search(r"pixdim3\s*(.*)", stdout).group(1)), } ) pixedim4: float = attrs.field( metadata={ "help_string": "pixel spacing in 4th dimension", - "callable": lambda stdout: float( - re.search(r"pixdim4\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: float(re.search(r"pixdim4\s*(.*)", stdout).group(1)), } ) cal_max: float = attrs.field( metadata={ "help_string": "maximum display intensity", - "callable": lambda stdout: float( - re.search(r"cal_max\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: float(re.search(r"cal_max\s*(.*)", stdout).group(1)), } ) cal_min: float = attrs.field( metadata={ "help_string": "minimum display intensity", - "callable": lambda stdout: float( - re.search(r"cal_min\s*(.*)", stdout).group(1) - ), + "callable": lambda stdout: float(re.search(r"cal_min\s*(.*)", stdout).group(1)), } ) diff --git a/pydra/tasks/fsl/utils/fslmaths.py b/src/pydra/tasks/fsl/utils/fslmaths.py similarity index 100% rename from pydra/tasks/fsl/utils/fslmaths.py rename to src/pydra/tasks/fsl/utils/fslmaths.py diff --git a/pydra/tasks/fsl/utils/fslmerge.py b/src/pydra/tasks/fsl/utils/fslmerge.py similarity index 100% rename from pydra/tasks/fsl/utils/fslmerge.py rename to src/pydra/tasks/fsl/utils/fslmerge.py diff --git a/pydra/tasks/fsl/utils/fslreorient2std.py b/src/pydra/tasks/fsl/utils/fslreorient2std.py similarity index 92% rename from pydra/tasks/fsl/utils/fslreorient2std.py rename to src/pydra/tasks/fsl/utils/fslreorient2std.py index c35a914..cccf681 100644 --- a/pydra/tasks/fsl/utils/fslreorient2std.py +++ b/src/pydra/tasks/fsl/utils/fslreorient2std.py @@ -59,6 +59,4 @@ class FSLReorient2Std(pydra.engine.ShellCommandTask): executable = "fslreorient2std" - input_spec = pydra.specs.SpecInfo( - name="FSLReorient2StdInput", bases=(FSLReorient2StdSpec,) - ) + input_spec = pydra.specs.SpecInfo(name="FSLReorient2StdInput", bases=(FSLReorient2StdSpec,)) diff --git a/pydra/tasks/fsl/utils/fslroi.py b/src/pydra/tasks/fsl/utils/fslroi.py similarity index 100% rename from pydra/tasks/fsl/utils/fslroi.py rename to src/pydra/tasks/fsl/utils/fslroi.py diff --git a/pydra/tasks/fsl/utils/fslsplit.py b/src/pydra/tasks/fsl/utils/fslsplit.py similarity index 100% rename from pydra/tasks/fsl/utils/fslsplit.py rename to src/pydra/tasks/fsl/utils/fslsplit.py diff --git a/pydra/tasks/fsl/utils/fslswapdim.py b/src/pydra/tasks/fsl/utils/fslswapdim.py similarity index 100% rename from pydra/tasks/fsl/utils/fslswapdim.py rename to src/pydra/tasks/fsl/utils/fslswapdim.py diff --git a/pydra/tasks/fsl/v1_0/__init__.py b/src/pydra/tasks/fsl/v1_0/__init__.py similarity index 100% rename from pydra/tasks/fsl/v1_0/__init__.py rename to src/pydra/tasks/fsl/v1_0/__init__.py From e06aa6a5d20b76fcad98ee58369d373a7a3a1634 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 153/224] DOC: Fix test command --- README.md | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index d7fcc69..b6c9452 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ pipx install hatch To run the test suite: ```console -hatch run test:no-cov +hatch run test ``` To fix linting issues: @@ -68,26 +68,16 @@ hatch run lint:fix ## License -`pydra-fsl` is distributed under the terms of the [Apache License, Version 2.0][license]. +This project is distributed under the terms of the [Apache License, Version 2.0][license]. [pypi-project]: https://pypi.org/project/pydra-fsl - [pypi-version]: https://img.shields.io/pypi/v/pydra-fsl.svg - [pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-fsl.svg - [pypi-downloads]: https://static.pepy.tech/badge/pydra-fsl - [status-test]: https://github.com/aramis-lab/pydra-fsl/actions/workflows/test.yaml/badge.svg - [pydra]: https://pydra.readthedocs.io/ - [fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL - [fsl-install]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FslInstallation - [fsl-license]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Licence - [hatch]: https://hatch.pypa.io/ - [license]: https://spdx.org/licenses/Apache-2.0.html From f18018627518393d34e0daa1b2dbadeb32a7cd1a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 154/224] NEW: Add task definition for FSLFFT --- README.md | 30 ++++++++++----- src/pydra/tasks/fsl/__init__.py | 1 + src/pydra/tasks/fsl/utils/__init__.py | 1 + src/pydra/tasks/fsl/utils/fslfft.py | 54 +++++++++++++++++++++++++++ 4 files changed, 76 insertions(+), 10 deletions(-) create mode 100644 src/pydra/tasks/fsl/utils/fslfft.py diff --git a/README.md b/README.md index b6c9452..033fcd7 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|-----------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | -| susan | SUSAN | -| utils | fslmaths, FSLROI, FSLChFileType, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | +| Module | Tasks | +|--------|-------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | +| susan | SUSAN | +| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | ## Installation @@ -71,13 +71,23 @@ hatch run lint:fix This project is distributed under the terms of the [Apache License, Version 2.0][license]. [pypi-project]: https://pypi.org/project/pydra-fsl + [pypi-version]: https://img.shields.io/pypi/v/pydra-fsl.svg + [pypi-pyversions]: https://img.shields.io/pypi/pyversions/pydra-fsl.svg + [pypi-downloads]: https://static.pepy.tech/badge/pydra-fsl + [status-test]: https://github.com/aramis-lab/pydra-fsl/actions/workflows/test.yaml/badge.svg + [pydra]: https://pydra.readthedocs.io/ + [fsl]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSL + [fsl-install]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FslInstallation + [fsl-license]: https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/Licence + [hatch]: https://hatch.pypa.io/ + [license]: https://spdx.org/licenses/Apache-2.0.html diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 817a75b..4414e7e 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -23,6 +23,7 @@ from .fugue import FUGUE from .susan import SUSAN from .utils import ( + FSLFFT, FSLROI, FSLChFileType, FSLInfo, diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index beec0ba..b602c08 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -1,5 +1,6 @@ from . import fslmaths from .fslchfiletype import FSLChFileType +from .fslfft import FSLFFT from .fslinfo import FSLInfo from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std diff --git a/src/pydra/tasks/fsl/utils/fslfft.py b/src/pydra/tasks/fsl/utils/fslfft.py new file mode 100644 index 0000000..e504763 --- /dev/null +++ b/src/pydra/tasks/fsl/utils/fslfft.py @@ -0,0 +1,54 @@ +""" +FSLFFT +====== + +Examples +-------- + +Compute the forward FFT: +>>> task = FSLFFT(input_image="input.nii") +>>> task.cmdline +'fslfft input.nii .../input_fslfft.nii' + +Compute the inverse FFT: +>>> task = FSLFFT( +... input_image="input.nii", +... output_image="output.nii", +... inverse=True, +... ) +>>> task.cmdline +'fslfft input.nii output.nii -inv' +""" + +__all__ = ["FSLFFT"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLFFTSpec(pydra.specs.ShellSpec): + """Specifications for fslfft.""" + + input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image}_fslfft", + } + ) + + inverse: bool = attrs.field(metadata={"help_string": "compute the inverse FFT", "argstr": "-inv"}) + + +class FSLFFT(pydra.engine.ShellCommandTask): + """Task definition for fslfft.""" + + executable = "fslfft" + + input_spec = pydra.specs.SpecInfo(name="FSLFFTInput", bases=(FSLFFTSpec,)) From 2363bd806e347dd5cfd47ca626a2ca4d88193865 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 155/224] NEW: Add task definition for fslinterleave --- README.md | 20 ++++---- src/pydra/tasks/fsl/__init__.py | 1 + src/pydra/tasks/fsl/utils/__init__.py | 1 + src/pydra/tasks/fsl/utils/fslinterleave.py | 57 ++++++++++++++++++++++ 4 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 src/pydra/tasks/fsl/utils/fslinterleave.py diff --git a/README.md b/README.md index 033fcd7..a1f1461 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|-------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | -| susan | SUSAN | -| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | +| Module | Tasks | +|--------|----------------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | +| susan | SUSAN | +| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 4414e7e..80997e3 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -27,6 +27,7 @@ FSLROI, FSLChFileType, FSLInfo, + FSLInterleave, FSLMerge, FSLReorient2Std, FSLSlice, diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index b602c08..b48f806 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -2,6 +2,7 @@ from .fslchfiletype import FSLChFileType from .fslfft import FSLFFT from .fslinfo import FSLInfo +from .fslinterleave import FSLInterleave from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI diff --git a/src/pydra/tasks/fsl/utils/fslinterleave.py b/src/pydra/tasks/fsl/utils/fslinterleave.py new file mode 100644 index 0000000..b85c785 --- /dev/null +++ b/src/pydra/tasks/fsl/utils/fslinterleave.py @@ -0,0 +1,57 @@ +""" +FSLInterleave +============= + +Examples +-------- + +Interleave images: +>>> task = FSLInterleave(input_image="in1.nii", other_image="in2.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'fslinterleave in1.nii in2.nii .../in1_interleaved.nii' + +Interleave in reverse order: +>>> task = FSLInterleave( +... input_image="in1.nii", +... other_image="in2.nii", +... output_image="out.nii", +... reverse=True, +... ) +>>> task.cmdline +'fslinterleave in1.nii in2.nii out.nii -i' +""" + +__all__ = ["FSLInterleave"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLInterleaveSpec(pydra.specs.ShellSpec): + """Specifications for fslinterleave.""" + + input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "argstr": ""}) + + other_image: os.PathLike = attrs.field(metadata={"help_string": "other image", "argstr": ""}) + + output_image: str = attrs.field( + metadata={ + "help_string": "output_image", + "argstr": "", + "output_file_template": "{input_image}_interleaved", + } + ) + + reverse: bool = attrs.field(metadata={"help_string": "reverse slice order", "argstr": "-i"}) + + +class FSLInterleave(pydra.engine.ShellCommandTask): + """Task definition for fslinterleave.""" + + executable = "fslinterleave" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLInterleaveSpec,)) From cd007617b51ac1893612030a112b6572f2dcd0ca Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 156/224] FIX: Declare input_image and other_image mandatory --- src/pydra/tasks/fsl/utils/fslinterleave.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pydra/tasks/fsl/utils/fslinterleave.py b/src/pydra/tasks/fsl/utils/fslinterleave.py index b85c785..4f5453d 100644 --- a/src/pydra/tasks/fsl/utils/fslinterleave.py +++ b/src/pydra/tasks/fsl/utils/fslinterleave.py @@ -34,9 +34,9 @@ class FSLInterleaveSpec(pydra.specs.ShellSpec): """Specifications for fslinterleave.""" - input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "argstr": ""}) + input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) - other_image: os.PathLike = attrs.field(metadata={"help_string": "other image", "argstr": ""}) + other_image: os.PathLike = attrs.field(metadata={"help_string": "other image", "mandatory": True, "argstr": ""}) output_image: str = attrs.field( metadata={ From a9013f77f465b7bb95a41796b60c591bf1fab255 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 157/224] NEW: Add task definition for fslselectvols --- README.md | 20 ++--- src/pydra/tasks/fsl/__init__.py | 1 + src/pydra/tasks/fsl/utils/__init__.py | 1 + src/pydra/tasks/fsl/utils/fslselectvols.py | 89 ++++++++++++++++++++++ 4 files changed, 101 insertions(+), 10 deletions(-) create mode 100644 src/pydra/tasks/fsl/utils/fslselectvols.py diff --git a/README.md b/README.md index a1f1461..af1f21b 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|----------------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | -| susan | SUSAN | -| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSlice, FSLSplit, FSLSwapDim | +| Module | Tasks | +|--------|-------------------------------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | +| susan | SUSAN | +| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSplit, FSLSwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 80997e3..57604fe 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -30,6 +30,7 @@ FSLInterleave, FSLMerge, FSLReorient2Std, + FSLSelectVols, FSLSlice, FSLSplit, FSLSwapDim, diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index b48f806..532243c 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -6,5 +6,6 @@ from .fslmerge import FSLMerge from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI +from .fslselectvols import FSLSelectVols from .fslsplit import FSLSlice, FSLSplit from .fslswapdim import FSLSwapDim diff --git a/src/pydra/tasks/fsl/utils/fslselectvols.py b/src/pydra/tasks/fsl/utils/fslselectvols.py new file mode 100644 index 0000000..d8fbc5a --- /dev/null +++ b/src/pydra/tasks/fsl/utils/fslselectvols.py @@ -0,0 +1,89 @@ +""" +FSLSelectVols +============= + +Examples +-------- + +Select volumes from a list and concatenate them: + +>>> task = FSLSelectVols(input_image="input.nii", volumes=[0, 1, 6, 7]) +>>> task.cmdline +'fslselectvols --in input.nii --out .../input_vols.nii --vols 0,1,6,7' + +Select volumes from a file and calculate their mean: + +>>> task = FSLSelectVols( +... input_image="input.nii", +... output_image="mean.nii", +... volumes="volumes.txt", +... calculate_mean=True, +... ) +>>> task.cmdline +'fslselectvols --in input.nii --out mean.nii --vols volumes.txt -m' + +Select volumes from a file and calculate their variance: + +>>> task = FSLSelectVols( +... input_image="input.nii", +... output_image="variance.nii", +... volumes="volumes.txt", +... calculate_variance=True, +... ) +>>> task.cmdline +'fslselectvols --in input.nii --out variance.nii --vols volumes.txt -v' +""" + +__all__ = ["FSLSelectVols"] + +import os +import typing as ty + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLSelectVolsSpec(pydra.specs.ShellSpec): + """Specifications for fslselectvols.""" + + input_image: os.PathLike = attrs.field(metadata={"help_string": "input_image", "mandatory": True, "argstr": "--in"}) + + output_image: str = attrs.field( + metadata={"help_string": "output image", "argstr": "--out", "output_file_template": "{input_image}_vols"} + ) + + volumes: ty.Union[os.PathLike, ty.Iterable[int]] = attrs.field( + metadata={ + "help_string": "volumes to select (from a file or as a list)", + "mandatory": True, + "formatter": lambda field: ( + f"--vols {str(field) if isinstance(field, (os.PathLike, str)) else ','.join(map(str, field))}" + ), + } + ) + + calculate_mean: bool = attrs.field( + metadata={ + "help_string": "calculate mean instead of concatenating", + "argstr": "-m", + "xor": {"calculate_variance"}, + } + ) + + calculate_variance: bool = attrs.field( + metadata={ + "help_string": "calculate variance instead of concatenating", + "argstr": "-v", + "xor": {"calculate_mean"}, + } + ) + + +class FSLSelectVols(pydra.engine.ShellCommandTask): + """Task definition for fslselectvols.""" + + executable = "fslselectvols" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLSelectVolsSpec,)) From 19556ffd551d2d090f7b6f6293f0b70ac4dc1ab5 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 158/224] NEW: Add task definition for fslsmoothfill --- README.md | 20 +++++----- src/pydra/tasks/fsl/__init__.py | 1 + src/pydra/tasks/fsl/utils/__init__.py | 1 + src/pydra/tasks/fsl/utils/fslsmoothfill.py | 46 ++++++++++++++++++++++ 4 files changed, 58 insertions(+), 10 deletions(-) create mode 100644 src/pydra/tasks/fsl/utils/fslsmoothfill.py diff --git a/README.md b/README.md index af1f21b..fba5d5d 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,16 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|-------------------------------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | -| susan | SUSAN | -| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSplit, FSLSwapDim | +| Module | Tasks | +|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE | +| susan | SUSAN | +| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 57604fe..2b0fd9a 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -32,6 +32,7 @@ FSLReorient2Std, FSLSelectVols, FSLSlice, + FSLSmoothFill, FSLSplit, FSLSwapDim, fslmaths, diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index 532243c..6d4f1d3 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -7,5 +7,6 @@ from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI from .fslselectvols import FSLSelectVols +from .fslsmoothfill import FSLSmoothFill from .fslsplit import FSLSlice, FSLSplit from .fslswapdim import FSLSwapDim diff --git a/src/pydra/tasks/fsl/utils/fslsmoothfill.py b/src/pydra/tasks/fsl/utils/fslsmoothfill.py new file mode 100644 index 0000000..0c6cc42 --- /dev/null +++ b/src/pydra/tasks/fsl/utils/fslsmoothfill.py @@ -0,0 +1,46 @@ +""" +FSLSmoothFill +============= + +Examples +-------- + +>>> task = FSLSmoothFill(input_image="input.nii", output_image="smoothed.nii", input_mask="mask.nii") +>>> task.cmdline +'fslsmoothfill --in input.nii --out smoothed.nii --mask mask.nii' +""" + +__all__ = ["FSLSmoothFill"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLSmoothFillSpec(pydra.specs.ShellSpec): + """Specifications for fslsmoothfill.""" + + input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"}) + + output_image: str = attrs.field( + metadata={ + "help_string": "output image", + "argstr": "--out", + "output_file_template": "{input_image}_smoothed", + } + ) + + input_mask: os.PathLike = attrs.field(metadata={"help_string": "input mask", "argstr": "--mask"}) + + num_iterations: int = attrs.field(metadata={"help_string": "number of iterations", "argstr": "--niter"}) + + +class FSLSmoothFill(pydra.engine.ShellCommandTask): + """Task definition for fslsmoothfill.""" + + executable = "fslsmoothfill" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLSmoothFillSpec,)) From 0e80f6704c6dc3a9880b6a0aa5fb756603579a9e Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 159/224] MNT: Bump version to 0.0.14 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index dd55d58..1639764 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.13" +version = "0.0.14" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 6e8014d41c03b93ae88e0b2df41ee14af7403baf Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 160/224] FIX: Correct typos and formatting --- src/pydra/tasks/fsl/bet/bet.py | 4 ++-- src/pydra/tasks/fsl/eddy.py | 4 ++-- src/pydra/tasks/fsl/fast.py | 4 ++-- src/pydra/tasks/fsl/utils/fslreorient2std.py | 2 +- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/pydra/tasks/fsl/bet/bet.py b/src/pydra/tasks/fsl/bet/bet.py index 9ef954f..4fc62e7 100644 --- a/src/pydra/tasks/fsl/bet/bet.py +++ b/src/pydra/tasks/fsl/bet/bet.py @@ -74,14 +74,14 @@ class BETSpec(pydra.specs.ShellSpec): head_radius: float = attrs.field( metadata={ - "help_string": ("Head radius (in millimeters)." " Initial surface sphere is set to half of this value."), + "help_string": "Head radius (in millimeters)." " Initial surface sphere is set to half of this value.", "argstr": "-r", } ) center_of_gravity: ty.Tuple[int, int, int] = attrs.field( metadata={ - "help_string": ("centre-of-gravity (in voxel coordinates) of initial mesh surface"), + "help_string": "centre-of-gravity (in voxel coordinates) of initial mesh surface", "argstr": "-c", } ) diff --git a/src/pydra/tasks/fsl/eddy.py b/src/pydra/tasks/fsl/eddy.py index 8944cfd..6b2e079 100644 --- a/src/pydra/tasks/fsl/eddy.py +++ b/src/pydra/tasks/fsl/eddy.py @@ -21,7 +21,7 @@ class EddySpec(pydra.specs.ShellSpec): # Parameters that specify input files. input_image: os.PathLike = attrs.field( metadata={ - "help_string": ("input image as a 4D volume of all images acquired in the diffusion protocol"), + "help_string": "input image as a 4D volume of all images acquired in the diffusion protocol", "mandatory": True, "argstr": "--imain", } @@ -131,7 +131,7 @@ class EddySpec(pydra.specs.ShellSpec): fwhm: float = attrs.field( default=0, metadata={ - "help_string": ("filter width used for pre-conditionning data prior to estimating distortions"), + "help_string": "filter width used for pre-conditioning data prior to estimating distortions", "argstr": "--fwhm", }, ) diff --git a/src/pydra/tasks/fsl/fast.py b/src/pydra/tasks/fsl/fast.py index 9b4957d..192fec9 100644 --- a/src/pydra/tasks/fsl/fast.py +++ b/src/pydra/tasks/fsl/fast.py @@ -2,7 +2,7 @@ FMRIB's Automated Segmentation Tool (FAST) ========================================== -FAST performs automtic segmentation of 3D images of the brain +FAST performs automatic segmentation of 3D images of the brain using hidden Markov random field model and the expectation-maximization algorithm. """ @@ -172,7 +172,7 @@ class FASTOutSpec(pydra.specs.ShellOutSpec): probability_maps: pydra.specs.MultiOutputFile = attrs.field( metadata={ - "help_string": "posterior probablity mapping for each class", + "help_string": "posterior probability mapping for each class", "requires": ["save_probability_maps"], "callable": get_probability_maps, } diff --git a/src/pydra/tasks/fsl/utils/fslreorient2std.py b/src/pydra/tasks/fsl/utils/fslreorient2std.py index cccf681..a478ceb 100644 --- a/src/pydra/tasks/fsl/utils/fslreorient2std.py +++ b/src/pydra/tasks/fsl/utils/fslreorient2std.py @@ -24,7 +24,7 @@ @attrs.define(slots=False, kw_only=True) class FSLReorient2StdSpec(pydra.specs.ShellSpec): - """Specificiations for fslreorient2std.""" + """Specifications for fslreorient2std.""" input_image: os.PathLike = attrs.field( metadata={ From 29a64492d5b47aa4586c0056776709194883d86b Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 161/224] FIX: Typo in output field name --- src/pydra/tasks/fsl/utils/fslinfo.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pydra/tasks/fsl/utils/fslinfo.py b/src/pydra/tasks/fsl/utils/fslinfo.py index 604c850..f0a70d9 100644 --- a/src/pydra/tasks/fsl/utils/fslinfo.py +++ b/src/pydra/tasks/fsl/utils/fslinfo.py @@ -93,7 +93,7 @@ class FSLInfoOutSpec(pydra.specs.ShellOutSpec): } ) - pixedim4: float = attrs.field( + pixdim4: float = attrs.field( metadata={ "help_string": "pixel spacing in 4th dimension", "callable": lambda stdout: float(re.search(r"pixdim4\s*(.*)", stdout).group(1)), From f8d3dec5bd1b4c9169bd16ba17822a354a2b41fb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 162/224] MNT: Bump version to 0.0.15 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1639764..c792ce4 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.14" +version = "0.0.15" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 742d060f0f33cb97b49af7dedd71083b7fb4b322 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 163/224] NEW: Add task definition for sigloss --- README.md | 2 +- src/pydra/tasks/fsl/__init__.py | 2 +- src/pydra/tasks/fsl/fugue/__init__.py | 2 + src/pydra/tasks/fsl/{ => fugue}/fugue.py | 0 src/pydra/tasks/fsl/fugue/sigloss.py | 58 ++++++++++++++++++++++++ 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 src/pydra/tasks/fsl/fugue/__init__.py rename src/pydra/tasks/fsl/{ => fugue}/fugue.py (100%) create mode 100644 src/pydra/tasks/fsl/fugue/sigloss.py diff --git a/README.md b/README.md index fba5d5d..2ef73be 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ for FMRI, MRI and DTI brain imaging data. | fast | FAST | | flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE | +| fugue | FUGUE, SigLoss | | susan | SUSAN | | utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 2b0fd9a..9059275 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -20,7 +20,7 @@ Std2ImgCoord, ) from .fnirt import FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp -from .fugue import FUGUE +from .fugue import FUGUE, SigLoss from .susan import SUSAN from .utils import ( FSLFFT, diff --git a/src/pydra/tasks/fsl/fugue/__init__.py b/src/pydra/tasks/fsl/fugue/__init__.py new file mode 100644 index 0000000..f758507 --- /dev/null +++ b/src/pydra/tasks/fsl/fugue/__init__.py @@ -0,0 +1,2 @@ +from .fugue import FUGUE +from .sigloss import SigLoss diff --git a/src/pydra/tasks/fsl/fugue.py b/src/pydra/tasks/fsl/fugue/fugue.py similarity index 100% rename from src/pydra/tasks/fsl/fugue.py rename to src/pydra/tasks/fsl/fugue/fugue.py diff --git a/src/pydra/tasks/fsl/fugue/sigloss.py b/src/pydra/tasks/fsl/fugue/sigloss.py new file mode 100644 index 0000000..6aed5ba --- /dev/null +++ b/src/pydra/tasks/fsl/fugue/sigloss.py @@ -0,0 +1,58 @@ +""" +SigLoss +======= + +Estimate signal loss from a B0 map. + +Examples +-------- + +>>> task = SigLoss(input_image="b0map.nii", input_mask="mask.nii", output_image="sigloss.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'sigloss ... --in b0map.nii --mask mask.nii --sigloss sigloss.nii' +""" + +__all__ = ["SigLoss"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class SigLossSpec(pydra.specs.ShellSpec): + """Specifications for sigloss.""" + + echo_time: float = attrs.field( + default=1.0, + metadata={"help_string": "echo time in seconds", "argstr": "--te"}, + ) + + slice_direction: str = attrs.field( + default="z", + metadata={"help_string": "slice direction", "argstr": "--slicedir", "allowed_values": {"x", "y", "z"}}, + ) + + input_image: os.PathLike = attrs.field( + metadata={"help_string": "input B0-map image in rad/s", "mandatory": True, "argstr": "--in"} + ) + + input_mask: os.PathLike = attrs.field(metadata={"help_string": "input mask", "argstr": "--mask"}) + + output_image: str = attrs.field( + metadata={ + "help_string": "output signal-loss image", + "argstr": "--sigloss", + "output_file_template": "{input_image}_sigloss", + } + ) + + +class SigLoss(pydra.engine.ShellCommandTask): + """Task definition for sigloss.""" + + executable = "sigloss" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(SigLossSpec,)) From 6d05517189b8904aec633323f59205a6713e1ba6 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 164/224] NEW: Add task definition for prelude --- README.md | 2 +- src/pydra/tasks/fsl/__init__.py | 2 +- src/pydra/tasks/fsl/fugue/__init__.py | 1 + src/pydra/tasks/fsl/fugue/prelude.py | 152 ++++++++++++++++++++++++++ 4 files changed, 155 insertions(+), 2 deletions(-) create mode 100644 src/pydra/tasks/fsl/fugue/prelude.py diff --git a/README.md b/README.md index 2ef73be..6cbcd8a 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ for FMRI, MRI and DTI brain imaging data. | fast | FAST | | flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, SigLoss | +| fugue | FUGUE, Prelude, SigLoss | | susan | SUSAN | | utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 9059275..3138909 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -20,7 +20,7 @@ Std2ImgCoord, ) from .fnirt import FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp -from .fugue import FUGUE, SigLoss +from .fugue import FUGUE, Prelude, SigLoss from .susan import SUSAN from .utils import ( FSLFFT, diff --git a/src/pydra/tasks/fsl/fugue/__init__.py b/src/pydra/tasks/fsl/fugue/__init__.py index f758507..1596497 100644 --- a/src/pydra/tasks/fsl/fugue/__init__.py +++ b/src/pydra/tasks/fsl/fugue/__init__.py @@ -1,2 +1,3 @@ from .fugue import FUGUE +from .prelude import Prelude from .sigloss import SigLoss diff --git a/src/pydra/tasks/fsl/fugue/prelude.py b/src/pydra/tasks/fsl/fugue/prelude.py new file mode 100644 index 0000000..ab67359 --- /dev/null +++ b/src/pydra/tasks/fsl/fugue/prelude.py @@ -0,0 +1,152 @@ +""" +Prelude +======= + +Phase Region Expanding Labeller for Unwrapping Discrete Estimates. + +Examples +-------- + +>>> task = Prelude(complex_image="complex.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'prelude --complex complex.nii --out complex_unwrapped_phase.nii --rawphase complex_raw_phase.nii \ +--labels complex_labels.nii --savemask complex_mask.nii ...' + +>>> task = Prelude( +... phase_image="phase.nii", +... magnitude_image="magnitude.nii", +... output_unwrapped_phase_image="unwrapped.nii", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'prelude --abs magnitude.nii --phase phase.nii --out unwrapped.nii ...' +""" + +__all__ = ["Prelude"] + +import os + +import attrs + +import pydra + + +def _output_filename_factory(complex_image, phase_image, suffix): + from pathlib import PurePath + + stem, ext = PurePath(complex_image or phase_image).name.split(".", maxsplit=1) + + return f"{stem}_{suffix}.{ext}" + + +@attrs.define(slots=False, kw_only=True) +class PreludeSpec(pydra.specs.ShellSpec): + """Specifications for prelude.""" + + complex_image: os.PathLike = attrs.field( + metadata={ + "help_string": "complex phase image", + "mandatory": True, + "argstr": "--complex", + "xor": {"phase_image"}, + } + ) + + magnitude_image: os.PathLike = attrs.field(metadata={"help_string": "magnitude image", "argstr": "--abs"}) + + phase_image: os.PathLike = attrs.field( + metadata={ + "help_string": "raw phase image", + "mandatory": True, + "argstr": "--phase", + "requires": {"magnitude_image"}, + "xor": {"complex_image"}, + } + ) + + input_mask: os.PathLike = attrs.field(metadata={"help_string": "input mask", "argstr": "--mask"}) + + output_unwrapped_phase_image: str = attrs.field( + metadata={ + "help_string": "output unwrapped phase image", + "formatter": lambda field, complex_image, phase_image: "--out {}".format( + field or _output_filename_factory(complex_image, phase_image, "unwrapped_phase") + ), + } + ) + + output_raw_phase_image: str = attrs.field( + metadata={ + "help_string": "output raw phase image", + "formatter": lambda field, complex_image, phase_image: "--rawphase {}".format( + field or _output_filename_factory(complex_image, phase_image, "raw_phase") + ), + } + ) + + output_labels: str = attrs.field( + metadata={ + "help_string": "output labels", + "formatter": lambda field, complex_image, phase_image: "--labels {}".format( + field or _output_filename_factory(complex_image, phase_image, "labels") + ), + } + ) + + output_mask: os.PathLike = attrs.field( + metadata={ + "help_string": "output mask", + "formatter": lambda field, complex_image, phase_image: "--savemask {}".format( + field or _output_filename_factory(complex_image, phase_image, "mask") + ), + } + ) + + num_partitions: int = attrs.field( + default=8, metadata={"help_string": "number of phase partitions", "argstr": "--numphasesplit"} + ) + + process_labels_in_2d: bool = attrs.field( + metadata={ + "help_string": "process labels in 2D", + "argstr": "--labelslices", + "xor": {"process_all_in_2d", "process_all_in_3d"}, + } + ) + + process_all_in_2d: bool = attrs.field( + metadata={ + "help_string": "process all in 2D", + "argstr": "--slices", + "xor": {"process_labels_in_2d", "process_all_in_3d"}, + } + ) + + process_all_in_3d: bool = attrs.field( + metadata={ + "help_string": "process all in 3D", + "argstr": "--force3D", + "xor": {"process_labels_in_2d", "process_all_in_2d"}, + } + ) + + threshold: float = attrs.field( + default=0.0, metadata={"help_string": "intensity threshold for masking", "argstr": "--thresh"} + ) + + first_image_index: int = attrs.field( + metadata={"help_string": "index of first image to process", "argstr": "--start"} + ) + + last_image_index: int = attrs.field(metadata={"help_string": "index of last image to process", "argstr": "--end"}) + + remove_ramps: bool = attrs.field( + metadata={"help_string": "remove phase ramps during unwrapping", "argstr": "--removeramps"} + ) + + +class Prelude(pydra.engine.ShellCommandTask): + """Task definition for prelude.""" + + executable = "prelude" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(PreludeSpec,)) From 4cf612c6770893f7320fbeca39aae93599072546 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 165/224] REF: Move ApplyXFM to flirt module --- src/pydra/tasks/fsl/flirt/__init__.py | 3 +- src/pydra/tasks/fsl/flirt/applyxfm.py | 116 ---------------------- src/pydra/tasks/fsl/flirt/flirt.py | 135 ++++++++++++++++++-------- 3 files changed, 97 insertions(+), 157 deletions(-) delete mode 100644 src/pydra/tasks/fsl/flirt/applyxfm.py diff --git a/src/pydra/tasks/fsl/flirt/__init__.py b/src/pydra/tasks/fsl/flirt/__init__.py index 472cac4..96b8224 100644 --- a/src/pydra/tasks/fsl/flirt/__init__.py +++ b/src/pydra/tasks/fsl/flirt/__init__.py @@ -1,7 +1,6 @@ -from .applyxfm import ApplyXFM from .concatxfm import ConcatXFM from .convertxfm import ConvertXFM -from .flirt import FLIRT +from .flirt import FLIRT, ApplyXFM from .img2imgcoord import Img2ImgCoord from .img2stdcoord import Img2StdCoord from .invertxfm import InvertXFM diff --git a/src/pydra/tasks/fsl/flirt/applyxfm.py b/src/pydra/tasks/fsl/flirt/applyxfm.py deleted file mode 100644 index 604f8cd..0000000 --- a/src/pydra/tasks/fsl/flirt/applyxfm.py +++ /dev/null @@ -1,116 +0,0 @@ -""" -ApplyXFM -======== - -Examples --------- - ->>> task = ApplyXFM( -... input_image="input.nii", -... reference_image="reference.nii", -... input_matrix="affine.mat", -... ) ->>> task.cmdline # doctest: +ELLIPSIS -'flirt -in input.nii -ref reference.nii -init affine.mat -out .../input_axfm.nii \ --applyxfm -interp trilinear' - ->>> task = ApplyXFM( -... input_image="input.nii", -... reference_image="reference.nii", -... input_matrix="affine.mat", -... isotropic_resolution=1, -... padding_size=5, -... ) ->>> task.cmdline # doctest: +ELLIPSIS -'flirt -in input.nii -ref reference.nii -init affine.mat -out .../input_axfm.nii \ --applyisoxfm 1 -paddingsize 5 -interp trilinear' - -""" - -__all__ = ["ApplyXFM"] - -import os - -import attrs - -import pydra - -from . import specs -from .flirt import FLIRT - - -@attrs.define(slots=False, kw_only=True) -class ApplyXFMSpec(pydra.specs.ShellSpec): - """Specifications for ApplyXFM.""" - - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "-in", - } - ) - - reference_image: os.PathLike = attrs.field( - metadata={ - "help_string": "reference image", - "mandatory": True, - "argstr": "-ref", - } - ) - - input_matrix: os.PathLike = attrs.field( - metadata={ - "help_string": "input transformation matrix", - "mandatory": True, - "argstr": "-init", - } - ) - - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "-out", - "output_file_template": "{input_image}_axfm", - } - ) - - output_datatype: str = attrs.field( - metadata={ - "help_string": "output datatype", - "argstr": "-datatype", - "allowed_values": { - "char", - "short", - "int", - "float", - "double", - }, - } - ) - - isotropic_resolution: float = attrs.field( - default=0.0, - metadata={ - "help_string": "force resampling to isotropic resolution", - "formatter": lambda isotropic_resolution: ( - f"-applyisoxfm {isotropic_resolution}" if isotropic_resolution else "-applyxfm" - ), - }, - ) - - padding_size: float = attrs.field( - metadata={ - "help_string": "padding size in voxels", - "argstr": "-paddingsize", - } - ) - - -class ApplyXFM(FLIRT): - """Task definition for ApplyXFM.""" - - input_spec = pydra.specs.SpecInfo( - name="ApplyXFMInput", - bases=(ApplyXFMSpec, specs.InterpolationSpec), - ) diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py index 54d2716..5684e10 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/src/pydra/tasks/fsl/flirt/flirt.py @@ -11,35 +11,55 @@ Register two images together: >>> task = FLIRT( -... input_image="invol", -... reference_image="refvol", -... output_image="outvol", +... input_image="invol.nii", +... reference_image="refvol.nii", ... output_matrix="invol2refvol.mat", ... cost_function="mutualinfo", ... degrees_of_freedom=6, ... ) ->>> task.cmdline -'flirt -in invol -ref refvol -omat invol2refvol.mat -out outvol \ --dof 6 -searchrx -90 90 -searchry -90 90 -searchrz -90 90 \ --cost mutualinfo -bins 256 -interp trilinear' +>>> task.cmdline # doctest: +ELLIPSIS +'flirt -in invol.nii -ref refvol.nii -out ...invol_flirt.nii -omat invol2refvol.mat ... -cost mutualinfo ...' Perform a single slice registration: >>> task = FLIRT( -... input_image="inslice", -... reference_image="refslice", -... output_image="outslice", +... input_image="inslice.nii", +... reference_image="refslice.nii", +... output_image="outslice.nii", ... output_matrix="i2r.mat", ... interpolation="nearestneighbour", ... use_2d_registration=True, ... no_search=True, ... ) >>> task.cmdline -'flirt -in inslice -ref refslice -omat i2r.mat -out outslice -2D \ --nosearch -cost corratio -bins 256 -interp nearestneighbour' +'flirt -in inslice.nii -ref refslice.nii -out outslice.nii -omat i2r.mat -2D -nosearch ... -interp nearestneighbour' + +Apply a transformation: + +>>> task = ApplyXFM( +... input_image="invol.nii", +... output_image="outvol.nii", +... reference_image="refvol.nii", +... input_matrix="affine.mat", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'flirt -in invol.nii -ref refvol.nii -out outvol.nii -init affine.mat -applyxfm ...' + +Apply a trasnformation and force isotropic resampling to 1 mm: + +>>> task = ApplyXFM( +... input_image="invol.nii", +... output_image="outvol.nii", +... reference_image="refvol.nii", +... input_matrix="affine.mat", +... isotropic_resolution=1, +... padding_size=5, +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'flirt -in invol.nii -ref refvol.nii -out outvol.nii -init affine.mat -applyisoxfm 1 -paddingsize 5 ...' """ -__all__ = ["FLIRT"] +__all__ = ["FLIRT", "ApplyXFM"] import os @@ -51,8 +71,8 @@ @attrs.define(slots=False, kw_only=True) -class FLIRTSpec(pydra.specs.ShellSpec): - """Specifications for FLIRT.""" +class BaseSpec(pydra.specs.ShellSpec): + """Common specifications for FLIRT-based tasks.""" input_image: os.PathLike = attrs.field( metadata={ @@ -70,25 +90,9 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) - input_matrix: os.PathLike = attrs.field( - metadata={ - "help_string": "input transformation matrix", - "argstr": "-init", - } - ) - - output_matrix: str = attrs.field( - metadata={ - "help_string": "output transformation matrix", - "argstr": "-omat", - "output_file_template": "{input_image}_flirt.mat", - "keep_extension": False, - } - ) - output_image: str = attrs.field( metadata={ - "help_string": "output volume", + "help_string": "output image", "argstr": "-out", "output_file_template": "{input_image}_flirt", } @@ -108,6 +112,27 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) + +@attrs.define(slots=False, kw_only=True) +class FLIRTSpec(BaseSpec): + """Specifications for FLIRT.""" + + input_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "input transformation matrix", + "argstr": "-init", + } + ) + + output_matrix: str = attrs.field( + metadata={ + "help_string": "output transformation matrix", + "argstr": "-omat", + "output_file_template": "{input_image}_flirt.mat", + "keep_extension": False, + } + ) + degrees_of_freedom: int = attrs.field( metadata={ "help_string": "degrees of freedom for the registration model", @@ -125,13 +150,6 @@ class FLIRTSpec(pydra.specs.ShellSpec): } ) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "-v", - } - ) - class FLIRT(pydra.engine.ShellCommandTask): """Task definition for FLIRT.""" @@ -146,5 +164,44 @@ class FLIRT(pydra.engine.ShellCommandTask): specs.CostFunctionSpec, specs.InterpolationSpec, specs.WeightingSpec, + specs.VerboseSpec, ), ) + + +@attrs.define(slots=False, kw_only=True) +class ApplyXFMSpec(BaseSpec): + """Specifications for ApplyXFM.""" + + input_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": "input transformation matrix", + "mandatory": True, + "argstr": "-init", + } + ) + + isotropic_resolution: float = attrs.field( + default=0.0, + metadata={ + "help_string": "force resampling to isotropic resolution", + "formatter": lambda isotropic_resolution: ( + f"-applyisoxfm {isotropic_resolution}" if isotropic_resolution else "-applyxfm" + ), + }, + ) + + padding_size: float = attrs.field( + metadata={ + "help_string": "padding size in voxels", + "argstr": "-paddingsize", + } + ) + + +class ApplyXFM(FLIRT): + """Task definition for ApplyXFM.""" + + input_spec = pydra.specs.SpecInfo( + name="ApplyXFMInput", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec) + ) From 844d9b809bd3a094c9395f2ba040d67da8d0e019 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 166/224] REF: Move all convert_xfm based utils to same module Also adds missing FixScaleSkew task in case someone needs it. --- src/pydra/tasks/fsl/flirt/__init__.py | 4 +- src/pydra/tasks/fsl/flirt/concatxfm.py | 44 ----------- src/pydra/tasks/fsl/flirt/convertxfm.py | 101 ++++++++++++++++++------ src/pydra/tasks/fsl/flirt/invertxfm.py | 38 --------- 4 files changed, 79 insertions(+), 108 deletions(-) delete mode 100644 src/pydra/tasks/fsl/flirt/concatxfm.py delete mode 100644 src/pydra/tasks/fsl/flirt/invertxfm.py diff --git a/src/pydra/tasks/fsl/flirt/__init__.py b/src/pydra/tasks/fsl/flirt/__init__.py index 96b8224..e6dd3b4 100644 --- a/src/pydra/tasks/fsl/flirt/__init__.py +++ b/src/pydra/tasks/fsl/flirt/__init__.py @@ -1,7 +1,5 @@ -from .concatxfm import ConcatXFM -from .convertxfm import ConvertXFM +from .convertxfm import ConcatXFM, ConvertXFM, FixScaleSkew, InvertXFM from .flirt import FLIRT, ApplyXFM from .img2imgcoord import Img2ImgCoord from .img2stdcoord import Img2StdCoord -from .invertxfm import InvertXFM from .std2imgcoord import Std2ImgCoord diff --git a/src/pydra/tasks/fsl/flirt/concatxfm.py b/src/pydra/tasks/fsl/flirt/concatxfm.py deleted file mode 100644 index 9f800c9..0000000 --- a/src/pydra/tasks/fsl/flirt/concatxfm.py +++ /dev/null @@ -1,44 +0,0 @@ -""" -ConcatXFM -========= - -Examples --------- - ->>> task = ConcatXFM( -... input_matrix="AtoB.mat", -... concat_matrix="BtoC.mat", -... output_matrix="AtoC.mat", -... ) ->>> task.cmdline -'convert_xfm -omat AtoC.mat -concat BtoC.mat AtoB.mat' -""" - -__all__ = ["ConcatXFM"] - -import os - -import attrs - -import pydra - -from .convertxfm import BaseConvertXFMSpec, ConvertXFM - - -@attrs.define(slots=False, kw_only=True) -class ConcatXFMSpec(BaseConvertXFMSpec): - """Specifications for concat_xfm.""" - - concat_matrix: os.PathLike = attrs.field( - metadata={ - "help_string": "concatenate this matrix with input matrix", - "mandatory": True, - "argstr": "-concat", - } - ) - - -class ConcatXFM(ConvertXFM): - """Task definition for concat_xfm.""" - - input_spec = pydra.specs.SpecInfo(name="ConcatXFMInput", bases=(ConcatXFMSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/convertxfm.py b/src/pydra/tasks/fsl/flirt/convertxfm.py index 92d1b7a..cc8f61e 100644 --- a/src/pydra/tasks/fsl/flirt/convertxfm.py +++ b/src/pydra/tasks/fsl/flirt/convertxfm.py @@ -5,20 +5,32 @@ Examples -------- ->>> task = ConvertXFM(input_matrix="input.mat", inverse=True) ->>> task.cmdline # doctest: +ELLIPSIS -'convert_xfm -omat ...input_cxfm.mat -inverse input.mat' - ->>> task = ConvertXFM( -... input_matrix="AtoB.mat", -... concat_matrix="BtoC.mat", -... output_matrix="AtoC.mat", -... ) +Concatenate transformation matrix: + +>>> task = ConcatXFM(input_matrix="AtoB.mat", concat_matrix="BtoC.mat", output_matrix="AtoC.mat") >>> task.cmdline 'convert_xfm -omat AtoC.mat -concat BtoC.mat AtoB.mat' + +Invert transformation matrix: + +>>> task = InvertXFM(input_matrix="AtoB.mat", output_matrix="BtoA.mat") +>>> task.cmdline +'convert_xfm -omat BtoA.mat -inverse AtoB.mat' + +Fix scaling and skewness with additional matrix: + +>>> task = FixScaleSkew(input_matrix="A.mat", fixscaleskew_matrix="B.mat") +>>> task.cmdline +'convert_xfm -omat ...A_cxfm.mat -fixscaleskew B.mat A.mat' + +Use ConvertXFM to combine multiple operations at once, such as concatenation and inversion: + +>>> task = ConvertXFM(input_matrix="AtoB.mat", concat_matrix="BtoC.mat", inverse=True, output_matrix="CtoA.mat") +>>> task.cmdline +'convert_xfm -omat CtoA.mat -concat BtoC.mat -inverse AtoB.mat' """ -__all__ = ["ConvertXFM", "BaseConvertXFMSpec"] +__all__ = ["ConvertXFM", "ConcatXFM", "InvertXFM", "FixScaleSkew"] import os @@ -28,7 +40,7 @@ @attrs.define(slots=False, kw_only=True) -class BaseConvertXFMSpec(pydra.specs.ShellSpec): +class BaseSpec(pydra.specs.ShellSpec): """Base specifications for all tasks using convert_xfm.""" input_matrix: os.PathLike = attrs.field( @@ -50,27 +62,70 @@ class BaseConvertXFMSpec(pydra.specs.ShellSpec): @attrs.define(slots=False, kw_only=True) -class ConvertXFMSpec(BaseConvertXFMSpec): +class ConvertXFMSpec(BaseSpec): """Specifications for convert_xfm.""" - concat_matrix: os.PathLike = attrs.field( - metadata={ - "help_string": "concatenate this matrix with input matrix", - "argstr": "-concat", - } + fixscaleskew_matrix: os.PathLike = attrs.field( + metadata={"help_string": " fix scaling and skewness with this matrix", "argstr": "-fixscaleskew"} ) - inverse: bool = attrs.field( - metadata={ - "help_string": "return inverse of computed matrix", - "argstr": "-inverse", - } + concat_matrix: os.PathLike = attrs.field( + metadata={"help_string": "concatenate with this matrix", "argstr": "-concat"} ) + inverse: bool = attrs.field(metadata={"help_string": "invert the resulting matrix", "argstr": "-inverse"}) + class ConvertXFM(pydra.engine.ShellCommandTask): """Task definition for convert_xfm.""" executable = "convert_xfm" - input_spec = pydra.specs.SpecInfo(name="ConvertXFMInput", bases=(ConvertXFMSpec,)) + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(ConvertXFMSpec,)) + + +@attrs.define(slots=False, kw_only=True) +class ConcatXFMSpec(BaseSpec): + """Specifications for concat_xfm.""" + + concat_matrix: os.PathLike = attrs.field( + metadata={"help_string": "concatenate with this matrix", "mandatory": True, "argstr": "-concat"} + ) + + +class ConcatXFM(ConvertXFM): + """Task definition for matrix concatenation using convert_xfm.""" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(ConcatXFMSpec,)) + + +@attrs.define(slots=False, kw_only=True) +class InvertXFMSpec(BaseSpec): + """Specifications for invert_xfm.""" + + inverse: bool = attrs.field(default=True, metadata={"help_string": "invert the input matrix", "argstr": "-inverse"}) + + +class InvertXFM(ConvertXFM): + """Task definition for matrix inversion using convert_xfm.""" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(InvertXFMSpec,)) + + +@attrs.define(slots=False, kw_only=True) +class FixScaleSkewSpec(BaseSpec): + """Specifications for fixing matrix scaling and skewness using convert_xfm.""" + + fixscaleskew_matrix: os.PathLike = attrs.field( + metadata={ + "help_string": " fix scaling and skewness with this matrix", + "mandatory": True, + "argstr": "-fixscaleskew", + } + ) + + +class FixScaleSkew(ConvertXFM): + """Task definition for fixing matrix scaling and skewness using convert_xfm.""" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FixScaleSkewSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/invertxfm.py b/src/pydra/tasks/fsl/flirt/invertxfm.py deleted file mode 100644 index 0b71ab8..0000000 --- a/src/pydra/tasks/fsl/flirt/invertxfm.py +++ /dev/null @@ -1,38 +0,0 @@ -""" -InvertXFM -========= - -Examples --------- - ->>> task = InvertXFM(input_matrix="AtoB.mat", output_matrix="BtoA.mat") ->>> task.cmdline -'convert_xfm -omat BtoA.mat -inverse AtoB.mat' -""" - -__all__ = ["InvertXFM"] - -import attrs - -import pydra - -from .convertxfm import BaseConvertXFMSpec, ConvertXFM - - -@attrs.define(slots=False, kw_only=True) -class InvertXFMSpec(BaseConvertXFMSpec): - """Specifications for invert_xfm.""" - - inverse: bool = attrs.field( - default=True, - metadata={ - "help_string": "return inverse of computed matrix", - "argstr": "-inverse", - }, - ) - - -class InvertXFM(ConvertXFM): - """Task definition for concat_xfm.""" - - input_spec = pydra.specs.SpecInfo(name="InvertXFMInput", bases=(InvertXFMSpec,)) From d2e8f5b1f16d5d391699d80b04b6c95e74772378 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 167/224] NEW: Add task definition for fsl_prepare_fieldmap --- README.md | 2 +- src/pydra/tasks/fsl/__init__.py | 2 +- src/pydra/tasks/fsl/fugue/__init__.py | 1 + .../tasks/fsl/fugue/fsl_prepare_fieldmap.py | 60 +++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py diff --git a/README.md b/README.md index 6cbcd8a..a3b5105 100644 --- a/README.md +++ b/README.md @@ -32,7 +32,7 @@ for FMRI, MRI and DTI brain imaging data. | fast | FAST | | flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, Prelude, SigLoss | +| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | | susan | SUSAN | | utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 3138909..b4444dc 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -20,7 +20,7 @@ Std2ImgCoord, ) from .fnirt import FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp -from .fugue import FUGUE, Prelude, SigLoss +from .fugue import FUGUE, FSLPrepareFieldmap, Prelude, SigLoss from .susan import SUSAN from .utils import ( FSLFFT, diff --git a/src/pydra/tasks/fsl/fugue/__init__.py b/src/pydra/tasks/fsl/fugue/__init__.py index 1596497..edfc1d5 100644 --- a/src/pydra/tasks/fsl/fugue/__init__.py +++ b/src/pydra/tasks/fsl/fugue/__init__.py @@ -1,3 +1,4 @@ +from .fsl_prepare_fieldmap import FSLPrepareFieldmap from .fugue import FUGUE from .prelude import Prelude from .sigloss import SigLoss diff --git a/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py b/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py new file mode 100644 index 0000000..e14e83b --- /dev/null +++ b/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py @@ -0,0 +1,60 @@ +""" +FSLPrepareFieldmap +================== + +EPI fieldmap preprocessing. + +Examples +======== + +>>> task = FSLPrepareFieldmap(phase_image="gre_phase.nii", magnitude_image="gre_mag.nii", output_image="fmap.nii") +>>> task.cmdline +'fsl_prepare_fieldmap SIEMENS gre_phase.nii gre_mag.nii fmap.nii 2.46' +""" + +__all__ = ["FSLPrepareFieldmap"] + +import os + +import attrs + +import pydra + + +@attrs.define(slots=False, kw_only=True) +class FSLPrepareFieldmapSpec(pydra.specs.ShellSpec): + """Specifications for fsl_prepare_fieldmap.""" + + scanner: str = attrs.field(default="SIEMENS", metadata={"help_string": "scanner (usually SIEMENS)", "argstr": ""}) + + phase_image: os.PathLike = attrs.field(metadata={"help_string": "phase image", "mandatory": True, "argstr": ""}) + + magnitude_image: os.PathLike = attrs.field( + metadata={"help_string": "magnitude (brain extracted) image", "mandatory": True, "argstr": ""} + ) + + output_image: str = attrs.field( + metadata={ + "help_string": "output fieldmap image in rad/s", + "argstr": "", + "output_file_template": "{phase_image}_fmap", + } + ) + + delta_te: float = attrs.field( + default=2.46, + metadata={ + "help_string": "echo time difference of the fieldmap sequence in milliseconds (usually 2.46 on SIEMENS)", + "argstr": "", + }, + ) + + no_check: bool = attrs.field(metadata={"help_string": "disable sanity checks for images", "argstr": "--nocheck"}) + + +class FSLPrepareFieldmap(pydra.engine.ShellCommandTask): + """Task definition for fsl_prepare_fieldmap.""" + + executable = "fsl_prepare_fieldmap" + + input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLPrepareFieldmapSpec,)) From 5ac08c703af6242ac368778cb27f9341c7fd048a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 168/224] MNT: Bump version to 0.0.16 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index c792ce4..957f11e 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.15" +version = "0.0.16" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 3244a3ef0cf0fb9b8da68909ada488100e9a9315 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 169/224] REF: Move fslmaths module from utils to root --- README.md | 21 +++++++++++---------- src/pydra/tasks/fsl/__init__.py | 2 +- src/pydra/tasks/fsl/{utils => }/fslmaths.py | 0 src/pydra/tasks/fsl/utils/__init__.py | 1 - 4 files changed, 12 insertions(+), 12 deletions(-) rename src/pydra/tasks/fsl/{utils => }/fslmaths.py (100%) diff --git a/README.md b/README.md index a3b5105..de4ecee 100644 --- a/README.md +++ b/README.md @@ -25,16 +25,17 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|--------|----------------------------------------------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | -| susan | SUSAN | -| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | +| Module | Tasks | +|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | +| fslmaths | (**experimental**) FSLMaths, Mul | +| susan | SUSAN | +| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index b4444dc..bab4df1 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -6,6 +6,7 @@ >>> import pydra.tasks.fsl """ +from . import fslmaths from .bet import BET, RobustFOV from .eddy import Eddy from .fast import FAST @@ -35,5 +36,4 @@ FSLSmoothFill, FSLSplit, FSLSwapDim, - fslmaths, ) diff --git a/src/pydra/tasks/fsl/utils/fslmaths.py b/src/pydra/tasks/fsl/fslmaths.py similarity index 100% rename from src/pydra/tasks/fsl/utils/fslmaths.py rename to src/pydra/tasks/fsl/fslmaths.py diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index 6d4f1d3..fbc1ebe 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -1,4 +1,3 @@ -from . import fslmaths from .fslchfiletype import FSLChFileType from .fslfft import FSLFFT from .fslinfo import FSLInfo From 7e67ebfc2cb8f2b8702d5c1d89131cf1d4fa4294 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 170/224] NEW: Add task definition for fslorient --- README.md | 22 +++---- src/pydra/tasks/fsl/__init__.py | 1 + src/pydra/tasks/fsl/utils/__init__.py | 1 + src/pydra/tasks/fsl/utils/fslorient.py | 86 ++++++++++++++++++++++++++ 4 files changed, 99 insertions(+), 11 deletions(-) create mode 100644 src/pydra/tasks/fsl/utils/fslorient.py diff --git a/README.md b/README.md index de4ecee..5fed9c0 100644 --- a/README.md +++ b/README.md @@ -25,17 +25,17 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|----------|----------------------------------------------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | -| fslmaths | (**experimental**) FSLMaths, Mul | -| susan | SUSAN | -| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | +| Module | Tasks | +|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | +| fslmaths | (**experimental**) FSLMaths, Mul | +| susan | SUSAN | +| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLOrient, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index bab4df1..224e00f 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -30,6 +30,7 @@ FSLInfo, FSLInterleave, FSLMerge, + FSLOrient, FSLReorient2Std, FSLSelectVols, FSLSlice, diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index fbc1ebe..96c2dc7 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -3,6 +3,7 @@ from .fslinfo import FSLInfo from .fslinterleave import FSLInterleave from .fslmerge import FSLMerge +from .fslorient import FSLOrient from .fslreorient2std import FSLReorient2Std from .fslroi import FSLROI from .fslselectvols import FSLSelectVols diff --git a/src/pydra/tasks/fsl/utils/fslorient.py b/src/pydra/tasks/fsl/utils/fslorient.py new file mode 100644 index 0000000..9986288 --- /dev/null +++ b/src/pydra/tasks/fsl/utils/fslorient.py @@ -0,0 +1,86 @@ +""" +FSLOrient +========= + +Change the orientation of an image. + +Examples +-------- + +>>> import tempfile +>>> input_file = tempfile.NamedTemporaryFile(suffix="input.nii") + +Change orientation to radiological: + +>>> task = FSLOrient(input_image=input_file.name, force_radiological=True) +>>> task.cmdline # doctest: +ELLIPSIS +'fslorient -forceradiological ...input.nii' + +Change orientation to neurological: + +>>> task = FSLOrient(input_image=input_file.name, force_neurological=True) +>>> task.cmdline # doctest: +ELLIPSIS +'fslorient -forceneurological ...input.nii' + +Swap between radiological and neurological: + +>>> task = FSLOrient(input_image=input_file.name, swap_orientation=True) +>>> task.cmdline # doctest: +ELLIPSIS +'fslorient -swaporient ...input.nii' + +Delete orientation: + +>>> task = FSLOrient(input_image=input_file.name, delete_orientation=True) +>>> task.cmdline # doctest: +ELLIPSIS +'fslorient -deleteorient ...input.nii' +""" + +__all__ = ["FSLOrient"] + +from attrs import define, field +from pydra.engine import ShellCommandTask +from pydra.engine.specs import File, ShellOutSpec, ShellSpec, SpecInfo + + +@define(slots=False, kw_only=True) +class FSLOrientSpec(ShellSpec): + """Specifications for fslorient.""" + + _xor = {"delete_orientation", "force_radiological", "force_neurological", "swap_orientation"} + + input_image: File = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": "", "position": -1, "copyfile": True} + ) + + delete_orientation: bool = field( + metadata={"help_string": "delete orientation", "argstr": "-deleteorient", "xor": _xor} + ) + + force_radiological: bool = field( + metadata={"help_string": "force orientation to radiological", "argstr": "-forceradiological", "xor": _xor} + ) + + force_neurological: bool = field( + metadata={"help_string": "force orientation to neurological", "argstr": "-forceneurological", "xor": _xor} + ) + + swap_orientation: bool = field( + metadata={"help_string": "swap between radiological and neurological", "argstr": "-swaporient", "xor": _xor} + ) + + +@define(slots=False, kw_only=True) +class FSLOrientOutSpec(ShellOutSpec): + """Output specifications for fslorient.""" + + output_image: File = field(metadata={"help_string": "output image", "output_file_template": "{input_image}"}) + + +class FSLOrient(ShellCommandTask): + """Task definition for fslorient.""" + + executable = "fslorient" + + input_spec = SpecInfo(name="Inputs", bases=(FSLOrientSpec,)) + + output_spec = SpecInfo(name="Outputs", bases=(FSLOrientOutSpec,)) From 5c174ccb78d18d0dce6244846e0c4795a6356fcb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 171/224] FIX: Expose FixScaleSkew to root imports --- README.md | 2 +- src/pydra/tasks/fsl/__init__.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5fed9c0..ec4c3ae 100644 --- a/README.md +++ b/README.md @@ -30,7 +30,7 @@ for FMRI, MRI and DTI brain imaging data. | bet | BET, RobustFOV | | eddy | Eddy | | fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | | fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | | fslmaths | (**experimental**) FSLMaths, Mul | diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 224e00f..bf6bbfa 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -15,6 +15,7 @@ ApplyXFM, ConcatXFM, ConvertXFM, + FixScaleSkew, Img2ImgCoord, Img2StdCoord, InvertXFM, From 1f5591a85580608846670fd7f7bb2cce434f7ba7 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 172/224] MNT: Bump version to 0.0.17 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 957f11e..008b298 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.16" +version = "0.0.17" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 404e7fbe71c921c919880f9970cd4f9089022dd6 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 173/224] DOC: Remove fslmaths from utils --- README.md | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/README.md b/README.md index ec4c3ae..a4f243e 100644 --- a/README.md +++ b/README.md @@ -25,17 +25,17 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|----------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | -| fslmaths | (**experimental**) FSLMaths, Mul | -| susan | SUSAN | -| utils | fslmaths, FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLOrient, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | +| Module | Tasks | +|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | +| fslmaths | (**experimental**) FSLMaths, Mul | +| susan | SUSAN | +| utils | FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLOrient, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | ## Installation From e2c4d401f7a8b030493d71bf4c457b0986649f60 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 174/224] NEW: Add task definition for topup --- src/pydra/tasks/fsl/__init__.py | 2 +- src/pydra/tasks/fsl/eddy/__init__.py | 2 + src/pydra/tasks/fsl/{ => eddy}/eddy.py | 0 src/pydra/tasks/fsl/eddy/topup.py | 180 +++++++++++++++++++++++++ 4 files changed, 183 insertions(+), 1 deletion(-) create mode 100644 src/pydra/tasks/fsl/eddy/__init__.py rename src/pydra/tasks/fsl/{ => eddy}/eddy.py (100%) create mode 100644 src/pydra/tasks/fsl/eddy/topup.py diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index bf6bbfa..6da0c3c 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -8,7 +8,7 @@ from . import fslmaths from .bet import BET, RobustFOV -from .eddy import Eddy +from .eddy import Eddy, Topup from .fast import FAST from .flirt import ( FLIRT, diff --git a/src/pydra/tasks/fsl/eddy/__init__.py b/src/pydra/tasks/fsl/eddy/__init__.py new file mode 100644 index 0000000..ffa4753 --- /dev/null +++ b/src/pydra/tasks/fsl/eddy/__init__.py @@ -0,0 +1,2 @@ +from .eddy import Eddy +from .topup import Topup diff --git a/src/pydra/tasks/fsl/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py similarity index 100% rename from src/pydra/tasks/fsl/eddy.py rename to src/pydra/tasks/fsl/eddy/eddy.py diff --git a/src/pydra/tasks/fsl/eddy/topup.py b/src/pydra/tasks/fsl/eddy/topup.py new file mode 100644 index 0000000..19a2cf9 --- /dev/null +++ b/src/pydra/tasks/fsl/eddy/topup.py @@ -0,0 +1,180 @@ +""" +Topup +===== +""" + +__all__ = ["Topup"] + +from os import PathLike +from typing import Iterable + +from attrs import define, field +from pydra.engine.specs import File, ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(slots=False, kw_only=True) +class TopupSpec(ShellSpec): + """Specifications for topup.""" + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--imain"}) + + encoding_file: PathLike = field( + metadata={ + "help_string": "text file containing phase encoding directions and timings", + "mandatory": True, + "argstr": "--datain", + } + ) + + output_basename: str = field( + default="topup", + metadata={"help_string": "output basename for field coefficients and movement parameters", "argstr": "--out"}, + ) + + output_fieldmap_image: str = field( + metadata={ + "help_string": "output fieldmap image", + "argstr": "--fout", + "output_file_template": "{input_image}_fieldmap", + } + ) + + output_unwarped_image: str = field( + metadata={ + "help_string": "output unwarped image", + "argstr": "--iout", + "output_file_template": "{input_image}_unwarped", + } + ) + + warp_resolution_per_level: Iterable[float] = field( + default=(10,), + metadata={"help_string": "resolution of warp basis in millimeters for a given level", "argstr": "--warpres..."}, + ) + + subsampling_per_level: Iterable[int] = field( + default=(1,), + metadata={"help_string": "subsampling factor for a given level", "argstr": "--subsamp..."}, + ) + + smoothing_per_level: Iterable[float] = field( + default=(8,), + metadata={"help_string": "FWHM of smoothing kernel in millimeters for a given level", "argstr": "--fwhm..."}, + ) + + max_iterations_per_level: Iterable[int] = field( + default=(5,), + metadata={"help_string": "maximum number of non-linear iterations for a given level", "argstr": "--miter..."}, + ) + + regularisation_per_level: Iterable[float] = field( + default=(0,), + metadata={"help_string": "weight of regularisation for a given level", "argstr": "--lambda..."}, + ) + + estimate_movement_per_level: Iterable[int] = field( + default=(1,), + metadata={ + "help_string": "wether to estimate (1) or keep movement parameters constant (0) for a given level", + "argstr": "--estmov...", + "allowed_values": {0, 1}, + }, + ) + + minimisation_method_per_level: Iterable[int] = field( + default=(0,), + metadata={ + "help_string": ( + "which minimisation method to use for a given level " + "(0: Levenberg-Marquardt, 1: Scaled Conjugate Gradient)" + ), + "argstr": "--minmet...", + "allowed_values": {0, 1}, + }, + ) + + weight_regularisation_by_ssq: bool = field( + default=True, + metadata={ + "help_string": "weight regularisation by sum-of-squares", + "formatter": lambda field: f"--ssqlambda {int(field)}", + }, + ) + + regularisation_model: str = field( + default="bending_energy", + metadata={ + "help_string": "regularisation model", + "argstr": "--regmod", + "allowed_values": {"bending_energy", "membrane_energy"}, + }, + ) + + spline_order: int = field( + default=3, + metadata={ + "help_string": "use quadratic (2) or cubic (3) splines", + "argstr": "--splineorder", + "allowed_values": {2, 3}, + }, + ) + + precision: str = field( + default="double", + metadata={"help_string": "numerical precision", "argstr": "--numprec", "allowed_values": {"float", "double"}}, + ) + + interpolation: str = field( + default="spline", + metadata={"help_string": "interpolation model", "argstr": "--interp", "allowed_values": {"linear", "spline"}}, + ) + + scale: bool = field( + default=False, + metadata={ + "help_string": "scale images to a common mean", + "formatter": lambda field: f"--scale {int(field)}", + }, + ) + + regrid: bool = field( + default=True, + metadata={ + "help_string": "perform calculations on a different grid", + "formatter": lambda field: f"--regrid {int(field)}", + }, + ) + + num_threads: int = field(default=1, metadata={"help_string": "number of threads to use", "argstr": "--nthr"}) + + verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) + + +@define(slots=False, kw_only=True) +class TopupOutSpec(ShellOutSpec): + """Output specifications for topup.""" + + output_field_coefficients_image: File = field( + metadata={ + "help_string": "output field coefficients", + "output_file_template": "{output_basename}_fieldcoef.nii.gz", + } + ) + + output_movement_parameters_file: File = field( + metadata={ + "help_string": "output movement parameters", + "output_file_template": "{output_basename}_movpar.txt", + } + ) + + +class Topup(ShellCommandTask): + """Task definition for topup.""" + + executable = "topup" + + input_spec = SpecInfo(name="Inputs", bases=(TopupSpec,)) + + output_spec = SpecInfo(name="Outputs", bases=(TopupOutSpec,)) From b914b94f7f47fab0eaf95dc7f5ffaffca8c2aec2 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 175/224] NEW: Add task definition for applytopup --- src/pydra/tasks/fsl/__init__.py | 2 +- src/pydra/tasks/fsl/eddy/__init__.py | 1 + src/pydra/tasks/fsl/eddy/applytopup.py | 118 +++++++++++++++++++++++++ 3 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/pydra/tasks/fsl/eddy/applytopup.py diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 6da0c3c..9dd93e6 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -8,7 +8,7 @@ from . import fslmaths from .bet import BET, RobustFOV -from .eddy import Eddy, Topup +from .eddy import ApplyTopup, Eddy, Topup from .fast import FAST from .flirt import ( FLIRT, diff --git a/src/pydra/tasks/fsl/eddy/__init__.py b/src/pydra/tasks/fsl/eddy/__init__.py index ffa4753..5d489fb 100644 --- a/src/pydra/tasks/fsl/eddy/__init__.py +++ b/src/pydra/tasks/fsl/eddy/__init__.py @@ -1,2 +1,3 @@ +from .applytopup import ApplyTopup from .eddy import Eddy from .topup import Topup diff --git a/src/pydra/tasks/fsl/eddy/applytopup.py b/src/pydra/tasks/fsl/eddy/applytopup.py new file mode 100644 index 0000000..466005e --- /dev/null +++ b/src/pydra/tasks/fsl/eddy/applytopup.py @@ -0,0 +1,118 @@ +""" +ApplyTopup +========== +""" + +__all__ = ["ApplyTopup"] + +from os import PathLike +from pathlib import PurePath +from typing import Iterable + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(slots=False, kw_only=True) +class ApplyTopupSpec(ShellSpec): + """Specifications for applytopup.""" + + input_images: Iterable[PathLike] = field( + metadata={ + "help_string": "", + "mandatory": True, + "formatter": lambda field: f"--imain {','.join(field)}", + } + ) + + encoding_file: PathLike = field( + metadata={ + "help_string": "", + "mandatory": True, + "argstr": "--datain", + } + ) + + input_indexes: Iterable[int] = field( + metadata={ + "help_string": "indices mapping each input image to a row of the encoding file", + "mandatory": True, + "formatter": lambda field: f"--inindex {','.join(field)}", + } + ) + + @staticmethod + def to_topup_basename(field_coefficients_image: PathLike) -> str: + path = PurePath(field_coefficients_image) + + return str(path.parent / path.name.split(".", 1)[0]) + + topup_basename: str = field( + metadata={ + "help_string": "basename for topup files", + "requires": {"field_coefficients_image", "movement_parameters_file"}, + "formatter": to_topup_basename, + "readonly": True, + } + ) + + field_coefficients_image: PathLike = field( + metadata={"help_string": "field coefficients image computed by topup", "mandatory": True, "argstr": None} + ) + + movement_parameters_file: PathLike = field( + metadata={"help_string": "movement parameters file computed by topup", "mandatory": True, "argstr": None} + ) + + @staticmethod + def to_output_image(output_image: PathLike, input_images: Iterable[PathLike]) -> str: + if output_image: + path = PurePath(output_image) + else: + path = PurePath(input_images[0]) + name, ext = path.name.split(".", 1) + path = path.with_name(f"{name}_topup.{ext}") + + return f"--out {path}" + + output_image: PathLike = field( + metadata={"help_string": "output image", "argstr": "--out", "formatter": to_output_image} + ) + + method: str = field( + default="lsr", + metadata={ + "help_string": "resampling method", + "argstr": "--method", + "allowed_values": {"jac", "lsr", "vb2D", "vb3D", "vb4D"}, + }, + ) + + interpolation: str = field( + default="spline", + metadata={ + "help_string": "interpolation model", + "argstr": "--interp", + "allowed_values": {"spline", "trilinear"}, + }, + ) + + datatype: str = field( + default="preserve", + metadata={ + "help_string": "force output datatype", + "argstr": "--datatype", + "allowed_values": {"preserve", "char", "short", "int", "float", "double"}, + }, + ) + + verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) + + +class ApplyTopup(ShellCommandTask): + """Task definition for applytopup.""" + + executable = "applytopup" + + input_spec = SpecInfo(name="Input", bases=(ApplyTopupSpec,)) From 72a12390aaea09a3f68b2bc2f6c558550c28ca89 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 176/224] DOC: Update available interfaces --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index a4f243e..931e1d7 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ for FMRI, MRI and DTI brain imaging data. | Module | Tasks | |----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| | bet | BET, RobustFOV | -| eddy | Eddy | +| eddy | Eddy, ApplyTopup, Topup | | fast | FAST | | flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | From 7df3fb3d25a74e6e864f104dd820280ea75959c3 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 177/224] ENH: Add doctest for Topup --- src/pydra/tasks/fsl/eddy/topup.py | 71 +++++++++++++++++++++++++------ 1 file changed, 59 insertions(+), 12 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/topup.py b/src/pydra/tasks/fsl/eddy/topup.py index 19a2cf9..fe45d9f 100644 --- a/src/pydra/tasks/fsl/eddy/topup.py +++ b/src/pydra/tasks/fsl/eddy/topup.py @@ -1,11 +1,33 @@ """ Topup ===== + +Examples +-------- + +Minimal call to `topup`: + +>>> task = Topup(input_image="input.nii", encoding_file="encoding.txt") +>>> task.cmdline # doctest: +ELLIPSIS +'topup --imain input.nii --datain encoding.txt --out input_topup \ +--fout ...input_fieldmap.nii --iout ...input_unwarped.nii ...' + +Using a multiple resolution approach: + +>>> task = Topup( +... input_image="input.nii", +... encoding_file="encoding.txt", +... subsampling_per_level=(4, 2, 1), +... smoothing_per_level=(8.0, 4.0, 0.0), +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'topup --imain input.nii --datain encoding.txt ... --subsamp 4,2,1 --fwhm 8.0,4.0,0.0 ...' """ __all__ = ["Topup"] from os import PathLike +from pathlib import PurePath from typing import Iterable from attrs import define, field @@ -13,6 +35,14 @@ from pydra.engine.task import ShellCommandTask +def to_field_per_level(field, param) -> str: + return f"--{param} {','.join([str(elem) for elem in field])}" + + +def to_output_basename(field, input_image) -> str: + return f"--out {field or PurePath(input_image).name.split('.', 1)[0] + '_topup'}" + + @define(slots=False, kw_only=True) class TopupSpec(ShellSpec): """Specifications for topup.""" @@ -28,8 +58,10 @@ class TopupSpec(ShellSpec): ) output_basename: str = field( - default="topup", - metadata={"help_string": "output basename for field coefficients and movement parameters", "argstr": "--out"}, + metadata={ + "help_string": "output basename for field coefficients and movement parameters", + "formatter": to_output_basename, + }, ) output_fieldmap_image: str = field( @@ -49,35 +81,50 @@ class TopupSpec(ShellSpec): ) warp_resolution_per_level: Iterable[float] = field( - default=(10,), - metadata={"help_string": "resolution of warp basis in millimeters for a given level", "argstr": "--warpres..."}, + default=(10.0,), + metadata={ + "help_string": "resolution of warp basis in millimeters for a given level", + "formatter": lambda field: to_field_per_level(field, "warpres"), + }, ) subsampling_per_level: Iterable[int] = field( default=(1,), - metadata={"help_string": "subsampling factor for a given level", "argstr": "--subsamp..."}, + metadata={ + "help_string": "subsampling factor for a given level", + "formatter": lambda field: to_field_per_level(field, "subsamp"), + }, ) smoothing_per_level: Iterable[float] = field( - default=(8,), - metadata={"help_string": "FWHM of smoothing kernel in millimeters for a given level", "argstr": "--fwhm..."}, + default=(8.0,), + metadata={ + "help_string": "FWHM of smoothing kernel in millimeters for a given level", + "formatter": lambda field: to_field_per_level(field, "fwhm"), + }, ) max_iterations_per_level: Iterable[int] = field( default=(5,), - metadata={"help_string": "maximum number of non-linear iterations for a given level", "argstr": "--miter..."}, + metadata={ + "help_string": "maximum number of non-linear iterations for a given level", + "formatter": lambda field: to_field_per_level(field, "miter"), + }, ) regularisation_per_level: Iterable[float] = field( - default=(0,), - metadata={"help_string": "weight of regularisation for a given level", "argstr": "--lambda..."}, + default=(0.0,), + metadata={ + "help_string": "weight of regularisation for a given level", + "formatter": lambda field: to_field_per_level(field, "lambda"), + }, ) estimate_movement_per_level: Iterable[int] = field( default=(1,), metadata={ "help_string": "wether to estimate (1) or keep movement parameters constant (0) for a given level", - "argstr": "--estmov...", + "formatter": lambda field: to_field_per_level(field, "estmov"), "allowed_values": {0, 1}, }, ) @@ -89,7 +136,7 @@ class TopupSpec(ShellSpec): "which minimisation method to use for a given level " "(0: Levenberg-Marquardt, 1: Scaled Conjugate Gradient)" ), - "argstr": "--minmet...", + "formatter": lambda field: to_field_per_level(field, "minmet"), "allowed_values": {0, 1}, }, ) From 7d66b897d198f078aab6b121f74faff4b3eaf5cb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 178/224] ENH: Add doctest for ApplyTopup --- src/pydra/tasks/fsl/eddy/applytopup.py | 125 +++++++++++++++++++------ 1 file changed, 94 insertions(+), 31 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/applytopup.py b/src/pydra/tasks/fsl/eddy/applytopup.py index 466005e..2a412a8 100644 --- a/src/pydra/tasks/fsl/eddy/applytopup.py +++ b/src/pydra/tasks/fsl/eddy/applytopup.py @@ -1,83 +1,146 @@ """ ApplyTopup ========== + +Examples +-------- + +>>> task = ApplyTopup( +... input_image="blipup.nii", +... encoding_file="parameters.txt", +... input_index=1, +... fieldmap_image="fieldmap.nii", +... method="jac", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'applytopup --imain blipup.nii --datain parameters.txt --inindex 1 \ +--topup fieldmap --out blipup_topup.nii --method jac ...' + +>>> task = ApplyTopup( +... input_image=["blipup.nii", "blipdown.nii"], +... encoding_file="parameters.txt", +... input_index=[1, 2, 3], +... field_coefficients_image="topup_fieldcoef.nii", +... movement_parameters_file="topup_movpar.txt", +... output_image="corrected.nii", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'applytopup --imain blipup.nii,blipdown.nii --datain parameters.txt \ +--inindex 1,2,3 --topup topup --out corrected.nii ...' """ __all__ = ["ApplyTopup"] from os import PathLike from pathlib import PurePath -from typing import Iterable +from typing import Sequence, Union from attrs import define, field from pydra.engine.specs import ShellSpec, SpecInfo from pydra.engine.task import ShellCommandTask +def _to_input_image(field: Union[PathLike, Sequence[PathLike]]) -> str: + try: + paths = [PurePath(field)] + except TypeError: + paths = [PurePath(path) for path in field] + + return f"--imain {','.join(str(path) for path in paths)}" + + +def _to_input_index(field: Union[int, Sequence[int]]) -> str: + try: + indexes = list(field) + except TypeError: + indexes = [field] + + return f"--inindex {','.join(str(index) for index in indexes)}" + + +def _to_topup_basename(fieldmap_image: PathLike, field_coefficients_image: PathLike) -> str: + if field_coefficients_image: + path = PurePath(field_coefficients_image) + basename = path.parent / path.name.split("_fieldcoef", 1)[0] + else: + path = PurePath(fieldmap_image) + basename = path.parent / path.name.split(".", 1)[0] + + return f"--topup {str(basename)}" + + +def _to_output_image( + output_image: PathLike, + input_image: Union[PathLike, Sequence[PathLike]], +) -> str: + if output_image: + path = PurePath(output_image) + else: + try: + path = PurePath(input_image) + except TypeError: + path = PurePath(input_image[0]) + name, ext = path.name.split(".", 1) + path = path.with_name(f"{name}_topup.{ext}") + + return f"--out {path}" + + @define(slots=False, kw_only=True) class ApplyTopupSpec(ShellSpec): """Specifications for applytopup.""" - input_images: Iterable[PathLike] = field( + input_image: Union[PathLike, Sequence[PathLike]] = field( metadata={ - "help_string": "", + "help_string": "input image", "mandatory": True, - "formatter": lambda field: f"--imain {','.join(field)}", + "formatter": _to_input_image, } ) encoding_file: PathLike = field( metadata={ - "help_string": "", + "help_string": "text file containing phase encoding directions and timings", "mandatory": True, "argstr": "--datain", } ) - input_indexes: Iterable[int] = field( + input_index: Union[int, Sequence[int]] = field( metadata={ "help_string": "indices mapping each input image to a row of the encoding file", "mandatory": True, - "formatter": lambda field: f"--inindex {','.join(field)}", + "formatter": _to_input_index, } ) - @staticmethod - def to_topup_basename(field_coefficients_image: PathLike) -> str: - path = PurePath(field_coefficients_image) - - return str(path.parent / path.name.split(".", 1)[0]) - topup_basename: str = field( metadata={ - "help_string": "basename for topup files", - "requires": {"field_coefficients_image", "movement_parameters_file"}, - "formatter": to_topup_basename, + "help_string": "basename for fieldmap or topup output files", + "formatter": _to_topup_basename, "readonly": True, } ) + fieldmap_image: PathLike = field( + metadata={"help_string": "fieldmap image", "mandatory": True, "xor": {"field_coefficients_image"}} + ) + field_coefficients_image: PathLike = field( - metadata={"help_string": "field coefficients image computed by topup", "mandatory": True, "argstr": None} + metadata={ + "help_string": "field coefficients image computed by topup", + "mandatory": True, + "xor": {"fieldmap_image"}, + "requires": {"movement_parameters_file"}, + } ) movement_parameters_file: PathLike = field( - metadata={"help_string": "movement parameters file computed by topup", "mandatory": True, "argstr": None} + metadata={"help_string": "movement parameters file computed by topup", "argstr": None} ) - @staticmethod - def to_output_image(output_image: PathLike, input_images: Iterable[PathLike]) -> str: - if output_image: - path = PurePath(output_image) - else: - path = PurePath(input_images[0]) - name, ext = path.name.split(".", 1) - path = path.with_name(f"{name}_topup.{ext}") - - return f"--out {path}" - output_image: PathLike = field( - metadata={"help_string": "output image", "argstr": "--out", "formatter": to_output_image} + metadata={"help_string": "output image", "argstr": "--out", "formatter": _to_output_image} ) method: str = field( @@ -115,4 +178,4 @@ class ApplyTopup(ShellCommandTask): executable = "applytopup" - input_spec = SpecInfo(name="Input", bases=(ApplyTopupSpec,)) + input_spec = SpecInfo(name="Inputs", bases=(ApplyTopupSpec,)) From fe72fee3848067adb47afc554fd824fb8f3cf331 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 179/224] REF: Rename output fields from Topup --- src/pydra/tasks/fsl/eddy/topup.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/topup.py b/src/pydra/tasks/fsl/eddy/topup.py index fe45d9f..257e533 100644 --- a/src/pydra/tasks/fsl/eddy/topup.py +++ b/src/pydra/tasks/fsl/eddy/topup.py @@ -202,14 +202,14 @@ class TopupSpec(ShellSpec): class TopupOutSpec(ShellOutSpec): """Output specifications for topup.""" - output_field_coefficients_image: File = field( + field_coefficients_image: File = field( metadata={ "help_string": "output field coefficients", "output_file_template": "{output_basename}_fieldcoef.nii.gz", } ) - output_movement_parameters_file: File = field( + movement_parameters_file: File = field( metadata={ "help_string": "output movement parameters", "output_file_template": "{output_basename}_movpar.txt", From 9f0d7e34057f556ecab8d862e90edcdfca145fa5 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 180/224] REF: Add doctest to Eddy --- src/pydra/tasks/fsl/eddy/eddy.py | 270 +++++++++++-------------------- 1 file changed, 92 insertions(+), 178 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py index 6b2e079..20bcf8f 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/src/pydra/tasks/fsl/eddy/eddy.py @@ -3,39 +3,48 @@ ==== Correct for artifacts induced by Eddy currents and subject motion. + +Examples +-------- + +>>> task = Eddy( +... input_image="input.nii", +... brain_mask="brain.nii", +... encoding_file="params.txt", +... index_file="index.txt", +... bvec_file="input.bvec", +... bval_file="input.bval", +... fieldmap_image="fieldmap.nii", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'eddy --imain input.nii --mask brain.nii --acqp params.txt --index index.txt \ +--bvecs input.bvec --bvals input.bval --field fieldmap.nii --out eddy ...' """ __all__ = ["Eddy"] -import os - -import attrs +from os import PathLike +from pathlib import PurePath -import pydra +from attrs import define, field +from pydra.engine.specs import File, ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask -@attrs.define(slots=False, kw_only=True) -class EddySpec(pydra.specs.ShellSpec): +@define(slots=False, kw_only=True) +class EddySpec(ShellSpec): """Specifications for eddy.""" # Parameters that specify input files. - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image as a 4D volume of all images acquired in the diffusion protocol", - "mandatory": True, - "argstr": "--imain", - } + input_image: PathLike = field( + metadata={"help_string": "input image as a 4D volume", "mandatory": True, "argstr": "--imain"} ) - mask_image: os.PathLike = attrs.field( - metadata={ - "help_string": "brain mask as a single volume image", - "mandatory": True, - "argstr": "--mask", - } + brain_mask: PathLike = field( + metadata={"help_string": "brain mask as a single volume image", "mandatory": True, "argstr": "--mask"} ) - acquisition_parameters_file: os.PathLike = attrs.field( + encoding_file: PathLike = field( metadata={ "help_string": "acquisition parameters for the diffusion protocol", "mandatory": True, @@ -43,49 +52,23 @@ class EddySpec(pydra.specs.ShellSpec): } ) - index_file: os.PathLike = attrs.field( + index_file: PathLike = field( metadata={ - "help_string": "mapping from volume index to acquisition parameters", + "help_string": "mapping from volume index to encoding parameters", "mandatory": True, "argstr": "--index", } ) - bvec_file: os.PathLike = attrs.field( - metadata={ - "help_string": "diffusion directions", - "mandatory": True, - "argstr": "--bvecs", - } + bvec_file: PathLike = field( + metadata={"help_string": "diffusion directions", "mandatory": True, "argstr": "--bvecs"} ) - bval_file: os.PathLike = attrs.field( - metadata={ - "help_string": "diffusion weighting", - "mandatory": True, - "argstr": "--bvals", - } - ) + bval_file: PathLike = field(metadata={"help_string": "diffusion weighting", "mandatory": True, "argstr": "--bvals"}) - topup_file: os.PathLike = attrs.field( - metadata={ - "help_string": "topup output file", - "mandatory": True, - "argstr": "--topup", - "xor": {"fieldmap_image"}, - } - ) - - fieldmap_image: os.PathLike = attrs.field( - metadata={ - "help_string": "fieldmap file", - "mandatory": True, - "argstr": "--field", - "xor": {"topup_file"}, - } - ) + fieldmap_image: PathLike = field(metadata={"help_string": "fieldmap image", "mandatory": True, "argstr": "--field"}) - fieldmap_matrix: os.PathLike = attrs.field( + fieldmap_matrix: PathLike = field( metadata={ "help_string": "rigid-body transformation matrix from fieldmap to first input volume", "argstr": "--field_mat", @@ -93,24 +76,17 @@ class EddySpec(pydra.specs.ShellSpec): } ) - no_peas: bool = attrs.field( - metadata={ - "help_string": "do not perform post-Eddy alignment of shells", - "argstr": "--dont_peas", - } + no_peas: bool = field( + metadata={"help_string": "do not perform post-Eddy alignment of shells", "argstr": "--dont_peas"} ) # Parameters specifying names of output-files. - output_basename: str = attrs.field( - default="eddy", - metadata={ - "help_string": "basename for output files", - "argstr": "--out", - }, + output_basename: str = field( + default="eddy", metadata={"help_string": "basename for output files", "argstr": "--out"} ) # Parameters specifying how eddy should be run. - first_level_model: str = attrs.field( + first_level_model: str = field( default="quadratic", metadata={ "help_string": "model for the magnetic field generated by Eddy currents", @@ -119,7 +95,7 @@ class EddySpec(pydra.specs.ShellSpec): }, ) - second_level_model: str = attrs.field( + second_level_model: str = field( default="none", metadata={ "help_string": "model for how diffusion gradients generate Eddy currents", @@ -128,7 +104,7 @@ class EddySpec(pydra.specs.ShellSpec): }, ) - fwhm: float = attrs.field( + fwhm: float = field( default=0, metadata={ "help_string": "filter width used for pre-conditioning data prior to estimating distortions", @@ -136,22 +112,13 @@ class EddySpec(pydra.specs.ShellSpec): }, ) - num_iterations: int = attrs.field( - default=5, - metadata={ - "help_string": "number of iterations for eddy", - "argstr": "--niter", - }, + num_iterations: int = field( + default=5, metadata={"help_string": "number of iterations for eddy", "argstr": "--niter"} ) - fill_empty_planes: bool = attrs.field( - metadata={ - "help_string": "detect and fill empty planes", - "argstr": "--fep", - } - ) + fill_empty_planes: bool = field(metadata={"help_string": "detect and fill empty planes", "argstr": "--fep"}) - interpolation: str = attrs.field( + interpolation: str = field( default="spline", metadata={ "help_string": "interpolation method for the estimation phase", @@ -160,35 +127,24 @@ class EddySpec(pydra.specs.ShellSpec): }, ) - resampling: str = attrs.field( + resampling: str = field( default="jac", - metadata={ - "help_string": "final resampling strategy", - "argstr": "--resamp", - "allowed_values": {"jac", "lsr"}, - }, + metadata={"help_string": "final resampling strategy", "argstr": "--resamp", "allowed_values": {"jac", "lsr"}}, ) - num_voxels: int = attrs.field( + num_voxels: int = field( default=1000, - metadata={ - "help_string": "number of voxels to use for GP hyperparameter estimation", - "argstr": "--nvoxhp", - }, + metadata={"help_string": "number of voxels to use for GP hyperparameter estimation", "argstr": "--nvoxhp"}, ) - fudge_factor: int = attrs.field( - default=10, - metadata={ - "help_string": "fudge factor for Q-space smoothing during estimation", - "argstr": "--ff", - }, + fudge_factor: int = field( + default=10, metadata={"help_string": "fudge factor for Q-space smoothing during estimation", "argstr": "--ff"} ) # Parameters for outlier replacement (ol) - replace_outliers: bool = attrs.field(metadata={"help_string": "replace outliers", "argstr": "--repol"}) + replace_outliers: bool = field(metadata={"help_string": "replace outliers", "argstr": "--repol"}) - outlier_num_stdevs: int = attrs.field( + outlier_num_stdevs: int = field( metadata={ "help_string": "number of times off the standard deviation to qualify as outlier", "argstr": "--ol_nstd", @@ -196,7 +152,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - outlier_num_voxels: int = attrs.field( + outlier_num_voxels: int = field( metadata={ "help_string": "minimum number of voxels in a slice to qualify for outlier detection", "argstr": "--ol_nvox", @@ -204,7 +160,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - outlier_type: str = attrs.field( + outlier_type: str = field( metadata={ "help_string": "type of outliers detected", "argstr": "--ol_type", @@ -213,45 +169,26 @@ class EddySpec(pydra.specs.ShellSpec): } ) - multiband_factor: int = attrs.field( - metadata={ - "help_string": "multiband factor", - "argstr": "--mb", - } - ) + multiband_factor: int = field(metadata={"help_string": "multiband factor", "argstr": "--mb"}) - multiband_offset: int = attrs.field( - metadata={ - "help_string": "multiband slice offset", - "argstr": "--mb_offs", - "requires": {"multiband_factor"}, - } + multiband_offset: int = field( + metadata={"help_string": "multiband slice offset", "argstr": "--mb_offs", "requires": {"multiband_factor"}} ) # Parameters for intra-volume movement correction (s2v) - movement_prediction_order: int = attrs.field( - default=0, - metadata={ - "help_string": "order of movement prediction model", - "argstr": "--mporder", - }, + movement_prediction_order: int = field( + default=0, metadata={"help_string": "order of movement prediction model", "argstr": "--mporder"} ) - s2v_num_iterations: int = attrs.field( - metadata={ - "help_string": "number of iterations for s2v movement estimation", - "argstr": "--s2v_niter", - } + s2v_num_iterations: int = field( + metadata={"help_string": "number of iterations for s2v movement estimation", "argstr": "--s2v_niter"} ) - s2v_lambda: float = attrs.field( - metadata={ - "help_string": "weighting of regularization for s2v movement estimation", - "argstr": "--s2v_lambda", - } + s2v_lambda: float = field( + metadata={"help_string": "weighting of regularization for s2v movement estimation", "argstr": "--s2v_lambda"} ) - s2v_interpolation: str = attrs.field( + s2v_interpolation: str = field( metadata={ "help_string": "interpolation method for s2v movement estimation.", "argstr": "--s2v_interp", @@ -259,7 +196,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - slice_grouping_file: os.PathLike = attrs.field( + slice_grouping_file: PathLike = field( metadata={ "help_string": "file containing slice grouping information", "argstr": "--slspec", @@ -267,7 +204,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - slice_timing_file: os.PathLike = attrs.field( + slice_timing_file: PathLike = field( metadata={ "help_string": "file containing slice timing information", "argstr": "--json", @@ -276,14 +213,14 @@ class EddySpec(pydra.specs.ShellSpec): ) # Parameters for move-by-susceptibility correction (mbs) - estimate_move_by_susceptibility: bool = attrs.field( + estimate_move_by_susceptibility: bool = field( metadata={ "help_string": "estimate susceptibility-induced field changes due to subject motion", "argstr": "--estimate_move_by_susceptibility", } ) - mbs_num_iterations: int = attrs.field( + mbs_num_iterations: int = field( metadata={ "help_string": "number of iterations for MBS field estimation", "argstr": "--mbs_niter", @@ -291,7 +228,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - mbs_lambda: int = attrs.field( + mbs_lambda: int = field( metadata={ "help_string": "weighting of regularization for MBS field estimation", "argstr": "--mbs_lambda", @@ -299,7 +236,7 @@ class EddySpec(pydra.specs.ShellSpec): } ) - mbs_knot_spacing: int = attrs.field( + mbs_knot_spacing: int = field( metadata={ "help_string": "knot-spacing for MBS field estimation", "argstr": "--mbs_ksp", @@ -308,88 +245,65 @@ class EddySpec(pydra.specs.ShellSpec): ) # Miscellaneous parameters. - data_is_shelled: bool = attrs.field( - metadata={ - "help_string": "bypass checks for data shelling", - "argstr": "--data_is_shelled", - } + data_is_shelled: bool = field( + metadata={"help_string": "bypass checks for data shelling", "argstr": "--data_is_shelled"} ) - random_seed: int = attrs.field( - metadata={ - "help_string": "random seed for voxel selection", - "argstr": "--initrand", - } - ) + random_seed: int = field(metadata={"help_string": "random seed for voxel selection", "argstr": "--initrand"}) - save_cnr_maps: bool = attrs.field( - metadata={ - "help_string": "save shell-wise CNR maps", - "argstr": "--cnr_maps", - } - ) + save_cnr_maps: bool = field(metadata={"help_string": "save shell-wise CNR maps", "argstr": "--cnr_maps"}) - save_residuals: bool = attrs.field( - metadata={ - "help_string": "save residuals for all scans", - "argstr": "--residuals", - } - ) + save_residuals: bool = field(metadata={"help_string": "save residuals for all scans", "argstr": "--residuals"}) - verbose: bool = attrs.field( - metadata={ - "help_string": "enable verbose logging", - "argstr": "-v", - } - ) + verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) -class EddyOutSpec(pydra.specs.ShellOutSpec): +class EddyOutSpec(ShellOutSpec): """Output specification for eddy.""" - corrected_image: pydra.specs.File = attrs.field( + corrected_image: File = field( metadata={ "help_string": "input image corrected for distortions", "output_file_template": "{output_basename}.nii.gz", } ) - parameters_file: pydra.specs.File = attrs.field( + parameters_file: File = field( metadata={ "help_string": "registration parameters for movement and EC", "output_file_template": "{output_basename}.eddy_parameters", } ) - rotated_bvec_file: pydra.specs.File = attrs.field( + rotated_bvec_file: File = field( metadata={ "help_string": "rotated b-vecs", "output_file_template": "{output_basename}.eddy_rotated_bvecs", } ) - movement_rms_matrix: pydra.specs.File = attrs.field( + movement_rms_matrix: File = field( metadata={ "help_string": "movement induced RMS", "output_file_template": "{output_basename}.eddy_movement_rms", } ) - restricted_movement_rms_matrix: pydra.specs.File = attrs.field( + restricted_movement_rms_matrix: File = field( metadata={ "help_string": "movement induced RMS without translation in the PE direction", "output_file_template": "{output_basename}.eddy_restricted_movement_rms", } ) - displacement_fields_image: pydra.specs.File = attrs.field( + displacement_fields_image: File = field( metadata={ "help_string": "displacement fields in millimeters", "output_file_template": "{output_basename}.eddy_displacement_fields", } ) - outlier_free_image: pydra.specs.File = attrs.field( + outlier_free_image: File = field( metadata={ "help_string": "input image with outliers replaced by predictions", "output_file_template": "{output_basename}.eddy_outlier_free_data", @@ -397,7 +311,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): } ) - movement_over_time_file: pydra.specs.File = attrs.field( + movement_over_time_file: File = field( metadata={ "help_string": "movement parameters per time-point (slice or group)", "output_file_template": "{output_basename}.eddy_movement_over_time", @@ -405,7 +319,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): } ) - cnr_maps_image: pydra.specs.File = attrs.field( + cnr_maps_image: File = field( metadata={ "help_string": "path to optional CNR maps image", "output_file_template": "{output_basename}.eddy_cnr_maps", @@ -413,7 +327,7 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): } ) - residuals_image: pydra.specs.File = attrs.field( + residuals_image: File = field( metadata={ "help_string": "path to optional residuals image", "output_file_template": "{output_basename}.eddy_residuals", @@ -422,11 +336,11 @@ class EddyOutSpec(pydra.specs.ShellOutSpec): ) -class Eddy(pydra.engine.ShellCommandTask): +class Eddy(ShellCommandTask): """Task definition for eddy.""" executable = "eddy" - input_spec = pydra.specs.SpecInfo(name="EddyInput", bases=(EddySpec,)) + input_spec = SpecInfo(name="Inputs", bases=(EddySpec,)) - output_spec = pydra.specs.SpecInfo(name="EddyOutput", bases=(EddyOutSpec,)) + output_spec = SpecInfo(name="Outputs", bases=(EddyOutSpec,)) From a62cb3129716e1a7f61882cec7f2f980007717e1 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:47:07 +1100 Subject: [PATCH 181/224] MNT: Add config for docs environment --- hatch.toml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/hatch.toml b/hatch.toml index 4a713c3..573ac83 100644 --- a/hatch.toml +++ b/hatch.toml @@ -26,3 +26,15 @@ fix = [ "black --quiet {args:src}", "isort --quiet {args:src}", ] + +[envs.docs] +template = "docs" +dependencies = [ + "pydata-sphinx-theme >=0.13", + "sphinx <7", + "sphinx-autobuild", + "sphinx-pyproject", +] +[envs.docs.scripts] +build = "sphinx-build docs docs/_build/html -b {args:html}" +serve = "sphinx-autobuild docs docs/_build/html {args}" From e4db59d8835d611c9cb6c9172d3b7a1894ad3b2a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:48:37 +1100 Subject: [PATCH 182/224] DOC: Initial Sphinx config --- docs/api.rst | 7 +++++++ docs/conf.py | 49 +++++++++++++++---------------------------------- docs/index.rst | 18 ++++++++++++++---- 3 files changed, 36 insertions(+), 38 deletions(-) create mode 100644 docs/api.rst diff --git a/docs/api.rst b/docs/api.rst new file mode 100644 index 0000000..a477980 --- /dev/null +++ b/docs/api.rst @@ -0,0 +1,7 @@ +API +=== + +.. autosummary:: + :toctree: generated + +.. automodule:: pydra.tasks.fsl diff --git a/docs/conf.py b/docs/conf.py index 66d60bd..f57d121 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -1,51 +1,32 @@ # Configuration file for the Sphinx documentation builder. # -# This file only contains a selection of the most common options. For a full -# list see the documentation: +# For the full list of built-in configuration values, see the documentation: # https://www.sphinx-doc.org/en/master/usage/configuration.html -# -- Path setup -------------------------------------------------------------- +import sys +from pathlib import Path -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) +from sphinx_pyproject import SphinxConfig +config = SphinxConfig(globalns=globals()) +sys.path.insert(0, str(Path.cwd().parent / "src")) # -- Project information ----------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information -project = "pydra-fsl" -copyright = "2020, Xihe Xie" -author = "Xihe Xie" - +project = config.name +author = "Pydra Development Team" +copyright = f"2022-2023, {author}" +release = config.version # -- General configuration --------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [] - -# Add any paths that contain templates here, relative to this directory. +extensions = ["sphinx.ext.autosummary", "sphinx.ext.napoleon"] templates_path = ["_templates"] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] - # -- Options for HTML output ------------------------------------------------- +# https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "alabaster" - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ["_static"] +html_theme = "pydata_sphinx_theme" diff --git a/docs/index.rst b/docs/index.rst index 81d6410..7a85fde 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,11 +1,17 @@ -Welcome to pydra-fsl's documentation! -========================================= +About pydra-fsl +=============== + +`Pydra`_ is a dataflow engine which provides a set of lightweight abstractions for DAG construction, manipulation, and distributed execution. + +`FSL`_ is a comprehensive library of analysis tools for FMRI, MRI and DTI brain imaging data. + +pydra-fsl provides Pydra tasks for running and composing FSL commands. .. toctree:: - :maxdepth: 2 + :maxdepth: 3 :caption: Contents: - + api Indices and tables ================== @@ -13,3 +19,7 @@ Indices and tables * :ref:`genindex` * :ref:`modindex` * :ref:`search` + + +.. _Pydra: https://nipype.github.io/pydra/ +.. _FSL: https://fsl.fmrib.ox.ac.uk/ From c573222fcc660d627ff14024f2d4dfe1a3dea94a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:48:59 +1100 Subject: [PATCH 183/224] DOC: Add API documentation --- src/pydra/tasks/fsl/__init__.py | 15 +++++++++++++-- src/pydra/tasks/fsl/bet/__init__.py | 8 ++++++++ src/pydra/tasks/fsl/eddy/__init__.py | 9 +++++++++ src/pydra/tasks/fsl/eddy/eddy.py | 2 +- src/pydra/tasks/fsl/fast.py | 7 +++---- src/pydra/tasks/fsl/flirt/__init__.py | 11 +++++++++++ src/pydra/tasks/fsl/flirt/flirt.py | 6 +++--- src/pydra/tasks/fsl/fnirt/__init__.py | 11 +++++++++++ src/pydra/tasks/fsl/fnirt/fnirt.py | 6 +++--- src/pydra/tasks/fsl/fslmaths.py | 2 ++ src/pydra/tasks/fsl/fugue/__init__.py | 10 ++++++++++ src/pydra/tasks/fsl/utils/__init__.py | 18 ++++++++++++++++++ src/pydra/tasks/fsl/utils/fslfft.py | 4 +++- src/pydra/tasks/fsl/utils/fslinterleave.py | 2 ++ src/pydra/tasks/fsl/utils/fslroi.py | 2 ++ 15 files changed, 99 insertions(+), 14 deletions(-) diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 9dd93e6..3f8a456 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -2,8 +2,19 @@ This is a basic doctest demonstrating that the package and pydra can both be successfully imported. ->>> import pydra.engine ->>> import pydra.tasks.fsl +FSL interfaces are available within the `pydra.tasks.fsl` package. + +>>> from pydra.tasks import fsl + +.. automodule:: pydra.tasks.fsl.bet +.. automodule:: pydra.tasks.fsl.eddy +.. automodule:: pydra.tasks.fsl.fast +.. automodule:: pydra.tasks.fsl.flirt +.. automodule:: pydra.tasks.fsl.fnirt +.. automodule:: pydra.tasks.fsl.fslmaths +.. automodule:: pydra.tasks.fsl.fugue +.. automodule:: pydra.tasks.fsl.susan +.. automodule:: pydra.tasks.fsl.utils """ from . import fslmaths diff --git a/src/pydra/tasks/fsl/bet/__init__.py b/src/pydra/tasks/fsl/bet/__init__.py index b721e03..9762648 100644 --- a/src/pydra/tasks/fsl/bet/__init__.py +++ b/src/pydra/tasks/fsl/bet/__init__.py @@ -1,2 +1,10 @@ +""" +BET +=== + +.. automodule:: pydra.tasks.fsl.bet.bet +.. automodule:: pydra.tasks.fsl.bet.robustfov +""" + from .bet import BET from .robustfov import RobustFOV diff --git a/src/pydra/tasks/fsl/eddy/__init__.py b/src/pydra/tasks/fsl/eddy/__init__.py index 5d489fb..60dd623 100644 --- a/src/pydra/tasks/fsl/eddy/__init__.py +++ b/src/pydra/tasks/fsl/eddy/__init__.py @@ -1,3 +1,12 @@ +""" +Eddy +==== + +.. automodule:: pydra.tasks.fsl.eddy.eddy +.. automodule:: pydra.tasks.fsl.eddy.topup +.. automodule:: pydra.tasks.fsl.eddy.applytopup +""" + from .applytopup import ApplyTopup from .eddy import Eddy from .topup import Topup diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py index 20bcf8f..d22f736 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/src/pydra/tasks/fsl/eddy/eddy.py @@ -1,5 +1,5 @@ """ -eddy +Eddy ==== Correct for artifacts induced by Eddy currents and subject motion. diff --git a/src/pydra/tasks/fsl/fast.py b/src/pydra/tasks/fsl/fast.py index 192fec9..ae22dc9 100644 --- a/src/pydra/tasks/fsl/fast.py +++ b/src/pydra/tasks/fsl/fast.py @@ -1,9 +1,8 @@ """ -FMRIB's Automated Segmentation Tool (FAST) -========================================== +FAST +==== -FAST performs automatic segmentation of 3D images of the brain -using hidden Markov random field model and the expectation-maximization algorithm. +Automatic segmentation of 3D images of the brain. """ __all__ = ["FAST"] diff --git a/src/pydra/tasks/fsl/flirt/__init__.py b/src/pydra/tasks/fsl/flirt/__init__.py index e6dd3b4..76fee01 100644 --- a/src/pydra/tasks/fsl/flirt/__init__.py +++ b/src/pydra/tasks/fsl/flirt/__init__.py @@ -1,3 +1,14 @@ +""" +FLIRT +===== + +.. automodule:: pydra.tasks.fsl.flirt.flirt +.. automodule:: pydra.tasks.fsl.flirt.convertxfm +.. automodule:: pydra.tasks.fsl.flirt.img2imgcoord +.. automodule:: pydra.tasks.fsl.flirt.img2stdcoord +.. automodule:: pydra.tasks.fsl.flirt.std2imgcoord +""" + from .convertxfm import ConcatXFM, ConvertXFM, FixScaleSkew, InvertXFM from .flirt import FLIRT, ApplyXFM from .img2imgcoord import Img2ImgCoord diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py index 5684e10..4754897 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/src/pydra/tasks/fsl/flirt/flirt.py @@ -1,8 +1,8 @@ """ -FMRIB's Linear Image Registration Tool (FLIRT) -============================================== +FLIRT +===== -FLIRT is a robust and accurate tool +FLIRT (FMRIB's Linear Image Registration Tool) is a robust and accurate tool for affine registration of intra- and inter-modal brain images. Examples diff --git a/src/pydra/tasks/fsl/fnirt/__init__.py b/src/pydra/tasks/fsl/fnirt/__init__.py index 6424d60..2dae811 100644 --- a/src/pydra/tasks/fsl/fnirt/__init__.py +++ b/src/pydra/tasks/fsl/fnirt/__init__.py @@ -1,3 +1,14 @@ +""" +FNIRT +===== + +.. automodule:: pydra.tasks.fsl.fnirt.fnirt +.. automodule:: pydra.tasks.fsl.fnirt.fnirtfileutils +.. automodule:: pydra.tasks.fsl.fnirt.applywarp +.. automodule:: pydra.tasks.fsl.fnirt.convertwarp +.. automodule:: pydra.tasks.fsl.fnirt.invwarp +""" + from .applywarp import ApplyWarp from .convertwarp import ConvertWarp from .fnirt import FNIRT diff --git a/src/pydra/tasks/fsl/fnirt/fnirt.py b/src/pydra/tasks/fsl/fnirt/fnirt.py index 0e4bc01..a297476 100644 --- a/src/pydra/tasks/fsl/fnirt/fnirt.py +++ b/src/pydra/tasks/fsl/fnirt/fnirt.py @@ -1,8 +1,8 @@ """ -FSL Non-linear Image Registration Tool (FNIRT) -============================================== +FNIRT +===== -FNIRT performs non-linear registration of brain images. +FNIRT (FSL Non-linear Image Registration Tool) performs non-linear registration of brain images. Examples -------- diff --git a/src/pydra/tasks/fsl/fslmaths.py b/src/pydra/tasks/fsl/fslmaths.py index db1b498..84cb97b 100644 --- a/src/pydra/tasks/fsl/fslmaths.py +++ b/src/pydra/tasks/fsl/fslmaths.py @@ -2,6 +2,8 @@ fslmaths ======== +Mathematical manipulation of images. + Examples -------- diff --git a/src/pydra/tasks/fsl/fugue/__init__.py b/src/pydra/tasks/fsl/fugue/__init__.py index edfc1d5..62ee1ed 100644 --- a/src/pydra/tasks/fsl/fugue/__init__.py +++ b/src/pydra/tasks/fsl/fugue/__init__.py @@ -1,3 +1,13 @@ +""" +FUGUE +===== + +.. automodule:: pydra.tasks.fsl.fugue.fugue +.. automodule:: pydra.tasks.fsl.fugue.fsl_prepare_fieldmap +.. automodule:: pydra.tasks.fsl.fugue.prelude +.. automodule:: pydra.tasks.fsl.fugue.sigloss +""" + from .fsl_prepare_fieldmap import FSLPrepareFieldmap from .fugue import FUGUE from .prelude import Prelude diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index 96c2dc7..4b00212 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -1,3 +1,21 @@ +""" +Utils +===== + +.. automodule:: pydra.tasks.fsl.utils.fslchfiletype +.. automodule:: pydra.tasks.fsl.utils.fslfft +.. automodule:: pydra.tasks.fsl.utils.fslinfo +.. automodule:: pydra.tasks.fsl.utils.fslinterleave +.. automodule:: pydra.tasks.fsl.utils.fslmerge +.. automodule:: pydra.tasks.fsl.utils.fslorient +.. automodule:: pydra.tasks.fsl.utils.fslreorient2std +.. automodule:: pydra.tasks.fsl.utils.fslroi +.. automodule:: pydra.tasks.fsl.utils.fslselectvols +.. automodule:: pydra.tasks.fsl.utils.fslsmoothfill +.. automodule:: pydra.tasks.fsl.utils.fslsplit +.. automodule:: pydra.tasks.fsl.utils.fslswapdim +""" + from .fslchfiletype import FSLChFileType from .fslfft import FSLFFT from .fslinfo import FSLInfo diff --git a/src/pydra/tasks/fsl/utils/fslfft.py b/src/pydra/tasks/fsl/utils/fslfft.py index e504763..0baac06 100644 --- a/src/pydra/tasks/fsl/utils/fslfft.py +++ b/src/pydra/tasks/fsl/utils/fslfft.py @@ -5,12 +5,14 @@ Examples -------- -Compute the forward FFT: +Compute the forward FFT: + >>> task = FSLFFT(input_image="input.nii") >>> task.cmdline 'fslfft input.nii .../input_fslfft.nii' Compute the inverse FFT: + >>> task = FSLFFT( ... input_image="input.nii", ... output_image="output.nii", diff --git a/src/pydra/tasks/fsl/utils/fslinterleave.py b/src/pydra/tasks/fsl/utils/fslinterleave.py index 4f5453d..4bb2fbd 100644 --- a/src/pydra/tasks/fsl/utils/fslinterleave.py +++ b/src/pydra/tasks/fsl/utils/fslinterleave.py @@ -6,11 +6,13 @@ -------- Interleave images: + >>> task = FSLInterleave(input_image="in1.nii", other_image="in2.nii") >>> task.cmdline # doctest: +ELLIPSIS 'fslinterleave in1.nii in2.nii .../in1_interleaved.nii' Interleave in reverse order: + >>> task = FSLInterleave( ... input_image="in1.nii", ... other_image="in2.nii", diff --git a/src/pydra/tasks/fsl/utils/fslroi.py b/src/pydra/tasks/fsl/utils/fslroi.py index 2989f04..135f47b 100644 --- a/src/pydra/tasks/fsl/utils/fslroi.py +++ b/src/pydra/tasks/fsl/utils/fslroi.py @@ -8,6 +8,7 @@ -------- Extract a 16-voxel cube starting at position (10, 20, 30): + >>> task = FSLROI( ... input_image="image.nii", ... min_x=10, @@ -21,6 +22,7 @@ 'fslroi image.nii ...image_roi.nii 10 16 20 16 30 16' Extract a temporal window starting at 5 onwards: + >>> task = FSLROI( ... input_image="input.nii", ... output_image="output.nii", From 70f9f6ae197f72e19fce351580f37a0d6ca922f7 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:48:59 +1100 Subject: [PATCH 184/224] MNT: Upload documentation to GitHub Pages --- .github/workflows/docs.yaml | 58 +++++++++++++++++++++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 .github/workflows/docs.yaml diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..c50459c --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,58 @@ +name: docs + +on: + push: + branches: [ main ] + pull_request: + branches: [ main ] + workflow_dispatch: + +permissions: + contents: read + pages: write + id-token: write + +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 + with: + python-version: '3.x' + - name: Install Hatch + run: pipx install hatch + - name: Build documentation + run: hatch run docs:build + - name: Upload documentation + uses: actions/upload-artifact@v3 + with: + name: docs + path: 'docs/_build/html' + retention-days: 1 + + deploy: + needs: build + if: contains('refs/heads/main', github.ref) + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + runs-on: ubuntu-latest + steps: + - name: Download documentation + uses: actions/download-artifact@v3 + with: + name: docs + - name: Setup GitHub Pages + uses: actions/configure-pages@v3 + - name: Upload artifact + uses: actions/upload-pages-artifact@v1 + with: + path: '.' + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@v2 From 871d9bb7dd30470ee465286c17706770f370d674 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:15 +1100 Subject: [PATCH 185/224] MNT: Add status badge for docs --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 931e1d7..da6dfc4 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,7 @@ [![PyPI - Version][pypi-version]][pypi-project] [![PyPI - Python Version][pypi-pyversions]][pypi-project] [![PyPI - Downloads][pypi-downloads]][pypi-project] +![][status-docs] ![][status-test] ---- @@ -79,6 +80,8 @@ This project is distributed under the terms of the [Apache License, Version 2.0] [pypi-downloads]: https://static.pepy.tech/badge/pydra-fsl +[status-docs]: https://github.com/aramis-lab/pydra-fsl/actions/workflows/docs.yaml/badge.svg + [status-test]: https://github.com/aramis-lab/pydra-fsl/actions/workflows/test.yaml/badge.svg [pydra]: https://pydra.readthedocs.io/ From 1e620d5471f62a6e9e5f143276a3f6780e5ddf28 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:15 +1100 Subject: [PATCH 186/224] MNT: Bump version to 0.0.18 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 008b298..5aa9a72 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.17" +version = "0.0.18" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From beed08c1cbfd025230d63ca5a4296e5205561ed4 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:15 +1100 Subject: [PATCH 187/224] ENH: Add input and reference weights for FLIRT --- src/pydra/tasks/fsl/flirt/flirt.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py index 4754897..35fa2fb 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/src/pydra/tasks/fsl/flirt/flirt.py @@ -117,6 +117,14 @@ class BaseSpec(pydra.specs.ShellSpec): class FLIRTSpec(BaseSpec): """Specifications for FLIRT.""" + input_weights: os.PathLike = attrs.field( + metadata={"help_string": "voxel-wise weighting for input image", "argstr": "-inweight"} + ) + + reference_weights: os.PathLike = attrs.field( + metadata={"help_string": "voxel-wise weighting for reference image", "argstr": "-refweight"} + ) + input_matrix: os.PathLike = attrs.field( metadata={ "help_string": "input transformation matrix", From a78490fe1c6f0e64e4ad66cb1a2052a4cfcca368 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:15 +1100 Subject: [PATCH 188/224] REF: Normalize flirt module --- src/pydra/tasks/fsl/flirt/flirt.py | 94 +++++++++--------------------- 1 file changed, 28 insertions(+), 66 deletions(-) diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py index 35fa2fb..f320acc 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/src/pydra/tasks/fsl/flirt/flirt.py @@ -61,78 +61,51 @@ __all__ = ["FLIRT", "ApplyXFM"] -import os +from os import PathLike -import attrs - -import pydra +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask from . import specs -@attrs.define(slots=False, kw_only=True) -class BaseSpec(pydra.specs.ShellSpec): +@define(slots=False, kw_only=True) +class BaseSpec(ShellSpec): """Common specifications for FLIRT-based tasks.""" - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "-in", - } - ) + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "-in"}) - reference_image: os.PathLike = attrs.field( - metadata={ - "help_string": "reference image", - "mandatory": True, - "argstr": "-ref", - } - ) + reference_image: PathLike = field(metadata={"help_string": "reference image", "mandatory": True, "argstr": "-ref"}) - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "-out", - "output_file_template": "{input_image}_flirt", - } + output_image: str = field( + metadata={"help_string": "output image", "argstr": "-out", "output_file_template": "{input_image}_flirt"} ) - output_datatype: str = attrs.field( + output_datatype: str = field( metadata={ "help_string": "output datatype", "argstr": "-datatype", - "allowed_values": { - "char", - "short", - "int", - "float", - "double", - }, + "allowed_values": {"char", "short", "int", "float", "double"}, } ) -@attrs.define(slots=False, kw_only=True) +@define(slots=False, kw_only=True) class FLIRTSpec(BaseSpec): """Specifications for FLIRT.""" - input_weights: os.PathLike = attrs.field( + input_weights: PathLike = field( metadata={"help_string": "voxel-wise weighting for input image", "argstr": "-inweight"} ) - reference_weights: os.PathLike = attrs.field( + reference_weights: PathLike = field( metadata={"help_string": "voxel-wise weighting for reference image", "argstr": "-refweight"} ) - input_matrix: os.PathLike = attrs.field( - metadata={ - "help_string": "input transformation matrix", - "argstr": "-init", - } - ) + input_matrix: PathLike = field(metadata={"help_string": "input transformation matrix", "argstr": "-init"}) - output_matrix: str = attrs.field( + output_matrix: str = field( metadata={ "help_string": "output transformation matrix", "argstr": "-omat", @@ -141,7 +114,7 @@ class FLIRTSpec(BaseSpec): } ) - degrees_of_freedom: int = attrs.field( + degrees_of_freedom: int = field( metadata={ "help_string": "degrees of freedom for the registration model", "argstr": "-dof", @@ -150,7 +123,7 @@ class FLIRTSpec(BaseSpec): } ) - use_2d_registration: bool = attrs.field( + use_2d_registration: bool = field( metadata={ "help_string": "use rigid-body registration model in 2D", "argstr": "-2D", @@ -159,13 +132,13 @@ class FLIRTSpec(BaseSpec): ) -class FLIRT(pydra.engine.ShellCommandTask): +class FLIRT(ShellCommandTask): """Task definition for FLIRT.""" executable = "flirt" - input_spec = pydra.specs.SpecInfo( - name="FLIRTInput", + input_spec = SpecInfo( + name="Inputs", bases=( FLIRTSpec, specs.SearchSpec, @@ -177,19 +150,15 @@ class FLIRT(pydra.engine.ShellCommandTask): ) -@attrs.define(slots=False, kw_only=True) +@define(slots=False, kw_only=True) class ApplyXFMSpec(BaseSpec): """Specifications for ApplyXFM.""" - input_matrix: os.PathLike = attrs.field( - metadata={ - "help_string": "input transformation matrix", - "mandatory": True, - "argstr": "-init", - } + input_matrix: PathLike = field( + metadata={"help_string": "input transformation matrix", "mandatory": True, "argstr": "-init"} ) - isotropic_resolution: float = attrs.field( + isotropic_resolution: float = field( default=0.0, metadata={ "help_string": "force resampling to isotropic resolution", @@ -199,17 +168,10 @@ class ApplyXFMSpec(BaseSpec): }, ) - padding_size: float = attrs.field( - metadata={ - "help_string": "padding size in voxels", - "argstr": "-paddingsize", - } - ) + padding_size: float = field(metadata={"help_string": "padding size in voxels", "argstr": "-paddingsize"}) class ApplyXFM(FLIRT): """Task definition for ApplyXFM.""" - input_spec = pydra.specs.SpecInfo( - name="ApplyXFMInput", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec) - ) + input_spec = SpecInfo(name="Inputs", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec)) From f433ccc2708665be699f948196737dea5df84665 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:31 +1100 Subject: [PATCH 189/224] MNT: Fix testing setup for src layout --- hatch.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hatch.toml b/hatch.toml index 573ac83..961f997 100644 --- a/hatch.toml +++ b/hatch.toml @@ -5,7 +5,7 @@ sources = ["src"] [envs.default] dependencies = ["pytest"] [envs.default.scripts] -test = "pytest {args:src}" +test = "pytest {args}" [[envs.all.matrix]] python = ["3.7", "3.8", "3.9", "3.10", "3.11"] From 655f13a0566536aa994ec804ff5dfe82148dce7f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:31 +1100 Subject: [PATCH 190/224] FIX: Rename input_matrix to initial_matrix in FLIRT / ApplyXFM --- src/pydra/tasks/fsl/flirt/flirt.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py index f320acc..4643f4d 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/src/pydra/tasks/fsl/flirt/flirt.py @@ -40,7 +40,7 @@ ... input_image="invol.nii", ... output_image="outvol.nii", ... reference_image="refvol.nii", -... input_matrix="affine.mat", +... initial_matrix="affine.mat", ... ) >>> task.cmdline # doctest: +ELLIPSIS 'flirt -in invol.nii -ref refvol.nii -out outvol.nii -init affine.mat -applyxfm ...' @@ -51,7 +51,7 @@ ... input_image="invol.nii", ... output_image="outvol.nii", ... reference_image="refvol.nii", -... input_matrix="affine.mat", +... initial_matrix="affine.mat", ... isotropic_resolution=1, ... padding_size=5, ... ) @@ -103,7 +103,7 @@ class FLIRTSpec(BaseSpec): metadata={"help_string": "voxel-wise weighting for reference image", "argstr": "-refweight"} ) - input_matrix: PathLike = field(metadata={"help_string": "input transformation matrix", "argstr": "-init"}) + initial_matrix: PathLike = field(metadata={"help_string": "initial transformation matrix", "argstr": "-init"}) output_matrix: str = field( metadata={ @@ -154,8 +154,8 @@ class FLIRT(ShellCommandTask): class ApplyXFMSpec(BaseSpec): """Specifications for ApplyXFM.""" - input_matrix: PathLike = field( - metadata={"help_string": "input transformation matrix", "mandatory": True, "argstr": "-init"} + initial_matrix: PathLike = field( + metadata={"help_string": "initial transformation matrix", "mandatory": True, "argstr": "-init"} ) isotropic_resolution: float = field( From dee9f268e776df3caeb5a9f60547fa0239b66cfb Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:31 +1100 Subject: [PATCH 191/224] ENH: Major improvement for FSLROI - Use upstream naming convention for fields (min_x -> x_min ...) - Require specification of ROI location in x, y and z together - Default t_min to 0 and t_max to -1 --- src/pydra/tasks/fsl/utils/fslroi.py | 125 ++++++++-------------------- 1 file changed, 37 insertions(+), 88 deletions(-) diff --git a/src/pydra/tasks/fsl/utils/fslroi.py b/src/pydra/tasks/fsl/utils/fslroi.py index 135f47b..95e349d 100644 --- a/src/pydra/tasks/fsl/utils/fslroi.py +++ b/src/pydra/tasks/fsl/utils/fslroi.py @@ -10,128 +10,77 @@ Extract a 16-voxel cube starting at position (10, 20, 30): >>> task = FSLROI( -... input_image="image.nii", -... min_x=10, -... min_y=20, -... min_z=30, -... size_x=16, -... size_y=16, -... size_z=16, +... input_image="image.nii", +... x_min=10, +... x_size=16, +... y_min=20, +... y_size=16, +... z_min=30, +... z_size=16, ... ) ->>> task.cmdline # doctest: +ELLIPSIS -'fslroi image.nii ...image_roi.nii 10 16 20 16 30 16' +>>> task.cmdline # doctest: +ELLIPSIS +'fslroi image.nii ...image_roi.nii 10 16 20 16 30 16 ...' Extract a temporal window starting at 5 onwards: ->>> task = FSLROI( -... input_image="input.nii", -... output_image="output.nii", -... min_t=5, -... size_t=-1, -... ) +>>> task = FSLROI(input_image="input.nii", output_image="output.nii", t_min=5) >>> task.cmdline 'fslroi input.nii output.nii 5 -1' """ __all__ = ["FSLROI"] -import os +from os import PathLike -import attrs +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask -import pydra - -@attrs.define(slots=False, kw_only=True) -class FSLROISpec(pydra.specs.ShellSpec): +@define(kw_only=True) +class FSLROISpec(ShellSpec): """Specifications for fslroi.""" - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "", - } - ) + _requires = {"x_min", "y_min", "z_min"} - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "", - "output_file_template": "{input_image}_roi", - } - ) + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) - min_x: int = attrs.field( - metadata={ - "help_string": "start of ROI in x-dimension (0-based indexing)", - "argstr": "", - } + output_image: str = field( + metadata={"help_string": "output image", "argstr": "", "output_file_template": "{input_image}_roi"} ) - size_x: int = attrs.field( - # default=-1, - metadata={ - "help_string": "size of ROI in x-dimension (-1 for maximum)", - "argstr": "", - "requires": {"min_x"}, - } + x_min: int = field( + metadata={"help_string": "start of ROI in x (0-based indexing)", "argstr": "", "requires": _requires} ) - min_y: int = attrs.field( - metadata={ - "help_string": "start of ROI in y-dimension (0-based indexing)", - "argstr": "", - "requires": {"min_x"}, - } + x_size: int = field( + metadata={"help_string": "size of ROI in x (-1 for maximum)", "argstr": "", "requires": {"x_min"}} ) - size_y: int = attrs.field( - # default=-1, - metadata={ - "help_string": "size of ROI in y-dimension (-1 for maximum)", - "argstr": "", - "requires": {"min_y"}, - } + y_min: int = field( + metadata={"help_string": "start of ROI in y (0-based indexing)", "argstr": "", "requires": _requires} ) - min_z: int = attrs.field( - metadata={ - "help_string": "start of ROI in z-dimension (0-based indexing)", - "argstr": "", - "requires": {"min_x"}, - } + y_size: int = field( + metadata={"help_string": "size of ROI in y (-1 for maximum)", "argstr": "", "requires": {"y_min"}} ) - size_z: int = attrs.field( - # default=-1, - metadata={ - "help_string": "size of ROI in z-dimension (-1 for maximum)", - "argstr": "", - "requires": {"min_z"}, - } + z_min: int = field( + metadata={"help_string": "start of ROI in z (0-based indexing)", "argstr": "", "requires": _requires} ) - min_t: int = attrs.field( - metadata={ - "help_string": "start of ROI in t-dimension (0-based indexing)", - "argstr": "", - } + z_size: int = field( + metadata={"help_string": "size of ROI in z (-1 for maximum)", "argstr": "", "requires": {"z_min"}} ) - size_t: int = attrs.field( - # default=-1, - metadata={ - "help_string": "size of ROI in t-dimension (-1 for maximum)", - "argstr": "", - "requires": {"min_t"}, - }, - ) + t_min: int = field(default=0, metadata={"help_string": "start of ROI in t (0-based indexing)", "argstr": ""}) + + t_size: int = field(default=-1, metadata={"help_string": "size of ROI in t (-1 for maximum)", "argstr": ""}) -class FSLROI(pydra.engine.ShellCommandTask): +class FSLROI(ShellCommandTask): """Task definition for fslroi.""" executable = "fslroi" - input_spec = pydra.engine.specs.SpecInfo(name="FSLROIInput", bases=(FSLROISpec,)) + input_spec = SpecInfo(name="Inputs", bases=(FSLROISpec,)) From 3cae0c2eba3c17ffa28b9f1ff5ad2dad28e0f616 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:31 +1100 Subject: [PATCH 192/224] ENH: Major improvement to fslmaths - Normalize module layout - Make other_image mandatory in Mul --- src/pydra/tasks/fsl/fslmaths.py | 60 ++++++++++++--------------------- 1 file changed, 21 insertions(+), 39 deletions(-) diff --git a/src/pydra/tasks/fsl/fslmaths.py b/src/pydra/tasks/fsl/fslmaths.py index 84cb97b..90d92e8 100644 --- a/src/pydra/tasks/fsl/fslmaths.py +++ b/src/pydra/tasks/fsl/fslmaths.py @@ -26,38 +26,28 @@ __all__ = ["FSLMaths", "Mul"] -import os +from os import PathLike -import attrs +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask -import pydra - -@attrs.define(slots=False, kw_only=True) -class FSLMathsSpec(pydra.specs.ShellSpec): +@define(slots=False, kw_only=True) +class FSLMathsSpec(ShellSpec): """Specifications for fslmaths.""" - _ALLOWED_DATATYPES = {"char", "short", "int", "float", "double", "input"} + _datatypes = {"char", "short", "int", "float", "double", "input"} - datatype: str = attrs.field( - metadata={ - "help_string": "datatype used for internal computation", - "argstr": "-dt", - "position": 1, - "allowed_values": _ALLOWED_DATATYPES, - } + internal_datatype: str = field( + metadata={"help_string": "internal datatype", "argstr": "-dt", "position": 1, "allowed_values": _datatypes} ) - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "", - "position": 2, - } + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": "", "position": 2} ) - output_image: str = attrs.field( + output_image: str = field( metadata={ "help_string": "output image", "argstr": "", @@ -66,38 +56,30 @@ class FSLMathsSpec(pydra.specs.ShellSpec): } ) - output_datatype: str = attrs.field( + output_datatype: str = field( default="float", - metadata={ - "help_string": "datatype used for output serialization", - "argstr": "-odt", - "position": -1, - "allowed_values": _ALLOWED_DATATYPES, - }, + metadata={"help_string": "output datatype", "argstr": "-odt", "position": -1, "allowed_values": _datatypes}, ) -class FSLMaths(pydra.engine.ShellCommandTask): +class FSLMaths(ShellCommandTask): """Task definition for fslmaths.""" executable = "fslmaths" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLMathsSpec,)) + input_spec = SpecInfo(name="Inputs", bases=(FSLMathsSpec,)) -@attrs.define(slots=False, kw_only=True) -class MulSpec(pydra.specs.ShellSpec): +@define(kw_only=True) +class MulSpec(FSLMathsSpec): """Specifications for fslmaths' mul.""" - other_image: os.PathLike = attrs.field( - metadata={ - "help_string": "multiply input with other image", - "argstr": "-mul", - } + other_image: PathLike = field( + metadata={"help_string": "multiply input with other image", "mandatory": True, "argstr": "-mul"} ) class Mul(FSLMaths): """Task definition for fslmaths' mul.""" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLMathsSpec, MulSpec)) + input_spec = SpecInfo(name="Inputs", bases=(MulSpec,)) From 075e34b9be1eda7f08b9b1c4d3398c571412981f Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:31 +1100 Subject: [PATCH 193/224] MNT: Bump version to 0.0.19 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 5aa9a72..07ccd7d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.18" +version = "0.0.19" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From b567f152b2f4d9f371a8c8b1295482c698093864 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 194/224] REF: Normalize all input and output spec names Apply convention used upstream in Pydra: - input_spec -> Input - output_spec -> Output --- src/pydra/tasks/fsl/bet/bet.py | 4 ++-- src/pydra/tasks/fsl/bet/robustfov.py | 2 +- src/pydra/tasks/fsl/eddy/applytopup.py | 2 +- src/pydra/tasks/fsl/eddy/eddy.py | 4 ++-- src/pydra/tasks/fsl/eddy/topup.py | 4 ++-- src/pydra/tasks/fsl/fast.py | 4 ++-- src/pydra/tasks/fsl/flirt/convertxfm.py | 8 ++++---- src/pydra/tasks/fsl/flirt/flirt.py | 4 ++-- src/pydra/tasks/fsl/flirt/img2imgcoord.py | 4 ++-- src/pydra/tasks/fsl/flirt/img2stdcoord.py | 4 ++-- src/pydra/tasks/fsl/flirt/std2imgcoord.py | 4 ++-- src/pydra/tasks/fsl/fnirt/applywarp.py | 5 +---- src/pydra/tasks/fsl/fnirt/convertwarp.py | 5 +---- src/pydra/tasks/fsl/fnirt/fnirt.py | 5 +---- src/pydra/tasks/fsl/fnirt/fnirtfileutils.py | 5 +---- src/pydra/tasks/fsl/fnirt/invwarp.py | 5 +---- src/pydra/tasks/fsl/fslmaths.py | 4 ++-- src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py | 2 +- src/pydra/tasks/fsl/fugue/fugue.py | 4 ++-- src/pydra/tasks/fsl/fugue/prelude.py | 2 +- src/pydra/tasks/fsl/fugue/sigloss.py | 2 +- src/pydra/tasks/fsl/susan.py | 2 +- src/pydra/tasks/fsl/utils/fslchfiletype.py | 4 ++-- src/pydra/tasks/fsl/utils/fslfft.py | 2 +- src/pydra/tasks/fsl/utils/fslinfo.py | 4 ++-- src/pydra/tasks/fsl/utils/fslinterleave.py | 2 +- src/pydra/tasks/fsl/utils/fslmerge.py | 2 +- src/pydra/tasks/fsl/utils/fslorient.py | 4 ++-- src/pydra/tasks/fsl/utils/fslreorient2std.py | 2 +- src/pydra/tasks/fsl/utils/fslroi.py | 2 +- src/pydra/tasks/fsl/utils/fslselectvols.py | 2 +- src/pydra/tasks/fsl/utils/fslsmoothfill.py | 2 +- src/pydra/tasks/fsl/utils/fslsplit.py | 8 ++++---- src/pydra/tasks/fsl/utils/fslswapdim.py | 2 +- 34 files changed, 53 insertions(+), 68 deletions(-) diff --git a/src/pydra/tasks/fsl/bet/bet.py b/src/pydra/tasks/fsl/bet/bet.py index 4fc62e7..b7f0693 100644 --- a/src/pydra/tasks/fsl/bet/bet.py +++ b/src/pydra/tasks/fsl/bet/bet.py @@ -197,6 +197,6 @@ class BET(pydra.engine.ShellCommandTask): executable = "bet" - input_spec = pydra.specs.SpecInfo(name="BETInput", bases=(BETSpec, BETVariationsSpec)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(BETSpec, BETVariationsSpec)) - output_spec = pydra.specs.SpecInfo(name="BETOutput", bases=(BETOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(BETOutSpec,)) diff --git a/src/pydra/tasks/fsl/bet/robustfov.py b/src/pydra/tasks/fsl/bet/robustfov.py index 8dababc..7dbaf6c 100644 --- a/src/pydra/tasks/fsl/bet/robustfov.py +++ b/src/pydra/tasks/fsl/bet/robustfov.py @@ -65,4 +65,4 @@ class RobustFOV(pydra.engine.ShellCommandTask): executable = "robustfov" - input_spec = pydra.specs.SpecInfo(name="RobustFOVInput", bases=(RobustFOVSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(RobustFOVSpec,)) diff --git a/src/pydra/tasks/fsl/eddy/applytopup.py b/src/pydra/tasks/fsl/eddy/applytopup.py index 2a412a8..db0cd13 100644 --- a/src/pydra/tasks/fsl/eddy/applytopup.py +++ b/src/pydra/tasks/fsl/eddy/applytopup.py @@ -178,4 +178,4 @@ class ApplyTopup(ShellCommandTask): executable = "applytopup" - input_spec = SpecInfo(name="Inputs", bases=(ApplyTopupSpec,)) + input_spec = SpecInfo(name="Input", bases=(ApplyTopupSpec,)) diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py index d22f736..d0a2faa 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/src/pydra/tasks/fsl/eddy/eddy.py @@ -341,6 +341,6 @@ class Eddy(ShellCommandTask): executable = "eddy" - input_spec = SpecInfo(name="Inputs", bases=(EddySpec,)) + input_spec = SpecInfo(name="Input", bases=(EddySpec,)) - output_spec = SpecInfo(name="Outputs", bases=(EddyOutSpec,)) + output_spec = SpecInfo(name="Output", bases=(EddyOutSpec,)) diff --git a/src/pydra/tasks/fsl/eddy/topup.py b/src/pydra/tasks/fsl/eddy/topup.py index 257e533..80c3159 100644 --- a/src/pydra/tasks/fsl/eddy/topup.py +++ b/src/pydra/tasks/fsl/eddy/topup.py @@ -222,6 +222,6 @@ class Topup(ShellCommandTask): executable = "topup" - input_spec = SpecInfo(name="Inputs", bases=(TopupSpec,)) + input_spec = SpecInfo(name="Input", bases=(TopupSpec,)) - output_spec = SpecInfo(name="Outputs", bases=(TopupOutSpec,)) + output_spec = SpecInfo(name="Output", bases=(TopupOutSpec,)) diff --git a/src/pydra/tasks/fsl/fast.py b/src/pydra/tasks/fsl/fast.py index ae22dc9..e7f96aa 100644 --- a/src/pydra/tasks/fsl/fast.py +++ b/src/pydra/tasks/fsl/fast.py @@ -207,6 +207,6 @@ class FAST(pydra.engine.ShellCommandTask): executable = "fast" - input_spec = pydra.specs.SpecInfo(name="FASTInput", bases=(FASTSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FASTSpec,)) - output_spec = pydra.specs.SpecInfo(name="FASTOuput", bases=(FASTOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Ouput", bases=(FASTOutSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/convertxfm.py b/src/pydra/tasks/fsl/flirt/convertxfm.py index cc8f61e..2d96c76 100644 --- a/src/pydra/tasks/fsl/flirt/convertxfm.py +++ b/src/pydra/tasks/fsl/flirt/convertxfm.py @@ -81,7 +81,7 @@ class ConvertXFM(pydra.engine.ShellCommandTask): executable = "convert_xfm" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(ConvertXFMSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(ConvertXFMSpec,)) @attrs.define(slots=False, kw_only=True) @@ -96,7 +96,7 @@ class ConcatXFMSpec(BaseSpec): class ConcatXFM(ConvertXFM): """Task definition for matrix concatenation using convert_xfm.""" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(ConcatXFMSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(ConcatXFMSpec,)) @attrs.define(slots=False, kw_only=True) @@ -109,7 +109,7 @@ class InvertXFMSpec(BaseSpec): class InvertXFM(ConvertXFM): """Task definition for matrix inversion using convert_xfm.""" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(InvertXFMSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(InvertXFMSpec,)) @attrs.define(slots=False, kw_only=True) @@ -128,4 +128,4 @@ class FixScaleSkewSpec(BaseSpec): class FixScaleSkew(ConvertXFM): """Task definition for fixing matrix scaling and skewness using convert_xfm.""" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FixScaleSkewSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FixScaleSkewSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/src/pydra/tasks/fsl/flirt/flirt.py index 4643f4d..5b118f0 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/src/pydra/tasks/fsl/flirt/flirt.py @@ -138,7 +138,7 @@ class FLIRT(ShellCommandTask): executable = "flirt" input_spec = SpecInfo( - name="Inputs", + name="Input", bases=( FLIRTSpec, specs.SearchSpec, @@ -174,4 +174,4 @@ class ApplyXFMSpec(BaseSpec): class ApplyXFM(FLIRT): """Task definition for ApplyXFM.""" - input_spec = SpecInfo(name="Inputs", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec)) + input_spec = SpecInfo(name="Input", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec)) diff --git a/src/pydra/tasks/fsl/flirt/img2imgcoord.py b/src/pydra/tasks/fsl/flirt/img2imgcoord.py index 428f431..8e2607d 100644 --- a/src/pydra/tasks/fsl/flirt/img2imgcoord.py +++ b/src/pydra/tasks/fsl/flirt/img2imgcoord.py @@ -56,6 +56,6 @@ class Img2ImgCoord(pydra.engine.ShellCommandTask): executable = "img2imgcoord" - input_spec = pydra.specs.SpecInfo(name="Img2ImgCoordInput", bases=(Img2ImgCoordSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(Img2ImgCoordSpec, specs.VerboseSpec)) - output_spec = pydra.specs.SpecInfo(name="Img2ImgCoordOutput", bases=(Img2ImgCoordOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(Img2ImgCoordOutSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/img2stdcoord.py b/src/pydra/tasks/fsl/flirt/img2stdcoord.py index f63565c..950b9d4 100644 --- a/src/pydra/tasks/fsl/flirt/img2stdcoord.py +++ b/src/pydra/tasks/fsl/flirt/img2stdcoord.py @@ -55,6 +55,6 @@ class Img2StdCoord(pydra.engine.ShellCommandTask): executable = "img2stdcoord" - input_spec = pydra.specs.SpecInfo(name="Img2StdCoordInput", bases=(Img2StdCoordSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(Img2StdCoordSpec, specs.VerboseSpec)) - output_spec = pydra.specs.SpecInfo(name="Img2StdCoordOutput", bases=(Img2StdCoordOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(Img2StdCoordOutSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/std2imgcoord.py b/src/pydra/tasks/fsl/flirt/std2imgcoord.py index a13cdf6..ec67193 100644 --- a/src/pydra/tasks/fsl/flirt/std2imgcoord.py +++ b/src/pydra/tasks/fsl/flirt/std2imgcoord.py @@ -55,6 +55,6 @@ class Std2ImgCoord(pydra.engine.ShellCommandTask): executable = "std2imgcoord" - input_spec = pydra.specs.SpecInfo(name="Std2ImgCoordSpecInput", bases=(Std2ImgCoordSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(Std2ImgCoordSpec, specs.VerboseSpec)) - output_spec = pydra.specs.SpecInfo(name="Std2ImgCoordSpecOutput", bases=(Std2ImgCoordOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(Std2ImgCoordOutSpec,)) diff --git a/src/pydra/tasks/fsl/fnirt/applywarp.py b/src/pydra/tasks/fsl/fnirt/applywarp.py index e83189e..d2773c4 100644 --- a/src/pydra/tasks/fsl/fnirt/applywarp.py +++ b/src/pydra/tasks/fsl/fnirt/applywarp.py @@ -147,7 +147,4 @@ class ApplyWarp(pydra.engine.ShellCommandTask): executable = "applywarp" - input_spec = pydra.specs.SpecInfo( - name="ApplyWarpInput", - bases=(ApplyWarpSpec, specs.VerboseSpec), - ) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(ApplyWarpSpec, specs.VerboseSpec)) diff --git a/src/pydra/tasks/fsl/fnirt/convertwarp.py b/src/pydra/tasks/fsl/fnirt/convertwarp.py index aa0d911..0ab1c34 100644 --- a/src/pydra/tasks/fsl/fnirt/convertwarp.py +++ b/src/pydra/tasks/fsl/fnirt/convertwarp.py @@ -171,7 +171,4 @@ class ConvertWarp(pydra.engine.ShellCommandTask): executable = "convertwarp" - input_spec = pydra.specs.SpecInfo( - name="ConvertWarpInput", - bases=(ConvertWarpSpec, specs.VerboseSpec), - ) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(ConvertWarpSpec, specs.VerboseSpec)) diff --git a/src/pydra/tasks/fsl/fnirt/fnirt.py b/src/pydra/tasks/fsl/fnirt/fnirt.py index a297476..f6d4818 100644 --- a/src/pydra/tasks/fsl/fnirt/fnirt.py +++ b/src/pydra/tasks/fsl/fnirt/fnirt.py @@ -262,7 +262,4 @@ class FNIRT(pydra.engine.ShellCommandTask): executable = "fnirt" - input_spec = pydra.specs.SpecInfo( - name="FNIRTInput", - bases=(FNIRTSpec, specs.VerboseSpec), - ) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FNIRTSpec, specs.VerboseSpec)) diff --git a/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py b/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py index e32c2a4..6f27632 100644 --- a/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py +++ b/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py @@ -115,7 +115,4 @@ class FNIRTFileUtils(pydra.engine.ShellCommandTask): executable = "fnirtfileutils" - input_spec = pydra.specs.SpecInfo( - name="FNIRTFileUtilsInput", - bases=(FNIRTFileUtilsSpec, specs.VerboseSpec), - ) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FNIRTFileUtilsSpec, specs.VerboseSpec)) diff --git a/src/pydra/tasks/fsl/fnirt/invwarp.py b/src/pydra/tasks/fsl/fnirt/invwarp.py index 8cc395f..cb682ab 100644 --- a/src/pydra/tasks/fsl/fnirt/invwarp.py +++ b/src/pydra/tasks/fsl/fnirt/invwarp.py @@ -100,7 +100,4 @@ class InvWarp(pydra.engine.ShellCommandTask): executable = "invwarp" - input_spec = pydra.specs.SpecInfo( - name="InvWarpInput", - bases=(InvWarpSpec, specs.VerboseSpec), - ) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(InvWarpSpec, specs.VerboseSpec)) diff --git a/src/pydra/tasks/fsl/fslmaths.py b/src/pydra/tasks/fsl/fslmaths.py index 90d92e8..b8e9651 100644 --- a/src/pydra/tasks/fsl/fslmaths.py +++ b/src/pydra/tasks/fsl/fslmaths.py @@ -67,7 +67,7 @@ class FSLMaths(ShellCommandTask): executable = "fslmaths" - input_spec = SpecInfo(name="Inputs", bases=(FSLMathsSpec,)) + input_spec = SpecInfo(name="Input", bases=(FSLMathsSpec,)) @define(kw_only=True) @@ -82,4 +82,4 @@ class MulSpec(FSLMathsSpec): class Mul(FSLMaths): """Task definition for fslmaths' mul.""" - input_spec = SpecInfo(name="Inputs", bases=(MulSpec,)) + input_spec = SpecInfo(name="Input", bases=(MulSpec,)) diff --git a/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py b/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py index e14e83b..0966e7f 100644 --- a/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py +++ b/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py @@ -57,4 +57,4 @@ class FSLPrepareFieldmap(pydra.engine.ShellCommandTask): executable = "fsl_prepare_fieldmap" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLPrepareFieldmapSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLPrepareFieldmapSpec,)) diff --git a/src/pydra/tasks/fsl/fugue/fugue.py b/src/pydra/tasks/fsl/fugue/fugue.py index 2910b44..014e158 100644 --- a/src/pydra/tasks/fsl/fugue/fugue.py +++ b/src/pydra/tasks/fsl/fugue/fugue.py @@ -237,6 +237,6 @@ class FUGUE(pydra.engine.ShellCommandTask): executable = "fugue" - input_spec = pydra.specs.SpecInfo(name="FUGUEInput", bases=(FUGUESpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FUGUESpec,)) - output_spec = pydra.specs.SpecInfo(name="FUGUEOutput", bases=(FUGUEOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(FUGUEOutSpec,)) diff --git a/src/pydra/tasks/fsl/fugue/prelude.py b/src/pydra/tasks/fsl/fugue/prelude.py index ab67359..197ff2d 100644 --- a/src/pydra/tasks/fsl/fugue/prelude.py +++ b/src/pydra/tasks/fsl/fugue/prelude.py @@ -149,4 +149,4 @@ class Prelude(pydra.engine.ShellCommandTask): executable = "prelude" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(PreludeSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(PreludeSpec,)) diff --git a/src/pydra/tasks/fsl/fugue/sigloss.py b/src/pydra/tasks/fsl/fugue/sigloss.py index 6aed5ba..22b3abd 100644 --- a/src/pydra/tasks/fsl/fugue/sigloss.py +++ b/src/pydra/tasks/fsl/fugue/sigloss.py @@ -55,4 +55,4 @@ class SigLoss(pydra.engine.ShellCommandTask): executable = "sigloss" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(SigLossSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(SigLossSpec,)) diff --git a/src/pydra/tasks/fsl/susan.py b/src/pydra/tasks/fsl/susan.py index de6ee2b..a0c5a77 100644 --- a/src/pydra/tasks/fsl/susan.py +++ b/src/pydra/tasks/fsl/susan.py @@ -100,4 +100,4 @@ class SUSAN(pydra.engine.ShellCommandTask): executable = "susan" - input_spec = pydra.specs.SpecInfo(name="SUSANInput", bases=(SUSANSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(SUSANSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslchfiletype.py b/src/pydra/tasks/fsl/utils/fslchfiletype.py index d0039d6..55cded3 100644 --- a/src/pydra/tasks/fsl/utils/fslchfiletype.py +++ b/src/pydra/tasks/fsl/utils/fslchfiletype.py @@ -113,6 +113,6 @@ class FSLChFileType(pydra.engine.ShellCommandTask): executable = "fslchfiletype" - input_spec = pydra.specs.SpecInfo(name="FSLChFileTypeInput", bases=(FSLChFileTypeSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLChFileTypeSpec,)) - output_spec = pydra.specs.SpecInfo(name="FSLChFileTypeOutput", bases=(FSLChFileTypeOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLChFileTypeOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslfft.py b/src/pydra/tasks/fsl/utils/fslfft.py index 0baac06..d65a77e 100644 --- a/src/pydra/tasks/fsl/utils/fslfft.py +++ b/src/pydra/tasks/fsl/utils/fslfft.py @@ -53,4 +53,4 @@ class FSLFFT(pydra.engine.ShellCommandTask): executable = "fslfft" - input_spec = pydra.specs.SpecInfo(name="FSLFFTInput", bases=(FSLFFTSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLFFTSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslinfo.py b/src/pydra/tasks/fsl/utils/fslinfo.py index f0a70d9..56a6c92 100644 --- a/src/pydra/tasks/fsl/utils/fslinfo.py +++ b/src/pydra/tasks/fsl/utils/fslinfo.py @@ -127,6 +127,6 @@ class FSLInfo(pydra.engine.ShellCommandTask): executable = "fslinfo" - input_spec = pydra.specs.SpecInfo(name="FSLInfoInput", bases=(FSLInfoSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLInfoSpec,)) - output_spec = pydra.specs.SpecInfo(name="FSLInfoOutput", bases=(FSLInfoOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLInfoOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslinterleave.py b/src/pydra/tasks/fsl/utils/fslinterleave.py index 4bb2fbd..302164e 100644 --- a/src/pydra/tasks/fsl/utils/fslinterleave.py +++ b/src/pydra/tasks/fsl/utils/fslinterleave.py @@ -56,4 +56,4 @@ class FSLInterleave(pydra.engine.ShellCommandTask): executable = "fslinterleave" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLInterleaveSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLInterleaveSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslmerge.py b/src/pydra/tasks/fsl/utils/fslmerge.py index cf3ce4f..607d580 100644 --- a/src/pydra/tasks/fsl/utils/fslmerge.py +++ b/src/pydra/tasks/fsl/utils/fslmerge.py @@ -75,4 +75,4 @@ class FSLMerge(pydra.engine.ShellCommandTask): executable = "fslmerge" - input_spec = pydra.specs.SpecInfo(name="FSLMergeInput", bases=(FSLMergeSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLMergeSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslorient.py b/src/pydra/tasks/fsl/utils/fslorient.py index 9986288..5ba8a46 100644 --- a/src/pydra/tasks/fsl/utils/fslorient.py +++ b/src/pydra/tasks/fsl/utils/fslorient.py @@ -81,6 +81,6 @@ class FSLOrient(ShellCommandTask): executable = "fslorient" - input_spec = SpecInfo(name="Inputs", bases=(FSLOrientSpec,)) + input_spec = SpecInfo(name="Input", bases=(FSLOrientSpec,)) - output_spec = SpecInfo(name="Outputs", bases=(FSLOrientOutSpec,)) + output_spec = SpecInfo(name="Output", bases=(FSLOrientOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslreorient2std.py b/src/pydra/tasks/fsl/utils/fslreorient2std.py index a478ceb..228500e 100644 --- a/src/pydra/tasks/fsl/utils/fslreorient2std.py +++ b/src/pydra/tasks/fsl/utils/fslreorient2std.py @@ -59,4 +59,4 @@ class FSLReorient2Std(pydra.engine.ShellCommandTask): executable = "fslreorient2std" - input_spec = pydra.specs.SpecInfo(name="FSLReorient2StdInput", bases=(FSLReorient2StdSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLReorient2StdSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslroi.py b/src/pydra/tasks/fsl/utils/fslroi.py index 95e349d..9b66702 100644 --- a/src/pydra/tasks/fsl/utils/fslroi.py +++ b/src/pydra/tasks/fsl/utils/fslroi.py @@ -83,4 +83,4 @@ class FSLROI(ShellCommandTask): executable = "fslroi" - input_spec = SpecInfo(name="Inputs", bases=(FSLROISpec,)) + input_spec = SpecInfo(name="Input", bases=(FSLROISpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslselectvols.py b/src/pydra/tasks/fsl/utils/fslselectvols.py index d8fbc5a..4d825b0 100644 --- a/src/pydra/tasks/fsl/utils/fslselectvols.py +++ b/src/pydra/tasks/fsl/utils/fslselectvols.py @@ -86,4 +86,4 @@ class FSLSelectVols(pydra.engine.ShellCommandTask): executable = "fslselectvols" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLSelectVolsSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSelectVolsSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslsmoothfill.py b/src/pydra/tasks/fsl/utils/fslsmoothfill.py index 0c6cc42..cbd900b 100644 --- a/src/pydra/tasks/fsl/utils/fslsmoothfill.py +++ b/src/pydra/tasks/fsl/utils/fslsmoothfill.py @@ -43,4 +43,4 @@ class FSLSmoothFill(pydra.engine.ShellCommandTask): executable = "fslsmoothfill" - input_spec = pydra.specs.SpecInfo(name="Inputs", bases=(FSLSmoothFillSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSmoothFillSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslsplit.py b/src/pydra/tasks/fsl/utils/fslsplit.py index 1233a37..ea69252 100644 --- a/src/pydra/tasks/fsl/utils/fslsplit.py +++ b/src/pydra/tasks/fsl/utils/fslsplit.py @@ -82,9 +82,9 @@ class FSLSplit(pydra.engine.ShellCommandTask): executable = "fslsplit" - input_spec = pydra.specs.SpecInfo(name="FSLSplitInput", bases=(FSLSplitSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSplitSpec,)) - output_spec = pydra.specs.SpecInfo(name="FSLSplitOutput", bases=(FSLSplitOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLSplitOutSpec,)) @attrs.define(slots=False, kw_only=True) @@ -108,6 +108,6 @@ class FSLSliceOutSpec(FSLSplitOutSpec): class FSLSlice(FSLSplit): """Task definition for fslslice.""" - input_spec = pydra.specs.SpecInfo(name="FSLSliceInput", bases=(FSLSliceSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSliceSpec,)) - output_spec = pydra.specs.SpecInfo(name="FSLSliceOutput", bases=(FSLSliceOutSpec,)) + output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLSliceOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslswapdim.py b/src/pydra/tasks/fsl/utils/fslswapdim.py index 4439741..d0ac0fc 100644 --- a/src/pydra/tasks/fsl/utils/fslswapdim.py +++ b/src/pydra/tasks/fsl/utils/fslswapdim.py @@ -102,4 +102,4 @@ class FSLSwapDim(pydra.engine.ShellCommandTask): executable = "fslswapdim" - input_spec = pydra.specs.SpecInfo(name="FSLSwapDimInput", bases=(FSLSwapDimSpec,)) + input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSwapDimSpec,)) From c346916e8fc005714d069a5051682344cbbd4787 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 195/224] ENH: Drop FSL prefix from utils (#58) * WIP: Drop FSL prefix from utils Improves consistency with Nipype. Compatibility aliases will be maintained in 0.0.x. * WIP: selectvols and roi * WIP: orient and reorient2std * WIP: merge + fixes * WIP: info and interleave * WIP: chfiletype and fft --- README.md | 22 ++-- src/pydra/tasks/fsl/__init__.py | 41 ++++-- src/pydra/tasks/fsl/utils/__init__.py | 48 +++---- src/pydra/tasks/fsl/utils/chfiletype.py | 98 +++++++++++++++ src/pydra/tasks/fsl/utils/fft.py | 50 ++++++++ src/pydra/tasks/fsl/utils/fslchfiletype.py | 118 ------------------ src/pydra/tasks/fsl/utils/fslfft.py | 56 --------- src/pydra/tasks/fsl/utils/fslinterleave.py | 59 --------- src/pydra/tasks/fsl/utils/fslmerge.py | 78 ------------ src/pydra/tasks/fsl/utils/fslselectvols.py | 89 ------------- src/pydra/tasks/fsl/utils/fslsmoothfill.py | 46 ------- src/pydra/tasks/fsl/utils/fslsplit.py | 113 ----------------- src/pydra/tasks/fsl/utils/fslswapdim.py | 105 ---------------- .../tasks/fsl/utils/{fslinfo.py => info.py} | 66 +++++----- src/pydra/tasks/fsl/utils/interleave.py | 55 ++++++++ src/pydra/tasks/fsl/utils/merge.py | 66 ++++++++++ .../fsl/utils/{fslorient.py => orient.py} | 30 ++--- .../{fslreorient2std.py => reorient2std.py} | 30 ++--- .../tasks/fsl/utils/{fslroi.py => roi.py} | 18 +-- src/pydra/tasks/fsl/utils/selectvols.py | 81 ++++++++++++ src/pydra/tasks/fsl/utils/smoothfill.py | 46 +++++++ src/pydra/tasks/fsl/utils/split.py | 86 +++++++++++++ src/pydra/tasks/fsl/utils/swapdim.py | 67 ++++++++++ 23 files changed, 682 insertions(+), 786 deletions(-) create mode 100644 src/pydra/tasks/fsl/utils/chfiletype.py create mode 100644 src/pydra/tasks/fsl/utils/fft.py delete mode 100644 src/pydra/tasks/fsl/utils/fslchfiletype.py delete mode 100644 src/pydra/tasks/fsl/utils/fslfft.py delete mode 100644 src/pydra/tasks/fsl/utils/fslinterleave.py delete mode 100644 src/pydra/tasks/fsl/utils/fslmerge.py delete mode 100644 src/pydra/tasks/fsl/utils/fslselectvols.py delete mode 100644 src/pydra/tasks/fsl/utils/fslsmoothfill.py delete mode 100644 src/pydra/tasks/fsl/utils/fslsplit.py delete mode 100644 src/pydra/tasks/fsl/utils/fslswapdim.py rename src/pydra/tasks/fsl/utils/{fslinfo.py => info.py} (70%) create mode 100644 src/pydra/tasks/fsl/utils/interleave.py create mode 100644 src/pydra/tasks/fsl/utils/merge.py rename src/pydra/tasks/fsl/utils/{fslorient.py => orient.py} (73%) rename src/pydra/tasks/fsl/utils/{fslreorient2std.py => reorient2std.py} (64%) rename src/pydra/tasks/fsl/utils/{fslroi.py => roi.py} (85%) create mode 100644 src/pydra/tasks/fsl/utils/selectvols.py create mode 100644 src/pydra/tasks/fsl/utils/smoothfill.py create mode 100644 src/pydra/tasks/fsl/utils/split.py create mode 100644 src/pydra/tasks/fsl/utils/swapdim.py diff --git a/README.md b/README.md index da6dfc4..cb68555 100644 --- a/README.md +++ b/README.md @@ -26,17 +26,17 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|----------|-----------------------------------------------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy, ApplyTopup, Topup | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | -| fslmaths | (**experimental**) FSLMaths, Mul | -| susan | SUSAN | -| utils | FSLFFT, FSLROI, FSLChFileType, FSLInfo, FSLInterleave, FSLMerge, FSLOrient, FSLReorient2Std, FSLSelectVols, FSLSlice, FSLSmoothFill, FSLSplit, FSLSwapDim | +| Module | Tasks | +|----------|--------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy, ApplyTopup, Topup | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | +| fslmaths | (**experimental**) FSLMaths, Mul | +| susan | SUSAN | +| utils | ChFileType, FFT, Info, Interleave, Merge, Orient, Reorient2Std, ROI, SelectVols, Slice, SmoothFill, Split, SwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 3f8a456..86f5d6f 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -36,17 +36,32 @@ from .fugue import FUGUE, FSLPrepareFieldmap, Prelude, SigLoss from .susan import SUSAN from .utils import ( - FSLFFT, - FSLROI, - FSLChFileType, - FSLInfo, - FSLInterleave, - FSLMerge, - FSLOrient, - FSLReorient2Std, - FSLSelectVols, - FSLSlice, - FSLSmoothFill, - FSLSplit, - FSLSwapDim, + FFT, + ROI, + ChFileType, + Info, + Interleave, + Merge, + Orient, + Reorient2Std, + SelectVols, + Slice, + SmoothFill, + Split, + SwapDim, ) + +# TODO: Drop compatibility aliases when 0.x is released. +FSLFFT = FFT +FSLROI = ROI +FSLChFileType = ChFileType +FSLInfo = Info +FSLInterleave = Interleave +FSLMerge = Merge +FSLOrient = Orient +FSLReorient2Std = Reorient2Std +FSLSelectVols = SelectVols +FSLSlice = Slice +FSLSmoothFill = SmoothFill +FSLSplit = Split +FSLSwapDim = SwapDim diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/src/pydra/tasks/fsl/utils/__init__.py index 4b00212..4d94ca8 100644 --- a/src/pydra/tasks/fsl/utils/__init__.py +++ b/src/pydra/tasks/fsl/utils/__init__.py @@ -2,29 +2,29 @@ Utils ===== -.. automodule:: pydra.tasks.fsl.utils.fslchfiletype -.. automodule:: pydra.tasks.fsl.utils.fslfft -.. automodule:: pydra.tasks.fsl.utils.fslinfo -.. automodule:: pydra.tasks.fsl.utils.fslinterleave -.. automodule:: pydra.tasks.fsl.utils.fslmerge -.. automodule:: pydra.tasks.fsl.utils.fslorient -.. automodule:: pydra.tasks.fsl.utils.fslreorient2std -.. automodule:: pydra.tasks.fsl.utils.fslroi -.. automodule:: pydra.tasks.fsl.utils.fslselectvols -.. automodule:: pydra.tasks.fsl.utils.fslsmoothfill -.. automodule:: pydra.tasks.fsl.utils.fslsplit -.. automodule:: pydra.tasks.fsl.utils.fslswapdim +.. automodule:: pydra.tasks.fsl.utils.chfiletype +.. automodule:: pydra.tasks.fsl.utils.fft +.. automodule:: pydra.tasks.fsl.utils.info +.. automodule:: pydra.tasks.fsl.utils.interleave +.. automodule:: pydra.tasks.fsl.utils.merge +.. automodule:: pydra.tasks.fsl.utils.orient +.. automodule:: pydra.tasks.fsl.utils.reorient2std +.. automodule:: pydra.tasks.fsl.utils.roi +.. automodule:: pydra.tasks.fsl.utils.selectvols +.. automodule:: pydra.tasks.fsl.utils.smoothfill +.. automodule:: pydra.tasks.fsl.utils.split +.. automodule:: pydra.tasks.fsl.utils.swapdim """ -from .fslchfiletype import FSLChFileType -from .fslfft import FSLFFT -from .fslinfo import FSLInfo -from .fslinterleave import FSLInterleave -from .fslmerge import FSLMerge -from .fslorient import FSLOrient -from .fslreorient2std import FSLReorient2Std -from .fslroi import FSLROI -from .fslselectvols import FSLSelectVols -from .fslsmoothfill import FSLSmoothFill -from .fslsplit import FSLSlice, FSLSplit -from .fslswapdim import FSLSwapDim +from .chfiletype import ChFileType +from .fft import FFT +from .info import Info +from .interleave import Interleave +from .merge import Merge +from .orient import Orient +from .reorient2std import Reorient2Std +from .roi import ROI +from .selectvols import SelectVols +from .smoothfill import SmoothFill +from .split import Slice, Split +from .swapdim import SwapDim diff --git a/src/pydra/tasks/fsl/utils/chfiletype.py b/src/pydra/tasks/fsl/utils/chfiletype.py new file mode 100644 index 0000000..f9024cd --- /dev/null +++ b/src/pydra/tasks/fsl/utils/chfiletype.py @@ -0,0 +1,98 @@ +""" +ChFileType +========== + +Convert image to a different NIfTI file format. + +Examples +-------- + +>>> task = ChFileType(filetype="NIFTI2_GZ", input_image="input.nii", output_basename="output") +>>> task.cmdline +'fslchfiletype NIFTI2_GZ input.nii output' +""" + +__all__ = ["ChFileType"] + +from os import PathLike +from pathlib import Path + +from attrs import define, field +from pydra.engine.specs import File, ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + +ALLOWED_FILETYPES = { + "ANALYZE", + "ANALYZE_GZ", + "NIFTI", + "NIFTI_GZ", + "NIFTI_STD::PAIR", + "NIFTI_STD::PAIR_GZ", + "NIFTI2", + "NIFTI2_GZ", + "NIFTI2_STD::PAIR", + "NIFTI2_STD::PAIR_GZ", +} + + +def _get_output_basename(output_basename, input_image): + return output_basename or Path(input_image).name.split(".", 1)[0] + + +def _get_output_image(output_basename, input_image, filetype): + output_basename = _get_output_basename(output_basename, input_image) + + extension = "img" if any(pat in filetype for pat in ["ANALYZE", "PAIR"]) else "nii" + if "GZ" in filetype: + extension += ".gz" + + return Path.cwd() / f"{output_basename}.{extension}" + + +def _get_output_header(output_basename, input_image, filetype): + output_basename = _get_output_basename(output_basename, input_image) + + if any(pat in filetype for pat in ["ANALYZE", "PAIR"]): + extension = "hdr.gz" if "GZ" in filetype else "hdr" + return Path.cwd() / f"{output_basename}.{extension}" + else: + return None + + +@define(kw_only=True) +class ChFileTypeSpec(ShellSpec): + """Specifications for fslchfiletype.""" + + filetype: str = field( + metadata={ + "help_string": "change to this file type", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_FILETYPES, + } + ) + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + + output_basename: str = field(metadata={"help_string": "output basename", "formatter": _get_output_basename}) + + +@define(slots=False, kw_only=True) +class ChFileTypeOutSpec(ShellOutSpec): + """Output specifications for fslchfiletype.""" + + output_image: File = field(metadata={"help_string": "output image", "callable": _get_output_image}) + + output_header: File = field( + metadata={"help_string": "output header for filetypes which support it", "callable": _get_output_header} + ) + + +class ChFileType(ShellCommandTask): + """Task definition for fslchfiletype.""" + + executable = "fslchfiletype" + + input_spec = SpecInfo(name="Input", bases=(ChFileTypeSpec,)) + + output_spec = SpecInfo(name="Output", bases=(ChFileTypeOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fft.py b/src/pydra/tasks/fsl/utils/fft.py new file mode 100644 index 0000000..05863a9 --- /dev/null +++ b/src/pydra/tasks/fsl/utils/fft.py @@ -0,0 +1,50 @@ +""" +FFT (Fast Fourier Transform) +============================ + +Compute the forward or inverse Fast Fourier Transform of a NIfTI image. + +Examples +-------- + +Compute the forward FFT: + +>>> task = FFT(input_image="input.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'fslfft input.nii .../input_fft.nii' + +Compute the inverse FFT: + +>>> task = FFT(input_image="input.nii", output_image="output.nii", inverse=True) +>>> task.cmdline +'fslfft input.nii output.nii -inv' +""" + +__all__ = ["FFT"] + +from os import PathLike + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class FFTSpec(ShellSpec): + """Specifications for fslfft.""" + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + + output_image: str = field( + metadata={"help_string": "output image", "argstr": "", "output_file_template": "{input_image}_fft"} + ) + + inverse: bool = field(metadata={"help_string": "compute the inverse FFT", "argstr": "-inv"}) + + +class FFT(ShellCommandTask): + """Task definition for fslfft.""" + + executable = "fslfft" + + input_spec = SpecInfo(name="Input", bases=(FFTSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslchfiletype.py b/src/pydra/tasks/fsl/utils/fslchfiletype.py deleted file mode 100644 index 55cded3..0000000 --- a/src/pydra/tasks/fsl/utils/fslchfiletype.py +++ /dev/null @@ -1,118 +0,0 @@ -""" -FSLChFileType -============= - -Examples --------- - ->>> task = FSLChFileType( -... filetype="NIFTI2_GZ", -... input_image="input.nii", -... output_basename="output", -... ) ->>> task.cmdline -'fslchfiletype NIFTI2_GZ input.nii output' -""" - -__all__ = ["FSLChFileType"] - -import pathlib - -import attrs - -import pydra - -ALLOWED_FILETYPES = { - "ANALYZE", - "ANALYZE_GZ", - "NIFTI", - "NIFTI_GZ", - "NIFTI_STD::PAIR", - "NIFTI_STD::PAIR_GZ", - "NIFTI2", - "NIFTI2_GZ", - "NIFTI2_STD::PAIR", - "NIFTI2_STD::PAIR_GZ", -} - - -def _get_output_basename(output_basename, input_image): - return output_basename or pathlib.PurePath(input_image).name.split(".", 1)[0] - - -def _get_output_image(output_basename, input_image, filetype): - output_basename = _get_output_basename(output_basename, input_image) - - extension = "img" if any(pat in filetype for pat in ["ANALYZE", "PAIR"]) else "nii" - if "GZ" in filetype: - extension += ".gz" - - return pathlib.Path.cwd() / f"{output_basename}.{extension}" - - -def _get_output_header(output_basename, input_image, filetype): - output_basename = _get_output_basename(output_basename, input_image) - - if any(pat in filetype for pat in ["ANALYZE", "PAIR"]): - extension = "hdr.gz" if "GZ" in filetype else "hdr" - return pathlib.Path.cwd() / f"{output_basename}.{extension}" - else: - return None - - -@attrs.define(slots=False, kw_only=True) -class FSLChFileTypeSpec(pydra.specs.ShellSpec): - """Specifications for fslchfiletype.""" - - filetype: str = attrs.field( - metadata={ - "help_string": "change to this file type", - "mandatory": True, - "argstr": "", - "allowed_values": ALLOWED_FILETYPES, - } - ) - - input_image: str = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "", - } - ) - - output_basename: str = attrs.field( - metadata={ - "help_string": "output basename", - "formatter": _get_output_basename, - } - ) - - -@attrs.define(slots=False, kw_only=True) -class FSLChFileTypeOutSpec(pydra.specs.ShellOutSpec): - """Output specifications for fslchfiletype.""" - - output_image: pydra.specs.File = attrs.field( - metadata={ - "help_string": "output image", - "callable": _get_output_image, - } - ) - - output_header: pydra.specs.File = attrs.field( - metadata={ - "help_string": "output header for filetypes which support it", - "callable": _get_output_header, - } - ) - - -class FSLChFileType(pydra.engine.ShellCommandTask): - """Task definition for fslchfiletype.""" - - executable = "fslchfiletype" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLChFileTypeSpec,)) - - output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLChFileTypeOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslfft.py b/src/pydra/tasks/fsl/utils/fslfft.py deleted file mode 100644 index d65a77e..0000000 --- a/src/pydra/tasks/fsl/utils/fslfft.py +++ /dev/null @@ -1,56 +0,0 @@ -""" -FSLFFT -====== - -Examples --------- - -Compute the forward FFT: - ->>> task = FSLFFT(input_image="input.nii") ->>> task.cmdline -'fslfft input.nii .../input_fslfft.nii' - -Compute the inverse FFT: - ->>> task = FSLFFT( -... input_image="input.nii", -... output_image="output.nii", -... inverse=True, -... ) ->>> task.cmdline -'fslfft input.nii output.nii -inv' -""" - -__all__ = ["FSLFFT"] - -import os - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLFFTSpec(pydra.specs.ShellSpec): - """Specifications for fslfft.""" - - input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) - - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "", - "output_file_template": "{input_image}_fslfft", - } - ) - - inverse: bool = attrs.field(metadata={"help_string": "compute the inverse FFT", "argstr": "-inv"}) - - -class FSLFFT(pydra.engine.ShellCommandTask): - """Task definition for fslfft.""" - - executable = "fslfft" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLFFTSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslinterleave.py b/src/pydra/tasks/fsl/utils/fslinterleave.py deleted file mode 100644 index 302164e..0000000 --- a/src/pydra/tasks/fsl/utils/fslinterleave.py +++ /dev/null @@ -1,59 +0,0 @@ -""" -FSLInterleave -============= - -Examples --------- - -Interleave images: - ->>> task = FSLInterleave(input_image="in1.nii", other_image="in2.nii") ->>> task.cmdline # doctest: +ELLIPSIS -'fslinterleave in1.nii in2.nii .../in1_interleaved.nii' - -Interleave in reverse order: - ->>> task = FSLInterleave( -... input_image="in1.nii", -... other_image="in2.nii", -... output_image="out.nii", -... reverse=True, -... ) ->>> task.cmdline -'fslinterleave in1.nii in2.nii out.nii -i' -""" - -__all__ = ["FSLInterleave"] - -import os - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLInterleaveSpec(pydra.specs.ShellSpec): - """Specifications for fslinterleave.""" - - input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) - - other_image: os.PathLike = attrs.field(metadata={"help_string": "other image", "mandatory": True, "argstr": ""}) - - output_image: str = attrs.field( - metadata={ - "help_string": "output_image", - "argstr": "", - "output_file_template": "{input_image}_interleaved", - } - ) - - reverse: bool = attrs.field(metadata={"help_string": "reverse slice order", "argstr": "-i"}) - - -class FSLInterleave(pydra.engine.ShellCommandTask): - """Task definition for fslinterleave.""" - - executable = "fslinterleave" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLInterleaveSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslmerge.py b/src/pydra/tasks/fsl/utils/fslmerge.py deleted file mode 100644 index 607d580..0000000 --- a/src/pydra/tasks/fsl/utils/fslmerge.py +++ /dev/null @@ -1,78 +0,0 @@ -""" -FSLMerge -======== - -Examples --------- - ->>> task = FSLMerge( -... dimension="t", -... input_images=["vol1.nii", "vol2.nii"], -... ) ->>> task.cmdline # doctest: +ELLIPSIS -'fslmerge -t ...merged vol1.nii vol2.nii' -""" - -__all__ = ["FSLMerge"] - -import os -import typing as ty - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLMergeSpec(pydra.specs.ShellSpec): - """Specifications for fslmerge.""" - - dimension: str = attrs.field( - metadata={ - "help_string": "merge dimension", - "mandatory": True, - "argstr": "-{dimension}", - "allowed_values": {"t", "x", "y", "z", "a", "tr"}, - "xor": {"volume_index"}, - } - ) - - volume_index: int = attrs.field( - metadata={ - "help_string": "merge volume N from each input file", - "mandatory": True, - "argstr": "-n", - "xor": {"dimension"}, - } - ) - - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "", - "output_file_template": "merged", - } - ) - - input_images: ty.Iterable[os.PathLike] = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "...", - } - ) - - repetition_time: float = attrs.field( - metadata={ - "help_string": "specify TR value in seconds (default is 1.0)", - "argstr": "", - } - ) - - -class FSLMerge(pydra.engine.ShellCommandTask): - """Task definition for fslmerge.""" - - executable = "fslmerge" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLMergeSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslselectvols.py b/src/pydra/tasks/fsl/utils/fslselectvols.py deleted file mode 100644 index 4d825b0..0000000 --- a/src/pydra/tasks/fsl/utils/fslselectvols.py +++ /dev/null @@ -1,89 +0,0 @@ -""" -FSLSelectVols -============= - -Examples --------- - -Select volumes from a list and concatenate them: - ->>> task = FSLSelectVols(input_image="input.nii", volumes=[0, 1, 6, 7]) ->>> task.cmdline -'fslselectvols --in input.nii --out .../input_vols.nii --vols 0,1,6,7' - -Select volumes from a file and calculate their mean: - ->>> task = FSLSelectVols( -... input_image="input.nii", -... output_image="mean.nii", -... volumes="volumes.txt", -... calculate_mean=True, -... ) ->>> task.cmdline -'fslselectvols --in input.nii --out mean.nii --vols volumes.txt -m' - -Select volumes from a file and calculate their variance: - ->>> task = FSLSelectVols( -... input_image="input.nii", -... output_image="variance.nii", -... volumes="volumes.txt", -... calculate_variance=True, -... ) ->>> task.cmdline -'fslselectvols --in input.nii --out variance.nii --vols volumes.txt -v' -""" - -__all__ = ["FSLSelectVols"] - -import os -import typing as ty - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLSelectVolsSpec(pydra.specs.ShellSpec): - """Specifications for fslselectvols.""" - - input_image: os.PathLike = attrs.field(metadata={"help_string": "input_image", "mandatory": True, "argstr": "--in"}) - - output_image: str = attrs.field( - metadata={"help_string": "output image", "argstr": "--out", "output_file_template": "{input_image}_vols"} - ) - - volumes: ty.Union[os.PathLike, ty.Iterable[int]] = attrs.field( - metadata={ - "help_string": "volumes to select (from a file or as a list)", - "mandatory": True, - "formatter": lambda field: ( - f"--vols {str(field) if isinstance(field, (os.PathLike, str)) else ','.join(map(str, field))}" - ), - } - ) - - calculate_mean: bool = attrs.field( - metadata={ - "help_string": "calculate mean instead of concatenating", - "argstr": "-m", - "xor": {"calculate_variance"}, - } - ) - - calculate_variance: bool = attrs.field( - metadata={ - "help_string": "calculate variance instead of concatenating", - "argstr": "-v", - "xor": {"calculate_mean"}, - } - ) - - -class FSLSelectVols(pydra.engine.ShellCommandTask): - """Task definition for fslselectvols.""" - - executable = "fslselectvols" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSelectVolsSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslsmoothfill.py b/src/pydra/tasks/fsl/utils/fslsmoothfill.py deleted file mode 100644 index cbd900b..0000000 --- a/src/pydra/tasks/fsl/utils/fslsmoothfill.py +++ /dev/null @@ -1,46 +0,0 @@ -""" -FSLSmoothFill -============= - -Examples --------- - ->>> task = FSLSmoothFill(input_image="input.nii", output_image="smoothed.nii", input_mask="mask.nii") ->>> task.cmdline -'fslsmoothfill --in input.nii --out smoothed.nii --mask mask.nii' -""" - -__all__ = ["FSLSmoothFill"] - -import os - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLSmoothFillSpec(pydra.specs.ShellSpec): - """Specifications for fslsmoothfill.""" - - input_image: os.PathLike = attrs.field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"}) - - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "--out", - "output_file_template": "{input_image}_smoothed", - } - ) - - input_mask: os.PathLike = attrs.field(metadata={"help_string": "input mask", "argstr": "--mask"}) - - num_iterations: int = attrs.field(metadata={"help_string": "number of iterations", "argstr": "--niter"}) - - -class FSLSmoothFill(pydra.engine.ShellCommandTask): - """Task definition for fslsmoothfill.""" - - executable = "fslsmoothfill" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSmoothFillSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslsplit.py b/src/pydra/tasks/fsl/utils/fslsplit.py deleted file mode 100644 index ea69252..0000000 --- a/src/pydra/tasks/fsl/utils/fslsplit.py +++ /dev/null @@ -1,113 +0,0 @@ -""" -FSLSplit -======== - -Examples --------- ->>> task = FSLSplit(input_image="input.nii.gz") ->>> task.cmdline -'fslsplit input.nii.gz input -t' - ->>> task = FSLSlice( -... input_image="volume.nii", -... output_basename="slice", -... ) ->>> task.cmdline -'fslsplit volume.nii slice -z' -""" - -__all__ = ["FSLSplit", "FSLSlice"] - -import os -import pathlib - -import attrs - -import pydra - - -def _get_output_basename(output_basename, input_image): - return output_basename or pathlib.PurePath(input_image).name.split(".", 1)[0] - - -def _get_output_images(output_basename, input_image): - output_basename = _get_output_basename(output_basename, input_image) - - return sorted(pathlib.Path.cwd().glob(f"{output_basename}*.*")) - - -@attrs.define(slots=False, kw_only=True) -class FSLSplitSpec(pydra.specs.ShellSpec): - """Specifications for fslsplit.""" - - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "", - } - ) - - output_basename: str = attrs.field( - metadata={ - "help_string": "output basename", - "formatter": _get_output_basename, - } - ) - - direction: str = attrs.field( - default="t", - metadata={ - "help_string": "split direction (x, y, z or t)", - "argstr": "-{direction}", - "allowed_values": {"x", "y", "z", "t"}, - }, - ) - - -@attrs.define(slots=False, kw_only=True) -class FSLSplitOutSpec(pydra.specs.ShellOutSpec): - """Output specifications for fslsplit.""" - - output_images: pydra.specs.MultiOutputFile = attrs.field( - metadata={ - "help_string": "output images", - "callable": _get_output_images, - } - ) - - -class FSLSplit(pydra.engine.ShellCommandTask): - """Task definition for fslsplit.""" - - executable = "fslsplit" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSplitSpec,)) - - output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLSplitOutSpec,)) - - -@attrs.define(slots=False, kw_only=True) -class FSLSliceSpec(FSLSplitSpec): - """Specifications for fslslice.""" - - direction: str = attrs.field( - default="z", - metadata={ - "help_string": "split direction (z)", - "argstr": "-{direction}", - "allowed_values": {"z"}, - }, - ) - - -class FSLSliceOutSpec(FSLSplitOutSpec): - """Output specifications for fslslice.""" - - -class FSLSlice(FSLSplit): - """Task definition for fslslice.""" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSliceSpec,)) - - output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLSliceOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslswapdim.py b/src/pydra/tasks/fsl/utils/fslswapdim.py deleted file mode 100644 index d0ac0fc..0000000 --- a/src/pydra/tasks/fsl/utils/fslswapdim.py +++ /dev/null @@ -1,105 +0,0 @@ -""" -FSLSwapDim -========== - -Examples --------- - ->>> task = FSLSwapDim( -... input_image="input.nii", -... new_x="y", -... new_y="x", -... new_z="-z", -... ) ->>> task.cmdline # doctest: +ELLIPSIS -'fslswapdim input.nii y x -z ...input_swapped.nii' - ->>> task = FSLSwapDim( -... input_image="input.nii", -... output_image="output.nii", -... new_x="RL", -... new_y="PA", -... new_z="IS", -... ) ->>> task.cmdline -'fslswapdim input.nii RL PA IS output.nii' -""" - -__all__ = ["FSLSwapDim"] - -import os - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLSwapDimSpec(pydra.specs.ShellSpec): - """Specifications for fslswapdim.""" - - ALLOWED_AXES = { - "x", - "-x", - "y", - "-y", - "z", - "-z", - "LR", - "RL", - "AP", - "PA", - "SI", - "IS", - } - - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "", - } - ) - - new_x: str = attrs.field( - metadata={ - "help_string": "new x-axis", - "mandatory": True, - "argstr": "", - "allowed_values": ALLOWED_AXES, - } - ) - - new_y: str = attrs.field( - metadata={ - "help_string": "new y-axis", - "mandatory": True, - "argstr": "", - "allowed_values": ALLOWED_AXES, - } - ) - - new_z: str = attrs.field( - metadata={ - "help_string": "new z-axis", - "mandatory": True, - "argstr": "", - "allowed_values": ALLOWED_AXES, - } - ) - - output_image: str = attrs.field( - metadata={ - "help_string": "output image", - "argstr": "", - "output_file_template": "{input_image}_swapped", - } - ) - - -class FSLSwapDim(pydra.engine.ShellCommandTask): - """Task definition for fslswapdim.""" - - executable = "fslswapdim" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLSwapDimSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslinfo.py b/src/pydra/tasks/fsl/utils/info.py similarity index 70% rename from src/pydra/tasks/fsl/utils/fslinfo.py rename to src/pydra/tasks/fsl/utils/info.py index 56a6c92..00137bd 100644 --- a/src/pydra/tasks/fsl/utils/fslinfo.py +++ b/src/pydra/tasks/fsl/utils/info.py @@ -1,120 +1,116 @@ """ -FSLInfo -======= +Info +==== + +Read essential metadata from the header of a NIfTI image. """ -__all__ = ["FSLInfo"] +__all__ = ["Info"] -import os import re +from os import PathLike -import attrs - -import pydra +from attrs import define, field +from pydra.engine.specs import ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask -@attrs.define(slots=False, kw_only=True) -class FSLInfoSpec(pydra.specs.ShellSpec): +@define(slots=False, kw_only=True) +class InfoSpec(ShellSpec): """Specifications for fslinfo.""" - input_image: os.PathLike = attrs.field( - metadata={ - "help_string": "input image", - "mandatory": True, - "argstr": "", - } - ) + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) -@attrs.define(slots=False, kw_only=True) -class FSLInfoOutSpec(pydra.specs.ShellOutSpec): +@define(kw_only=True) +class InfoOutSpec(ShellOutSpec): """Output specifications for fslinfo.""" - data_type: str = attrs.field( + data_type: str = field( metadata={ "help_string": "data type string", "callable": lambda stdout: re.search(r"data_type\s*(.*)", stdout).group(1), } ) - dim1: int = attrs.field( + dim1: int = field( metadata={ "help_string": "array size in 1st dimension", "callable": lambda stdout: int(re.search(r"\sdim1\s*(.*)", stdout).group(1)), } ) - dim2: int = attrs.field( + dim2: int = field( metadata={ "help_string": "array size in 2nd dimension", "callable": lambda stdout: int(re.search(r"\sdim2\s*(.*)", stdout).group(1)), } ) - dim3: int = attrs.field( + dim3: int = field( metadata={ "help_string": "array size in 3rd dimension", "callable": lambda stdout: int(re.search(r"\sdim3\s*(.*)", stdout).group(1)), } ) - dim4: int = attrs.field( + dim4: int = field( metadata={ "help_string": "array size in 4th dimension", "callable": lambda stdout: int(re.search(r"\sdim4\s*(.*)", stdout).group(1)), } ) - datatype: int = attrs.field( + datatype: int = field( metadata={ "help_string": "data type code", "callable": lambda stdout: int(re.search(r"datatype\s*(.*)", stdout).group(1)), } ) - pixdim1: float = attrs.field( + pixdim1: float = field( metadata={ "help_string": "pixel spacing in 1st dimension", "callable": lambda stdout: float(re.search(r"pixdim1\s*(.*)", stdout).group(1)), } ) - pixdim2: float = attrs.field( + pixdim2: float = field( metadata={ "help_string": "pixel spacing in 2nd dimension", "callable": lambda stdout: float(re.search(r"pixdim2\s*(.*)", stdout).group(1)), } ) - pixdim3: float = attrs.field( + pixdim3: float = field( metadata={ "help_string": "pixel spacing in 3rd dimension", "callable": lambda stdout: float(re.search(r"pixdim3\s*(.*)", stdout).group(1)), } ) - pixdim4: float = attrs.field( + pixdim4: float = field( metadata={ "help_string": "pixel spacing in 4th dimension", "callable": lambda stdout: float(re.search(r"pixdim4\s*(.*)", stdout).group(1)), } ) - cal_max: float = attrs.field( + cal_max: float = field( metadata={ "help_string": "maximum display intensity", "callable": lambda stdout: float(re.search(r"cal_max\s*(.*)", stdout).group(1)), } ) - cal_min: float = attrs.field( + cal_min: float = field( metadata={ "help_string": "minimum display intensity", "callable": lambda stdout: float(re.search(r"cal_min\s*(.*)", stdout).group(1)), } ) - file_type: str = attrs.field( + file_type: str = field( metadata={ "help_string": "NIfTI file type", "callable": lambda stdout: re.search(r"file_type\s*(.*)", stdout).group(1), @@ -122,11 +118,11 @@ class FSLInfoOutSpec(pydra.specs.ShellOutSpec): ) -class FSLInfo(pydra.engine.ShellCommandTask): - """ """ +class Info(ShellCommandTask): + """Task definition for fslinfo.""" executable = "fslinfo" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLInfoSpec,)) + input_spec = SpecInfo(name="Input", bases=(InfoSpec,)) - output_spec = pydra.specs.SpecInfo(name="Output", bases=(FSLInfoOutSpec,)) + output_spec = SpecInfo(name="Output", bases=(InfoOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/interleave.py b/src/pydra/tasks/fsl/utils/interleave.py new file mode 100644 index 0000000..db067ff --- /dev/null +++ b/src/pydra/tasks/fsl/utils/interleave.py @@ -0,0 +1,55 @@ +""" +Interleave +========== + +Examples +-------- + +Interleave images: + +>>> task = Interleave(input_image="in1.nii", other_image="in2.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'fslinterleave in1.nii in2.nii .../in1_interleave.nii' + +Interleave in reverse order: + +>>> task = Interleave( +... input_image="in1.nii", +... other_image="in2.nii", +... output_image="out.nii", +... reverse=True, +... ) +>>> task.cmdline +'fslinterleave in1.nii in2.nii out.nii -i' +""" + +__all__ = ["Interleave"] + +from os import PathLike + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class InterleaveSpec(ShellSpec): + """Specifications for fslinterleave.""" + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + + other_image: PathLike = field(metadata={"help_string": "other image", "mandatory": True, "argstr": ""}) + + output_image: str = field( + metadata={"help_string": "output_image", "argstr": "", "output_file_template": "{input_image}_interleave"} + ) + + reverse: bool = field(metadata={"help_string": "reverse slice order", "argstr": "-i"}) + + +class Interleave(ShellCommandTask): + """Task definition for fslinterleave.""" + + executable = "fslinterleave" + + input_spec = SpecInfo(name="Input", bases=(InterleaveSpec,)) diff --git a/src/pydra/tasks/fsl/utils/merge.py b/src/pydra/tasks/fsl/utils/merge.py new file mode 100644 index 0000000..eca13ee --- /dev/null +++ b/src/pydra/tasks/fsl/utils/merge.py @@ -0,0 +1,66 @@ +""" +Merge +===== + +Examples +-------- + +>>> task = Merge(dimension="t", input_images=["vol1.nii", "vol2.nii"]) +>>> task.cmdline # doctest: +ELLIPSIS +'fslmerge -t ...merged vol1.nii vol2.nii' +""" + +__all__ = ["Merge"] + +from os import PathLike +from typing import Iterable + +from attrs import define, field +from pydra.engine.specs import File, ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class MergeSpec(ShellSpec): + """Specifications for fslmerge.""" + + dimension: str = field( + metadata={ + "help_string": "merge dimension", + "mandatory": True, + "argstr": "-{dimension}", + "allowed_values": {"t", "x", "y", "z", "a", "tr"}, + "xor": {"volume_index"}, + } + ) + + volume_index: int = field( + metadata={ + "help_string": "merge volume N from each input file", + "mandatory": True, + "argstr": "-n", + "xor": {"dimension"}, + } + ) + + output_image: str = field(metadata={"help_string": "output image", "argstr": "", "output_file_template": "merged"}) + + input_images: Iterable[PathLike] = field( + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "...", + } + ) + + repetition_time: float = field( + metadata={"help_string": "specify TR value in seconds (default is 1.0)", "argstr": ""} + ) + + +class Merge(ShellCommandTask): + """Task definition for fslmerge.""" + + executable = "fslmerge" + + input_spec = SpecInfo(name="Input", bases=(MergeSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslorient.py b/src/pydra/tasks/fsl/utils/orient.py similarity index 73% rename from src/pydra/tasks/fsl/utils/fslorient.py rename to src/pydra/tasks/fsl/utils/orient.py index 5ba8a46..2c963c3 100644 --- a/src/pydra/tasks/fsl/utils/fslorient.py +++ b/src/pydra/tasks/fsl/utils/orient.py @@ -1,6 +1,6 @@ """ -FSLOrient -========= +Orient +====== Change the orientation of an image. @@ -12,38 +12,38 @@ Change orientation to radiological: ->>> task = FSLOrient(input_image=input_file.name, force_radiological=True) +>>> task = Orient(input_image=input_file.name, force_radiological=True) >>> task.cmdline # doctest: +ELLIPSIS 'fslorient -forceradiological ...input.nii' Change orientation to neurological: ->>> task = FSLOrient(input_image=input_file.name, force_neurological=True) +>>> task = Orient(input_image=input_file.name, force_neurological=True) >>> task.cmdline # doctest: +ELLIPSIS 'fslorient -forceneurological ...input.nii' Swap between radiological and neurological: ->>> task = FSLOrient(input_image=input_file.name, swap_orientation=True) +>>> task = Orient(input_image=input_file.name, swap_orientation=True) >>> task.cmdline # doctest: +ELLIPSIS 'fslorient -swaporient ...input.nii' Delete orientation: ->>> task = FSLOrient(input_image=input_file.name, delete_orientation=True) +>>> task = Orient(input_image=input_file.name, delete_orientation=True) >>> task.cmdline # doctest: +ELLIPSIS 'fslorient -deleteorient ...input.nii' """ -__all__ = ["FSLOrient"] +__all__ = ["Orient"] from attrs import define, field -from pydra.engine import ShellCommandTask from pydra.engine.specs import File, ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask -@define(slots=False, kw_only=True) -class FSLOrientSpec(ShellSpec): +@define(kw_only=True) +class OrientSpec(ShellSpec): """Specifications for fslorient.""" _xor = {"delete_orientation", "force_radiological", "force_neurological", "swap_orientation"} @@ -69,18 +69,18 @@ class FSLOrientSpec(ShellSpec): ) -@define(slots=False, kw_only=True) -class FSLOrientOutSpec(ShellOutSpec): +@define(kw_only=True) +class OrientOutSpec(ShellOutSpec): """Output specifications for fslorient.""" output_image: File = field(metadata={"help_string": "output image", "output_file_template": "{input_image}"}) -class FSLOrient(ShellCommandTask): +class Orient(ShellCommandTask): """Task definition for fslorient.""" executable = "fslorient" - input_spec = SpecInfo(name="Input", bases=(FSLOrientSpec,)) + input_spec = SpecInfo(name="Input", bases=(OrientSpec,)) - output_spec = SpecInfo(name="Output", bases=(FSLOrientOutSpec,)) + output_spec = SpecInfo(name="Output", bases=(OrientOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslreorient2std.py b/src/pydra/tasks/fsl/utils/reorient2std.py similarity index 64% rename from src/pydra/tasks/fsl/utils/fslreorient2std.py rename to src/pydra/tasks/fsl/utils/reorient2std.py index 228500e..e563216 100644 --- a/src/pydra/tasks/fsl/utils/fslreorient2std.py +++ b/src/pydra/tasks/fsl/utils/reorient2std.py @@ -1,6 +1,6 @@ """ -FSLReorient2Std -=============== +Reorient2Std +============ Change orientation of the image to match the one used for standard template images (MNI152). @@ -8,25 +8,25 @@ Examples -------- ->>> task = FSLReorient2Std(input_image="image.nii") +>>> task = Reorient2Std(input_image="image.nii") >>> task.cmdline # doctest: +ELLIPSIS 'fslreorient2std -m ...image_r2std.mat image.nii ...image_r2std.nii' """ -__all__ = ["FSLReorient2Std"] +__all__ = ["Reorient2Std"] -import os +from os import PathLike -import attrs +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask -import pydra - -@attrs.define(slots=False, kw_only=True) -class FSLReorient2StdSpec(pydra.specs.ShellSpec): +@define(kw_only=True) +class Reorient2StdSpec(ShellSpec): """Specifications for fslreorient2std.""" - input_image: os.PathLike = attrs.field( + input_image: PathLike = field( metadata={ "help_string": "input image", "mandatory": True, @@ -35,7 +35,7 @@ class FSLReorient2StdSpec(pydra.specs.ShellSpec): } ) - output_image: str = attrs.field( + output_image: str = field( metadata={ "help_string": "output reoriented image", "argstr": "", @@ -44,7 +44,7 @@ class FSLReorient2StdSpec(pydra.specs.ShellSpec): } ) - output_matrix: str = attrs.field( + output_matrix: str = field( metadata={ "help_string": "output transformation matrix", "argstr": "-m", @@ -54,9 +54,9 @@ class FSLReorient2StdSpec(pydra.specs.ShellSpec): ) -class FSLReorient2Std(pydra.engine.ShellCommandTask): +class Reorient2Std(ShellCommandTask): """Task definition for fslreorient2std.""" executable = "fslreorient2std" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLReorient2StdSpec,)) + input_spec = SpecInfo(name="Input", bases=(Reorient2StdSpec,)) diff --git a/src/pydra/tasks/fsl/utils/fslroi.py b/src/pydra/tasks/fsl/utils/roi.py similarity index 85% rename from src/pydra/tasks/fsl/utils/fslroi.py rename to src/pydra/tasks/fsl/utils/roi.py index 9b66702..de223ec 100644 --- a/src/pydra/tasks/fsl/utils/fslroi.py +++ b/src/pydra/tasks/fsl/utils/roi.py @@ -1,15 +1,15 @@ """ -FSLROI -====== +ROI (Region-Of-Interest) +======================== -Manual cropping to a region-of-interest (ROI) for structural brain images. +Manual cropping to a region-of-interest for structural brain images. Examples -------- Extract a 16-voxel cube starting at position (10, 20, 30): ->>> task = FSLROI( +>>> task = ROI( ... input_image="image.nii", ... x_min=10, ... x_size=16, @@ -23,12 +23,12 @@ Extract a temporal window starting at 5 onwards: ->>> task = FSLROI(input_image="input.nii", output_image="output.nii", t_min=5) +>>> task = ROI(input_image="input.nii", output_image="output.nii", t_min=5) >>> task.cmdline 'fslroi input.nii output.nii 5 -1' """ -__all__ = ["FSLROI"] +__all__ = ["ROI"] from os import PathLike @@ -38,7 +38,7 @@ @define(kw_only=True) -class FSLROISpec(ShellSpec): +class ROISpec(ShellSpec): """Specifications for fslroi.""" _requires = {"x_min", "y_min", "z_min"} @@ -78,9 +78,9 @@ class FSLROISpec(ShellSpec): t_size: int = field(default=-1, metadata={"help_string": "size of ROI in t (-1 for maximum)", "argstr": ""}) -class FSLROI(ShellCommandTask): +class ROI(ShellCommandTask): """Task definition for fslroi.""" executable = "fslroi" - input_spec = SpecInfo(name="Input", bases=(FSLROISpec,)) + input_spec = SpecInfo(name="Input", bases=(ROISpec,)) diff --git a/src/pydra/tasks/fsl/utils/selectvols.py b/src/pydra/tasks/fsl/utils/selectvols.py new file mode 100644 index 0000000..34e95db --- /dev/null +++ b/src/pydra/tasks/fsl/utils/selectvols.py @@ -0,0 +1,81 @@ +""" +SelectVols +========== + +Examples +-------- + +Select volumes from a list and concatenate them: + +>>> task = SelectVols(input_image="input.nii", volumes=[0, 1, 6, 7]) +>>> task.cmdline +'fslselectvols --in input.nii --out .../input_selectvols.nii --vols 0,1,6,7' + +Select volumes from a file and calculate their mean: + +>>> task = SelectVols( +... input_image="input.nii", +... output_image="mean.nii", +... volumes="volumes.txt", +... calculate_mean=True, +... ) +>>> task.cmdline +'fslselectvols --in input.nii --out mean.nii --vols volumes.txt -m' + +Select volumes from a file and calculate their variance: + +>>> task = SelectVols( +... input_image="input.nii", +... output_image="variance.nii", +... volumes="volumes.txt", +... calculate_variance=True, +... ) +>>> task.cmdline +'fslselectvols --in input.nii --out variance.nii --vols volumes.txt -v' +""" + +__all__ = ["SelectVols"] + +from os import PathLike +from typing import Iterable, Union + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class SelectVolsSpec(ShellSpec): + """Specifications for fslselectvols.""" + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"}) + + output_image: str = field( + metadata={"help_string": "output image", "argstr": "--out", "output_file_template": "{input_image}_selectvols"} + ) + + volumes: Union[PathLike, Iterable[int]] = field( + metadata={ + "help_string": "volumes to select (from a file or as a list)", + "mandatory": True, + "formatter": lambda volumes: ( + f"--vols {str(volumes) if isinstance(volumes, (PathLike, str)) else ','.join(map(str, volumes))}" + ), + } + ) + + calculate_mean: bool = field( + metadata={"help_string": "calculate mean", "argstr": "-m", "xor": {"calculate_variance"}} + ) + + calculate_variance: bool = field( + metadata={"help_string": "calculate variance", "argstr": "-v", "xor": {"calculate_mean"}} + ) + + +class SelectVols(ShellCommandTask): + """Task definition for fslselectvols.""" + + executable = "fslselectvols" + + input_spec = SpecInfo(name="Input", bases=(SelectVolsSpec,)) diff --git a/src/pydra/tasks/fsl/utils/smoothfill.py b/src/pydra/tasks/fsl/utils/smoothfill.py new file mode 100644 index 0000000..008494b --- /dev/null +++ b/src/pydra/tasks/fsl/utils/smoothfill.py @@ -0,0 +1,46 @@ +""" +SmoothFill +========== + +Examples +-------- + +>>> task = SmoothFill(input_image="input.nii", output_image="smoothed.nii", input_mask="mask.nii") +>>> task.cmdline +'fslsmoothfill --in input.nii --out smoothed.nii --mask mask.nii' +""" + +__all__ = ["SmoothFill"] + +from os import PathLike + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class SmoothFillSpec(ShellSpec): + """Specifications for fslsmoothfill.""" + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"}) + + output_image: str = field( + metadata={ + "help_string": "output image", + "argstr": "--out", + "output_file_template": "{input_image}_smoothfill", + } + ) + + input_mask: PathLike = field(metadata={"help_string": "input mask", "argstr": "--mask"}) + + num_iterations: int = field(metadata={"help_string": "number of iterations", "argstr": "--niter"}) + + +class SmoothFill(ShellCommandTask): + """Task definition for fslsmoothfill.""" + + executable = "fslsmoothfill" + + input_spec = SpecInfo(name="Input", bases=(SmoothFillSpec,)) diff --git a/src/pydra/tasks/fsl/utils/split.py b/src/pydra/tasks/fsl/utils/split.py new file mode 100644 index 0000000..3900d5d --- /dev/null +++ b/src/pydra/tasks/fsl/utils/split.py @@ -0,0 +1,86 @@ +""" +Split +===== + +Examples +-------- +>>> task = Split(input_image="input.nii.gz") +>>> task.cmdline +'fslsplit input.nii.gz input -t' + +>>> task = Slice(input_image="volume.nii", output_basename="slice") +>>> task.cmdline +'fslsplit volume.nii slice -z' +""" + +__all__ = ["Split", "Slice"] + +from os import PathLike +from pathlib import Path + +from attrs import define, field +from pydra.engine.specs import MultiOutputFile, ShellOutSpec, ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +def _get_output_basename(output_basename, input_image): + return output_basename or Path(input_image).name.split(".", 1)[0] + + +def _get_output_images(output_basename, input_image): + output_basename = _get_output_basename(output_basename, input_image) + + return sorted(Path.cwd().glob(f"{output_basename}*.*")) + + +@define(kw_only=True) +class SplitSpec(ShellSpec): + """Specifications for fslsplit.""" + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + + output_basename: str = field(metadata={"help_string": "output basename", "formatter": _get_output_basename}) + + direction: str = field( + default="t", + metadata={"help_string": "split direction", "argstr": "-{direction}", "allowed_values": {"x", "y", "z", "t"}}, + ) + + +@define(slots=False, kw_only=True) +class SplitOutSpec(ShellOutSpec): + """Output specifications for fslsplit.""" + + output_images: MultiOutputFile = field(metadata={"help_string": "output images", "callable": _get_output_images}) + + +class Split(ShellCommandTask): + """Task definition for fslsplit.""" + + executable = "fslsplit" + + input_spec = SpecInfo(name="Input", bases=(SplitSpec,)) + + output_spec = SpecInfo(name="Output", bases=(SplitOutSpec,)) + + +@define(kw_only=True) +class SliceSpec(SplitSpec): + """Specifications for fslslice.""" + + direction: str = field( + default="z", + metadata={"help_string": "split direction (z)", "argstr": "-{direction}", "allowed_values": {"z"}}, + ) + + +class SliceOutSpec(SplitOutSpec): + """Output specifications for fslslice.""" + + +class Slice(Split): + """Task definition for fslslice.""" + + input_spec = SpecInfo(name="Input", bases=(SliceSpec,)) + + output_spec = SpecInfo(name="Output", bases=(SliceOutSpec,)) diff --git a/src/pydra/tasks/fsl/utils/swapdim.py b/src/pydra/tasks/fsl/utils/swapdim.py new file mode 100644 index 0000000..49887e9 --- /dev/null +++ b/src/pydra/tasks/fsl/utils/swapdim.py @@ -0,0 +1,67 @@ +""" +SwapDim +======= + +Examples +-------- + +>>> task = SwapDim( +... input_image="input.nii", +... new_x="y", +... new_y="x", +... new_z="-z", +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fslswapdim input.nii y x -z ...input_swapdim.nii' + +>>> task = SwapDim( +... input_image="input.nii", +... output_image="output.nii", +... new_x="RL", +... new_y="PA", +... new_z="IS", +... ) +>>> task.cmdline +'fslswapdim input.nii RL PA IS output.nii' +""" + +__all__ = ["SwapDim"] + +from os import PathLike + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class SwapDimSpec(ShellSpec): + """Specifications for fslswapdim.""" + + ALLOWED_AXES = {"x", "-x", "y", "-y", "z", "-z", "LR", "RL", "AP", "PA", "SI", "IS"} + + input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + + new_x: str = field( + metadata={"help_string": "new x-axis", "mandatory": True, "argstr": "", "allowed_values": ALLOWED_AXES} + ) + + new_y: str = field( + metadata={"help_string": "new y-axis", "mandatory": True, "argstr": "", "allowed_values": ALLOWED_AXES} + ) + + new_z: str = field( + metadata={"help_string": "new z-axis", "mandatory": True, "argstr": "", "allowed_values": ALLOWED_AXES} + ) + + output_image: str = field( + metadata={"help_string": "output image", "argstr": "", "output_file_template": "{input_image}_swapdim"} + ) + + +class SwapDim(ShellCommandTask): + """Task definition for fslswapdim.""" + + executable = "fslswapdim" + + input_spec = SpecInfo(name="Input", bases=(SwapDimSpec,)) From 0b612dabe345093954ab8d55725556e73fc3ee88 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 196/224] ENH: Drop FSL prefix from prepare_fieldmap (#59) --- src/pydra/tasks/fsl/__init__.py | 3 +- src/pydra/tasks/fsl/fugue/__init__.py | 4 +- .../tasks/fsl/fugue/fsl_prepare_fieldmap.py | 60 ------------------- src/pydra/tasks/fsl/fugue/prepare_fieldmap.py | 60 +++++++++++++++++++ 4 files changed, 64 insertions(+), 63 deletions(-) delete mode 100644 src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py create mode 100644 src/pydra/tasks/fsl/fugue/prepare_fieldmap.py diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 86f5d6f..4898973 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -33,7 +33,7 @@ Std2ImgCoord, ) from .fnirt import FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp -from .fugue import FUGUE, FSLPrepareFieldmap, Prelude, SigLoss +from .fugue import FUGUE, Prelude, PrepareFieldmap, SigLoss from .susan import SUSAN from .utils import ( FFT, @@ -59,6 +59,7 @@ FSLInterleave = Interleave FSLMerge = Merge FSLOrient = Orient +FSLPrepareFieldmap = PrepareFieldmap FSLReorient2Std = Reorient2Std FSLSelectVols = SelectVols FSLSlice = Slice diff --git a/src/pydra/tasks/fsl/fugue/__init__.py b/src/pydra/tasks/fsl/fugue/__init__.py index 62ee1ed..efa3700 100644 --- a/src/pydra/tasks/fsl/fugue/__init__.py +++ b/src/pydra/tasks/fsl/fugue/__init__.py @@ -3,12 +3,12 @@ ===== .. automodule:: pydra.tasks.fsl.fugue.fugue -.. automodule:: pydra.tasks.fsl.fugue.fsl_prepare_fieldmap +.. automodule:: pydra.tasks.fsl.fugue.prepare_fieldmap .. automodule:: pydra.tasks.fsl.fugue.prelude .. automodule:: pydra.tasks.fsl.fugue.sigloss """ -from .fsl_prepare_fieldmap import FSLPrepareFieldmap from .fugue import FUGUE from .prelude import Prelude +from .prepare_fieldmap import PrepareFieldmap from .sigloss import SigLoss diff --git a/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py b/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py deleted file mode 100644 index 0966e7f..0000000 --- a/src/pydra/tasks/fsl/fugue/fsl_prepare_fieldmap.py +++ /dev/null @@ -1,60 +0,0 @@ -""" -FSLPrepareFieldmap -================== - -EPI fieldmap preprocessing. - -Examples -======== - ->>> task = FSLPrepareFieldmap(phase_image="gre_phase.nii", magnitude_image="gre_mag.nii", output_image="fmap.nii") ->>> task.cmdline -'fsl_prepare_fieldmap SIEMENS gre_phase.nii gre_mag.nii fmap.nii 2.46' -""" - -__all__ = ["FSLPrepareFieldmap"] - -import os - -import attrs - -import pydra - - -@attrs.define(slots=False, kw_only=True) -class FSLPrepareFieldmapSpec(pydra.specs.ShellSpec): - """Specifications for fsl_prepare_fieldmap.""" - - scanner: str = attrs.field(default="SIEMENS", metadata={"help_string": "scanner (usually SIEMENS)", "argstr": ""}) - - phase_image: os.PathLike = attrs.field(metadata={"help_string": "phase image", "mandatory": True, "argstr": ""}) - - magnitude_image: os.PathLike = attrs.field( - metadata={"help_string": "magnitude (brain extracted) image", "mandatory": True, "argstr": ""} - ) - - output_image: str = attrs.field( - metadata={ - "help_string": "output fieldmap image in rad/s", - "argstr": "", - "output_file_template": "{phase_image}_fmap", - } - ) - - delta_te: float = attrs.field( - default=2.46, - metadata={ - "help_string": "echo time difference of the fieldmap sequence in milliseconds (usually 2.46 on SIEMENS)", - "argstr": "", - }, - ) - - no_check: bool = attrs.field(metadata={"help_string": "disable sanity checks for images", "argstr": "--nocheck"}) - - -class FSLPrepareFieldmap(pydra.engine.ShellCommandTask): - """Task definition for fsl_prepare_fieldmap.""" - - executable = "fsl_prepare_fieldmap" - - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FSLPrepareFieldmapSpec,)) diff --git a/src/pydra/tasks/fsl/fugue/prepare_fieldmap.py b/src/pydra/tasks/fsl/fugue/prepare_fieldmap.py new file mode 100644 index 0000000..cc55806 --- /dev/null +++ b/src/pydra/tasks/fsl/fugue/prepare_fieldmap.py @@ -0,0 +1,60 @@ +""" +PrepareFieldmap +=============== + +EPI fieldmap preprocessing. + +Examples +======== + +>>> task = PrepareFieldmap(phase_image="gre_phase.nii", magnitude_image="gre_mag.nii", output_image="fmap.nii") +>>> task.cmdline +'fsl_prepare_fieldmap SIEMENS gre_phase.nii gre_mag.nii fmap.nii 2.46' +""" + +__all__ = ["PrepareFieldmap"] + +from os import PathLike + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class PrepareFieldmapSpec(ShellSpec): + """Specifications for fsl_prepare_fieldmap.""" + + scanner: str = field(default="SIEMENS", metadata={"help_string": "scanner (usually SIEMENS)", "argstr": ""}) + + phase_image: PathLike = field(metadata={"help_string": "phase image", "mandatory": True, "argstr": ""}) + + magnitude_image: PathLike = field( + metadata={"help_string": "magnitude (brain extracted) image", "mandatory": True, "argstr": ""} + ) + + output_image: str = field( + metadata={ + "help_string": "output fieldmap image in rad/s", + "argstr": "", + "output_file_template": "{phase_image}_fmap", + } + ) + + delta_te: float = field( + default=2.46, + metadata={ + "help_string": "echo time difference of the fieldmap sequence in milliseconds (usually 2.46 on SIEMENS)", + "argstr": "", + }, + ) + + no_check: bool = field(metadata={"help_string": "disable sanity checks for images", "argstr": "--nocheck"}) + + +class PrepareFieldmap(ShellCommandTask): + """Task definition for fsl_prepare_fieldmap.""" + + executable = "fsl_prepare_fieldmap" + + input_spec = SpecInfo(name="Input", bases=(PrepareFieldmapSpec,)) From 6ca81adddc305a9c9b18cd746c8957344987ab0c Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 197/224] FIX: FSLPrepareFieldmap -> PrepareFieldmap in docs --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index cb68555..b4f839b 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ for FMRI, MRI and DTI brain imaging data. | fast | FAST | | flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | | fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, FSLPrepareFieldmap, Prelude, SigLoss | +| fugue | FUGUE, PrepareFieldmap, Prelude, SigLoss | | fslmaths | (**experimental**) FSLMaths, Mul | | susan | SUSAN | | utils | ChFileType, FFT, Info, Interleave, Merge, Orient, Reorient2Std, ROI, SelectVols, Slice, SmoothFill, Split, SwapDim | From 8af8e47a3f58d1cae0c2c72c659a3ce40a831d0a Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 198/224] ENH: Drop FSL prefix from maths (#60) --- README.md | 22 +++++------ src/pydra/tasks/fsl/__init__.py | 3 +- src/pydra/tasks/fsl/{fslmaths.py => maths.py} | 39 ++++++++++--------- 3 files changed, 33 insertions(+), 31 deletions(-) rename src/pydra/tasks/fsl/{fslmaths.py => maths.py} (66%) diff --git a/README.md b/README.md index b4f839b..08aa0c0 100644 --- a/README.md +++ b/README.md @@ -26,17 +26,17 @@ for FMRI, MRI and DTI brain imaging data. ## Available tasks -| Module | Tasks | -|----------|--------------------------------------------------------------------------------------------------------------------| -| bet | BET, RobustFOV | -| eddy | Eddy, ApplyTopup, Topup | -| fast | FAST | -| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | -| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | -| fugue | FUGUE, PrepareFieldmap, Prelude, SigLoss | -| fslmaths | (**experimental**) FSLMaths, Mul | -| susan | SUSAN | -| utils | ChFileType, FFT, Info, Interleave, Merge, Orient, Reorient2Std, ROI, SelectVols, Slice, SmoothFill, Split, SwapDim | +| Module | Tasks | +|--------|--------------------------------------------------------------------------------------------------------------------| +| bet | BET, RobustFOV | +| eddy | Eddy, ApplyTopup, Topup | +| fast | FAST | +| flirt | FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, InvertXFM, FixScaleSkew, Img2ImgCoord, Img2StdCoord, Std2ImgCoord | +| fnirt | FNIRT, FNIRTFileUtils, ApplyWarp, ConvertWarp, InvWarp | +| fugue | FUGUE, PrepareFieldmap, Prelude, SigLoss | +| maths | (**experimental**) Maths, Mul | +| susan | SUSAN | +| utils | ChFileType, FFT, Info, Interleave, Merge, Orient, Reorient2Std, ROI, SelectVols, Slice, SmoothFill, Split, SwapDim | ## Installation diff --git a/src/pydra/tasks/fsl/__init__.py b/src/pydra/tasks/fsl/__init__.py index 4898973..8d155ce 100644 --- a/src/pydra/tasks/fsl/__init__.py +++ b/src/pydra/tasks/fsl/__init__.py @@ -17,7 +17,7 @@ .. automodule:: pydra.tasks.fsl.utils """ -from . import fslmaths +from . import maths from .bet import BET, RobustFOV from .eddy import ApplyTopup, Eddy, Topup from .fast import FAST @@ -66,3 +66,4 @@ FSLSmoothFill = SmoothFill FSLSplit = Split FSLSwapDim = SwapDim +fslmaths = maths diff --git a/src/pydra/tasks/fsl/fslmaths.py b/src/pydra/tasks/fsl/maths.py similarity index 66% rename from src/pydra/tasks/fsl/fslmaths.py rename to src/pydra/tasks/fsl/maths.py index b8e9651..646fea0 100644 --- a/src/pydra/tasks/fsl/fslmaths.py +++ b/src/pydra/tasks/fsl/maths.py @@ -9,22 +9,18 @@ Convert input image to float: ->>> task = FSLMaths(input_image="input.nii") ->>> task.cmdline # doctest: +ELLIPSIS -'fslmaths input.nii .../input_fslmaths.nii -odt float' +>>> task = Maths(input_image="input.nii") +>>> task.cmdline # doctest: +ELLIPSIS +'fslmaths input.nii .../input_fslmaths.nii' -Apply mask to input image: +Multiply input image with a binary mask: ->>> task = Mul( -... input_image="input.nii", -... other_image="mask.nii", -... output_image="output.nii", -... ) +>>> task = Mul(input_image="input.nii", other_image="mask.nii", output_image="output.nii") >>> task.cmdline -'fslmaths input.nii -mul mask.nii output.nii -odt float' +'fslmaths input.nii -mul mask.nii output.nii' """ -__all__ = ["FSLMaths", "Mul"] +__all__ = ["Maths", "MathsSpec", "Mul"] from os import PathLike @@ -33,8 +29,8 @@ from pydra.engine.task import ShellCommandTask -@define(slots=False, kw_only=True) -class FSLMathsSpec(ShellSpec): +@define(kw_only=True) +class MathsSpec(ShellSpec): """Specifications for fslmaths.""" _datatypes = {"char", "short", "int", "float", "double", "input"} @@ -57,21 +53,20 @@ class FSLMathsSpec(ShellSpec): ) output_datatype: str = field( - default="float", - metadata={"help_string": "output datatype", "argstr": "-odt", "position": -1, "allowed_values": _datatypes}, + metadata={"help_string": "output datatype", "argstr": "-odt", "position": -1, "allowed_values": _datatypes} ) -class FSLMaths(ShellCommandTask): +class Maths(ShellCommandTask): """Task definition for fslmaths.""" executable = "fslmaths" - input_spec = SpecInfo(name="Input", bases=(FSLMathsSpec,)) + input_spec = SpecInfo(name="Input", bases=(MathsSpec,)) @define(kw_only=True) -class MulSpec(FSLMathsSpec): +class MulSpec(MathsSpec): """Specifications for fslmaths' mul.""" other_image: PathLike = field( @@ -79,7 +74,13 @@ class MulSpec(FSLMathsSpec): ) -class Mul(FSLMaths): +class Mul(Maths): """Task definition for fslmaths' mul.""" input_spec = SpecInfo(name="Input", bases=(MulSpec,)) + + +# TODO: Drop compatibility alias for 0.x +FSLMaths = Maths +FSLMathsSpec = MathsSpec +__all__ += ["FSLMaths", "FSLMathsSpec"] From b9ddf087987a1cc9d8cd920ce4d0bf236c0d9055 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 199/224] CI: Drop testing on Python 3.7 (#61) Python 3.7 is reaching its end-of-life status. --- .github/workflows/test.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 3eef824..8788e16 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -32,7 +32,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest, macos-latest] - python-version: ['3.7', '3.8', '3.9', '3.10', '3.11'] + python-version: ['3.8', '3.9', '3.10', '3.11'] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v3 From 45177d4e6207d1bd56dface52f2c534c33c748d9 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 200/224] MNT: Bump version to 0.0.20 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 07ccd7d..1d49176 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.19" +version = "0.0.20" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From cb8841c6d1f3cab9aa7af555e7039bb1ad823bff Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 201/224] ENH: Use explicit name for image type argument in FAST (#62) Use T1, T2 and PD and convert to 1, 2, 3 under the hood. --- src/pydra/tasks/fsl/fast.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/pydra/tasks/fsl/fast.py b/src/pydra/tasks/fsl/fast.py index e7f96aa..6e0cd68 100644 --- a/src/pydra/tasks/fsl/fast.py +++ b/src/pydra/tasks/fsl/fast.py @@ -28,12 +28,13 @@ class FASTSpec(pydra.specs.ShellSpec): } ) - image_type: int = attrs.field( - default=1, + image_type: str = attrs.field( + default="T1", metadata={ - "help_string": "type of input image(s) (1: T1, 2: T2, 3: PD)", + "help_string": "type of input image (T1, T2 or PD)", "argstr": "-t", - "allowed_values": {1, 2, 3}, + "allowed_values": {"T1", "T2", "PD"}, + "formatter": lambda image_type: "-t {:d}".format({"T1": 1, "T2": 2, "PD": 3}.get(image_type)), }, ) From 44e933343a20d6b66a6f936b899bf39b44114a1b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 202/224] Bump actions/upload-pages-artifact from 1 to 2 (#63) Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 1 to 2. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v1...v2) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index c50459c..8f165c7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -50,7 +50,7 @@ jobs: - name: Setup GitHub Pages uses: actions/configure-pages@v3 - name: Upload artifact - uses: actions/upload-pages-artifact@v1 + uses: actions/upload-pages-artifact@v2 with: path: '.' - name: Deploy to GitHub Pages From fc107c82aad97e4e3b021868ffc05b578ddedea9 Mon Sep 17 00:00:00 2001 From: Gensollen Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 203/224] add missing decorator to Eddy output specs (#64) --- src/pydra/tasks/fsl/eddy/eddy.py | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py index d0a2faa..240204e 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/src/pydra/tasks/fsl/eddy/eddy.py @@ -258,6 +258,7 @@ class EddySpec(ShellSpec): verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) +@define(slots=False, kw_only=True) class EddyOutSpec(ShellOutSpec): """Output specification for eddy.""" From 09a9d49adf50a27238cfc19f981b75df90136906 Mon Sep 17 00:00:00 2001 From: Gensollen Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 204/224] make eddy fieldmap optional (#65) --- src/pydra/tasks/fsl/eddy/eddy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py index 240204e..202a712 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/src/pydra/tasks/fsl/eddy/eddy.py @@ -66,7 +66,7 @@ class EddySpec(ShellSpec): bval_file: PathLike = field(metadata={"help_string": "diffusion weighting", "mandatory": True, "argstr": "--bvals"}) - fieldmap_image: PathLike = field(metadata={"help_string": "fieldmap image", "mandatory": True, "argstr": "--field"}) + fieldmap_image: PathLike = field(metadata={"help_string": "fieldmap image", "argstr": "--field"}) fieldmap_matrix: PathLike = field( metadata={ From f622806fb5b55b1e1f26427536a4869c270726b8 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 205/224] MNT: Bump version to 0.0.21 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 1d49176..6932619 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.20" +version = "0.0.21" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 98387234f1c605930e50cba86df3382d77fd2828 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 206/224] Bump actions/checkout from 3 to 4 (#66) Bumps [actions/checkout](https://github.com/actions/checkout) from 3 to 4. - [Release notes](https://github.com/actions/checkout/releases) - [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md) - [Commits](https://github.com/actions/checkout/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/checkout dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .github/workflows/docs.yaml | 2 +- .github/workflows/publish.yaml | 2 +- .github/workflows/test.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 8f165c7..3d47d12 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -20,7 +20,7 @@ jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: '3.x' diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index e355d3c..540172c 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -15,7 +15,7 @@ jobs: publish: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: '3.x' diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 8788e16..59f8e35 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -18,7 +18,7 @@ jobs: lint: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: '3.x' @@ -35,7 +35,7 @@ jobs: python-version: ['3.8', '3.9', '3.10', '3.11'] runs-on: ${{ matrix.os }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} From 22ff22b813e68fe378f0fd7f5ac6f4782ab0cb76 Mon Sep 17 00:00:00 2001 From: Gensollen Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 207/224] FIX: Use equal-separated option value pairs in eddy (#67) --- src/pydra/tasks/fsl/eddy/eddy.py | 121 ++++++++++++++++++++++--------- 1 file changed, 87 insertions(+), 34 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/src/pydra/tasks/fsl/eddy/eddy.py index 202a712..d40a583 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/src/pydra/tasks/fsl/eddy/eddy.py @@ -17,8 +17,8 @@ ... fieldmap_image="fieldmap.nii", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'eddy --imain input.nii --mask brain.nii --acqp params.txt --index index.txt \ ---bvecs input.bvec --bvals input.bval --field fieldmap.nii --out eddy ...' +'eddy --imain=input.nii --mask=brain.nii --acqp=params.txt --index=index.txt \ +--bvecs=input.bvec --bvals=input.bval --field=fieldmap.nii --out=eddy ...' """ __all__ = ["Eddy"] @@ -37,18 +37,26 @@ class EddySpec(ShellSpec): # Parameters that specify input files. input_image: PathLike = field( - metadata={"help_string": "input image as a 4D volume", "mandatory": True, "argstr": "--imain"} + metadata={ + "help_string": "input image as a 4D volume", + "mandatory": True, + "argstr": "--imain={input_image}", + } ) brain_mask: PathLike = field( - metadata={"help_string": "brain mask as a single volume image", "mandatory": True, "argstr": "--mask"} + metadata={ + "help_string": "brain mask as a single volume image", + "mandatory": True, + "argstr": "--mask={brain_mask}", + } ) encoding_file: PathLike = field( metadata={ "help_string": "acquisition parameters for the diffusion protocol", "mandatory": True, - "argstr": "--acqp", + "argstr": "--acqp={encoding_file}", } ) @@ -56,22 +64,32 @@ class EddySpec(ShellSpec): metadata={ "help_string": "mapping from volume index to encoding parameters", "mandatory": True, - "argstr": "--index", + "argstr": "--index={index_file}", } ) bvec_file: PathLike = field( - metadata={"help_string": "diffusion directions", "mandatory": True, "argstr": "--bvecs"} + metadata={ + "help_string": "diffusion directions", + "mandatory": True, + "argstr": "--bvecs={bvec_file}", + } ) - bval_file: PathLike = field(metadata={"help_string": "diffusion weighting", "mandatory": True, "argstr": "--bvals"}) + bval_file: PathLike = field( + metadata={ + "help_string": "diffusion weighting", + "mandatory": True, + "argstr": "--bvals={bval_file}", + } + ) - fieldmap_image: PathLike = field(metadata={"help_string": "fieldmap image", "argstr": "--field"}) + fieldmap_image: PathLike = field(metadata={"help_string": "fieldmap image", "argstr": "--field={fieldmap_image}"}) fieldmap_matrix: PathLike = field( metadata={ "help_string": "rigid-body transformation matrix from fieldmap to first input volume", - "argstr": "--field_mat", + "argstr": "--field_mat={fieldmap_matrix}", "requires": {"fieldmap_image"}, } ) @@ -82,7 +100,11 @@ class EddySpec(ShellSpec): # Parameters specifying names of output-files. output_basename: str = field( - default="eddy", metadata={"help_string": "basename for output files", "argstr": "--out"} + default="eddy", + metadata={ + "help_string": "basename for output files", + "argstr": "--out={output_basename}", + }, ) # Parameters specifying how eddy should be run. @@ -90,7 +112,7 @@ class EddySpec(ShellSpec): default="quadratic", metadata={ "help_string": "model for the magnetic field generated by Eddy currents", - "argstr": "--flm", + "argstr": "--flm={first_level_model}", "allowed_values": {"movement", "linear", "quadratic", "cubic"}, }, ) @@ -99,7 +121,7 @@ class EddySpec(ShellSpec): default="none", metadata={ "help_string": "model for how diffusion gradients generate Eddy currents", - "argstr": "--slm", + "argstr": "--slm={second_level_model}", "allowed_values": {"none", "linear", "quadratic"}, }, ) @@ -108,12 +130,16 @@ class EddySpec(ShellSpec): default=0, metadata={ "help_string": "filter width used for pre-conditioning data prior to estimating distortions", - "argstr": "--fwhm", + "argstr": "--fwhm={fwhm}", }, ) num_iterations: int = field( - default=5, metadata={"help_string": "number of iterations for eddy", "argstr": "--niter"} + default=5, + metadata={ + "help_string": "number of iterations for eddy", + "argstr": "--niter={num_iterations}", + }, ) fill_empty_planes: bool = field(metadata={"help_string": "detect and fill empty planes", "argstr": "--fep"}) @@ -122,23 +148,34 @@ class EddySpec(ShellSpec): default="spline", metadata={ "help_string": "interpolation method for the estimation phase", - "argstr": "--interp", + "argstr": "--interp={interpolation}", "allowed_values": {"spline", "trilinear"}, }, ) resampling: str = field( default="jac", - metadata={"help_string": "final resampling strategy", "argstr": "--resamp", "allowed_values": {"jac", "lsr"}}, + metadata={ + "help_string": "final resampling strategy", + "argstr": "--resamp={resampling}", + "allowed_values": {"jac", "lsr"}, + }, ) num_voxels: int = field( default=1000, - metadata={"help_string": "number of voxels to use for GP hyperparameter estimation", "argstr": "--nvoxhp"}, + metadata={ + "help_string": "number of voxels to use for GP hyperparameter estimation", + "argstr": "--nvoxhp={num_voxels}", + }, ) fudge_factor: int = field( - default=10, metadata={"help_string": "fudge factor for Q-space smoothing during estimation", "argstr": "--ff"} + default=10, + metadata={ + "help_string": "fudge factor for Q-space smoothing during estimation", + "argstr": "--ff={fudge_factor}", + }, ) # Parameters for outlier replacement (ol) @@ -147,7 +184,7 @@ class EddySpec(ShellSpec): outlier_num_stdevs: int = field( metadata={ "help_string": "number of times off the standard deviation to qualify as outlier", - "argstr": "--ol_nstd", + "argstr": "--ol_nstd={outlier_num_stdevs}", "requires": {"replace_outliers"}, } ) @@ -155,7 +192,7 @@ class EddySpec(ShellSpec): outlier_num_voxels: int = field( metadata={ "help_string": "minimum number of voxels in a slice to qualify for outlier detection", - "argstr": "--ol_nvox", + "argstr": "--ol_nvox={outlier_num_voxels}", "requires": {"replace_outliers"}, } ) @@ -163,35 +200,49 @@ class EddySpec(ShellSpec): outlier_type: str = field( metadata={ "help_string": "type of outliers detected", - "argstr": "--ol_type", + "argstr": "--ol_type={outlier_type}", "allowed_values": {"both", "gw", "sw"}, "requires": {"replace_outliers"}, } ) - multiband_factor: int = field(metadata={"help_string": "multiband factor", "argstr": "--mb"}) + multiband_factor: int = field(metadata={"help_string": "multiband factor", "argstr": "--mb={multiband_factor}"}) multiband_offset: int = field( - metadata={"help_string": "multiband slice offset", "argstr": "--mb_offs", "requires": {"multiband_factor"}} + metadata={ + "help_string": "multiband slice offset", + "argstr": "--mb_offs={multiband_offset}", + "requires": {"multiband_factor"}, + } ) # Parameters for intra-volume movement correction (s2v) movement_prediction_order: int = field( - default=0, metadata={"help_string": "order of movement prediction model", "argstr": "--mporder"} + default=0, + metadata={ + "help_string": "order of movement prediction model", + "argstr": "--mporder={movement_prediction_order}", + }, ) s2v_num_iterations: int = field( - metadata={"help_string": "number of iterations for s2v movement estimation", "argstr": "--s2v_niter"} + metadata={ + "help_string": "number of iterations for s2v movement estimation", + "argstr": "--s2v_niter={s2v_num_iterations}", + } ) s2v_lambda: float = field( - metadata={"help_string": "weighting of regularization for s2v movement estimation", "argstr": "--s2v_lambda"} + metadata={ + "help_string": "weighting of regularization for s2v movement estimation", + "argstr": "--s2v_lambda={s2v_lambda}", + } ) s2v_interpolation: str = field( metadata={ "help_string": "interpolation method for s2v movement estimation.", - "argstr": "--s2v_interp", + "argstr": "--s2v_interp={s2v_interpolation}", "allowed_values": {"spline", "trilinear"}, } ) @@ -199,7 +250,7 @@ class EddySpec(ShellSpec): slice_grouping_file: PathLike = field( metadata={ "help_string": "file containing slice grouping information", - "argstr": "--slspec", + "argstr": "--slspec={slice_grouping_file}", "xor": {"slice_timing_file"}, } ) @@ -207,7 +258,7 @@ class EddySpec(ShellSpec): slice_timing_file: PathLike = field( metadata={ "help_string": "file containing slice timing information", - "argstr": "--json", + "argstr": "--json={slice_timing_file}", "xor": {"slice_grouping_file"}, } ) @@ -223,7 +274,7 @@ class EddySpec(ShellSpec): mbs_num_iterations: int = field( metadata={ "help_string": "number of iterations for MBS field estimation", - "argstr": "--mbs_niter", + "argstr": "--mbs_niter={mbs_num_iterations}", "requires": {"estimate_move_by_susceptibility"}, } ) @@ -231,7 +282,7 @@ class EddySpec(ShellSpec): mbs_lambda: int = field( metadata={ "help_string": "weighting of regularization for MBS field estimation", - "argstr": "--mbs_lambda", + "argstr": "--mbs_lambda={mbs_lambda}", "requires": {"estimate_move_by_susceptibility"}, } ) @@ -239,7 +290,7 @@ class EddySpec(ShellSpec): mbs_knot_spacing: int = field( metadata={ "help_string": "knot-spacing for MBS field estimation", - "argstr": "--mbs_ksp", + "argstr": "--mbs_ksp={mbs_knot_spacing}", "requires": {"estimate_move_by_susceptibility"}, } ) @@ -249,7 +300,9 @@ class EddySpec(ShellSpec): metadata={"help_string": "bypass checks for data shelling", "argstr": "--data_is_shelled"} ) - random_seed: int = field(metadata={"help_string": "random seed for voxel selection", "argstr": "--initrand"}) + random_seed: int = field( + metadata={"help_string": "random seed for voxel selection", "argstr": "--initrand={random_seed}"} + ) save_cnr_maps: bool = field(metadata={"help_string": "save shell-wise CNR maps", "argstr": "--cnr_maps"}) From 02690418df15f1cbfab851f5845409efaf5a5013 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 208/224] FIX: Use equal-separated option value pairs in applytopup --- src/pydra/tasks/fsl/eddy/applytopup.py | 28 ++++++++++++-------------- 1 file changed, 13 insertions(+), 15 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/applytopup.py b/src/pydra/tasks/fsl/eddy/applytopup.py index db0cd13..aa2c14f 100644 --- a/src/pydra/tasks/fsl/eddy/applytopup.py +++ b/src/pydra/tasks/fsl/eddy/applytopup.py @@ -13,8 +13,8 @@ ... method="jac", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'applytopup --imain blipup.nii --datain parameters.txt --inindex 1 \ ---topup fieldmap --out blipup_topup.nii --method jac ...' +'applytopup --imain=blipup.nii --datain=parameters.txt --inindex=1 \ +--topup=fieldmap --out=blipup_topup.nii --method=jac ...' >>> task = ApplyTopup( ... input_image=["blipup.nii", "blipdown.nii"], @@ -25,8 +25,8 @@ ... output_image="corrected.nii", ... ) >>> task.cmdline # doctest: +ELLIPSIS -'applytopup --imain blipup.nii,blipdown.nii --datain parameters.txt \ ---inindex 1,2,3 --topup topup --out corrected.nii ...' +'applytopup --imain=blipup.nii,blipdown.nii --datain=parameters.txt \ +--inindex=1,2,3 --topup=topup --out=corrected.nii ...' """ __all__ = ["ApplyTopup"] @@ -46,7 +46,7 @@ def _to_input_image(field: Union[PathLike, Sequence[PathLike]]) -> str: except TypeError: paths = [PurePath(path) for path in field] - return f"--imain {','.join(str(path) for path in paths)}" + return f"--imain={','.join(str(path) for path in paths)}" def _to_input_index(field: Union[int, Sequence[int]]) -> str: @@ -55,7 +55,7 @@ def _to_input_index(field: Union[int, Sequence[int]]) -> str: except TypeError: indexes = [field] - return f"--inindex {','.join(str(index) for index in indexes)}" + return f"--inindex={','.join(str(index) for index in indexes)}" def _to_topup_basename(fieldmap_image: PathLike, field_coefficients_image: PathLike) -> str: @@ -66,7 +66,7 @@ def _to_topup_basename(fieldmap_image: PathLike, field_coefficients_image: PathL path = PurePath(fieldmap_image) basename = path.parent / path.name.split(".", 1)[0] - return f"--topup {str(basename)}" + return f"--topup={str(basename)}" def _to_output_image( @@ -83,7 +83,7 @@ def _to_output_image( name, ext = path.name.split(".", 1) path = path.with_name(f"{name}_topup.{ext}") - return f"--out {path}" + return f"--out={path}" @define(slots=False, kw_only=True) @@ -102,7 +102,7 @@ class ApplyTopupSpec(ShellSpec): metadata={ "help_string": "text file containing phase encoding directions and timings", "mandatory": True, - "argstr": "--datain", + "argstr": "--datain={encoding_file}", } ) @@ -135,9 +135,7 @@ class ApplyTopupSpec(ShellSpec): } ) - movement_parameters_file: PathLike = field( - metadata={"help_string": "movement parameters file computed by topup", "argstr": None} - ) + movement_parameters_file: PathLike = field(metadata={"help_string": "movement parameters file computed by topup"}) output_image: PathLike = field( metadata={"help_string": "output image", "argstr": "--out", "formatter": _to_output_image} @@ -147,7 +145,7 @@ class ApplyTopupSpec(ShellSpec): default="lsr", metadata={ "help_string": "resampling method", - "argstr": "--method", + "argstr": "--method={method}", "allowed_values": {"jac", "lsr", "vb2D", "vb3D", "vb4D"}, }, ) @@ -156,7 +154,7 @@ class ApplyTopupSpec(ShellSpec): default="spline", metadata={ "help_string": "interpolation model", - "argstr": "--interp", + "argstr": "--interp={interpolation}", "allowed_values": {"spline", "trilinear"}, }, ) @@ -165,7 +163,7 @@ class ApplyTopupSpec(ShellSpec): default="preserve", metadata={ "help_string": "force output datatype", - "argstr": "--datatype", + "argstr": "--datatype={datatype}", "allowed_values": {"preserve", "char", "short", "int", "float", "double"}, }, ) From 429e4797546afd7473580998a56779fbff5797d3 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 209/224] FIX: Use equal-separated option value pairs in topup --- src/pydra/tasks/fsl/eddy/topup.py | 46 +++++++++++++++++++------------ 1 file changed, 29 insertions(+), 17 deletions(-) diff --git a/src/pydra/tasks/fsl/eddy/topup.py b/src/pydra/tasks/fsl/eddy/topup.py index 80c3159..723a2f3 100644 --- a/src/pydra/tasks/fsl/eddy/topup.py +++ b/src/pydra/tasks/fsl/eddy/topup.py @@ -9,8 +9,8 @@ >>> task = Topup(input_image="input.nii", encoding_file="encoding.txt") >>> task.cmdline # doctest: +ELLIPSIS -'topup --imain input.nii --datain encoding.txt --out input_topup \ ---fout ...input_fieldmap.nii --iout ...input_unwarped.nii ...' +'topup --imain=input.nii --datain=encoding.txt --out=input_topup \ +--fout=...input_fieldmap.nii --iout=...input_unwarped.nii ...' Using a multiple resolution approach: @@ -21,7 +21,7 @@ ... smoothing_per_level=(8.0, 4.0, 0.0), ... ) >>> task.cmdline # doctest: +ELLIPSIS -'topup --imain input.nii --datain encoding.txt ... --subsamp 4,2,1 --fwhm 8.0,4.0,0.0 ...' +'topup --imain=input.nii --datain=encoding.txt ... --subsamp=4,2,1 --fwhm=8.0,4.0,0.0 ...' """ __all__ = ["Topup"] @@ -36,24 +36,26 @@ def to_field_per_level(field, param) -> str: - return f"--{param} {','.join([str(elem) for elem in field])}" + return f"--{param}={','.join([str(elem) for elem in field])}" def to_output_basename(field, input_image) -> str: - return f"--out {field or PurePath(input_image).name.split('.', 1)[0] + '_topup'}" + return f"--out={field or PurePath(input_image).name.split('.', 1)[0] + '_topup'}" @define(slots=False, kw_only=True) class TopupSpec(ShellSpec): """Specifications for topup.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--imain"}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": "--imain={input_image}"} + ) encoding_file: PathLike = field( metadata={ "help_string": "text file containing phase encoding directions and timings", "mandatory": True, - "argstr": "--datain", + "argstr": "--datain={encoding_file}", } ) @@ -67,7 +69,7 @@ class TopupSpec(ShellSpec): output_fieldmap_image: str = field( metadata={ "help_string": "output fieldmap image", - "argstr": "--fout", + "argstr": "--fout={output_fieldmap_image}", "output_file_template": "{input_image}_fieldmap", } ) @@ -75,7 +77,7 @@ class TopupSpec(ShellSpec): output_unwarped_image: str = field( metadata={ "help_string": "output unwarped image", - "argstr": "--iout", + "argstr": "--iout={output_unwarped_image}", "output_file_template": "{input_image}_unwarped", } ) @@ -145,7 +147,7 @@ class TopupSpec(ShellSpec): default=True, metadata={ "help_string": "weight regularisation by sum-of-squares", - "formatter": lambda field: f"--ssqlambda {int(field)}", + "formatter": lambda field: f"--ssqlambda={field:d}", }, ) @@ -153,7 +155,7 @@ class TopupSpec(ShellSpec): default="bending_energy", metadata={ "help_string": "regularisation model", - "argstr": "--regmod", + "argstr": "--regmod={regularisation_model}", "allowed_values": {"bending_energy", "membrane_energy"}, }, ) @@ -162,26 +164,34 @@ class TopupSpec(ShellSpec): default=3, metadata={ "help_string": "use quadratic (2) or cubic (3) splines", - "argstr": "--splineorder", + "argstr": "--splineorder={spline_order}", "allowed_values": {2, 3}, }, ) precision: str = field( default="double", - metadata={"help_string": "numerical precision", "argstr": "--numprec", "allowed_values": {"float", "double"}}, + metadata={ + "help_string": "numerical precision", + "argstr": "--numprec={precision}", + "allowed_values": {"float", "double"}, + }, ) interpolation: str = field( default="spline", - metadata={"help_string": "interpolation model", "argstr": "--interp", "allowed_values": {"linear", "spline"}}, + metadata={ + "help_string": "interpolation model", + "argstr": "--interp={interpolation}", + "allowed_values": {"linear", "spline"}, + }, ) scale: bool = field( default=False, metadata={ "help_string": "scale images to a common mean", - "formatter": lambda field: f"--scale {int(field)}", + "formatter": lambda field: f"--scale={field:d}", }, ) @@ -189,11 +199,13 @@ class TopupSpec(ShellSpec): default=True, metadata={ "help_string": "perform calculations on a different grid", - "formatter": lambda field: f"--regrid {int(field)}", + "formatter": lambda field: f"--regrid={field:d}", }, ) - num_threads: int = field(default=1, metadata={"help_string": "number of threads to use", "argstr": "--nthr"}) + num_threads: int = field( + default=1, metadata={"help_string": "number of threads to use", "argstr": "--nthr={num_threads}"} + ) verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) From 2e8c3bc0535ce1f99bf23ce63e89ed78c2b59234 Mon Sep 17 00:00:00 2001 From: Ghislain Vaillant Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 210/224] MNT: Bump version to 0.0.22 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 6932619..fd65464 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.21" +version = "0.0.22" description = "Pydra tasks for FSL" readme = "README.md" requires-python = ">=3.7" From 1fc0c51dfe5f8b5dcbc64ab31394e12df995237e Mon Sep 17 00:00:00 2001 From: Gensollen Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 211/224] NEW: Add Threshold to fsl.maths (#68) * add threshold to fsl maths * MNT: Add unit test for Threshold task --------- Co-authored-by: Ghislain Vaillant --- src/pydra/tasks/fsl/maths.py | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/pydra/tasks/fsl/maths.py b/src/pydra/tasks/fsl/maths.py index 646fea0..9802701 100644 --- a/src/pydra/tasks/fsl/maths.py +++ b/src/pydra/tasks/fsl/maths.py @@ -18,9 +18,13 @@ >>> task = Mul(input_image="input.nii", other_image="mask.nii", output_image="output.nii") >>> task.cmdline 'fslmaths input.nii -mul mask.nii output.nii' + +>>> task = Threshold(input_image="input.nii", threshold=0.3, output_image="output.nii") +>>> task.cmdline +'fslmaths input.nii -thr 0.3 output.nii' """ -__all__ = ["Maths", "MathsSpec", "Mul"] +__all__ = ["Maths", "MathsSpec", "Mul", "Threshold"] from os import PathLike @@ -80,6 +84,21 @@ class Mul(Maths): input_spec = SpecInfo(name="Input", bases=(MulSpec,)) +@define(kw_only=True) +class ThresholdSpec(MathsSpec): + """Specifications for fslmaths' threshold.""" + + threshold: float = field( + metadata={"help_string": "value for thresholding the image", "mandatory": True, "argstr": "-thr"} + ) + + +class Threshold(Maths): + """Task definition for fslmaths' threshold.""" + + input_spec = SpecInfo(name="Input", bases=(ThresholdSpec,)) + + # TODO: Drop compatibility alias for 0.x FSLMaths = Maths FSLMathsSpec = MathsSpec From d3f2b732865aa616a2a2cf91afda67afc3668a8b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 212/224] Bump actions/deploy-pages from 2 to 3 Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 2 to 3. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 3d47d12..3930a28 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -55,4 +55,4 @@ jobs: path: '.' - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v2 + uses: actions/deploy-pages@v3 From 9c3121295b5c9e953bfddcf42c3a78f89e18731a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 213/224] Bump actions/setup-python from 4 to 5 Bumps [actions/setup-python](https://github.com/actions/setup-python) from 4 to 5. - [Release notes](https://github.com/actions/setup-python/releases) - [Commits](https://github.com/actions/setup-python/compare/v4...v5) --- updated-dependencies: - dependency-name: actions/setup-python dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- .github/workflows/publish.yaml | 2 +- .github/workflows/test.yaml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 3930a28..3f36b11 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -21,7 +21,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install Hatch diff --git a/.github/workflows/publish.yaml b/.github/workflows/publish.yaml index 540172c..e06b07a 100644 --- a/.github/workflows/publish.yaml +++ b/.github/workflows/publish.yaml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Build distribution diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml index 59f8e35..801641a 100644 --- a/.github/workflows/test.yaml +++ b/.github/workflows/test.yaml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: '3.x' - name: Install Hatch @@ -36,7 +36,7 @@ jobs: runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v4 - - uses: actions/setup-python@v4 + - uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - name: Install Hatch From e8d0be4102df80f8fa30880994fcbe4f37643351 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 214/224] Bump actions/configure-pages from 3 to 4 Bumps [actions/configure-pages](https://github.com/actions/configure-pages) from 3 to 4. - [Release notes](https://github.com/actions/configure-pages/releases) - [Commits](https://github.com/actions/configure-pages/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/configure-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 3f36b11..faf6f31 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -48,7 +48,7 @@ jobs: with: name: docs - name: Setup GitHub Pages - uses: actions/configure-pages@v3 + uses: actions/configure-pages@v4 - name: Upload artifact uses: actions/upload-pages-artifact@v2 with: From ef786245dfe3891d90034e10d6c188a2ecff56fb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 215/224] Bump actions/download-artifact from 3 to 4 Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 3 to 4. - [Release notes](https://github.com/actions/download-artifact/releases) - [Commits](https://github.com/actions/download-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/download-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index faf6f31..498abb7 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -44,7 +44,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Download documentation - uses: actions/download-artifact@v3 + uses: actions/download-artifact@v4 with: name: docs - name: Setup GitHub Pages From b16f0e7bbd727c5d7ffed04da2d35e779470b72c Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 216/224] Bump actions/upload-artifact from 3 to 4 Bumps [actions/upload-artifact](https://github.com/actions/upload-artifact) from 3 to 4. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](https://github.com/actions/upload-artifact/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/upload-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 498abb7..e0ad625 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -29,7 +29,7 @@ jobs: - name: Build documentation run: hatch run docs:build - name: Upload documentation - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: docs path: 'docs/_build/html' From 9d44bdced48812ea93b833bd3060582b3dff4eb6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 217/224] Bump actions/deploy-pages from 3 to 4 Bumps [actions/deploy-pages](https://github.com/actions/deploy-pages) from 3 to 4. - [Release notes](https://github.com/actions/deploy-pages/releases) - [Commits](https://github.com/actions/deploy-pages/compare/v3...v4) --- updated-dependencies: - dependency-name: actions/deploy-pages dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index e0ad625..8b62890 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -55,4 +55,4 @@ jobs: path: '.' - name: Deploy to GitHub Pages id: deployment - uses: actions/deploy-pages@v3 + uses: actions/deploy-pages@v4 From 9985b1a1f163e2b76b56b5f44167e4c9bc19a75f Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 12:49:32 +1100 Subject: [PATCH 218/224] Bump actions/upload-pages-artifact from 2 to 3 Bumps [actions/upload-pages-artifact](https://github.com/actions/upload-pages-artifact) from 2 to 3. - [Release notes](https://github.com/actions/upload-pages-artifact/releases) - [Commits](https://github.com/actions/upload-pages-artifact/compare/v2...v3) --- updated-dependencies: - dependency-name: actions/upload-pages-artifact dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/docs.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml index 8b62890..9ec3cc8 100644 --- a/.github/workflows/docs.yaml +++ b/.github/workflows/docs.yaml @@ -50,7 +50,7 @@ jobs: - name: Setup GitHub Pages uses: actions/configure-pages@v4 - name: Upload artifact - uses: actions/upload-pages-artifact@v2 + uses: actions/upload-pages-artifact@v3 with: path: '.' - name: Deploy to GitHub Pages From dc54ad7852df4ced914f08407d72ef97e431994b Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 12:57:03 +1100 Subject: [PATCH 219/224] moved packages out of src and set up auto version --- pydra/tasks/fsl/__init__.py | 38 ++++++ pydra/tasks/fsl/latest.py | 3 + .../fsl => pydra/tasks/fsl/v6_0}/__init__.py | 0 .../tasks/fsl/v6_0}/bet/__init__.py | 0 .../fsl => pydra/tasks/fsl/v6_0}/bet/bet.py | 11 +- .../tasks/fsl/v6_0}/bet/robustfov.py | 0 .../tasks/fsl/v6_0}/eddy/__init__.py | 0 .../tasks/fsl/v6_0}/eddy/applytopup.py | 24 +++- .../fsl => pydra/tasks/fsl/v6_0}/eddy/eddy.py | 49 +++++-- .../tasks/fsl/v6_0}/eddy/topup.py | 16 ++- .../fsl => pydra/tasks/fsl/v6_0}/fast.py | 4 +- .../tasks/fsl/v6_0}/flirt/__init__.py | 0 .../tasks/fsl/v6_0}/flirt/convertxfm.py | 20 ++- .../tasks/fsl/v6_0}/flirt/flirt.py | 46 +++++-- .../tasks/fsl/v6_0}/flirt/img2imgcoord.py | 4 +- .../tasks/fsl/v6_0}/flirt/img2stdcoord.py | 4 +- .../tasks/fsl/v6_0}/flirt/specs.py | 12 +- .../tasks/fsl/v6_0}/flirt/std2imgcoord.py | 4 +- .../tasks/fsl/v6_0}/fnirt/__init__.py | 0 .../tasks/fsl/v6_0}/fnirt/applywarp.py | 4 +- .../tasks/fsl/v6_0}/fnirt/convertwarp.py | 4 +- .../tasks/fsl/v6_0}/fnirt/fnirt.py | 4 +- .../tasks/fsl/v6_0}/fnirt/fnirtfileutils.py | 4 +- .../tasks/fsl/v6_0}/fnirt/invwarp.py | 4 +- .../tasks/fsl/v6_0}/fnirt/specs.py | 0 .../tasks/fsl/v6_0}/fugue/__init__.py | 0 .../tasks/fsl/v6_0}/fugue/fugue.py | 0 .../tasks/fsl/v6_0}/fugue/prelude.py | 37 ++++-- .../tasks/fsl/v6_0}/fugue/prepare_fieldmap.py | 22 +++- .../tasks/fsl/v6_0}/fugue/sigloss.py | 16 ++- .../fsl => pydra/tasks/fsl/v6_0}/maths.py | 33 ++++- .../fsl => pydra/tasks/fsl/v6_0}/susan.py | 5 +- .../tasks/fsl/v6_0}/utils/__init__.py | 0 .../tasks/fsl/v6_0}/utils/chfiletype.py | 17 ++- .../fsl => pydra/tasks/fsl/v6_0}/utils/fft.py | 14 +- .../tasks/fsl/v6_0}/utils/info.py | 48 +++++-- .../tasks/fsl/v6_0}/utils/interleave.py | 18 ++- .../tasks/fsl/v6_0}/utils/merge.py | 13 +- .../tasks/fsl/v6_0}/utils/orient.py | 46 ++++++- .../tasks/fsl/v6_0}/utils/reorient2std.py | 0 pydra/tasks/fsl/v6_0/utils/roi.py | 122 ++++++++++++++++++ .../tasks/fsl/v6_0}/utils/selectvols.py | 22 +++- .../tasks/fsl/v6_0}/utils/smoothfill.py | 12 +- .../tasks/fsl/v6_0}/utils/split.py | 24 +++- .../tasks/fsl/v6_0}/utils/swapdim.py | 31 ++++- pyproject.toml | 16 ++- src/pydra/tasks/fsl/latest.py | 3 - src/pydra/tasks/fsl/utils/roi.py | 86 ------------ src/pydra/tasks/fsl/v1_0/__init__.py | 0 49 files changed, 629 insertions(+), 211 deletions(-) create mode 100644 pydra/tasks/fsl/__init__.py create mode 100644 pydra/tasks/fsl/latest.py rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/bet/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/bet/bet.py (93%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/bet/robustfov.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/eddy/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/eddy/applytopup.py (87%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/eddy/eddy.py (89%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/eddy/topup.py (94%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fast.py (97%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/convertxfm.py (85%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/flirt.py (76%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/img2imgcoord.py (91%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/img2stdcoord.py (91%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/specs.py (91%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/flirt/std2imgcoord.py (91%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/applywarp.py (97%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/convertwarp.py (97%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/fnirt.py (98%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/fnirtfileutils.py (96%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/invwarp.py (95%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fnirt/specs.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fugue/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fugue/fugue.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fugue/prelude.py (78%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fugue/prepare_fieldmap.py (69%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/fugue/sigloss.py (72%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/maths.py (72%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/susan.py (93%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/__init__.py (100%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/chfiletype.py (81%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/fft.py (70%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/info.py (62%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/interleave.py (65%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/merge.py (81%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/orient.py (60%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/reorient2std.py (100%) create mode 100644 pydra/tasks/fsl/v6_0/utils/roi.py rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/selectvols.py (76%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/smoothfill.py (72%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/split.py (71%) rename {src/pydra/tasks/fsl => pydra/tasks/fsl/v6_0}/utils/swapdim.py (58%) delete mode 100644 src/pydra/tasks/fsl/latest.py delete mode 100644 src/pydra/tasks/fsl/utils/roi.py delete mode 100644 src/pydra/tasks/fsl/v1_0/__init__.py diff --git a/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/__init__.py new file mode 100644 index 0000000..dc03b8a --- /dev/null +++ b/pydra/tasks/fsl/__init__.py @@ -0,0 +1,38 @@ +""" +This is a basic doctest demonstrating that the package and pydra can both be successfully +imported. + +>>> import pydra.engine +>>> import pydra.tasks.fsl +""" + +from warnings import warn +from pathlib import Path + +pkg_path = Path(__file__).parent.parent + +try: + from ._version import __version__ +except ImportError: + raise RuntimeError( + "pydra-fsl has not been properly installed, please run " + f"`pip install -e {str(pkg_path)}` to install a development version" + ) +if "nipype" not in __version__: + try: + from .auto._version import nipype_version, nipype2pydra_version + except ImportError: + warn( + "Nipype interfaces haven't been automatically converted from their specs in " + f"`nipype-auto-conv`. Please run `{str(pkg_path / 'nipype-auto-conv' / 'generate')}` " + "to generated the converted Nipype interfaces in pydra.tasks.fsl.auto" + ) + else: + n_ver = nipype_version.replace(".", "_") + n2p_ver = nipype2pydra_version.replace(".", "_") + __version__ += ( + "_" if "+" in __version__ else "+" + ) + f"nipype{n_ver}_nipype2pydra{n2p_ver}" + + +__all__ = ["__version__"] diff --git a/pydra/tasks/fsl/latest.py b/pydra/tasks/fsl/latest.py new file mode 100644 index 0000000..edb8f37 --- /dev/null +++ b/pydra/tasks/fsl/latest.py @@ -0,0 +1,3 @@ +PACKAGE_VERSION = "v6_0" + +from .v6_0 import * # noqa diff --git a/src/pydra/tasks/fsl/__init__.py b/pydra/tasks/fsl/v6_0/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/__init__.py rename to pydra/tasks/fsl/v6_0/__init__.py diff --git a/src/pydra/tasks/fsl/bet/__init__.py b/pydra/tasks/fsl/v6_0/bet/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/bet/__init__.py rename to pydra/tasks/fsl/v6_0/bet/__init__.py diff --git a/src/pydra/tasks/fsl/bet/bet.py b/pydra/tasks/fsl/v6_0/bet/bet.py similarity index 93% rename from src/pydra/tasks/fsl/bet/bet.py rename to pydra/tasks/fsl/v6_0/bet/bet.py index b7f0693..1247886 100644 --- a/src/pydra/tasks/fsl/bet/bet.py +++ b/pydra/tasks/fsl/v6_0/bet/bet.py @@ -41,9 +41,13 @@ class BETSpec(pydra.specs.ShellSpec): metadata={"help_string": "save brain surface outline", "argstr": "-o"} ) - save_brain_mask: bool = attrs.field(metadata={"help_string": "save binary brain mask", "argstr": "-m"}) + save_brain_mask: bool = attrs.field( + metadata={"help_string": "save binary brain mask", "argstr": "-m"} + ) - save_skull_image: bool = attrs.field(metadata={"help_string": "save approximate skull image", "argstr": "-s"}) + save_skull_image: bool = attrs.field( + metadata={"help_string": "save approximate skull image", "argstr": "-s"} + ) save_brain_surface_mesh: bool = attrs.field( metadata={ @@ -74,7 +78,8 @@ class BETSpec(pydra.specs.ShellSpec): head_radius: float = attrs.field( metadata={ - "help_string": "Head radius (in millimeters)." " Initial surface sphere is set to half of this value.", + "help_string": "Head radius (in millimeters)." + " Initial surface sphere is set to half of this value.", "argstr": "-r", } ) diff --git a/src/pydra/tasks/fsl/bet/robustfov.py b/pydra/tasks/fsl/v6_0/bet/robustfov.py similarity index 100% rename from src/pydra/tasks/fsl/bet/robustfov.py rename to pydra/tasks/fsl/v6_0/bet/robustfov.py diff --git a/src/pydra/tasks/fsl/eddy/__init__.py b/pydra/tasks/fsl/v6_0/eddy/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/eddy/__init__.py rename to pydra/tasks/fsl/v6_0/eddy/__init__.py diff --git a/src/pydra/tasks/fsl/eddy/applytopup.py b/pydra/tasks/fsl/v6_0/eddy/applytopup.py similarity index 87% rename from src/pydra/tasks/fsl/eddy/applytopup.py rename to pydra/tasks/fsl/v6_0/eddy/applytopup.py index aa2c14f..bc974d7 100644 --- a/src/pydra/tasks/fsl/eddy/applytopup.py +++ b/pydra/tasks/fsl/v6_0/eddy/applytopup.py @@ -58,7 +58,9 @@ def _to_input_index(field: Union[int, Sequence[int]]) -> str: return f"--inindex={','.join(str(index) for index in indexes)}" -def _to_topup_basename(fieldmap_image: PathLike, field_coefficients_image: PathLike) -> str: +def _to_topup_basename( + fieldmap_image: PathLike, field_coefficients_image: PathLike +) -> str: if field_coefficients_image: path = PurePath(field_coefficients_image) basename = path.parent / path.name.split("_fieldcoef", 1)[0] @@ -123,7 +125,11 @@ class ApplyTopupSpec(ShellSpec): ) fieldmap_image: PathLike = field( - metadata={"help_string": "fieldmap image", "mandatory": True, "xor": {"field_coefficients_image"}} + metadata={ + "help_string": "fieldmap image", + "mandatory": True, + "xor": {"field_coefficients_image"}, + } ) field_coefficients_image: PathLike = field( @@ -135,10 +141,16 @@ class ApplyTopupSpec(ShellSpec): } ) - movement_parameters_file: PathLike = field(metadata={"help_string": "movement parameters file computed by topup"}) + movement_parameters_file: PathLike = field( + metadata={"help_string": "movement parameters file computed by topup"} + ) output_image: PathLike = field( - metadata={"help_string": "output image", "argstr": "--out", "formatter": _to_output_image} + metadata={ + "help_string": "output image", + "argstr": "--out", + "formatter": _to_output_image, + } ) method: str = field( @@ -168,7 +180,9 @@ class ApplyTopupSpec(ShellSpec): }, ) - verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) + verbose: bool = field( + metadata={"help_string": "enable verbose logging", "argstr": "--verbose"} + ) class ApplyTopup(ShellCommandTask): diff --git a/src/pydra/tasks/fsl/eddy/eddy.py b/pydra/tasks/fsl/v6_0/eddy/eddy.py similarity index 89% rename from src/pydra/tasks/fsl/eddy/eddy.py rename to pydra/tasks/fsl/v6_0/eddy/eddy.py index d40a583..38335d4 100644 --- a/src/pydra/tasks/fsl/eddy/eddy.py +++ b/pydra/tasks/fsl/v6_0/eddy/eddy.py @@ -84,7 +84,9 @@ class EddySpec(ShellSpec): } ) - fieldmap_image: PathLike = field(metadata={"help_string": "fieldmap image", "argstr": "--field={fieldmap_image}"}) + fieldmap_image: PathLike = field( + metadata={"help_string": "fieldmap image", "argstr": "--field={fieldmap_image}"} + ) fieldmap_matrix: PathLike = field( metadata={ @@ -95,7 +97,10 @@ class EddySpec(ShellSpec): ) no_peas: bool = field( - metadata={"help_string": "do not perform post-Eddy alignment of shells", "argstr": "--dont_peas"} + metadata={ + "help_string": "do not perform post-Eddy alignment of shells", + "argstr": "--dont_peas", + } ) # Parameters specifying names of output-files. @@ -142,7 +147,9 @@ class EddySpec(ShellSpec): }, ) - fill_empty_planes: bool = field(metadata={"help_string": "detect and fill empty planes", "argstr": "--fep"}) + fill_empty_planes: bool = field( + metadata={"help_string": "detect and fill empty planes", "argstr": "--fep"} + ) interpolation: str = field( default="spline", @@ -179,7 +186,9 @@ class EddySpec(ShellSpec): ) # Parameters for outlier replacement (ol) - replace_outliers: bool = field(metadata={"help_string": "replace outliers", "argstr": "--repol"}) + replace_outliers: bool = field( + metadata={"help_string": "replace outliers", "argstr": "--repol"} + ) outlier_num_stdevs: int = field( metadata={ @@ -206,7 +215,12 @@ class EddySpec(ShellSpec): } ) - multiband_factor: int = field(metadata={"help_string": "multiband factor", "argstr": "--mb={multiband_factor}"}) + multiband_factor: int = field( + metadata={ + "help_string": "multiband factor", + "argstr": "--mb={multiband_factor}", + } + ) multiband_offset: int = field( metadata={ @@ -297,18 +311,33 @@ class EddySpec(ShellSpec): # Miscellaneous parameters. data_is_shelled: bool = field( - metadata={"help_string": "bypass checks for data shelling", "argstr": "--data_is_shelled"} + metadata={ + "help_string": "bypass checks for data shelling", + "argstr": "--data_is_shelled", + } ) random_seed: int = field( - metadata={"help_string": "random seed for voxel selection", "argstr": "--initrand={random_seed}"} + metadata={ + "help_string": "random seed for voxel selection", + "argstr": "--initrand={random_seed}", + } ) - save_cnr_maps: bool = field(metadata={"help_string": "save shell-wise CNR maps", "argstr": "--cnr_maps"}) + save_cnr_maps: bool = field( + metadata={"help_string": "save shell-wise CNR maps", "argstr": "--cnr_maps"} + ) - save_residuals: bool = field(metadata={"help_string": "save residuals for all scans", "argstr": "--residuals"}) + save_residuals: bool = field( + metadata={ + "help_string": "save residuals for all scans", + "argstr": "--residuals", + } + ) - verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) + verbose: bool = field( + metadata={"help_string": "enable verbose logging", "argstr": "--verbose"} + ) @define(slots=False, kw_only=True) diff --git a/src/pydra/tasks/fsl/eddy/topup.py b/pydra/tasks/fsl/v6_0/eddy/topup.py similarity index 94% rename from src/pydra/tasks/fsl/eddy/topup.py rename to pydra/tasks/fsl/v6_0/eddy/topup.py index 723a2f3..54f51f7 100644 --- a/src/pydra/tasks/fsl/eddy/topup.py +++ b/pydra/tasks/fsl/v6_0/eddy/topup.py @@ -48,7 +48,11 @@ class TopupSpec(ShellSpec): """Specifications for topup.""" input_image: PathLike = field( - metadata={"help_string": "input image", "mandatory": True, "argstr": "--imain={input_image}"} + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "--imain={input_image}", + } ) encoding_file: PathLike = field( @@ -204,10 +208,16 @@ class TopupSpec(ShellSpec): ) num_threads: int = field( - default=1, metadata={"help_string": "number of threads to use", "argstr": "--nthr={num_threads}"} + default=1, + metadata={ + "help_string": "number of threads to use", + "argstr": "--nthr={num_threads}", + }, ) - verbose: bool = field(metadata={"help_string": "enable verbose logging", "argstr": "--verbose"}) + verbose: bool = field( + metadata={"help_string": "enable verbose logging", "argstr": "--verbose"} + ) @define(slots=False, kw_only=True) diff --git a/src/pydra/tasks/fsl/fast.py b/pydra/tasks/fsl/v6_0/fast.py similarity index 97% rename from src/pydra/tasks/fsl/fast.py rename to pydra/tasks/fsl/v6_0/fast.py index 6e0cd68..ed3a010 100644 --- a/src/pydra/tasks/fsl/fast.py +++ b/pydra/tasks/fsl/v6_0/fast.py @@ -34,7 +34,9 @@ class FASTSpec(pydra.specs.ShellSpec): "help_string": "type of input image (T1, T2 or PD)", "argstr": "-t", "allowed_values": {"T1", "T2", "PD"}, - "formatter": lambda image_type: "-t {:d}".format({"T1": 1, "T2": 2, "PD": 3}.get(image_type)), + "formatter": lambda image_type: "-t {:d}".format( + {"T1": 1, "T2": 2, "PD": 3}.get(image_type) + ), }, ) diff --git a/src/pydra/tasks/fsl/flirt/__init__.py b/pydra/tasks/fsl/v6_0/flirt/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/flirt/__init__.py rename to pydra/tasks/fsl/v6_0/flirt/__init__.py diff --git a/src/pydra/tasks/fsl/flirt/convertxfm.py b/pydra/tasks/fsl/v6_0/flirt/convertxfm.py similarity index 85% rename from src/pydra/tasks/fsl/flirt/convertxfm.py rename to pydra/tasks/fsl/v6_0/flirt/convertxfm.py index 2d96c76..680ac08 100644 --- a/src/pydra/tasks/fsl/flirt/convertxfm.py +++ b/pydra/tasks/fsl/v6_0/flirt/convertxfm.py @@ -66,14 +66,19 @@ class ConvertXFMSpec(BaseSpec): """Specifications for convert_xfm.""" fixscaleskew_matrix: os.PathLike = attrs.field( - metadata={"help_string": " fix scaling and skewness with this matrix", "argstr": "-fixscaleskew"} + metadata={ + "help_string": " fix scaling and skewness with this matrix", + "argstr": "-fixscaleskew", + } ) concat_matrix: os.PathLike = attrs.field( metadata={"help_string": "concatenate with this matrix", "argstr": "-concat"} ) - inverse: bool = attrs.field(metadata={"help_string": "invert the resulting matrix", "argstr": "-inverse"}) + inverse: bool = attrs.field( + metadata={"help_string": "invert the resulting matrix", "argstr": "-inverse"} + ) class ConvertXFM(pydra.engine.ShellCommandTask): @@ -89,7 +94,11 @@ class ConcatXFMSpec(BaseSpec): """Specifications for concat_xfm.""" concat_matrix: os.PathLike = attrs.field( - metadata={"help_string": "concatenate with this matrix", "mandatory": True, "argstr": "-concat"} + metadata={ + "help_string": "concatenate with this matrix", + "mandatory": True, + "argstr": "-concat", + } ) @@ -103,7 +112,10 @@ class ConcatXFM(ConvertXFM): class InvertXFMSpec(BaseSpec): """Specifications for invert_xfm.""" - inverse: bool = attrs.field(default=True, metadata={"help_string": "invert the input matrix", "argstr": "-inverse"}) + inverse: bool = attrs.field( + default=True, + metadata={"help_string": "invert the input matrix", "argstr": "-inverse"}, + ) class InvertXFM(ConvertXFM): diff --git a/src/pydra/tasks/fsl/flirt/flirt.py b/pydra/tasks/fsl/v6_0/flirt/flirt.py similarity index 76% rename from src/pydra/tasks/fsl/flirt/flirt.py rename to pydra/tasks/fsl/v6_0/flirt/flirt.py index 5b118f0..8fe7a6a 100644 --- a/src/pydra/tasks/fsl/flirt/flirt.py +++ b/pydra/tasks/fsl/v6_0/flirt/flirt.py @@ -74,12 +74,20 @@ class BaseSpec(ShellSpec): """Common specifications for FLIRT-based tasks.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "-in"}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": "-in"} + ) - reference_image: PathLike = field(metadata={"help_string": "reference image", "mandatory": True, "argstr": "-ref"}) + reference_image: PathLike = field( + metadata={"help_string": "reference image", "mandatory": True, "argstr": "-ref"} + ) output_image: str = field( - metadata={"help_string": "output image", "argstr": "-out", "output_file_template": "{input_image}_flirt"} + metadata={ + "help_string": "output image", + "argstr": "-out", + "output_file_template": "{input_image}_flirt", + } ) output_datatype: str = field( @@ -96,14 +104,22 @@ class FLIRTSpec(BaseSpec): """Specifications for FLIRT.""" input_weights: PathLike = field( - metadata={"help_string": "voxel-wise weighting for input image", "argstr": "-inweight"} + metadata={ + "help_string": "voxel-wise weighting for input image", + "argstr": "-inweight", + } ) reference_weights: PathLike = field( - metadata={"help_string": "voxel-wise weighting for reference image", "argstr": "-refweight"} + metadata={ + "help_string": "voxel-wise weighting for reference image", + "argstr": "-refweight", + } ) - initial_matrix: PathLike = field(metadata={"help_string": "initial transformation matrix", "argstr": "-init"}) + initial_matrix: PathLike = field( + metadata={"help_string": "initial transformation matrix", "argstr": "-init"} + ) output_matrix: str = field( metadata={ @@ -155,7 +171,11 @@ class ApplyXFMSpec(BaseSpec): """Specifications for ApplyXFM.""" initial_matrix: PathLike = field( - metadata={"help_string": "initial transformation matrix", "mandatory": True, "argstr": "-init"} + metadata={ + "help_string": "initial transformation matrix", + "mandatory": True, + "argstr": "-init", + } ) isotropic_resolution: float = field( @@ -163,15 +183,21 @@ class ApplyXFMSpec(BaseSpec): metadata={ "help_string": "force resampling to isotropic resolution", "formatter": lambda isotropic_resolution: ( - f"-applyisoxfm {isotropic_resolution}" if isotropic_resolution else "-applyxfm" + f"-applyisoxfm {isotropic_resolution}" + if isotropic_resolution + else "-applyxfm" ), }, ) - padding_size: float = field(metadata={"help_string": "padding size in voxels", "argstr": "-paddingsize"}) + padding_size: float = field( + metadata={"help_string": "padding size in voxels", "argstr": "-paddingsize"} + ) class ApplyXFM(FLIRT): """Task definition for ApplyXFM.""" - input_spec = SpecInfo(name="Input", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec)) + input_spec = SpecInfo( + name="Input", bases=(ApplyXFMSpec, specs.InterpolationSpec, specs.VerboseSpec) + ) diff --git a/src/pydra/tasks/fsl/flirt/img2imgcoord.py b/pydra/tasks/fsl/v6_0/flirt/img2imgcoord.py similarity index 91% rename from src/pydra/tasks/fsl/flirt/img2imgcoord.py rename to pydra/tasks/fsl/v6_0/flirt/img2imgcoord.py index 8e2607d..d4794ec 100644 --- a/src/pydra/tasks/fsl/flirt/img2imgcoord.py +++ b/pydra/tasks/fsl/v6_0/flirt/img2imgcoord.py @@ -56,6 +56,8 @@ class Img2ImgCoord(pydra.engine.ShellCommandTask): executable = "img2imgcoord" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(Img2ImgCoordSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(Img2ImgCoordSpec, specs.VerboseSpec) + ) output_spec = pydra.specs.SpecInfo(name="Output", bases=(Img2ImgCoordOutSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/img2stdcoord.py b/pydra/tasks/fsl/v6_0/flirt/img2stdcoord.py similarity index 91% rename from src/pydra/tasks/fsl/flirt/img2stdcoord.py rename to pydra/tasks/fsl/v6_0/flirt/img2stdcoord.py index 950b9d4..3bfb396 100644 --- a/src/pydra/tasks/fsl/flirt/img2stdcoord.py +++ b/pydra/tasks/fsl/v6_0/flirt/img2stdcoord.py @@ -55,6 +55,8 @@ class Img2StdCoord(pydra.engine.ShellCommandTask): executable = "img2stdcoord" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(Img2StdCoordSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(Img2StdCoordSpec, specs.VerboseSpec) + ) output_spec = pydra.specs.SpecInfo(name="Output", bases=(Img2StdCoordOutSpec,)) diff --git a/src/pydra/tasks/fsl/flirt/specs.py b/pydra/tasks/fsl/v6_0/flirt/specs.py similarity index 91% rename from src/pydra/tasks/fsl/flirt/specs.py rename to pydra/tasks/fsl/v6_0/flirt/specs.py index 63ec506..fe1afe6 100644 --- a/src/pydra/tasks/fsl/flirt/specs.py +++ b/pydra/tasks/fsl/v6_0/flirt/specs.py @@ -75,7 +75,9 @@ class SearchSpec(pydra.specs.ShellSpec): default=[-90, 90], metadata={ "help_string": "range of search angles in x", - "formatter": lambda field, no_search: ("" if no_search else f"-searchrx {field[0]} {field[1]}"), + "formatter": lambda field, no_search: ( + "" if no_search else f"-searchrx {field[0]} {field[1]}" + ), }, ) @@ -83,7 +85,9 @@ class SearchSpec(pydra.specs.ShellSpec): default=[-90, 90], metadata={ "help_string": "range of search angles in y", - "formatter": lambda field, no_search: ("" if no_search else f"-searchry {field[0]} {field[1]}"), + "formatter": lambda field, no_search: ( + "" if no_search else f"-searchry {field[0]} {field[1]}" + ), }, ) @@ -91,7 +95,9 @@ class SearchSpec(pydra.specs.ShellSpec): default=[-90, 90], metadata={ "help_string": "range of search angles in z", - "formatter": lambda field, no_search: ("" if no_search else f"-searchrz {field[0]} {field[1]}"), + "formatter": lambda field, no_search: ( + "" if no_search else f"-searchrz {field[0]} {field[1]}" + ), }, ) diff --git a/src/pydra/tasks/fsl/flirt/std2imgcoord.py b/pydra/tasks/fsl/v6_0/flirt/std2imgcoord.py similarity index 91% rename from src/pydra/tasks/fsl/flirt/std2imgcoord.py rename to pydra/tasks/fsl/v6_0/flirt/std2imgcoord.py index ec67193..f45e707 100644 --- a/src/pydra/tasks/fsl/flirt/std2imgcoord.py +++ b/pydra/tasks/fsl/v6_0/flirt/std2imgcoord.py @@ -55,6 +55,8 @@ class Std2ImgCoord(pydra.engine.ShellCommandTask): executable = "std2imgcoord" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(Std2ImgCoordSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(Std2ImgCoordSpec, specs.VerboseSpec) + ) output_spec = pydra.specs.SpecInfo(name="Output", bases=(Std2ImgCoordOutSpec,)) diff --git a/src/pydra/tasks/fsl/fnirt/__init__.py b/pydra/tasks/fsl/v6_0/fnirt/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/fnirt/__init__.py rename to pydra/tasks/fsl/v6_0/fnirt/__init__.py diff --git a/src/pydra/tasks/fsl/fnirt/applywarp.py b/pydra/tasks/fsl/v6_0/fnirt/applywarp.py similarity index 97% rename from src/pydra/tasks/fsl/fnirt/applywarp.py rename to pydra/tasks/fsl/v6_0/fnirt/applywarp.py index d2773c4..c14e640 100644 --- a/src/pydra/tasks/fsl/fnirt/applywarp.py +++ b/pydra/tasks/fsl/v6_0/fnirt/applywarp.py @@ -147,4 +147,6 @@ class ApplyWarp(pydra.engine.ShellCommandTask): executable = "applywarp" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(ApplyWarpSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(ApplyWarpSpec, specs.VerboseSpec) + ) diff --git a/src/pydra/tasks/fsl/fnirt/convertwarp.py b/pydra/tasks/fsl/v6_0/fnirt/convertwarp.py similarity index 97% rename from src/pydra/tasks/fsl/fnirt/convertwarp.py rename to pydra/tasks/fsl/v6_0/fnirt/convertwarp.py index 0ab1c34..37a038f 100644 --- a/src/pydra/tasks/fsl/fnirt/convertwarp.py +++ b/pydra/tasks/fsl/v6_0/fnirt/convertwarp.py @@ -171,4 +171,6 @@ class ConvertWarp(pydra.engine.ShellCommandTask): executable = "convertwarp" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(ConvertWarpSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(ConvertWarpSpec, specs.VerboseSpec) + ) diff --git a/src/pydra/tasks/fsl/fnirt/fnirt.py b/pydra/tasks/fsl/v6_0/fnirt/fnirt.py similarity index 98% rename from src/pydra/tasks/fsl/fnirt/fnirt.py rename to pydra/tasks/fsl/v6_0/fnirt/fnirt.py index f6d4818..314f2b2 100644 --- a/src/pydra/tasks/fsl/fnirt/fnirt.py +++ b/pydra/tasks/fsl/v6_0/fnirt/fnirt.py @@ -262,4 +262,6 @@ class FNIRT(pydra.engine.ShellCommandTask): executable = "fnirt" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FNIRTSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(FNIRTSpec, specs.VerboseSpec) + ) diff --git a/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py b/pydra/tasks/fsl/v6_0/fnirt/fnirtfileutils.py similarity index 96% rename from src/pydra/tasks/fsl/fnirt/fnirtfileutils.py rename to pydra/tasks/fsl/v6_0/fnirt/fnirtfileutils.py index 6f27632..d066e37 100644 --- a/src/pydra/tasks/fsl/fnirt/fnirtfileutils.py +++ b/pydra/tasks/fsl/v6_0/fnirt/fnirtfileutils.py @@ -115,4 +115,6 @@ class FNIRTFileUtils(pydra.engine.ShellCommandTask): executable = "fnirtfileutils" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(FNIRTFileUtilsSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(FNIRTFileUtilsSpec, specs.VerboseSpec) + ) diff --git a/src/pydra/tasks/fsl/fnirt/invwarp.py b/pydra/tasks/fsl/v6_0/fnirt/invwarp.py similarity index 95% rename from src/pydra/tasks/fsl/fnirt/invwarp.py rename to pydra/tasks/fsl/v6_0/fnirt/invwarp.py index cb682ab..0ee4ca2 100644 --- a/src/pydra/tasks/fsl/fnirt/invwarp.py +++ b/pydra/tasks/fsl/v6_0/fnirt/invwarp.py @@ -100,4 +100,6 @@ class InvWarp(pydra.engine.ShellCommandTask): executable = "invwarp" - input_spec = pydra.specs.SpecInfo(name="Input", bases=(InvWarpSpec, specs.VerboseSpec)) + input_spec = pydra.specs.SpecInfo( + name="Input", bases=(InvWarpSpec, specs.VerboseSpec) + ) diff --git a/src/pydra/tasks/fsl/fnirt/specs.py b/pydra/tasks/fsl/v6_0/fnirt/specs.py similarity index 100% rename from src/pydra/tasks/fsl/fnirt/specs.py rename to pydra/tasks/fsl/v6_0/fnirt/specs.py diff --git a/src/pydra/tasks/fsl/fugue/__init__.py b/pydra/tasks/fsl/v6_0/fugue/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/fugue/__init__.py rename to pydra/tasks/fsl/v6_0/fugue/__init__.py diff --git a/src/pydra/tasks/fsl/fugue/fugue.py b/pydra/tasks/fsl/v6_0/fugue/fugue.py similarity index 100% rename from src/pydra/tasks/fsl/fugue/fugue.py rename to pydra/tasks/fsl/v6_0/fugue/fugue.py diff --git a/src/pydra/tasks/fsl/fugue/prelude.py b/pydra/tasks/fsl/v6_0/fugue/prelude.py similarity index 78% rename from src/pydra/tasks/fsl/fugue/prelude.py rename to pydra/tasks/fsl/v6_0/fugue/prelude.py index 197ff2d..6745f14 100644 --- a/src/pydra/tasks/fsl/fugue/prelude.py +++ b/pydra/tasks/fsl/v6_0/fugue/prelude.py @@ -51,7 +51,9 @@ class PreludeSpec(pydra.specs.ShellSpec): } ) - magnitude_image: os.PathLike = attrs.field(metadata={"help_string": "magnitude image", "argstr": "--abs"}) + magnitude_image: os.PathLike = attrs.field( + metadata={"help_string": "magnitude image", "argstr": "--abs"} + ) phase_image: os.PathLike = attrs.field( metadata={ @@ -63,13 +65,18 @@ class PreludeSpec(pydra.specs.ShellSpec): } ) - input_mask: os.PathLike = attrs.field(metadata={"help_string": "input mask", "argstr": "--mask"}) + input_mask: os.PathLike = attrs.field( + metadata={"help_string": "input mask", "argstr": "--mask"} + ) output_unwrapped_phase_image: str = attrs.field( metadata={ "help_string": "output unwrapped phase image", "formatter": lambda field, complex_image, phase_image: "--out {}".format( - field or _output_filename_factory(complex_image, phase_image, "unwrapped_phase") + field + or _output_filename_factory( + complex_image, phase_image, "unwrapped_phase" + ) ), } ) @@ -78,7 +85,8 @@ class PreludeSpec(pydra.specs.ShellSpec): metadata={ "help_string": "output raw phase image", "formatter": lambda field, complex_image, phase_image: "--rawphase {}".format( - field or _output_filename_factory(complex_image, phase_image, "raw_phase") + field + or _output_filename_factory(complex_image, phase_image, "raw_phase") ), } ) @@ -102,7 +110,11 @@ class PreludeSpec(pydra.specs.ShellSpec): ) num_partitions: int = attrs.field( - default=8, metadata={"help_string": "number of phase partitions", "argstr": "--numphasesplit"} + default=8, + metadata={ + "help_string": "number of phase partitions", + "argstr": "--numphasesplit", + }, ) process_labels_in_2d: bool = attrs.field( @@ -130,17 +142,26 @@ class PreludeSpec(pydra.specs.ShellSpec): ) threshold: float = attrs.field( - default=0.0, metadata={"help_string": "intensity threshold for masking", "argstr": "--thresh"} + default=0.0, + metadata={ + "help_string": "intensity threshold for masking", + "argstr": "--thresh", + }, ) first_image_index: int = attrs.field( metadata={"help_string": "index of first image to process", "argstr": "--start"} ) - last_image_index: int = attrs.field(metadata={"help_string": "index of last image to process", "argstr": "--end"}) + last_image_index: int = attrs.field( + metadata={"help_string": "index of last image to process", "argstr": "--end"} + ) remove_ramps: bool = attrs.field( - metadata={"help_string": "remove phase ramps during unwrapping", "argstr": "--removeramps"} + metadata={ + "help_string": "remove phase ramps during unwrapping", + "argstr": "--removeramps", + } ) diff --git a/src/pydra/tasks/fsl/fugue/prepare_fieldmap.py b/pydra/tasks/fsl/v6_0/fugue/prepare_fieldmap.py similarity index 69% rename from src/pydra/tasks/fsl/fugue/prepare_fieldmap.py rename to pydra/tasks/fsl/v6_0/fugue/prepare_fieldmap.py index cc55806..6e6bb67 100644 --- a/src/pydra/tasks/fsl/fugue/prepare_fieldmap.py +++ b/pydra/tasks/fsl/v6_0/fugue/prepare_fieldmap.py @@ -25,12 +25,21 @@ class PrepareFieldmapSpec(ShellSpec): """Specifications for fsl_prepare_fieldmap.""" - scanner: str = field(default="SIEMENS", metadata={"help_string": "scanner (usually SIEMENS)", "argstr": ""}) + scanner: str = field( + default="SIEMENS", + metadata={"help_string": "scanner (usually SIEMENS)", "argstr": ""}, + ) - phase_image: PathLike = field(metadata={"help_string": "phase image", "mandatory": True, "argstr": ""}) + phase_image: PathLike = field( + metadata={"help_string": "phase image", "mandatory": True, "argstr": ""} + ) magnitude_image: PathLike = field( - metadata={"help_string": "magnitude (brain extracted) image", "mandatory": True, "argstr": ""} + metadata={ + "help_string": "magnitude (brain extracted) image", + "mandatory": True, + "argstr": "", + } ) output_image: str = field( @@ -49,7 +58,12 @@ class PrepareFieldmapSpec(ShellSpec): }, ) - no_check: bool = field(metadata={"help_string": "disable sanity checks for images", "argstr": "--nocheck"}) + no_check: bool = field( + metadata={ + "help_string": "disable sanity checks for images", + "argstr": "--nocheck", + } + ) class PrepareFieldmap(ShellCommandTask): diff --git a/src/pydra/tasks/fsl/fugue/sigloss.py b/pydra/tasks/fsl/v6_0/fugue/sigloss.py similarity index 72% rename from src/pydra/tasks/fsl/fugue/sigloss.py rename to pydra/tasks/fsl/v6_0/fugue/sigloss.py index 22b3abd..45ba20e 100644 --- a/src/pydra/tasks/fsl/fugue/sigloss.py +++ b/pydra/tasks/fsl/v6_0/fugue/sigloss.py @@ -32,14 +32,24 @@ class SigLossSpec(pydra.specs.ShellSpec): slice_direction: str = attrs.field( default="z", - metadata={"help_string": "slice direction", "argstr": "--slicedir", "allowed_values": {"x", "y", "z"}}, + metadata={ + "help_string": "slice direction", + "argstr": "--slicedir", + "allowed_values": {"x", "y", "z"}, + }, ) input_image: os.PathLike = attrs.field( - metadata={"help_string": "input B0-map image in rad/s", "mandatory": True, "argstr": "--in"} + metadata={ + "help_string": "input B0-map image in rad/s", + "mandatory": True, + "argstr": "--in", + } ) - input_mask: os.PathLike = attrs.field(metadata={"help_string": "input mask", "argstr": "--mask"}) + input_mask: os.PathLike = attrs.field( + metadata={"help_string": "input mask", "argstr": "--mask"} + ) output_image: str = attrs.field( metadata={ diff --git a/src/pydra/tasks/fsl/maths.py b/pydra/tasks/fsl/v6_0/maths.py similarity index 72% rename from src/pydra/tasks/fsl/maths.py rename to pydra/tasks/fsl/v6_0/maths.py index 9802701..1670cde 100644 --- a/src/pydra/tasks/fsl/maths.py +++ b/pydra/tasks/fsl/v6_0/maths.py @@ -40,11 +40,21 @@ class MathsSpec(ShellSpec): _datatypes = {"char", "short", "int", "float", "double", "input"} internal_datatype: str = field( - metadata={"help_string": "internal datatype", "argstr": "-dt", "position": 1, "allowed_values": _datatypes} + metadata={ + "help_string": "internal datatype", + "argstr": "-dt", + "position": 1, + "allowed_values": _datatypes, + } ) input_image: PathLike = field( - metadata={"help_string": "input image", "mandatory": True, "argstr": "", "position": 2} + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + "position": 2, + } ) output_image: str = field( @@ -57,7 +67,12 @@ class MathsSpec(ShellSpec): ) output_datatype: str = field( - metadata={"help_string": "output datatype", "argstr": "-odt", "position": -1, "allowed_values": _datatypes} + metadata={ + "help_string": "output datatype", + "argstr": "-odt", + "position": -1, + "allowed_values": _datatypes, + } ) @@ -74,7 +89,11 @@ class MulSpec(MathsSpec): """Specifications for fslmaths' mul.""" other_image: PathLike = field( - metadata={"help_string": "multiply input with other image", "mandatory": True, "argstr": "-mul"} + metadata={ + "help_string": "multiply input with other image", + "mandatory": True, + "argstr": "-mul", + } ) @@ -89,7 +108,11 @@ class ThresholdSpec(MathsSpec): """Specifications for fslmaths' threshold.""" threshold: float = field( - metadata={"help_string": "value for thresholding the image", "mandatory": True, "argstr": "-thr"} + metadata={ + "help_string": "value for thresholding the image", + "mandatory": True, + "argstr": "-thr", + } ) diff --git a/src/pydra/tasks/fsl/susan.py b/pydra/tasks/fsl/v6_0/susan.py similarity index 93% rename from src/pydra/tasks/fsl/susan.py rename to pydra/tasks/fsl/v6_0/susan.py index a0c5a77..d6a06dd 100644 --- a/src/pydra/tasks/fsl/susan.py +++ b/pydra/tasks/fsl/v6_0/susan.py @@ -89,7 +89,10 @@ class SUSANSpec(pydra.specs.ShellSpec): metadata={ "help_string": "find smoothing area from secondary images (up to 2)", "formatter": lambda field: ( - " ".join([f"{len(field or [])}"] + [f"{usan} {bt}" for usan, bt in field or []]) + " ".join( + [f"{len(field or [])}"] + + [f"{usan} {bt}" for usan, bt in field or []] + ) ), }, ) diff --git a/src/pydra/tasks/fsl/utils/__init__.py b/pydra/tasks/fsl/v6_0/utils/__init__.py similarity index 100% rename from src/pydra/tasks/fsl/utils/__init__.py rename to pydra/tasks/fsl/v6_0/utils/__init__.py diff --git a/src/pydra/tasks/fsl/utils/chfiletype.py b/pydra/tasks/fsl/v6_0/utils/chfiletype.py similarity index 81% rename from src/pydra/tasks/fsl/utils/chfiletype.py rename to pydra/tasks/fsl/v6_0/utils/chfiletype.py index f9024cd..dce65e9 100644 --- a/src/pydra/tasks/fsl/utils/chfiletype.py +++ b/pydra/tasks/fsl/v6_0/utils/chfiletype.py @@ -72,19 +72,28 @@ class ChFileTypeSpec(ShellSpec): } ) - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) - output_basename: str = field(metadata={"help_string": "output basename", "formatter": _get_output_basename}) + output_basename: str = field( + metadata={"help_string": "output basename", "formatter": _get_output_basename} + ) @define(slots=False, kw_only=True) class ChFileTypeOutSpec(ShellOutSpec): """Output specifications for fslchfiletype.""" - output_image: File = field(metadata={"help_string": "output image", "callable": _get_output_image}) + output_image: File = field( + metadata={"help_string": "output image", "callable": _get_output_image} + ) output_header: File = field( - metadata={"help_string": "output header for filetypes which support it", "callable": _get_output_header} + metadata={ + "help_string": "output header for filetypes which support it", + "callable": _get_output_header, + } ) diff --git a/src/pydra/tasks/fsl/utils/fft.py b/pydra/tasks/fsl/v6_0/utils/fft.py similarity index 70% rename from src/pydra/tasks/fsl/utils/fft.py rename to pydra/tasks/fsl/v6_0/utils/fft.py index 05863a9..b51c86c 100644 --- a/src/pydra/tasks/fsl/utils/fft.py +++ b/pydra/tasks/fsl/v6_0/utils/fft.py @@ -33,13 +33,21 @@ class FFTSpec(ShellSpec): """Specifications for fslfft.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) output_image: str = field( - metadata={"help_string": "output image", "argstr": "", "output_file_template": "{input_image}_fft"} + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image}_fft", + } ) - inverse: bool = field(metadata={"help_string": "compute the inverse FFT", "argstr": "-inv"}) + inverse: bool = field( + metadata={"help_string": "compute the inverse FFT", "argstr": "-inv"} + ) class FFT(ShellCommandTask): diff --git a/src/pydra/tasks/fsl/utils/info.py b/pydra/tasks/fsl/v6_0/utils/info.py similarity index 62% rename from src/pydra/tasks/fsl/utils/info.py rename to pydra/tasks/fsl/v6_0/utils/info.py index 00137bd..a142bb6 100644 --- a/src/pydra/tasks/fsl/utils/info.py +++ b/pydra/tasks/fsl/v6_0/utils/info.py @@ -19,7 +19,9 @@ class InfoSpec(ShellSpec): """Specifications for fslinfo.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) @define(kw_only=True) @@ -36,77 +38,99 @@ class InfoOutSpec(ShellOutSpec): dim1: int = field( metadata={ "help_string": "array size in 1st dimension", - "callable": lambda stdout: int(re.search(r"\sdim1\s*(.*)", stdout).group(1)), + "callable": lambda stdout: int( + re.search(r"\sdim1\s*(.*)", stdout).group(1) + ), } ) dim2: int = field( metadata={ "help_string": "array size in 2nd dimension", - "callable": lambda stdout: int(re.search(r"\sdim2\s*(.*)", stdout).group(1)), + "callable": lambda stdout: int( + re.search(r"\sdim2\s*(.*)", stdout).group(1) + ), } ) dim3: int = field( metadata={ "help_string": "array size in 3rd dimension", - "callable": lambda stdout: int(re.search(r"\sdim3\s*(.*)", stdout).group(1)), + "callable": lambda stdout: int( + re.search(r"\sdim3\s*(.*)", stdout).group(1) + ), } ) dim4: int = field( metadata={ "help_string": "array size in 4th dimension", - "callable": lambda stdout: int(re.search(r"\sdim4\s*(.*)", stdout).group(1)), + "callable": lambda stdout: int( + re.search(r"\sdim4\s*(.*)", stdout).group(1) + ), } ) datatype: int = field( metadata={ "help_string": "data type code", - "callable": lambda stdout: int(re.search(r"datatype\s*(.*)", stdout).group(1)), + "callable": lambda stdout: int( + re.search(r"datatype\s*(.*)", stdout).group(1) + ), } ) pixdim1: float = field( metadata={ "help_string": "pixel spacing in 1st dimension", - "callable": lambda stdout: float(re.search(r"pixdim1\s*(.*)", stdout).group(1)), + "callable": lambda stdout: float( + re.search(r"pixdim1\s*(.*)", stdout).group(1) + ), } ) pixdim2: float = field( metadata={ "help_string": "pixel spacing in 2nd dimension", - "callable": lambda stdout: float(re.search(r"pixdim2\s*(.*)", stdout).group(1)), + "callable": lambda stdout: float( + re.search(r"pixdim2\s*(.*)", stdout).group(1) + ), } ) pixdim3: float = field( metadata={ "help_string": "pixel spacing in 3rd dimension", - "callable": lambda stdout: float(re.search(r"pixdim3\s*(.*)", stdout).group(1)), + "callable": lambda stdout: float( + re.search(r"pixdim3\s*(.*)", stdout).group(1) + ), } ) pixdim4: float = field( metadata={ "help_string": "pixel spacing in 4th dimension", - "callable": lambda stdout: float(re.search(r"pixdim4\s*(.*)", stdout).group(1)), + "callable": lambda stdout: float( + re.search(r"pixdim4\s*(.*)", stdout).group(1) + ), } ) cal_max: float = field( metadata={ "help_string": "maximum display intensity", - "callable": lambda stdout: float(re.search(r"cal_max\s*(.*)", stdout).group(1)), + "callable": lambda stdout: float( + re.search(r"cal_max\s*(.*)", stdout).group(1) + ), } ) cal_min: float = field( metadata={ "help_string": "minimum display intensity", - "callable": lambda stdout: float(re.search(r"cal_min\s*(.*)", stdout).group(1)), + "callable": lambda stdout: float( + re.search(r"cal_min\s*(.*)", stdout).group(1) + ), } ) diff --git a/src/pydra/tasks/fsl/utils/interleave.py b/pydra/tasks/fsl/v6_0/utils/interleave.py similarity index 65% rename from src/pydra/tasks/fsl/utils/interleave.py rename to pydra/tasks/fsl/v6_0/utils/interleave.py index db067ff..14260ce 100644 --- a/src/pydra/tasks/fsl/utils/interleave.py +++ b/pydra/tasks/fsl/v6_0/utils/interleave.py @@ -36,15 +36,25 @@ class InterleaveSpec(ShellSpec): """Specifications for fslinterleave.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) - other_image: PathLike = field(metadata={"help_string": "other image", "mandatory": True, "argstr": ""}) + other_image: PathLike = field( + metadata={"help_string": "other image", "mandatory": True, "argstr": ""} + ) output_image: str = field( - metadata={"help_string": "output_image", "argstr": "", "output_file_template": "{input_image}_interleave"} + metadata={ + "help_string": "output_image", + "argstr": "", + "output_file_template": "{input_image}_interleave", + } ) - reverse: bool = field(metadata={"help_string": "reverse slice order", "argstr": "-i"}) + reverse: bool = field( + metadata={"help_string": "reverse slice order", "argstr": "-i"} + ) class Interleave(ShellCommandTask): diff --git a/src/pydra/tasks/fsl/utils/merge.py b/pydra/tasks/fsl/v6_0/utils/merge.py similarity index 81% rename from src/pydra/tasks/fsl/utils/merge.py rename to pydra/tasks/fsl/v6_0/utils/merge.py index eca13ee..13b4e28 100644 --- a/src/pydra/tasks/fsl/utils/merge.py +++ b/pydra/tasks/fsl/v6_0/utils/merge.py @@ -43,7 +43,13 @@ class MergeSpec(ShellSpec): } ) - output_image: str = field(metadata={"help_string": "output image", "argstr": "", "output_file_template": "merged"}) + output_image: str = field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "merged", + } + ) input_images: Iterable[PathLike] = field( metadata={ @@ -54,7 +60,10 @@ class MergeSpec(ShellSpec): ) repetition_time: float = field( - metadata={"help_string": "specify TR value in seconds (default is 1.0)", "argstr": ""} + metadata={ + "help_string": "specify TR value in seconds (default is 1.0)", + "argstr": "", + } ) diff --git a/src/pydra/tasks/fsl/utils/orient.py b/pydra/tasks/fsl/v6_0/utils/orient.py similarity index 60% rename from src/pydra/tasks/fsl/utils/orient.py rename to pydra/tasks/fsl/v6_0/utils/orient.py index 2c963c3..dc93a09 100644 --- a/src/pydra/tasks/fsl/utils/orient.py +++ b/pydra/tasks/fsl/v6_0/utils/orient.py @@ -46,26 +46,53 @@ class OrientSpec(ShellSpec): """Specifications for fslorient.""" - _xor = {"delete_orientation", "force_radiological", "force_neurological", "swap_orientation"} + _xor = { + "delete_orientation", + "force_radiological", + "force_neurological", + "swap_orientation", + } input_image: File = field( - metadata={"help_string": "input image", "mandatory": True, "argstr": "", "position": -1, "copyfile": True} + metadata={ + "help_string": "input image", + "mandatory": True, + "argstr": "", + "position": -1, + "copyfile": True, + } ) delete_orientation: bool = field( - metadata={"help_string": "delete orientation", "argstr": "-deleteorient", "xor": _xor} + metadata={ + "help_string": "delete orientation", + "argstr": "-deleteorient", + "xor": _xor, + } ) force_radiological: bool = field( - metadata={"help_string": "force orientation to radiological", "argstr": "-forceradiological", "xor": _xor} + metadata={ + "help_string": "force orientation to radiological", + "argstr": "-forceradiological", + "xor": _xor, + } ) force_neurological: bool = field( - metadata={"help_string": "force orientation to neurological", "argstr": "-forceneurological", "xor": _xor} + metadata={ + "help_string": "force orientation to neurological", + "argstr": "-forceneurological", + "xor": _xor, + } ) swap_orientation: bool = field( - metadata={"help_string": "swap between radiological and neurological", "argstr": "-swaporient", "xor": _xor} + metadata={ + "help_string": "swap between radiological and neurological", + "argstr": "-swaporient", + "xor": _xor, + } ) @@ -73,7 +100,12 @@ class OrientSpec(ShellSpec): class OrientOutSpec(ShellOutSpec): """Output specifications for fslorient.""" - output_image: File = field(metadata={"help_string": "output image", "output_file_template": "{input_image}"}) + output_image: File = field( + metadata={ + "help_string": "output image", + "output_file_template": "{input_image}", + } + ) class Orient(ShellCommandTask): diff --git a/src/pydra/tasks/fsl/utils/reorient2std.py b/pydra/tasks/fsl/v6_0/utils/reorient2std.py similarity index 100% rename from src/pydra/tasks/fsl/utils/reorient2std.py rename to pydra/tasks/fsl/v6_0/utils/reorient2std.py diff --git a/pydra/tasks/fsl/v6_0/utils/roi.py b/pydra/tasks/fsl/v6_0/utils/roi.py new file mode 100644 index 0000000..72cd5f7 --- /dev/null +++ b/pydra/tasks/fsl/v6_0/utils/roi.py @@ -0,0 +1,122 @@ +""" +ROI (Region-Of-Interest) +======================== + +Manual cropping to a region-of-interest for structural brain images. + +Examples +-------- + +Extract a 16-voxel cube starting at position (10, 20, 30): + +>>> task = ROI( +... input_image="image.nii", +... x_min=10, +... x_size=16, +... y_min=20, +... y_size=16, +... z_min=30, +... z_size=16, +... ) +>>> task.cmdline # doctest: +ELLIPSIS +'fslroi image.nii ...image_roi.nii 10 16 20 16 30 16 ...' + +Extract a temporal window starting at 5 onwards: + +>>> task = ROI(input_image="input.nii", output_image="output.nii", t_min=5) +>>> task.cmdline +'fslroi input.nii output.nii 5 -1' +""" + +__all__ = ["ROI"] + +from os import PathLike + +from attrs import define, field +from pydra.engine.specs import ShellSpec, SpecInfo +from pydra.engine.task import ShellCommandTask + + +@define(kw_only=True) +class ROISpec(ShellSpec): + """Specifications for fslroi.""" + + _requires = {"x_min", "y_min", "z_min"} + + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) + + output_image: str = field( + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image}_roi", + } + ) + + x_min: int = field( + metadata={ + "help_string": "start of ROI in x (0-based indexing)", + "argstr": "", + "requires": _requires, + } + ) + + x_size: int = field( + metadata={ + "help_string": "size of ROI in x (-1 for maximum)", + "argstr": "", + "requires": {"x_min"}, + } + ) + + y_min: int = field( + metadata={ + "help_string": "start of ROI in y (0-based indexing)", + "argstr": "", + "requires": _requires, + } + ) + + y_size: int = field( + metadata={ + "help_string": "size of ROI in y (-1 for maximum)", + "argstr": "", + "requires": {"y_min"}, + } + ) + + z_min: int = field( + metadata={ + "help_string": "start of ROI in z (0-based indexing)", + "argstr": "", + "requires": _requires, + } + ) + + z_size: int = field( + metadata={ + "help_string": "size of ROI in z (-1 for maximum)", + "argstr": "", + "requires": {"z_min"}, + } + ) + + t_min: int = field( + default=0, + metadata={"help_string": "start of ROI in t (0-based indexing)", "argstr": ""}, + ) + + t_size: int = field( + default=-1, + metadata={"help_string": "size of ROI in t (-1 for maximum)", "argstr": ""}, + ) + + +class ROI(ShellCommandTask): + """Task definition for fslroi.""" + + executable = "fslroi" + + input_spec = SpecInfo(name="Input", bases=(ROISpec,)) diff --git a/src/pydra/tasks/fsl/utils/selectvols.py b/pydra/tasks/fsl/v6_0/utils/selectvols.py similarity index 76% rename from src/pydra/tasks/fsl/utils/selectvols.py rename to pydra/tasks/fsl/v6_0/utils/selectvols.py index 34e95db..972d04a 100644 --- a/src/pydra/tasks/fsl/utils/selectvols.py +++ b/pydra/tasks/fsl/v6_0/utils/selectvols.py @@ -48,10 +48,16 @@ class SelectVolsSpec(ShellSpec): """Specifications for fslselectvols.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"} + ) output_image: str = field( - metadata={"help_string": "output image", "argstr": "--out", "output_file_template": "{input_image}_selectvols"} + metadata={ + "help_string": "output image", + "argstr": "--out", + "output_file_template": "{input_image}_selectvols", + } ) volumes: Union[PathLike, Iterable[int]] = field( @@ -65,11 +71,19 @@ class SelectVolsSpec(ShellSpec): ) calculate_mean: bool = field( - metadata={"help_string": "calculate mean", "argstr": "-m", "xor": {"calculate_variance"}} + metadata={ + "help_string": "calculate mean", + "argstr": "-m", + "xor": {"calculate_variance"}, + } ) calculate_variance: bool = field( - metadata={"help_string": "calculate variance", "argstr": "-v", "xor": {"calculate_mean"}} + metadata={ + "help_string": "calculate variance", + "argstr": "-v", + "xor": {"calculate_mean"}, + } ) diff --git a/src/pydra/tasks/fsl/utils/smoothfill.py b/pydra/tasks/fsl/v6_0/utils/smoothfill.py similarity index 72% rename from src/pydra/tasks/fsl/utils/smoothfill.py rename to pydra/tasks/fsl/v6_0/utils/smoothfill.py index 008494b..3a0eb66 100644 --- a/src/pydra/tasks/fsl/utils/smoothfill.py +++ b/pydra/tasks/fsl/v6_0/utils/smoothfill.py @@ -23,7 +23,9 @@ class SmoothFillSpec(ShellSpec): """Specifications for fslsmoothfill.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": "--in"} + ) output_image: str = field( metadata={ @@ -33,9 +35,13 @@ class SmoothFillSpec(ShellSpec): } ) - input_mask: PathLike = field(metadata={"help_string": "input mask", "argstr": "--mask"}) + input_mask: PathLike = field( + metadata={"help_string": "input mask", "argstr": "--mask"} + ) - num_iterations: int = field(metadata={"help_string": "number of iterations", "argstr": "--niter"}) + num_iterations: int = field( + metadata={"help_string": "number of iterations", "argstr": "--niter"} + ) class SmoothFill(ShellCommandTask): diff --git a/src/pydra/tasks/fsl/utils/split.py b/pydra/tasks/fsl/v6_0/utils/split.py similarity index 71% rename from src/pydra/tasks/fsl/utils/split.py rename to pydra/tasks/fsl/v6_0/utils/split.py index 3900d5d..01e0d23 100644 --- a/src/pydra/tasks/fsl/utils/split.py +++ b/pydra/tasks/fsl/v6_0/utils/split.py @@ -37,13 +37,21 @@ def _get_output_images(output_basename, input_image): class SplitSpec(ShellSpec): """Specifications for fslsplit.""" - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) - output_basename: str = field(metadata={"help_string": "output basename", "formatter": _get_output_basename}) + output_basename: str = field( + metadata={"help_string": "output basename", "formatter": _get_output_basename} + ) direction: str = field( default="t", - metadata={"help_string": "split direction", "argstr": "-{direction}", "allowed_values": {"x", "y", "z", "t"}}, + metadata={ + "help_string": "split direction", + "argstr": "-{direction}", + "allowed_values": {"x", "y", "z", "t"}, + }, ) @@ -51,7 +59,9 @@ class SplitSpec(ShellSpec): class SplitOutSpec(ShellOutSpec): """Output specifications for fslsplit.""" - output_images: MultiOutputFile = field(metadata={"help_string": "output images", "callable": _get_output_images}) + output_images: MultiOutputFile = field( + metadata={"help_string": "output images", "callable": _get_output_images} + ) class Split(ShellCommandTask): @@ -70,7 +80,11 @@ class SliceSpec(SplitSpec): direction: str = field( default="z", - metadata={"help_string": "split direction (z)", "argstr": "-{direction}", "allowed_values": {"z"}}, + metadata={ + "help_string": "split direction (z)", + "argstr": "-{direction}", + "allowed_values": {"z"}, + }, ) diff --git a/src/pydra/tasks/fsl/utils/swapdim.py b/pydra/tasks/fsl/v6_0/utils/swapdim.py similarity index 58% rename from src/pydra/tasks/fsl/utils/swapdim.py rename to pydra/tasks/fsl/v6_0/utils/swapdim.py index 49887e9..4aa0607 100644 --- a/src/pydra/tasks/fsl/utils/swapdim.py +++ b/pydra/tasks/fsl/v6_0/utils/swapdim.py @@ -40,22 +40,43 @@ class SwapDimSpec(ShellSpec): ALLOWED_AXES = {"x", "-x", "y", "-y", "z", "-z", "LR", "RL", "AP", "PA", "SI", "IS"} - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) + input_image: PathLike = field( + metadata={"help_string": "input image", "mandatory": True, "argstr": ""} + ) new_x: str = field( - metadata={"help_string": "new x-axis", "mandatory": True, "argstr": "", "allowed_values": ALLOWED_AXES} + metadata={ + "help_string": "new x-axis", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_AXES, + } ) new_y: str = field( - metadata={"help_string": "new y-axis", "mandatory": True, "argstr": "", "allowed_values": ALLOWED_AXES} + metadata={ + "help_string": "new y-axis", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_AXES, + } ) new_z: str = field( - metadata={"help_string": "new z-axis", "mandatory": True, "argstr": "", "allowed_values": ALLOWED_AXES} + metadata={ + "help_string": "new z-axis", + "mandatory": True, + "argstr": "", + "allowed_values": ALLOWED_AXES, + } ) output_image: str = field( - metadata={"help_string": "output image", "argstr": "", "output_file_template": "{input_image}_swapdim"} + metadata={ + "help_string": "output image", + "argstr": "", + "output_file_template": "{input_image}_swapdim", + } ) diff --git a/pyproject.toml b/pyproject.toml index fd65464..85c326b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,11 +4,17 @@ build-backend = "hatchling.build" [project] name = "pydra-fsl" -version = "0.0.22" -description = "Pydra tasks for FSL" -readme = "README.md" -requires-python = ">=3.7" -license = "Apache-2.0" +description = "Pydra tasks package for fsl" +readme = "README.rst" +requires-python = ">=3.8" +dependencies = [ + "pydra >=0.22", + "fileformats >=0.8.3", + "fileformats-datascience >=0.1", + "fileformats-medimage >=0.4.1", + "fileformats-medimage-fsl", +] +license = { file = "LICENSE" } keywords = ["pydra", "neuroimaging", "fsl"] authors = [ { name = "Nipype developers", email = "neuroimaging@python.org" }, diff --git a/src/pydra/tasks/fsl/latest.py b/src/pydra/tasks/fsl/latest.py deleted file mode 100644 index f41e057..0000000 --- a/src/pydra/tasks/fsl/latest.py +++ /dev/null @@ -1,3 +0,0 @@ -PACKAGE_VERSION = "v1" - -from .v1 import * # noqa diff --git a/src/pydra/tasks/fsl/utils/roi.py b/src/pydra/tasks/fsl/utils/roi.py deleted file mode 100644 index de223ec..0000000 --- a/src/pydra/tasks/fsl/utils/roi.py +++ /dev/null @@ -1,86 +0,0 @@ -""" -ROI (Region-Of-Interest) -======================== - -Manual cropping to a region-of-interest for structural brain images. - -Examples --------- - -Extract a 16-voxel cube starting at position (10, 20, 30): - ->>> task = ROI( -... input_image="image.nii", -... x_min=10, -... x_size=16, -... y_min=20, -... y_size=16, -... z_min=30, -... z_size=16, -... ) ->>> task.cmdline # doctest: +ELLIPSIS -'fslroi image.nii ...image_roi.nii 10 16 20 16 30 16 ...' - -Extract a temporal window starting at 5 onwards: - ->>> task = ROI(input_image="input.nii", output_image="output.nii", t_min=5) ->>> task.cmdline -'fslroi input.nii output.nii 5 -1' -""" - -__all__ = ["ROI"] - -from os import PathLike - -from attrs import define, field -from pydra.engine.specs import ShellSpec, SpecInfo -from pydra.engine.task import ShellCommandTask - - -@define(kw_only=True) -class ROISpec(ShellSpec): - """Specifications for fslroi.""" - - _requires = {"x_min", "y_min", "z_min"} - - input_image: PathLike = field(metadata={"help_string": "input image", "mandatory": True, "argstr": ""}) - - output_image: str = field( - metadata={"help_string": "output image", "argstr": "", "output_file_template": "{input_image}_roi"} - ) - - x_min: int = field( - metadata={"help_string": "start of ROI in x (0-based indexing)", "argstr": "", "requires": _requires} - ) - - x_size: int = field( - metadata={"help_string": "size of ROI in x (-1 for maximum)", "argstr": "", "requires": {"x_min"}} - ) - - y_min: int = field( - metadata={"help_string": "start of ROI in y (0-based indexing)", "argstr": "", "requires": _requires} - ) - - y_size: int = field( - metadata={"help_string": "size of ROI in y (-1 for maximum)", "argstr": "", "requires": {"y_min"}} - ) - - z_min: int = field( - metadata={"help_string": "start of ROI in z (0-based indexing)", "argstr": "", "requires": _requires} - ) - - z_size: int = field( - metadata={"help_string": "size of ROI in z (-1 for maximum)", "argstr": "", "requires": {"z_min"}} - ) - - t_min: int = field(default=0, metadata={"help_string": "start of ROI in t (0-based indexing)", "argstr": ""}) - - t_size: int = field(default=-1, metadata={"help_string": "size of ROI in t (-1 for maximum)", "argstr": ""}) - - -class ROI(ShellCommandTask): - """Task definition for fslroi.""" - - executable = "fslroi" - - input_spec = SpecInfo(name="Input", bases=(ROISpec,)) diff --git a/src/pydra/tasks/fsl/v1_0/__init__.py b/src/pydra/tasks/fsl/v1_0/__init__.py deleted file mode 100644 index e69de29..0000000 From 29e28aa5f6d965a1fdc1fd063600ee93b9d61b6b Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 25 Mar 2024 01:58:01 +0000 Subject: [PATCH 220/224] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 3cd7ac8..5925b7e 100644 --- a/.gitignore +++ b/.gitignore @@ -181,4 +181,4 @@ cython_debug/ /related-packages/fileformats/fileformats/medimage_fsl/_version.py /related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py /pydra/tasks/fsl/auto -/pydra/tasks/fsl/_version.py \ No newline at end of file +/pydra/tasks/fsl/_version.py From 1b20f47b3af646d88f1b300b3dcdebb2145ad921 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 13:34:14 +1100 Subject: [PATCH 221/224] deleted hatch.toml --- hatch.toml | 40 ---------------------------------------- 1 file changed, 40 deletions(-) delete mode 100644 hatch.toml diff --git a/hatch.toml b/hatch.toml deleted file mode 100644 index 961f997..0000000 --- a/hatch.toml +++ /dev/null @@ -1,40 +0,0 @@ -[build.targets.wheel] -only-include = ["src/pydra/tasks/fsl"] -sources = ["src"] - -[envs.default] -dependencies = ["pytest"] -[envs.default.scripts] -test = "pytest {args}" - -[[envs.all.matrix]] -python = ["3.7", "3.8", "3.9", "3.10", "3.11"] - -[envs.lint] -detached = true -dependencies = [ - "black", - "isort", - "tomli", -] -[envs.lint.scripts] -all = [ - "black --check --diff {args:src}", - "isort --check --diff {args:src}", -] -fix = [ - "black --quiet {args:src}", - "isort --quiet {args:src}", -] - -[envs.docs] -template = "docs" -dependencies = [ - "pydata-sphinx-theme >=0.13", - "sphinx <7", - "sphinx-autobuild", - "sphinx-pyproject", -] -[envs.docs.scripts] -build = "sphinx-build docs docs/_build/html -b {args:html}" -serve = "sphinx-autobuild docs docs/_build/html {args}" From f3c24e0349c37d239ba3728e0448e5e92d5c2a68 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 13:41:25 +1100 Subject: [PATCH 222/224] removed duplicate _version.py ignore in gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index 5925b7e..942699c 100644 --- a/.gitignore +++ b/.gitignore @@ -181,4 +181,3 @@ cython_debug/ /related-packages/fileformats/fileformats/medimage_fsl/_version.py /related-packages/fileformats-extras/fileformats/extras/medimage_fsl/_version.py /pydra/tasks/fsl/auto -/pydra/tasks/fsl/_version.py From 3ee213674d18f2335199918e54b26c29cea54211 Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 13:58:23 +1100 Subject: [PATCH 223/224] updated NOTICE file --- NOTICE | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/NOTICE b/NOTICE index aee9927..32f4baf 100644 --- a/NOTICE +++ b/NOTICE @@ -1,6 +1,13 @@ -Pydra-fsl +Pydra-FSL Copyright 2024 Pydra Development Team -The bases for the task interfaces defined in this package were semi-automatically converted -from Nipype interfaces (https://github.com/nipy/nipype) using the Nipype2Pydra tool -(https://github.com/nipype/nipype2pydra). +Portions of this software were developed by the ARAMIS Lab for the Clinica project. +Initial code for the FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, FixScaleSkew, Img2ImgCoord, +Img2StdCoord, InvertXFM, Std2ImgCoord, FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, +InvWarp FUGUE, Prelude, PrepareFieldmap, SigLoss SUSAN FFT, ROI, ChFileType, Info, +Interleave, Merge, Orient, Reorient2Std, SelectVols, Slice, SmoothFill, Split, SwapDim, +tasks were copied from . + +The basis for the remaining task interfaces defined in this package were semi-automatically +converted from Nipype interfaces (https://github.com/nipy/nipype) using the Nipype2Pydra +tool (https://github.com/nipype/nipype2pydra). From 170b92d57426445301b351e2422fd300744a7eef Mon Sep 17 00:00:00 2001 From: Tom Close Date: Mon, 25 Mar 2024 14:01:29 +1100 Subject: [PATCH 224/224] updated notice file to include aramis lab --- NOTICE | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NOTICE b/NOTICE index 32f4baf..7424f8b 100644 --- a/NOTICE +++ b/NOTICE @@ -6,7 +6,7 @@ Initial code for the FLIRT, ApplyXFM, ConcatXFM, ConvertXFM, FixScaleSkew, Img2I Img2StdCoord, InvertXFM, Std2ImgCoord, FNIRT, ApplyWarp, ConvertWarp, FNIRTFileUtils, InvWarp FUGUE, Prelude, PrepareFieldmap, SigLoss SUSAN FFT, ROI, ChFileType, Info, Interleave, Merge, Orient, Reorient2Std, SelectVols, Slice, SmoothFill, Split, SwapDim, -tasks were copied from . +tasks were copied from . The basis for the remaining task interfaces defined in this package were semi-automatically converted from Nipype interfaces (https://github.com/nipy/nipype) using the Nipype2Pydra