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.
Files changed (73) hide show
  1. spmkit-0.1.0/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  2. spmkit-0.1.0/.github/ISSUE_TEMPLATE/feature_request.md +18 -0
  3. spmkit-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +26 -0
  4. spmkit-0.1.0/.github/workflows/ci.yml +42 -0
  5. spmkit-0.1.0/.github/workflows/publish.yml +41 -0
  6. spmkit-0.1.0/.gitignore +29 -0
  7. spmkit-0.1.0/.pre-commit-config.yaml +28 -0
  8. spmkit-0.1.0/CHANGELOG.md +31 -0
  9. spmkit-0.1.0/CITATION.cff +28 -0
  10. spmkit-0.1.0/CONTRIBUTING.md +55 -0
  11. spmkit-0.1.0/LICENSE +21 -0
  12. spmkit-0.1.0/Makefile +34 -0
  13. spmkit-0.1.0/PKG-INFO +206 -0
  14. spmkit-0.1.0/README.md +140 -0
  15. spmkit-0.1.0/docs/ARCHITECTURE.md +76 -0
  16. spmkit-0.1.0/docs/ROADMAP.md +64 -0
  17. spmkit-0.1.0/docs/UI_DESIGN.md +70 -0
  18. spmkit-0.1.0/docs/VALIDATION.md +63 -0
  19. spmkit-0.1.0/docs/images/figure_demo.png +0 -0
  20. spmkit-0.1.0/docs/images/screenshot_viewer.png +0 -0
  21. spmkit-0.1.0/pyproject.toml +97 -0
  22. spmkit-0.1.0/src/spmkit/__init__.py +16 -0
  23. spmkit-0.1.0/src/spmkit/cli/__init__.py +5 -0
  24. spmkit-0.1.0/src/spmkit/cli/app.py +233 -0
  25. spmkit-0.1.0/src/spmkit/core/__init__.py +15 -0
  26. spmkit-0.1.0/src/spmkit/core/analysis/__init__.py +21 -0
  27. spmkit-0.1.0/src/spmkit/core/analysis/kpfm.py +65 -0
  28. spmkit-0.1.0/src/spmkit/core/analysis/leveling.py +61 -0
  29. spmkit-0.1.0/src/spmkit/core/analysis/mechanics.py +272 -0
  30. spmkit-0.1.0/src/spmkit/core/analysis/profiles.py +76 -0
  31. spmkit-0.1.0/src/spmkit/core/analysis/roughness.py +76 -0
  32. spmkit-0.1.0/src/spmkit/core/batch.py +110 -0
  33. spmkit-0.1.0/src/spmkit/core/export/__init__.py +5 -0
  34. spmkit-0.1.0/src/spmkit/core/export/writers.py +90 -0
  35. spmkit-0.1.0/src/spmkit/core/io/__init__.py +8 -0
  36. spmkit-0.1.0/src/spmkit/core/io/gwy.py +97 -0
  37. spmkit-0.1.0/src/spmkit/core/io/nhf.py +74 -0
  38. spmkit-0.1.0/src/spmkit/core/io/nid.py +163 -0
  39. spmkit-0.1.0/src/spmkit/core/io/registry.py +44 -0
  40. spmkit-0.1.0/src/spmkit/core/models/__init__.py +5 -0
  41. spmkit-0.1.0/src/spmkit/core/models/spmdata.py +106 -0
  42. spmkit-0.1.0/src/spmkit/core/report.py +134 -0
  43. spmkit-0.1.0/src/spmkit/core/viz/__init__.py +21 -0
  44. spmkit-0.1.0/src/spmkit/core/viz/colormaps.py +97 -0
  45. spmkit-0.1.0/src/spmkit/core/viz/figure.py +222 -0
  46. spmkit-0.1.0/src/spmkit/gui/__init__.py +5 -0
  47. spmkit-0.1.0/src/spmkit/gui/app.py +25 -0
  48. spmkit-0.1.0/src/spmkit/gui/compare_tab.py +165 -0
  49. spmkit-0.1.0/src/spmkit/gui/figure_tab.py +239 -0
  50. spmkit-0.1.0/src/spmkit/gui/main_window.py +215 -0
  51. spmkit-0.1.0/src/spmkit/gui/nanomech_tab.py +157 -0
  52. spmkit-0.1.0/src/spmkit/gui/theme.py +187 -0
  53. spmkit-0.1.0/src/spmkit/gui/viewer_tab.py +187 -0
  54. spmkit-0.1.0/src/spmkit/gui/welcome.py +62 -0
  55. spmkit-0.1.0/tests/__init__.py +0 -0
  56. spmkit-0.1.0/tests/conftest.py +75 -0
  57. spmkit-0.1.0/tests/core/__init__.py +0 -0
  58. spmkit-0.1.0/tests/core/test_export.py +43 -0
  59. spmkit-0.1.0/tests/core/test_gwy.py +58 -0
  60. spmkit-0.1.0/tests/core/test_io_nid.py +66 -0
  61. spmkit-0.1.0/tests/core/test_kpfm.py +25 -0
  62. spmkit-0.1.0/tests/core/test_leveling.py +39 -0
  63. spmkit-0.1.0/tests/core/test_maps_grid_report.py +85 -0
  64. spmkit-0.1.0/tests/core/test_mechanics.py +69 -0
  65. spmkit-0.1.0/tests/core/test_profiles.py +31 -0
  66. spmkit-0.1.0/tests/core/test_roughness.py +38 -0
  67. spmkit-0.1.0/tests/core/test_viz_report_batch.py +77 -0
  68. spmkit-0.1.0/tests/gui/__init__.py +0 -0
  69. spmkit-0.1.0/tests/gui/test_smoke.py +83 -0
  70. spmkit-0.1.0/tests/validation/__init__.py +0 -0
  71. spmkit-0.1.0/tests/validation/test_nanomech_real.py +49 -0
  72. spmkit-0.1.0/tests/validation/test_nid_vs_gwyddion.py +77 -0
  73. 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
@@ -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
+ [![CI](https://github.com/kegouro/spmkit/actions/workflows/ci.yml/badge.svg)](https://github.com/kegouro/spmkit/actions/workflows/ci.yml)
70
+ [![PyPI](https://img.shields.io/pypi/v/spmkit.svg)](https://pypi.org/project/spmkit/)
71
+ [![Python](https://img.shields.io/pypi/pyversions/spmkit.svg)](https://pypi.org/project/spmkit/)
72
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)
73
+ [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](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
+ ![spmkit GUI](docs/images/screenshot_viewer.png)
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.