@@ -172,6 +172,7 @@ def __init__(
172172 metadata_path = None ,
173173 metadata_translation_script = None ,
174174 additional_arguments = {},
175+ dcm2niix_options = "" ,
175176 file_format = "%p_%i_%t_%s" ,
176177 silent = False ,
177178 tempdir_location = None ,
@@ -364,6 +365,42 @@ def __init__(
364365 load_spreadsheet_data ["blood_json" ]
365366 )
366367
368+ # we default to these options, a user may supply their own combination, this will allow full customization of all
369+ # but the file arguments for dcm2niix
370+ if dcm2niix_options :
371+ # Filter out -f flag and its value from custom options since file format is handled separately
372+ options_list = dcm2niix_options .split ()
373+ filtered_options = []
374+ i = 0
375+ while i < len (options_list ):
376+ if options_list [i ] == "-f" and i + 1 < len (options_list ):
377+ # Skip -f and its value
378+ i += 2
379+ else :
380+ filtered_options .append (options_list [i ])
381+ i += 1
382+ self .dcm2niix_options = " " .join (filtered_options )
383+ else :
384+ # Check for dcm2niix options in config file and environment variable
385+ config_options = helper_functions .check_pet2bids_config (
386+ "PET2BIDS_DCM2NIIX_OPTIONS"
387+ )
388+ env_options = environ .get ("PET2BIDS_DCM2NIIX_OPTIONS" )
389+
390+ # Priority: command line > environment variable > config file > default
391+ if env_options :
392+ self .dcm2niix_options = env_options
393+ logger .info (
394+ f"Using dcm2niix options from environment variable: { env_options } "
395+ )
396+ elif config_options :
397+ self .dcm2niix_options = config_options
398+ logger .info (
399+ f"Using dcm2niix options from config file: { config_options } "
400+ )
401+ else :
402+ self .dcm2niix_options = "-b y -w 1 -z y"
403+ logger .debug ("Using default dcm2niix options: -b y -w 1 -z y" )
367404 self .file_format = file_format
368405 # we may want to include additional information to the sidecar, tsv, or json files generated after conversion
369406 # this variable stores the mapping between output files and a single dicom header used to generate those files
@@ -480,7 +517,7 @@ def run_dcm2niix(self):
480517 self .tempdir_location = tempdir_pathlike
481518 # people use screwy paths, we do this before running dcm2niix to account for that
482519 image_folder = helper_functions .sanitize_bad_path (self .image_folder )
483- cmd = f"{ self .dcm2niix_path } -b y -w 1 -z y { file_format_args } -o { tempdir_pathlike } { image_folder } "
520+ cmd = f"{ self .dcm2niix_path } { self . dcm2niix_options } { file_format_args } -o { tempdir_pathlike } { image_folder } "
484521 convert = subprocess .run (cmd , shell = True , capture_output = True )
485522 self .telemetry_data ["dcm2niix" ] = {
486523 "returncode" : convert .returncode ,
@@ -674,10 +711,19 @@ def run_dcm2niix(self):
674711 if re .search (
675712 r"\d+.\d+" , sidecar_json .get ("ConvolutionKernel" )
676713 ):
677- recon_filter_size = re .search (
678- r"\d+.\d*" , sidecar_json .get ("ConvolutionKernel" )
679- )[0 ]
680- recon_filter_size = float (recon_filter_size )
714+ try :
715+ recon_filter_size = re .search (
716+ r"\d+.\d*" ,
717+ sidecar_json .get ("ConvolutionKernel" ),
718+ )[0 ]
719+ recon_filter_size = float (recon_filter_size )
720+ except ValueError :
721+ # If float conversion fails, try splitting and take first part
722+ match_str = re .search (
723+ r"\d+.\d*" ,
724+ sidecar_json .get ("ConvolutionKernel" ),
725+ )[0 ]
726+ recon_filter_size = float (match_str .split ()[0 ])
681727 sidecar_json .update (
682728 {"ReconFilterSize" : float (recon_filter_size )}
683729 )
@@ -1037,9 +1083,13 @@ def load_spread_sheet_data(self):
10371083
10381084 example usage:
10391085
1040- dcm2niix4pet folder_with_pet_dicoms/ --destinationp -path sub-ValidBidSSubject/pet # the simplest conversion
1086+ dcm2niix4pet folder_with_pet_dicoms/ --destination -path sub-ValidBidSSubject/pet # the simplest conversion
10411087 dcm2niix4pet folder_with_pet_dicoms/ --destination-path sub-ValidBidsSubject/pet --metadata-path metadata.xlsx \
10421088 # use with an input spreadsheet
1089+ dcm2niix4pet folder_with_pet_dicoms/ --destination-path sub-ValidBidsSubject/pet --dcm2niix-options -v y -w 1 -z y \
1090+ # use with custom dcm2niix options
1091+ dcm2niix4pet --set-dcm2niix-options '-v y -w 1 -z y' \
1092+ # set default dcm2niix options in config file
10431093
10441094"""
10451095)
@@ -1135,6 +1185,13 @@ def cli():
11351185 f"DCM2NIIX_PATH" ,
11361186 type = pathlib .Path ,
11371187 )
1188+ parser .add_argument (
1189+ "--set-dcm2niix-options" ,
1190+ help = "Provide dcm2niix options to be used as defaults, writes to config "
1191+ f"file { Path .home ()} /.pet2bidsconfig under the variable "
1192+ f"PET2BIDS_DCM2NIIX_OPTIONS. Example: --set-dcm2niix-options '-v y -w 1 -z y'" ,
1193+ type = str ,
1194+ )
11381195 parser .add_argument (
11391196 "--set-default-metadata-json" ,
11401197 help = "Provide a path to a default metadata file json file."
@@ -1190,6 +1247,15 @@ def cli():
11901247 help = "Accept any NifTi produced by dcm2niix even if it contains errors. This flag should only be used for "
11911248 "batch processing and only if you're performing robust QC after the fact." ,
11921249 )
1250+ parser .add_argument (
1251+ "--dcm2niix-options" ,
1252+ nargs = "*" ,
1253+ default = [],
1254+ help = "Additional dcm2niix options to pass through. Use the same format as dcm2niix command line. "
1255+ "Note: -f flag and its value will be filtered out as file format is handled separately. "
1256+ "You can also set default options using --set-dcm2niix-options or the PET2BIDS_DCM2NIIX_OPTIONS environment variable. "
1257+ "Example: --dcm2niix-options -v y -w 1 -z y" ,
1258+ )
11931259 return parser
11941260
11951261
@@ -1336,6 +1402,12 @@ def main():
13361402 helper_functions .modify_config_file ("DCM2NIIX_PATH" , cli_args .set_dcm2niix_path )
13371403 sys .exit (0 )
13381404
1405+ if cli_args .set_dcm2niix_options :
1406+ helper_functions .modify_config_file (
1407+ "PET2BIDS_DCM2NIIX_OPTIONS" , cli_args .set_dcm2niix_options
1408+ )
1409+ sys .exit (0 )
1410+
13391411 if cli_args .set_default_metadata_json :
13401412 helper_functions .modify_config_file (
13411413 "DEFAULT_METADATA_JSON" , cli_args .set_default_metadata_json
@@ -1354,6 +1426,9 @@ def main():
13541426 cli_args .translation_script_path
13551427 ),
13561428 additional_arguments = cli_args .kwargs ,
1429+ dcm2niix_options = (
1430+ " " .join (cli_args .dcm2niix_options ) if cli_args .dcm2niix_options else ""
1431+ ),
13571432 tempdir_location = cli_args .tempdir ,
13581433 silent = cli_args .silent ,
13591434 ezbids = cli_args .ezbids ,
0 commit comments