Esempio n. 1
0
    def blur(img, fwhm, gradient=True, subdir='tmp'):
        # note c3d can take voxel rather than fwhm specification, but the Algorithms interface
        # currently doesn't allow this to be used ... maybe an argument from switching from mincblur
        if fwhm in (-1, 0, None):
            if gradient:
                raise ValueError(
                    "can't compute gradient without a positive FWHM")
            return Result(stages=Stages(), output=Namespace(img=img))

        if gradient:
            out_gradient = img.newname_with("_blur%s_grad" % fwhm)
        else:
            out_gradient = None

        out_img = img.newname_with("_blurred%s" % fwhm)

        cmd = CmdStage(cmd=[
            'c3d', '-smooth',
            "%smm" % fwhm, '-o', out_img.path, img.path
        ] + (['-gradient', '-o', out_gradient.path] if gradient else []),
                       inputs=(img),
                       outputs=(out_img, out_gradient) if gradient else
                       (out_img, ))
        return Result(stages=Stages((cmd, )),
                      output=Namespace(img=out_img, gradient=out_gradient)
                      if gradient else Namespace(img=out_img))
Esempio n. 2
0
def itk_convert_xfm(xfm: ITKXfmAtom, out_ext: str) -> Result[ITKXfmAtom]:
    if xfm.ext == out_ext:
        return Result(stages=Stages(), output=xfm)
    else:
        out_xfm = xfm.newext(out_ext)
        cmd = CmdStage(
            inputs=(xfm, ),
            outputs=(out_xfm, ),
            cmd=["itk_convert_xfm", "--clobber", xfm.path, out_xfm.path])
        return Result(stages=Stages((cmd, )), output=out_xfm)
def deep_segment(
    image: FileAtom,
    deep_segment_pipeline: FileAtom,
    anatomical_suffix: str,
    count_suffix: str,
    outline_suffix: str = None,
    cell_min_area: int = None,
    cell_mean_area: float = None,
    cell_max_area: int = None,
    temp_dir: str = None,
):
    anatomical = image.newname_with_suffix("_" + anatomical_suffix)
    count = image.newname_with_suffix("_" + count_suffix)
    outline = image.newname_with_suffix(
        "_" + outline_suffix) if outline_suffix else None
    stage = CmdStage(inputs=(image, deep_segment_pipeline),
                     outputs=(anatomical, count),
                     cmd=['deep_segment.py',
                          '--segment-intensity 1',
                          '--temp-dir %s' % temp_dir if temp_dir else "",
                          '--learner %s' % deep_segment_pipeline.path,
                          '--image %s' % image.path,
                          '--image-output %s' % anatomical.path,
                          '--centroids-output %s' % count.path,
                          '--outlines-output %s' % outline.path if outline_suffix else ""
                          '--cell-min-area %s' % cell_min_area if cell_min_area else "",
                          '--process-clusters --cell-mean-area %s --cell-max-area %s' % (cell_mean_area, cell_max_area)\
                              if (cell_mean_area and cell_max_area) else ""
                          ])
    return Result(stages=Stages([stage]), output=(anatomical, count, outline))
def antsRegistration(fixed: MincAtom,
                     moving: MincAtom,
                     transform: XfmAtom,
                     output_dir: str,
                     warped: str = "Warped.nii.gz",
                     inversewarped: str = "InverseWarped.nii.gz",
                     dimensionality: int = 3):
    #TODO warped and inversewarped output to the working directory
    stage = CmdStage(
        inputs=(fixed, moving),
        outputs=(transform, ),
        cmd=[
            'antsRegistration',
            '--verbose 1',
            '--float 0',
            '--minc',
            '--dimensionality %s' % dimensionality,
            '--output [%s,%s,%s]' % (transform.path.replace(
                '0_GenericAffine.xfm', ''), warped, inversewarped),
            '--interpolation Linear',
            '--use-histogram-matching 0',
            '--winsorize-image-intensities [0.01,0.99]',
            '--initial-moving-transform [%s,%s,1]' %
            (fixed.path, moving.path),  #1 indicates center of mass
            '--transform Translation[0.1]',
            '--metric MI[%s,%s,1,32,Regular,0.25]' % (fixed.path, moving.path),
            '--convergence [1000x500x250x0,1e-6,10]',
            '--shrink-factors 12x8x4x2',
            '--smoothing-sigmas 4x3x2x1vox'
        ],
        log_file=os.path.join(output_dir, "join_sections.log"))

    return Result(stages=Stages([stage]), output=(transform))
