Esempio n. 1
0
    def _run_interface(self, runtime):
        # Get a list of settings files.
        settings_files = self._get_settings()
        ants_args = self._get_ants_args()

        if not isdefined(self.inputs.initial_moving_transform):
            NIWORKFLOWS_LOG.info(
                "Estimating initial transform using AffineInitializer")
            init = AffineInitializer(
                fixed_image=ants_args["fixed_image"],
                moving_image=ants_args["moving_image"],
                num_threads=self.inputs.num_threads,
            )
            init.resource_monitor = False
            init.terminal_output = "allatonce"
            init_result = init.run()
            # Save outputs (if available)
            init_out = _write_outputs(init_result.runtime, ".nipype-init")
            if init_out:
                NIWORKFLOWS_LOG.info(
                    "Terminal outputs of initialization saved (%s).",
                    ", ".join(init_out),
                )

            ants_args[
                "initial_moving_transform"] = init_result.outputs.out_file

        # For each settings file...
        for ants_settings in settings_files:

            NIWORKFLOWS_LOG.info("Loading settings from file %s.",
                                 ants_settings)
            # Configure an ANTs run based on these settings.
            self.norm = Registration(from_file=ants_settings, **ants_args)
            self.norm.resource_monitor = False
            self.norm.terminal_output = self.terminal_output

            cmd = self.norm.cmdline
            # Print the retry number and command line call to the log.
            NIWORKFLOWS_LOG.info("Retry #%d, commandline: \n%s", self.retry,
                                 cmd)
            self.norm.ignore_exception = True
            with open("command.txt", "w") as cmdfile:
                print(cmd + "\n", file=cmdfile)

            # Try running registration.
            interface_result = self.norm.run()

            if interface_result.runtime.returncode != 0:
                NIWORKFLOWS_LOG.warning("Retry #%d failed.", self.retry)
                # Save outputs (if available)
                term_out = _write_outputs(interface_result.runtime,
                                          ".nipype-%04d" % self.retry)
                if term_out:
                    NIWORKFLOWS_LOG.warning("Log of failed retry saved (%s).",
                                            ", ".join(term_out))
            else:
                runtime.returncode = 0
                # Note this in the log.
                NIWORKFLOWS_LOG.info(
                    "Successful spatial normalization (retry #%d).",
                    self.retry)
                # Break out of the retry loop.
                return runtime

            self.retry += 1

        # If all tries fail, raise an error.
        raise RuntimeError(
            "Robust spatial normalization failed after %d retries." %
            (self.retry - 1))
Esempio n. 2
0
    def _run_interface(self, runtime):
        # Get a list of settings files.
        settings_files = self._get_settings()
        ants_args = self._get_ants_args()

        if not isdefined(self.inputs.initial_moving_transform):
            NIWORKFLOWS_LOG.info('Estimating initial transform using AffineInitializer')
            init = AffineInitializer(
                fixed_image=ants_args['fixed_image'],
                moving_image=ants_args['moving_image'],
                num_threads=self.inputs.num_threads)
            init.resource_monitor = False
            init.terminal_output = 'allatonce'
            init_result = init.run()
            # Save outputs (if available)
            init_out = _write_outputs(init_result.runtime, '.nipype-init')
            if init_out:
                NIWORKFLOWS_LOG.info(
                    'Terminal outputs of initialization saved (%s).',
                    ', '.join(init_out))

            ants_args['initial_moving_transform'] = init_result.outputs.out_file

        # For each settings file...
        for ants_settings in settings_files:

            NIWORKFLOWS_LOG.info('Loading settings from file %s.',
                                 ants_settings)
            # Configure an ANTs run based on these settings.
            self.norm = Registration(from_file=ants_settings,
                                     **ants_args)
            self.norm.resource_monitor = False
            self.norm.terminal_output = self.terminal_output

            # Print the retry number and command line call to the log.
            NIWORKFLOWS_LOG.info(
                'Retry #%d, commandline: \n%s', self.retry, self.norm.cmdline)
            self.norm.ignore_exception = True
            # Try running registration.
            interface_result = self.norm.run()

            if interface_result.runtime.returncode != 0:
                NIWORKFLOWS_LOG.warning('Retry #%d failed.', self.retry)
                # Save outputs (if available)
                term_out = _write_outputs(interface_result.runtime,
                                          '.nipype-%04d' % self.retry)
                if term_out:
                    NIWORKFLOWS_LOG.warning(
                        'Log of failed retry saved (%s).', ', '.join(term_out))
            else:
                runtime.returncode = 0
                # Grab the outputs.
                self._results.update(interface_result.outputs.get())
                if isdefined(self.inputs.moving_mask):
                    self._validate_results()

                # Note this in the log.
                NIWORKFLOWS_LOG.info(
                    'Successful spatial normalization (retry #%d).', self.retry)
                # Break out of the retry loop.
                return runtime

            self.retry += 1

        # If all tries fail, raise an error.
        raise RuntimeError(
            'Robust spatial normalization failed after %d retries.' % (self.retry - 1))
