def compute_areas_from_periphery(self): # compute cell area per isoline in cytoplasm cytoplasm_mask = self.get_cytoplasm_mask() distance_map = self.get_cell_mask_distance_map() areas = np.zeros(constants.analysis_config['NUM_CONTOURS']) for i in range(constants.analysis_config['NUM_CONTOURS']): areas[i] = cytoplasm_mask[(distance_map <= i + 1)].sum() * helpers.surface_coeff() return areas
def compute_cell_area(self): """compute cell surface in real pixel size using cell mask""" cell_mask = self.get_cell_mask() area = cell_mask.sum() * helpers.surface_coeff( ) # * by pixel dimensions if (len(self.get_multiple_nucleus_centroid())) > 1: return area / len(self.get_multiple_nucleus_centroid()) else: return area
def compute_cytoplasmic_coordinates_peripheral_distance( self, coordinates) -> np.ndarray: """ Perform the computation of distance to the periphery for cytoplasmic coordinates Computation is done in pseudo 3D Returns an array of integer distances """ logger.info( "Computing 3D peripheral distance for {} coordinates in image {}", len(coordinates), self._path) assert coordinates.shape[ 1] == 3, "3D coordinates needed for distance to the periphery" max_height = np.max(self.adjust_height_map()) peripheral_distance_map = self.get_cell_mask_distance_map() cell_area = self.compute_cell_area() distances = np.array([]) slices = self.get_cell_mask_slices() for slice_num in range(0, slices.shape[2]): slice_mask = slices[:, :, slice_num] slice_area = slice_mask.sum() * helpers.surface_coeff() assert slice_area >= 0, "Empty slice area" coordinates_this_height = coordinates[np.around(coordinates[:, 2]) == max_height - slice_num] for c in coordinates_this_height: if not self.is_in_cytoplasm(c[0:2][::-1]): distances = np.append(distances, np.nan) else: area_ratio = slice_area / cell_area old_periph_distance = peripheral_distance_map[c[1], c[0]] new_periph_distance = math.sqrt( area_ratio) * old_periph_distance if (new_periph_distance > old_periph_distance ): # coordinate falls out of the slice distances = np.append(distances, np.nan) else: distances = np.append( distances, int(np.around(new_periph_distance))) if (len(distances) < len(coordinates)) or (len( distances[np.isnan(distances)]) > 0): num = len(coordinates) - len(distances) + len( distances[np.isnan(distances)]) logger.info(" found {} coordinates outside of cytoplasm", num) return distances
def compute_clustering_indices(self) -> np.ndarray: """ Point process Ripkey-K computation for disks of radius r < MAX_CELL_RADIUS return: clustering indices for all r """ logger.info("Running {} simulations of Ripley-K for {}", constants.analysis_config["RIPLEY_K_SIMULATION_NUMBER"], self._path) spots = self.get_spots() n_spots = len(spots) cell_mask = self.get_cell_mask() nuw = (np.sum(cell_mask[:, :] == 1) ) * helpers.surface_coeff() # whole surface of the cell my_lambda = float(n_spots) / float(nuw) # spot's volumic density k = self.ripley_k_point_process( nuw=nuw, my_lambda=my_lambda ) # TODO : first call for _all_ spots while the subsequent only for those in the height_map k_sim = np.zeros( (constants.analysis_config["RIPLEY_K_SIMULATION_NUMBER"], constants.analysis_config["MAX_CELL_RADIUS"])) # simulate RIPLEY_K_SIMULATION_NUMBER lists of random spots and run ripley_k for t in tqdm.tqdm(range( constants.analysis_config["RIPLEY_K_SIMULATION_NUMBER"]), desc="Simulations"): random_spots = self.compute_random_spots() tmp_k = self.ripley_k_point_process(spots=random_spots, nuw=nuw, my_lambda=my_lambda).flatten() k_sim[t] = tmp_k h = np.subtract( np.sqrt(k / math.pi), np.arange(1, constants.analysis_config["MAX_CELL_RADIUS"] + 1).reshape( (constants.analysis_config["MAX_CELL_RADIUS"], 1))) synth5, synth50, synth95 = helpers.compute_statistics_random_h_star_2d( h_sim=k_sim) return helpers.compute_h_star_2d(h, synth5, synth50, synth95)
def compute_density_per_quadrant(self, mtoc_quad, quadrant_mask, cell_mask, quadrants_num=4) -> np.ndarray: """ Given an quadrant mask and the number of the MTOC containing quadrant, compute surfacic density per quadrant; return an array of values of density paired with the MTOC presence flag (0/1) """ surface_coeff = helpers.surface_coeff() spots = self.get_cytoplasmic_spots() density_per_quadrant = np.zeros((quadrants_num, 2)) for spot in spots: spot_quad = quadrant_mask[spot[1], spot[0]] density_per_quadrant[spot_quad - 1, 0] += 1 # mark the mtoc quadrant density_per_quadrant[mtoc_quad - 1, 1] = 1 for quad_num in range(quadrants_num): density_per_quadrant[ quad_num, 0] = density_per_quadrant[quad_num, 0] / (np.sum( cell_mask[quadrant_mask == quad_num + 1]) * surface_coeff) return density_per_quadrant
def compute_cell_area(self): """compute cell surface in real pixel size using cell mask""" cell_mask = self.get_cell_mask() area = cell_mask.sum() * helpers.surface_coeff() # * by pixel dimensions return area
def compute_nucleus_area(self): """compute nucleus surface in pixel using nucleus mask""" nucleus_mask = self.get_nucleus_mask() area = nucleus_mask.sum() * helpers.surface_coeff() # * by pixel dimensions return area
def compute_density_per_quadrant(self, mtoc_quad, quadrant_mask, cell_mask, quadrants_num=4) -> np.ndarray: """ Given a quadrant mask and number of MTOC containing quadrant, compute 2D density per quadrant; return an array of values of density paired with the MTOC presence flag (0/1) """ IF = self.compute_cytoplasmic_intensities() density_per_quadrant = np.zeros((quadrants_num, 2)) # mark the MTOC quadrant density_per_quadrant[mtoc_quad - 1, 1] = 1 for quad_num in range(quadrants_num): density_per_quadrant[quad_num, 0] = np.sum(IF[quadrant_mask == (quad_num + 1)]) / \ (np.sum( cell_mask[quadrant_mask == quad_num + 1]) * helpers.surface_coeff()) if density_per_quadrant[:, 1].sum() != 1.0: raise (RuntimeError, "error in the MTOC quadrant detection for image %s" % self._path) return density_per_quadrant