topostats.tracing.disordered_tracing ==================================== .. py:module:: topostats.tracing.disordered_tracing .. autoapi-nested-parse:: Generates disordered traces (pruned skeletons) and metrics. .. !! processed by numpydoc !! Attributes ---------- .. autoapisummary:: topostats.tracing.disordered_tracing.LOGGER Classes ------- .. autoapisummary:: topostats.tracing.disordered_tracing.disorderedTrace Functions --------- .. autoapisummary:: topostats.tracing.disordered_tracing.trace_image_disordered topostats.tracing.disordered_tracing.compile_skan_stats topostats.tracing.disordered_tracing.segment_heights topostats.tracing.disordered_tracing.segment_middles topostats.tracing.disordered_tracing.find_connections topostats.tracing.disordered_tracing.prep_arrays topostats.tracing.disordered_tracing.grain_anchor topostats.tracing.disordered_tracing.disordered_trace_grain topostats.tracing.disordered_tracing.get_skan_image topostats.tracing.disordered_tracing.crop_array topostats.tracing.disordered_tracing.pad_bounding_box Module Contents --------------- .. py:data:: LOGGER .. py:class:: disorderedTrace(image: numpy.typing.NDArray, mask: numpy.typing.NDArray, filename: str, pixel_to_nm_scaling: float, min_skeleton_size: int = 10, mask_smoothing_params: dict | None = None, skeletonisation_params: dict | None = None, pruning_params: dict | None = None, n_grain: int = None) Calculate disordered traces for a DNA molecule and calculates statistics from those traces. :param image: Cropped image, typically padded beyond the bounding box. :type image: npt.NDArray :param mask: Labelled mask for the grain, typically padded beyond the bounding box. :type mask: npt.NDArray :param filename: Filename being processed. :type filename: str :param pixel_to_nm_scaling: Pixel to nm scaling. :type pixel_to_nm_scaling: float :param min_skeleton_size: Minimum skeleton size below which tracing statistics are not calculated. :type min_skeleton_size: int :param mask_smoothing_params: Dictionary of parameters to smooth the grain mask for better quality skeletonisation results. Contains a gaussian 'sigma' and number of dilation iterations. :type mask_smoothing_params: dict :param skeletonisation_params: Skeletonisation Parameters. Method of skeletonisation to use 'topostats' is the original TopoStats method. Three methods from scikit-image are available 'zhang', 'lee' and 'thin'. :type skeletonisation_params: dict :param pruning_params: Dictionary of pruning parameters. Contains 'method', 'max_length', 'height_threshold', 'method_values' and 'method_outlier'. :type pruning_params: dict :param n_grain: Grain number being processed (only used in logging). :type n_grain: int .. !! processed by numpydoc !! .. py:attribute:: image .. py:attribute:: mask .. py:attribute:: filename .. py:attribute:: pixel_to_nm_scaling .. py:attribute:: min_skeleton_size :value: 10 .. py:attribute:: mask_smoothing_params :value: None .. py:attribute:: skeletonisation_params :value: None .. py:attribute:: pruning_params :value: None .. py:attribute:: n_grain :value: None .. py:attribute:: smoothed_mask .. py:attribute:: skeleton .. py:attribute:: pruned_skeleton .. py:attribute:: disordered_trace :value: None .. py:method:: trace_dna() Perform the DNA skeletonisation and cleaning pipeline. .. !! processed by numpydoc !! .. py:method:: re_add_holes(orig_mask: numpy.typing.NDArray, smoothed_mask: numpy.typing.NDArray, holearea_min_max: tuple[float | int | None] = (2, None)) -> numpy.typing.NDArray Restore holes in masks that were occluded by dilation. As Gaussian dilation smoothing methods can close holes in the original mask, this function obtains those holes (based on the general background being the first due to padding) and adds them back into the smoothed mask. When paired with ``smooth_mask``, this essentially just smooths the outer edge of the mask. :param orig_mask: Original mask. :type orig_mask: npt.NDArray :param smoothed_mask: Original mask but with inner and outer edged smoothed. The smoothing operation may have closed up important holes in the mask. :type smoothed_mask: npt.NDArray :param holearea_min_max: Tuple of minimum and maximum hole area (in nanometers) to replace from the original mask into the smoothed mask. :type holearea_min_max: tuple[float | int | None] :returns: Smoothed mask with holes restored. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:method:: remove_touching_edge(skeleton: numpy.typing.NDArray) -> numpy.typing.NDArray :staticmethod: Remove any skeleton points touching the border (to prevent errors later). :param skeleton: A binary array where touching clusters of 1's become 0's if touching the edge of the array. :type skeleton: npt.NDArray :returns: Skeleton without points touching the border. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:method:: smooth_mask(grain: numpy.typing.NDArray, dilation_iterations: int = 2, gaussian_sigma: float | int = 2, holearea_min_max: tuple[int | float | None] = (0, None)) -> numpy.typing.NDArray Smooth a grain mask based on the lower number of binary pixels added from dilation or gaussian. This method ensures gaussian smoothing isn't too aggressive and covers / creates gaps in the mask. :param grain: Numpy array of the grain mask. :type grain: npt.NDArray :param dilation_iterations: Number of times to dilate the grain to smooth it. Default is 2. :type dilation_iterations: int :param gaussian_sigma: Gaussian sigma value to smooth the grains after an Otsu threshold. If None, defaults to 2. :type gaussian_sigma: float | None :param holearea_min_max: Tuple of minimum and maximum hole area (in nanometers) to replace from the original mask into the smoothed mask. :type holearea_min_max: tuple[float | int | None] :returns: Numpy array of smoothed image. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:method:: calculate_dna_width(smoothed_mask: numpy.typing.NDArray, pruned_skeleton: numpy.typing.NDArray, pixel_to_nm_scaling: float = 1) -> float :staticmethod: Calculate the mean width in metres of the DNA using the trace and mask. :param smoothed_mask: Smoothed mask to be measured. :type smoothed_mask: npt.NDArray :param pruned_skeleton: Pruned skeleton. :type pruned_skeleton: npt.NDArray :param pixel_to_nm_scaling: Scaling of pixels to nanometres. :type pixel_to_nm_scaling: float :returns: Width of grain in metres. :rtype: float .. !! processed by numpydoc !! .. py:function:: trace_image_disordered(image: numpy.typing.NDArray, grains_mask: numpy.typing.NDArray, filename: str, pixel_to_nm_scaling: float, min_skeleton_size: int, mask_smoothing_params: dict, skeletonisation_params: dict, pruning_params: dict, pad_width: int = 1) -> tuple[dict, pandas.DataFrame, dict, pandas.DataFrame] Processor function for tracing image. :param image: Full image as Numpy Array. :type image: npt.NDArray :param grains_mask: Full image as Grains that are labelled. :type grains_mask: npt.NDArray :param filename: File being processed. :type filename: str :param pixel_to_nm_scaling: Pixel to nm scaling. :type pixel_to_nm_scaling: float :param min_skeleton_size: Minimum size of grain in pixels after skeletonisation. :type min_skeleton_size: int :param mask_smoothing_params: Dictionary of parameters to smooth the grain mask for better quality skeletonisation results. Contains a gaussian 'sigma' and number of dilation iterations. :type mask_smoothing_params: dict :param skeletonisation_params: Dictionary of options for skeletonisation, options are 'zhang' (scikit-image) / 'lee' (scikit-image) / 'thin' (scikitimage) or 'topostats' (original TopoStats method). :type skeletonisation_params: dict :param pruning_params: Dictionary of options for pruning. :type pruning_params: dict :param pad_width: Padding to the cropped image mask. :type pad_width: int :returns: Binary and integer labeled cropped and full-image masks from skeletonising and pruning the grains in the image. :rtype: tuple[dict, pd.DataFrame, dict, pd.DataFrame] .. !! processed by numpydoc !! .. py:function:: compile_skan_stats(skan_df: pandas.DataFrame, skan_skeleton: skan.Skeleton, image: numpy.typing.NDArray, filename: str, grain_number: int) -> pandas.DataFrame Obtain and add more stats to the resultant Skan dataframe. :param skan_df: The statistics DataFrame produced by Skan's `summarize` function. :type skan_df: pd.DataFrame :param skan_skeleton: The graphical representation of the skeleton produced by Skan. :type skan_skeleton: skan.Skeleton :param image: The image the skeleton was produced from. :type image: npt.NDArray :param filename: Name of the file being processed. :type filename: str :param grain_number: The number of the grain being processed. :type grain_number: int :returns: A dataframe containing the filename, grain_number, branch-distance, branch-type, connected_segments, mean-pixel-value, stdev-pixel-value, min-value, median-value, and mid-value. :rtype: pd.DataFrame .. !! processed by numpydoc !! .. py:function:: segment_heights(row: pandas.Series, skan_skeleton: skan.Skeleton, image: numpy.typing.NDArray) -> numpy.typing.NDArray Obtain an ordered list of heights from the skan defined skeleton segment. :param row: A row from the Skan summarize dataframe. :type row: pd.Series :param skan_skeleton: The graphical representation of the skeleton produced by Skan. :type skan_skeleton: skan.Skeleton :param image: The image the skeleton was produced from. :type image: npt.NDArray :returns: Heights along the segment, naturally ordered by Skan. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:function:: segment_middles(row: pandas.Series, skan_skeleton: skan.csr.Skeleton, image: numpy.typing.NDArray) -> float Obtain the pixel value in the middle of the ordered segment. :param row: A row from the Skan summarize dataframe. :type row: pd.Series :param skan_skeleton: The graphical representation of the skeleton produced by Skan. :type skan_skeleton: skan.csr.Skeleton :param image: The image the skeleton was produced from. :type image: npt.NDArray :returns: The single or mean pixel value corresponding to the middle coordinate(s) of the segment. :rtype: float .. !! processed by numpydoc !! .. py:function:: find_connections(row: pandas.Series, skan_df: pandas.DataFrame) -> str Compile the neighbouring branch indexes of the row. :param row: A row from the Skan summarize dataframe. :type row: pd.Series :param skan_df: The statistics DataFrame produced by Skan's `summarize` function. :type skan_df: pd.DataFrame :returns: A string representation of a list of matching row indices where the node src and dst columns match that of the rows. String is needed for csv compatibility since csvs can't hold lists. :rtype: str .. !! processed by numpydoc !! .. py:function:: prep_arrays(image: numpy.typing.NDArray, labelled_grains_mask: numpy.typing.NDArray, pad_width: int) -> tuple[dict[int, numpy.typing.NDArray], dict[int, numpy.typing.NDArray]] Take an image and labelled mask and crops individual grains and original heights to a list. A second padding is made after cropping to ensure for "edge cases" where grains are close to bounding box edges that they are traced correctly. This is accounted for when aligning traces to the whole image mask. :param image: Gaussian filtered image. Typically filtered_image.images["gaussian_filtered"]. :type image: npt.NDArray :param labelled_grains_mask: 2D Numpy array of labelled grain masks, with each mask being comprised solely of unique integer (not zero). Typically this will be output from 'grains.directions[["labelled_region_02]'. :type labelled_grains_mask: npt.NDArray :param pad_width: Cells by which to pad cropped regions by. :type pad_width: int :returns: Returns a tuple of three dictionaries, the cropped images, cropped masks and bounding boxes. :rtype: Tuple .. !! processed by numpydoc !! .. py:function:: grain_anchor(array_shape: tuple, bounding_box: list, pad_width: int) -> list Extract anchor (min_row, min_col) from labelled regions and align individual traces over the original image. :param array_shape: Shape of original array. :type array_shape: tuple :param bounding_box: A list of region properties returned by 'skimage.measure.regionprops()'. :type bounding_box: list :param pad_width: Padding for image. :type pad_width: int :returns: A list of tuples of the min_row, min_col of each bounding box. :rtype: list(Tuple) .. !! processed by numpydoc !! .. py:function:: disordered_trace_grain(cropped_image: numpy.typing.NDArray, cropped_mask: numpy.typing.NDArray, pixel_to_nm_scaling: float, mask_smoothing_params: dict, skeletonisation_params: dict, pruning_params: dict, filename: str = None, min_skeleton_size: int = 10, n_grain: int = None) -> dict Trace an individual grain. Tracing involves multiple steps... 1. Skeletonisation 2. Pruning of side branches (artefacts from skeletonisation). 3. Ordering of the skeleton. :param cropped_image: Cropped array from the original image defined as the bounding box from the labelled mask. :type cropped_image: npt.NDArray :param cropped_mask: Cropped array from the labelled image defined as the bounding box from the labelled mask. This should have been converted to a binary mask. :type cropped_mask: npt.NDArray :param pixel_to_nm_scaling: Pixel to nm scaling. :type pixel_to_nm_scaling: float :param mask_smoothing_params: Dictionary of parameters to smooth the grain mask for better quality skeletonisation results. Contains a gaussian 'sigma' and number of dilation iterations. :type mask_smoothing_params: dict :param skeletonisation_params: Dictionary of skeletonisation parameters, options are 'zhang' (scikit-image) / 'lee' (scikit-image) / 'thin' (scikitimage) or 'topostats' (original TopoStats method). :type skeletonisation_params: dict :param pruning_params: Dictionary of pruning parameters. :type pruning_params: dict :param filename: File being processed. :type filename: str :param min_skeleton_size: Minimum size of grain in pixels after skeletonisation. :type min_skeleton_size: int :param n_grain: Grain number being processed. :type n_grain: int :returns: Dictionary of the contour length, whether the image is circular or linear, the end-to-end distance and an array of coordinates. :rtype: dict .. !! processed by numpydoc !! .. py:function:: get_skan_image(original_image: numpy.typing.NDArray, pruned_skeleton: numpy.typing.NDArray, skan_column: str) -> numpy.typing.NDArray Label each branch with it's Skan branch type label. Branch types (+1 compared to Skan docs) are defined as: 1 = Endpoint-to-endpoint (isolated branch) 2 = Junction-to-endpoint 3 = Junction-to-junction 4 = Isolated cycle :param original_image: Height image from which the pruned skeleton is derived from. :type original_image: npt.NDArray :param pruned_skeleton: Single pixel thick skeleton mask. :type pruned_skeleton: npt.NDArray :param skan_column: A column from Skan's summarize function to colour the branch segments with. :type skan_column: str :returns: 2D array where the background is 0, and skeleton branches label as their Skan branch type. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:function:: crop_array(array: numpy.typing.NDArray, bounding_box: tuple, pad_width: int = 0) -> numpy.typing.NDArray Crop an array. Ideally we pad the array that is being cropped so that we have heights outside of the grains bounding box. However, in some cases, if a grain is near the edge of the image scan this results in requesting indexes outside of the existing image. In which case we get as much of the image padded as possible. :param array: 2D Numpy array to be cropped. :type array: npt.NDArray :param bounding_box: Tuple of coordinates to crop, should be of form (min_row, min_col, max_row, max_col). :type bounding_box: Tuple :param pad_width: Padding to apply to bounding box. :type pad_width: int :returns: Cropped array. :rtype: npt.NDArray() .. !! processed by numpydoc !! .. py:function:: pad_bounding_box(array_shape: tuple, bounding_box: list, pad_width: int) -> list Pad coordinates, if they extend beyond image boundaries stop at boundary. :param array_shape: Shape of original image (row, columns). :type array_shape: tuple :param bounding_box: List of coordinates 'min_row', 'min_col', 'max_row', 'max_col'. :type bounding_box: list :param pad_width: Cells to pad arrays by. :type pad_width: int :returns: List of padded coordinates. :rtype: list .. !! processed by numpydoc !!