Processing¶
Overview¶
The playnano.processing subpackage provides tools for preparing AFM time-series
data for viewing and analysis. It includes functions for levelling, filtering,
masking, alignment, and trimming. These
operations are modular and composable,
allowing reproducible pipelines tailored to specific datasets and goals.
Processing is coordinated by
ProcessingPipeline, which manages the
reproducible and provenance-tracked transformation of an
AFMImageStack. A pipeline consists of an ordered list
of steps, where each step defines an operation and its parameters. Steps are executed
sequentially, and all parameters, versions, and outputs are logged for traceability.
This guide covers:
CLI / GUI usage and examples
Pipeline structure and step types
Built-in processing operations and plugin support
Programmatic usage
What the pipeline records
See also the Command Line Interface (CLI), GUI: Interactive Playback, and Analysis pages for related workflows.
CLI / GUI Usage¶
Processing can be applied directly from the CLI (process subcommand) or in the
interactive GUI (play command). In both cases, processing steps are defined using
a semicolon-separated string or a YAML file.
The --processing argument accepts a semicolon-separated list of steps. Each step
is either a data operation, a mask generator, with optional parameters passed via
colon-separated key-value pairs or clear that resets masks. For example:
playnano process ./tests/resources/sample_0.h5-jpk \
--processing "remove_plane;threshold_mask:threshold=1.5;row_median_align;gaussian_filter:sigma=2.0" \
--export tif,npz \
--make-gif \
--output-folder ./results \
--output-name sample_processed
Alternatively, pipelines can be defined in YAML for better readability and reuse:
filters:
- name: remove_plane
- name: threshold_mask
threshold: 2
- name: polynomial_flatten
order: 2
- name: gaussian_filter
sigma: 2.0
Run it via:
playnano process ./tests/resources/sample_0.h5-jpk \
--processing-file pipeline.yaml \
--export tif,npz \
--make-gif \
--output-folder ./results \
--output-name sample_processed
Interactive pipeline creation is supported via the wizard subcommand:
playnano wizard ./tests/resources/sample_0.h5-jpk \
--output-folder ./results \
--output-name processed_sample
Use save <filename-to_save>.yaml within the wizard to export the constructed
pipeline as YAML for reuse with --processing-file.
Pipeline Structure and Step Types¶
A ProcessingPipeline organizes transformations
into sequential steps applied to an
AFMImageStack. Each step performs a specific task such
as filtering, masking, or alignment and can be configured with parameters. Steps are
executed in order, and results are tracked with metadata to ensure reproducibility.
After execution, the data attribute is
updated with the final processed array.
Operation Types¶
Filters (2D frame operations) — modify individual frames (e.g. flattening, smoothing). Accept 2D NumPy arrays and return float arrays. Masked regions (if defined by a preceding mask operation) are excluded automatically.
Masks (2D binary operations) — generate boolean masks to exclude regions from filters or analysis. Masks are combined via logical OR. Use
clearto reset.Video Processing (3D stack operations) — apply transformations across full time-series stacks, such as alignment or drift correction. Operate on 3D arrays and may record metadata.
Stack Edits (AFMImageStack-level operations) — modify dataset structure (e.g. cropping, frame removal). Return a new 3D array, with metadata and timestamps updated automatically.
Step Naming and Provenance¶
Each step is named as step_<index>_<operation_name> and its output is stored in
processed (for data) or
masks (for binary masks).
Provenance information is stored in
provenance["processing"] and includes:
steps— ordered list of step records (parameters, versions, timestamps, etc.)keys_by_name— maps operation names to their snapshot keys.
This ensures all transformations are traceable and reproducible.
Processing Operations¶
Built-in Filters & Masks¶
Several built-in filters and masks are available. Each takes a NumPy array and optional parameters, returning either a processed float array (filters) or binary mask array (masks).
See Processing Operations Reference for a full list.
Plugins¶
Custom filters can be added via entry points under playnano.filters. Any callable
that accepts a 2D NumPy array and returns a processed array can be registered.
Example pyproject.toml snippet:
[project.entry-points."playnano.filters"]
my_plugin = "my_pkg.module:my_filter"
Example plugin function:
def my_filter(frame: np.ndarray, **kwargs) -> np.ndarray:
"""Process a 2D array and return a filtered version."""
When the plugin is installed, it appears in the same CLI/API list as the built-in filters.
CLI / GUI Usage¶
The processing pipeline can defined in the CLI and run in the CLI or the GUI.
The playNano wizard allows processing pipelines to be built interactively.
To launch this you use the wizard subcommand followed by a path to the file you
are processing and flags that define the output folder and file name (see Command Line Interface (CLI)).
Once built the pipeline can be saved as yaml file that can be used in future runs or
run immediately within the wizard.
Run the wizard with:
playnano wizard .test/resources/sample_0.h5-jpk --output-folder ./results --output-name processed_sample
Once the data is loaded, use the add command followed by the name of a filter, mask
or mask to add steps to the pipeline. The wizard will then prompt you to enter optional or
required parameters. Once the pipeline is complete use the save with the path to a .yaml
file to save the pipeline.
Once constructed and saved the processing pipeline that has been built can be run with the
run command which will run the processing pipeline, step-by-step, with the configured
parameters. The wizard will then ask if you would like to export the processed data as .npz,
.h5 or .ome-tiff and then if you would like to generate a .gif.
- Programmatic usage
“””Process a 2D array and return a filtered version.””” …
Installed plugins appear alongside built-in filters in the CLI and GUI.
Programmatic Usage¶
Use the ProcessingPipeline class directly for
custom pipelines:
from playnano.afm_stack import AFMImageStack
from playnano.processing.pipeline import ProcessingPipeline
stack = AFMImageStack.load_afm_stack("data/sample.h5-jpk", channel="height_trace")
pipeline = ProcessingPipeline(stack)
pipeline.add_filter("remove_plane")
pipeline.add_mask("mask_threshold", threshold=2.0)
pipeline.add_filter("gaussian_filter", sigma=1.0)
pipeline.run() # updates stack.processed and stack.data
After execution, the processed frames are available via stack.data, and intermediate
snapshots can be accessed through stack.processed.
Saved data & exports¶
The processing system supports exporting processed results and snapshots to:
OME-TIFF - multi-frame TIFF, compatible with ImageJ/Fiji.
NPZ - numpy zipped archive containing arrays and metadata.
HDF5 - self-contained bundle including data, processed snapshots and provenance.
GIF - annotated animated GIF (requires timing metadata for correct frame rates).
Use the CLI flags --export, --make-gif, --output-folder and --output-name to
control export behaviour (See Command Line Interface (CLI) for CLI flag details).
What the pipeline records¶
After execution, the following are available:
stack.processed— processed frame snapshots keyed by step namestack.masks— boolean masks keyed by step namestack.provenance["processing"]— full step records and mappingsstack.provenance["environment"]— runtime metadata (Python/OS/package versions)
These enable complete reproducibility and intermediate inspection.
Inspecting Results Programmatically¶
After running a processing pipeline, processed arrays, masks, and provenance information
are stored directly on the AFMImageStack object.
You can use the following commands to explore what was generated:
print(sorted(stack.processed.keys()))
print(sorted(stack.masks.keys()))
for step in stack.provenance["processing"]["steps"]:
print(step["index"], step["step_type"], step["name"])
for key in stack.provenance["processing"]["keys_by_name"].get("polynomial_flatten", []):
arr = stack.processed[key]
['step_1_remove_plane', 'step_2_polynomial_flatten']
['step_3_threshold_mask']
1 filter remove_plane
2 filter polynomial_flatten
3 mask threshold_mask
This indicates two filters and one mask were applied in sequence. You can access a specific result directly:
flattened = stack.processed[“step_2_polynomial_flatten”] print(flattened.shape)
which returns a NumPy array representing the processed frame or stack at that step.
Tips & Troubleshooting¶
If a
rawsnapshot is missing, check if it was loaded from an existing bundle.If a plugin does not appear in the CLI, verify that its entry point group is
playnano.filters.For large datasets, prefer exporting HDF5 bundles instead of large JSON logs.
See also¶
Processing Operations Reference — list of all built-in operations
Command Line Interface (CLI) — command-line usage
GUI: Interactive Playback — interactive GUI overview
Exporting Data — export formats and options
Analysis — analysis pipelines and provenance