def tamarack_pipeline(options):

    output_dir = options.application.output_directory
    pipeline_name = options.application.pipeline_name
    #processed_dir = os.path.join(output_dir, pipeline_name + "_processed")
    first_level_dir = os.path.join(output_dir, pipeline_name + "_first_level")

    s = Stages()

    with open(options.application.csv_file, 'r') as f:
        files_df = (pd.read_csv(
            filepath_or_buffer=f,
            usecols=['group', 'filename']).assign(file=lambda df: df.apply(
                axis="columns",
                func=lambda r: MincAtom(r.filename.strip(),
                                        pipeline_sub_dir=os.path.join(
                                            first_level_dir, "%s_processed" % r
                                            .group.strip())))))

    check_MINC_input_files(files_df.file.apply(lambda img: img.path))

    #grouped_files_df = pd.DataFrame({'file' : pd.concat([imgs])}).assign(group=lambda df: df.index)

    tamarack_result = s.defer(tamarack(files_df, options=options))

    tamarack_result.first_level_results.applymap(maybe_deref_path).to_csv(
        "first_level_results.csv", index=False)
    tamarack_result.resampled_determinants.applymap(maybe_deref_path).to_csv(
        "resampled_determinants.csv", index=False)
    tamarack_result.overall_determinants.applymap(maybe_deref_path).to_csv(
        "overall_determinants.csv", index=False)

    return Result(stages=s, output=tamarack_result)
    def f(
        imgs: List[MincAtom],
        nlin_dir: str,
        conf: nlin_module.MultilevelConf,
        initial_target: MincAtom,
        nlin_prefix: str,
        #output_dir_for_avg: str = None,
        #output_name_wo_ext: str = None
    ):
        s = Stages()

        pairwise_result = s.defer(
            pairwise(nlin_module, max_images=25, max_pairs=None).build_model(
                imgs=imgs,
                nlin_dir=nlin_dir,
                conf=nlin_module.hierarchical_to_single(conf)[-1]
                if conf else None,
                initial_target=initial_target,
                nlin_prefix=nlin_prefix
                #, output_name_wo_ext=output_name_wo_ext  #, algorithms=nlin_module.algorithms
            ))

        build_model_result = s.defer(
            build_model(nlin_module).build_model(
                imgs=imgs,
                nlin_dir=nlin_dir,
                conf=conf,
                initial_target=pairwise_result.avg_img,
                nlin_prefix=nlin_prefix
                #, output_name_wo_ext=output_name_wo_ext  #, algorithms=algorithms
            ))

        return Result(stages=s, output=build_model_result)
        def build_model(imgs,
                        conf,
                        nlin_dir,
                        nlin_prefix,
                        initial_target,
                        output_name_wo_ext = None):
            s = Stages()
            mincify = base_build_model.ToMinc
            imgs = tuple(s.defer(mincify.from_mnc(img)) for img in imgs)
            result = s.defer(base_build_model.build_model(imgs=imgs, conf=conf,
                                                  nlin_dir=nlin_dir, nlin_prefix=nlin_prefix,
                                                  initial_target=s.defer(mincify.from_mnc(initial_target))
                                                  #output_name_wo_ext=output_name_wo_ext
                                                  ))

            def wrap_output_xfmh(xfmh):
                return XfmHandler(source=s.defer(mincify.to_mnc(xfmh.source)) if xfmh.source else None,
                                  target=s.defer(mincify.to_mnc(xfmh.target)) if xfmh.target else None,
                                  resampled=s.defer(mincify.to_mnc(xfmh.resampled)) if xfmh.has_resampled() else None,
                                  xfm=s.defer(mincify.to_mni_xfm(xfmh.xfm)),
                                  inverse=wrap_output_xfmh(xfmh.inverse) if xfmh.has_inverse() else None)

            return Result(stages=s, output=WithAvgImgs(avg_imgs=[s.defer(mincify.to_mnc(img))
                                                                 for img in result.avg_imgs],
                                                       avg_img=s.defer(mincify.to_mnc(result.avg_img)),
                                                       output=[wrap_output_xfmh(x)
                                                               for x in result.output]))
