topostats.classes#

Define custom classes for TopoStats.

Attributes#

Classes#

GrainCrop

Class for storing the crops of grains.

DisorderedTrace

Dataclass for storing the disordered tracing data.

TopoStats

Class for storing TopoStats objects.

MatchedBranch

Class for storing matched branches data and attributes.

UnMatchedBranch

Class for storing matched branches data and attributes.

Node

Class for storing Node data and attributes.

OrderedTrace

Class for Ordered Trace data and attributes.

Molecule

Class for Molecules identified during ordered tracing.

Functions#

validate_full_mask_tensor_shape(...)

Validate the shape of the full mask tensor.

convert_to_dict(→ dict[str, Any])

Convert a class to a dictionary representation of itself.

Module Contents#

topostats.classes.LOGGER#
class topostats.classes.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)[source]#

Class for storing the crops of grains.

Parameters:
  • image (npt.NDArray[np.float32]) – 2-D Numpy array of the cropped image.

  • mask (npt.NDArray[np.bool_]) – 3-D Numpy tensor of the cropped mask.

  • padding (int) – Padding added to the bounding box of the grain during cropping.

  • bbox (tuple[int, int, int, int]) – Bounding box of the crop including padding.

  • pixel_to_nm_scaling (float) – Pixel to nanometre scaling factor for the crop.

  • thresholds (list[float]) – Thresholds used to find the grain.

  • filename (str) – Filename of the image from which the crop was taken.

  • threshold (str) – Direction of the molecule from the threshold (above / below).

  • skeleton (npt.NDArray[np.bool_]) – 3-D Numpy tensor of the skeletonised mask.

  • convolved_skeleton (npt.NDArray[np.int32] | None = None) – 2-D Numpy array of the convolved skeleton.

  • height_profiles (dict[int, dict[int, npt.NDArray[np.float32]]] | None) – Nested dictionary height profiles.

  • stats (dict[int, dict[int, Any]] | None) – Dictionary of grain statistics.

  • disordered_trace (DisorderedTrace) – A disordered trace for the grain.

  • nodes (dict[str, Node]) – Dictionary of grain nodes.

  • ordered_trace (OrderedTrace) – An ordered trace for the grain.

  • threshold_method (str) – Threshold method used to find grains.

property padding: int#

Getter for the padding attribute.

Returns:

The padding amount.

Return type:

int

property image: numpy.typing.NDArray[float]#

Getter for the image attribute.

Returns:

Numpy array of the image.

Return type:

npt.NDArray

property mask: numpy.typing.NDArray[numpy.bool_]#

Getter for the mask attribute.

Returns:

Numpy array of the mask.

Return type:

npt.NDArray[np.bool_]

property bbox: tuple[int, int, int, int]#

Getter for the bounding box attribute.

Returns:

Bounding box of the crop.

Return type:

tuple

Raises:

ValueError – If the bounding box is not square.

property pixel_to_nm_scaling: float#

Getter for the pixel to nanometre scaling factor attribute.

Returns:

Pixel to nanometre scaling factor.

Return type:

float

property thresholds: list[float]#

Getter for the thresholds attribute.

Returns:

Returns the value of thresholds.

Return type:

list[float]

property filename: str#

Getter for the filename attribute.

Returns:

The image filename attribute.

Return type:

str

threshold: str | None = None#
property height_profiles: numpy.typing.NDArray#

Getter for the height_profile attribute.

Returns:

The image height_profile.

Return type:

str

property stats: dict[str, Any]#

Getter for the stats.

Returns:

Dictionary of image statistics.

Return type:

str

property skeleton: numpy.typing.NDArray#

Getter for the skeleton attribute.

Returns:

Returns the value of skeleton.

Return type:

npt.NDArray

convolved_skeleton: numpy.typing.NDArray[numpy.int32] | None = None#
property disordered_trace: DisorderedTrace#

Getter for the disordered_trace attribute.

Returns:

dict[str – Returns the value of disordered_trace.

Return type:

Any]

property nodes: dict[int, Node]#

Getter for the nodes attribute.

Returns:

Returns nodes, a dictionary of Nodes.

Return type:

dict[int, Nodes]

property ordered_trace: OrderedTrace#

Getter for the ordered_trace attribute.

Returns:

dict[str – Returns the value of ordered_trace.

Return type:

Any]

property threshold_method: list[float]#

The threshold_method used to find the grain.

Returns:

Returns the value of threshold_method.

Return type:

list[float]

__eq__(other: object) bool[source]#

Check if two GrainCrop objects are equal.

Parameters:

other (object) – Object to compare to.

Returns:

True if the objects are equal, False otherwise.

Return type:

bool

__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted statistics on matched branches.

Return type:

str

debug_locate_difference(other: object) None[source]#

Debug function to find the culprit when two GrainCrop objects are not equal.

Parameters:

other (object) – Object to compare to.

Raises:

ValueError – If the objects are not equal

topostats.classes.validate_full_mask_tensor_shape(array: numpy.typing.NDArray[numpy.bool_]) numpy.typing.NDArray[numpy.bool_][source]#

Validate the shape of the full mask tensor.

Parameters:

