What’s New in playNano 0.4.0¶
Release date: 226-05-11
This release adds a new file reader for Asylum Research high-speed AFM data, three new animated export formats, a unified colormap system with perceptually linear maps designed for AFM data, and a vertical-flip processing filter. It also extends Python and NumPy support, refactors the visual rendering pipeline, and includes numerous fixes to per-frame metadata handling across all loaders.
Added¶
ARIS File Reader: playNano can now load Asylum Research
.arishigh-speed AFM files. The loader extracts channel names from HDF5 metadata, computes global and per-frame pixel-size scaling with well-defined fallback behaviour, sorts and stacks frames, and parses and validates timestamps. Multi-suffix file loading (e.g..ome.tif) is also now supported in the loader dispatch logic.Video and Image Sequence Export: Two new animated export formats are available alongside GIF:
Video — MP4, AVI, MOV, and MKV via
playnano.io.video_export.Image sequences — individual PNG or JPEG files in a named folder via
playnano.io.image_sequence_export.
All three formats share a unified rendering pipeline in the new
playnano.io.render_utilsmodule, which enforces a minimum output resolution (512 px), ensures scale bars are physically accurate regardless of frame size, and keeps annotation proportions consistent across resolutions. See :doc:exportingfor full details.Native Colormaps: Three perceptually designed colormaps are now bundled and registered globally as Matplotlib colormaps on import:
afm_brown(default) — perceptually linear (R² ≈ 0.996), eliminates the dark plateau and flicker artefacts common in traditional AFM colour schemes.playnano_gold— full dynamic range (L* 0–100), high contrast for complex topography.classic_afm— non-linear legacy map for continuity with existing workflows.
Reversed variants (
_r) are registered automatically. See :doc:colormapsfor background, usage, and a comparison withafmhot.Vertical Flip Filter: A new built-in processing filter
vertical_flipreverses the row order of a 2D frame usingnumpy.flipud.Python 3.13 and NumPy 2.x Support: Python 3.13 is now officially supported and included in the CI test matrix. The NumPy upper-version pin (
<2.0) has been removed, enabling compatibility with NumPy 2.0 and later.CLI Additions:
--versionglobal flag prints the installed playNano version and exits.--cmapselects a colormap inplay,process, andwizard.--fpscontrols frame rate for animated exports. Inplay, the argument is optional and falls back gracefully to a default of 5 fps with a logged warning if a non-numeric value is supplied; inprocess, a numeric value is required.--make-videoexports video after processing (default format: MP4).--make-sequenceexports a PNG image sequence after processing.--draw-tstoggles timestamp rendering on animated exports (default: off).Wizard REPL extended: after GIF export the wizard now prompts for timestamps, scale-bar length, and optionally exports a video with configurable
zmin,zmax, timestamps, and scale bar.
src/playnano/resources/: A dedicated package for non-code assets. Bundled fonts have been moved here fromsrc/playnano/fonts/, and colormap CSV files are loaded viaimportlib.resourcesfor robust cross-platform asset access.sphinx-apidocIntegration: API documentation is now generated automatically via abuilder-initedhook inconf.py, removing the need to maintain RST stubs manually.
Changed¶
Per-Frame Pixel-Size Semantics¶
AFMImageStack.pixel_size_nm now represents the global or first-frame pixel size only.
Per-frame overrides are stored in frame_metadata[i]["frame_pixel_size_nm"] and are read
via the new AFMImageStack.scaling_for_frame(idx) method. For most datasets the values
are identical; differences arise when scan size changes mid-acquisition (e.g. ARIS files).
GUI playback and all animated exports now respect per-frame pixel size.
All loaders have been updated to populate frame_pixel_size_nm in every frame_metadata
entry. The frame_metadata construction bug that caused entries to be overwritten or
incomplete in the .spm and .jpk loaders has been fixed. The .h5-jpk and .asd
loaders record a constant value; .jpk, .spm, and .aris record per-frame values.
OME-TIFF export now raises a ValueError if pixel sizes are not consistent across frames,
since the format only supports a single PhysicalSizeX/PhysicalSizeY value.
Visualisation Rendering¶
The rendering logic previously embedded in export_gif has been extracted into
playnano.io.render_utils, which is now the single source of truth for frame
normalisation, colourisation, upscaling, and annotation across all visual exports.
Visual constants (minimum frame height, reference height, annotation colour, font scale)
are centralised here. The default colormap for all exports has changed from afmhot
to afm_brown.
GUI¶
A colormap selection dropdown has been added to the export panel.
The z-scale histogram bars are now coloured with the active colormap and update dynamically when
zmin,zmax, or the colormap change.The GIF export panel has been replaced with a unified Save Animated Data panel supporting GIF, MP4, AVI, and PNG folder exports via per-format checkboxes.
FPS is now initialised from
--fpsif provided, otherwise derived fromline_ratein the first frame’s metadata (previously always defaulted to 10 fps in the controls).
Developer Tooling¶
Pre-commit exclude paths updated from
src/playnano/fonts/tosrc/playnano/resources/fonts/across all hooks.np.string_()replaced withnp.bytes_()in HDF5 export for NumPy 2.x compatibility._decode_attrinread_h5jpkpromoted toplaynano.utils.io_utils.decode_hdf5_attrand reused inread_aris.
Fixed¶
Fixed loader errors caused by missing file extensions or no-suffix inputs; the loader now correctly handles multi-suffix formats such as
.ome.tifand.ome.tiff.Connected FPS calculation based on
line_rateto GUI playback; previously the computed value was not passed through to the GUI controls.Fixed
frame_metadataconstruction in.spmand.jpkfolder loaders: entries were previously overwritten in the loop, resulting in only the last frame’s metadata being retained.Standardised per-frame metadata keys across all formats:
timestamp,frame_pixel_size_nm, andline_rate.Removed the inconsistent pixel-size equality check in
.spmand.jpkfolder loaders; per-frame variation is now recorded rather than raising aValueError.Improved numerical robustness in tests: floating-point comparisons now use
pytest.approxfor cross-platform consistency.
Documentation¶
New :doc:
colormapspage covering the three native colormaps, their perceptual properties, usage in the CLI and GUI, and background on perceptual linearity in AFM visualisation.:doc:
exportingrestructured into Animated Exports (GIF, video, image sequence) and Data Exports (OME-TIFF, NPZ, HDF5) sections, with full CLI and programmatic usage for each format.:doc:
cliupdated with global options (--version,--log-level), newprocessandplayflags, and corrected help text for FPS defaults.:doc:
guiupdated to document the colormap selector, unified animated export panel, and revised annotation controls.:doc:
introductionand :doc:indexupdated to include.arisin the list of supported formats.processing-operations-referenceupdated to includevertical_flip.API reference reorganised into captioned sections: Core, IO & Data Formats, Processing Pipeline, Analysis & Modules, General Utilities, CLI & App Utils, and Graphical Interface.
Pytest Coverage Added¶
ARIS HDF5 loading: channel extraction, global pixel scaling, frame key sorting, per-frame pixel-size overrides and fallback to global scale, timestamp mismatch, and missing channel errors.
Multi-suffix file handling:
.ome.tif,.ome.tiff, and all single-suffix formats viaget_loader_for_file.Video export: all four container formats, flat data, various z-scale configurations, raw/processed data selection, and early-exit when
make_video=False.Image sequence export: PNG and JPEG output, flat data, various z-scale configurations, raw/processed data selection, and invalid format rejection.
render_utils: upscaling behaviour, global normalisation, flat-frame handling, NaN/inf robustness, and physically accurate scale bar width across frame sizes and pixel sizes.Colormap utilities:
resolve_cmapfallback and warning, load-failure error logging,is_valid_cmapwith non-string and unregistered inputs,get_available_cmapssort order.GUI:
_get_cmapfallback,_on_cmap_changedwith valid and invalid names,_update_histogram_colorsz-range selection, and_export_animatedraw/processed branch logic.CLI FPS parsing:
playwith no flag, flag without value, valid numeric value, and invalid string;processerror on invalid value; help text content.AFMImageStack.scaling_for_frame: present and missingframe_pixel_size_nmentries.