Esempio n. 8
0
def det_and_log_det(
    displacement_grid: MincAtom,
    fwhm: Optional[float],
    annotation: str = ""
) -> Result[Namespace]:  # (det=MincAtom, log_det=MincAtom)]:
    """
    When this function is called, you might (or should) know what kind of
    deformation grid is passed along. This allows you to provide a proper
    annotation for the produced log determinant file. For instance "absolute"
    or "relative" for transformations that include an affine linear part, or
    that have the linear part taken out respectively.
    """
    s = Stages()
    # TODO: naming doesn't correspond with the (automagic) file naming: d-1 <=> det(f), det <=> det+1(f)
    det = s.defer(
        determinant(
            s.defer(smooth_vector(source=displacement_grid, fwhm=fwhm)
                    ) if fwhm else displacement_grid))

    output_filename_wo_ext = displacement_grid.filename_wo_ext + "_log_det" + annotation
    if fwhm:
        output_filename_wo_ext += "_fwhm" + str(fwhm)
    log_det = s.defer(
        mincmath(op='log',
                 vols=[det],
                 subdir="stats-volumes",
                 new_name=output_filename_wo_ext))
    return Result(stages=s, output=Namespace(det=det, log_det=log_det))
Esempio n. 9
0
def asymmetry_pipeline(options):

    output_dir = options.application.output_directory
    pipeline_name = options.application.pipeline_name
    processed_dir = os.path.join(output_dir, pipeline_name + "_processed")

    s = Stages()

    #imgs_ = [MincAtom(f, pipeline_sub_dir=processed_dir) for f in options.application.files]

    imgs_ = get_imgs(options.application)

    check_MINC_input_files([img.path for img in imgs_])

    imgs = pd.Series(imgs_, index=[img.filename_wo_ext for img in imgs_])
    flipped_imgs = imgs.apply(lambda img: s.defer(volflip(img))
                              )  # TODO add flags to control flip axis ...

    # TODO ugly - MincAtom API should allow this somehow without mutation (also, how to pass into `volflip`, etc.?)
    for f_i in flipped_imgs:
        f_i.output_sub_dir += "_flipped"

    check_MINC_input_files(imgs.apply(lambda img: img.path))

    grouped_files_df = pd.DataFrame({
        'file': pd.concat([imgs, flipped_imgs])
    }).assign(group=lambda df: df.index)

    two_level_result = s.defer(two_level(grouped_files_df, options=options))

    return Result(stages=s, output=two_level_result)
def shift_modify_header(img: MincAtom,
                        shifted_img: MincAtom,
                        newx: float,
                        newy: float,
                        newz: float):
    s = Stages()
    #Copy file to new location
    stage = CmdStage(inputs=(img,), outputs=(shifted_img,), memory=1,
                     cmd=['cp', img.path, shifted_img.path])
    print(stage.render())
    s.add(stage)
    #Alter header of copied image to shift
    xspace_start = 'xspace:start='+newx
    yspace_start = 'yspace:start='+newy
    zspace_start = 'zspace:start='+newz
    stage = CmdStage(inputs=(shifted_img,), outputs=(shifted_img,), memory=1,
                     cmd=['minc_modify_header','-dinsert',xspace_start,
                          '-dinsert',yspace_start,
                          '-dinsert',zspace_start,
                          shifted_img.path])
    print(stage.render())
    s.add(stage)
    #Alter header of copied image with header modification
    append_history_string = ':history= >>> copy and shift: '+ shifted_img.path +' to '+ shifted_img.path
    stage = CmdStage(inputs=(shifted_img,), outputs=(shifted_img,), memory=1,
                     cmd=['minc_modify_header','-sappend',
                          append_history_string,
                          shifted_img.path])
    print(stage.render())
    s.add(stage)
    return Result(stages=s, output=shifted_img)
