spmkit 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- spmkit-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
- spmkit-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
- spmkit-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +26 -0
- spmkit-0.1.0/.github/workflows/ci.yml +42 -0
- spmkit-0.1.0/.github/workflows/publish.yml +41 -0
- spmkit-0.1.0/.gitignore +29 -0
- spmkit-0.1.0/.pre-commit-config.yaml +28 -0
- spmkit-0.1.0/CHANGELOG.md +31 -0
- spmkit-0.1.0/CITATION.cff +28 -0
- spmkit-0.1.0/CONTRIBUTING.md +55 -0
- spmkit-0.1.0/LICENSE +21 -0
- spmkit-0.1.0/Makefile +34 -0
- spmkit-0.1.0/PKG-INFO +206 -0
- spmkit-0.1.0/README.md +140 -0
- spmkit-0.1.0/docs/ARCHITECTURE.md +76 -0
- spmkit-0.1.0/docs/ROADMAP.md +64 -0
- spmkit-0.1.0/docs/UI_DESIGN.md +70 -0
- spmkit-0.1.0/docs/VALIDATION.md +63 -0
- spmkit-0.1.0/docs/images/figure_demo.png +0 -0
- spmkit-0.1.0/docs/images/screenshot_viewer.png +0 -0
- spmkit-0.1.0/pyproject.toml +97 -0
- spmkit-0.1.0/src/spmkit/__init__.py +16 -0
- spmkit-0.1.0/src/spmkit/cli/__init__.py +5 -0
- spmkit-0.1.0/src/spmkit/cli/app.py +233 -0
- spmkit-0.1.0/src/spmkit/core/__init__.py +15 -0
- spmkit-0.1.0/src/spmkit/core/analysis/__init__.py +21 -0
- spmkit-0.1.0/src/spmkit/core/analysis/kpfm.py +65 -0
- spmkit-0.1.0/src/spmkit/core/analysis/leveling.py +61 -0
- spmkit-0.1.0/src/spmkit/core/analysis/mechanics.py +272 -0
- spmkit-0.1.0/src/spmkit/core/analysis/profiles.py +76 -0
- spmkit-0.1.0/src/spmkit/core/analysis/roughness.py +76 -0
- spmkit-0.1.0/src/spmkit/core/batch.py +110 -0
- spmkit-0.1.0/src/spmkit/core/export/__init__.py +5 -0
- spmkit-0.1.0/src/spmkit/core/export/writers.py +90 -0
- spmkit-0.1.0/src/spmkit/core/io/__init__.py +8 -0
- spmkit-0.1.0/src/spmkit/core/io/gwy.py +97 -0
- spmkit-0.1.0/src/spmkit/core/io/nhf.py +74 -0
- spmkit-0.1.0/src/spmkit/core/io/nid.py +163 -0
- spmkit-0.1.0/src/spmkit/core/io/registry.py +44 -0
- spmkit-0.1.0/src/spmkit/core/models/__init__.py +5 -0
- spmkit-0.1.0/src/spmkit/core/models/spmdata.py +106 -0
- spmkit-0.1.0/src/spmkit/core/report.py +134 -0
- spmkit-0.1.0/src/spmkit/core/viz/__init__.py +21 -0
- spmkit-0.1.0/src/spmkit/core/viz/colormaps.py +97 -0
- spmkit-0.1.0/src/spmkit/core/viz/figure.py +222 -0
- spmkit-0.1.0/src/spmkit/gui/__init__.py +5 -0
- spmkit-0.1.0/src/spmkit/gui/app.py +25 -0
- spmkit-0.1.0/src/spmkit/gui/compare_tab.py +165 -0
- spmkit-0.1.0/src/spmkit/gui/figure_tab.py +239 -0
- spmkit-0.1.0/src/spmkit/gui/main_window.py +215 -0
- spmkit-0.1.0/src/spmkit/gui/nanomech_tab.py +157 -0
- spmkit-0.1.0/src/spmkit/gui/theme.py +187 -0
- spmkit-0.1.0/src/spmkit/gui/viewer_tab.py +187 -0
- spmkit-0.1.0/src/spmkit/gui/welcome.py +62 -0
- spmkit-0.1.0/tests/__init__.py +0 -0
- spmkit-0.1.0/tests/conftest.py +75 -0
- spmkit-0.1.0/tests/core/__init__.py +0 -0
- spmkit-0.1.0/tests/core/test_export.py +43 -0
- spmkit-0.1.0/tests/core/test_gwy.py +58 -0
- spmkit-0.1.0/tests/core/test_io_nid.py +66 -0
- spmkit-0.1.0/tests/core/test_kpfm.py +25 -0
- spmkit-0.1.0/tests/core/test_leveling.py +39 -0
- spmkit-0.1.0/tests/core/test_maps_grid_report.py +85 -0
- spmkit-0.1.0/tests/core/test_mechanics.py +69 -0
- spmkit-0.1.0/tests/core/test_profiles.py +31 -0
- spmkit-0.1.0/tests/core/test_roughness.py +38 -0
- spmkit-0.1.0/tests/core/test_viz_report_batch.py +77 -0
- spmkit-0.1.0/tests/gui/__init__.py +0 -0
- spmkit-0.1.0/tests/gui/test_smoke.py +83 -0
- spmkit-0.1.0/tests/validation/__init__.py +0 -0
- spmkit-0.1.0/tests/validation/test_nanomech_real.py +49 -0
- spmkit-0.1.0/tests/validation/test_nid_vs_gwyddion.py +77 -0
- spmkit-0.1.0/tests/validation/test_robustness.py +37 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Reporte de bug
|
|
3
|
+
about: Informar un problema para ayudarnos a mejorar spmkit
|
|
4
|
+
title: "[BUG] "
|
|
5
|
+
labels: bug
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**Descripción**
|
|
9
|
+
Qué pasó y qué esperabas que pasara.
|
|
10
|
+
|
|
11
|
+
**Pasos para reproducir**
|
|
12
|
+
1. ...
|
|
13
|
+
2. ...
|
|
14
|
+
|
|
15
|
+
**Archivo de ejemplo**
|
|
16
|
+
Si es posible, adjunta un archivo sintético mínimo que reproduzca el bug
|
|
17
|
+
(no subas datos del instrumento sin permiso).
|
|
18
|
+
|
|
19
|
+
**Entorno**
|
|
20
|
+
- spmkit: (ej. `spmkit --version`)
|
|
21
|
+
- SO: (ej. macOS 14, Ubuntu 22.04)
|
|
22
|
+
- Python: (ej. 3.12)
|
|
23
|
+
- Instalación: `pip` / `uv`, con extras `[...]`
|
|
24
|
+
|
|
25
|
+
**Traza / salida**
|
|
26
|
+
```
|
|
27
|
+
pega aquí el error
|
|
28
|
+
```
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Solicitud de feature
|
|
3
|
+
about: Proponer una idea o mejora para spmkit
|
|
4
|
+
title: "[FEATURE] "
|
|
5
|
+
labels: enhancement
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
**¿Qué problema resuelve?**
|
|
9
|
+
Describe el caso de uso científico o de flujo de trabajo.
|
|
10
|
+
|
|
11
|
+
**Propuesta**
|
|
12
|
+
Qué te gustaría que hiciera spmkit.
|
|
13
|
+
|
|
14
|
+
**Alternativas**
|
|
15
|
+
Otras formas en que lo resuelves hoy (ej. Gwyddion, scripts).
|
|
16
|
+
|
|
17
|
+
**Contexto**
|
|
18
|
+
Instrumento, formato de archivo, técnica (AFM/KPFM/nanomecánica), etc.
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
## Descripción
|
|
2
|
+
|
|
3
|
+
Qué cambia y por qué.
|
|
4
|
+
|
|
5
|
+
## Tipo de cambio
|
|
6
|
+
|
|
7
|
+
- [ ] Bugfix
|
|
8
|
+
- [ ] Nueva feature
|
|
9
|
+
- [ ] Soporte de formato/instrumento
|
|
10
|
+
- [ ] Documentación
|
|
11
|
+
- [ ] Refactor / mantenimiento
|
|
12
|
+
|
|
13
|
+
## Checklist
|
|
14
|
+
|
|
15
|
+
- [ ] `ruff check src tests` pasa
|
|
16
|
+
- [ ] `black --check src tests` pasa
|
|
17
|
+
- [ ] `mypy src` pasa
|
|
18
|
+
- [ ] `pytest` pasa
|
|
19
|
+
- [ ] Agregué/actualicé tests (y `tests/validation/` si toqué manejo de datos)
|
|
20
|
+
- [ ] La lógica de análisis vive en `core/` (CLI/GUI solo orquestan)
|
|
21
|
+
- [ ] No subo datos del instrumento
|
|
22
|
+
|
|
23
|
+
## Notas de validación científica
|
|
24
|
+
|
|
25
|
+
Si cambiaste parsers/conversión/orientación, ¿cómo verificaste que sigue
|
|
26
|
+
siendo correcto?
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- uses: actions/checkout@v4
|
|
14
|
+
- name: Install uv
|
|
15
|
+
uses: astral-sh/setup-uv@v5
|
|
16
|
+
- name: Create venv
|
|
17
|
+
run: uv venv --python 3.12
|
|
18
|
+
- name: Install dev deps
|
|
19
|
+
run: uv pip install -e ".[dev]"
|
|
20
|
+
- name: Ruff (lint)
|
|
21
|
+
run: uv run ruff check src tests
|
|
22
|
+
- name: Black (format check)
|
|
23
|
+
run: uv run black --check src tests
|
|
24
|
+
- name: Mypy (types)
|
|
25
|
+
run: uv run mypy src
|
|
26
|
+
|
|
27
|
+
test:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
strategy:
|
|
30
|
+
fail-fast: false
|
|
31
|
+
matrix:
|
|
32
|
+
python-version: ["3.11", "3.12"]
|
|
33
|
+
steps:
|
|
34
|
+
- uses: actions/checkout@v4
|
|
35
|
+
- name: Install uv
|
|
36
|
+
uses: astral-sh/setup-uv@v5
|
|
37
|
+
- name: Create venv (Python ${{ matrix.python-version }})
|
|
38
|
+
run: uv venv --python ${{ matrix.python-version }}
|
|
39
|
+
- name: Install package + test deps
|
|
40
|
+
run: uv pip install -e ".[dev,hdf5,gwy,report]"
|
|
41
|
+
- name: Run tests (core + ciencia; los de GUI se omiten sin Qt)
|
|
42
|
+
run: uv run pytest
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
name: Publish to PyPI
|
|
2
|
+
|
|
3
|
+
# Publica en PyPI al crear un Release de GitHub, usando Trusted Publishing
|
|
4
|
+
# (OIDC, sin tokens). Requiere configurar el publisher en pypi.org una vez:
|
|
5
|
+
# PyPI → tu cuenta → Publishing → Add pending publisher
|
|
6
|
+
# Project: spmkit · Owner: kegouro · Repo: spmkit
|
|
7
|
+
# Workflow: publish.yml · Environment: pypi
|
|
8
|
+
|
|
9
|
+
on:
|
|
10
|
+
release:
|
|
11
|
+
types: [published]
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
build:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v5
|
|
20
|
+
- name: Build sdist + wheel
|
|
21
|
+
run: uv build
|
|
22
|
+
- name: Upload artifacts
|
|
23
|
+
uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: dist
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment: pypi
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write # necesario para Trusted Publishing (OIDC)
|
|
34
|
+
steps:
|
|
35
|
+
- name: Download artifacts
|
|
36
|
+
uses: actions/download-artifact@v4
|
|
37
|
+
with:
|
|
38
|
+
name: dist
|
|
39
|
+
path: dist/
|
|
40
|
+
- name: Publish to PyPI
|
|
41
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
spmkit-0.1.0/.gitignore
ADDED
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.eggs/
|
|
6
|
+
build/
|
|
7
|
+
dist/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
|
|
11
|
+
# Tooling caches
|
|
12
|
+
.pytest_cache/
|
|
13
|
+
.mypy_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
htmlcov/
|
|
17
|
+
|
|
18
|
+
# OS
|
|
19
|
+
.DS_Store
|
|
20
|
+
|
|
21
|
+
# Reference material (datos de instrumento, no versionar grandes binarios)
|
|
22
|
+
reference/
|
|
23
|
+
|
|
24
|
+
# IDE
|
|
25
|
+
.idea/
|
|
26
|
+
.vscode/
|
|
27
|
+
|
|
28
|
+
# Capturas de UI (preview local)
|
|
29
|
+
ui_preview/
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
3
|
+
rev: v0.6.9
|
|
4
|
+
hooks:
|
|
5
|
+
- id: ruff
|
|
6
|
+
args: [--fix]
|
|
7
|
+
- id: ruff-format
|
|
8
|
+
|
|
9
|
+
- repo: https://github.com/psf/black
|
|
10
|
+
rev: 24.10.0
|
|
11
|
+
hooks:
|
|
12
|
+
- id: black
|
|
13
|
+
|
|
14
|
+
- repo: https://github.com/pre-commit/mirrors-mypy
|
|
15
|
+
rev: v1.11.2
|
|
16
|
+
hooks:
|
|
17
|
+
- id: mypy
|
|
18
|
+
additional_dependencies: ["numpy>=1.24"]
|
|
19
|
+
args: [--ignore-missing-imports]
|
|
20
|
+
|
|
21
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
22
|
+
rev: v5.0.0
|
|
23
|
+
hooks:
|
|
24
|
+
- id: trailing-whitespace
|
|
25
|
+
- id: end-of-file-fixer
|
|
26
|
+
- id: check-yaml
|
|
27
|
+
- id: check-added-large-files
|
|
28
|
+
args: [--maxkb=2000]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
Todos los cambios notables de este proyecto se documentan aquí.
|
|
4
|
+
El formato sigue [Keep a Changelog](https://keepachangelog.com/es/1.1.0/) y
|
|
5
|
+
el versionado es [SemVer](https://semver.org/lang/es/).
|
|
6
|
+
|
|
7
|
+
## [Unreleased]
|
|
8
|
+
|
|
9
|
+
## [0.1.0] - 2026-06-15
|
|
10
|
+
|
|
11
|
+
### Añadido
|
|
12
|
+
- Lectura de NanoSurf `.nid` (validada contra Gwyddion) y `.nhf`; interop
|
|
13
|
+
Gwyddion `.gwy` (lectura/escritura vía `gwyfile`).
|
|
14
|
+
- Análisis: rugosidad ISO 25178, nivelación, perfiles de línea, KPFM (CPD /
|
|
15
|
+
función de trabajo) y nanomecánica (Hertz/Sneddon, mapas de módulo/adhesión).
|
|
16
|
+
- Visualización: figuras de publicación con colormaps científicos (incluido el
|
|
17
|
+
dorado estilo NanoSurf), barra de escala, editor WYSIWYG con textos
|
|
18
|
+
arrastrables y rango de color `vmin/vmax`.
|
|
19
|
+
- Comparación multi-archivo (2–4) con colorbar y escala compartidas.
|
|
20
|
+
- Reportes HTML, procesamiento por lotes, exportación CSV/JSON/HDF5/PNG/SVG/PDF.
|
|
21
|
+
- GUI por pestañas (Visor · Nanomecánica · Editor · Comparar) con tema
|
|
22
|
+
claro/oscuro persistente, atajos de teclado, recientes, drag & drop y
|
|
23
|
+
diálogo de bienvenida.
|
|
24
|
+
- CLI `spmkit` (info, roughness, analyze, nanomech, batch, figure, convert, gui).
|
|
25
|
+
|
|
26
|
+
### Validado
|
|
27
|
+
- Lectura del `.nid` exacta a precisión de máquina contra el export `.gwy` del
|
|
28
|
+
lab; orientación de imagen consistente con Gwyddion/NanoSurf.
|
|
29
|
+
|
|
30
|
+
[Unreleased]: https://github.com/kegouro/spmkit/compare/v0.1.0...HEAD
|
|
31
|
+
[0.1.0]: https://github.com/kegouro/spmkit/releases/tag/v0.1.0
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
cff-version: 1.2.0
|
|
2
|
+
title: "spmkit: Analizador open-source de datos AFM/KPFM"
|
|
3
|
+
message: "Si usas este software en tu investigación, por favor cítalo."
|
|
4
|
+
type: software
|
|
5
|
+
authors:
|
|
6
|
+
- family-names: Labarca
|
|
7
|
+
given-names: José
|
|
8
|
+
affiliation: "Universidad Técnica Federico Santa María (UTFSM)"
|
|
9
|
+
- family-names: Corrales
|
|
10
|
+
given-names: Tomás
|
|
11
|
+
affiliation: "Universidad Técnica Federico Santa María (UTFSM)"
|
|
12
|
+
orcid: ""
|
|
13
|
+
abstract: >-
|
|
14
|
+
spmkit es una herramienta open-source para el análisis de datos de
|
|
15
|
+
microscopía de sonda de barrido (SPM), incluyendo AFM y KPFM. Lee
|
|
16
|
+
formatos NanoSurf (.nid, .nhf), calcula rugosidad, perfiles de línea,
|
|
17
|
+
estadísticas KPFM (CPD) y exporta a formatos abiertos (CSV, HDF5, JSON).
|
|
18
|
+
keywords:
|
|
19
|
+
- AFM
|
|
20
|
+
- KPFM
|
|
21
|
+
- SPM
|
|
22
|
+
- NanoSurf
|
|
23
|
+
- microscopy
|
|
24
|
+
- roughness
|
|
25
|
+
license: MIT
|
|
26
|
+
version: 0.1.0
|
|
27
|
+
date-released: "2026-06-14"
|
|
28
|
+
repository-code: "https://github.com/kegouro/spmkit"
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Contribuir a spmkit
|
|
2
|
+
|
|
3
|
+
¡Gracias por tu interés! spmkit es desarrollado por el SPM Lab de la UTFSM y
|
|
4
|
+
recibe contribuciones de la comunidad.
|
|
5
|
+
|
|
6
|
+
## Preparar el entorno
|
|
7
|
+
|
|
8
|
+
```bash
|
|
9
|
+
git clone https://github.com/kegouro/spmkit
|
|
10
|
+
cd spmkit
|
|
11
|
+
uv pip install -e ".[dev,gui,hdf5,gwy,report,test-gui]" # o pip
|
|
12
|
+
pre-commit install
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
> Los tests de la GUI requieren los extras `gui` + `test-gui` (PyQt6 + pytest-qt)
|
|
16
|
+
> y un entorno con Qt; en CI se omiten automáticamente (la ciencia sí se prueba).
|
|
17
|
+
|
|
18
|
+
## Principios de diseño
|
|
19
|
+
|
|
20
|
+
spmkit separa estrictamente tres capas (ver [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)):
|
|
21
|
+
|
|
22
|
+
- **`core/`** — puro Python, sin dependencias de UI. Toda la ciencia vive aquí.
|
|
23
|
+
- **`cli/`** y **`gui/`** — solo orquestan/presentan; nunca implementan análisis
|
|
24
|
+
ni tocan parsers directamente.
|
|
25
|
+
|
|
26
|
+
Si agregas análisis, va en `core/` con su test. La CLI/GUI solo lo invocan.
|
|
27
|
+
|
|
28
|
+
## Antes de abrir un PR
|
|
29
|
+
|
|
30
|
+
Todo lo que corre CI debe pasar localmente:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
ruff check src tests # lint
|
|
34
|
+
black --check src tests # formato
|
|
35
|
+
mypy src # tipos
|
|
36
|
+
pytest # tests (+ cobertura)
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
- **Tests con datos**: usa datos sintéticos (ver `tests/conftest.py`). No
|
|
40
|
+
subas archivos del instrumento (`reference/` está en `.gitignore`).
|
|
41
|
+
- **Confianza científica**: si tocas el manejo de datos (parsers, conversión
|
|
42
|
+
de unidades, orientación), agrega o actualiza una prueba en
|
|
43
|
+
`tests/validation/` y documenta el porqué. Ver [docs/VALIDATION.md](docs/VALIDATION.md).
|
|
44
|
+
- Mantén el estilo del código vecino (nombres, docstrings en español).
|
|
45
|
+
|
|
46
|
+
## Formatos e instrumentos nuevos
|
|
47
|
+
|
|
48
|
+
Para soportar un formato, agrega un parser en `core/io/` que devuelva un
|
|
49
|
+
`SPMData`, regístralo en `core/io/registry.py` y valídalo contra una
|
|
50
|
+
referencia conocida (otra herramienta o un archivo de especificación).
|
|
51
|
+
|
|
52
|
+
## Reportar bugs / pedir features
|
|
53
|
+
|
|
54
|
+
Usa las plantillas de issues. Incluye versión de spmkit, SO, y pasos para
|
|
55
|
+
reproducir (o un archivo sintético mínimo).
|
spmkit-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 SPM Lab UTFSM - Prof. Tomás Corrales, José Labarca
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
spmkit-0.1.0/Makefile
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
.PHONY: help install dev test lint format type check gui clean
|
|
2
|
+
|
|
3
|
+
help: ## Muestra esta ayuda
|
|
4
|
+
@grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | \
|
|
5
|
+
awk 'BEGIN {FS = ":.*?## "}; {printf " \033[36m%-12s\033[0m %s\n", $$1, $$2}'
|
|
6
|
+
|
|
7
|
+
install: ## Instala el paquete (núcleo + CLI)
|
|
8
|
+
uv pip install -e .
|
|
9
|
+
|
|
10
|
+
dev: ## Instala con extras de desarrollo y hooks
|
|
11
|
+
uv pip install -e ".[dev,gui,hdf5]"
|
|
12
|
+
pre-commit install
|
|
13
|
+
|
|
14
|
+
test: ## Corre los tests con cobertura
|
|
15
|
+
pytest
|
|
16
|
+
|
|
17
|
+
lint: ## Linting con ruff
|
|
18
|
+
ruff check src tests
|
|
19
|
+
|
|
20
|
+
format: ## Formatea con black + ruff
|
|
21
|
+
black src tests
|
|
22
|
+
ruff check src tests --fix
|
|
23
|
+
|
|
24
|
+
type: ## Chequeo de tipos con mypy
|
|
25
|
+
mypy src
|
|
26
|
+
|
|
27
|
+
check: lint type test ## Lint + tipos + tests (lo que corre CI)
|
|
28
|
+
|
|
29
|
+
gui: ## Lanza la interfaz gráfica
|
|
30
|
+
spmkit gui
|
|
31
|
+
|
|
32
|
+
clean: ## Limpia cachés y artefactos
|
|
33
|
+
rm -rf .pytest_cache .mypy_cache .ruff_cache htmlcov .coverage dist build
|
|
34
|
+
find . -type d -name __pycache__ -exec rm -rf {} +
|
spmkit-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: spmkit
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Analizador open-source de datos AFM/KPFM para microscopía de sonda de barrido (SPM)
|
|
5
|
+
Project-URL: Homepage, https://github.com/kegouro/spmkit
|
|
6
|
+
Project-URL: Repository, https://github.com/kegouro/spmkit
|
|
7
|
+
Project-URL: Issues, https://github.com/kegouro/spmkit/issues
|
|
8
|
+
Author: Tomás Corrales
|
|
9
|
+
Author-email: José Labarca <joselabarcabaeza11@hotmail.com>
|
|
10
|
+
Maintainer: SPM Lab UTFSM
|
|
11
|
+
License: MIT
|
|
12
|
+
License-File: LICENSE
|
|
13
|
+
Keywords: afm,kpfm,microscopy,nanosurf,nid,roughness,spm
|
|
14
|
+
Classifier: Development Status :: 3 - Alpha
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Image Processing
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
21
|
+
Requires-Python: >=3.11
|
|
22
|
+
Requires-Dist: numpy>=1.24
|
|
23
|
+
Requires-Dist: rich>=13.0
|
|
24
|
+
Requires-Dist: typer>=0.12
|
|
25
|
+
Provides-Extra: all
|
|
26
|
+
Requires-Dist: cmcrameri>=1.7; extra == 'all'
|
|
27
|
+
Requires-Dist: gwyfile>=0.3; extra == 'all'
|
|
28
|
+
Requires-Dist: h5py>=3.8; extra == 'all'
|
|
29
|
+
Requires-Dist: jinja2>=3.1; extra == 'all'
|
|
30
|
+
Requires-Dist: matplotlib-scalebar>=0.8; extra == 'all'
|
|
31
|
+
Requires-Dist: matplotlib>=3.8; extra == 'all'
|
|
32
|
+
Requires-Dist: nsfopen>=2.2; extra == 'all'
|
|
33
|
+
Requires-Dist: pyqt6>=6.6; extra == 'all'
|
|
34
|
+
Requires-Dist: pyqtgraph>=0.13; extra == 'all'
|
|
35
|
+
Provides-Extra: dev
|
|
36
|
+
Requires-Dist: black>=24.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
38
|
+
Requires-Dist: pre-commit>=3.7; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
41
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
42
|
+
Provides-Extra: gui
|
|
43
|
+
Requires-Dist: cmcrameri>=1.7; extra == 'gui'
|
|
44
|
+
Requires-Dist: matplotlib-scalebar>=0.8; extra == 'gui'
|
|
45
|
+
Requires-Dist: matplotlib>=3.8; extra == 'gui'
|
|
46
|
+
Requires-Dist: pyqt6>=6.6; extra == 'gui'
|
|
47
|
+
Requires-Dist: pyqtgraph>=0.13; extra == 'gui'
|
|
48
|
+
Provides-Extra: gwy
|
|
49
|
+
Requires-Dist: gwyfile>=0.3; extra == 'gwy'
|
|
50
|
+
Provides-Extra: hdf5
|
|
51
|
+
Requires-Dist: h5py>=3.8; extra == 'hdf5'
|
|
52
|
+
Provides-Extra: nanosurf
|
|
53
|
+
Requires-Dist: nsfopen>=2.2; extra == 'nanosurf'
|
|
54
|
+
Provides-Extra: report
|
|
55
|
+
Requires-Dist: cmcrameri>=1.7; extra == 'report'
|
|
56
|
+
Requires-Dist: jinja2>=3.1; extra == 'report'
|
|
57
|
+
Requires-Dist: matplotlib-scalebar>=0.8; extra == 'report'
|
|
58
|
+
Requires-Dist: matplotlib>=3.8; extra == 'report'
|
|
59
|
+
Provides-Extra: test-gui
|
|
60
|
+
Requires-Dist: pytest-qt>=4.4; extra == 'test-gui'
|
|
61
|
+
Provides-Extra: viz
|
|
62
|
+
Requires-Dist: cmcrameri>=1.7; extra == 'viz'
|
|
63
|
+
Requires-Dist: matplotlib-scalebar>=0.8; extra == 'viz'
|
|
64
|
+
Requires-Dist: matplotlib>=3.8; extra == 'viz'
|
|
65
|
+
Description-Content-Type: text/markdown
|
|
66
|
+
|
|
67
|
+
# spmkit
|
|
68
|
+
|
|
69
|
+
[](https://github.com/kegouro/spmkit/actions/workflows/ci.yml)
|
|
70
|
+
[](https://pypi.org/project/spmkit/)
|
|
71
|
+
[](https://pypi.org/project/spmkit/)
|
|
72
|
+
[](LICENSE)
|
|
73
|
+
[](https://github.com/astral-sh/ruff)
|
|
74
|
+
|
|
75
|
+
Analizador **open-source** de datos de microscopía de sonda de barrido (SPM),
|
|
76
|
+
con foco en **AFM** y **KPFM**. Desarrollado en el **SPM Lab de la UTFSM**.
|
|
77
|
+
|
|
78
|
+
Lee formatos NanoSurf (`.nid`, `.nhf`) y Gwyddion (`.gwy`), calcula rugosidad,
|
|
79
|
+
perfiles de línea, KPFM (CPD / función de trabajo) y nanomecánica, y exporta a
|
|
80
|
+
formatos abiertos (CSV, HDF5, JSON, figuras). Incluye CLI y una GUI científica
|
|
81
|
+
(PyQt6 + pyqtgraph).
|
|
82
|
+
|
|
83
|
+

|
|
84
|
+
|
|
85
|
+
> _Captura con datos sintéticos de ejemplo._
|
|
86
|
+
|
|
87
|
+
## Tabla de contenidos
|
|
88
|
+
|
|
89
|
+
- [Capacidades](#capacidades) · [Instalación](#instalación) · [Uso rápido](#uso-rápido)
|
|
90
|
+
- [Formatos](#formatos-soportados) · [Arquitectura](#arquitectura) ·
|
|
91
|
+
[Validación científica](docs/VALIDATION.md) · [Desarrollo](#desarrollo) ·
|
|
92
|
+
[Contribuir](CONTRIBUTING.md) · [Citación](#citación)
|
|
93
|
+
|
|
94
|
+
## Arquitectura
|
|
95
|
+
|
|
96
|
+
Separación estricta en tres capas. CLI y GUI **solo** usan la API pública del
|
|
97
|
+
`core`; nunca tocan parsers ni implementan análisis.
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
┌───────────────┐ ┌───────────────┐
|
|
101
|
+
│ cli/ │ │ gui/ │ ← capas de presentación
|
|
102
|
+
│ (typer+rich) │ │ (PyQt6+pg) │
|
|
103
|
+
└───────┬───────┘ └───────┬───────┘
|
|
104
|
+
│ importan funciones del core │
|
|
105
|
+
└───────────────┬─────────────────┘
|
|
106
|
+
▼
|
|
107
|
+
┌───────────────────────────────┐
|
|
108
|
+
│ core/ │ ← puro Python, sin UI
|
|
109
|
+
│ io · models · analysis · export │
|
|
110
|
+
└───────────────────────────────┘
|
|
111
|
+
▲
|
|
112
|
+
.nid / .nhf ───┘ (archivos del instrumento)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## Instalación
|
|
116
|
+
|
|
117
|
+
```bash
|
|
118
|
+
# Recomendado: con uv
|
|
119
|
+
uv pip install spmkit # núcleo + CLI
|
|
120
|
+
uv pip install "spmkit[gui]" # + interfaz gráfica (PyQt6, incluye viz)
|
|
121
|
+
uv pip install "spmkit[viz]" # + figuras de publicación (matplotlib, colormaps, scale bar)
|
|
122
|
+
uv pip install "spmkit[gwy]" # + interop Gwyddion (.gwy)
|
|
123
|
+
uv pip install "spmkit[hdf5]" # + lectura/exportación HDF5
|
|
124
|
+
uv pip install "spmkit[report]" # + reportes HTML/PDF
|
|
125
|
+
uv pip install "spmkit[nanosurf]"# + lector .nhf validado (NSFopen)
|
|
126
|
+
uv pip install "spmkit[all]" # todo
|
|
127
|
+
|
|
128
|
+
# Desarrollo (desde el repo)
|
|
129
|
+
uv pip install -e ".[dev,gui,hdf5,gwy,report]"
|
|
130
|
+
pre-commit install
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
> También funciona con `pip` clásico (`pip install spmkit`). El build backend es
|
|
134
|
+
> `hatchling`, moderno y compatible.
|
|
135
|
+
|
|
136
|
+
## Uso rápido
|
|
137
|
+
|
|
138
|
+
### CLI
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
spmkit info scan.nid # metadatos y canales
|
|
142
|
+
spmkit roughness scan.nid -c Z-Axis # rugosidad (ISO 25178)
|
|
143
|
+
spmkit analyze scan.nid -o ./results/ # pipeline completo → CSV+JSON
|
|
144
|
+
spmkit nanomech spec.nid --tip-radius 10e-9 # ajuste Hertz → módulo de Young
|
|
145
|
+
spmkit batch ./carpeta/ -o resumen.csv # procesa una carpeta completa
|
|
146
|
+
spmkit figure scan.nid -o fig.svg --colormap batlow # figura de publicación
|
|
147
|
+
spmkit convert scan.nid scan.gwy # convierte a Gwyddion (.gwy)
|
|
148
|
+
spmkit gui # interfaz gráfica
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Como librería
|
|
152
|
+
|
|
153
|
+
```python
|
|
154
|
+
from spmkit import load
|
|
155
|
+
from spmkit.core.analysis import leveling, roughness, profiles, kpfm
|
|
156
|
+
|
|
157
|
+
data = load("scan.nid")
|
|
158
|
+
print(data.names) # ['Z-Axis', 'CPD', 'Amplitude', ...]
|
|
159
|
+
|
|
160
|
+
ch = data["Z-Axis"]
|
|
161
|
+
flat = leveling.plane_fit(ch) # corrige inclinación
|
|
162
|
+
stats = roughness.statistics(flat) # Sa, Sq, Sz, Ssk, Sku
|
|
163
|
+
print(stats.Sq, stats.unit)
|
|
164
|
+
|
|
165
|
+
line = profiles.line(flat, (0, 0), (100, 100)) # perfil de línea
|
|
166
|
+
cpd = kpfm.statistics(data["CPD"], tip_work_function=5.0)
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
## Capacidades
|
|
170
|
+
|
|
171
|
+
- **Lectura**: NanoSurf `.nid` (validado), `.nhf` (HDF5) y Gwyddion `.gwy`.
|
|
172
|
+
- **Análisis**: rugosidad ISO 25178, nivelación, perfiles, KPFM (CPD/función de
|
|
173
|
+
trabajo) y **nanomecánica** (curvas fuerza-distancia, Hertz/Sneddon → módulo
|
|
174
|
+
de Young, punto de contacto, adhesión).
|
|
175
|
+
- **Interop Gwyddion**: lee/escribe `.gwy` (pure-Python) y abre el archivo en
|
|
176
|
+
Gwyddion con un clic.
|
|
177
|
+
- **Figuras de publicación**: editor WYSIWYG (título, ejes, colormaps
|
|
178
|
+
científicos, barra de escala, anotaciones arrastrables) → PNG/SVG/PDF.
|
|
179
|
+
- **Quality of life**: procesamiento por lotes, reportes HTML/PDF, archivos
|
|
180
|
+
recientes, drag & drop, tema claro/oscuro.
|
|
181
|
+
|
|
182
|
+
## Formatos soportados
|
|
183
|
+
|
|
184
|
+
| Formato | Extensión | Estado |
|
|
185
|
+
|---------|-----------|--------|
|
|
186
|
+
| NanoSurf clásico | `.nid` | ✅ Lectura completa (validado) |
|
|
187
|
+
| NanoSurf HDF5 | `.nhf` | 🧪 Experimental (`[hdf5]` o `[nanosurf]`) |
|
|
188
|
+
| Gwyddion | `.gwy` | ✅ Lectura y escritura (`[gwy]`) |
|
|
189
|
+
| Exportación | `.csv`, `.json`, `.h5`, `.png/.svg/.pdf` | ✅ |
|
|
190
|
+
|
|
191
|
+
## Desarrollo
|
|
192
|
+
|
|
193
|
+
```bash
|
|
194
|
+
pytest # tests + cobertura
|
|
195
|
+
ruff check src tests # lint
|
|
196
|
+
black src tests # formato
|
|
197
|
+
mypy src # tipos
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## Citación
|
|
201
|
+
|
|
202
|
+
Si usas spmkit en tu investigación, cítalo según [`CITATION.cff`](CITATION.cff).
|
|
203
|
+
|
|
204
|
+
## Licencia
|
|
205
|
+
|
|
206
|
+
MIT © 2026 SPM Lab UTFSM — Prof. Tomás Corrales, José Labarca.
|