def f(imgs: List[MincAtom], initial_target: MincAtom, conf: reg_module.Conf, nlin_dir: str, nlin_prefix: str, tournament_name_wo_ext: str = "tournament") -> Result[List[XfmHandler]]: s = Stages() Weight = int def h(xfms : List[XfmHandler], name_wo_ext : str) -> List[XfmHandler]: # TODO add weights to each return # TODO check len(...) == 0 case?? if len(xfms) <= 1: return xfms else: first_half = xfms[: len(xfms)//2] second_half = xfms[len(xfms)//2 :] first_half_result = h(first_half, name_wo_ext=name_wo_ext + "_L") second_half_result = h(second_half, name_wo_ext=name_wo_ext + "_R") A_halfway_to_B, B_halfway_to_A, avg_img = s.defer( nonlinear_midpoint_xfm( img_A = first_half_result[0].resampled, img_B = second_half_result[0].resampled, out_name_wo_ext=name_wo_ext, nlin_algorithm=reg_module, conf=conf, out_dir=nlin_dir)) xfms_to_midpoint = ([XfmHandler(source=xfm.source, target=avg_img, resampled=A_halfway_to_B.resampled, xfm=s.defer(xfmconcat([xfm.xfm, A_halfway_to_B.xfm], name="%s_%s" % (xfm.source.filename_wo_ext, name_wo_ext)))) for xfm in first_half_result] + [XfmHandler(source=xfm.source, target=avg_img, resampled=B_halfway_to_A.resampled, xfm=s.defer(xfmconcat([xfm.xfm, B_halfway_to_A.xfm], name="%s_%s" % (xfm.source.filename_wo_ext, name_wo_ext)))) for xfm in second_half_result]) return xfms_to_midpoint identity_xfm = s.defer(param2xfm(out_xfm=XfmAtom(pipeline_sub_dir=imgs[0].pipeline_sub_dir, output_sub_dir=imgs[0].output_sub_dir, name=os.path.join(imgs[0].pipeline_sub_dir, imgs[0].output_sub_dir, "id.xfm")))) initial_xfms = [XfmHandler(source=img, target=img, resampled=img, xfm=identity_xfm) for img in imgs] xfms_to_avg = h(initial_xfms, tournament_name_wo_ext) avg_img = xfms_to_avg[0].target return Result(stages=s, output=WithAvgImgs(avg_img=avg_img, avg_imgs=[avg_img], output=xfms_to_avg))
def scale_transform(xfm, scale, newname_wo_ext): s = Stages() defs = s.defer(as_deformation(transform=xfm.xfm, reference=xfm.source)) scaled_defs = (defs.xfm.newname(newname_wo_ext) if newname_wo_ext else defs.xfm.newname_with_suffix("_scaled_%s" % scale)) s.defer( CmdStage(cmd=[ 'c3d', '-scale', str(scale), defs.path, "-o", scaled_defs.path ], inputs=(defs, ), outputs=(scaled_defs, ))) return Result(stages=s, output=scaled_defs)
def to_mni_xfm(xfm): s = Stages() defs = xfm.newname_with_suffix("_defs", subdir="tmp") s.add( CmdStage(cmd=[ "transformix", "-def", "all", "-out", defs.dir, "-tp", xfm.path, "-xfm", os.path.join(defs.filename_wo_ext, defs.ext) ], inputs=(xfm, ), outputs=(defs, ))) out_xfm = s.defer(itk.itk_convert_xfm(defs, out_ext=".mnc")) return Result(stages=s, output=out_xfm)
def lin_from_nlin(xfm: XfmHandler) -> Result[XfmHandler]: # TODO add dir argument out_xfm = xfm.xfm.newname_with_suffix("_linear_part", subdir="tmp") stage = CmdStage( inputs=(xfm.source, xfm.xfm), outputs=(out_xfm, ), cmd=(['lin_from_nlin', '-clobber', '-lsq12'] + (['-mask', xfm.source.mask.path] if xfm.source.mask else []) + [xfm.target.path, xfm.xfm.path, out_xfm.path])) return Result(stages=Stages([stage]), output=XfmHandler(xfm=out_xfm, source=xfm.source, target=xfm.target))
def tv_slice_recon_pipeline(options): output_dir = options.application.output_directory pipeline_name = options.application.pipeline_name s = Stages() df = pd.read_csv(options.application.csv_file, dtype={ "brain_name": str, "brain_directory": str }) # transforms = (mbm_result.xfms.assign( # native_file=lambda df: df.rigid_xfm.apply(lambda x: x.source), df["mosaic_file"] = df.apply(lambda row: find_mosaic_file(row), axis=1) df["mosaic_dictionary"] = df.apply( lambda row: read_mosaic_file(row.mosaic_file), axis=1) df["number_of_slices"] = df.apply( lambda row: int(row.mosaic_dictionary["sections"]), axis=1) df["interslice_distance"] = df.apply( lambda row: float(row.mosaic_dictionary["sectionres"]) / 1000, axis=1) df["Zstart"] = df.apply(lambda row: 1 if isnan(row.Zstart) else row.Zstart, axis=1) df["Zend"] = df.apply(lambda row: row.number_of_slices - row.Zstart + 1 if isnan(row.Zend) else row.Zend, axis=1) df["slice_directory"] = df.apply(lambda row: os.path.join( output_dir, pipeline_name + "_stitched", row.brain_name), axis=1) ############################# # Step 1: Run TV_stitch.py ############################# #TODO surely theres a way around this? df = df.assign(TV_stitch_result="") for index, row in df.iterrows(): df.at[index, "TV_stitch_result"] = s.defer( TV_stitch_wrap(brain_directory=FileAtom(row.brain_directory), brain_name=row.brain_name, slice_directory=row.slice_directory, TV_stitch_options=options.TV_stitch, Zstart=row.Zstart, Zend=row.Zend, output_dir=output_dir)) df.drop(["mosaic_dictionary", "TV_stitch_result"], axis=1).to_csv("TV_brains.csv", index=False) df.explode("TV_stitch_result")\ .assign(slice=lambda df: df.apply(lambda row: row.TV_stitch_result.path, axis=1))\ .drop(["mosaic_dictionary", "TV_stitch_result"], axis=1)\ .to_csv("TV_slices.csv", index=False) return Result(stages=s, output=())
def TV_stitch_wrap(brain_directory: FileAtom, brain_name: str, slice_directory: str, TV_stitch_options, Zstart: int, Zend: int, output_dir: str): #TODO inputs should be tiles not just brain_directory stitched = [] for z in range(Zstart, Zend + 1): slice_stitched = FileAtom( os.path.join(slice_directory, brain_name + "_Z%04d.tif" % z)) stitched.append(slice_stitched) stage = CmdStage( inputs=(brain_directory, ), outputs=tuple(stitched), cmd=[ 'TV_stitch.py', '--clobber', #'--verbose', '--Zstart %s' % Zstart, '--Zend %s' % Zend, '--save_positions_file %s_positions.txt' % os.path.join(stitched[0].dir, brain_name + '_Zstart' + str(Zstart)) if TV_stitch_options.save_positions_file else "", '--keeptmp' if TV_stitch_options.keep_tmp else "", '--scaleoutput %s' % TV_stitch_options.scale_output if TV_stitch_options.scale_output else '', # '--skip_tile_match' if TV_stitch_options.skip_tile_match else '', # '--Ystart %s' % TV_stitch_options.Ystart if TV_stitch_options.Ystart else '', # '--Yend %s' % TV_stitch_options.Yend if TV_stitch_options.Yend else '', # '--Xstart %s' % TV_stitch_options.Xstart if TV_stitch_options.Xstart else '', # '--Xend %s' % TV_stitch_options.Xend if TV_stitch_options.Xend else '', # '--nogradimag' if TV_stitch_options.no_gradient_image else '', # '--use_positions_file %s' % TV_stitch_options.use_positions_file # if TV_stitch_options.use_positions_file else '', # '--overlapx %s' % TV_stitch_options.overlapx if TV_stitch_options.overlapx else '', # '--overlapy %s' % TV_stitch_options.overlapy if TV_stitch_options.overlapy else '', # '--channel %s' % TV_stitch_options.channel if TV_stitch_options.channel else '', # '--Zref %s' % TV_stitch_options.Zref if TV_stitch_options.Zref else '', # '--Zstack_pzIcorr' if TV_stitch_options.inormalize_piezo_stack else '', # '--fastpiezo' if TV_stitch_options.fast_piezo else '', # '--short' if TV_stitch_options.short_int else '', # '--file_type %s' % TV_stitch_options.use_positions_file if TV_stitch_options.use_positions_file else '', # '--TV_file_type %s' % TV_stitch_options.use_positions_file if TV_stitch_options.use_positions_file el # '--use_IM' if TV_stitch_options.use_imagemagick else '', os.path.join(brain_directory.path, brain_name), os.path.join(stitched[0].dir, brain_name) ], log_file=os.path.join(output_dir, "TV_stitch.log")) return Result(stages=Stages([stage]), output=(stitched))
def f( imgs: List[MincAtom], initial_target: MincAtom, conf: reg_module.MultilevelConf, use_robust_averaging: bool, nlin_dir: str, nlin_prefix: str, #algorithms : Type[Algorithms] ) -> Result[WithAvgImgs[List[XfmHandler]]]: confs = reg_module.hierarchical_to_single( conf) if conf is not None else None if confs is None or len(confs) == 0: raise ValueError("No configurations supplied ...") s = Stages() avg = initial_target avg_imgs = [] xfms = [None] * len(imgs) for i, conf in enumerate(confs, start=1): xfms = s.defer_map([ reg_module.register( source=img, # in the case the registration algorithm doesn't accept # an initial transform, # we could use the resampled output of the previous # step for a more efficient registration process, # although this would require more careful bookkeeping # of transforms and incur additional resampling error target=avg, conf=conf, initial_source_transform=xfm.xfm if reg_module.accepts_initial_transform() and (xfm is not None) else None, ##generation=i, # TODO reduce unneeded resamplings if accepts_initial_transform? resample_source=True) for img, xfm in zip(imgs, xfms) ]) avg = s.defer( reg_module.Algorithms.average([xfm.resampled for xfm in xfms], robust=use_robust_averaging, name_wo_ext='%s-nlin-%d' % (nlin_prefix, i), output_dir=nlin_dir)) avg_imgs.append(avg) return Result(stages=s, output=WithAvgImgs(output=xfms, avg_img=avg, avg_imgs=avg_imgs))
def voxel_vote(label_files: List[MincAtom], output_dir: str, name: str = "voted"): # TODO too stringy ... if len(label_files) == 0: raise ValueError("can't vote with 0 files") out = MincAtom(name=os.path.join(output_dir, "%s.mnc" % name), output_sub_dir=output_dir) # FIXME better naming s = CmdStage(cmd=["voxel_vote", "--clobber"] + [l.path for l in sorted(label_files)] + [out.path], inputs=tuple(label_files), outputs=(out, )) return Result(stages=Stages([s]), output=out)
def make_laplace_grid(input_labels: FileAtom, label_mapping: FileAtom, binary_closing: bool = None, side: Optional[Side] = None): out_grid = input_labels.newname_with_suffix("_laplace_grid" + ("_%s" % side.name if side else "")) s = CmdStage(inputs=(input_labels, label_mapping), outputs=(out_grid, ), cmd=["make_laplace_grid", "--clobber"] + optional(binary_closing, "--binary_closing") + optional(side, "--%s" % side.name) + [input_labels.path, label_mapping.path, out_grid.path]) return Result(stages=Stages([s]), output=out_grid)
def crop_to_brain(img: MincAtom, cropped_img: MincAtom, crop_to_brain_options): stage = CmdStage(inputs=(img,), outputs=(cropped_img,), memory=4, cmd=['crop_to_brain.py', '--bbox_x',str(crop_to_brain_options.bbox_x), '--bbox_y',str(crop_to_brain_options.bbox_y), '--bbox_z',str(crop_to_brain_options.bbox_z), '--intermediate_bbox=1.5', '--buffer_z',str(crop_to_brain_options.buffer_z), '--clobber', img.path, cropped_img.path]) print(stage.render()) stage.set_log_file(log_file_name=os.path.join(img.pipeline_sub_dir,"crop_to_brain.log")) return Result(stages=Stages([stage]), output=cropped_img)
def nlin_displacement( xfm: XfmHandler, inv_xfm: Optional[XfmHandler] = None) -> Result[MincAtom]: """ See: nlin_part(). This returns the nonlinear part of the input transformation (xfm) in the form of a grid file (vector field). All transformations are encapsulated in this field (linear parts that are normally specified in the .xfm file are placed in the vector field) """ s = Stages() return Result(stages=s, output=s.defer( minc_displacement( s.defer(nlin_part(xfm, inv_xfm=inv_xfm)))))
def average_transforms(xfms, avg_xfm): s = Stages() defs = [ s.defer( as_deformation(transform=xfm.xfm, reference_image=xfm.source)) for xfm in xfms ] #avg_img = NotImplemented avg = imageToXfm( s.defer( average_images( defs, avg_file=xfmToImage(avg_xfm), #output_dir=os.path.join(defs[0].pipeline_sub_dir, # defs[0].output_sub_dir, # "transforms") ))) return Result(stages=s, output=avg)
def as_deformation(transform, reference_image, interpolation: Interpolation = None, invert: bool = None, dimensionality: int = None, default_voxel_value: float = None, new_name_wo_ext: str = None, subdir: str = None, ext: str = None) -> Result[ITKImgAtom]: """Convert an arbitrary ITK transformation to a deformation field representation. Consider this an image rather than a transformation since, e.g., AverageImages can be used.""" if not subdir: subdir = 'tmp' ext = ext or ".nii.gz" if not new_name_wo_ext: out_xfm = xfmToImage( transform.newname(name=transform.filename_wo_ext + '_def', subdir=subdir, ext=ext)) else: out_xfm = xfmToImage( transform.newname(name=new_name_wo_ext, subdir=subdir, ext=ext)) # TODO add rest of --output options cmd = ([ "antsApplyTransforms", "--reference-image", reference_image.path, "--output", "[%s,1]" % out_xfm.path ] + (["--transform", transform.path] if invert is None else ["-t", "[%s,%d]" % (transform.path, invert)]) + (["--dimensionality", dimensionality] if dimensionality is not None else []) + (["--interpolation", interpolation.render()] if interpolation is not None else []) + (["--default-voxel-value", str(default_voxel_value)] if default_voxel_value is not None else [])) s = CmdStage(cmd=cmd, inputs=(transform, reference_image), outputs=(out_xfm, )) return Result(stages=Stages([s]), output=out_xfm)
def varian_recon_ge3dmice_saddle(fids: List[FileAtom], imgs: List[MincAtom], varian_recon_options, output_dir: str): stage = CmdStage(inputs=tuple(fids), outputs=tuple(imgs), memory=25, cmd=['mri_recon.py', 'ge3dmice_sg_cylA' , '--petable_ordered_pairs', '--grappa_coil_decouple', '--outputreps', '--phasedriftcorr', '--mouse_list',varian_recon_options.mouse_list, '--petable',varian_recon_options.petable, '--grappa_coil_groupings',varian_recon_options.grappa_coil_groupings, '--procpar_file_name', varian_recon_options.procpar_file_name, '--clobber', '--fermi_ellipse' if varian_recon_options.fermi_ellipse else '', varian_recon_options.fid_input_directory, os.path.join(output_dir,varian_recon_options.output_file_name)]) print(stage.render()) stage.set_log_file(log_file_name=os.path.join(output_dir,"varian_recon.log")) return Result(stages=Stages([stage]), output=imgs)
def get_through_plane_xfm(img: MincAtom, xfm: XfmAtom, output_dir: str): stage = CmdStage(inputs=(img, ), outputs=(xfm, ), cmd=[ 'param2xfm', '-clobber', '-translation', '0', '{y}', '0', xfm.path ], log_file=os.path.join(output_dir, "join_sections.log")) def set_params(stage: CmdStage): img_pyminc = pyminc.volumeFromFile(img.path) count = img_pyminc.data.count separations = img_pyminc.data.separations for index, arg in enumerate(stage.cmd): stage.cmd[index] = arg.format(y=count[0] * separations[0]) stage.when_runnable_hooks.append(lambda stage: set_params(stage)) return Result(stages=Stages([stage]), output=(xfm))
def diffuse( obj_file: FileAtom, input_signal: FileAtom, #output_signal : FileAtom, kernel: Optional[float] = None, iterations: Optional[int] = None, parametric: Optional[int] = None): output_signal = input_signal.newname_with_suffix("_thickness") stage = CmdStage( inputs=(obj_file, input_signal), outputs=(output_signal, ), cmd=[ "diffuse" ] # TODO make an abstraction for this; see Nix stdlib's `optional` + ["-kernel", str(kernel)] if kernel is not None else [] + ["-iterations", iterations] if iterations is not None else [] + ["-parametric", parametric] if parametric is not None else [] + [obj_file, input_signal, output_signal]) return Result(stages=Stages([stage]), output=output_signal)
def decimate(in_obj: FileAtom, reduction: float, smoothing_method: Optional[Smoothing] = None, smoothing_iterations: Optional[int] = None): decimated = in_obj.newname_with_suffix("_decimated_%s" % reduction + ( "_smooth" if smoothing_method not in (Smoothing.none, None) else "")) stage = CmdStage(inputs=(in_obj, ), outputs=(decimated, ), cmd=["decimate.py"] + (["--smoothing-method", smoothing_method.name] if smoothing_method not in ("none", None) else []) + (["--smoothing-iterations", str(smoothing_iterations)] if smoothing_iterations is not None else []) + [str(reduction), in_obj.path, decimated.path]) return Result(stages=Stages([stage]), output=decimated)
def antsApplyTransforms(img: FileAtom, transform: XfmAtom, transformed: FileAtom, output_dir: str, dimensionality: int = 2): stage = CmdStage(inputs=(img, transform), outputs=(transformed, ), cmd=[ 'antsApplyTransform', '--verbose', '--dimensionality %s' % dimensionality, '--input %s' % img, '--reference-image %s' % img, '--output %s' % transformed, '--transform %s' % transform, ], log_file=os.path.join(output_dir, "join_sections.log")) return Result(stages=Stages([stage]), output=(transformed, ))
def antsApplyTransforms( img, transform, reference_image, #outfile: str = None, interpolation: Interpolation = None, invert: bool = None, dimensionality: int = None, input_image_type=None, output_warped_file: bool = None, default_voxel_value: float = None, #static_case_for_R: bool = None, #float: bool = None new_name_wo_ext: str = None, subdir: str = None): if not subdir: subdir = 'resampled' if not new_name_wo_ext: out_img = img.newname(name=transform.filename_wo_ext + '-resampled', subdir=subdir) else: out_img = img.newname(name=new_name_wo_ext, subdir=subdir) # TODO add rest of --output options cmd = ([ "antsApplyTransforms", "--input", img.path, "--reference-image", reference_image.path, "--output", out_img.path ] + (["--transform", transform.path] if invert is None else ["-t", "[%s,%d]" % (transform.path, invert)]) + (["--dimensionality", dimensionality] if dimensionality is not None else []) + (["--interpolation", interpolation.render()] if interpolation is not None else []) + (["--default-voxel-value", str(default_voxel_value)] if default_voxel_value is not None else [])) s = CmdStage(cmd=cmd, inputs=(img, transform, reference_image), outputs=(out_img, )) return Result(stages=Stages([s]), output=out_img)
def f(img): s = Stages() def run_cmd(i, o): c = CmdStage(inputs=(i, ), outputs=(o, ), cmd=mk_cmd(i.path, o.path)) s.add(c) out_img = renamer(img) if img.mask: out_mask = renamer(img.mask) out_img.mask = out_mask run_cmd(img.mask, out_img.mask) if img.labels: out_labels = renamer(img.labels) out_img.labels = out_labels run_cmd(img.labels, out_img.labels) run_cmd(img, out_img) return Result(stages=s, output=out_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)
def build_model(imgs, conf, nlin_dir, nlin_prefix, use_robust_averaging, 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, use_robust_averaging=use_robust_averaging, 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]))
def marching_cubes(in_volume: MincAtom, min_threshold: float = None, max_threshold: float = None, threshold: float = None): if not xor(threshold is None, min_threshold is None and max_threshold is None): raise ValueError("specify either threshold or min and max thresholds") out_volume = FileAtom( in_volume.newname_with(NotImplemented) ) # forget MINCy fields # FIXME this coercion doesn't work stage = CmdStage( inputs=(in_volume, ), outputs=(out_volume, ), cmd=["marching_cubes", in_volume.path, out_volume.path] + ([str(threshold)] if threshold is not None else [str(min_threshold), str(max_threshold)])) return Result(stages=Stages([stage]), output=out_volume)
def tif_to_minc(tif: FileAtom, volume: MincAtom, z_resolution: float, stacks_to_volume_options, output_dir: str, uniform_sum: bool = False): stage = CmdStage(inputs=(tif, ), outputs=(volume, ), cmd=[ 'stacks_to_volume.py', '--input-resolution %s' % stacks_to_volume_options.input_resolution, '--output-resolution %s' % stacks_to_volume_options.plane_resolution, '--slice-gap %s' % z_resolution, '--uniform-sum' if uniform_sum else '', '%s' % tif.path, '%s' % volume.path ], log_file=os.path.join(output_dir, "join_sections.log")) return Result(stages=Stages([stage]), output=(volume))
def match_embryo_to_4D_atlas(embryo_with_volume_est, full_4D_atlas_info, lsq6_conf: LSQ6Conf, lsq12_conf: MinctraccConf, nlin_module: NLIN, resolution: float, nlin_options): s = Stages() # 1 what's the closest match in the 4D atlas? mid_index = get_index_closest_volume_match(embryo_with_volume_est["rough_volume"].astype(float), full_4D_atlas_info) print("Best initial match for: \n", embryo_with_volume_est["mincatom"].orig_path, " ", full_4D_atlas_info.loc[mid_index]["timepoint"]) # register embryo to closest match +/- 5 time points # make sure we don't index outside the possible range lowest_index = max(0, mid_index - 7) highest_index = min(full_4D_atlas_info.shape[0] - 1, mid_index + 7) all_transforms = [s.defer(lsq6_lsq12_nlin(source=embryo_with_volume_est["mincatom"], target=full_4D_atlas_info.loc[i]["mincatom"], lsq6_conf=lsq6_conf, lsq12_conf=lsq12_conf, nlin_module=nlin_module, resolution=resolution, nlin_options=nlin_options.nlin_protocol, resampled_post_fix_string="E" + str(full_4D_atlas_info.loc[i]["timepoint"]))) for i in range(lowest_index, highest_index + 1, 1)] # gather stats on those registrations # the match is determined by the sum of the magnitude # of the inverse transformation from 4D instance -> embryo # using the mask of the 4D instance to limit the total sum # 1) calculate inverse all_inv_transforms = [s.defer(invert_xfmhandler(xfm)) for xfm in all_transforms] minc_displacement_grids = [s.defer(minc_displacement(inv_xfm)) for inv_xfm in all_inv_transforms] magnitudes = [s.defer(mincblob(op='magnitude', grid=disp_grid)) for disp_grid in minc_displacement_grids] return Result(stages=s, output=all_transforms)
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 get_like(img: MincAtom, ref: MincAtom, like: MincAtom, output_dir: str): stage = CmdStage(inputs=(img, ref), outputs=(like, ), cmd=[ 'mincreshape', '-clobber', '-start {start}', '-count {count}', img.path, like.path ], log_file=os.path.join(output_dir, "join_sections.log")) def set_params(stage: CmdStage): img_pyminc = pyminc.volumeFromFile(img.path) ref_pyminc = pyminc.volumeFromFile(ref.path) count = np.maximum(ref_pyminc.data.count, img_pyminc.data.count) sum = ref_pyminc.data.count[0] + img_pyminc.data.count[0] for index, arg in enumerate(stage.cmd): stage.cmd[index] = arg.format(start='0,0,0,', count='%s,%s,%s' % (sum, count[1], count[2])) stage.when_runnable_hooks.append(lambda stage: set_params(stage)) return Result(stages=Stages([stage]), output=(like))
def mincblob(op: str, grid: MincAtom, subdir: str = "tmp") -> Result[MincAtom]: """ Low-level mincblob wrapper with the one exception being the determinant option. By default the inner clockwork of mincblob subtracts 1 from all determinant values that are being calculated. As such, 1 needs to be added to the result of the mincblob call. We will do that here, because it makes most sense here. >>> stages = mincblob('determinant', MincAtom("/images/img_1.mnc", pipeline_sub_dir="/tmp")).stages >>> [s.render() for s in stages] ['mincblob -clobber -determinant /images/img_1.mnc /tmp/img_1/img_1_determinant.mnc'] """ if op not in ["determinant", "trace", "translation", "magnitude"]: raise ValueError('mincblob: invalid operation %s' % op) # if we are calculating the determinant, the first file produced is a temp file: if op == "determinant": out_file = grid.newname_with_suffix("_temp_det", subdir=subdir) else: out_file = grid.newname_with_suffix('_' + op, subdir=subdir) stage = CmdStage( inputs=(grid, ), outputs=(out_file, ), cmd=['mincblob', '-clobber', '-' + op, grid.path, out_file.path]) s = Stages([stage]) # now create the proper determinant if that's what was asked for if op == "determinant": result_file = s.defer( mincmath(op='add', const=1, vols=[out_file], subdir=subdir, new_name=grid.filename_wo_ext + "_det")) else: result_file = out_file return Result(stages=s, output=result_file)
def stacks_to_volume(slices: List[FileAtom], output_volume: FileAtom, z_resolution: float, stacks_to_volume_options, scale_output: float = 1.0, uniform_sum: bool = False): stage = CmdStage( inputs=tuple(slices), outputs=(output_volume, ), cmd=[ 'stacks_to_volume.py', #TODO these should be part of csv not command line options '--input-resolution %s' % stacks_to_volume_options.input_resolution, '--output-resolution %s' % stacks_to_volume_options.plane_resolution, '--slice-gap %s' % z_resolution, '--uniform-sum' if uniform_sum else '', '--scale-output %s' % scale_output, ' '.join(slice.path for slice in slices.__iter__()), #is this hacky or the right way? '%s' % output_volume.path ]) return Result(stages=Stages([stage]), output=(output_volume))
def minclaplace( input_grid: MincAtom, extra_args: List[str] = [], solution_vertices: Optional[FileAtom] = None, create_surface: bool = True, ) -> Result[FileAtom]: # TODO the ambiguity of the return type is slightly annoying ... # best to create separate minclaplace_at_vertices for the case when `--solve-at-vertices` is used? solved = input_grid.newname_with_suffix( "_solved", ext=".txt" if solution_vertices else ".mnc") if create_surface: out_surface = input_grid.newname_with_suffix("_surface", ext=".obj") stage = CmdStage( inputs=(input_grid, ), outputs=(solved, ) + ((out_surface, ) if create_surface else ()), cmd=["minclaplace"] + (["--solve-at-vertices=%s" % solution_vertices.path] if solution_vertices is not None else []) + (["--create-surface=%s" % out_surface.path] if create_surface else []) + extra_args + [input_grid.path, solved.path]) return Result(stages=Stages([stage]), output=Namespace(solved=solved, surface=out_surface) if create_surface else Namespace(solved=solved))