Custom Analysis Modules¶
You can extend playNano by writing your own analysis modules and registering them as plugins. This allows you to integrate custom feature detectors, tracking methods, or specialised statistics into the standard pipeline.
Stucture and Requirements¶
Custom modules must subclass playnano.analysis.base.AnalysisModule and
implement two things:
a
nameproperty returning a unique string identifiera
run(stack, previous_results=None, **params) -> dictmethod
You may also define:
a
versionclass attribute (string) to help with provenance trackinga
requireslist to declare required previous analysis modules
Minimal Example¶
from playnano.analysis.base import AnalysisModule
from playnano.afm_stack import AFMImageStack
class MyModule(AnalysisModule):
version = "0.1.0"
@property
def name(self) -> str:
return "my_module"
def run(self, stack: AFMImageStack, previous_results=None, **params):
# Example: count total number of pixels in the dataset
return {"count": stack.data.size}
Outputs must be returned as a dictionary mapping string keys to
results (arrays, dicts, numbers, etc.). These values are stored under
stack.analysis and linked in the provenance log.
Declaring Dependencies¶
If your module requires the outputs of another analysis step, you can
declare this using the requires class attribute:
class MyDependentModule(AnalysisModule):
requires = ["detect_particles"]
@property
def name(self):
return "my_dependent"
def run(self, stack, previous_results=None, **params):
particles = previous_results["detect_particles"]["coords"]
return {"n_particles": len(particles)}
This ensures the pipeline provides access to upstream results.
This isn’t fully fleshed out so if you encounter any isssue please raise and issue on GitHub.
Registering the Module¶
Add an entry under [project.entry-points."playnano.analysis"] in
pyproject.toml so the plugin system can discover your module:
[project.entry-points."playnano.analysis"]
my_module = "mypackage.mymodule:MyModule"
After installation (pip install .), playNano will automatically detect
your plugin.
Best Practices¶
Keep outputs JSON-friendly if you expect to log or export to JSON. For large arrays, consider summarising or providing statistics.
Add a version string (
version = "0.1.0") to make provenance records more reproducible.Document parameters and outputs with clear docstrings - they appear in generated module documentation.
Test modules in isolation before adding them to pipelines.
Use consistent naming: short, lowercase, underscores for
name.
Usage in a Pipeline¶
Once installed, your module can be invoked just like a built-in one:
playnano analyze data/sample.h5 \
--analysis-steps "my_module:param1=42"
or programmatically:
from playnano.analysis.pipeline import AnalysisPipeline
pipeline = AnalysisPipeline()
pipeline.add("my_module", param1=42)
pipeline.run(stack)
Debugging & Troubleshooting¶
Use logging (
import logging) within your module for debug output.Check
stack.provenance["analysis"]after running a pipeline to confirm your module’s results were recorded.