Source code for ClearMap.processors.batch_process

# -*- coding: utf-8 -*-
"""
batch_process
=============

The processor set of scripts to batch process a group of samples.
This can be used from the GUI, from the CLI or interactively from the python interpreter
"""
import functools
import multiprocessing
import sys
from concurrent.futures import ThreadPoolExecutor

import numpy as np

from skimage.transform import rescale
from tqdm import tqdm

try:
    from ClearMap.processors.tube_map import BinaryVesselProcessor, VesselGraphProcessor
    graph_gt = True
except ImportError:
    graph_gt = False
from ClearMap.processors.cell_map import CellDetector
from ClearMap.processors.sample_preparation import PreProcessor, init_preprocessor
from ClearMap.config.config_loader import get_configs, ConfigLoader
from ClearMap.IO import IO as clearmap_io

__author__ = 'Charly Rousseau <charly.rousseau@icm-institute.org>'
__license__ = 'GPLv3 - GNU General Public License v3 (see LICENSE.txt)'
__copyright__ = 'Copyright © 2022 by Charly Rousseau'
__webpage__ = 'https://idisco.info'
__download__ = 'https://www.github.com/ChristophKirst/ClearMap2'


[docs] def process_sample(configs, align=False, cells=False, vasc=False): patch_pipeline_name(configs, cells, vasc) pre_proc = PreProcessor() pre_proc.setup(configs) pre_proc.setup_atlases() if align: pre_proc.run() if cells: cell_detector = CellDetector(pre_proc) cell_detector.processing_config.reload() cell_detector.run_cell_detection() cell_detector.post_process_cells() cell_detector.voxelize() if vasc: binary_vessel_processor = BinaryVesselProcessor(pre_proc) binary_vessel_processor.binarize() binary_vessel_processor.combine_binary() vessel_graph_processor = VesselGraphProcessor(pre_proc) vessel_graph_processor.pre_process() vessel_graph_processor.post_process()
[docs] def patch_pipeline_name(configs, cells, vasc): configs[2]['pipeline_name'] = 'CellMap' if cells else 'TubeMap' if cells and vasc: configs[2]['pipeline_name'] = 'Both'
[docs] class BatchProcessor: def __init__(self, progress_watcher, results_folder=None, params=None): self.results_folder = results_folder self.progress_watcher = progress_watcher self.params = params
[docs] def process_folders(self): paths = [p for ps in self.params.get_all_paths() for p in ps] # flatten list for folder in tqdm(paths, desc='Processing sample ', unit='brain'): cfg_loader = ConfigLoader(folder) configs = get_configs(cfg_loader.get_cfg_path('sample'), cfg_loader.get_cfg_path('processing')) process_sample(configs, align=self.params.align, cells=self.params.count_cells, vasc=self.params.run_vaculature) self.progress_watcher.finish()
[docs] def process_folders(folders, align=False, cells=False, vasc=False): for folder in tqdm(folders, desc='Processing sample ', unit='brain'): cfg_loader = ConfigLoader(folder) configs = get_configs(cfg_loader.get_cfg_path('sample'), cfg_loader.get_cfg_path('processing')) process_sample(configs, align=align, cells=cells, vasc=vasc)
[docs] def main(samples_file): with open(samples_file, 'r') as infile: folders = infile.readlines() folders = [f.strip() for f in folders if not f.startswith('#')] voxelize_folders(folders)
[docs] def voxelize_sample(configs, align=False, cells=False, vasc=False): patch_pipeline_name(configs, cells, vasc) pre_proc = PreProcessor() pre_proc.setup(configs) pre_proc.setup_atlases() if align: pre_proc.run() if cells: cell_detector = CellDetector(pre_proc) cell_detector.processing_config.reload() # cell_detector.atlas_align() # cell_detector.export_collapsed_stats() cell_detector.processing_config['voxelization']['radii'] = (10, 10, 10) cell_detector.processing_config.write() cell_detector.voxelize()
[docs] def voxelize_folders(folders, align=False, cells=True, vasc=False): for folder in tqdm(folders, desc='Processing sample ', unit='brain'): cfg_loader = ConfigLoader(folder) configs = get_configs(cfg_loader.get_cfg_path('sample'), cfg_loader.get_cfg_path('processing')) voxelize_sample(configs, align=align, cells=cells, vasc=vasc)
[docs] def convert_to_cm_2_1(folder, atlas_base_name='ABA_25um'): pre_proc = init_preprocessor(folder, atlas_base_name) pre_proc.setup_atlases() cell_detector = CellDetector(pre_proc) cell_detector.convert_cm2_to_cm2_1_fmt()
[docs] def realign(folder, atlas_base_name='ABA_25um'): pre_proc = init_preprocessor(folder, atlas_base_name) pre_proc.setup_atlases() cell_detector = CellDetector(pre_proc) cell_detector.filter_cells() cell_detector.atlas_align()
[docs] def rescale_img(f_path, scaling_factor): print(f'Rescaling {f_path} by {scaling_factor}') img = clearmap_io.read(f_path) rescaled_img = rescale(img, scaling_factor, preserve_range=True, anti_aliasing=True) clearmap_io.write(f_path, rescaled_img)
[docs] def rescale_channel(folder, atlas_base_name=None, dest_resolution=(3, 3, 6), n_cpus=None, channel='raw', ext='.tif', chunk_size=1): """ Used to rescale to create e.g. test samples that can be ran quickly Parameters ---------- folder str: The experiment folder with the tiles atlas_base_name str: The base name of the atlas that serves as a file prefix for the atlas files dest_resolution tuple: The desired resolution Returns ------- """ n_cpus = multiprocessing.cpu_count() - 2 if n_cpus is None else n_cpus pre_proc = init_preprocessor(folder, atlas_base_name) file_list = pre_proc.workspace.file_list(channel, prefix=pre_proc.prefix, extension=ext) print(f'Processing {file_list}') scaling_factors = np.array(pre_proc.sample_config['resolutions'][channel]) / np.array(dest_resolution) print(scaling_factors) rescale_f = functools.partial(rescale_img, scaling_factor=tuple(scaling_factors)) if n_cpus*chunk_size == 1: for f_path in file_list: rescale_f(f_path) else: with ThreadPoolExecutor(n_cpus) as executor: executor.map(rescale_f, file_list, chunksize=chunk_size) pre_proc.sample_config['resolutions'][channel] = list(dest_resolution) pre_proc.sample_config.write() print('DONE')
[docs] def batch_crop(folder, crop_x=0, crop_y=0, suffix='_cropped'): from ClearMap.processors.sample_preparation import init_preprocessor preproc = init_preprocessor(folder) shape = clearmap_io.shape(preproc.workspace.file_list('raw')[-1]) for f_path in preproc.workspace.file_list('raw'): img = clearmap_io.read(f_path) cropped_img = img[crop_x:shape[0] - crop_x, crop_y:shape[1] - crop_y, :] cropped_path = f_path.replace('.ome.tif', f'{suffix}.ome.tif') clearmap_io.write(cropped_path, cropped_img)
if __name__ == '__main__': main(sys.argv[1])