playnano.analysis.modules package¶
Submodules¶
playnano.analysis.modules.count_nonzero module¶
Analysis module for counting non-zero data points in an array.
- class playnano.analysis.modules.count_nonzero.CountNonzeroModule[source]¶
Bases:
AnalysisModuleCount non-zero pixels in each frame of an AFMImageStack.
This simple analysis module computes the number of non-zero pixels per frame and returns the result as a 1D array.
Version¶
0.1.0
Examples
>>> module = CountNonzeroModule() >>> result = module.run(stack) >>> result['counts'].shape (n_frames,)
- property name: str¶
Name of the analysis module.
- Returns:
The string identifier for this module.
- Return type:
- run(stack, previous_results=None, **params) dict[str, Any][source]¶
Count non-zero pixels per frame in the AFMImageStack.
- Parameters:
stack (AFMImageStack) – Stack of AFM frames with .data of shape (n_frames, H, W).
previous_results (dict[str, Any], optional) – Ignored by this module. Included for API compatibility.
**params (dict) – Additional parameters (unused).
- Returns:
Dictionary with key:
”counts”: np.ndarray of shape (n_frames,), number of non-zero pixels per frame.
- Return type:
- version = '0.1.0'¶
playnano.analysis.modules.dbscan_clustering module¶
DBSCAN clustering on features over the entire stack in 3D (x, y, time).
This module extracts feature points from a previous analysis step, optionally normalizes them, applies DBSCAN, and returns clusters (with noise as label -1 omitted or optionally retained), cluster cores, and a summary.
- param coord_key:
Key in previous_results containing features_per_frame.
- type coord_key:
str
- param coord_columns:
Which keys in each feature-dict to use (e.g. (“x”,”y”)).
- type coord_columns:
Sequence[str]
- param use_time:
If True and coord_columns length is 2, append frame time as the third dimension.
- type use_time:
bool
- param eps:
The maximum distance between two samples for them to be considered as in the same neighborhood (in normalized units if normalise=True).
- type eps:
float
- param min_samples:
The number of samples in a neighborhood for a point to be considered as a core point.
- type min_samples:
int
- param normalise:
If True, min-max normalize each axis before clustering.
- type normalise:
bool
- param time_weight:
If given, multiply the time axis by this weight.
- type time_weight:
float | None
- param **dbscan_kwargs:
Forwarded to sklearn.cluster.DBSCAN.
- class playnano.analysis.modules.dbscan_clustering.DBSCANClusteringModule[source]¶
Bases:
AnalysisModuleDBSCAN clustering of features across an AFMImageStack in (x, y, time) space.
This module extracts coordinates from per-frame features, optionally adds time as a third dimension, normalizes the space, and applies DBSCAN clustering. It returns clusters with point metadata, core point means as cluster centers, and a summary of cluster sizes.
Version¶
0.1.0
- property name: str¶
Name of the analysis module.
- Returns:
The string identifier for this module: “dbscan_clustering”.
- Return type:
- requires = ['feature_detection', 'log_blob_detection']¶
- run(stack, previous_results: dict[str, Any] | None = None, *, detection_module: str = 'feature_detection', coord_key: str = 'features_per_frame', coord_columns: Sequence[str] = ('centroid_x', 'centroid_y'), use_time: bool = True, eps: float = 0.3, min_samples: int = 5, normalise: bool = True, time_weight: float | None = None, **dbscan_kwargs: Any) dict[str, Any][source]¶
Perform DBSCAN clustering on detected features in (x, y[, t]) space.
- Parameters:
stack (AFMImageStack) – The input stack with .data and .time_for_frame() method.
previous_results (dict[str, Any], optional) – Output from previous analysis steps. Must contain features under the given detection_module and coord_key.
detection_module (str) – Which module’s output to use from previous_results. Default is “feature_detection”.
coord_key (str) – Key in previous_results[detection_module] containing the list of per-frame features. Default is “features_per_frame”.
coord_columns (Sequence[str]) – Keys to extract coordinates from each feature. If missing, will fall back to centroid tuple. Default is (“centroid_x”, “centroid_y”).
use_time (bool) – Whether to append frame timestamp as a third coordinate. Dafaulr is True.
eps (float) – Maximum distance for neighborhood inclusion (in normalized units if normalise=True). Default is 0.3.
min_samples (int) – Minimum number of points in a neighborhood to form a core point. Default is 5.
normalise (bool) – If True, normalize coordinate axes to [0, 1] range before clustering. Default is True.
time_weight (float or None, optional) – Scaling factor for the time axis (after normalization). If None, no weighting is applied.
**dbscan_kwargs (dict) – Additional keyword arguments forwarded to sklearn.cluster.DBSCAN.
- Returns:
Output dictionary with the following keys:
- ”clusters”: list of dicts, one per cluster, containing:
”id”: cluster ID (int)
”frames”: list of frame indices
”point_indices”: list of feature indices within frames
”coords”: list of 2D or 3D coordinates (post-normalization)
- ”cluster_centers”: np.ndarray of shape (n_clusters, D)
Mean location of each cluster in original coordinate units.
- ”summary”: dict with:
”n_clusters”: total number of clusters found
”members_per_cluster”: dict of cluster ID to count
- Return type:
- version = '0.1.0'¶
playnano.analysis.modules.feature_detection module¶
Threshold-based feature detection for AFM image stacks.
This is a playNano analysis module implementing a concrete subclass of the abstract AnalysisModule base class. It detects contiguous features in each frame of an AFM image stack using user-provided or precomputed masks, with optional hole filling, morphological separation, size and edge filtering, and per-feature statistics extraction.
See also
playnano.analysis.modules.log_blob_detectionLoG-based alternative detection method.
playnano.analysis.modules.particle_trackingLinks detected features across frames.
, Author, ------, Daniel, AI, --------------------, AI-based, and, refactoring, and, algorithms, and
- class playnano.analysis.modules.feature_detection.FeatureDetectionModule[source]¶
Bases:
AnalysisModuleDetect contiguous features in each frame of an AFM image stack.
This module accepts either a callable mask-generating function or a reference to a boolean mask array stored in previous_results. Connected components are identified per frame, optionally morphologically separated, filtered by size and edge contact, and returned along with feature statistics and labeled masks.
- Parameters:
mask_fn (callable, optional) – Function of the form frame -> bool_2D_array used to generate a mask for each frame. Required if mask_key is not provided.
mask_key (str, optional) – Key referencing a boolean mask array stored in previous_results. Required if mask_fn is not provided.
morph_opening (bool, default False) – If True, apply morphological opening to each labeled object to separate touching features.
sep_radius (int, default 6) – Radius of the disk structuring element used for morphological opening.
min_size (int, default 10) – Minimum pixel area for a region to be retained.
remove_edge (bool, default True) – If True, discard any region touching the frame boundary.
fill_holes (bool, default False) – If True, fill holes within each mask before labeling.
hole_area (int or None, optional) – Maximum size of holes to fill. If None, fill all holes.
**mask_kwargs (Any) – Additional keyword arguments passed to mask_fn(frame, **mask_kwargs).
- Returns:
features_per_frame : list[list[dict]] Per-frame list of feature stats dicts, each with:
”frame_timestamp” : float
”label” : int
”area” : int
”min”, “max”, “mean” : float
”bbox” : (min_row, min_col, max_row, max_col)
”centroid” : (row, col)
- labeled_maskslist[np.ndarray]
Integer-labeled masks for each frame.
- summarydict
Aggregate values: total frames, total features, average features per frame.
- Return type:
- Raises:
ValueError – If mask configuration is invalid or mask has incorrect shape/dtype.
KeyError – If mask_key is supplied but missing from previous_results.
Version –
------- –
0.2.0 –
Version 0.2.0 adds morphological opening for separating close or touching particles. –
Examples
>>> pipeline.add("feature_detection", mask_fn=mask_mean_offset, ... min_size=20, fill_holes=True, hole_area=50) >>> result = pipeline.run(stack) >>> result["summary"]["total_features"] 123
- property name: str¶
Return the name of the analysis module.
- Returns:
The identifier for this module:
"feature_detection".- Return type:
- run(stack, previous_results: dict[str, Any] | None = None, *, mask_fn: callable | None = None, mask_key: str | None = None, morph_opening: bool = False, sep_radius: int = 6, min_size: int = 10, remove_edge: bool = True, fill_holes: bool = False, hole_area: int | None = None, **mask_kwargs) dict[str, Any][source]¶
Detect contiguous features on each frame of stack.data.
- Parameters:
stack (AFMImageStack) – The AFM stack whose .data (3D array) and .time_for_frame() are used.
previous_results (dict[str, Any], optional) – Mapping of earlier analysis outputs. If mask_key is given, must contain a boolean mask array under that key.
mask_fn (callable, optional) – Function frame->bool array for masking. Required if mask_key is None.
- Returns:
Dictionary containing:
features_per_frame : list of lists of dict
labeled_masks : list of np.ndarray
summary : dict with total_features, total_frames, avg_features_per_frame
- Return type:
- Raises:
ValueError – If stack.data is None or not 3D, or mask array invalid, or neither mask_fn nor mask_key provided.
KeyError – If mask_key not found in previous_results.
Examples
>>> pipeline.add("feature_detection", mask_fn=mask_mean_offset, min_size=20) >>> result = pipeline.run(stack)
- version = '0.2.0'¶
playnano.analysis.modules.k_means_clustering module¶
K-Means clustering on features over the entire stack in 3D (x, y, time).
This module extracts a point-cloud from per-frame feature dictionaries (e.g. coordinates + timestamps), optionally normalizes each axis to [0,1], applies K-Means with a user-supplied k, then returns cluster assignments, cluster centers (in original coordinate units), and a summary.
- param coord_key:
Key in previous_results whose value is features_per_frame (list of lists of dicts).
- type coord_key:
str
- param coord_columns:
Which keys in each feature-dict to use (e.g. (“x”,”y”)).
- type coord_columns:
Sequence[str]
- param use_time:
If True and coord_columns length is 2, append frame time as the third dimension.
- type use_time:
bool
- param k:
Number of clusters.
- type k:
int
- param normalise:
If True, min-max normalize each axis before clustering.
- type normalise:
bool
- param time_weight:
If given, multiply the time axis by this weight.
- type time_weight:
float | None
- param **kmeans_kwargs:
Forwarded to sklearn.cluster.KMeans.
- class playnano.analysis.modules.k_means_clustering.KMeansClusteringModule[source]¶
Bases:
AnalysisModuleCluster features across all frames using K-Means in 2D or 3D (x, y, [time]).
Extracts point coordinates from per-frame features, applies optional normalization and time weighting, then performs K-Means clustering. Returns cluster assignments, centers in original scale, and a summary report.
- Parameters:
coord_key (str) – Key in previous_results pointing to ‘features_per_frame’ structure.
coord_columns (Sequence[str]) – Keys to extract coordinates from each feature (e.g. (“x”, “y”)).
use_time (bool) – If True, appends frame timestamp as a third clustering dimension.
k (int) – Number of clusters to fit.
normalise (bool) – If True, normalize each axis to [0, 1] before clustering.
time_weight (float or None) – Optional multiplier for time axis after normalization.
**kmeans_kwargs – Additional keyword arguments passed to sklearn.cluster.KMeans.
Version
-------
0.1.0
- property name: str¶
Name of the analysis module.
- Returns:
The string identifier for this module.
- Return type:
- requires = ['feature_detection', 'log_blob_detection']¶
- run(stack, previous_results: dict[str, Any] | None = None, *, detection_module: str = 'feature_detection', coord_key: str = 'features_per_frame', coord_columns: Sequence[str] = ('centroid_x', 'centroid_y'), use_time: bool = True, k: int, normalise: bool = True, time_weight: float | None = None, **kmeans_kwargs: Any) dict[str, Any][source]¶
Perform K-Means clustering on features extracted from a stack.
Constructs a coordinate array from features (x, y[, t]), optionally applies normalization and time weighting, and fits k-means to assign clusters.
- Parameters:
stack (AFMImageStack) – The input image stack providing frame times and data context.
previous_results (dict[str, Any], optional) – Dictionary containing outputs from previous analysis steps. Must contain the selected detection_module and coord_key.
detection_module (str) – Key identifying which previous module’s output to use. Default is “feature_detection”.
coord_key (str) – Key under the detection module that holds per-frame feature dicts. Default is “features_per_frame”.
coord_columns (Sequence[str]) – Keys to extract from each feature for clustering coordinates. If missing, fallback to the “centroid” tuple is attempted. Default is (“centroid_x”, “centroid_y”)
use_time (bool) – If True and coord_columns is 2D, append frame timestamp as third dimension. Default is True.
k (int) – Number of clusters to compute.
normalise (bool) – Whether to min-max normalize each axis of the feature points before clustering. Default is True.
time_weight (float or None, optional) – Weighting factor for time axis (applied after normalization). Only used if time is included as a third dimension.
**kmeans_kwargs (dict) – Additional arguments forwarded to sklearn.cluster.KMeans.
- Returns:
A dictionary with the following keys:
- ”clusters”list of dicts, each with:
id : int
frames : list of int
point_indices : list of int
- coordslist of tuple
The normalized coordinates used in clustering for each point in the cluster (e.g., (x, y[, t])).
- ”cluster_centers”ndarray of shape (k, D)
Cluster centers in original coordinate units.
- ”summary”dict
”n_clusters” : int
”members_per_cluster” : dict mapping cluster id to point count
- Return type:
- Raises:
RuntimeError – If the required detection_module output is not found in previous_results.
KeyError – If the required coordinate keys are missing in any feature dictionary.
- version = '0.1.0'¶
playnano.analysis.modules.log_blob_detection module¶
Module for LoG blob detection.
Detect “blobs” in each frame of an AFM image stack using the Laplacian-of-Gaussian method. Provides automatic multi-scale blob detection and optional radius estimation.
- class playnano.analysis.modules.log_blob_detection.LoGBlobDetectionModule[source]¶
Bases:
AnalysisModuleDetect blobs in AFM image stacks using the Laplacian-of-Gaussian (LoG) method.
This module applies multi-scale blob detection to each frame in an AFM image stack using the Laplacian-of-Gaussian algorithm from skimage.feature.blob_log. It supports automatic scale selection and optional estimation of blob radii.
- run(stack, previous_results=None, \*, min_sigma=1.0, max_sigma=5.0, num_sigma=10,
threshold=0.1, overlap=0.5, include_radius=True) Detects blobs in each frame of the AFM image stack and returns per-frame features and a summary.
- Version()¶
- -------
- 0.1.0()¶
Examples
>>> module = LoGBlobDetectionModule() >>> result = module.run(stack, min_sigma=1.0, max_sigma=5.0, num_sigma=10) >>> result['summary']['total_blobs'] 42
- property name: str¶
Name of the analysis module.
- Returns:
The string identifier for this module: “log_blob_detection”.
- Return type:
- run(stack, previous_results: dict[str, Any] | None = None, *, min_sigma: float = 1.0, max_sigma: float = 5.0, num_sigma: int = 10, threshold: float = 0.1, overlap: float = 0.5, include_radius: bool = True) dict[str, Any][source]¶
Detect “blobs” in each frame via a Laplacian-of-Gaussian filter.
- Parameters:
stack (AFMImageStack) – Must have stack.data of shape (n_frames, H, W).
min_sigma (float) – Parameters passed to skimage.feature.blob_log.
max_sigma (float) – Parameters passed to skimage.feature.blob_log.
num_sigma (int) – Parameter passed to skimage.feature.blob_log.
threshold (float) – Absolute intensity threshold for LoG response.
overlap (float) – If two detected blobs overlap more than this fraction, only the larger is kept.
include_radius (bool) – If True, append the estimated blob radius in each feature-dict.
- Returns:
Dictionary with keys:
- features_per_framelist of list of dict
Per-frame list of detected blobs. Each dict contains: - frame_timestamp : float - y, x : float - sigma : float - radius : float, optional (if include_radius=True)
- summarydict
Aggregate metrics: - total_frames : int - total_blobs : int - avg_blobs_per_frame : float
- Return type:
- version = '0.1.0'¶
playnano.analysis.modules.particle_tracking module¶
Module for linking particle features across frames to build trajectories.
This module defines the ParticleTrackingModule, which links features detected in sequential frames of an AFM image stack using nearest-neighbor matching based on feature coordinates.
Features are matched across frames if they lie within a specified maximum distance. Tracks are formed by chaining these matches over time.
- Each resulting track includes:
A unique track ID
A list of frames spanned by the track (first→last detection)
A list of point indices aligned with frames; missing detections are None
A list of coordinates describing the particle’s positions
Optionally, per-track masks are extracted from the labeled feature masks.
See also
playnano.analysis.modules.feature_detectionMask based particle detection method.
playnano.analysis.modules.log_blob_detectionLoG-based particle detection method.
, Author, ------, Daniel, AI, --------------------, AI-based, and, refactoring, and, algorithms, and
- class playnano.analysis.modules.particle_tracking.ParticleTrackingModule[source]¶
Bases:
AnalysisModuleLink detected features frame-to-frame to produce particle trajectories.
This module links features detected by a prior feature detection module using nearest-neighbor coordinate matching across adjacent frames. A new track is created for each unmatched feature.
Version¶
0.2.0
Version 0.2.0 allows tracks to continue across missing detections and supports scaling the distance threshold with time since last detection.
- property name: str¶
Name of the analysis module.
- Returns:
Unique identifier: “particle_tracking”.
- Return type:
- requires = ['feature_detection', 'log_blob_detection']¶
- run(stack: AFMImageStack, previous_results: dict[str, Any] | None = None, detection_module: str = 'feature_detection', coord_key: str = 'features_per_frame', coord_columns: Sequence[str] = ('centroid_x', 'centroid_y'), max_distance: float = 5.0, max_missing: int = 0, distance_scale: str = 'constant', **params) dict[str, Any][source]¶
Track particles across frames using nearest-neighbor association.
- Parameters:
stack (AFMImageStack) – The input AFM image stack.
previous_results (dict[str, Any], optional) –
Must contain results from a detection module, including:
coord_key (e.g., “features_per_frame”): list of dicts with per-frame features
”labeled_masks”: per-frame mask of label regions
detection_module (str, optional) – Which module to read features from (default: “feature_detection”).
coord_key (str, optional) – Key in previous_results[detection_module] containing per-frame feature dicts (default: “features_per_frame”).
coord_columns (Sequence[str], optional) – Keys to extract coordinates from each feature; falls back to “centroid” if needed. Default is (“centroid_x”, “centroid_y”).
max_distance (float, optional) – Maximum allowed movement per frame in coordinate units (default: 5.0).
max_missing (int, optional) – Maximum allowed consecutive missing detections before terminating a track. Default is 0 (no missing allowed).
distance_scale (str, optional) – How to scale max_distance with time since last detection in frames: “constant” (default), “linear” (scale linearly with time), or “sqrt” (scale with square root of time).
- Returns:
Dictionary with keys:
- trackslist of dict
Per-track dictionaries containing:
id : int Track ID
frames : list[int] Frame indices spanned by track
point_indices : list[Optional[int]] Indices into features_per_frame
coords : list[Optional[tuple[float, float]]] Coordinates (coord0, coord1) aligned with frames; None indicates missing detection.
track_masks : dict[int, np.ndarray] Last mask per track
n_tracks : int Total number of tracks
- Return type:
- version = '0.2.0'¶
playnano.analysis.modules.x_means_clustering module¶
Module for X-Means clustering as part of the playNano analysis pipeline.
This module implements a version of the X-Means clustering algorithm, an extension of K-Means that estimates the optimal number of clusters using the Bayesian Information Criterion (BIC).
Based on: Pelleg, D., & Moore, A. W. (2000). X-means: Extending K-means with Efficient Estimation of the Number of Clusters. Carnegie Mellon University. http://www.cs.cmu.edu/~dpelleg/download/xmeans.pdf
- class playnano.analysis.modules.x_means_clustering.XMeansClusteringModule[source]¶
Bases:
AnalysisModuleCluster features using the X-Means algorithm over (x, y[, t]) coordinates.
This module clusters spatial (and optionally temporal) feature coordinates extracted from an AFM stack using an X-Means algorithm implemented in pure Python.
- Parameters:
coord_key (str) – Key in previous_results[detection_module] to find feature list.
coord_columns (Sequence[str]) – Names of feature dictionary keys to use for coordinates (e.g. centroid_x, centroid_y).
use_time (bool) – Whether to append frame timestamps as the third coordinate.
min_k (int) – Initial number of clusters (minimum).
max_k (int) – Maximum number of clusters to allow.
normalise (bool) – Whether to min-max normalize coordinate space before clustering.
time_weight (float, optional) – Multiplier for time dimension (after normalization).
- Returns:
dict – Dictionary with clustering results: - clusters: list of {id, frames, point_indices, coords} - cluster_centers: (K, D) ndarray in original units - summary: {n_clusters: int, members_per_cluster: dict}
Version
——-
0.1.0
- property name: str¶
Name of the analysis module.
- Returns:
The string identifier for this module.
- Return type:
- requires = ['feature_detection', 'log_blob_detection']¶
- run(stack: AFMImageStack, previous_results: dict[str, Any] | None = None, *, detection_module: str = 'feature_detection', coord_key: str = 'features_per_frame', coord_columns: Sequence[str] = ('centroid_x', 'centroid_y'), use_time: bool = True, min_k: int = 1, max_k: int = 10, normalise: bool = True, time_weight: float | None = None, replicates: int = 3, max_iter: int = 300, bic_threshold: float = 0.0) dict[str, Any][source]¶
Perform X-Means clustering on features extracted from an AFM stack.
This method extracts (x, y[, t]) coordinates from detected features, optionally normalizes and time-weights them, and applies the X-Means algorithm to automatically select the number of clusters based on the BIC score.
- Parameters:
stack (AFMImageStack) – The input image stack providing frame timing and metadata context.
previous_results (dict[str, Any], optional) – Dictionary containing outputs from previous analysis steps. Must contain the selected detection_module and coord_key.
detection_module (str) – Key identifying which previous modules output to use. Default is “feature_detection”.
coord_key (str) – Key under the detection module that holds per-frame feature dicts. Default is “features_per_frame”.
coord_columns (Sequence[str]) – Keys to extract from each feature for clustering coordinates. If missing, will fall back to using the “centroid” tuple if available. Defaults is (“centroid_x”, “centroid_y”).
use_time (bool) – If True and coord_columns only gives 2D coordinates, appends the frame timestamp as a third dimension. Default is True.
min_k (int) – Initial number of clusters to start with. Default is 1.
max_k (int) – Maximum number of clusters allowed. Default is 10.
normalise (bool) – Whether to normalize the feature coordinate axes to the [0, 1] range before clustering. Default is True.
time_weight (float or None, optional) – Multiplicative factor applied to the time axis (after normalization). Used only if time is included as a third coordinate.
replicates (int) – Number of times to run k-means internally to choose the best split. Default is 3.
max_iter (int) – Maximum number of iterations for each k-means call. Default is 300.
bic_threshold (float) – Minimum improvement in BIC required to split a cluster. Default is 0.0 (any improvement allows a split).
- Returns:
A dictionary with the following keys:
- ”clusters”list of dicts, each with:
id : int
frames : list of int
point_indices : list of int
coords : list of tuple (normalized x, y, [t])
- ”cluster_centers”ndarray of shape (k, D)
Final cluster centers in original (denormalized) coordinates.
- ”summary”dict
”n_clusters” : int
”members_per_cluster” : dict mapping cluster ID to point count.
- Return type:
- Raises:
RuntimeError – If the required detection module output is missing from previous_results.
KeyError – If the expected coordinate keys are missing from any feature dictionary.
- version = '0.1.0'¶
- playnano.analysis.modules.x_means_clustering.compute_bic(points: ndarray, center: ndarray) float[source]¶
Compute Bayesian Information Criterion for a cluster.
- Parameters:
points (np.ndarray) – Points in the cluster.
center (np.ndarray) – Cluster center (shape (1, D)).
- Returns:
BIC value.
- Return type:
Module contents¶
Public package initialization for analysis modules.
- noindex: