Ejemplo n.º 1
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)
Ejemplo n.º 2
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)
Ejemplo n.º 3
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)
Ejemplo n.º 4
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")
    processed_dir = os.path.join(output_dir, pipeline_name + "_processed")
    imgs = get_imgs(options.application)

    s = Stages()

    # TODO this is quite tedious and duplicates stuff in the registration chain ...
    resolution = (options.registration.resolution or
                  get_resolution_from_file(
                      s.defer(registration_targets(lsq6_conf=options.lsq6,
                                                   app_conf=options.application,
                                                   reg_conf=options.registration)).registration_standard.path))

    # 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]))
    # 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)
Ejemplo n.º 5
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 = get_imgs(options.application)

    # 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,
                                                              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))
def stage_embryos_pipeline(options):
    s = Stages()

    imgs = get_imgs(options.application)
    rough_volume_imgs = get_volume_estimate(imgs)
    imgs_and_rough_volume = pd.DataFrame({"mincatom" : imgs,
                                          "rough_volume" : pd.Series(rough_volume_imgs, dtype=float)})

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

    output_directory = options.application.output_directory
    output_sub_dir = os.path.join(output_directory,
                                  options.application.pipeline_name + "_4D_atlas")

    time_points_in_4D_atlas = instances_in_4D_atlas_from_csv(options.staging.staging.csv_4D,
                                                             output_sub_dir)

    # we can use the resolution of one of the time points in the 4D atlas
    # for all the registrations that will be run.
    resolution = get_resolution_from_file(time_points_in_4D_atlas.loc[0]["mincatom"].orig_path)

    print(options.staging.lsq12)

    lsq12_conf = get_linear_configuration_from_options(options.staging.lsq12,
                                                       transform_type=LinearTransType.lsq12,
                                                       file_resolution=resolution)

    nlin_component = get_nonlinear_component(options.staging.nlin.reg_method)

    # match each of the embryos individually
    for i in range(imgs_and_rough_volume.shape[0]):
        s.defer(match_embryo_to_4D_atlas(imgs_and_rough_volume.loc[i],
                                         time_points_in_4D_atlas,
                                         lsq6_conf=options.staging.lsq6,
                                         lsq12_conf=lsq12_conf,
                                         nlin_module=nlin_component,
                                         resolution=resolution,
                                         nlin_options=options.staging.nlin))


    return Result(stages=s, output=None)