Esempio n. 11
0
def lsq6_pipeline(options):
    # TODO could also allow pluggable pipeline parts e.g. LSQ6 could be substituted out for the modified LSQ6
    # for the kidney tips, etc...
    output_dir = options.application.output_directory
    pipeline_name = options.application.pipeline_name

    # TODO this is tedious and annoyingly similar to the registration chain and MBM ...
    lsq6_dir = os.path.join(output_dir, pipeline_name + "_lsq6")
    imgs = get_imgs(options.application)

    s = Stages()

    # FIXME: why do we have to call registration_targets *outside* of lsq6_nuc_inorm? is it just because of the extra
    # options required?
    targets = s.defer(
        registration_targets(lsq6_conf=options.lsq6,
                             app_conf=options.application,
                             reg_conf=options.registration,
                             first_input_file=imgs[0].path))

    # TODO this is quite tedious and duplicates stuff in the registration chain ...
    resolution = (options.registration.resolution or get_resolution_from_file(
        targets.registration_standard.path))

    # This must happen after calling registration_targets otherwise it will resample to options.registration.resolution
    options.registration = options.registration.replace(resolution=resolution)
    lsq6_result = s.defer(
        lsq6_nuc_inorm(imgs=imgs,
                       resolution=resolution,
                       registration_targets=targets,
                       lsq6_dir=lsq6_dir,
                       lsq6_options=options.lsq6))

    return Result(stages=s, output=lsq6_result)
Esempio n. 12
0
def nlin_part(xfm: XfmHandler,
              inv_xfm: Optional[XfmHandler] = None) -> Result[XfmHandler]:
    """
    *** = non linear deformations
    --- = linear (affine) deformations

    Input:
    xfm     :     ******------>
    inv_xfm :    <******------ (optional)

    Calculated:
    inv_lin_xfm :      <------

    Returned:
    concat :      ******------> +
                       <------
    equals :      ******>

    Compute the nonlinear part of a transform as follows:
    go forwards across xfm and then backwards across the linear part
    of the inverse xfm (by first calculating the inverse or using the one supplied) 
    Finally, use minc_displacement to compute the resulting gridfile of the purely 
    nonlinear part.

    The optional inv_xfm (which must be the inverse!) is an optimization -
    we don't go looking for an inverse by filename munging and don't programmatically
    keep a log of operations applied, so any preexisting inverse must be supplied explicitly.
    """
    s = Stages()
    inv_xfm = inv_xfm or s.defer(invert_xfmhandler(xfm))
    inv_lin_part = s.defer(lin_from_nlin(inv_xfm))
    xfm = s.defer(concat_xfmhandlers([xfm, inv_lin_part]))
    return Result(stages=s, output=xfm)
Esempio n. 13
0
def as_deformation(xfm):
    c = CmdStage(cmd=[
        "transformix", "-def", "all", "-out", dirname, "-tp", xfm.path, "-xfm",
        out_path
    ],
                 inputs=(xfm, ),
                 outputs=NotImplemented)
    return Result(stages=Stages([c]), output=NotImplemented)
Esempio n. 14
0
 def scale_transform(xfm, scale, newname_wo_ext):
     scaled_xfm = xfm.newname_with_suffix("_scaled%s" % scale)
     c = CmdStage(
         cmd=["dramms-defop", "-m",
              str(scale), xfm.path, scaled_xfm.path],
         inputs=(xfm, ),
         outputs=(scaled_xfm, ))
     return Result(stages=Stages([c]), output=scaled_xfm)
Esempio n. 15
0
def determinant(displacement_grid: MincAtom) -> Result[MincAtom]:
    """
    Takes a displacement field (deformation grid, vector field, those are
    all the same thing) and calculates the proper determinant (mincblob()
    takes care of adding 1 to the silly output of running mincblob directly)
    """
    s = Stages()
    det = s.defer(mincblob(op='determinant', grid=displacement_grid))
    return Result(stages=s, output=det)
Esempio n. 16
0
def smooth_vector(source: MincAtom, fwhm: float) -> Result[MincAtom]:
    outf = source.newname_with_suffix(
        "_smooth_fwhm%s" % fwhm, subdir="tmp")  # TODO smooth_displacement_?
    cmd = [
        'smooth_vector', '--clobber', '--filter',
        '--fwhm=%s' % fwhm, source.path, outf.path
    ]
    stage = CmdStage(inputs=(source, ), outputs=(outf, ), cmd=cmd)
    return Result(stages=Stages([stage]), output=outf)
