Metadata-Version: 2.4
Name: isomap-desktop
Version: 0.3.0
Summary: Isotopic and paleoecological data standardisation middleware
Requires-Python: >=3.12
Requires-Dist: anytree>=2.8
Requires-Dist: chardet>=5.2
Requires-Dist: geopandas>=1.0
Requires-Dist: httpx>=0.27
Requires-Dist: jinja2>=3.1
Requires-Dist: networkx>=3.0
Requires-Dist: nltk>=3.8
Requires-Dist: openpyxl>=3.1
Requires-Dist: pandas>=2.2
Requires-Dist: pandera>=0.20
Requires-Dist: pot>=0.9
Requires-Dist: pulp<4.0,>=2.5
Requires-Dist: pydantic>=2.8
Requires-Dist: pylipd>=1.3
Requires-Dist: pyproj>=3.6
Requires-Dist: rapidfuzz>=3.9
Requires-Dist: rocrate>=0.15
Requires-Dist: scipy<2.0,>=1.12
Requires-Dist: shapely>=2.0
Requires-Dist: valentine>=1.0
Requires-Dist: xlrd>=2.0
Requires-Dist: xlsxwriter>=3.2
Provides-Extra: dev
Requires-Dist: pre-commit>=3.8; extra == 'dev'
Requires-Dist: pytest-asyncio>=0.24; extra == 'dev'
Requires-Dist: pytest>=8.0; extra == 'dev'
Requires-Dist: ruff>=0.6; extra == 'dev'
Provides-Extra: ml
Requires-Dist: onnxruntime>=1.19; extra == 'ml'
Requires-Dist: optimum[onnxruntime]>=1.20; extra == 'ml'
Requires-Dist: transformers>=4.40; extra == 'ml'
Description-Content-Type: text/markdown

# IsoMap

Isotopic and paleoecological data standardisation middleware.

IsoMap is an open-source desktop application that automates the standardisation, validation, and export of legacy isotopic and paleoecological datasets for submission to centralised repositories (Neotoma, IsoArcH, PANGAEA, NOAA NCEI, LiPD).

📖 **[User Guide](USER_GUIDE.md)** — full walkthrough with screenshots, workflow steps, and troubleshooting.
📋 **[Changelog](CHANGELOG.md)** — version history and release notes.

## Features

IsoMap provides a 6-tab wizard interface backed by 8 processing engines.
**Implementation status** is marked next to each engine — several engines
are partial stubs; see `CHANGELOG.md` for the full list of known
limitations.

- **Import Engine** ✅: CSV and Excel spreadsheets with automatic encoding detection and type inference.
- **Column Mapping Engine** ✅: 6-stage fallback pipeline (exact → preferences → fuzzy → semantic embeddings → Valentine ensemble → distribution profiling) to map source columns to 5 target repository schemas. Valentine is now correctly wired against the ≥1.0 API; the semantic stage requires the optional `[ml]` extras (SciBERT ONNX, ~400 MB).
- **Chronology Engine** ✅: Auto-detects and normalises uncalibrated/calibrated dates to `cal_BP` with 1950 CE anchor. Note: this is *format normalisation* only — no radiocarbon calibration (IntCal20 etc.) is performed.
- **Spatial Verification Engine** ✅: Cleans coordinates, displays on interactive Leaflet map, exports bounding box. EPSG:4326 only — no UTM/other CRS transformation yet.
- **Validation Engine** ✅: Pandera constraint checking with row-level error tracking against schema definitions. Required-field presence is enforced.
- **Export Engine** ⚠️ partial: CSV, Excel, GeoJSON, JSON, PANGAEA, NOAA, RO-Crate, LaTeX data paper all produce output. **LiPD export is non-conformant** (missing required LiPD v1.3 fields; `pylipd.load()` rejects it). **PANGAEA and NOAA exports are template stubs** with `[INSERT_*]` placeholders, not submission-ready files.
- **Provenance Engine** ⚠️ partial: `ProvenanceTracker` class exists and is unit-tested but is **not wired into the RPC pipeline** — `main.py` doesn't instantiate it. Produces a JSON audit log, not PROV-O RDF as the original scope doc describes.
- **Automated Data Papers** ✅: Jinja2 ESSD-compliant LaTeX manuscript generation.

## Technology Stack

| Layer | Technology |
|-------|-----------|
| Desktop shell | Tauri v2 (Rust) |
| Frontend | React 19, Vite 7, TypeScript, Leaflet |
| Backend (sidecar) | Python 3.12+, Pandas, Pandera, GeoPandas |
| ML/NLP | SciBERT ONNX (Optimum), RapidFuzz, Valentine |
| Testing | Pytest (backend), Playwright (E2E) |

## Getting Started

### Prerequisites

- **Rust 1.70+** — [rustup.rs](https://rustup.rs)
- **Python 3.12+** — `pip install -e ".[dev]"`
- **Node.js 20+** with npm

### Development

```bash
cd ui && npm install        # Frontend dependencies
npm run tauri dev           # Full desktop app with hot-reload
npm run dev                 # Vite frontend only (no Tauri)
cd src-tauri && cargo build # Rust backend only
```

### Testing

```bash
pytest tests/               # Python backend (36 tests)
cd ui && npx playwright test # E2E browser tests (6 tests)
```

### Production Build

```bash
./scripts/build-sidecar.sh  # PyInstaller standalone binary
cd ui && npm run tauri build # Full desktop app bundle
```

Bundles output to `ui/src-tauri/target/release/bundle/`.

## Supported Repositories

| Schema | Repository | Fields | Required Fields |
|--------|-----------|--------|----------------|
| `neotoma_v2` | Neotoma | 11 | SiteName, Latitude, Longitude, TaxonName, Value |
| `isoarch_v1` | IsoArcH | 10 | site_name, latitude, longitude, sample_id, material, d13c |
| `pangaea` | PANGAEA | 20 | Event, Latitude, Longitude, Parameter, Value, Unit |
| `noaa` | NOAA NCEI | 24 | SiteName, Latitude, Longitude, Proxy, Proxy_Value, Proxy_Unit |
| `lipd` | LiPD v1.3 | 24 | dataSetName, SiteName, Latitude, Longitude, PaleoData_VariableName, PaleoData_Value, PaleoData_Unit |

Add custom schemas in `data/schemas/` following the [JSON Schema](https://json-schema.org/) format.

## Architecture

```
React invoke() → Rust Tauri commands → sidecar_rpc() → shell wrapper → Python JSON-RPC
```

The Rust layer (`ui/src-tauri/src/lib.rs`) exposes 9 Tauri commands that serialise
parameters to JSON-RPC and forward them to the Python sidecar (`src/isomap/main.py`)
via stdin/stdout. The sidecar processes the request and returns a JSON-RPC response.

### Key Files

| File | Purpose |
|------|---------|
| `ui/src-tauri/src/lib.rs` | 9 Tauri commands + `sidecar_rpc()` JSON-RPC helper |
| `ui/src-tauri/tauri.conf.json` | App config, window, sidecar external binary |
| `ui/src-tauri/binaries/isomap-sidecar*` | Platform-specific sidecar wrappers |
| `src/isomap/main.py` | Python JSON-RPC server (stdin/stdout or CLI mode) |
| `ui/src/api/sidecar.ts` | Frontend API layer (`invoke()` calls) |
| `ui/src/App.tsx` | Main React app with shared wizard state |
| `data/schemas/*.json` | Repository schema definitions |
| `scripts/build-sidecar.sh` | PyInstaller sidecar binary builder |

## License

MIT

