Skip to content

API Python

spmkit expone una API pública limpia en spmkit.core. La CLI y la GUI solo orquestan — toda la lógica vive aquí.

Instalación

pip install spmkit

Carga de datos — spmkit.load

Punto de entrada principal. Detecta el formato automáticamente.

from spmkit import load

data = load("scan.nid")    # NanoSurf clásico
data = load("scan.nhf")    # NanoSurf HDF5
data = load("scan.gwy")    # Gwyddion

SPMData

El objeto devuelto por load().

# Ver canales disponibles
print(data.names)          # ['Z-Axis', 'CPD', 'Phase', ...]

# Acceder a un canal (devuelve SPMChannel)
ch = data["Z-Axis"]

# Acceder con dirección explícita
ch = data["Z-Axis", "forward"]
ch = data["Z-Axis", "backward"]

# Metadatos del barrido
print(data.metadata)       # dict con parámetros del instrumento

SPMChannel

Representa un canal 2D en unidades físicas.

ch = data["Z-Axis"]

ch.data        # numpy.ndarray 2D (shape: rows × cols)
ch.unit        # str, p.ej. "m", "V", "°"
ch.x_range     # float, rango horizontal en metros
ch.y_range     # float, rango vertical en metros
ch.shape       # tuple (rows, cols)
ch.name        # str, nombre del canal
ch.direction   # "forward" | "backward"

Nivelación — spmkit.core.analysis.leveling

from spmkit.core.analysis import leveling

# Corrección de plano (elimina inclinación)
flat = leveling.plane_fit(ch)

# Corrección polinómica (orden configurable)
flat = leveling.polynomial(ch, order=2)

# Alineado de filas (corrige deriva línea a línea)
flat = leveling.align_rows(ch)

Todas las funciones devuelven un nuevo SPMChannel (inmutable).


Rugosidad — spmkit.core.analysis.roughness

Parámetros ISO 25178.

from spmkit.core.analysis import roughness

result = roughness.statistics(flat)

result.sa      # rugosidad media aritmética
result.sq      # rugosidad RMS
result.sz      # altura máxima (Sp + Sv)
result.sp      # altura máxima de picos
result.sv      # profundidad máxima de valles
result.ssk     # asimetría (skewness)
result.sku     # curtosis (kurtosis)
result.unit    # unidad del canal ("m", "nm", …)

# Convertir a dict
d = result.to_dict()

KPFM — spmkit.core.analysis.kpfm

Potencial de contacto y función de trabajo.

from spmkit.core.analysis import kpfm

# Estadísticas básicas del canal CPD
result = kpfm.statistics(data["CPD"])

result.mean_cpd       # CPD medio (V)
result.std_cpd        # desviación estándar (V)
result.min_cpd        # mínimo (V)
result.max_cpd        # máximo (V)

# Con función de trabajo de la punta (eV)
result = kpfm.statistics(data["CPD"], tip_work_function=4.8)
result.work_function  # función de trabajo de la muestra (eV)

Nanomecánica — spmkit.core.analysis.mechanics

Curvas fuerza-distancia, modelos de contacto.

from spmkit.core.analysis import mechanics

# Extraer curvas del canal de espectroscopía
curves = mechanics.extract_curves(data["Deflection"])

# Ajustar modelo de Hertz a una curva
result = mechanics.fit_hertz(
    curves[50],
    tip_radius=10e-9,          # radio de punta (m)
    model="sphere",            # "sphere" | "paraboloid" | "cone"
    spring_constant=0.3,       # N/m (opcional)
)

result.young_modulus   # módulo de Young (Pa)
result.contact_point   # punto de contacto (m)
result.adhesion        # fuerza de adhesión (N)
result.rmse            # error del ajuste

# Mapa de módulo (force-volume)
modulus_map = mechanics.modulus_map(curves, tip_radius=10e-9)
# modulus_map.data → ndarray 2D con E en Pa