Esempio n. 17
0
def surface_mask2(input: MincAtom,
                  surface: FileAtom,
                  args: List[str] = []) -> Result[MincAtom]:
    mask_vol = surface.newname_with_suffix("_mask", ext=".mnc")
    stage = CmdStage(inputs=(input, surface),
                     outputs=(mask_vol, ),
                     cmd=["surface_mask2", "-clobber"] + args +
                     [input.path, surface.path, mask_vol.path])
    return Result(stages=Stages([stage]), output=mask_vol)
Esempio n. 18
0
def dramms_warp(
        img: NiiAtom,  # TODO change to ITKAtom ?!
        xfm: XfmAtom,  # TODO: update to handler?
        like: NiiAtom,
        invert: bool = False,
        use_nn_interpolation=None,
        new_name_wo_ext: str = None,
        subdir: str = None,
        postfix: str = None) -> Result[NiiAtom]:

    s = Stages()

    if not subdir:
        subdir = 'resampled'

    # we need to get the filename without extension here in case we have
    # masks/labels associated with the input file. When that's the case,
    # we supply its name with "_mask" and "_labels" for which we need
    # to know what the main file will be resampled as
    if not new_name_wo_ext:
        # FIXME this is wrong when invert=True
        new_name_wo_ext = xfm.filename_wo_ext + '-resampled'

    new_img = s.defer(
        dramms_warp_simple(
            img=img,
            xfm=xfm,
            like=like,
            #extra_flags=extra_flags,
            invert=invert,
            #interpolation=interpolation,
            use_nn_interpolation=use_nn_interpolation,
            new_name_wo_ext=new_name_wo_ext,
            subdir=subdir))
    new_img.mask = s.defer(
        dramms_warp_simple(img=img.mask,
                           xfm=xfm,
                           like=like,
                           use_nn_interpolation=True,
                           invert=invert,
                           new_name_wo_ext=new_name_wo_ext + "_mask",
                           subdir=subdir)) if img.mask is not None else None
    new_img.labels = s.defer(
        dramms_warp_simple(img=img.labels,
                           xfm=xfm,
                           like=like,
                           use_nn_interpolation=True,
                           invert=invert,
                           new_name_wo_ext=new_name_wo_ext + "_labels",
                           subdir=subdir)) if img.labels is not None else None

    # Note that new_img can't be used for anything until the mask/label files are also resampled.
    # This shouldn't create a problem with stage dependencies as long as masks/labels appear in inputs/outputs of CmdStages.
    # (If this isn't automatic, a relevant helper function would be trivial.)
    # TODO: can/should this be done semi-automatically? probably ...
    return Result(stages=s, output=new_img)
Esempio n. 19
0
    def register(
            source: MincAtom,
            target: MincAtom,
            conf: Conf,
            initial_source_transform: Optional[XfmAtom] = None,
            transform_name_wo_ext: str = None,
            generation: int = None,  # not used; remove from API (fix ANTS)
            resample_source: bool = False,
            resample_subdir: str = "resampled") -> Result[XfmHandler]:
        if conf is None:
            raise ValueError("no configuration supplied")

        out_dir = os.path.join(
            source.pipeline_sub_dir, source.output_sub_dir,
            "%s_elastix_to_%s" %
            (source.filename_wo_ext, target.filename_wo_ext))

        # elastix chooses this for us:
        out_img = NiiAtom(
            name=os.path.join(out_dir, "result.%d.mnc" %
                              0),  # TODO number of param files ?!?!
            pipeline_sub_dir=source.pipeline_sub_dir,
            output_sub_dir=source.output_sub_dir)
        #out_xfm = XfmAtom(name = "%s_elastix_to_%s.xfm" % (source.filename_wo_ext, target.filename_wo_ext),
        #                  pipeline_sub_dir=source.pipeline_sub_dir, output_sub_dir=source.output_sub_dir)
        out_xfm = XfmAtom(
            name=os.path.join(out_dir, "TransformParameters.%d.txt" %
                              0),  # TODO number of param files ?!?!
            pipeline_sub_dir=source.pipeline_sub_dir,
            output_sub_dir=source.output_sub_dir)
        cmd = (['elastix', '-f', source.path, '-m', target.path] +
               (flatten(*[["-p", x] for x in conf])) +
               (["-fMask", source.mask.path] if source.mask else []) +
               (["-mMask", target.mask.path] if target.mask else []) +
               (["-t0", initial_source_transform.path]
                if initial_source_transform else []) + (["-out", out_dir]))
        s = CmdStage(cmd=cmd,
                     inputs=(source, target) +
                     ((source.mask, ) if source.mask else
                      ()) + ((target.mask, ) if target.mask else ()),
                     outputs=(out_xfm, out_img))

        #s2 = CmdStage(cmd=['transformix', '-out', os.path.join(resample_subdir, "%s" % c),
        #                   "-tp", out_xfm, "-in", out_name],
        #              inputs=(), outputs=())

        xfm = XfmHandler(source=source,
                         target=target,
                         xfm=out_xfm,
                         resampled=out_img)
        return Result(stages=Stages([s]), output=xfm)


