grainstats#

Contains class for calculating the statistics of grains - 2d raster images.

class topostats.grainstats.GrainStats(data: numpy.typing.NDArray, labelled_data: numpy.typing.NDArray, pixel_to_nanometre_scaling: float, direction: str, base_output_dir: str | Path, image_name: str = None, edge_detection_method: str = 'binary_erosion', extract_height_profile: bool = False, cropped_size: float = -1, plot_opts: dict = None, metre_scaling_factor: float = 1e-09)[source]#

Class for calculating grain stats.

Parameters:
  • data (npt.NDArray) – 2D Numpy array containing the flattened afm image. Data in this 2D array is floating point.

  • labelled_data (npt.NDArray) – 2D Numpy array containing all the grain masks in the image. Data in this 2D array is boolean.

  • pixel_to_nanometre_scaling (float) – Floating point value that defines the scaling factor between nanometres and pixels.

  • direction (str) – Direction for which grains have been detected (“above” or “below”).

  • base_output_dir (Path) – Path to the folder that will store the grain stats output images and data.

  • image_name (str) – The name of the file being processed.

  • edge_detection_method (str) – Method used for detecting the edges of grain masks before calculating statistics on them. Do not change unless you know exactly what this is doing. Options: “binary_erosion”, “canny”.

  • extract_height_profile (bool) – Extract the height profile.

  • cropped_size (float) – Length of square side (in nm) to crop grains to.

  • plot_opts (dict) – Plotting options dictionary for the cropped grains.

  • metre_scaling_factor (float) – Multiplier to convert the current length scale to metres. Default: 1e-9 for the usual AFM length scale of nanometres.

Methods

calculate_aspect_ratio(edges, ...[, debug])

Calculate the width, length and aspect ratio of the smallest bounding rectangle of a grain.

calculate_edges(grain_mask, ...)

Convert 2D boolean array to list of the coordinates of the edges of the grain.

calculate_points(grain_mask)

Convert a 2D boolean array to a list of coordinates.

calculate_radius_stats(edges, points)

Calculate the radius of grains.

calculate_squared_distance(point_2[, point_1])

Calculate the squared distance between two points.

calculate_stats()

Calculate the stats of grains in the labelled image.

convex_hull(edges, base_output_dir[, debug])

Calculate a grain's convex hull.

find_cartesian_extremes(rotated_points)

Find the limits of x and y of rotated points.

get_angle(point_1, point_2)

Calculate the angle in radians between two points.

get_cropped_region(image, length, centre)

Crop the image with respect to a given pixel length around the centre coordinates.

get_shift(coords, shape)

Obtain the coordinate shift to reflect the cropped image box for molecules near the edges of the image.

get_start_point(edges)

Determine the index of the bottom most point of the hull when sorted by x-position.

graham_scan(edges)

Construct the convex hull using the Graham Scan algorithm.

is_clockwise(p_1, p_2, p_3)

Determine if three points make a clockwise or counter-clockwise turn.

plot(edges[, convex_hull, file_path])

Plot and save the coordinates of the edges in the grain and optionally the hull.

sort_points(points)

Sort points in counter-clockwise order of angle made with the starting point.

calculate_aspect_ratio(edges: list, hull_simplices: numpy.typing.NDArray, path: Path, debug: bool = False) tuple[source]#

Calculate the width, length and aspect ratio of the smallest bounding rectangle of a grain.

Parameters:
  • edges (list) – A python list of coordinates of the edge of the grain.

  • hull_simplices (npt.NDArray) – A 2D numpy array of simplices that the hull is comprised of.

  • path (Path) – Path to the save folder for the grain.

  • debug (bool) – If true, various plots will be saved for diagnostic purposes.

Returns:

The smallest_bouning_width (float) in pixels (not nanometres) of the smallest bounding rectangle for the grain. The smallest_bounding_length (float) in pixels (not nanometres), of the smallest bounding rectangle for the grain. And the aspect_ratio (float) the width divided by the length of the smallest bounding rectangle for the grain. It will always be greater or equal to 1.

Return type:

tuple

static calculate_edges(grain_mask: numpy.typing.NDArray, edge_detection_method: str) list[source]#

Convert 2D boolean array to list of the coordinates of the edges of the grain.

Parameters:
  • grain_mask (npt.NDArray) – A 2D numpy array image of a grain. Data in the array must be boolean.

  • edge_detection_method (str) – Method used for detecting the edges of grain masks before calculating statistics on them. Do not change unless you know exactly what this is doing. Options: “binary_erosion”, “canny”.

Returns:

List containing the coordinates of the edges of the grain.

Return type:

list

static calculate_points(grain_mask: numpy.typing.NDArray) list[source]#

Convert a 2D boolean array to a list of coordinates.

Parameters:

grain_mask (npt.NDArray) – A 2D numpy array image of a grain. Data in the array must be boolean.

Returns:

A python list containing the coordinates of the pixels in the grain.

Return type:

list

calculate_radius_stats(edges: list, points: list) tuple[float][source]#

Calculate the radius of grains.

The radius in this context is the distance from the centroid to points on the edge of the grain.