Ejemplo n.º 7
0
def mbm_pipeline(options: MBMConf):
    s = Stages()

    imgs = get_imgs(options.application)

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

    output_dir = options.application.output_directory

    mbm_result = s.defer(
        mbm(imgs=imgs,
            options=options,
            prefix=options.application.pipeline_name,
            output_dir=output_dir))

    if options.mbm.common_space.do_common_space_registration:
        s.defer(common_space(mbm_result, options))

    # create useful CSVs (note the files listed therein won't yet exist ...):

    transforms = (mbm_result.xfms.assign(
        native_file=lambda df: df.rigid_xfm.apply(lambda x: x.source),
        lsq6_file=lambda df: df.lsq12_nlin_xfm.apply(lambda x: x.source),
        lsq6_mask_file=lambda df: df.lsq12_nlin_xfm.apply(
            lambda x: x.source.mask if x.source.mask else ""),
        nlin_file=lambda df: df.lsq12_nlin_xfm.apply(lambda x: x.resampled),
        nlin_mask_file=lambda df: df.lsq12_nlin_xfm.apply(
            lambda x: x.resampled.mask if x.resampled.mask else ""),
        common_space_file=lambda df: df.xfm_to_common.apply(lambda x: x.
                                                            resampled)
        if options.mbm.common_space.do_common_space_registration else None
    ).applymap(maybe_deref_path).drop(
        ["common_space_file"]
        if not options.mbm.common_space.do_common_space_registration else [],
        axis=1))
    transforms.to_csv("transforms.csv", index=False)

    determinants = (mbm_result.determinants.drop(
        ["full_det", "nlin_det"], axis=1).applymap(maybe_deref_path))
    determinants.to_csv("determinants.csv", index=False)

    analysis = (transforms.merge(determinants,
                                 left_on="lsq12_nlin_xfm",
                                 right_on="inv_xfm",
                                 how='inner').drop(["xfm", "inv_xfm"], axis=1))
    if options.mbm.segmentation.run_maget:
        maget_df = pd.DataFrame(
            data={
                'label_file':
                [result.labels.path for result in mbm_result.maget_result],
                'native_file':
                [result.orig_path for result in mbm_result.maget_result]
            })
        analysis = analysis.merge(maget_df, on="native_file")

    if options.application.files:
        analysis.to_csv("analysis.csv", index=False)
    elif options.application.csv_file:
        csv_file = (
            pd.read_csv(options.application.csv_file).assign(
                native_file=lambda df: df.file.apply(
                    # TODO this is duplicating the logic in get_imgs - fix
                    lambda fp: os.path.join(
                        os.path.dirname(options.application.csv_file), fp)
                    if not options.application.csv_paths_relative_to_wd else fp
                ).apply(os.path.normpath)))
        csv_file.merge(analysis, on="native_file").to_csv("analysis.csv",
                                                          index=False)

    # # TODO moved here from inside `mbm` for now ... does this make most sense?
    # if options.mbm.segmentation.run_maget:
    #     import copy
    #     maget_options = copy.deepcopy(options)  #Namespace(maget=options)
    #     #maget_options
    #     #maget_options.maget = maget_options.mbm
    #     #maget_options.execution = options.execution
    #     #maget_options.application = options.application
    #     maget_options.application.output_directory = os.path.join(options.application.output_directory, "segmentation")
    #     maget_options.maget = options.mbm.maget
    #
    #     fixup_maget_options(maget_options=maget_options.maget,
    #                         nlin_options=maget_options.mbm.nlin,
    #                         lsq12_options=maget_options.mbm.lsq12)
    #     del maget_options.mbm
    #
    #
    #     #def with_new_output_dir(img : MincAtom):
    #         #img = copy.copy(img)
    #         #img.pipeline_sub_dir = img.pipeline_sub_dir + img.output_dir
    #         #img.
    #         #return img.newname_with_suffix(suffix="", subdir="segmentation")
    #
    #     s.defer(maget([xfm.resampled for _ix, xfm in mbm_result.xfms.rigid_xfm.iteritems()],
    #                    options=maget_options,
    #                    prefix="%s_MAGeT" % prefix,
    #                    output_dir=os.path.join(options.application.output_directory, prefix + "_processed")))

    return Result(stages=s, output=mbm_result)
Ejemplo n.º 8
0
def NLIN_pipeline(options):

    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 = get_imgs(options.application)

    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)

    nlin_module = get_nonlinear_component(reg_method=options.nlin.reg_method)

    nlin_build_model_component = get_model_building_procedure(
        options.nlin.reg_strategy, reg_module=nlin_module)

    nlin_conf = (nlin_build_model_component.parse_build_model_protocol(
        options.nlin.nlin_protocol, resolution=resolution)
                 if options.nlin.nlin_protocol is not None else
                 nlin_build_model_component.get_default_build_model_conf(
                     resolution=resolution))

    s = Stages()

    nlin_result = s.defer(
        nlin_build_model_component.build_model(
            imgs=imgs,
            initial_target=initial_target,
            conf=nlin_conf,
            nlin_dir=nlin_dir,
            use_robust_averaging=options.nlin.use_robust_averaging,
            nlin_prefix=""))

    inverted_xfms = [
        s.defer(invert_xfmhandler(xfm)) for xfm in nlin_result.output
    ]

    if options.stats.calc_stats:

        determinants = s.defer(
            determinants_at_fwhms(xfms=inverted_xfms,
                                  inv_xfms=nlin_result.output,
                                  blur_fwhms=options.stats.stats_kernels))

        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))