Source code for deepblink.data

"""List of functions to handle data including converting matrices <-> coordinates."""


from typing import Tuple
import math
import operator

import numpy as np


[docs]def next_power(x: int, k: int = 2) -> int: """Calculate x's next higher power of k.""" y, power = 0, 1 while y < x: y = k ** power power += 1 return y
[docs]def next_multiple(x: int, k: int = 512) -> int: """Calculate x's closest higher multiple of base k.""" if x % k: x = x + (k - x % k) return x
[docs]def normalize_image(image: np.ndarray) -> np.ndarray: """Normalize image to a mean of zero and a standard deviation of one.""" image = (image - image.mean()) / image.std() return image.astype(np.float32)
[docs]def get_coordinate_list( matrix: np.ndarray, image_size: int = 512, probability: float = 0.5 ) -> np.ndarray: """Convert the prediction matrix into a list of coordinates. NOTE - plt.scatter uses the x, y system. Therefore any plots must be inverted by assigning x=c, y=r! Args: matrix: Matrix representation of spot coordinates. image_size: Default image size the grid was layed on. probability: Cutoff value to round model prediction probability. Returns: Array of r, c coordinates with the shape (n, 2). """ if not matrix.ndim == 3: raise ValueError("Matrix must have a shape of (r, c, 3).") if not matrix.shape[2] == 3: raise ValueError("Matrix must have a depth of 3.") if not matrix.shape[0] == matrix.shape[1] and not matrix.shape[0] >= 1: raise ValueError("Matrix must have equal length >= 1 of r, c.") matrix_size = max(matrix.shape) cell_size = image_size // matrix_size coords_r = [] coords_c = [] # Top left coordinates of every cell grid = np.array([c * cell_size for c in range(matrix_size)]) # Coordinates of cells > 0.5 matrix_r, matrix_c, *_ = np.where(matrix[..., 0] > probability, 1, 0).nonzero() for r, c in zip(matrix_r, matrix_c): grid_r = grid[r] grid_c = grid[c] spot_r = matrix[r, c, 1] spot_c = matrix[r, c, 2] coord_abs = absolute_coordinate( coord_spot=(spot_r, spot_c), coord_cell=(grid_r, grid_c), cell_size=cell_size, ) coords_r.append(coord_abs[0]) coords_c.append(coord_abs[1]) return np.array([coords_r, coords_c]).T
[docs]def absolute_coordinate( coord_spot: Tuple[np.float32, np.float32], coord_cell: Tuple[np.float32, np.float32], cell_size: int = 4, ) -> Tuple[np.float32, np.float32]: """Return the absolute image coordinate from a relative cell coordinate. Args: coord_spot: Relative spot coordinate in format (r, c). coord_cell: Top-left coordinate of the cell. cell_size: Size of one cell in a grid. Returns: Absolute coordinate. """ if not len(coord_spot) == len(coord_cell) == 2: raise ValueError( f"coord_spot, coord_cell must have format (r, c). Lengths are {len(coord_spot), len(coord_cell)} resp." ) coord_rel = tuple(map(lambda x: x * cell_size, coord_spot)) coord_abs = tuple(map(operator.add, coord_cell, coord_rel)) return coord_abs # type: ignore
[docs]def get_prediction_matrix( coords: np.ndarray, image_size: int, cell_size: int = 4, size_c: int = None ) -> np.ndarray: """Return np.ndarray of shape (n, n, 3): p, r, c format for each cell. Args: coords: List of coordinates in r, c format with shape (n, 2). image_size: Size of the image from which List of coordinates are extracted. cell_size: Size of one grid cell inside the matrix. A cell_size of 2 means that one cell corresponds to 2 pixels in the original image. size_c: If empty, assumes a squared image. Else the length of the r axis. Returns: The prediction matrix as numpy array of shape (n, n, 3): p, r, c format for each cell. """ nrow = ncol = math.ceil(image_size / cell_size) if size_c is not None: ncol = math.ceil(size_c / cell_size) prediction_matrix = np.zeros((nrow, ncol, 3)) for r, c in coords: # Position of cell coordinate in prediction matrix cell_r = min(nrow - 1, int(np.floor(r)) // cell_size) cell_c = min(ncol - 1, int(np.floor(c)) // cell_size) # Relative position within cell relative_r = (r - cell_r * cell_size) / cell_size relative_c = (c - cell_c * cell_size) / cell_size # Assign values along prediction matrix dimension 3 prediction_matrix[cell_r, cell_c] = 1, relative_r, relative_c return prediction_matrix