Parameters:
  • edges (list) – A 2D python list containing the coordinates of the edges of a grain.

  • points (list) – A 2D python list containing the coordinates of the points in a grain.

Returns:

A tuple of the minimum, maximum, mean and median radius of the grain.

Return type:

tuple[float]

calculate_squared_distance(point_2: tuple, point_1: tuple = None) float[source]#

Calculate the squared distance between two points.

Used for distance sorting purposes and therefore does not perform a square root in the interests of efficiency.

Parameters:
  • point_2 (tuple) – The point to find the squared distance to.

  • point_1 (tuple) – Optional - defaults to the starting point defined in the graham_scan() function. The point to find the squared distance from.

Returns:

The squared distance between the two points.

Return type:

float

calculate_stats()[source]#

Calculate the stats of grains in the labelled image.

Returns:

Consists of a pd.DataFrame containing all the grain stats that have been calculated for the labelled image and a list of dictionaries containing grain data to be plotted.

Return type:

tuple

convex_hull(edges: list, base_output_dir: Path, debug: bool = False) tuple[list, list, list][source]#

Calculate a grain’s convex hull.

Based off of the Graham Scan algorithm and should ideally scale in time with O(nlog(n)).

Parameters:
  • edges (list) – A python list containing the coordinates of the edges of the grain.

  • base_output_dir (Path) – Directory to save output to.

  • debug (bool) – Default false. If true, debug information will be displayed to the terminal and plots for the convex hulls and edges will be saved.

Returns:

A hull (list) of the coordinates of each point on the hull. Hull indices providing a way to find the points from the hill inside the edge list that was passed. Simplices (list) of tuples each representing a simplex of the convex hull, these are sorted in a counter-clockwise order.

Return type:

tuple[list, list, list]

static find_cartesian_extremes(rotated_points: numpy.typing.NDArray) dict[source]#

Find the limits of x and y of rotated points.

Parameters:

rotated_points (npt.NDArray) – 2-D array of rotated points.

Returns:

Dictionary of the x and y min and max.__annotations__.

Return type:

Dict

static get_angle(point_1: tuple, point_2: tuple) float[source]#

Calculate the angle in radians between two points.

Parameters:
  • point_1 (tuple) – Coordinate vectors for the first point to find the angle between.

  • point_2 (tuple) – Coordinate vectors for the second point to find the angle between.

Returns:

The angle in radians between the two input vectors.

Return type:

float

get_cropped_region(image: numpy.typing.NDArray, length: int, centre: numpy.typing.NDArray) numpy.typing.NDArray[source]#

Crop the image with respect to a given pixel length around the centre coordinates.

Parameters:
  • image (npt.NDArray) – The image array.

  • length (int) – The length (in pixels) of the resultant cropped image.

  • centre (npt.NDArray) – The centre of the object to crop.

Returns:

Cropped array of the image.

Return type:

npt.NDArray

static get_shift(coords: numpy.typing.NDArray, shape: numpy.typing.NDArray) int[source]#

Obtain the coordinate shift to reflect the cropped image box for molecules near the edges of the image.

Parameters:
  • coords (npt.NDArray) – Value representing integer coordinates which may be outside of the image.

  • shape (npt.NDArray) – Array of the shape of an image.

Returns:

Max value of the shift to reflect the croped region so it stays within the image.

Return type:

np.int64

get_start_point(edges: numpy.typing.NDArray) None[source]#

Determine the index of the bottom most point of the hull when sorted by x-position.

Parameters:

edges (npt.NDArray) – Array of coordinates.

graham_scan(edges: list) tuple[list, list, list][source]#

Construct the convex hull using the Graham Scan algorithm.

Ideally this algorithm will take O( n * log(n) ) time.

Parameters:

edges (list) – A python list of coordinates that make up the edges of the grain.

Returns:

A hull (list) of the coordinates of each point on the hull. Hull indices providing a way to find the points from the hill inside the edge list that was passed. Simplices (list) of tuples each representing a simplex of the convex hull, these are sorted in a counter-clockwise order.

Return type:

tuple[list, list, list]

static is_clockwise(p_1: tuple, p_2: tuple, p_3: tuple) bool[source]#

Determine if three points make a clockwise or counter-clockwise turn.

Parameters:
  • p_1 (tuple) – First point to be used to calculate turn.

  • p_2 (tuple) – Second point to be used to calculate turn.

  • p_3 (tuple) – Third point to be used to calculate turn.

Returns:

Indicator of whether turn is clockwise.

Return type:

boolean

static plot(edges: list, convex_hull: list = None, file_path: Path = None) None[source]#

Plot and save the coordinates of the edges in the grain and optionally the hull.

Parameters:
  • edges (list) – A list of points to be plotted.

  • convex_hull (list) – Optional argument. A list of points that form the convex hull. Will be plotted with the coordinates if provided.

  • file_path (Path) – Path of the file to save the plot as.

sort_points(points: list) list[source]#

Sort points in counter-clockwise order of angle made with the starting point.

Parameters:

points (list) – A python list of the coordinates to sort.

Returns:

Points (coordinates) sorted counter-clockwise.

Return type:

list