From 2c7493d6aa2cefcee79a5eb07ac5a802e3ad2bf6 Mon Sep 17 00:00:00 2001
From: Christopher Rhodes <christopher.rhodes@embl.de>
Date: Wed, 17 Jul 2024 13:18:47 +0200
Subject: [PATCH] Removed focal point projection

---
 model_server/base/roiset.py | 80 +++++--------------------------------
 1 file changed, 10 insertions(+), 70 deletions(-)

diff --git a/model_server/base/roiset.py b/model_server/base/roiset.py
index 74d85ace..ce0157c5 100644
--- a/model_server/base/roiset.py
+++ b/model_server/base/roiset.py
@@ -10,9 +10,7 @@ from pydantic import BaseModel
 from scipy.stats import moment
 from skimage.filters import sobel
 
-from skimage.measure import label, regionprops_table, shannon_entropy, find_contours
-from sklearn.preprocessing import PolynomialFeatures
-from sklearn.linear_model import LinearRegression
+from skimage.measure import label, regionprops_table, shannon_entropy
 
 from .accessors import GenericImageDataAccessor, InMemoryDataAccessor, write_accessor_data_to_file
 from .models import InstanceSegmentationModel
@@ -170,7 +168,6 @@ def make_df_from_object_ids(acc_raw, acc_obj_ids, expand_box_by) -> pd.DataFrame
 
     df = df_insert_slices(df, acc_raw.shape_dict, expand_box_by)
 
-    # TODO: make this contingent on whether seg is included
     def _make_binary_mask(r):
         acc = InMemoryDataAccessor(acc_obj_ids.data == r.label)
         cropped = acc.get_mono(0, mip=True).crop_hw((r.y0, r.x0, (r.y1 - r.y0), (r.x1 - r.x0))).data[:, :, 0, 0]
@@ -263,7 +260,6 @@ class RoiSet(object):
     def __init__(
             self,
             acc_raw: GenericImageDataAccessor,
-            # acc_obj_ids: GenericImageDataAccessor,
             df: pd.DataFrame,
             params: RoiSetMetaParams = RoiSetMetaParams(),
     ):
@@ -271,8 +267,7 @@ class RoiSet(object):
         A set of regions of interest, referenced by their positions and contours in the YXCZ space of stack acc_raw.
         RoiSet contains their internal state, which may be exported as patches, maps, and other products by export methods.
         :param acc_raw: accessor to a generally a multichannel z-stack
-        :param acc_obj_ids: accessor to a 2D single-channel object identities map, where each pixel's intensity
-            labels its membership in a connected object
+        :param df: dataframe containing at minimum bounding box and segmentation mask information
         :param params: optional arguments that influence the definition and representation of ROIs
         """
         # assert acc_obj_ids.chroma == 1
@@ -281,13 +276,6 @@ class RoiSet(object):
         self.accs_derived = []
         self.params = params
 
-        # self._df = self.filter_df(
-        #     self.make_df_from_object_ids(
-        #         self.acc_raw, self.acc_obj_ids, expand_box_by=params.expand_box_by
-        #     ),
-        #     params.filters,
-        # )
-
         self._df = df
         self.count = len(self._df)
         self.object_class_maps = {}  # classification results
@@ -302,6 +290,14 @@ class RoiSet(object):
             acc_obj_ids: GenericImageDataAccessor,
             params: RoiSetMetaParams = RoiSetMetaParams(),
     ):
+        """
+
+        :param acc_raw:
+        :param acc_obj_ids: accessor to a 2D single-channel object identities map, where each pixel's intensity
+            labels its membership in a connected object
+        :param params:
+        :return:
+        """
         assert acc_obj_ids.chroma == 1
 
         df = filter_df(
@@ -335,15 +331,6 @@ class RoiSet(object):
         return RoiSet.from_object_ids(acc_raw, get_label_ids(acc_seg, allow_3d=allow_3d, connect_3d=connect_3d), params)
 
 
-    # TODO: generate overlapping RoiSet from multiple masks
-    # call e.g. static adder
-
-
-    @staticmethod
-    def make_df_from_patches():
-        pass
-
-
     # TODO: get overlapping segments
     def get_overlap_seg(self) -> pd.DataFrame:
         dfbb = filter_overlap_bbox(self._df)
@@ -797,53 +784,6 @@ class RoiSet(object):
         return RoiSet.from_object_ids(acc_raw, id_mask)
 
 
-def project_stack_from_focal_points(
-        xx: np.ndarray,
-        yy: np.ndarray,
-        zz: np.ndarray,
-        stack: GenericImageDataAccessor,
-        degree: int = 2,
-) -> np.ndarray:
-    """
-    Given a set of 3D points, project a multichannel z-stack based on a surface fit of the provided points
-    :param xx: vector of point x-coordinates
-    :param yy: vector of point y-coordinates
-    :param zz: vector of point z-coordinates
-    :param stack: z-stack to project
-    :param degree: order of polynomial to fit
-    :return: multichannel 2d projected image array
-    """
-    assert xx.shape == yy.shape
-    assert xx.shape == zz.shape
-
-    poly = PolynomialFeatures(degree=degree)
-    X = np.stack([xx, yy]).T
-    features = poly.fit_transform(X, zz)
-    model = LinearRegression(fit_intercept=False)
-    model.fit(features, zz)
-
-    xy_indices = np.indices(stack.hw).reshape(2, -1).T
-    xy_features = np.dot(
-        poly.fit_transform(xy_indices, zz),
-        model.coef_
-    )
-    zi_image = xy_features.reshape(
-        stack.hw
-    ).round().clip(
-        0, (stack.nz - 1)
-    ).astype('uint16')
-
-    return np.take_along_axis(
-        stack.data,
-        np.repeat(
-            np.expand_dims(zi_image, (2, 3)),
-            stack.chroma,
-            axis=2
-        ),
-        axis=3
-    )
-
-
 
 class Error(Exception):
     pass
-- 
GitLab