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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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
Ejemplo n.º 5
0
    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