Resonancia — spmkit.core.analysis.resonance

Thermal tuning y sensado de masa.

from spmkit.core.analysis import resonance
from pathlib import Path

# Cargar serie temporal de espectros
files = sorted(Path("./tuning/").glob("*.nid"))
ev = resonance.load_evaporation_series(files, spring_constant=0.3)

ev.time              # ndarray, tiempo (s)
ev.frequency         # ndarray, frecuencia de resonancia (Hz)
ev.mass              # ndarray, masa efectiva (kg)
ev.added_mass        # ndarray, Δm respecto a la primera medida (kg)
ev.evaporation_rate  # ndarray, dm/dt (kg/s)
ev.spring_constant   # float (N/m)
ev.bare_frequency    # float, f₀ sin masa (Hz)

# Ajuste de ley d² (evaporación limitada por difusión)
radii = resonance.droplet_radius(ev.added_mass)
d2 = resonance.fit_d2_law(ev.time, radii)

d2.r0                    # radio inicial (m)
d2.tau                   # tiempo de vida total (s)
d2.rate_constant         # K (m²/s)
d2.r_squared             # R² del ajuste
d2.is_diffusion_limited  # bool

Análisis espectral — spmkit.core.analysis.spectral

PSD radial, dimensión fractal, longitud de correlación.

from spmkit.core.analysis import spectral

# Dimensión fractal y exponente de Hurst
frac = spectral.fractal_dimension(flat)
frac.fractal_dimension   # D (2 < D < 3 para superficies rugosas)
frac.hurst               # H = 3 - D
frac.psd_slope           # pendiente β del ajuste log-log
frac.r_squared           # bondad del ajuste

# Longitud de correlación
corr_length = spectral.correlation_length(flat)  # metros

Granos — spmkit.core.analysis.grains

Detección de partículas y estadística de tamaños.

from spmkit.core.analysis import grains

result = grains.detect(
    flat,
    threshold=None,       # None = automático
    min_size=4,           # píxeles mínimos por grano
    relative_height=0.5,  # fracción para umbral auto
)

result.n_grains         # número de granos detectados
result.mean_diameter    # diámetro medio (m)
result.density          # densidad (granos/m²)
result.coverage         # fracción de cobertura (0..1)
result.labels           # ndarray 2D con etiquetas de granos

Visualización — spmkit.core.viz

Figuras de publicación con colormaps científicos.

from spmkit.core.viz import FigureSpec, save_figure

spec = FigureSpec(
    title="Topografía AFM",
    colormap="batlow",                    # colormaps Crameri
    colorbar_label="Z-Axis (nm)",
)

# Exportar a PNG / SVG / PDF
save_figure(flat, spec, "topografia.png")
save_figure(flat, spec, "topografia.svg")
save_figure(flat, spec, "topografia.pdf")

Colormaps disponibles (Crameri perceptualmente uniformes):

batlow, tokyo, oslo, vik, davos, hawaii, lapaz, roma, turku, acton


Exportación — spmkit.core.export

from spmkit.core.export import to_csv, to_json, to_hdf5

# Exportar resultados de rugosidad
to_csv(roughness_result, "roughness.csv")
to_json(roughness_result, "roughness.json")

# Exportar datos completos a HDF5
to_hdf5(data, "scan.h5")

Conversión de formatos — spmkit.core.io

from spmkit.core.io import save_gwy

# Guardar como Gwyddion (.gwy)
save_gwy(data, "scan.gwy")

Procesamiento por lotes — spmkit.core.batch

from spmkit.core import batch
from pathlib import Path

# Encontrar archivos SPM en una carpeta
files = batch.find_files(Path("./medidas/"))

# Procesar todos
result = batch.process(files, channel="Z-Axis")

result.n_ok        # archivos procesados con éxito
result.n_failed    # archivos con error
result.to_csv(Path("summary.csv"))