Source code for paprica.converter

"""
Submodule containing classes and functions relative to **converting** tiles to APR.

The general workflow is first to parse tiles using a *parser* object and then convert using the tileConverter class.
This class is essentially a wrapper to pyapr which allows to facilitate batch conversions and batch reconstructions.

By using this code you agree to the terms of the software license agreement.

© Copyright 2020 Wyss Center for Bio and Neuro Engineering – All rights reserved
"""

import os
from pathlib import Path

import pyapr
from skimage.io import imsave
from tqdm import tqdm

import paprica


[docs]class tileConverter(): """ Class to convert tiles to APR or to tiff. """
[docs] def __init__(self, tiles: paprica.parser.baseParser): """ Constructor for the tileConverter class. Parameters ---------- tiles: baseParser parser object referencing tiles to be converted. """ if isinstance(tiles, paprica.parser.tileParser): self.is_multitile = True # Not multitile else: self.is_multitile = False # Multitile self.tiles = tiles self.path = tiles.path self.n_tiles = tiles.n_tiles self.compression = 0 self.bg = None self.quantization_factor = None
[docs] def set_compression(self, quantization_factor=1, bg=108): """ Activate B3D compression for saving tiles. Parameters ---------- quantization_factor: int quantization factor: the higher, the more compressed (refer to B3D paper for more detail). bg: int background value: any value below this threshold will be set to the background value. This helps save up space by having the same value for the background (refer to B3D paper for more details). Returns ------- None """ self.compression = True self.bg = bg self.quantization_factor = quantization_factor
[docs] def deactivate_compression(self): """ Deactivate B3D compression when saving particles. Returns ------- None """ self.compression = False self.bg = None self.quantization_factor = None
[docs] def batch_convert_to_apr(self, Ip_th=108, rel_error=0.2, gradient_smoothing=2, dx=1, dy=1, dz=1, path=None, lazy_loading=True, tree_mode='mean', progress_bar=True): """ Convert all parsed tiles to APR using auto-parameters. Parameters ---------- Ip_th: int Intensity threshold rel_error: float in [0, 1[ relative error bound gradient_smoothing: (float) B-Spline smoothing parameter (typically between 0 (no smoothing) and 10 (LOTS of smoothing) dx: float PSF size in x, used to compute the gradient dy: float PSF size in y, used to compute the gradient dz: float PSF size in z, used to compute the gradient path: str path to save the converted APR data (defaut is creating a folder named `APR` in the raw data directory. lazy_loading: bool if lazy_loading is true then the converter save mean tree particle which are necessary for lazy loading of the APR. It will require about 1/7 more storage. tree_mode: str ('mean' or 'max') controls how downsampled particles are computed. Either the mean or the max is taken. Returns ------- None """ if self.tiles.type == 'apr': raise TypeError('Error: data already in APR format.') if tree_mode not in ['mean', 'max']: raise ValueError('Error: invalid tree_mode.') # Safely create folder to save apr data if path is None: base_folder, _ = os.path.split(self.path) if self.tiles.channel is None: folder_apr = os.path.join(base_folder, 'APR') else: folder_apr = os.path.join(base_folder, 'APR', 'ch{}'.format(self.tiles.channel)) else: folder_apr = path Path(folder_apr).mkdir(parents=True, exist_ok=True) for tile in tqdm(self.tiles, desc='Converting tiles', disable=not progress_bar): tile.load_tile() # Set parameters par = pyapr.APRParameters() par.Ip_th = Ip_th par.rel_error = rel_error par.dx = dx par.dy = dy par.dz = dz par.gradient_smoothing = gradient_smoothing par.auto_parameters = True # Convert tile to APR and save apr = pyapr.APR() parts = pyapr.ShortParticles() converter = pyapr.converter.FloatConverter() converter.set_parameters(par) converter.verbose = True converter.get_apr(apr, tile.data) parts.sample_image(apr, tile.data) if self.compression: parts.set_compression_type(1) parts.set_quantization_factor(self.quantization_factor) parts.set_background(self.bg) if lazy_loading: if tree_mode == 'mean': tree_parts = pyapr.tree.fill_tree_mean(apr, parts) elif tree_mode == 'max': tree_parts = pyapr.tree.fill_tree_max(apr, parts) else: tree_parts = None # Save converted data if not self.is_multitile: if tile.type == 'tiff2D': basename, filename = os.path.split(tile.path[:-1]) pyapr.io.write(os.path.join(folder_apr, filename + '.apr'), apr, parts, tree_parts=tree_parts) else: basename, filename = os.path.split(tile.path) pyapr.io.write(os.path.join(folder_apr, filename[:-4] + '.apr'), apr, parts, tree_parts=tree_parts) else: filename = '{}_{}.apr'.format(tile.row, tile.col) pyapr.io.write(os.path.join(folder_apr, filename), apr, parts, tree_parts=tree_parts) if self.is_multitile: # Modify tileParser object to use APR instead self.tiles = paprica.parser.tileParser(folder_apr, frame_size=self.tiles.frame_size, ftype='apr')
[docs] def batch_reconstruct_pixel(self, mode='constant', progress_bar=True): """ Reconstruct all APR tiles to pixel data. Parameters ---------- mode: string reconstruction mode, can be 'constant', 'smooth' or 'level' Returns ------- None """ if self.tiles.type != 'apr': raise TypeError('Error: data not in APR format.') # Safely create folder to save apr data base_folder, _ = os.path.split(self.path) folder_tiff = os.path.join(base_folder, 'TIFF') Path(folder_tiff).mkdir(parents=True, exist_ok=True) for tile in tqdm(self.tiles, desc='Converting tiles', disable=not progress_bar): tile.load_tile() if mode == 'constant': data = pyapr.reconstruction.reconstruct_constant(tile.apr, tile.parts).squeeze() elif mode == 'smoth': data = pyapr.reconstruction.reconstruct_smooth(tile.apr, tile.parts).squeeze() elif mode == 'level': data = pyapr.reconstruction.reconstruct_level(tile.apr, tile.parts).squeeze() else: raise ValueError('Error: unknown mode for APR reconstruction.') # Save converted data if not self.is_multitile: basename, filename = os.path.split(tile.path) imsave(os.path.join(folder_tiff, filename[:-4] + '.tif'), data, check_contrast=False) else: filename = '{}_{}.tif'.format(tile.row, tile.col) imsave(os.path.join(folder_tiff, filename), data, check_contrast=False)