def main(): """Main function that creates and executes the BIDS App docker command. Returns ------- exit_code : {0, 1} An exit code given to `sys.exit()` that can be: * '0' in case of successful completion * '1' in case of an error """ # Create and parse arguments parser = get_parser() args = parser.parse_args() # Create the docker run command cmd = create_docker_cmd(args) # Execute the docker run command try: print(f'... cmd: {cmd}') run(cmd) exit_code = 0 except Exception as e: print('Failed') print(e) exit_code = 1 return exit_code
def _run_interface(self, runtime): _, name, ext = split_filename(os.path.abspath(self.inputs.in_file)) out_file = os.path.join( os.getcwd().replace(self.inputs.bids_dir, '/fetaldata'), ''.join( (name, self.inputs.out_postfix, ext))) cmd = 'mialsrtkCorrectSliceIntensity "{}" "{}" "{}"'.format( self.inputs.in_file, self.inputs.in_mask, out_file) try: print('... cmd: {}'.format(cmd)) run(self, cmd, env={}, cwd=os.path.abspath(self.inputs.bids_dir)) except: print('Failed') return runtime
def _run_interface(self, runtime): _, name, ext = split_filename(os.path.abspath(self.inputs.in_file)) #Version from MIAL/mialsuperresolutiontoolkit with no docker #out_file = os.path.join(self.inputs.bids_dir, ''.join((name, self.inputs.out_postfix, ext))) out_file = os.path.join( os.getcwd().replace(self.inputs.bids_dir, '/fetaldata'), ''.join( (name, self.inputs.out_postfix, ext))) uid = os.getuid() gid = os.getgid() cmd = [] cmd.append("docker run --rm -u {}:{}".format(uid, gid)) cmd.append("--volumes-from sinapp_nlmdenoise") cmd.append( "sebastientourbier/mialsuperresolutiontoolkit btkNLMDenoising") cmd.append("-i {} -o {} -b {}".format(self.inputs.in_file, out_file, self.inputs.weight)) if self.inputs.in_mask: cmd.append("-m {}".format(self.inputs.in_mask)) try: print('... cmd: {}'.format(cmd)) p = run(' '.join(cmd), env={}, cwd=os.path.abspath(self.inputs.bids_dir)) print(p) except: print('Failed') return runtime
def _run_interface(self, runtime): _, name, ext = split_filename(os.path.abspath(self.inputs.input_image)) out_corr = self._gen_filename('output_image') out_fld = self._gen_filename('output_field') cmd = [ 'mialsrtkN4BiasFieldCorrection', self.inputs.input_image, self.inputs.input_mask, out_corr, out_fld ] try: print('... cmd: {}'.format(cmd)) cmd = ' '.join(cmd) run(cmd, env={}, cwd=os.path.abspath(self.inputs.bids_dir)) except Exception as e: print('Failed') print(e) return runtime
def _run_interface(self, runtime): _, name, ext = split_filename(os.path.abspath(self.inputs.in_file)) out_file = os.path.join( os.getcwd().replace(self.inputs.bids_dir, '/fetaldata'), ''.join( (name, self.inputs.out_postfix, ext))) if self.inputs.in_max: cmd = 'mialsrtkIntensityStandardization --input "{}" --output "{}" --max "{}"'.format( self.inputs.in_file, out_file, self.inputs.in_max) else: cmd = 'mialsrtkIntensityStandardization --input "{}" --output "{}"'.format( self.inputs.in_file, out_file) try: print('... cmd: {}'.format(cmd)) run(self, cmd, env={}, cwd=os.path.abspath(self.inputs.bids_dir)) except: print('Failed') return runtime
def _run_interface(self, runtime): params = [''.join(["--", self.inputs.in_roi])] input_images = reorder_by_run_ids(self.inputs.input_images, self.inputs.stacks_order) input_masks = reorder_by_run_ids(self.inputs.input_masks, self.inputs.stacks_order) for in_image, in_mask in zip(input_images, input_masks): params.append("-i") params.append(in_image) if self.inputs.in_roi == "mask": params.append("-m") params.append(in_mask) transf_file = self._gen_filename(in_image, 'output_transforms') params.append("-t") params.append(transf_file) out_file = self._gen_filename(self.inputs.input_images[0], 'output_sdi') params.append("-o") params.append(out_file) if self.inputs.no_reg: params.append("--noreg") cmd = ["mialsrtkImageReconstruction"] cmd += params try: print('... cmd: {}'.format(cmd)) cmd = ' '.join(cmd) run(cmd, cwd=os.path.abspath(self.inputs.bids_dir)) except Exception as e: print('Failed') print(e) return runtime
def _run_interface(self, runtime): cmd = ['mialsrtkRefineHRMaskByIntersection'] cmd += ['--radius-dilation', str(self.inputs.input_rad_dilatation)] if self.inputs.in_use_staple: cmd += ['--use-staple'] for in_file, in_mask, in_transform in zip( self.inputs.input_images, self.inputs.input_masks, self.inputs.input_transforms): cmd += ['-i', in_file] cmd += ['-m', in_mask] cmd += ['-t', in_transform] out_file = self._gen_filename(in_file, 'output_lrmasks') cmd += ['-O', out_file] out_file = self._gen_filename(self.inputs.input_images[0], 'output_srmask') cmd += ['-r', self.inputs.input_sr] cmd += ['-o', out_file] try: print('... cmd: {}'.format(cmd)) cmd = ' '.join(cmd) run(cmd, env={}, cwd=os.path.abspath(self.inputs.bids_dir)) except Exception as e: print('Failed') print(e) return runtime
def main(): """Main function that creates and executes the BIDS App singularity command. Returns ------- exit_code : {0, 1} An exit code given to `sys.exit()` that can be: * '0' in case of successful completion * '1' in case of an error """ # Create and parse arguments parser = get_singularity_wrapper_parser() args = parser.parse_args() # Create the singularity run command cmd = create_singularity_cmd(args) # Create and start the carbon footprint tracker if args.track_carbon_footprint: logging.getLogger( "codecarbon").disabled = True # Comment this line for debug tracker = EmissionsTracker( project_name=f"MIALSRTK{__version__}-docker", output_dir=str(Path(args.bids_dir) / "code"), measure_power_secs=15, ) tracker.start() # Execute the singularity run command try: print(f'... cmd: {cmd}') run(cmd) exit_code = 0 except Exception as e: print('Failed') print(e) exit_code = 1 if args.track_carbon_footprint: emissions: float = tracker.stop() print("############################################################") print( f"CARBON FOOTPRINT OF {len(args.participant_label)} SUBJECT(S) PROCESSED" ) print("############################################################") print(f" * Estimated Co2 emissions: {emissions} kg") car_kms = get_emission_car_miles_equivalent(emissions) print(f" * Equivalent in distance travelled by avg car: {car_kms} kms") tv_time = get_emission_tv_time_equivalent(emissions) print( f" * Equivalent in amount of time watching a 32-inch LCD flat screen TV: {tv_time}" ) print("############################################################") print(f"PREDICTED CARBON FOOTPRINT OF 100 SUBJECTS PROCESSED") print("############################################################") pred_emissions = 100 * emissions / len(args.participant_label) print(f" * Estimated Co2 emissions: {pred_emissions} kg") car_kms = get_emission_car_miles_equivalent(pred_emissions) print(f" * Equivalent in distance travelled by avg car: {car_kms} kms") tv_time = get_emission_tv_time_equivalent(pred_emissions) print( f" * Equivalent in amount of time watching a 32-inch LCD flat screen TV: {tv_time}" ) print("############################################################") print( "Results can be visualized with the codecarbon visualization tool using following command:\n" ) print( f'\t$ carbonboard --filepath="{args.bids_dir}/code/emissions.csv" --port=9999\n' ) return exit_code
def _run_interface(self, runtime): cmd = ['mialsrtkTVSuperResolution'] input_images = reorder_by_run_ids(self.inputs.input_images, self.inputs.stacks_order) input_masks = reorder_by_run_ids(self.inputs.input_masks, self.inputs.stacks_order) input_transforms = reorder_by_run_ids(self.inputs.input_transforms, self.inputs.stacks_order) for in_image, in_mask, in_transform in zip(input_images, input_masks, input_transforms): cmd += ['-i', in_image] cmd += ['-m', in_mask] cmd += ['-t', in_transform] cmd += ['-r', self.inputs.input_sdi] out_sr = self._gen_filename('output_sr') cmd += ['-o', out_sr] if self.inputs.deblurring: cmd += ['--debluring'] cmd += ['--loop', str(self.inputs.in_loop)] cmd += ['--deltat', str(self.inputs.in_deltat)] cmd += ['--lambda', str(self.inputs.in_lambda)] cmd += ['--bregman-loop', str(self.inputs.in_bregman_loop)] cmd += ['--iter', str(self.inputs.in_iter)] cmd += ['--step-scale', str(self.inputs.in_step_scale)] cmd += ['--gamma', str(self.inputs.in_gamma)] cmd += ['--inner-thresh', str(self.inputs.in_inner_thresh)] cmd += ['--outer-thresh', str(self.inputs.in_outer_thresh)] try: cmd = ' '.join(cmd) run(cmd, cwd=os.path.abspath(self.inputs.bids_dir)) except Exception as e: print('Failed') print(e) ################################################ # Creation of JSON sidecar file of the SR image ################################################ self.m_output_dict["Description"] = "Isotropic high-resolution image reconstructed using the Total-Variation" \ " Super-Resolution algorithm provided by MIALSRTK" self.m_output_dict[ "Input sources run order"] = self.inputs.stacks_order self.m_output_dict["CustomMetaData"] = {} self.m_output_dict["CustomMetaData"]["Number of scans used"] = str( len(self.inputs.stacks_order)) self.m_output_dict["CustomMetaData"][ "Masks used"] = 'Manual' if self.inputs.use_manual_masks else 'Automatic' self.m_output_dict["CustomMetaData"][ "TV regularization weight lambda"] = self.inputs.in_lambda self.m_output_dict["CustomMetaData"][ "Optimization time step"] = self.inputs.in_deltat self.m_output_dict["CustomMetaData"][ "Primal/dual loops"] = self.inputs.in_loop output_json_path = self._gen_filename('output_json_path') with open(output_json_path, 'w') as outfile: print(' > Write JSON side-car...') json.dump(self.m_output_dict, outfile, indent=4) ######################################################### # Save cuts of the SR image in a PNG for later reporting ######################################################### out_sr_png = self._gen_filename('output_sr_png') # Load the super-resolution image print(f' > Load SR image {out_sr}...') img = nib.load(out_sr) # Get image properties zooms = img.header.get_zooms() # zooms are the size of the voxels shapes = img.shape fovs = np.array(zooms) * np.array(shapes) # Get middle cut cuts = [s // 2 for s in shapes] print( f' Image properties: Zooms={zooms}/ Shape={shapes}/ FOV={fovs}/ middle cut={cuts}' ) # Crop the image if the FOV exceeds a certain value def compute_axis_crop_indices(cut, fov, max_fov=120): """Compute the cropping index in a dimension if the Field-Of-View exceeds a maximum value of 120mm by default. Parameters ---------- cut: int Middle slice index in a given dimension fov: float Slice Field-of-View (mm) in a given dimension max_fov: float Maximum Slice Field-of-View (mm) to which the image does not need to be cropped (120mm by default) Returns ------- (crop_start_index, crop_end_index): (int, int) Starting and ending indices of the image crop along the given dimension """ crop_start_index = cut - max_fov // 2 if fov > max_fov else 0 crop_end_index = cut + max_fov // 2 if fov > max_fov else -1 return crop_start_index, crop_end_index crop_start_x, crop_end_x = compute_axis_crop_indices(cuts[0], fovs[0], max_fov=120) crop_start_y, crop_end_y = compute_axis_crop_indices(cuts[1], fovs[1], max_fov=120) crop_start_z, crop_end_z = compute_axis_crop_indices(cuts[2], fovs[2], max_fov=120) print(f' > Crop SR image at ' f'({crop_start_x}:{crop_end_x}, ' f'{crop_start_y}:{crop_end_y}, ' f'{crop_start_z}:{crop_end_z})...') cropped_img = img.slicer[crop_start_x:crop_end_x, crop_start_y:crop_end_y, crop_start_z:crop_end_z] del img # Create and save the figure plot_anat( anat_img=cropped_img, annotate=True, draw_cross=False, black_bg=True, dim='auto', display_mode='ortho', ) print(f'Save the PNG image cuts as {out_sr_png}') plt.savefig(out_sr_png, dpi=100, facecolor='k', edgecolor='k') return runtime