array (npt.NDArray) – Numpy array to validate.

Returns:

Numpy array if valid.

Return type:

npt.NDArray

class topostats.classes.DisorderedTrace[source]#

Dataclass for storing the disordered tracing data.

images#

Dictionary of images generated during disordered tracing, should include ‘’pruned_skeleton’’.

Type:

dict[str: npt.NDArray]

grain_endpoints#

Number of Grain endpoints.

Type:

int

grain_junctions#

Number of Grain junctions.

Type:

int

total_branch_length#

Total branch length in nanometres.

Type:

float

grain_width_mean#

Mean grain width in nanometres.

Type:

float

stats#

Dictionary of stats for each branch of a grain.

Type:

dict[int, Any]

images: dict[str, numpy.typing.NDArray] | None = None#
grain_endpoints: int | None = None#
grain_junctions: int | None = None#
total_branch_length: float | None = None#
grain_width_mean: float | None = None#
stats: dict[int, Any] | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted statistics on matched branches.

Return type:

str

class topostats.classes.TopoStats[source]#

Class for storing TopoStats objects.

grain_crops#

Dictionary of GrainCrop objects.

Type:

dict[int, GrainCrop] | None

filename#

Filename.

Type:

str | None

image_name#

Filename without its extension.

Type:

str | None

pixel_to_nm_scaling#

Pixel to nanometre scaling.

Type:

str | None

img_path#

Original path to image.

Type:

str | None

image#

Flattened image (post Filter()).

Type:

npt.NDArray | None

image_original#

Original image.

Type:

npt.NDArray | None

image_statistics#

Pandas dataframe of

Type:

pd.DataFrame | None

full_mask_tensor#

Tensor mask for the full image.

Type:

npt.NDArray

topostats_version#

TopoStats version.

Type:

str | None

config#

Configuration used when processing the grain.

Type:

dict[str, Any] | None

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]]

basename#

Basename of image locations.

Type:

str

grain_crops: dict[int, GrainCrop] | None = None#
filename: str | None = None#
image_name: str | None = None#
pixel_to_nm_scaling: float | None = None#
img_path: pathlib.Path | str | None = None#
image: numpy.typing.NDArray | None = None#
image_original: numpy.typing.NDArray | None = None#
image_statistics: dict[str, int | float | str] | None = None#
full_mask_tensor: numpy.typing.NDArray | None = None#
topostats_version: str | None = None#
config: dict[str, Any] | None = None#
full_image_plots: dict[str, numpy.typing.NDArray[numpy.float64]] | None = None#
basename: str | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted and user-friendly statistics.

Return type:

str

__eq__(other: object) bool[source]#

Check if two TopoStats objects are equal.

Parameters:

other (object) – Other TopoStats object to compare to.

Returns:

True if the objects are equal, False otherwise.

Return type:

bool

calculate_image_statistics() dict[str, int | float][source]#

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.

Return type:

dict[str, int | float]

class topostats.classes.MatchedBranch[source]#

Class for storing matched branches data and attributes.

ordered_coords#

Numpy array of ordered coordinates.

Type:

npt.NDArray[np.int32]

heights#

Numpy array of heights.

Type:

npt.NDArray[np.number]

distances#

Numpy array of distances.

Type:

npt.NDArray[np.number]

fwhm#

Full-width half maximum.

Type:

float

fwhm_half_maxs#

Half-maximums from a matched branch.

Type:

list[float]

fwhm_peaks#

Peaks from a matched branch.

Type:

list[int | float]

angles#

Angle between branches.

Type:

float

branch_statistics#

Dictionary of branch statistics, fwhm, fwhm_half_maxs and fwhm_peaks.

Type:

dict[str, float | int | list[Any] | str]

ordered_coords: numpy.typing.NDArray[numpy.int32] | None = None#
heights: numpy.typing.NDArray[numpy.number] | None = None#
distances: numpy.typing.NDArray[numpy.number] | None = None#
fwhm: float | None = None#
fwhm_half_maxs: list[float] | None = None#
fwhm_peaks: list[float] | None = None#
angles: float | list[float] | None = None#
branch_statistics: dict[str, float | int | list[Any] | str] | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted and user-friendly statistics.

Return type:

str

collate_branch_statistics(image: str, basename: str) dict[str, float | int | list[Any] | str][source]#

Collate matched branch statistics to dictionary.

Parameters:
  • image (str) – Image being processed, added to dictionary for subsequent aggregation, typically TopoStats.filename.

  • basename (str) – Base image path, added to dictionary for subsequent aggregation, typically TopoStats.img_path.

Returns:

Dictionary of fwhm, fwhm_half_maxs and fwhm_peaks along with image and basename.

Return type:

dict[str, float | int | list[Any] | str]

class topostats.classes.UnMatchedBranch[source]#

Class for storing matched branches data and attributes.

angles#

Angle between branches.

Type:

float

angles: float | list[float] | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted and user-friendly statistics.

Return type:

str

class topostats.classes.Node[source]#

Class for storing Node data and attributes.

error#

Whether an error occurred calculating statistics for this node.

Type:

bool

pixel_to_nm_scaling#