# one question is whether we should have separate NLIN/LSQ12/LSQ6 interfaces or not, given that these differences seem
# like they should be rather irrelevant to general registration procedures ... at present minctracc
# is the main difficulty, since it uses different
Esempio n. 20
0
def transform_objects(
        input_obj: FileAtom,
        xfm: XfmAtom) -> Result[FileAtom]:  # XfmAtom -> XfmHandler??
    output_obj = input_obj.newname_with_suffix("_resampled_via_%s" %
                                               xfm.filename_wo_ext)
    stage = CmdStage(
        inputs=(input_obj, xfm),
        outputs=(output_obj, ),
        cmd=["transform_objects", input_obj.path, xfm.path, output_obj.path])
    return Result(stages=Stages([stage]), output=output_obj)
Esempio n. 21
0
def dramms_invert(defs: DrammsXfmAtom,
                  out_defs: Optional[DrammsXfmAtom] = None):
    out_defs = out_defs or defs.newname_with_suffix("_inverted")

    return Result(stages=Stages([
        CmdStage(cmd=['dramms-defop', '-i', defs.path, out_defs.path],
                 inputs=(defs, ),
                 outputs=(out_defs, ))
    ]),
                  output=out_defs)
def mincmath(imgs: List[MincAtom], result: MincAtom, output_dir: str):
    stage = CmdStage(inputs=tuple(imgs),
                     outputs=(result, ),
                     cmd=[
                         'mincmath', '-clobber', '-add',
                         ' '.join(img.path for img in imgs.__iter__()),
                         result.path
                     ],
                     log_file=os.path.join(output_dir, "join_sections.log"))
    return Result(stages=Stages([stage]), output=result)
def concat_xfm(xfms: List[XfmAtom], outxfm: XfmAtom, output_dir: str):
    stage = CmdStage(inputs=tuple(xfms),
                     outputs=(outxfm, ),
                     cmd=[
                         'xfmconcat', '-clobber',
                         ' '.join(xfm.path for xfm in xfms.__iter__()),
                         outxfm.path
                     ],
                     log_file=os.path.join(output_dir, "join_sections.log"))
    return Result(stages=Stages([stage]), output=(outxfm))
Esempio n. 24
0
def reconstitute_laplacian_grid(cortex: MincAtom, grid: MincAtom,
                                midline: MincAtom) -> Result[MincAtom]:
    output_grid = grid.newname_with_suffix("_reconstituted")
    stage = CmdStage(inputs=(cortex, grid, midline),
                     outputs=(output_grid, ),
                     cmd=[
                         "reconstitute_laplacian_grid", midline.path,
                         cortex.path, grid.path, output_grid.path
                     ])
    return Result(stages=Stages([stage]), output=output_grid)
Esempio n. 25
0
 def average_transforms(xfms, avg_xfm):
     s = Stages()
     itk_xfms = copy.deepcopy(xfms)
     for xfm in itk_xfms:
         xfm.xfm = s.defer(dramms_to_itk(xfm.xfm))
     return Result(stages=s,
                   output=s.defer(
                       itk_to_dramms(
                           s.defer(
                               itk.Algorithms.average_transforms(
                                   itk_xfms, avg_xfm)))))
def dist_corr_basket(img: MincAtom,
                     dc_img: MincAtom):

    stage = CmdStage(inputs=(img,), outputs=(dc_img,), memory=4,
                     cmd=['distortion_correction_september_2014.pl',
                          '-spawn','-output-dir', img.pipeline_sub_dir,
                          img.path])
    print(stage.render())
    stage.set_log_file(log_file_name=os.path.join(img.pipeline_sub_dir,"dist_corr.log"))

    return Result(stages=Stages([stage]), output=dc_img)
