def get_parser(): parser = SCTArgumentParser( description="Utility functions for label images." ) req_group = parser.add_argument_group("\nREQUIRED I/O") req_group.add_argument( '-i', metavar=Metavar.file, required=True, help="Input image (Required) Example: t2_labels.nii.gz" ) io_group = parser.add_argument_group("\nOPTIONAL I/O") io_group.add_argument( '-o', metavar=Metavar.file, default='labels.nii.gz', help=("Output image. Note: Only some label utilities create an output image. Example: t2_labels.nii.gz") ) io_group.add_argument( '-ilabel', metavar=Metavar.file, help="File that contain labels that you want to correct. It is possible to add new points with this option. " "Use with -create-viewer. Example: t2_labels_auto.nii.gz" ) functions = parser.add_argument_group("\nLABEL FUNCTIONS") func_group = functions.add_mutually_exclusive_group(required=True) func_group.add_argument( '-add', metavar=Metavar.int, type=int, help="Add value to all labels. Value can be negative." ) func_group.add_argument( '-create', metavar=Metavar.list, type=list_type(':', Coordinate), help="Create labels in a new image. List labels as: x1,y1,z1,value1:x2,y2,z2,value2. " "Example: 12,34,32,1:12,35,33,2" ) func_group.add_argument( '-create-add', metavar=Metavar.list, type=list_type(':', Coordinate), help="Same as '-create', but add labels to the input image instead of creating a new image. " "Example: 12,34,32,1:12,35,33,2" ) func_group.add_argument( '-create-seg', metavar=Metavar.list, type=list_type(':', list_type(',', int)), help="R|Create labels on a cord segmentation (or centerline) image defined by '-i'. Each label should be " "specified using the form 'v1,v2' where 'v1' is value of the slice index along the inferior-superior " "axis, and 'v2' is the value of the label. Separate each label with ':'. \n" "Example: '-create-seg 5,1:14,2:23,3' adds three labels at the axial slices 5, 14, and 23 (starting from " "the most inferior slice)." ) func_group.add_argument( '-create-seg-mid', metavar=Metavar.int, type=int, help="R|Similar to '-create-seg'. This option takes a single label value, and will automatically select the " "mid-point slice in the inferior-superior direction (so there is no need for a slice index).\n" "This is useful for when you have centered the field of view of your data at a specific location. " "For example, if you already know that the C2-C3 disc is centered in the I-S direction, then " "you can enter '-create-seg-mid 3' for that label. This saves you the trouble of having to manually " "specify a slice index using '-create-seg'." ) func_group.add_argument( '-create-viewer', metavar=Metavar.list, help="Manually label from a GUI a list of labels IDs. Provide a comma-separated list " "containing individual values and/or intervals. Example: '-create-viewer 1:4,6,8' " "will allow you to add labels [1,2,3,4,6,8] using the GUI." ) func_group.add_argument( '-cubic-to-point', action="store_true", help="Compute the center-of-mass for each label value." ) func_group.add_argument( '-disc', metavar=Metavar.file, help="Create an image with regions labelized depending on values from reference" ) func_group.add_argument( '-display', action="store_true", help="Display all labels (i.e. non-zero values)." ) func_group.add_argument( '-increment', action="store_true", help="Takes all non-zero values, sort them along the inverse z direction, and attributes the values " "1, 2, 3, etc." ) func_group.add_argument( '-vert-body', metavar=Metavar.list, type=list_type(',', int), help="R|From vertebral labeling, create points that are centered at the mid-vertebral levels. Separate " "desired levels with ','. Example: 3,8\n" "To get all levels, enter 0." ) func_group.add_argument( '-vert-continuous', action="store_true", help="Convert discrete vertebral labeling to continuous vertebral labeling.", ) func_group.add_argument( '-MSE', metavar=Metavar.file, help="Compute Mean Square Error between labels from input and reference image. Specify reference image here." ) func_group.add_argument( '-remove-reference', metavar=Metavar.file, help="Remove labels from input image (-i) that are not in reference image (specified here)." ) func_group.add_argument( '-remove-sym', metavar=Metavar.file, help="Remove labels from input image (-i) and reference image (specified here) that don't match. You must " "provide two output names separated by ','." ) func_group.add_argument( '-remove', metavar=Metavar.list, type=list_type(',', int), help="Remove labels of specific value (specified here) from reference image." ) func_group.add_argument( '-keep', metavar=Metavar.list, type=list_type(',', int), help="Keep labels of specific value (specified here) from reference image." ) optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument( "-h", "--help", action="help", help="Show this help message and exit." ) optional.add_argument( '-msg', metavar=Metavar.str, help="Display a message to explain the labeling task. Use with -create-viewer" ) optional.add_argument( '-v', metavar=Metavar.int, type=int, choices=[0, 1, 2], default=1, # Values [0, 1, 2] map to logging levels [WARNING, INFO, DEBUG], but are also used as "if verbose == #" in API help="Verbosity. 0: Display only errors/warnings, 1: Errors/warnings + info messages, 2: Debug mode" ) optional.add_argument( '-qc', metavar=Metavar.folder, action=ActionCreateFolder, help="The path where the quality control generated content will be saved." ) optional.add_argument( '-qc-dataset', metavar=Metavar.str, help="If provided, this string will be mentioned in the QC report as the dataset the process was run on." ) optional.add_argument( '-qc-subject', metavar=Metavar.str, help="If provided, this string will be mentioned in the QC report as the subject the process was run on." ) return parser
def get_parser(): param_default = Param() # Read .txt files referencing the labels (for extended usage description) file_label = os.path.join(param_default.path_label, param_default.file_info_label) sct.check_file_exist(file_label, 0) default_info_label = open(file_label, 'r') label_references = default_info_label.read() default_info_label.close() description = (f"This program extracts metrics (e.g., DTI or MTR) within labels. Labels could be a single file or " f"a folder generated with 'sct_warp_template' and containing multiple label files and a label " f"description file (info_label.txt). The labels should be in the same space coordinates as the " f"input image.\n" f"\n" f"To list white matter atlas labels: {os.path.basename(__file__)} -f " f"{os.path.join(path_sct, 'data', 'atlas')}\n" f"\n" f"To compute FA within labels 0, 2 and 3 within vertebral levels C2 to C7 using binary method: " f"{os.path.basename(__file__)} -i dti_FA.nii.gz -f label/atlas -l 0,2,3 -v 2:7 -m bin\n") if label_references != '': description += (f"\nTo compute average MTR in a region defined by a single label file (could be binary or 0-1 " f"weighted mask) between slices 1 and 4: {os.path.basename(__file__)} -i mtr.nii.gz -f " f"my_mask.nii.gz -z 1:4 -m wa\n" f"List of labels in {file_label}:\n" f"--------------------------------------------------------------------------------------\n" f"{label_references}\n" f"--------------------------------------------------------------------------------------\n") parser = argparse.ArgumentParser( description=description, formatter_class=SmartFormatter, add_help=None, prog=os.path.basename(__file__).strip(".py") ) mandatory = parser.add_argument_group("\nMANDATORY ARGUMENTS") mandatory.add_argument( '-i', metavar=Metavar.file, required=True, help="Image file to extract metrics from. Example: FA.nii.gz" ) optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument( "-h", "--help", action="help", help="Show this help message and exit." ) optional.add_argument( '-f', metavar=Metavar.folder, default=os.path.join("label", "atlas"), help=(f"Single label file, or folder that contains WM tract labels." f"Example: {os.path.join(path_sct, 'data', 'atlas')}") ) optional.add_argument( '-l', metavar=Metavar.str, default='', help="Label IDs to extract the metric from. Default = all labels. Separate labels with ','. To select a group " "of consecutive labels use ':'. Example: 1:3 is equivalent to 1,2,3. Maximum Likelihood (or MAP) is " "computed using all tracts, but only values of the selected tracts are reported." ) optional.add_argument( '-method', choices=['ml', 'map', 'wa', 'bin', 'max'], default=param_default.method, help="R|Method to extract metrics.\n" " - ml: maximum likelihood (only use with well-defined regions and low noise)\n" " N.B. ONLY USE THIS METHOD WITH THE WHITE MATTER ATLAS! The sum of all tracts should be 1 in " "all voxels (the algorithm doesn't normalize the atlas).\n" " - map: maximum a posteriori. Mean priors are estimated by maximum likelihood within three clusters " "(white matter, gray matter and CSF). Tract and noise variance are set with flag -p.\n" " N.B. ONLY USE THIS METHOD WITH THE WHITE MATTER ATLAS! The sum of all tracts should be 1 in " "all voxels (the algorithm doesn't normalize the atlas).\n" " - wa: weighted average\n" " - bin: binarize mask (threshold=0.5)\n" " - max: for each z-slice of the input data, extract the max value for each slice of the input data." ) optional.add_argument( '-append', type=int, choices=(0, 1), default=0, help="Whether to append results as a new line in the output csv file instead of overwriting it. 0 = no, 1 = yes" ) optional.add_argument( '-combine', type=int, choices=(0, 1), default=0, help="Whether to combine multiple labels into a single estimation. 0 = no, 1 = yes" ) optional.add_argument( '-o', metavar=Metavar.file, default=param_default.fname_output, help="R|File name of the output result file collecting the metric estimation results. Include the '.csv' " "file extension in the file name. Example: extract_metric.csv" ) optional.add_argument( '-output-map', metavar=Metavar.file, default='', help="File name for an image consisting of the atlas labels multiplied by the estimated metric values " "yielding the metric value map, useful to assess the metric estimation and especially partial volume " "effects." ) optional.add_argument( '-z', metavar=Metavar.str, default=param_default.slices_of_interest, help="R|Slice range to estimate the metric from. First slice is 0. Example: 5:23\n" "You can also select specific slices using commas. Example: 0,2,3,5,12'" ) optional.add_argument( '-perslice', type=int, choices=(0, 1), default=param_default.perslice, help="R|Whether to output one metric per slice instead of a single output metric. 0 = no, 1 = yes.\n" "Please note that when methods ml or map are used, outputting a single metric per slice and then " "averaging them all is not the same as outputting a single metric at once across all slices." ) optional.add_argument( '-vert', metavar=Metavar.str, default=param_default.vertebral_levels, help="Vertebral levels to estimate the metric across. Example: 2:9 (for C2 to T2)" ) optional.add_argument( '-vertfile', metavar=Metavar.file, default="./label/template/PAM50_levels.nii.gz", help="Vertebral labeling file. Only use with flag -vert. Example: PAM50_levels.nii.gz" ) optional.add_argument( '-perlevel', type=int, metavar=Metavar.int, default=0, help="R|Whether to output one metric per vertebral level instead of a single output metric. 0 = no, 1 = yes.\n" "Please note that this flag needs to be used with the -vert option." ) optional.add_argument( '-v', choices=("0", "1"), default="1", help="Verbose. 0 = nothing, 1 = expanded" ) advanced = parser.add_argument_group("\nFOR ADVANCED USERS") advanced.add_argument( '-param', metavar=Metavar.str, default='', help="R|Advanced parameters for the 'map' method. Separate with comma. All items must be listed (separated " "with comma).\n" " - #1: standard deviation of metrics across labels\n" " - #2: standard deviation of the noise (assumed Gaussian)" ) advanced.add_argument( '-fix-label', metavar=Metavar.list, type=list_type(',', str), default='', help="When using ML or MAP estimations, if you do not want to estimate the metric in one label and fix its " "value to avoid effects on other labels, specify <label_ID>,<metric_value. Example: -fix-label 36,0 " "(Fix the CSF value)" ) advanced.add_argument( '-norm-file', metavar=Metavar.file, default='', help='Filename of the label by which the user wants to normalize.' ) advanced.add_argument( '-norm-method', choices=['sbs', 'whole'], default='', help="R|Method to use for normalization:\n" " - sbs: normalization slice-by-slice\n" " - whole: normalization by the metric value in the whole label for all slices." ) advanced.add_argument( '-mask-weighted', metavar=Metavar.file, default='', help="Nifti mask to weight each voxel during ML or MAP estimation. Example: PAM50_wm.nii.gz" ) advanced.add_argument( '-discard-neg-val', choices=('0', '1'), default='0', help='Whether to discard voxels with negative value when computing metrics statistics. 0 = no, 1 = yes' ) return parser
def get_parser(): # initialize default parameters param_default = Param() # Initialize the parser parser = argparse.ArgumentParser( description="Smooth the spinal cord along its centerline. Steps are:\n" " 1) Spinal cord is straightened (using centerline),\n" " 2) a Gaussian kernel is applied in the superior-inferior direction,\n" " 3) then cord is de-straightened as originally.\n", formatter_class=SmartFormatter, add_help=None, prog=os.path.basename(__file__).strip(".py")) mandatory = parser.add_argument_group("\nMANDATORY ARGUMENTS") mandatory.add_argument('-i', metavar=Metavar.file, required=True, help="Image to smooth. Example: data.nii.gz") mandatory.add_argument( '-s', metavar=Metavar.file, required=True, help= "Spinal cord centerline or segmentation. Example: data_centerline.nii.gz" ) optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit.") optional.add_argument( '-smooth', metavar=Metavar.list, type=list_type(',', float), default=[0, 0, 3], help= "Sigma (standard deviation) of the smoothing Gaussian kernel (in mm). For isotropic smoothing you only " "need to specify a value (e.g. 2). For anisotropic smoothing specify a value for each axis, separated " "with a comma. The order should follow axes Right-Left, Antero-Posterior, Superior-Inferior " "(e.g.: 1,1,3). For no smoothing, set value to 0.") optional.add_argument( '-algo-fitting', metavar=Metavar.str, choices=['bspline', 'polyfit'], default=param_default.algo_fitting, help= f"Algorithm for curve fitting. For more information, see sct_straighten_spinalcord." ) optional.add_argument( '-r', choices=[0, 1], default=1, help="Whether to remove temporary files. 0 = no, 1 = yes") optional.add_argument( '-v', choices=['0', '1', '2'], default='1', help="Verbose: 0 = nothing, 1 = classic, 2 = expended") return parser
def main(argv=None): parser = get_parser() arguments = parser.parse_args(argv) verbose = arguments.v set_loglevel(verbose=verbose) model = arguments.model if "," in arguments.radius: patch_radius = list_type(",", int)(arguments.radius) else: patch_radius = int(arguments.radius) file_to_denoise = arguments.i bval_file = arguments.b output_file_name = arguments.o path, file, ext = extract_fname(file_to_denoise) img = nib.load(file_to_denoise) bvals = np.loadtxt(bval_file) hdr_0 = img.get_header() data = img.get_data() printv('Applying Patch2Self Denoising...') den = patch2self(data, bvals, patch_radius=patch_radius, model=model, verbose=True) if verbose == 2: import matplotlib.pyplot as plt fig, ax = plt.subplots(1, 3) axial_middle = int(data.shape[2] / 2) middle_vol = int(data.shape[3] / 2) before = data[:, :, axial_middle, middle_vol].T ax[0].imshow(before, cmap='gray', origin='lower') ax[0].set_title('before') after = den[:, :, axial_middle, middle_vol].T ax[1].imshow(after, cmap='gray', origin='lower') ax[1].set_title('after') difference = np.absolute(after.astype('f8') - before.astype('f8')) ax[2].imshow(difference, cmap='gray', origin='lower') ax[2].set_title('difference') for i in range(3): ax[i].set_axis_off() plt.show() # Save files img_denoise = nib.Nifti1Image(den, None, hdr_0) diff_4d = np.absolute(den.astype('f8') - data.astype('f8')) img_diff = nib.Nifti1Image(diff_4d, None, hdr_0) if output_file_name is not None: output_file_name_den = output_file_name output_file_name_diff = add_suffix(output_file_name, "_difference") else: output_file_name_den = file + '_patch2self_denoised' + ext output_file_name_diff = file + '_patch2self_difference' + ext nib.save(img_denoise, output_file_name_den) nib.save(img_diff, output_file_name_diff) printv('\nDone! To view results, type:', verbose) printv('fsleyes ' + file_to_denoise + ' ' + output_file_name + ' & \n', verbose, 'info')
def get_parser(): # initialize parameters # TODO: create a class ParamFmriMoco which inheritates from ParamMoco param_default = ParamMoco(group_size=1, metric='MeanSquares', smooth='0') # parser initialisation parser = argparse.ArgumentParser( description= "Motion correction of fMRI data. Some robust features include:\n" " - group-wise (-g)\n" " - slice-wise regularized along z using polynomial function (-p)\n" " (For more info about the method, type: isct_antsSliceRegularizedRegistration)\n" " - masking (-m)\n" " - iterative averaging of target volume\n" "\n" "The outputs of the motion correction process are:\n" " - the motion-corrected fMRI volumes\n" " - the time average of the corrected fMRI volumes\n" " - a time-series with 1 voxel in the XY plane, for the X and Y motion direction (two separate " "files), as required for FSL analysis.\n" " - a TSV file with the slice-wise average of the motion correction for XY (one file), that " "can be used for Quality Control.\n", formatter_class=SmartFormatter, add_help=None, prog=os.path.basename(__file__).strip(".py")) mandatory = parser.add_argument_group("\nMANDATORY ARGUMENTS") mandatory.add_argument('-i', metavar=Metavar.file, required=True, help="Input data (4D). Example: fmri.nii.gz") optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit.") optional.add_argument( '-g', metavar=Metavar.int, type=int, help="Group nvols successive fMRI volumes for more robustness.") optional.add_argument( '-m', metavar=Metavar.file, help= "Binary mask to limit voxels considered by the registration metric.") optional.add_argument( '-param', metavar=Metavar.list, type=list_type(',', str), help= f"R|Advanced parameters. Assign value with \"=\"; Separate arguments with \",\".\n" f" - poly [int]: Degree of polynomial function used for regularization along Z. For no regularization " f"set to 0. Default={param_default.poly}.\n" f" - smooth [mm]: Smoothing kernel. Default={param_default.smooth}.\n" f" - iter [int]: Number of iterations. Default={param_default.iter}.\n" f" - metric {{MI, MeanSquares, CC}}: Metric used for registration. Default={param_default.metric}.\n" f" - gradStep [float]: Searching step used by registration algorithm. The higher the more deformation " f"allowed. Default={param_default.gradStep}.\n" f" - sampling [None or 0-1]: Sampling rate used for registration metric. " f"Default={param_default.sampling}.\n" f" - numTarget [int]: Target volume or group (starting with 0). Default={param_default.num_target}.\n" f" - iterAvg [int]: Iterative averaging: Target volume is a weighted average of the " f"previously-registered volumes. Default={param_default.iterAvg}.\n") optional.add_argument('-ofolder', metavar=Metavar.folder, action=ActionCreateFolder, default='./', help="Output path.") optional.add_argument('-x', choices=['nn', 'linear', 'spline'], default='linear', help="Final interpolation.") optional.add_argument('-r', metavar=Metavar.int, type=int, choices=[0, 1], default=1, help="Remove temporary files. O = no, 1 = yes") optional.add_argument( '-v', choices=['0', '1', '2'], default='1', help="Verbose: 0 = nothing, 1 = basic, 2 = extended.") return parser
def get_parser(): # initialize parameters param_default = ParamMoco(is_diffusion=True, group_size=3, metric='MI', smooth='1') parser = SCTArgumentParser( description= "Motion correction of dMRI data. Some of the features to improve robustness were proposed in Xu et " "al. (http://dx.doi.org/10.1016/j.neuroimage.2012.11.014) and include:\n" " - group-wise (-g)\n" " - slice-wise regularized along z using polynomial function (-param). For more info about the " "method, type: isct_antsSliceRegularizedRegistration\n" " - masking (-m)\n" " - iterative averaging of target volume\n") mandatory = parser.add_argument_group("\nMANDATORY ARGUMENTS") mandatory.add_argument('-i', metavar=Metavar.file, required=True, help="Diffusion data. Example: dmri.nii.gz") mandatory.add_argument('-bvec', metavar=Metavar.file, required=True, help='Bvecs file. Example: bvecs.txt') optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit.") optional.add_argument( '-bval', metavar=Metavar.file, default=param_default.fname_bvals, help='Bvals file. Example: bvals.nii.gz', ) optional.add_argument( '-bvalmin', type=float, metavar=Metavar.float, default=param_default.bval_min, help= 'B-value threshold (in s/mm2) below which data is considered as b=0. Example: 50.0', ) optional.add_argument( '-g', type=int, metavar=Metavar.int, default=param_default.group_size, help= 'Group nvols successive dMRI volumes for more robustness. Example: 2', ) optional.add_argument( '-m', metavar=Metavar.file, default=param_default.fname_mask, help= 'Binary mask to limit voxels considered by the registration metric. Example: dmri_mask.nii.gz', ) optional.add_argument( '-param', metavar=Metavar.list, type=list_type(',', str), help= f"R|Advanced parameters. Assign value with \"=\", and separate arguments with \",\".\n" f" - poly [int]: Degree of polynomial function used for regularization along Z. For no regularization " f"set to 0. Default={param_default.poly}.\n" f" - smooth [mm]: Smoothing kernel. Default={param_default.smooth}.\n" f" - metric {{MI, MeanSquares, CC}}: Metric used for registration. Default={param_default.metric}.\n" f" - gradStep [float]: Searching step used by registration algorithm. The higher the more deformation " f"allowed. Default={param_default.gradStep}.\n" f" - sample [None or 0-1]: Sampling rate used for registration metric. " f"Default={param_default.sampling}.\n") optional.add_argument('-x', choices=['nn', 'linear', 'spline'], default=param_default.interp, help="Final interpolation.") optional.add_argument('-ofolder', metavar=Metavar.folder, action=ActionCreateFolder, default=param_default.path_out, help="Output folder. Example: dmri_moco_results/") optional.add_argument("-r", choices=('0', '1'), default=param_default.remove_temp_files, help="Remove temporary files. 0 = no, 1 = yes") optional.add_argument( '-v', metavar=Metavar.int, type=int, choices=[0, 1, 2], default=1, # Values [0, 1, 2] map to logging levels [WARNING, INFO, DEBUG], but are also used as "if verbose == #" in API help= "Verbosity. 0: Display only errors/warnings, 1: Errors/warnings + info messages, 2: Debug mode" ) return parser
def get_parser(): parser = argparse.ArgumentParser( description="Utility functions for label images.", formatter_class=SmartFormatter, add_help=None, prog=os.path.basename(__file__).strip(".py")) req_group = parser.add_argument_group("\nREQUIRED I/O") req_group.add_argument( '-i', metavar=Metavar.file, required=True, help="Input image (Required) Example: t2_labels.nii.gz") io_group = parser.add_argument_group("\nOPTIONAL I/O") io_group.add_argument( '-o', metavar=Metavar.file, default='labels.nii.gz', help= ("Output image. Note: Only some label utilities create an output image. Example: t2_labels.nii.gz" )) io_group.add_argument( '-ilabel', metavar=Metavar.file, help= "File that contain labels that you want to correct. It is possible to add new points with this option. " "Use with -create-viewer. Example: t2_labels_auto.nii.gz") functions = parser.add_argument_group("\nLABEL FUNCTIONS") func_group = functions.add_mutually_exclusive_group(required=True) func_group.add_argument( '-add', metavar=Metavar.int, type=int, help="Add value to all labels. Value can be negative.") func_group.add_argument( '-create', metavar=Metavar.list, type=list_type(':', Coordinate), help= "Create labels in a new image. List labels as: x1,y1,z1,value1:x2,y2,z2,value2. " "Example: 12,34,32,1:12,35,33,2") func_group.add_argument( '-create-add', metavar=Metavar.list, type=list_type(':', Coordinate), help= "Same as '-create', but add labels to the input image instead of creating a new image. " "Example: 12,34,32,1:12,35,33,2") func_group.add_argument( '-create-seg', metavar=Metavar.list, type=list_type(':', list_type(',', int)), help= "R|Create labels along cord segmentation (or centerline) defined by '-i'. First value is 'z', second is " "the value of the label. Separate labels with ':'. Example: 5,1:14,2:23,3. \n" "To select the mid-point in the superior-inferior direction, set z to '-1'. For example if you know that " "C2-C3 disc is centered in the S-I direction, then enter: -1,3") func_group.add_argument( '-create-viewer', metavar=Metavar.list, type=list_type(',', int), help= "Manually label from a GUI a list of labels IDs, separated with ','. Example: 2,3,4,5" ) func_group.add_argument( '-cubic-to-point', action="store_true", help="Compute the center-of-mass for each label value.") func_group.add_argument( '-disc', metavar=Metavar.file, help= "Create an image with regions labelized depending on values from reference" ) func_group.add_argument('-display', action="store_true", help="Display all labels (i.e. non-zero values).") func_group.add_argument( '-increment', action="store_true", help= "Takes all non-zero values, sort them along the inverse z direction, and attributes the values " "1, 2, 3, etc.") func_group.add_argument( '-vert-body', metavar=Metavar.list, type=list_type(',', int), help= "R|From vertebral labeling, create points that are centered at the mid-vertebral levels. Separate " "desired levels with ','. Example: 3,8\n" "To get all levels, enter 0.") func_group.add_argument( '-vert-continuous', action="store_true", help= "Convert discrete vertebral labeling to continuous vertebral labeling.", ) func_group.add_argument( '-MSE', metavar=Metavar.file, help= "Compute Mean Square Error between labels from input and reference image. Specify reference image here." ) func_group.add_argument( '-remove-reference', metavar=Metavar.file, help= "Remove labels from input image (-i) that are not in reference image (specified here)." ) func_group.add_argument( '-remove-sym', metavar=Metavar.file, help= "Remove labels from input image (-i) and reference image (specified here) that don't match. You must " "provide two output names separated by ','.") func_group.add_argument( '-remove', metavar=Metavar.list, type=list_type(',', int), help= "Remove labels of specific value (specified here) from reference image." ) func_group.add_argument( '-keep', metavar=Metavar.list, type=list_type(',', int), help= "Keep labels of specific value (specified here) from reference image.") optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit.") optional.add_argument( '-msg', metavar=Metavar.str, help= "Display a message to explain the labeling task. Use with -create-viewer" ) optional.add_argument('-v', choices=[0, 1, 2], default=1, metavar=Metavar.int, type=int, help="Verbose. 0: nothing. 1: basic. 2: extended.") optional.add_argument( '-qc', metavar=Metavar.folder, action=ActionCreateFolder, help= "The path where the quality control generated content will be saved.") optional.add_argument( '-qc-dataset', metavar=Metavar.str, help= "If provided, this string will be mentioned in the QC report as the dataset the process was run on." ) optional.add_argument( '-qc-subject', metavar=Metavar.str, help= "If provided, this string will be mentioned in the QC report as the subject the process was run on." ) return parser
def get_parser(): parser = argparse.ArgumentParser( description= 'Perform mathematical operations on images. Some inputs can be either a number or a 4d image or ' 'several 3d images separated with ","', add_help=None, formatter_class=SmartFormatter, prog=os.path.basename(__file__).strip(".py")) mandatory = parser.add_argument_group("MANDATORY ARGUMENTS") mandatory.add_argument("-i", metavar=Metavar.file, help="Input file. Example: data.nii.gz", required=True) mandatory.add_argument("-o", metavar=Metavar.file, help='Output file. Example: data_mean.nii.gz', required=True) optional = parser.add_argument_group("OPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit") basic = parser.add_argument_group('BASIC OPERATIONS') basic.add_argument( "-add", metavar='', nargs="+", help= 'Add following input. Can be a number or multiple images (separated with space).', required=False) basic.add_argument( "-sub", metavar='', nargs="+", help='Subtract following input. Can be a number or an image.', required=False) basic.add_argument( "-mul", metavar='', nargs="+", help= 'Multiply by following input. Can be a number or multiple images (separated with space).', required=False) basic.add_argument( "-div", metavar='', nargs="+", help='Divide by following input. Can be a number or an image.', required=False) basic.add_argument('-mean', help='Average data across dimension.', required=False, choices=('x', 'y', 'z', 't')) basic.add_argument('-rms', help='Compute root-mean-squared across dimension.', required=False, choices=('x', 'y', 'z', 't')) basic.add_argument('-std', help='Compute STD across dimension.', required=False, choices=('x', 'y', 'z', 't')) basic.add_argument( "-bin", type=float, metavar=Metavar.float, help='Binarize image using specified threshold. Example: 0.5', required=False) thresholding = parser.add_argument_group("THRESHOLDING METHODS") thresholding.add_argument( '-otsu', type=int, metavar=Metavar.int, help= 'Threshold image using Otsu algorithm (from skimage). Specify the number of bins (e.g. 16, 64, 128)', required=False) thresholding.add_argument( "-adap", metavar=Metavar.list, type=list_type(',', int), help= "R|Threshold image using Adaptive algorithm (from skimage). Provide 2 values separated by ',' that " "correspond to the parameters below. For example, '-adap 7,0' corresponds to a block size of 7 and an " "offset of 0.\n" " - Block size: Odd size of pixel neighborhood which is used to calculate the threshold value. \n" " - Offset: Constant subtracted from weighted mean of neighborhood to calculate the local threshold " "value. Suggested offset is 0.", required=False) thresholding.add_argument( "-otsu-median", metavar=Metavar.list, type=list_type(',', int), help= "R|Threshold image using Median Otsu algorithm (from dipy). Provide 2 values separated by ',' that " "correspond to the parameters below. For example, '-otsu-median 3,5' corresponds to a filter size of 3 " "repeated over 5 iterations.\n" " - Size: Radius (in voxels) of the applied median filter.\n" " - Iterations: Number of passes of the median filter.", required=False) thresholding.add_argument( '-percent', type=int, help="Threshold image using percentile of its histogram.", metavar=Metavar.int, required=False) thresholding.add_argument( "-thr", type=float, help='Use following number to threshold image (zero below number).', metavar=Metavar.float, required=False) mathematical = parser.add_argument_group("MATHEMATICAL MORPHOLOGY") mathematical.add_argument( '-dilate', type=int, metavar=Metavar.int, help= "Dilate binary or greyscale image with specified size. If shape={'square', 'cube'}: size corresponds to the length of " "an edge (size=1 has no effect). If shape={'disk', 'ball'}: size corresponds to the radius, not including " "the center element (size=0 has no effect).", required=False) mathematical.add_argument( '-erode', type=int, metavar=Metavar.int, help= "Erode binary or greyscale image with specified size. If shape={'square', 'cube'}: size corresponds to the length of " "an edge (size=1 has no effect). If shape={'disk', 'ball'}: size corresponds to the radius, not including " "the center element (size=0 has no effect).", required=False) mathematical.add_argument( '-shape', help= "R|Shape of the structuring element for the mathematical morphology operation. Default: ball.\n" "If a 2D shape {'disk', 'square'} is selected, -dim must be specified.", required=False, choices=('square', 'cube', 'disk', 'ball'), default='ball') mathematical.add_argument( '-dim', type=int, help= "Dimension of the array which 2D structural element will be orthogonal to. For example, if you wish to " "apply a 2D disk kernel in the X-Y plane, leaving Z unaffected, parameters will be: shape=disk, dim=2.", required=False, choices=(0, 1, 2)) filtering = parser.add_argument_group("FILTERING METHODS") filtering.add_argument( "-smooth", metavar=Metavar.list, type=list_type(',', float), help= 'Gaussian smoothing filtering. Supply values for standard deviations in mm. If a single value is provided, ' 'it will be applied to each axis of the image. If multiple values are provided, there must be one value ' 'per image axis. (Examples: "-smooth 2.0,3.0,2.0" (3D image), "-smooth 2.0" (any-D image)).', required=False) filtering.add_argument( '-laplacian', metavar=Metavar.list, type=list_type(',', float), help= 'Laplacian filtering. Supply values for standard deviations in mm. If a single value is provided, it will ' 'be applied to each axis of the image. If multiple values are provided, there must be one value per ' 'image axis. (Examples: "-laplacian 2.0,3.0,2.0" (3D image), "-laplacian 2.0" (any-D image)).', required=False) filtering.add_argument( '-denoise', help= 'R|Non-local means adaptative denoising from P. Coupe et al. as implemented in dipy. Separate with ". Example: p=1,b=3\n' ' p: (patch radius) similar patches in the non-local means are searched for locally, inside a cube of side 2*p+1 centered at each voxel of interest. Default: p=1\n' ' b: (block radius) the size of the block to be used (2*b+1) in the blockwise non-local means implementation. Default: b=5 ' ' Note, block radius must be smaller than the smaller image dimension: default value is lowered for small images)\n' 'To use default parameters, write -denoise 1', required=False) similarity = parser.add_argument_group("SIMILARITY METRIC") similarity.add_argument( '-mi', metavar=Metavar.file, help= 'Compute the mutual information (MI) between both input files (-i and -mi) as in: ' 'http://scikit-learn.org/stable/modules/generated/sklearn.metrics.mutual_info_score.html', required=False) similarity.add_argument( '-minorm', metavar=Metavar.file, help= 'Compute the normalized mutual information (MI) between both input files (-i and -mi) as in: ' 'http://scikit-learn.org/stable/modules/generated/sklearn.metrics.normalized_mutual_info_score.html', required=False) similarity.add_argument( '-corr', metavar=Metavar.file, help= 'Compute the cross correlation (CC) between both input files (-i and -cc).', required=False) misc = parser.add_argument_group("MISC") misc.add_argument('-symmetrize', type=int, help='Symmetrize data along the specified dimension.', required=False, choices=(0, 1, 2)) misc.add_argument('-type', required=False, help='Output type.', choices=('uint8', 'int16', 'int32', 'float32', 'complex64', 'float64', 'int8', 'uint16', 'uint32', 'int64', 'uint64')) misc.add_argument("-v", type=int, help="Verbose. 0: nothing. 1: basic. 2: extended.", required=False, default=1, choices=(0, 1, 2)) return parser
def get_parser(): # initialize default param param_default = Param() # parser initialisation parser = argparse.ArgumentParser(description=( "This function takes an anatomical image and its cord segmentation (binary file), and outputs the " "cord segmentation labeled with vertebral level. The algorithm requires an initialization (first disc) and " "then performs a disc search in the superior, then inferior direction, using template disc matching based " "on mutual information score. The automatic method uses the module implemented in " "'spinalcordtoolbox/vertebrae/detect_c2c3.py' to detect the C2-C3 disc.\n" "Tips: To run the function with init txt file that includes flags -initz/-initcenter:\n" " sct_label_vertebrae -i t2.nii.gz -s t2_seg-manual.nii.gz '$(< init_label_vertebrae.txt)'" ), formatter_class=SmartFormatter, add_help=None, prog=os.path.basename(__file__).strip( ".py")) mandatory = parser.add_argument_group("\nMANDATORY ARGUMENTS") mandatory.add_argument('-i', metavar=Metavar.file, required=True, help="Input image. Example: t2.nii.gz") mandatory.add_argument( '-s', metavar=Metavar.file, required=True, help="Segmentation of the spinal cord. Example: t2_seg.nii.gz") mandatory.add_argument( '-c', choices=['t1', 't2'], required=True, help= "Type of image contrast. 't2': cord dark / CSF bright. 't1': cord bright / CSF dark" ) optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit.") optional.add_argument('-t', metavar=Metavar.folder, default=os.path.join(sct.__data_dir__, "PAM50"), help="Path to template.") optional.add_argument( '-initz', metavar=Metavar.list, type=list_type(',', int), help= "R|Initialize using slice number and disc value. Example: 68,4 (slice 68 corresponds to disc C3/C4). " "Example: 125,3\n" "WARNING: Slice number should correspond to superior-inferior direction (e.g. Z in RPI orientation, but " "Y in LIP orientation).") optional.add_argument( '-initcenter', metavar=Metavar.int, type=int, help= "Initialize using disc value centered in the rostro-caudal direction. If the spine is curved, then " "consider the disc that projects onto the cord at the center of the z-FOV." ) optional.add_argument( '-initfile', metavar=Metavar.file, help= "Initialize labeling by providing a text file which includes either -initz or -initcenter flag." ) optional.add_argument( '-initlabel', metavar=Metavar.file, help= "Initialize vertebral labeling by providing a nifti file that has a single disc label. An example of " "such file is a single voxel with value '3', which would be located at the posterior tip of C2-C3 disc. " "Such label file can be created using: sct_label_utils -i IMAGE_REF -create-viewer 3 ; or by using the " "Python module 'detect_c2c3' implemented in 'spinalcordtoolbox/vertebrae/detect_c2c3.py'." ) optional.add_argument( '-discfile', metavar=Metavar.file, help= "File with disc labels, which will be used to transform the input segmentation into a vertebral level " "file. In that case, there will be no disc detection. The convention for disc labels is the following: " "value=3 -> disc C2/C3, value=4 -> disc C3/C4, etc.") optional.add_argument('-ofolder', metavar=Metavar.file, action=ActionCreateFolder, default='', help="Output folder.") optional.add_argument( '-denoise', metavar=Metavar.int, type=int, choices=[0, 1], default=0, help= "Apply denoising filter (non-local means adaptative denoising) to the data. Sometimes denoising is too " "aggressive, so use with care.") optional.add_argument( '-laplacian', metavar=Metavar.int, type=int, choices=[0, 1], default=0, help= "Apply Laplacian filtering. More accurate but could mistake disc depending on anatomy." ) optional.add_argument( '-scale-dist', metavar=Metavar.float, type=float, default=1., help= "Scaling factor to adjust the average distance between two adjacent intervertebral discs. For example, " "if you are dealing with images from pediatric population, the distance should be reduced, so you can " "try a scaling factor of about 0.7.") optional.add_argument( '-param', metavar=Metavar.list, type=list_type(',', str), help= f"R|Advanced parameters. Assign value with \"=\"; Separate arguments with \",\"\n" f" - shift_AP [mm]: AP shift of centerline for disc search. Default={param_default.shift_AP}.\n" f" - size_AP [mm]: AP window size for disc search. Default={param_default.size_AP}.\n" f" - size_RL [mm]: RL window size for disc search. Default={param_default.size_RL}.\n" f" - size_IS [mm]: IS window size for disc search. Default={param_default.size_IS}.\n" f" - gaussian_std [mm]: STD of the Gaussian function, centered at the most rostral point of the " f"image, and used to weight C2-C3 disk location finding towards the rostral portion of the FOV. Values " f"to set between 0.1 (strong weighting) and 999 (no weighting). " f"Default={param_default.gaussian_std}.\n") optional.add_argument('-r', metavar=Metavar.int, type=int, choices=[0, 1], default=1, help="Remove temporary files.") optional.add_argument('-v', choices=['0', '1', '2'], default='1', help="Verbose. 0: nothing. 1: basic. 2: extended.") optional.add_argument( '-qc', metavar=Metavar.folder, action=ActionCreateFolder, default=param_default.path_qc, help= "The path where the quality control generated content will be saved.") optional.add_argument( '-qc-dataset', metavar=Metavar.str, help= "If provided, this string will be mentioned in the QC report as the dataset the process was run on." ) optional.add_argument( '-qc-subject', metavar=Metavar.str, help= "If provided, this string will be mentioned in the QC report as the subject the process was run on." ) return parser
def get_parser(paramregmulti=None): # Initialize the parser if paramregmulti is None: step0 = Paramreg( step='0', type='im', algo='syn', metric='MI', iter='0', shrink='1', smooth='0', gradStep='0.5', slicewise='0', dof='Tx_Ty_Tz_Rx_Ry_Rz') # only used to put src into dest space step1 = Paramreg(step='1', type='im') paramregmulti = ParamregMultiStep([step0, step1]) parser = argparse.ArgumentParser( description= "This program co-registers two 3D volumes. The deformation is non-rigid and is constrained along " "Z direction (i.e., axial plane). Hence, this function assumes that orientation of the destination " "image is axial (RPI). If you need to register two volumes with large deformations and/or " "different contrasts, it is recommended to input spinal cord segmentations (binary mask) in order " "to achieve maximum robustness. The program outputs a warping field that can be used to register " "other images to the destination image. To apply the warping field to another image, use " "'sct_apply_transfo'", formatter_class=SmartFormatter, add_help=None, prog=os.path.basename(__file__).strip(".py")) mandatory = parser.add_argument_group("\nMANDATORY ARGUMENTS") mandatory.add_argument('-i', metavar=Metavar.file, required=True, help="Image source. Example: src.nii.gz") mandatory.add_argument('-d', metavar=Metavar.file, required=True, help="Image destination. Example: dest.nii.gz") optional = parser.add_argument_group("\nOPTIONAL ARGUMENTS") optional.add_argument("-h", "--help", action="help", help="Show this help message and exit.") optional.add_argument('-iseg', metavar=Metavar.file, help="Segmentation source. Example: src_seg.nii.gz") optional.add_argument( '-dseg', metavar=Metavar.file, help="Segmentation destination. Example: dest_seg.nii.gz") optional.add_argument('-ilabel', metavar=Metavar.file, help="Labels source.") optional.add_argument('-dlabel', metavar=Metavar.file, help="Labels destination.") optional.add_argument( '-initwarp', metavar=Metavar.file, help="Initial warping field to apply to the source image.") optional.add_argument( '-initwarpinv', metavar=Metavar.file, help= "Initial inverse warping field to apply to the destination image (only use if you wish to generate the " "dest->src warping field)") optional.add_argument( '-m', metavar=Metavar.file, help= "Mask that can be created with sct_create_mask to improve accuracy over region of interest. This mask " "will be used on the destination image. Example: mask.nii.gz") optional.add_argument('-o', metavar=Metavar.file, help="Name of output file. Example: src_reg.nii.gz") optional.add_argument('-owarp', metavar=Metavar.file, help="Name of output forward warping field.") optional.add_argument( '-param', metavar=Metavar.list, type=list_type(':', str), help= (f"R|Parameters for registration. Separate arguments with \",\". Separate steps with \":\".\n" f"Example: step=1,type=seg,algo=slicereg,metric=MeanSquares:step=2,type=im,algo=syn,metric=MI,iter=5," f"shrink=2\n" f" - step: <int> Step number (starts at 1, except for type=label).\n" f" - type: {{im, seg, imseg, label}} type of data used for registration. Use type=label only at " f"step=0.\n" f" - algo: Default={paramregmulti.steps['1'].algo}\n" f" - translation: translation in X-Y plane (2dof)\n" f" - rigid: translation + rotation in X-Y plane (4dof)\n" f" - affine: translation + rotation + scaling in X-Y plane (6dof)\n" f" - syn: non-linear symmetric normalization\n" f" - bsplinesyn: syn regularized with b-splines\n" f" - slicereg: regularized translations (see: goo.gl/Sj3ZeU)\n" f" - centermass: slicewise center of mass alignment (seg only).\n" f" - centermassrot: slicewise center of mass and rotation alignment using method specified in " f"'rot_method'\n" f" - columnwise: R-L scaling followed by A-P columnwise alignment (seg only).\n" f" - slicewise: <int> Slice-by-slice 2d transformation. " f"Default={paramregmulti.steps['1'].slicewise}.\n" f" - metric: {{CC,MI,MeanSquares}}. Default={paramregmulti.steps['1'].metric}.\n" f" - iter: <int> Number of iterations. Default={paramregmulti.steps['1'].iter}.\n" f" - shrink: <int> Shrink factor (only for syn/bsplinesyn). " f"Default={paramregmulti.steps['1'].shrink}.\n" f" - smooth: <int> Smooth factor (in mm). Note: if algo={{centermassrot,columnwise}} the smoothing " f"kernel is: SxSx0. Otherwise it is SxSxS. Default={paramregmulti.steps['1'].smooth}.\n" f" - laplacian: <int> Laplacian filter. Default={paramregmulti.steps['1'].laplacian}.\n" f" - gradStep: <float> Gradient step. Default={paramregmulti.steps['1'].gradStep}.\n" f" - deformation: ?x?x?: Restrict deformation (for ANTs algo). Replace ? by 0 (no deformation) or 1 " f"(deformation). Default={paramregmulti.steps['1'].deformation}.\n" f" - init: Initial translation alignment based on:\n" f" * geometric: Geometric center of images\n" f" * centermass: Center of mass of images\n" f" * origin: Physical origin of images\n" f" - poly: <int> Polynomial degree of regularization (only for algo=slicereg). " f"Default={paramregmulti.steps['1'].poly}.\n" f" - filter_size: <float> Filter size for regularization (only for algo=centermassrot). " f"Default={paramregmulti.steps['1'].filter_size}.\n" f" - smoothWarpXY: <int> Smooth XY warping field (only for algo=columnwize). " f"Default={paramregmulti.steps['1'].smoothWarpXY}.\n" f" - pca_eigenratio_th: <int> Min ratio between the two eigenvalues for PCA-based angular adjustment " f"(only for algo=centermassrot and rot_method=pca). " f"Default={paramregmulti.steps['1'].pca_eigenratio_th}.\n" f" - dof: <str> Degree of freedom for type=label. Separate with '_'. " f"Default={paramregmulti.steps['0'].dof}.\n" f" - rot_method {{pca, hog, pcahog}}: rotation method to be used with algo=centermassrot. pca: " f"approximate cord segmentation by an ellipse and finds it orientation using PCA's eigenvectors; hog: " f"finds the orientation using the symmetry of the image; pcahog: tries method pca and if it fails, uses " f"method hog. If using hog or pcahog, type should be set to imseg." f"Default={paramregmulti.steps['1'].rot_method}\n")) optional.add_argument( '-identity', metavar=Metavar.int, type=int, choices=[0, 1], default=0, help="Just put source into destination (no optimization).") optional.add_argument( '-z', metavar=Metavar.int, type=int, default=Param().padding, help="Size of z-padding to enable deformation at edges when using SyN." ) optional.add_argument('-x', choices=['nn', 'linear', 'spline'], default='linear', help="Final interpolation.") optional.add_argument('-ofolder', metavar=Metavar.folder, action=ActionCreateFolder, help="Output folder. Example: reg_results/") optional.add_argument( '-qc', metavar=Metavar.folder, action=ActionCreateFolder, help= "The path where the quality control generated content will be saved.") optional.add_argument( '-qc-dataset', metavar=Metavar.str, help= "If provided, this string will be mentioned in the QC report as the dataset the process was run on." ) optional.add_argument( '-qc-subject', metavar=Metavar.str, help= "If provided, this string will be mentioned in the QC report as the subject the process was run on." ) optional.add_argument( '-r', metavar=Metavar.int, type=int, choices=[0, 1], default=1, help="Whether to remove temporary files. 0 = no, 1 = yes") optional.add_argument('-v', choices=['0', '1', '2'], default='1', help="Verbose. 0: nothing, 1: basic, 2: extended.") return parser