Pixel to nanometre scaling.

Type:

np.float64

branch_stats#

Dictionary of MatchedBranch objects.

Type:

dict[int, MatchedBranch]

unmatched_branch_stats#

Dictionary of UnmatchedBranch objects.

Type:

dict[int, UnMatchedBranch]

node_coords#

Numpy array of node coordinates.

Type:

npt.NDArray[np.int32]

confidence#

Normalised confidence of the crossing in the range of 0-1.

Type:

np.float64

reduced_node_area#

The molecule skeleton, with all branches removed that are not connected to the current node.

Type:

npt.NDArray[np.int32]

node_area_skeleton#

Numpy array of skeleton.

Type:

npt.NDArray[np.int32]

node_branch_mask#

Numpy array of branch mask.

Type:

npt.NDArray[np.int32]

node_avg_mask#

Numpy array of averaged mask.

Type:

npt.NDArray[np.int32]

writhe#

Writhe type for the node.

Type:

str

error: bool | None = None#
pixel_to_nm_scaling: float | None = None#
branch_stats: dict[int, MatchedBranch] | None = None#
unmatched_branch_stats: dict[int, UnMatchedBranch] | None = None#
node_coords: numpy.typing.NDArray[numpy.int32] | None = None#
confidence: float | None = None#
reduced_node_area: numpy.typing.NDArray[numpy.int32] | None = None#
node_area_skeleton: numpy.typing.NDArray[numpy.int32] | None = None#
node_branch_mask: numpy.typing.NDArray[numpy.int32] | None = None#
node_avg_mask: numpy.typing.NDArray[numpy.int32] | None = None#
writhe: str | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted and user-friendly statistics.

Return type:

str

class topostats.classes.OrderedTrace[source]#

Class for Ordered Trace data and attributes.

molecule_datadict[int, Molecule]

Dictionary of Molecule objects indexed by molecule number.

tracing_statsdict | None

Tracing statistics.

grain_molstatsAny | None

Grain molecule statistics.

moleculesint

Number of molecules within the grain.

writhestr

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_statisticsdict[int, dict[str, bool | str | float | None]] | None

Dictionary of molecule statistics, with one entry for each molecule.

molecule_data: dict[int, Molecule] | None = None#
tracing_stats: dict | None = None#
grain_molstats: Any | None = None#
molecules: int | None = None#
writhe: str | None = None#
pixel_to_nm_scaling: float | None = None#
images: dict[str, numpy.typing.NDArray] | None = None#
error: bool | None = None#
molecule_statistics: dict[int, dict[str, bool | str | float | None]] | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted and user-friendly statistics.

Return type:

str

collate_molecule_statistics() dict[int, dict[str, bool | int | str | None]][source]#

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.

Return type:

dict[int, dict[str, bool | int | str | None]]

class topostats.classes.Molecule[source]#

Class for Molecules identified during ordered tracing.

thresholdstr

Direction from threshold of molecule (above / below)

molecule_numberint

Index of the molecule (per grain)

circularstr, bool, optional

Whether the molecule is circular or linear.

processingstr

Which processing type was used, topostats or nodestats.

topologystr, optional

Topological classification of the molecule.

topology_flipAny, optional

Unknown?

ordered_coordsnpt.NDArray, optional

Ordered coordinates for the molecule.

splined_coordsnpt.NDArray, optional

Smoothed (aka splined) coordinates for the molecule.

contour_lengthfloat

Length of the molecule.

end_to_end_distancefloat

Distance between ends of molecule. Will be 0.0 for circular molecules which don’t have ends.

heightsnpt.NDArray

Height along molecule.

distancesnpt.NDArray

Distance between points on the molecule.

curvature_statsnpt.NDArray, optional

Angle changes along molecule. NB - These are always positive due to use of np.abs() during calculation.

bboxtuple[int, int, int, int], optional

Bounding box.

threshold: str | None = None#
molecule_number: int | None = None#
circular: str | bool | None = None#
processing: str | None = None#
topology: str | None = None#
topology_flip: Any | None = None#
ordered_coords: numpy.typing.NDArray | None = None#
splined_coords: numpy.typing.NDArray | None = None#
contour_length: float | None = None#
end_to_end_distance: float | None = None#
heights: numpy.typing.NDArray | None = None#
distances: numpy.typing.NDArray | None = None#
curvature_stats: numpy.typing.NDArray | None = None#
bbox: tuple[int, int, int, int] | None = None#
molecule_statistics: dict[str, bool | str | float | None] | None = None#
__str__() str[source]#

Representation function for useful statistics for the class.

Returns:

Set of formatted and user-friendly statistics.

Return type:

str

collate_molecule_statistics() dict[str, bool | str | float | None][source]#

Collate the molecule statsistics to a dictionary.

Returns:

Dataframe of the classes attributes and their data.

Return type:

dict[str, bool | str | float | None]

topostats.classes.convert_to_dict(to_convert: Any) dict[str, Any][source]#

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.

Parameters:

to_convert (dict[str, Any]) – An object to be converted to a dictionary / dictionary item.

Returns:

Input parameter as a dictionary / dictionary item.

Return type:

Any