Esempio n. 27
0
def dramms_combine(t1: DrammsXfmAtom,
                   t2: DrammsXfmAtom,
                   name: Optional[str] = None):
    # TODO this is a hack ... implement more sane naming (factor from xfmconcat?)
    out_xfm = t1.newname(name="concat_of_%s_and_%s" %
                         (t1.filename_wo_ext, t2.filename_wo_ext),
                         subdir="transforms")
    s = CmdStage(cmd=['dramms-combine', '-c', t1.path, t2.path, out_xfm.path],
                 inputs=(t1, t2),
                 outputs=(out_xfm))
    return Result(stages=Stages([s]), output=out_xfm)
Esempio n. 28
0
def itk_to_dramms(xfm: ITKXfmAtom) -> Result[DrammsXfmAtom]:
    out_xfm = xfm.newname_with_suffix("_dramms")
    return Result(stages=Stages([
        CmdStage(cmd=[
            'dramms-convert', '-f', 'ITK', '-i', xfm.path, '-F', 'DRAMMS',
            '-o', out_xfm.path
        ],
                 inputs=(xfm, ),
                 outputs=(out_xfm, ))
    ]),
                  output=out_xfm)
Esempio n. 29
0
def NLIN_pipeline(options):

    if options.application.files is None:
        raise ValueError("Please, some files! (or try '--help')")  # TODO make a util procedure for this

    output_dir    = options.application.output_directory
    pipeline_name = options.application.pipeline_name

    # TODO this is tedious and annoyingly similar to the registration chain and MBM and LSQ6 ...
    processed_dir = os.path.join(output_dir, pipeline_name + "_processed")
    nlin_dir      = os.path.join(output_dir, pipeline_name + "_nlin")

    resolution = (options.registration.resolution  # TODO does using the finest resolution here make sense?
                  or min([get_resolution_from_file(f) for f in options.application.files]))

    imgs = [MincAtom(f, pipeline_sub_dir=processed_dir) for f in options.application.files]

    # determine NLIN settings by overriding defaults with
    # any settings present in protocol file, if it exists
    # could add a hook to print a message announcing completion, output files,
    # add more stages here to make a CSV

    initial_target_mask = MincAtom(options.nlin.target_mask) if options.nlin.target_mask else None
    initial_target = MincAtom(options.nlin.target, mask=initial_target_mask)

    full_hierarchy = get_nonlinear_configuration_from_options(nlin_protocol=options.nlin.nlin_protocol,
                                                              flag_nlin_protocol=next(iter(options.nlin.flags_.nlin_protocol)),
                                                              reg_method=options.nlin.reg_method,
                                                              file_resolution=resolution)

    s = Stages()

    nlin_result = s.defer(nlin_build_model(imgs, initial_target=initial_target, conf=full_hierarchy, nlin_dir=nlin_dir))

    # TODO return these?
    inverted_xfms = [s.defer(invert_xfmhandler(xfm)) for xfm in nlin_result.output]

    if options.stats.calc_stats:
        # TODO: put the stats part behind a flag ...

        determinants = [s.defer(determinants_at_fwhms(
                                  xfm=inv_xfm,
                                  inv_xfm=xfm,
                                  blur_fwhms=options.stats.stats_kernels))
                        for xfm, inv_xfm in zip(nlin_result.output, inverted_xfms)]

        return Result(stages=s,
                      output=Namespace(nlin_xfms=nlin_result,
                                       avg_img=nlin_result.avg_img,
                                       determinants=determinants))
    else:
        # there's no consistency in what gets returned, yikes ...
        return Result(stages=s, output=Namespace(nlin_xfms=nlin_result, avg_img=nlin_result.avg_img))
Esempio n. 30
0
 def scale_transform(xfm, scale):
     scaled_xfm = xfm.newname_with_suffix("_scaled_%s" % scale)
     # don't actually evaluate the resulting vector field:
     s = CmdStage(cmd=[
         "echo",
         ('(Transform "WeightedCombinationTransform")\n'
          '(SubTransforms %s)\n'
          '(Scales %s)\n') % (xfm.path, scale)
     ],
                  inputs=(xfm, ),
                  outputs=(scaled_xfm, ))
     return Result(stages=Stages([s]), output=scaled_xfm)