Esempio n. 3
0
    def _run_interface(self, runtime):
        # Get a list of settings files.
        settings_files = self._get_settings()
        ants_args = self._get_ants_args()

        if not isdefined(self.inputs.initial_moving_transform):
            NIWORKFLOWS_LOG.info(
                'Estimating initial transform using AffineInitializer')
            init = AffineInitializer(fixed_image=ants_args['fixed_image'],
                                     moving_image=ants_args['moving_image'],
                                     num_threads=self.inputs.num_threads)
            init.resource_monitor = False
            init.terminal_output = 'allatonce'
            init_result = init.run()
            # Save outputs (if available)
            init_out = _write_outputs(init_result.runtime, '.nipype-init')
            if init_out:
                NIWORKFLOWS_LOG.info(
                    'Terminal outputs of initialization saved (%s).',
                    ', '.join(init_out))

            ants_args[
                'initial_moving_transform'] = init_result.outputs.out_file

        # For each settings file...
        for ants_settings in settings_files:

            NIWORKFLOWS_LOG.info('Loading settings from file %s.',
                                 ants_settings)
            # Configure an ANTs run based on these settings.
            self.norm = Registration(from_file=ants_settings, **ants_args)
            self.norm.resource_monitor = False
            self.norm.terminal_output = self.terminal_output

            # Print the retry number and command line call to the log.
            NIWORKFLOWS_LOG.info('Retry #%d, commandline: \n%s', self.retry,
                                 self.norm.cmdline)
            self.norm.ignore_exception = True
            # Try running registration.
            interface_result = self.norm.run()

            if interface_result.runtime.returncode != 0:
                NIWORKFLOWS_LOG.warning('Retry #%d failed.', self.retry)
                # Save outputs (if available)
                term_out = _write_outputs(interface_result.runtime,
                                          '.nipype-%04d' % self.retry)
                if term_out:
                    NIWORKFLOWS_LOG.warning('Log of failed retry saved (%s).',
                                            ', '.join(term_out))
            else:
                runtime.returncode = 0
                # Grab the outputs.
                self._results.update(interface_result.outputs.get())
                if isdefined(self.inputs.moving_mask):
                    self._validate_results()

                # Note this in the log.
                NIWORKFLOWS_LOG.info(
                    'Successful spatial normalization (retry #%d).',
                    self.retry)
                # Break out of the retry loop.
                return runtime

            self.retry += 1

        # If all tries fail, raise an error.
        raise RuntimeError(
            'Robust spatial normalization failed after %d retries.' %
            (self.retry - 1))
