Source code for slitflow.loc.convert

import numpy as np
import pandas as pd
from scipy.sparse import csr_matrix, find

from ..tbl.table import Table, merge_different_index
from ..img.filter import DifferenceOfGaussian, LocalMax


[docs] class LocalMax2Xy(Table): """Convert nonzero local max pixels to X,Y-coordinate. .. caution:: The input image should be split into a single frame image. In other words, the shape of reqs[0] in :meth:`process()` should be (1, height, width). Args: reqs[0] (LocalMax): Local max images to pick up coordinates. Required params; ``length_unit``, ``pitch``. param["split_depth"] (int): File split depth number. Returns: Table: X,Y-coordinate of local max pixels """
[docs] def set_info(self, param): """Copy info from reqs[0] and add columns. """ self.info.copy_req(0) length_unit = self.info.get_param_value("length_unit") self.info.delete_column(["intensity"]) self.info.add_column( 0, "pt_no", "int32", "num", "Point number") self.info.add_column( 0, "x_" + length_unit, "float32", length_unit, "X-coordinate") self.info.add_column( 0, "y_" + length_unit, "float32", length_unit, "Y-coordinate") self.info.add_column( 0, "intensity", "float32", "a.u.", "Pixel intensity") self.info.set_split_depth(param["split_depth"])
[docs] @ staticmethod def process(reqs, param): """Convert nonzero local max pixels to X,Y-coordinate. Args: reqs[0] (numpy.ndarray): Numpy 3D array with the shape of (1, height, width). param["length_unit"] (str): Unit string for column names such as "um" and "nm". param["pitch"] (float): Length per pixel. Returns: pandas.DataFrame: X,Y-coordinate of local max pixels """ img = reqs[0].copy() if img.shape[0] != 1: raise Exception( "Input image should be split into a single frame image.") frm = img[0, :, :] yxi = find(csr_matrix(frm)) df = pd.DataFrame( {"pt_no": range(1, len(yxi[0]) + 1), "x_" + param["length_unit"]: yxi[1] * param["pitch"], "y_" + param["length_unit"]: yxi[0] * param["pitch"], "intensity": yxi[2]}) return df
[docs] def post_run(self): """Index columns should be added on the upper level of the DataFrame. """ merge_different_index(self, 0)
[docs] class LocalMax2XyWithDoG(Table): """Convert nonzero local max pixels to X,Y-coordinate with DoG filter. Args: reqs[0] (Image): Image to apply the filter to. Required parameters; ``length_unit``, ``pitch``. param["wavelength"] (int): Emission wavelength in length_unit. param["NA"] (float): Numerical aperture. param["size_factor"] (float, optional): Particle size factor to multiply PSF size. Defaults to 1. param["mask_factor"] (float, optional): Mask size factor to multiply PSF diameter. Defaults to 1. param["split_depth"] (int): File split depth number. Returns: Table: X,Y-coordinate of detected local max """
[docs] def set_info(self, param): """Copy info from reqs[0] and add params. """ self.info.copy_req(0) length_unit = self.info.get_param_value("length_unit") self.info.delete_column(["intensity"]) self.info.add_column( 0, "pt_no", "int32", "num", "Point number") self.info.add_column( 0, "x_" + length_unit, "float32", length_unit, "X-coordinate") self.info.add_column( 0, "y_" + length_unit, "float32", length_unit, "Y-coordinate") self.info.add_column( 0, "intensity", "float32", "a.u.", "Pixel intensity") pitch = self.info.get_param_value("pitch") d_psf_pix = (1.22 * param["wavelength"] / (param["NA"] * pitch)) self.info.add_param( "d_psf", d_psf_pix, "pix", "PSF diameter") self.info.add_param( "wavelength", param["wavelength"], length_unit, "Wavelength") self.info.add_param( "NA", param["NA"], "none", "Numerical aperture") if "size_factor" not in param: param["size_factor"] = 1 self.info.add_param( "size_factor", param["size_factor"], "none", "Particle size factor to multiply PSF size") particle_size = param["size_factor"] * d_psf_pix dog_sd1 = particle_size / (1 + np.sqrt(2)) dog_sd2 = np.sqrt(2) * dog_sd1 self.info.add_param( "dog_sd1", dog_sd1, "pix", "SD of Gauss filter 1") self.info.add_param( "dog_sd2", dog_sd2, "pix", "SD of Gauss filter 2") if "mask_factor" not in param: param["mask_factor"] = 1 self.info.add_param( "mask_factor", param["mask_factor"], "none", "Local maximum mask size factor") mask_size = int(np.ceil(param["mask_factor"] * d_psf_pix)) self.info.add_param( "mask_size", mask_size, "pix", "Local maximum mask size") self.info.set_split_depth(param["split_depth"])
[docs] @ staticmethod def process(reqs, param): """Convert nonzero local max pixels to X,Y-coordinate with DoG filter. Args: reqs[0] (numpy.ndarray): Image to apply the filter to. The image should have the shape of (frame number, height, width). param["dog_sd1"] (float): Standard deviation of the first Gaussian filter. param["dog_sd2"] (float): Standard deviation of the second Gaussian filter. param["mask_size"] (int): Mask size factor to multiply PSF diameter. param["length_unit"] (str): Unit string for column names such as "um" and "nm". param["pitch"] (float): Length per pixel. Returns: pandas.DataFrame: X,Y-coordinate of local max pixels """ img = reqs[0].copy() img = DifferenceOfGaussian.process(reqs, param) img = LocalMax.process([img], param) df = LocalMax2Xy.process([img], param) return df
[docs] def post_run(self): """Index columns should be added on the upper level of the DataFrame. """ merge_different_index(self, 0)