SPM-Kit · Fathom — Usage Guide¶
Source manual 0.1.5.dev0 (Alpha) — GitHub release 0.1.4 — PyPI 0.1.2 — 2026-07-29
Canonical documentation: This Markdown file is the authoritative reference for the SPM‑Kit
development tree 0.1.5.dev0. A printable companion PDF is available at
docs/user-guide.pdf and in the embedded PDF reader. Both are verified
against the current source tree. The latest tagged source release is 0.1.4; the latest
PyPI distribution is 0.1.2.
Creator, author, and lead developer: José Labarca Baeza.
Tomás Corrales and the SPM Lab at Universidad Técnica Federico Santa María provided selected experimental datasets and laboratory context during the development and evaluation of SPM-Kit.
María Saavedra Fredes and Benjamin Schleyer helped locate and share candidate datasets for the validation campaigns.
Released under the MIT license, without dedicated institutional funding. License: MIT • Repository: https://github.com/kegouro/spmkit • Site: https://kegouro.github.io/spmkit
1. Introduction¶
1.1 What is SPM-Kit?¶
SPM‑Kit is an open‑source Python toolkit for analysing AFM/KPFM scanning‑probe‑microscopy data.
It reads demonstrated variants of NanoSurf .nid / .nhf, Gwyddion .gwy, Bruker/Nanoscope
.spm, and JPK force data, then exports inspectable results: roughness parameters, line profiles, KPFM contact‑potential
statistics, nanomechanical property maps, thermal‑tune cantilever calibration, grain detection,
spectral analysis, and single‑molecule force spectroscopy.
SPM‑Kit was created and is authored and led by José Labarca Baeza as an independent software project. Acknowledged dataset and laboratory-context contributions do not create software authorship or institutional ownership.
1.2 What is Fathom?¶
Fathom is the desktop workspace application bundled with SPM‑Kit. It is a PyQt6 + pyqtgraph
GUI organised into perspectives (task‑oriented views) rather than flat tabs. Each perspective
shows only the panels relevant to a specific workflow. A command palette (Ctrl+K) provides
keyboard access to everything.
1.3 Relationship between components¶
spmkit (Python package)
├── spmkit.core — numerical engine (pure Python, no UI imports)
├── spmkit.cli — command‑line interface (Typer + Rich)
└── spmkit.gui — Fathom desktop workspace (PyQt6 + pyqtgraph)
spmkitis the Python package and CLI entry point.- Fathom is the graphical workspace. It imports
spmkit.corefor all computation; it never contains analysis logic itself. - SPM-Kit is the project/ecosystem name.
1.4 What SPM-Kit does not do¶
- It is not a microscope controller (cannot connect to an instrument).
- It is not a certified metrology tool.
- It does not provide medical, clinical, or regulatory reports.
- It does not guarantee correctness for any specific instrument or sample.
- Its simulation features are educational, not quantitative digital twins.
1.5 Reproducibility¶
SPM‑Kit enforces strict separation between computation and presentation (verified by
tests/test_architecture.py). Analysis pipelines can be saved as YAML recipes (core.pipeline)
to preserve declared operations and parameters. Byte‑level tracing for demonstrated .nid paths is available through
spmkit verify.
1.6 Status¶
SPM‑Kit is alpha‑stage software (Development Status :: 3 - Alpha). Its strongest
retained evidence is LEVEL 3 — CROSS_VALIDATED for Sa, Sq, and Sz under frozen campaign
conditions: 48 synthetic matrices produced 144/144 conforming comparisons and 12 public
experimental GWY records produced 36/36 shared‑matrix comparisons against Gwyddion 2.71.
The parser/end‑to‑end observations remain separate. Six Nanoscope III .spm files support a
partial LEVEL 2 claim with a documented pre‑freeze unblinding incident. KPFM, spectra,
grains, and resonance remain at Level 1; contact and chain models have claim‑scoped synthetic
Level 2 evidence. No general Level 4 or Level 5 claim is made. See
§13.
2. Installation¶
Requirements: Python ≥ 3.11.
| Distribution | Version documented on 2026-07-29 | Use when |
|---|---|---|
| PyPI | 0.1.2 |
you need the published package snapshot |
| GitHub release | 0.1.4 |
you need the latest tagged source release |
main source tree |
0.1.5.dev0 |
you need the behavior documented by this manual |
Choose the source explicitly. pip install spmkit currently installs the PyPI
snapshot, not the latest GitHub release.
2.1 Core only¶
Installs the numerical core and CLI. Optional format dependencies are still required for
.nhf, .gwy, and adapter-backed formats.
2.2 GUI / Fathom¶
Adds: PyQt6, pyqtgraph, matplotlib, Crameri colormaps, matplotlib‑scalebar.
2.3 All features¶
all includes the declared reader, visualization, reporting, and GUI extras. It does not
include developer, GUI-test, parallel, or pandas extras.
2.4 Extras matrix¶
| Extra | Provides | Dependencies |
|---|---|---|
gui |
Fathom desktop workspace | PyQt6, pyqtgraph, matplotlib |
viz |
Publication figures, colormaps | matplotlib, cmcrameri, matplotlib‑scalebar |
gwy |
Gwyddion read/write (.gwy) |
gwyfile |
hdf5 |
HDF5 import/export | h5py |
grains |
Grain/particle detection | scipy |
report |
HTML/PDF report generation | Jinja2 + spmkit[viz] |
nanosurf |
Optional NSFopen dependency | NSFopen |
afm |
JPK QI, .ibw, HDF5, NT‑MDT, etc. |
afmformats |
jpk |
JPK TIFF force curves | tifffile |
parallel |
Parallel force‑volume processing | joblib |
pandas |
DataFrame export for batch results | pandas |
dev |
Lint, test, type‑check | pytest, ruff, mypy, black |
test-gui |
GUI test runner | pytest‑qt |
docs |
Documentation build | mkdocs‑material |
2.5 Development installation¶
2.6 Headless / HPC¶
For headless or cluster use, install the tagged core package only:
All analysis code (core.*) has no GUI dependencies. For headless figure generation, add viz:
2.7 Platform notes¶
SPM‑Kit is developed and tested on macOS and Linux. Windows is not regularly tested.
GUI (Fathom) requires a Qt platform plugin. On headless servers, set QT_QPA_PLATFORM=offscreen
for tests; Fathom itself requires a display.
3. Verifying the installation¶
spmkit --version
# spmkit 0.1.4 for the tagged install above
python -c "import spmkit; print(spmkit.__version__)"
# 0.1.4 for the tag, 0.1.2 from PyPI, or 0.1.5.dev0 from main
python -c "from spmkit.gui.app import run; print('GUI import OK')"
# GUI import OK (does not launch; no Qt display needed)
4. Conceptual model¶
4.1 Architecture¶
┌─────────────┐
.nid / .nhf │ spmkit.core│ .gwy, .h5, .csv, .json, .png, .pdf
.gwy / .jpk ──► │ (pure Py) │ ──►
└──────┬──────┘
│ public API
┌─────────┴─────────┐
│ │
spmkit.cli spmkit.gui
(Typer+Rich) (Fathom · PyQt6+pyqtgraph)
corenever imports fromcliorgui(enforced by AST test).cliandguiimport only the public API ofcore.- All scientific logic lives in
core.analysis.*.
4.2 Data model¶
from spmkit import load, SPMData, SPMChannel
data: SPMData = load("scan.nid")
ch: SPMChannel = data["Z-Axis"] # or data["Z-Axis", "forward"]
ch.data # 2D ndarray in physical units
ch.unit # "m", "V", "°", etc.
ch.x_range # metres
ch.y_range # metres
ch.shape # (rows, cols)
ch.direction # "forward" | "backward"
ch.metadata # dict with instrument parameters
4.3 Force‑spectroscopy domain model¶
For force‑curve analysis, spmkit.core.models.force provides:
ForceCurve— a single approach/retract cycleForceSegment— a labelled segment (extend, retract, pause, modulation)ForceVolume— a grid of force curves (lazy‑loaded, not all held in RAM)Calibration— InvOLS, spring constant, method, temperature
4.4 Result objects¶
Every analysis function returns an immutable dataclass (e.g. RoughnessResult,
CPDResult, GrainResult, FractalResult, IndentationResult, MechanicalMap,
VolumeResult). Each has a .to_dict() method and can be serialised via
spmkit.core.export.
5. Supported file formats¶
| Extension | Source | Data type | Access | Extra | Status |
|---|---|---|---|---|---|
.nid |
NanoSurf classic | Images + spectroscopy | Read | — | Implemented; selected comparisons, synthetic byte/orientation tests; variants remain scoped |
.nhf |
NanoSurf HDF5 | Images | Read | hdf5 |
Experimental generic HDF5 traversal |
.gwy |
Gwyddion | Images | Read + Write | gwy |
Implemented interoperability; no universal Gwyddion equivalence |
.spm and detected numbered Nanoscope files |
Bruker / Digital Instruments | Images | Read | — | Partial LEVEL 2; six demonstrated files; pre-freeze unblinding incident |
.jpk-force, .jpk |
JPK | Single force curve | Read | — | Implemented with synthetic fixtures; vendor variants remain scoped |
| JPK tagged TIFF | JPK export | Force data | Read | jpk |
Experimental content-detected route |
.jpk-qi-data, .jpk-force-map, .jpk-qi-series |
JPK | Force data | Read | afm |
Experimental adapter path |
.ibw, .h5, .tab |
afmformats-supported sources | Force data | Read | afm |
Experimental adapter path; behavior follows installed afmformats |
.npz |
SPM-Kit Phantoms | Images | Read | — | Implemented for declared bundle keys, not generic NumPy archives |
5.1 Maturity vocabulary¶
| Label | Meaning |
|---|---|
| LEVEL 0 — CLAIMED | Intended behavior is documented without retained executable evidence. |
| LEVEL 1 — SOFTWARE_VERIFIED | Automated software tests exercise the declared path. |
| LEVEL 2 — NUMERICALLY_VERIFIED | A known value is recovered within a stated numerical scope and tolerance. |
| LEVEL 3 — CROSS_VALIDATED | A frozen external comparison supports a claim under declared versions, data, preprocessing, and tolerance. |
| LEVEL 4 — PHYSICALLY_VALIDATED | A calibrated physical reference supports the scoped capability. |
| LEVEL 5 — REPRODUCIBILITY_VALIDATED | An independent party reproduced the declared result. |
5.2 What "validated" means for .nid¶
The NanoSurf parser implements header-directed integer decoding, physical conversion, channel
ordering, and orientation. Synthetic byte-budget and orientation tests provide Level 1 evidence;
selected laboratory-context comparisons do not establish universal NanoSurf coverage. The
private instrument corpus is not distributed. Separately, the Sa/Sq/Sz shared-matrix campaigns
provide scoped Level 3 evidence. Keep parser, algorithm, and physical-validation claims separate;
see docs/TRACEABILITY.md, docs/SCIENTIFIC_STATUS.md, and SPM-Kit Validation.
6. Quick start¶
6.1 CLI: inspect a file¶
6.2 CLI: roughness¶
6.3 Python: load and analyse¶
from spmkit import load
from spmkit.core.analysis import leveling, roughness
data = load("scan.nid")
flat = leveling.plane_fit(data["Z-Axis"])
stats = roughness.statistics(flat)
print(f"Sa = {stats.Sa:.3g} {stats.unit}")
6.4 Fathom: open a file¶
Then drag‑and‑drop a different file onto the window, or use Ctrl+O.
6.5 CLI: force curve¶
6.6 Export a publication figure¶
7. Fathom desktop workspace¶
7.1 Launching¶
spmkit gui # Fathom (default)
spmkit gui scan.nid # open file on launch
spmkit gui --legacy # legacy 7‑tab application (fallback)
7.2 Workspace layout¶
- Top toolbar — file actions (Open/Save) then perspective buttons.
- Central area — the main canvas for the active perspective.
- Side docks — inspector, navigator, pipeline, log panels (perspective‑dependent).
- Command palette —
Ctrl+K; search or execute any command by name. - Status bar — progress, errors, workspace state.
7.3 Opening data¶
- Drag and drop a file onto the window.
Ctrl+Oopens the file dialog.- Fathom inspects the file and routes it: image channels go to image perspectives; force/spectroscopy data goes to force perspectives. If a file contains both images and curves, Fathom asks which to open.
7.4 Projects (.spmproj)¶
- Save (
Ctrl+S) — persists the open file, pipeline parameters, and active perspective. - Open project — restores the previous session state.
- File format: human‑editable YAML (
.spmproj).
7.5 Reports¶
Ctrl+Shift+R— generate a report (HTML + PDF) from the current data.- For force‑volume data:
spmkit forcereport scan.nid -o reportgenerates a full report with property maps, statistics, and fitted curves.
7.6 Appearance¶
Ctrl+Shift+L— toggle light/dark theme.Ctrl+Shift+A— appearance dialog with live preview. Choose from presets (Graphite, Paper, NanoSurf gold, Nord, Dracula, Solarized, Gruvbox), custom accent colour, and font size (Compact/Normal/Comfortable/Large).- Settings persist between sessions.
- The theme feeds the application, pyqtgraph, and matplotlib simultaneously.
7.7 Command palette¶
Press Ctrl+K, type a command name, and press Enter. The palette indexes:
- "Go to <Perspective>" for every registered perspective
- "Theme: toggle light/dark" (
Ctrl+Shift+L) - "Customize appearance…" (
Ctrl+Shift+A) - Any commands registered by installed modules
7.8 Error reporting¶
Panel build failures show an error card inside the panel instead of crashing the application. The Log panel (in Batch perspective) collects diagnostic messages.
7.9 Perspectives¶
Image (image)¶
Purpose: Visualise and analyse 2D SPM image channels.
| Feature | Description |
|---|---|
| Channel selector | Choose any loaded channel (Z‑Axis, Phase, CPD, etc.) |
| Leveling | Plane fit / polynomial / align‑rows; applied on selection |
| Colormap | Crameri or NanoSurf gold; switchable per channel |
| Line profile | Drag an ROI on the image to extract a 1D profile |
| Analysis panel | Roughness (Sa, Sq, Sz, Ssk, Sku), KPFM/CPD statistics, profile plot |
| Export | Profile CSV, figure PNG/SVG/PDF |
Scientific assumptions: Leveling plane‑fit preserves mean height and removes tilt.
KPFM work‑function calculation uses Φ_sample = Φ_tip - e·CPD.
Grains (grains)¶
Purpose: Detect particles/grains on a levelled topography channel.
Uses SciPy, which is a required SPMKit dependency.
| Feature | Description |
|---|---|
| Detection | Adaptive threshold (fraction of height range) + minimum size filter |
| Overlay | Colour‑coded grain overlay on the image |
| Statistics | Count, mean equivalent diameter, coverage fraction, density per μm² |
| Controls | Minimum pixel size, relative height threshold |
Limitations: Simple threshold‑based watershed; not robust for overlapping or highly irregular grains. No shape metrics beyond equivalent diameter.
Spectral (spectral)¶
Purpose: Compute the radial power spectral density (PSD) and fractal parameters.
| Feature | Description |
|---|---|
| PSD plot | Log‑log radial PSD |
| Fractal dimension | D = (7 − β) / 2 |
| Hurst exponent | H = 3 − D |
| Correlation length | From PSD crossover |
Scientific assumptions: Self‑affine surface model. The fractal dimension is valid only when the PSD is well approximated by a power law over the measured bandwidth.
Thermal Tune (resonance)¶
Purpose: Fit a thermal noise spectrum to extract cantilever resonance parameters.
| Feature | Description |
|---|---|
| SHO fit | Simple harmonic oscillator fit to the thermal spectrum |
| Outputs | Resonance frequency f₀, quality factor Q, spring constant k (by equipartition) |
| Input | A spectral channel loaded from a thermal‑tune measurement |
Limitations: Requires a clean thermal spectrum with a clear resonance peak. Calibration accuracy depends on the quality of the thermal spectrum and the equipartition assumption.
Evaporation (evaporation)¶
Purpose: Mass sensing via evaporating droplet — track resonance frequency over time.
| Feature | Description |
|---|---|
| Series | Load a folder of sequential thermal‑tune .nid files |
| Mass | Computed from frequency shift and cantilever calibration |
| Evaporation rate | dm/dt from mass vs. time |
| d² law | Linear fit of (radius)² vs. time; indicates diffusion‑limited evaporation |
| Outputs | Time series CSV, plots |
Scientific assumptions: Droplet mass is computed from Δm = k / (4π²) · (1/f² - 1/f₀²).
The d² law fit assumes spherical droplet geometry. The evaporation rate is valid only
for diffusion‑limited regimes.
Force Curve (force)¶
Purpose: Navigate, calibrate, and fit individual force‑distance curves.
| Feature | Description |
|---|---|
| Curve navigation | Ctrl+← / Ctrl+→ for previous/next curve |
| Calibration | InvOLS, spring constant (from metadata or manual) |
| Contact detection | Threshold or rate‑of‑variance (ROV) method |
| Contact models | sphere (Hertz), paraboloid (Sneddon), cone (Sneddon), DMT (Hertz + adhesion) |
| JKR | Experimental adhesive contact model |
| Monte Carlo | Optional uncertainty propagation for E and contact point |
| Outputs | Young's modulus ± 1σ, R², adhesion, dissipation, contact point |
| Export | Scientific CSV with fit curve, raw data, and units |
| Pipeline | Reproducible recipe (YAML) for calibration + contact + fit |
Pipelines are editable in‑app: every threshold, fit range, and model parameter is exposed. The current pipeline can be saved/loaded as a YAML recipe.
SMFS (smfs)¶
Purpose: Single‑molecule force spectroscopy — detect rupture events on retraction curves and fit polymer chain models.
| Feature | Description |
|---|---|
| Event detection | Peak‑prominence based (not a naive threshold) |
| Polymer models | WLC (Marko‑Siggia / Bouchiat) and FJC (Langevin) |
| Outputs | Contour length, persistence/Kuhn length per event; R² quality filter |
| Population | Contour‑length histogram across all events |
| Controls | R² threshold, prominence, height, temperature, WLC variant |
| Export | Events CSV |
Limitations: SMFS interpretation depends on the choice of polymer model and temperature parameter. Prominence‑based detection may miss closely spaced or weak events.
Map (map)¶
Purpose: Analyse a full force‑volume grid and generate property maps.
| Feature | Description |
|---|---|
| Processing | Elasticity pipeline on every curve in the volume |
| Fast path | Vectorised (CPU) or GPU‑accelerated; used for uniform‑length curves |
| Pipeline path | Per‑curve pipeline; used for variable‑length curves (QI data) |
| Maps | Young's modulus, adhesion, contact point, R² — one 2D image each |
| Histogram | Distribution of each property |
| Export | Comprehensive CSV (metadata, per‑property statistics, per‑point table, no NaN dumps) |
--backend cpu vs --backend gpu: GPU backend requires CuPy (optional, not included
in any extra). CPU backend uses vectorised NumPy and is always available.
Batch (batch)¶
Purpose: Process a folder of force curves (or maps) and produce a summary table.
| Feature | Description |
|---|---|
| Input | Folder of .jpk-force, .nid, or other supported force files |
| Output | CSV with one row per file/curve; units in headers; empty cells for missing values |
| Pipeline | Same recipe used for all curves; can be customised |
Figure (figure)¶
Purpose: WYSIWYG editor for publication‑quality figures.
| Feature | Description |
|---|---|
| Layout | Title, axis labels, colour bar, scale bar |
| Colormap | All Crameri gradients + NanoSurf gold |
| Annotations | Draggable text annotations (fully customisable) |
| Scale bar | Physical‑unit scale bar (automatic or manual) |
| Export | PNG, SVG, PDF at publication resolution |
3D View (view3d)¶
Purpose: Interactive 3D surface rendering of topography.
| Feature | Description |
|---|---|
| Surface | Hill‑shaded 3D mesh of the topography channel |
| Z exaggeration | Visual only; data values are unchanged |
| Rotation | Click and drag to rotate; scroll to zoom |
| Display | Z‑axis shown in nm/μm for readability |
Simulator (simulator)¶
Purpose: Educational cantilever digital twin.
| Feature | Description |
|---|---|
| Model | Simple harmonic oscillator with thermal noise |
| Controls | Spring constant, quality factor, added mass |
| Visualisation | Thermal noise spectrum; resonance shift with added mass |
Limitations: Educational only. Does not account for nonlinearities, higher modes, fluid damping, or real cantilever geometry.
8. End‑to‑end workflows¶
8.1 Topography leveling and roughness¶
Goal: Compute ISO 25178 areal roughness parameters from a scanned image.
| Step | GUI | CLI |
|---|---|---|
| Load | Drag & drop .nid onto Fathom |
spmkit info scan.nid |
| Level | Select channel, click Plane Fit | --level plane |
| Analyse | Read Sa, Sq, Sz from Analysis panel | spmkit roughness scan.nid -c Z-Axis |
| Export | Export figure via Figure perspective | spmkit figure scan.nid -o topo.png |
Example data: Synthetic data can be generated with:
import numpy as np
# synthetic roughness demo
x = np.linspace(0, 5e-6, 256)
X, Y = np.meshgrid(x, x)
noise = np.random.normal(0, 1e-8, (256, 256))
topo = noise # flat surface with Gaussian noise; Sq ≈ 1e-8 m
Interpretation: Sa is the arithmetic mean height; Sq is the RMS. Sz = Sp + Sv. Ssk < 0 indicates valleys dominate; Ssk > 0 indicates peaks dominate. Sku > 3 indicates spiky surface; Sku < 3 indicates bumpy surface.
Caveats: Roughness depends on scan size, pixel density, and leveling method. Always report these alongside roughness values.
8.2 Force‑curve contact mechanics¶
Goal: Fit a Hertz/DMT model to a single force‑distance curve and extract Young's modulus.
Output (illustrative values; actual results depend on input data): Force Curve Fit · curve 0 · dmt
┌───────────────────────┬───────────────────────┐
│ Parameter │ Value │
├───────────────────────┼───────────────────────┤
│ Young's Modulus │ 4.50 ± 0.08 MPa │
│ R² │ 0.99921 │
│ Contact Point │ 12.45 nm │
│ Adhesion │ 3.21 nN │
│ RMSE │ 1.234e-11 N │
│ Points Fitted │ 214 │
└───────────────────────┴───────────────────────┘
GUI path: Open file → Force Curve perspective → set model in Pipeline panel → inspect fit on canvas → Export Curve CSV.
Models: sphere (Hertz), paraboloid (Sneddon paraboloid), cone (Sneddon cone),
dmt (Derjaguin‑Muller‑Toporov, Hertz + constant adhesion offset).
Parameters:
| Parameter | Typical range | Notes |
|---|---|---|
--tip-radius |
1–100 nm | Nominal tip radius from manufacturer or blind‑tip reconstruction |
--model |
sphere/dmt/paraboloid/cone | dmt is most common for soft samples |
--contact-method |
threshold/rov | rov is more robust to noise |
Caveats: Modulus values depend on tip radius (uncertain), contact model choice, and
calibration accuracy. Always report the tip radius, model, and fitting range. The JKR
model (spmkit jkr) is experimental — not validated against an independent reference.
8.3 Force‑volume property mapping¶
Goal: Process all curves in a force‑volume grid and generate property maps.
Output: Maps of Young's modulus, adhesion, contact point, and R² — one 2D image per property, plus a histogram.
Fast vs Pipeline: The --fast flag (default) uses vectorised computation; works
for uniform‑length curves. For variable‑length curves (QI data), use --pipeline.
Parallel: Add --parallel for multi‑core processing. Requires the parallel extra.
Export everything:
Creates results/ containing CSV maps, per‑curve table, summary statistics, and
an HTML + PDF report.
8.4 Thermal tune and cantilever calibration¶
Goal: Determine cantilever spring constant and resonance parameters.
CLI path:
# Process individual thermal spectrum (via Python API)
python -c "
from spmkit.core.analysis.mechanics import thermal_spring_constant
from spmkit.core.analysis.resonance import load_evaporation_series
# Load a series of thermal spectra
series = load_evaporation_series(sorted(Path('./tuning/').glob('*.nid')), spring_constant=0.3)
print(f'f0 = {series.bare_frequency:.1f} Hz')
print(f'k = {series.spring_constant:.3f} N/m')
"
GUI path: Open the first file of a tuning series → Thermal Tune perspective
(resonance) → inspect SHO fit and derived parameters.
Caveats: The equipartition method assumes the cantilever is a single‑mode SHO in thermal equilibrium. Accuracy depends on bandwidth, sampling, and background noise.
8.5 Evaporation / mass sensing¶
Goal: Track mass loss of an evaporating droplet via cantilever resonance shift.
Output CSV: time (s), frequency (Hz), mass (kg), added mass (kg), evaporation rate (kg/s). If d² law fitting succeeds, reports initial radius, lifetime, and rate constant.
Interpretation: A linear d² vs. time trend indicates diffusion‑limited evaporation (classic droplet model). Deviations may indicate pinning, environmental changes, or non‑spherical geometry.
8.6 KPFM¶
Goal: Analyse contact potential difference (CPD) from a KPFM channel.
Output: results/scan_kpfm.csv and results/scan_kpfm.json containing mean CPD,
standard deviation, min, max, and (if tip work function provided) sample work function.
Formula: Φsample = Φtip − e · CPD
Caveats: KPFM CPD values are relative to the tip. Absolute work function requires tip calibration on a known reference sample (e.g. HOPG).
8.7 Grain analysis¶
Output: Number of grains, mean equivalent diameter, density, coverage fraction.
8.8 Spectral / fractal analysis¶
Output: Fractal dimension D, Hurst exponent H, PSD slope β, R² of log‑log fit, correlation length.
8.9 Batch processing¶
8.10 Publication figure¶
9. Command‑line reference¶
9.1 Global options¶
| Option | Description |
|---|---|
--version, -V |
Print version and exit |
--help |
Show command help |
9.2 spmkit info — File metadata¶
Displays a table of channels (name, direction, shape, unit, physical size).
9.3 spmkit roughness — ISO 25178 parameters¶
| Option | Default | Values |
|---|---|---|
--channel, -c |
Z-Axis |
Any channel name |
--level, -l |
plane |
plane, poly, none |
Output: Sa, Sq, Sz, Ssk, Sku table via Rich.
9.4 spmkit psd — Spectral analysis¶
Output: Fractal dimension D, Hurst exponent H, PSD slope β, R², correlation length.
9.5 spmkit analyze — Full pipeline¶
Output: DIR/FILE_roughness.csv, DIR/FILE_roughness.json, and KPFM equivalents
if a CPD channel is present.
9.6 spmkit nanomech — Single curve fit¶
| Option | Default | Values |
|---|---|---|
--channel, -c |
Deflection |
Force channel |
--curve |
-1 |
Curve index (-1 = centre) |
--tip-radius |
1e-08 |
Metres |
--model |
sphere |
sphere, paraboloid, cone, dmt |
--contact-method |
threshold |
threshold, rov |
--spring-constant |
— | N/m for indentation correction |
9.7 spmkit grains — Grain detection¶
9.8 spmkit batch — Batch image processing¶
9.9 spmkit evaporation — Mass sensing¶
9.10 spmkit figure — Publication figure¶
| Option | Default | Notes |
|---|---|---|
--output, -o |
figure.png |
.png, .svg, or .pdf |
--colormap |
batlow |
Any Crameri colormap or gold |
9.11 spmkit convert — Format conversion¶
Converts .nid → .gwy (for opening in Gwyddion) or .nid → .h5 (HDF5). Output
format is determined by extension.
9.12 spmkit verify — .nid integrity check¶
Performs up to eight structural and numeric integrity checks over the .nid header,
declared binary layout, channel ranges, and image axes. Malformed files can stop the
sequence early; exit code 1 is returned if any completed check fails.
9.13 spmkit gui — Launch Fathom¶
9.14 spmkit workspace — Force‑curve workspace¶
Alternative force‑spectroscopy workspace (redesign). Requires gui.
9.15 spmkit forcecurve — Force curve fit¶
9.16 spmkit forcemap — Force‑volume analysis¶
spmkit forcemap FILE [--model M] [--tip-radius R] [-o CSV] [-f PNG] [--fast|--pipeline] [--backend cpu|gpu] [--parallel]
9.17 spmkit forcereport — Force‑volume report¶
spmkit forcereport FILE [-o BASE] [--model M] [--tip-radius R] [--formats html,latex,pdf] [--backend cpu|gpu]
9.18 spmkit forceexport — Full export¶
Exports CSV maps, per‑curve table, summary, and (optionally) HTML/PDF report.
9.19 spmkit fbatch — Batch force processing¶
9.20 spmkit jkr — Experimental JKR fit¶
⚠️ Experimental. Not validated against an independent reference. Do not use for publishable results without re‑validation.
10. Python API¶
10.1 Public imports¶
from spmkit import load, SPMData, SPMChannel, __version__
from spmkit.core.analysis import leveling, roughness, kpfm, mechanics, profiles
from spmkit.core.analysis import spectral, grains, resonance, forcevolume, forcecurve
from spmkit.core.export import to_csv, to_json, to_hdf5
from spmkit.core.viz import FigureSpec, save_figure
10.2 Loading data¶
from spmkit import load
data = load("scan.nid") # NanoSurf classic
data = load("scan.nhf") # NanoSurf HDF5
data = load("scan.gwy") # Gwyddion
print(data.names) # ['Z-Axis', 'Phase', 'CPD', ...]
channel = data["Z-Axis"] # SPMChannel
10.3 Channel properties¶
ch = data["Z-Axis"]
ch.data # ndarray
ch.unit # "m"
ch.x_range # metres
ch.y_range # metres
ch.shape # (rows, cols)
ch.pixel_size_x # x_range / cols
ch.pixel_size_y # y_range / rows
10.4 Leveling¶
from spmkit.core.analysis import leveling
flat = leveling.plane_fit(channel)
flat = leveling.polynomial(channel, order=2)
flat = leveling.align_rows(channel)
10.5 Roughness¶
from spmkit.core.analysis import roughness
result = roughness.statistics(flat)
print(result.Sa, result.Sq, result.Sz, result.Ssk, result.Sku)
d = result.to_dict()
10.6 KPFM¶
from spmkit.core.analysis import kpfm
result = kpfm.statistics(data["CPD"], tip_work_function=4.8)
print(result.mean, result.work_function)
10.7 Force spectroscopy¶
from spmkit.core.analysis.mechanics import fit_hertz
from spmkit.core.io.forceload import load_nid_force
volume = load_nid_force("sample.nid")
curve = volume.curves[0]
result = fit_hertz(curve, tip_radius=10e-9, model="dmt")
print(result.young_modulus, result.r_squared, result.adhesion)
10.8 Force‑volume maps¶
from spmkit.core.analysis.forcevolume import analyze_volume
result = analyze_volume(volume, model="dmt", parallel=True)
print(result.stats("young_modulus"))
emap = result.maps["young_modulus"] # 2D ndarray
10.9 Spectral¶
from spmkit.core.analysis.spectral import fractal_dimension, correlation_length
frac = fractal_dimension(flat)
print(frac.fractal_dimension, frac.hurst, frac.r_squared)
10.10 Grains¶
from spmkit.core.analysis.grains import detect
result = detect(flat, min_size=4, relative_height=0.5)
print(result.n_grains, result.mean_diameter, result.density)
10.11 Export¶
from spmkit.core.export import to_csv, to_json, to_hdf5
to_csv(roughness_result, "roughness.csv")
to_json(roughness_result, "roughness.json")
to_hdf5(data, "scan.h5")
10.12 Publication figures¶
from spmkit.core.viz import FigureSpec, save_figure
spec = FigureSpec(title="AFM Topography", colormap="batlow")
save_figure(flat, spec, "topo.png")
10.13 Recipes¶
from spmkit.core.pipeline import Recipe, Step, run
recipe = Recipe(steps=(
Step(op="calibrate"),
Step(op="find_contact_point"),
Step(op="fit_elasticity", params={"model": "dmt", "tip_radius": 2e-8}),
))
_, ctx = run(recipe, curve)
print(ctx["young_modulus"], ctx["r_squared"])
11. Keyboard shortcuts¶
| Action | Shortcut | Context |
|---|---|---|
| Command palette | Ctrl+K |
Fathom (global) |
| Open file | Ctrl+O |
Fathom |
| Save project | Ctrl+S |
Fathom |
| Calculate map | Ctrl+M |
Fathom |
| Generate report | Ctrl+Shift+R |
Fathom |
| Toggle light/dark theme | Ctrl+Shift+L |
Fathom (global) |
| Customize appearance | Ctrl+Shift+A |
Fathom (global) |
| Export results (JSON) | Ctrl+E |
Force‑curve workspace |
| Copy results | Ctrl+Shift+C |
Force‑curve workspace |
| Pin current curve | Ctrl+P |
Force‑curve workspace |
| Previous curve | Ctrl+← |
Force Curve perspective |
| Next curve | Ctrl+→ |
Force Curve perspective |
| First curve | Ctrl+Home |
Force‑curve workspace |
| Last curve | Ctrl+End |
Force‑curve workspace |
| Switch tab 1–5 | Ctrl+1…Ctrl+5 |
Legacy app only |
All shortcuts use Ctrl (macOS: ⌘ is mapped to Ctrl by Qt).
12. Exports, provenance, and reproducibility¶
12.1 Export formats¶
| Format | Via | Notes |
|---|---|---|
| CSV | to_csv(), CLI |
Standard; units in headers |
| JSON | to_json(), CLI |
Structured; suitable for programmatic consumption |
| HDF5 | to_hdf5() + spmkit convert |
Self‑describing binary; requires hdf5 extra |
Gwyddion .gwy |
spmkit convert |
Round‑trip compatible with Gwyddion |
| PNG, SVG, PDF | spmkit figure, save_figure() |
Publication‑quality figures |
| HTML + PDF | spmkit forcereport |
Full force‑volume report |
| YAML recipe | core.pipeline |
Reproducible analysis pipeline |
12.2 Units¶
All physical channels are stored in SI units (metres, Newtons, Volts, degrees).
Exported CSV/JSON files include unit annotations. SPMChannel.unit is always
present and should be checked before comparing values.
12.3 NaN behaviour¶
- Blank/unfitted regions in force‑volume maps are stored as NaN.
- Exported CSVs use empty cells for NaN (not the string "nan").
- Analysis functions propagate NaN to output; missing data is never silently filled with zeros.
12.4 Provenance¶
SPMData.source_pathrecords the original file path.SPMData.metadatapreserves all instrument parameters from the file header..nidfiles can be audited against their declared header and binary layout withspmkit verify.- YAML recipes capture the exact pipeline parameters used.
- Export files include metadata when the format supports it (HDF5, JSON).
12.5 Round‑trip integrity¶
.nid→.gwy: the current automated tests verify that the file is written and, separately, that representative in-memory GWY image data reload within numerical tolerance. They do not establish lossless round-trip fidelity for every.nidvariant..nid→.h5: the current automated tests verify that the exported HDF5 hierarchy is non-empty; full data-and-metadata round-trip equivalence is not yet claimed.- CSV export is lossy (floating‑point formatting); use HDF5 for archival.
13. Scientific validation philosophy¶
Evidence belongs to a claim, data family, version, preprocessing path, tolerance, and campaign. A high level for one metric never transfers automatically to an adjacent reader, model, or sample.
Evidence‑level vocabulary¶
| Level | Meaning |
|---|---|
| LEVEL 0 — CLAIMED | Intended behavior is documented without retained executable evidence. |
| LEVEL 1 — SOFTWARE_VERIFIED | Automated tests exercise the declared behavior. |
| LEVEL 2 — NUMERICALLY_VERIFIED | Known values are recovered within a stated numerical scope and tolerance. |
| LEVEL 3 — CROSS_VALIDATED | An external software or reference route is compared under a frozen protocol. |
| LEVEL 4 — PHYSICALLY_VALIDATED | A physical reference or calibrated experiment supports the scoped capability. |
| LEVEL 5 — REPRODUCIBILITY_VALIDATED | An independent party reproduced the declared result. |
13.1 Status table¶
| Capability | Evidence | Status | Limitations |
|---|---|---|---|
| Sa/Sq/Sz, frozen synthetic matrices | 48 cases, 144/144 within 1e-6 nm + 1e-6 relative vs Gwyddion 2.71 |
LEVEL 3 | shared matrices, no preprocessing, three metrics only |
| Sa/Sq/Sz, public experimental GWY | 12 records, 36/36 shared‑matrix comparisons | LEVEL 3 for algorithm track | parser track separately retained ten equivalences and two channel-count differences |
Nanoscope III .spm |
six files, 18/18 Sa/Sq/Sz and zero reported pixel delta | LEVEL 2 | partial variants; ACCIDENTAL_PRE_FREEZE_UNBLINDING; no blind holdout |
NanoSurf .nid mapping/orientation |
synthetic byte/orientation tests and selected context comparisons | LEVEL 1 | private corpus not distributed; no universal format coverage |
| Hertz/cone/DMT and force maps | analytical construction and synthetic recovery | LEVEL 2 within synthetic scope | no certified tip/cantilever calibration or broad experimental campaign |
| Experimental JKR, WLC/FJC, SLS | analytical construction and synthetic recovery | LEVEL 2 within synthetic scope | no physical-reference campaign; JKR and SLS remain explicitly experimental |
| KPFM, PSD/fractal, grains, resonance | unit and controlled software tests | LEVEL 1 | no frozen public physical-reference campaign |
| Fathom workspace | offscreen GUI and architecture tests | LEVEL 1 | platform and Qt behavior vary; GUI evidence does not upgrade numerical maturity |
13.2 Gwyddion as reference¶
Gwyddion is an external software route only where a campaign declares its version, matrix handoff, wrapper, preprocessing, and tolerance. It is not universal ground truth. The retained summaries live in https://github.com/kegouro/spmkit-validation/tree/main/evidence/campaigns. Passing those campaigns does not constitute physical validation or feature parity.
13.3 Simulator¶
The cantilever simulator is educational only. It models a damped harmonic oscillator with additive white noise. It does not account for higher flexural modes, fluid‑structure interaction, optical‑lever sensitivity, or real cantilever geometry. Use it to understand qualitative behaviour, not for calibration or metrology.
14. Safety and interpretation warnings¶
- Results require domain judgment. A high R² does not guarantee that the chosen contact model is physically correct for your sample.
- Calibration values matter. Young's modulus extracted from force curves depends on tip radius (often uncertain), spring constant (calibration uncertainty), and contact model (an approximation). Report all three.
- Units and conventions must be checked.
SPMChannel.unittells you the physical unit. Do not assume all channels are in metres. - Experimental readers may misinterpret metadata. Format‑specific metadata parsing is a best‑effort process, especially for formats reverse‑engineered with limited documentation.
- Fitted parameters are not automatically physical truth. A Hertz fit always produces a number. Whether that number represents the true Young's modulus depends on whether the sample is elastic, isotropic, homogeneous, and whether the contact is purely elastic within the fit range.
- SPM‑Kit is not a medical, clinical, regulatory, or safety‑critical instrument. Do not use it for diagnostic, treatment, or compliance decisions.
- Preserve original data. SPM‑Kit reads files without modifying them. Export results alongside the original instrument files.
15. Extensibility¶
15.1 Adding a file format¶
Register a Reader Protocol in spmkit.plugins.v1 entry‑point group or in
core/plugins/registry.py. The reader must implement inspect(path) → DatasetInfo
and load(path, kind) → SPMData | ForceVolume.
15.2 Adding a Fathom perspective¶
Define a ModuleSpec with PanelSpec and PerspectiveSpec entries, then register
it via the spmkit.gui.modules entry‑point group.
from spmkit.gui.extensions import ModuleSpec, PanelSpec, PerspectiveSpec, ModuleContext
MY_MODULE = ModuleSpec(
name="my_domain",
panels=(PanelSpec("my_canvas", "My Canvas", _factory, area="central"),),
perspectives=(PerspectiveSpec("my_view", "My View", ("navigator", "my_canvas")),),
)
15.3 Adding an analysis¶
Implement the Analysis Protocol and register via spmkit.plugins.v1.
15.4 Entry‑point groups¶
| Group | Purpose |
|---|---|
spmkit.plugins.v1 |
Readers, analyses, domains |
spmkit.gui.modules |
Fathom modules (perspectives + panels) |
See extending.md for full details.
16. Troubleshooting¶
Missing GUI extra¶
Fix:pip install "spmkit[gui]"
Qt platform plugin error¶
Fix: Install Qt platform dependencies (libxcb-cursor0 on Debian/Ubuntu) or
set QT_QPA_PLATFORM=offscreen for headless environments.
Unsupported file format¶
Fix: Check that the file extension matches a supported format (.nid, .nhf,
.gwy, .jpk-force). For experimental readers, install afm or jpk extras.
Missing optional dependency¶
Fix: Reinstall SPMKit so its required dependencies are restored (for a development checkout:python -m pip install -e .).
Empty or unexpected channels¶
Fix: Verify withspmkit info file.nid that the channel exists. Not all scans
include all channel types.
Large force‑volume memory use¶
Fix: Use lazy loading (ForceVolume does not hold all curves in RAM). For vectorised
processing, use the --fast path with CPU backend. Reduce grid resolution if possible.
GPU / CuPy fallback¶
Fix: CuPy is not bundled. Install it separately if GPU acceleration is desired:pip install cupy-cuda12x (match your CUDA version).
Export failure¶
Fix: Check write permissions. Use--output to specify a writable directory.
GUI crash logs¶
Fathom logs errors to the Log panel (visible in Batch perspective). For terminal
output, launch from a terminal: spmkit gui 2>&1 | tee fathom.log.
macOS launch behaviour¶
macOS may require the application bundle or python to have accessibility
permissions if using screen recording or automation features. Qt 6 on macOS
typically works without special configuration.
17. Development and quality¶
17.1 Development setup¶
git clone https://github.com/kegouro/spmkit
cd spmkit
pip install -e ".[all,dev,test-gui]"
pre-commit install
17.2 Quality checks¶
make check # lint + types + tests (the CI gate)
make lint # ruff check
make format # black + ruff --fix
make type # mypy (strict on core)
make test # pytest with coverage
17.3 GUI tests¶
17.4 Documentation¶
17.5 CI¶
GitHub Actions workflow .github/workflows/ci.yml runs make check on push.
GUI tests are skipped in CI (no display), but unit and architecture tests always run.
18. SPM-Kit ecosystem relationship¶
The ecosystem has five identities with distinct responsibilities:
- SPM‑Kit Core reads demonstrated data variants and performs numerical analysis.
- Fathom invokes Core through an interactive scientific workspace.
- SPM‑Kit Data Hunter records public candidate datasets and provenance. Discovery is not validation, and not every located candidate is usable, redistributable, or suitable.
- SPM‑Kit Phantoms generates deterministic truth-bearing synthetic fixtures and declared corruptions without importing the analyzer under test.
- SPM‑Kit Validation runs frozen black-box campaigns against installed public SPM‑Kit interfaces and preserves evidence.
Artifacts move between repositories through declared files, manifests, hashes, and commands; there is no automatic pipeline from every Data Hunter record into Validation. See the ecosystem portal and artifact contracts.
19. Citation, license, and contributions¶
19.1 How to cite¶
@software{spmkit2026,
author = {José Labarca Baeza},
title = {spmkit: Open-source AFM/KPFM analyser for scanning probe microscopy},
year = {2026},
version = {0.1.4},
doi = {10.5281/zenodo.21303280},
url = {https://github.com/kegouro/spmkit},
}
19.2 License¶
MIT. See LICENSE in the repository root.
19.3 Contributing¶
See CONTRIBUTING.md. Issues and pull requests are welcome at
https://github.com/kegouro/spmkit/issues.
19.4 Funding¶
This open‑source project has been developed without dedicated institutional funding.
19.5 Project status¶
Alpha (source 0.1.5.dev0; GitHub release 0.1.4; PyPI 0.1.2). APIs may change
before 1.0. Evidence and compatibility remain capability- and format-specific.
20. Acknowledgements¶
José Labarca Baeza is the creator, author, and lead developer of SPM-Kit.
English¶
Tomás Corrales and the SPM Lab at Universidad Técnica Federico Santa María provided selected experimental datasets and laboratory context during the development and evaluation of SPM-Kit.
María Saavedra Fredes and Benjamin Schleyer helped locate and share candidate datasets for the validation campaigns.
Español¶
Tomás Corrales y el SPM Lab de la Universidad Técnica Federico Santa María proporcionaron datasets experimentales seleccionados y contexto de laboratorio durante el desarrollo y la evaluación de SPM-Kit.
María Saavedra Fredes y Benjamin Schleyer ayudaron a localizar y compartir datasets candidatos para las campañas de validación.
These acknowledgements do not imply that every located dataset was used, accepted, redistributable, or scientifically suitable. They do not constitute software authorship, institutional ownership, or endorsement.
Appendices¶
A. Quick reference¶
# Install the current source documented here
python -m pip install "spmkit[gui] @ git+https://github.com/kegouro/spmkit@main"
# Inspect
spmkit info scan.nid
# Analyse
spmkit roughness scan.nid -c Z-Axis --level plane
spmkit psd scan.nid -c Z-Axis
spmkit analyze scan.nid -o ./results --tip-wf 4.8
# Figures
spmkit figure scan.nid -o topo.png --colormap batlow
# Convert
spmkit convert scan.nid scan.gwy
# Verify
spmkit verify scan.nid
# Force
spmkit forcecurve curve.jpk-force --model dmt --tip-radius 2e-8
spmkit forcemap volume.nid --fast -f maps.png
spmkit forcereport volume.nid -o report
spmkit forceexport volume.nid -o ./export
spmkit fbatch ./curves/ -o batch.csv
# Evaporation
spmkit evaporation ./tuning/ -k 0.3 -o evap.csv
# Grains
spmkit grains scan.nid --min-size 10
# GUI
spmkit gui [file]
spmkit gui --legacy
B. Extras matrix¶
| Extra | Contents |
|---|---|
| (none) | Core CLI/Python API and dependency-free built-in paths; some formats need extras |
gui |
Fathom desktop workspace |
viz |
Publication figures, Crameri colormaps |
gwy |
Gwyddion .gwy read/write |
hdf5 |
HDF5 import/export |
grains |
Grain detection |
report |
HTML/PDF reports |
nanosurf |
Optional NSFopen dependency |
afm |
Long‑tail format readers (afmformats) |
jpk |
JPK TIFF force curves |
parallel |
Multi‑core force‑volume processing |
pandas |
DataFrame export |
all |
Reader, GUI, visualization, report, grain, HDF5, and GWY extras declared by the package |
dev |
Developer tools |
test-gui |
GUI test runner |
docs |
Documentation builder |
C. CLI command index¶
| Command | Category | Input |
|---|---|---|
info |
Inspection | .nid, .nhf |
roughness |
Image analysis | .nid, .nhf, .gwy |
profile |
Profile extraction | .nid, .nhf, .gwy |
psd |
Spectral | .nid, .nhf, .gwy |
analyze |
Pipeline | .nid, .nhf, .gwy |
nanomech |
Force | .nid (spectroscopy) |
grains |
Image | .nid, .nhf, .gwy |
batch |
Batch | Folder of SPM files |
evaporation |
Resonance | Folder of .nid tuning files |
figure |
Figure | .nid, .nhf, .gwy |
convert |
Format | .nid |
verify |
Audit | .nid |
gui |
GUI | — (optional file) |
workspace |
GUI | Force‑curve file |
forcecurve |
Force | .jpk-force, .nid |
forcemap |
Force | .nid (force‑volume) |
forcereport |
Force | .nid (force‑volume) |
forceexport |
Force | .nid (force‑volume) |
fbatch |
Batch force | Folder of force curves |
jkr |
Force (experimental) | Calibrated force curve |
D. Perspective index¶
| Key | Label | Module | Type |
|---|---|---|---|
image |
Imagen | image | Image |
grains |
Granos | image | Image |
spectral |
Espectral | image | Image |
resonance |
Sintonía térmica | image | Image |
evaporation |
Evaporación | image | Image |
force |
Curva de fuerza | force | Force |
smfs |
SMFS | force | Force |
map |
Mapa | force | Force |
batch |
Batch | force | Force |
figure |
Figura | figure | Figure |
view3d |
Vista 3D | view3d | Image |
simulator |
Simulador | simulator | Educational |
E. Validation status vocabulary¶
| Term | Definition |
|---|---|
| Level 0 | Claim documented without retained executable evidence |
| Level 1 | Automated software verification within declared scope |
| Level 2 | Known-value numerical recovery within declared scope and tolerance |
| Level 3 | Frozen external cross-validation under declared conditions |
| Level 4 | Scoped physical-reference validation |
| Level 5 | Independent reproduction of the declared result |
F. Keyboard shortcuts¶
| Shortcut | Action |
|---|---|
Ctrl+K |
Command palette |
Ctrl+O |
Open file |
Ctrl+S |
Save project |
Ctrl+M |
Calculate map |
Ctrl+Shift+R |
Generate report |
Ctrl+Shift+L |
Toggle theme |
Ctrl+Shift+A |
Appearance settings |
Ctrl+E |
Export results (JSON) |
Ctrl+Shift+C |
Copy results |
Ctrl+P |
Pin curve |
Ctrl+← / Ctrl+→ |
Previous / next curve |
Ctrl+Home / Ctrl+End |
First / last curve |
Ctrl+1…Ctrl+5 |
Tab switching (legacy app) |
G. Common output files¶
| File | Source | Contents |
|---|---|---|
batch_summary.csv |
spmkit batch |
Roughness summary per file |
*_roughness.csv/json |
spmkit analyze |
Roughness parameters |
*_kpfm.csv/json |
spmkit analyze |
KPFM/CPD statistics |
figure.png/svg/pdf |
spmkit figure |
Publication figure |
scan.gwy |
spmkit convert |
Gwyddion‑compatible file |
scan.h5 |
spmkit convert |
HDF5 archive |
force_batch.csv |
spmkit fbatch |
Force curve summary |
maps.png |
spmkit forcemap -f |
Property map visualisation |
informe.html/pdf |
spmkit forcereport |
Full force‑volume report |
export/ |
spmkit forceexport |
Complete export bundle |
.spmproj |
Fathom Ctrl+S |
Project file (YAML) |
End of SPM‑Kit · Fathom Usage Guide — source 0.1.5.dev0 · GitHub 0.1.4 · PyPI 0.1.2