playnano.afm_stack module¶
Defines AFMImageStack for managing AFM time-series data and processing steps.
- class playnano.afm_stack.AFMImageStack(data: ndarray, pixel_size_nm: float, channel: str, file_path: Path, frame_metadata: list[dict[str, Any]] = None)[source]¶
Bases:
objectManage stacks of AFM images with metadata, analysis results, and provenance.
Contains snapshots of each stage of processing (including the raw data after the first processing step), any masks generated, analysis results, and the provenance of each processing and analysis step.
- data¶
3D array of shape (n_frames,
height,width) holding the raw or current data.- Type:
np.ndarray
- file_path¶
Path to the source file or folder.
- Type:
Path
- frame_metadata¶
Per-frame metadata dicts; each will include a normalized ‘timestamp’ key.
- processed¶
Snapshots of processed data arrays from filters. Keys like ‘step_1_remove_plane’.
- masks¶
Boolean mask arrays from mask steps. Keys like ‘step_2_threshold’.
- provenance¶
Records environment info and provenance of processing and analysis pipelines:
{ "environment": {...}, "processing": {"steps": [...], "keys_by_name": {...}}, "analysis": {"frame_times": [...], "steps": [...], "results_by_name": {...}}, }
- apply(steps: list[str], **kwargs) ndarray[source]¶
Apply a sequence of processing steps to each frame in the AFM image stack.
Steps can be:
“clear” : reset any existing mask
mask names : keys in MASK_MAP
filter names : keys in FILTER_MAP
plugin names : entry points in ‘playnano.filters’
method names : bound methods on this class
**kwargsare forwarded to mask functions or filter functions as appropriate.This is a stateless convenience: applies clear/mask/filter steps in order, snapshots only ‘raw’ and final data in self.processed, but does not assign unique keys per step or update provenance.
- Parameters:
- Returns:
Final processed 3D array (shape (n_frames,
height,width)).- Return type:
np.ndarray
Notes
For tracked, reproducible processing, use ProcessingPipeline.
- channel_for_frame(idx: int) str[source]¶
Get the channel name for a given frame index.
Returns the value of the ‘channel’ key in the frame’s metadata if present, otherwise falls back to the global stack-level channel.
- export_analysis_log(path: str) None[source]¶
Export analysis provenance and results to a JSON file.
Expects that stack.analysis (or stack.analysis_results) and stack.provenance[“analysis”] are populated by AnalysisPipeline.run().
Writes¶
Example JSON structure:
{ "environment": { ... }, "analysis": { <step_key>: outputs, ... }, "provenance": { "steps": [ ... ], "results_by_name": { ... }, "frame_times": [...], } }
- param path:
File path to write the JSON log. Creates parent dirs as needed.
- type path:
str
- raises ValueError:
If no analysis results found on this stack.
- export_processing_log(path: str) None[source]¶
Export processing provenance and environment metadata to a JSON file.
Writes¶
Example JSON structure:
{ "environment": { ... }, "processing": { "steps": [ ... ], "keys_by_name": { ... } } }
- param path:
File path to write the JSON log. Creates parent dirs as needed.
- type path:
str
- frames_with_metadata()[source]¶
Yield tuples of (index, frame_array, metadata) for all frames.
- Yields:
tuple[int, np.ndarray, dict[str, Any]] – Frame index, 2D image array, and metadata dict.
Notes
If any frame array is None, it is skipped with a warning log.
- get_frame(index: int) ndarray[source]¶
Retrieve the 2D image array for a specific frame index.
- Parameters:
index (int) – Frame index to retrieve.
- Returns:
2D array of shape (
height,width) for the frame.- Return type:
np.ndarray
- Raises:
IndexError – If index is out of bounds.
- get_frame_metadata(index: int) dict[str, Any][source]¶
Retrieve metadata dict for a specific frame index.
- Parameters:
index (int) – Frame index.
- Returns:
Metadata dict for that frame (includes normalized ‘timestamp’).
- Return type:
- Raises:
IndexError – If index is out of range.
- get_frame_times() list[float][source]¶
Return a list of timestamps (in seconds) for each frame in the stack.
This method uses time_for_frame() to retrieve the timestamp for each frame, which allows central control over fallback behavior.
- Returns:
List of timestamps per frame. If unavailable, the frame index is used as a fallback.
- Return type:
Examples
>>> stack.frame_metadata = [{"timestamp": 0.0}, {"timestamp": 1.0}] >>> stack.get_frame_times() [0.0, 1.0]
>>> stack.frame_metadata = [{"timestamp": 0.0}, {}] >>> stack.get_frame_times() [0.0, 1.0]
- get_frames() list[ndarray][source]¶
Return a list of all individual 2D frame arrays.
- Returns:
List of length n_frames, each a 2D array.
- Return type:
list of np.ndarray
- property height: int¶
Get the number of pixel rows (frame height).
- Returns:
Number of rows per frame.
- Return type:
- property image_shape: tuple[int, int]¶
Spatial dimensions of a single frame.
- Return type:
tuple of (
height,width)
- classmethod load_data(path: str | Path, channel: str = 'height_trace') AFMImageStack[source]¶
Load AFM data from a file or folder into AFMImageStack, normalizing timestamps.
- Parameters:
- Returns:
Fully reconstructed AFMImageStack with processed snapshots and provenance.
- Return type:
- property n_frames: int¶
Number of frames in the stack.
- Returns:
Number of frames (size along axis 0).
- Return type:
- restore_raw() ndarray[source]¶
Restore self.data from the ‘raw’ snapshot in self.processed.
- Returns:
The restored raw data.
- Return type:
np.ndarray
- Raises:
KeyError – If ‘raw’ data is not available in self.processed.
- time_for_frame(idx: int) float[source]¶
Get timestamp for a given frame index, fallback to index if missing.
- Parameters:
idx (int) – Frame index.
- Returns:
Timestamp in seconds; if metadata lacks ‘timestamp’, returns float(idx).
- Return type:
- Raises:
IndexError – If idx is out of range.
Notes
This fallback (index-as-time) assumes uniform frame intervals and is useful for stacks without explicit time metadata.
Examples
>>> stack.frame_metadata = [{"timestamp": 0.0}, {}, {"timestamp": 2.0}] >>> stack.time_for_frame(1) 1.0 >>> stack.time_for_frame(2) 2.0