Esempio n. 4
0
def jip_align(source_file, target_file, outdir, jipdir, prefix="w",
              auto=False, non_linear=False, fslconfig=DEFAULT_FSL_PATH):
    """ Register a source image to a taget image using the 'jip_align'
    command.

    Parameters
    ----------
    source_file: str (mandatory)
        the source Nifti image.
    target_file: str (mandatory)
        the target Nifti masked image.
    outdir: str (mandatory)
        the destination folder.
    jipdir: str (mandatory)
        the jip binary path.
    prefix: str (optional, default 'w')
        prefix the generated file with this character.
    auto: bool (optional, default False)
        if set control the JIP window with the script.
    non_linear: bool (optional, default False)
        in the automatic mode, decide or not to compute the non-linear
        deformation field.
    fslconfig: str (optional)
        the FSL .sh configuration file.

    Returns
    -------
    register_file: str
        the registered image.
    register_mask_file: str
        the registered and masked image.
    native_masked_file: str
        the masked image in the native space.
    """
    # Check input image orientation: must be the same
    same_orient, orients = check_orientation([source_file, target_file])
    if not same_orient:
        print(
            "[WARNING] Source file '{0}' ({2}) and taget file '{1}' ({3}) "
            "must have the same orientation for JIP to work properly.".format(
                source_file, target_file, orients[0], orients[1]))

    # Try to init the affine deformation
    # ToDo: find a way to init the JIP deformation
    if False:
        nb_cpus = multiprocessing.cpu_count()
        init_file = os.path.join(outdir, "init_affine.mat")
        init = AffineInitializer()
        init.inputs.fixed_image = target_file
        init.inputs.moving_image = source_file
        init.inputs.num_threads = nb_cpus
        init.inputs.out_file = init_file
        init.run()
        init_source_file = os.path.join(outdir, "init_source.nii.gz")
        at = ApplyTransforms()
        at.inputs.dimension = 3
        at.inputs.input_image = source_file
        at.inputs.reference_image = target_file
        at.inputs.output_image = init_source_file
        at.inputs.transforms = init_file
        at.inputs.interpolation = "BSpline"
        at.inputs.num_threads = nb_cpus
        at.run()
        # From https://github.com/ANTsX/ANTs/wiki/ITK-affine-transform-conversion
        # From https://github.com/netstim/leaddbs/blob/master/helpers/ea_antsmat2mat.m
        init_mat = loadmat(init_file)
        afftransform = init_mat["AffineTransform_double_3_3"]
        m_center = init_mat["fixed"]
        mat = numpy.eye(4)
        mat[:3, :3] = afftransform[:9].reshape(3, 3).T
        m_translation = afftransform[9:]
        m_offset = m_translation + m_center - numpy.dot(mat[:3, :3], m_center)
        mat[:3, 3] = m_offset.squeeze()
        mat = numpy.linalg.inv(mat)
        #rotation = swap_affine(axes="LPS")
        #mat = numpy.dot(rotation, mat)
        ras_to_lps = numpy.ones((4, 4))
        ras_to_lps[2, :2] = -1
        ras_to_lps[:2, 2:] = -1
        mat = mat * ras_to_lps
        print(mat)
        trans, rot, zoom, shear = decompose44(mat)
        euler = numpy.asarray(mat2euler(rot, axes='sxyz')) * 180. / numpy.pi
        print(trans, euler, zoom, shear)
        align_file = os.path.join(outdir, "align.com")
        im = nibabel.load(source_file)
        orig = im.affine[:3, 3]
        print(orig)
        shift = orig - trans
        with open(align_file, "wt") as of:
            of.write("set registration-translations {0} \n".format(
                " ".join([str(elem) for elem in shift])))

    # Change current working directory
    cwd = os.getcwd()
    os.chdir(outdir)

    # Only support uncompressed Nifti
    source_file = ungzip_file(source_file, prefix="", outdir=outdir)
    target_file = ungzip_file(target_file, prefix="", outdir=outdir)

    # Create jip environment
    jip_envriron = os.environ
    jip_envriron["JIP_HOME"] = os.path.dirname(jipdir)
    if "PATH" in jip_envriron:
        jip_envriron["PATH"] = jip_envriron["PATH"] + ":" + jipdir
    else:
        jip_envriron["PATH"] = jipdir

    # Copy source file
    align_file = os.path.join(outdir, "align.com")
    cmd = ["align", source_file, "-t", target_file]
    if auto:
        if non_linear:
            auto_cmd = cmd + ["-L", "111111111111", "-W", "111", "-a"]
        else:
            auto_cmd = cmd + ["-L", "111111000000", "-W", "000", "-A"]
        if os.path.isfile(align_file):
            auto_cmd += ["-I"]
        subprocess.call(auto_cmd, env=jip_envriron)  
    else:
        print(" ".join(cmd))
        subprocess.call(cmd, env=jip_envriron)
    if not os.path.isfile(align_file):
        raise ValueError(
            "No 'align.com' file in '{0}' folder. JIP has probably failed: "
            "'{1}'".format(outdir, " ".join(cmd)))

    # Get the apply nonlinear deformation jip batches
    aplly_nonlin_batch = os.path.join(
        os.path.dirname(preproc.__file__), "resources", "apply_nonlin.com")
    aplly_inv_nonlin_batch = os.path.join(
        os.path.dirname(preproc.__file__), "resources", "apply_inv_nonlin.com")

    # Resample the source image
    register_file = os.path.join(outdir, prefix + os.path.basename(source_file))
    cmd = ["jip", aplly_nonlin_batch, source_file, register_file]
    subprocess.call(cmd, env=jip_envriron)

    # Apply mask
    if os.path.isfile(register_file + ".gz"):
        os.remove(register_file + ".gz")
    register_mask_fileroot = os.path.join(
        outdir, "m" + prefix + os.path.basename(source_file).split(".")[0])
    register_mask_file = apply_mask(
        input_file=register_file,
        output_fileroot=register_mask_fileroot,
        mask_file=target_file,
        fslconfig=fslconfig)

    # Send back masked image to original space
    register_mask_file = ungzip_file(register_mask_file, prefix="",
                                     outdir=outdir)
    native_masked_file = os.path.join(
        outdir, "n" + prefix + os.path.basename(register_mask_file))
    cmd = ["jip", aplly_inv_nonlin_batch, register_mask_file,
           native_masked_file]
    subprocess.call(cmd, env=jip_envriron)              

    # Restore current working directory and gzip output
    os.chdir(cwd)
    register_file = gzip_file(
        register_file, prefix="", outdir=outdir,
        remove_original_file=True)
    register_mask_file = gzip_file(
        register_mask_file, prefix="", outdir=outdir,
        remove_original_file=True)
    native_masked_file = gzip_file(
        native_masked_file, prefix="", outdir=outdir,
        remove_original_file=True)

    return register_file, register_mask_file, native_masked_file, align_file
Esempio n. 5
0
def spatial_normalization(settings,
                          mod='T1w',
                          name='SpatialNormalization',
                          resolution=2.0):
    """
    A simple workflow to perform spatial normalization

    """
    from mriqc.interfaces.common import EnsureSize
    from nipype.interfaces.ants import AffineInitializer
    from niworkflows.data import getters as niwgetters

    # Have some settings handy
    tpl_id = settings.get('template_id', 'mni_icbm152_nlin_asym_09c')
    mni_template = getattr(niwgetters, 'get_{}'.format(tpl_id))()

    # Define workflow interface
    workflow = pe.Workflow(name=name)
    inputnode = pe.Node(
        niu.IdentityInterface(fields=['moving_image', 'moving_mask']),
        name='inputnode')
    outputnode = pe.Node(niu.IdentityInterface(
        fields=['inverse_composite_transform', 'out_report']),
                         name='outputnode')

    # Mask inputs for initialization
    mmask = pe.Node(fsl.ApplyMask(), name='MovingApplyMask')
    fmask = pe.Node(fsl.ApplyMask(), name='FixedApplyMask')
    fmask.inputs.in_file = op.join(
        mni_template, '%dmm_%s.nii.gz' % (int(resolution), mod[:2]))
    fmask.inputs.mask_file = op.join(mni_template,
                                     '%dmm_brainmask.nii.gz' % int(resolution))

    # Ensure resolution
    resample = pe.Node(EnsureSize(pixel_size=resolution), 'EnsureSize')

    # Initializer
    init = pe.Node(
        AffineInitializer(num_threads=settings.get('ants_nthreads')),
        name='NormalizationInit')

    # Spatial normalization
    norm = pe.Node(
        RobustMNINormalization(
            flavor='testing' if settings.get('testing', False) else 'fast',
            num_threads=settings.get('ants_nthreads'),
            template=tpl_id,
            template_resolution=2,
            reference=mod[:2],
            generate_report=True,
        ),
        name='SpatialNormalization',
        # Request all MultiProc processes when ants_nthreads > n_procs
        num_threads=min(
            settings.get('ants_nthreads', DEFAULTS['ants_nthreads']),
            settings.get('n_procs', 1)),
        estimated_memory_gb=3)

    workflow.connect([
        (inputnode, resample, [('moving_image', 'in_file'),
                               ('moving_mask', 'in_mask')]),
        (resample, mmask, [('out_file', 'in_file'),
                           ('out_mask', 'mask_file')]),
        (mmask, init, [('out_file', 'moving_image')]),
        (fmask, init, [('out_file', 'fixed_image')]),
        (init, norm, [('out_file', 'initial_moving_transform')]),
        (resample, norm, [('out_file', 'moving_image'),
                          ('out_mask', 'moving_mask')]),
        (norm, outputnode, [('inverse_composite_transform',
                             'inverse_composite_transform'),
                            ('out_report', 'out_report')]),
    ])
    return workflow