topostats.classes ================= .. py:module:: topostats.classes .. autoapi-nested-parse:: Define custom classes for TopoStats. .. !! processed by numpydoc !! Attributes ---------- .. autoapisummary:: topostats.classes.LOGGER Classes ------- .. autoapisummary:: topostats.classes.GrainCrop topostats.classes.DisorderedTrace topostats.classes.TopoStats topostats.classes.MatchedBranch topostats.classes.UnMatchedBranch topostats.classes.Node topostats.classes.OrderedTrace topostats.classes.Molecule Functions --------- .. autoapisummary:: topostats.classes.validate_full_mask_tensor_shape topostats.classes.convert_to_dict Module Contents --------------- .. py:data:: LOGGER .. py:class:: GrainCrop(image: numpy.typing.NDArray[numpy.float32], mask: numpy.typing.NDArray[numpy.bool_], padding: int, bbox: tuple[int, int, int, int], pixel_to_nm_scaling: float, thresholds: list[float], filename: str, threshold: str | None = None, skeleton: numpy.typing.NDArray[numpy.bool_] | None = None, convolved_skeleton: numpy.typing.NDArray[numpy.int32] | None = None, height_profiles: dict[int, dict[int, numpy.typing.NDArray[numpy.float32]]] | None = None, stats: dict[int, dict[int, Any]] | None = None, disordered_trace: DisorderedTrace | None = None, nodes: dict[str, Node] | None = None, ordered_trace: OrderedTrace | None = None, threshold_method: str | None = None) Class for storing the crops of grains. :param image: 2-D Numpy array of the cropped image. :type image: npt.NDArray[np.float32] :param mask: 3-D Numpy tensor of the cropped mask. :type mask: npt.NDArray[np.bool_] :param padding: Padding added to the bounding box of the grain during cropping. :type padding: int :param bbox: Bounding box of the crop including padding. :type bbox: tuple[int, int, int, int] :param pixel_to_nm_scaling: Pixel to nanometre scaling factor for the crop. :type pixel_to_nm_scaling: float :param thresholds: Thresholds used to find the grain. :type thresholds: list[float] :param filename: Filename of the image from which the crop was taken. :type filename: str :param threshold: Direction of the molecule from the threshold (above / below). :type threshold: str :param skeleton: 3-D Numpy tensor of the skeletonised mask. :type skeleton: npt.NDArray[np.bool_] :param convolved_skeleton: 2-D Numpy array of the convolved skeleton. :type convolved_skeleton: npt.NDArray[np.int32] | None = None :param height_profiles: Nested dictionary height profiles. :type height_profiles: dict[int, dict[int, npt.NDArray[np.float32]]] | None :param stats: Dictionary of grain statistics. :type stats: dict[int, dict[int, Any]] | None :param disordered_trace: A disordered trace for the grain. :type disordered_trace: DisorderedTrace :param nodes: Dictionary of grain nodes. :type nodes: dict[str, Node] :param ordered_trace: An ordered trace for the grain. :type ordered_trace: OrderedTrace :param threshold_method: Threshold method used to find grains. :type threshold_method: str .. !! processed by numpydoc !! .. py:property:: padding :type: int Getter for the ``padding`` attribute. :returns: The padding amount. :rtype: int .. !! processed by numpydoc !! .. py:property:: image :type: numpy.typing.NDArray[float] Getter for the ``image`` attribute. :returns: Numpy array of the image. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:property:: mask :type: numpy.typing.NDArray[numpy.bool_] Getter for the ``mask`` attribute. :returns: Numpy array of the mask. :rtype: npt.NDArray[np.bool_] .. !! processed by numpydoc !! .. py:property:: bbox :type: tuple[int, int, int, int] Getter for the bounding box attribute. :returns: Bounding box of the crop. :rtype: tuple :raises ValueError: If the bounding box is not square. .. !! processed by numpydoc !! .. py:property:: pixel_to_nm_scaling :type: float Getter for the pixel to nanometre scaling factor attribute. :returns: Pixel to nanometre scaling factor. :rtype: float .. !! processed by numpydoc !! .. py:property:: thresholds :type: list[float] Getter for the ``thresholds`` attribute. :returns: Returns the value of ``thresholds``. :rtype: list[float] .. !! processed by numpydoc !! .. py:property:: filename :type: str Getter for the ``filename`` attribute. :returns: The image ``filename`` attribute. :rtype: str .. !! processed by numpydoc !! .. py:attribute:: threshold :type: str | None :value: None .. py:property:: height_profiles :type: numpy.typing.NDArray Getter for the ``height_profile`` attribute. :returns: The image height_profile. :rtype: str .. !! processed by numpydoc !! .. py:property:: stats :type: dict[str, Any] Getter for the stats. :returns: Dictionary of image statistics. :rtype: str .. !! processed by numpydoc !! .. py:property:: skeleton :type: numpy.typing.NDArray Getter for the ``skeleton`` attribute. :returns: Returns the value of ``skeleton``. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:attribute:: convolved_skeleton :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:property:: disordered_trace :type: DisorderedTrace Getter for the ``disordered_trace`` attribute. :returns: **dict[str** -- Returns the value of ``disordered_trace``. :rtype: Any] .. !! processed by numpydoc !! .. py:property:: nodes :type: dict[int, Node] Getter for the ``nodes`` attribute. :returns: Returns ``nodes``, a dictionary of Nodes. :rtype: dict[int, Nodes] .. !! processed by numpydoc !! .. py:property:: ordered_trace :type: OrderedTrace Getter for the ``ordered_trace`` attribute. :returns: **dict[str** -- Returns the value of ``ordered_trace``. :rtype: Any] .. !! processed by numpydoc !! .. py:property:: threshold_method :type: list[float] The ``threshold_method`` used to find the grain. :returns: Returns the value of ``threshold_method``. :rtype: list[float] .. !! processed by numpydoc !! .. py:method:: __eq__(other: object) -> bool Check if two GrainCrop objects are equal. :param other: Object to compare to. :type other: object :returns: True if the objects are equal, False otherwise. :rtype: bool .. !! processed by numpydoc !! .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted statistics on matched branches. :rtype: str .. !! processed by numpydoc !! .. py:method:: debug_locate_difference(other: object) -> None Debug function to find the culprit when two GrainCrop objects are not equal. :param other: Object to compare to. :type other: object :raises ValueError: If the objects are not equal .. !! processed by numpydoc !! .. py:function:: validate_full_mask_tensor_shape(array: numpy.typing.NDArray[numpy.bool_]) -> numpy.typing.NDArray[numpy.bool_] Validate the shape of the full mask tensor. :param array: Numpy array to validate. :type array: npt.NDArray :returns: Numpy array if valid. :rtype: npt.NDArray .. !! processed by numpydoc !! .. py:class:: DisorderedTrace Dataclass for storing the disordered tracing data. .. attribute:: images Dictionary of images generated during disordered tracing, should include ''pruned_skeleton''. :type: dict[str: npt.NDArray] .. attribute:: grain_endpoints Number of Grain endpoints. :type: int .. attribute:: grain_junctions Number of Grain junctions. :type: int .. attribute:: total_branch_length Total branch length in nanometres. :type: float .. attribute:: grain_width_mean Mean grain width in nanometres. :type: float .. attribute:: stats Dictionary of stats for each branch of a grain. :type: dict[int, Any] .. !! processed by numpydoc !! .. py:attribute:: images :type: dict[str, numpy.typing.NDArray] | None :value: None .. py:attribute:: grain_endpoints :type: int | None :value: None .. py:attribute:: grain_junctions :type: int | None :value: None .. py:attribute:: total_branch_length :type: float | None :value: None .. py:attribute:: grain_width_mean :type: float | None :value: None .. py:attribute:: stats :type: dict[int, Any] | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted statistics on matched branches. :rtype: str .. !! processed by numpydoc !! .. py:class:: TopoStats Class for storing TopoStats objects. .. attribute:: grain_crops Dictionary of ``GrainCrop`` objects. :type: dict[int, GrainCrop] | None .. attribute:: filename Filename. :type: str | None .. attribute:: image_name Filename without its extension. :type: str | None .. attribute:: pixel_to_nm_scaling Pixel to nanometre scaling. :type: str | None .. attribute:: img_path Original path to image. :type: str | None .. attribute:: image Flattened image (post ``Filter()``). :type: npt.NDArray | None .. attribute:: image_original Original image. :type: npt.NDArray | None .. attribute:: image_statistics Pandas dataframe of :type: pd.DataFrame | None .. attribute:: full_mask_tensor Tensor mask for the full image. :type: npt.NDArray .. attribute:: topostats_version TopoStats version. :type: str | None .. attribute:: config Configuration used when processing the grain. :type: dict[str, Any] | None .. attribute:: full_image_plots Dictionary of numpy arrays where disordered tracing, nodestats and ordered tracing skeletons are mapped back to the original image. :type: dict[str, npt.NDArray[np.float64]] .. attribute:: basename Basename of image locations. :type: str .. !! processed by numpydoc !! .. py:attribute:: grain_crops :type: dict[int, GrainCrop] | None :value: None .. py:attribute:: filename :type: str | None :value: None .. py:attribute:: image_name :type: str | None :value: None .. py:attribute:: pixel_to_nm_scaling :type: float | None :value: None .. py:attribute:: img_path :type: pathlib.Path | str | None :value: None .. py:attribute:: image :type: numpy.typing.NDArray | None :value: None .. py:attribute:: image_original :type: numpy.typing.NDArray | None :value: None .. py:attribute:: image_statistics :type: dict[str, int | float | str] | None :value: None .. py:attribute:: full_mask_tensor :type: numpy.typing.NDArray | None :value: None .. py:attribute:: topostats_version :type: str | None :value: None .. py:attribute:: config :type: dict[str, Any] | None :value: None .. py:attribute:: full_image_plots :type: dict[str, numpy.typing.NDArray[numpy.float64]] | None :value: None .. py:attribute:: basename :type: str | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted and user-friendly statistics. :rtype: str .. !! processed by numpydoc !! .. py:method:: __eq__(other: object) -> bool Check if two ``TopoStats`` objects are equal. :param other: Other ``TopoStats`` object to compare to. :type other: object :returns: ``True`` if the objects are equal, ``False`` otherwise. :rtype: bool .. !! processed by numpydoc !! .. py:method:: calculate_image_statistics() -> dict[str, int | float] Calculate the image statistics via ``statistics.image_statistics()``. :returns: Dictionary of image size and area in both metres and pixels, the number of grains, density and the root mean square of the image roughness. :rtype: dict[str, int | float] .. !! processed by numpydoc !! .. py:class:: MatchedBranch Class for storing matched branches data and attributes. .. attribute:: ordered_coords Numpy array of ordered coordinates. :type: npt.NDArray[np.int32] .. attribute:: heights Numpy array of heights. :type: npt.NDArray[np.number] .. attribute:: distances Numpy array of distances. :type: npt.NDArray[np.number] .. attribute:: fwhm Full-width half maximum. :type: float .. attribute:: fwhm_half_maxs Half-maximums from a matched branch. :type: list[float] .. attribute:: fwhm_peaks Peaks from a matched branch. :type: list[int | float] .. attribute:: angles Angle between branches. :type: float .. attribute:: branch_statistics Dictionary of branch statistics, ``fwhm``, ``fwhm_half_maxs`` and ``fwhm_peaks``. :type: dict[str, float | int | list[Any] | str] .. !! processed by numpydoc !! .. py:attribute:: ordered_coords :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:attribute:: heights :type: numpy.typing.NDArray[numpy.number] | None :value: None .. py:attribute:: distances :type: numpy.typing.NDArray[numpy.number] | None :value: None .. py:attribute:: fwhm :type: float | None :value: None .. py:attribute:: fwhm_half_maxs :type: list[float] | None :value: None .. py:attribute:: fwhm_peaks :type: list[float] | None :value: None .. py:attribute:: angles :type: float | list[float] | None :value: None .. py:attribute:: branch_statistics :type: dict[str, float | int | list[Any] | str] | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted and user-friendly statistics. :rtype: str .. !! processed by numpydoc !! .. py:method:: collate_branch_statistics(image: str, basename: str) -> dict[str, float | int | list[Any] | str] Collate matched branch statistics to dictionary. :param image: Image being processed, added to dictionary for subsequent aggregation, typically ``TopoStats.filename``. :type image: str :param basename: Base image path, added to dictionary for subsequent aggregation, typically ``TopoStats.img_path``. :type basename: str :returns: Dictionary of ``fwhm``, ``fwhm_half_maxs`` and ``fwhm_peaks`` along with ``image`` and ``basename``. :rtype: dict[str, float | int | list[Any] | str] .. !! processed by numpydoc !! .. py:class:: UnMatchedBranch Class for storing matched branches data and attributes. .. attribute:: angles Angle between branches. :type: float .. !! processed by numpydoc !! .. py:attribute:: angles :type: float | list[float] | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted and user-friendly statistics. :rtype: str .. !! processed by numpydoc !! .. py:class:: Node Class for storing Node data and attributes. .. attribute:: error Whether an error occurred calculating statistics for this node. :type: bool .. attribute:: pixel_to_nm_scaling Pixel to nanometre scaling. :type: np.float64 .. attribute:: branch_stats Dictionary of ``MatchedBranch`` objects. :type: dict[int, MatchedBranch] .. attribute:: unmatched_branch_stats Dictionary of ``UnmatchedBranch`` objects. :type: dict[int, UnMatchedBranch] .. attribute:: node_coords Numpy array of node coordinates. :type: npt.NDArray[np.int32] .. attribute:: confidence Normalised confidence of the crossing in the range of ``0-1``. :type: np.float64 .. attribute:: reduced_node_area The molecule skeleton, with all branches removed that are not connected to the current node. :type: npt.NDArray[np.int32] .. attribute:: node_area_skeleton Numpy array of skeleton. :type: npt.NDArray[np.int32] .. attribute:: node_branch_mask Numpy array of branch mask. :type: npt.NDArray[np.int32] .. attribute:: node_avg_mask Numpy array of averaged mask. :type: npt.NDArray[np.int32] .. attribute:: writhe Writhe type for the node. :type: str .. !! processed by numpydoc !! .. py:attribute:: error :type: bool | None :value: None .. py:attribute:: pixel_to_nm_scaling :type: float | None :value: None .. py:attribute:: branch_stats :type: dict[int, MatchedBranch] | None :value: None .. py:attribute:: unmatched_branch_stats :type: dict[int, UnMatchedBranch] | None :value: None .. py:attribute:: node_coords :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:attribute:: confidence :type: float | None :value: None .. py:attribute:: reduced_node_area :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:attribute:: node_area_skeleton :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:attribute:: node_branch_mask :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:attribute:: node_avg_mask :type: numpy.typing.NDArray[numpy.int32] | None :value: None .. py:attribute:: writhe :type: str | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted and user-friendly statistics. :rtype: str .. !! processed by numpydoc !! .. py:class:: OrderedTrace Class for Ordered Trace data and attributes. molecule_data : dict[int, Molecule] Dictionary of ``Molecule`` objects indexed by molecule number. tracing_stats : dict | None Tracing statistics. grain_molstats : Any | None Grain molecule statistics. molecules : int Number of molecules within the grain. writhe : str The writhe sign, can be either `+`, `-` or `0` for positive, negative or no writhe. pixel_to_nm_scaling: np.float64 | None Pixel to nm scaling. images: dict[str, npt.NDArray] | None Diagnostic images produced during processing. error: bool | None Errors encountered? molecule_statistics : dict[int, dict[str, bool | str | float | None]] | None Dictionary of molecule statistics, with one entry for each molecule. .. !! processed by numpydoc !! .. py:attribute:: molecule_data :type: dict[int, Molecule] | None :value: None .. py:attribute:: tracing_stats :type: dict | None :value: None .. py:attribute:: grain_molstats :type: Any | None :value: None .. py:attribute:: molecules :type: int | None :value: None .. py:attribute:: writhe :type: str | None :value: None .. py:attribute:: pixel_to_nm_scaling :type: float | None :value: None .. py:attribute:: images :type: dict[str, numpy.typing.NDArray] | None :value: None .. py:attribute:: error :type: bool | None :value: None .. py:attribute:: molecule_statistics :type: dict[int, dict[str, bool | str | float | None]] | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted and user-friendly statistics. :rtype: str .. !! processed by numpydoc !! .. py:method:: collate_molecule_statistics() -> dict[int, dict[str, bool | int | str | None]] Collate molecule statistics for all molecules to dictionary. The resulting dictionary can be easily converted to Pandas Dataframes for writing to CSV. :returns: Dictionary, indexed by molecule where the value is the molecules statistics for the given molecule. :rtype: dict[int, dict[str, bool | int | str | None]] .. !! processed by numpydoc !! .. py:class:: Molecule Class for Molecules identified during ordered tracing. threshold : str Direction from threshold of molecule (above / below) molecule_number : int Index of the molecule (per grain) circular : str, bool, optional Whether the molecule is circular or linear. processing : str Which processing type was used, topostats or nodestats. topology : str, optional Topological classification of the molecule. topology_flip : Any, optional Unknown? ordered_coords : npt.NDArray, optional Ordered coordinates for the molecule. splined_coords : npt.NDArray, optional Smoothed (aka splined) coordinates for the molecule. contour_length : float Length of the molecule. end_to_end_distance : float Distance between ends of molecule. Will be ``0.0`` for circular molecules which don't have ends. heights : npt.NDArray Height along molecule. distances : npt.NDArray Distance between points on the molecule. curvature_stats : npt.NDArray, optional Angle changes along molecule. NB - These are always positive due to use of ``np.abs()`` during calculation. bbox : tuple[int, int, int, int], optional Bounding box. .. !! processed by numpydoc !! .. py:attribute:: threshold :type: str | None :value: None .. py:attribute:: molecule_number :type: int | None :value: None .. py:attribute:: circular :type: str | bool | None :value: None .. py:attribute:: processing :type: str | None :value: None .. py:attribute:: topology :type: str | None :value: None .. py:attribute:: topology_flip :type: Any | None :value: None .. py:attribute:: ordered_coords :type: numpy.typing.NDArray | None :value: None .. py:attribute:: splined_coords :type: numpy.typing.NDArray | None :value: None .. py:attribute:: contour_length :type: float | None :value: None .. py:attribute:: end_to_end_distance :type: float | None :value: None .. py:attribute:: heights :type: numpy.typing.NDArray | None :value: None .. py:attribute:: distances :type: numpy.typing.NDArray | None :value: None .. py:attribute:: curvature_stats :type: numpy.typing.NDArray | None :value: None .. py:attribute:: bbox :type: tuple[int, int, int, int] | None :value: None .. py:attribute:: molecule_statistics :type: dict[str, bool | str | float | None] | None :value: None .. py:method:: __str__() -> str Representation function for useful statistics for the class. :returns: Set of formatted and user-friendly statistics. :rtype: str .. !! processed by numpydoc !! .. py:method:: collate_molecule_statistics() -> dict[str, bool | str | float | None] Collate the molecule statsistics to a dictionary. :returns: Dataframe of the classes attributes and their data. :rtype: dict[str, bool | str | float | None] .. !! processed by numpydoc !! .. py:function:: convert_to_dict(to_convert: Any) -> dict[str, Any] Convert a class to a dictionary representation of itself. Classes that are part of the ``topostats`` package (``TopoStats``, ``GrainCrop``, ``DisorderedTrace``, ``Node``, ``OrderedTrace``, ``MatchedBranch``, ``UnMatchedBranch`` and ``Molecule``) can be converted to dictionaries along with any other class that has the ``__dict__`` attribute. The keys are the attribute names (with the ``_`` prefix removed) and the values are the stored values of the attribute. Values of type ``str``, ``int``, ``float``, ``bool``, ``tuple``, ``np.ndarray`` and ``pathlib.Path`` are returned as is. If a value is itself a dictionary (e.g. ``TopoStats.grain_crops`` ``Node.branch_stats`` or ``OrderedTrace.molecule_data`` which are all dictionaries of the objects) then the object is recursed. If lists or dictionaries are provided a ``TypeError`` is raised and any object that doesn't have the ``__dict__`` attribute then an ``AttributeError`` is raised. :param to_convert: An object to be converted to a dictionary / dictionary item. :type to_convert: dict[str, Any] :returns: Input parameter as a dictionary / dictionary item. :rtype: Any .. !! processed by numpydoc !!