From 85a66bb2b1e87821836c6daad3cb9b499e8c6461 Mon Sep 17 00:00:00 2001 From: Swainlab <peter.swain@ed.ac.uk> Date: Fri, 11 Aug 2023 20:26:59 +0100 Subject: [PATCH] added moment_of_inertia to cell functions --- src/aliby/pipeline.py | 26 +++++++------- src/extraction/core/functions/cell.py | 36 +++++++++++++++++++ .../core/functions/custom/localisation.py | 5 +-- src/extraction/core/functions/loaders.py | 4 +-- 4 files changed, 54 insertions(+), 17 deletions(-) diff --git a/src/aliby/pipeline.py b/src/aliby/pipeline.py index c31d0fc2..e5d5bc66 100644 --- a/src/aliby/pipeline.py +++ b/src/aliby/pipeline.py @@ -126,7 +126,7 @@ class PipelineParameters(ParametersABC): use_explog=True, ) } - # update default values using inputs + # update default values for general using inputs for k, v in general.items(): if k not in defaults["general"]: defaults["general"][k] = v @@ -306,7 +306,7 @@ class Pipeline(ProcessABC): # extract from configuration expt_id = config["general"]["id"] distributed = config["general"]["distributed"] - pos_filter = config["general"]["filter"] + position_filter = config["general"]["filter"] root_dir = Path(config["general"]["directory"]) self.server_info = { k: config["general"].get(k) @@ -329,15 +329,15 @@ class Pipeline(ProcessABC): config["general"]["directory"] = directory self.setLogger(directory) # pick particular positions if desired - if pos_filter is not None: - if isinstance(pos_filter, list): + if position_filter is not None: + if isinstance(position_filter, list): position_ids = { k: v - for filt in pos_filter + for filt in position_filter for k, v in self.apply_filter(position_ids, filt).items() } else: - position_ids = self.apply_filter(position_ids, pos_filter) + position_ids = self.apply_filter(position_ids, position_filter) if not len(position_ids): raise Exception("No images to segment.") # create and run pipelines @@ -356,26 +356,26 @@ class Pipeline(ProcessABC): ] return results - def apply_filter(self, position_ids: dict, pos_filter: int or str): + def apply_filter(self, position_ids: dict, position_filter: int or str): """ Select positions. - Either pick a particular one or use a regular expression to parse - their file names. + Either pick a particular position or use a regular expression + to parse their file names. """ - if isinstance(pos_filter, str): + if isinstance(position_filter, str): # pick positions using a regular expression position_ids = { k: v for k, v in position_ids.items() - if re.search(pos_filter, k) + if re.search(position_filter, k) } - elif isinstance(pos_filter, int): + elif isinstance(position_filter, int): # pick a particular position position_ids = { k: v for i, (k, v) in enumerate(position_ids.items()) - if i == pos_filter + if i == position_filter } return position_ids diff --git a/src/extraction/core/functions/cell.py b/src/extraction/core/functions/cell.py index 0e7b9fe8..4d97f23a 100644 --- a/src/extraction/core/functions/cell.py +++ b/src/extraction/core/functions/cell.py @@ -193,3 +193,39 @@ def min_maj_approximation(cell_mask) -> t.Tuple[int]: # + distance from the center of cone top to edge of cone top maj_ax = np.round(np.max(dn) + np.sum(cone_top) / 2) return min_ax, maj_ax + + +def moment_of_inertia(cell_mask, trap_image): + """ + Find moment of inertia - a measure of homogeneity. + + From iopscience.iop.org/article/10.1088/1742-6596/1962/1/012028 + which cites ieeexplore.ieee.org/document/1057692. + """ + # set pixels not in cell to zero + trap_image[~cell_mask] = 0 + x = trap_image + if np.any(x): + # x-axis : column=x-axis + columnvec = np.arange(1, x.shape[1] + 1, 1)[:, None].T + # y-axis : row=y-axis + rowvec = np.arange(1, x.shape[0] + 1, 1)[:, None] + # find raw moments + M00 = np.sum(x) + M10 = np.sum(np.multiply(x, columnvec)) + M01 = np.sum(np.multiply(x, rowvec)) + # find centroid + Xm = M10 / M00 + Ym = M01 / M00 + # find central moments + Mu00 = M00 + Mu20 = np.sum(np.multiply(x, (columnvec - Xm) ** 2)) + Mu02 = np.sum(np.multiply(x, (rowvec - Ym) ** 2)) + # find invariants + Eta20 = Mu20 / Mu00 ** (1 + (2 + 0) / 2) + Eta02 = Mu02 / Mu00 ** (1 + (0 + 2) / 2) + # find moments of inertia + moi = Eta20 + Eta02 + return moi + else: + return np.nan diff --git a/src/extraction/core/functions/custom/localisation.py b/src/extraction/core/functions/custom/localisation.py index 07c22587..08f034e8 100644 --- a/src/extraction/core/functions/custom/localisation.py +++ b/src/extraction/core/functions/custom/localisation.py @@ -1,8 +1,9 @@ -""" How to do the nuc Est Conv from MATLAB +""" +How to do the nuc Est Conv from MATLAB Based on the code in MattSegCode/Matt Seg GUI/@timelapseTraps/extractCellDataStacksParfor.m -Especially lines 342 to 399. +Especially lines 342 to 399. This part only replicates the method to get the nuc_est_conv values """ import typing as t diff --git a/src/extraction/core/functions/loaders.py b/src/extraction/core/functions/loaders.py index ff83b20c..ce33f845 100644 --- a/src/extraction/core/functions/loaders.py +++ b/src/extraction/core/functions/loaders.py @@ -11,8 +11,8 @@ from extraction.core.functions.math_utils import div0 """ Load functions for analysing cells and their background. -Note that inspect.getmembers returns a list of function names and functions, -and inspect.getfullargspec returns a function's arguments. +Note that inspect.getmembers returns a list of function names and +functions, and inspect.getfullargspec returns a function's arguments. """ -- GitLab