Metadata-Version: 2.4
Name: zs2fast
Version: 0.6.0
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Rust
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering
Classifier: Topic :: Software Development :: Libraries
License-File: LICENSE
Summary: Fast Rust/PyO3 parser for ZS2 files with Parquet export
Keywords: zs2,parquet,pyo3,rust,materials
Home-Page: https://github.com/weltidom/zs2fast
Author: Dominic Welti
Requires-Python: >=3.9
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM
Project-URL: Homepage, https://github.com/weltidom/zs2fast
Project-URL: Issues, https://github.com/weltidom/zs2fast/issues
Project-URL: Repository, https://github.com/weltidom/zs2fast

# zs2fast

A fast Python extension for converting Zwick ZS2 test machine files to Parquet format, written in Rust/PyO3.

## Features

- Fast gzip decompression and binary parsing of .zs2 files
- Extracts channel time-series data with automatic unit resolution
- Extracts evaluated parameters and test results with units
- Converts to Parquet format using Apache Arrow
- Built with PyO3 for seamless Python integration
- Supports Python 3.9–3.12 on Linux, macOS, and Windows

## Installation

### From PyPI

```bash
pip install zs2fast
```

### From Source

Requires Rust and Python 3.9+.

```bash
# Install maturin
pip install maturin

# Clone and build
git clone https://github.com/weltidom/zs2fast.git
cd zs2fast
maturin develop --release
```

## Usage

```python
import zs2fast
import polars as pl

# Convert a .zs2 file to raw long-format Parquet
# Useful for exploring binary structure and raw values
zs2fast.zs2_to_parquet("input.zs2", "output.parquet", include_u32=False)
# columns: series, subtype, index, value

# Export channel time-series with semantic names and units
zs2fast.zs2_channels_to_parquet("input.zs2", "channels.parquet")
# columns: sample_idx, channel_idx, channel_name, unit, timepoint, value, data_type
channels = pl.read_parquet("channels.parquet")
print(channels.filter(pl.col('unit').is_not_null()).head())

# Export calculated test results (Bruchbild, elongation, max force, etc.)
# Units are resolved from EinheitName → QS_ValSetting blob → UnitTables
zs2fast.zs2_export_enriched_params_to_parquet("input.zs2", "evaluated_params.parquet")
# columns: sample_idx, param_id, short_name, param_name, unit, value, value_text
params = pl.read_parquet("evaluated_params.parquet")
print(params.filter(pl.col('value').is_not_null()).head())

# Extract per-sample test settings and parameters (not calculated results)
zs2fast.zs2_export_sample_results_to_parquet("input.zs2", "sample_params.parquet")
# columns: sample_id, result_id, result_name, unit, value_text, value
sample_params = pl.read_parquet("sample_params.parquet")
print(sample_params.head())
```

## Which Parameter Export Should I Use?

Both APIs read the per-sample `ParameterListe`, but they optimize for different goals.

| Function | Primary goal | Output columns | Notes |
|---|---|---|---|
| `zs2_export_enriched_params_to_parquet` | Build a normalized parameter table with strong metadata enrichment | `sample_idx, param_id, short_name, param_name, unit, value, value_text` | Best for analysis tables where stable names/units matter most |
| `zs2_export_sample_results_to_parquet` | Preserve per-sample result rows as stored/evaluated in `ParameterListe` | `sample_id, result_id, result_name, unit, value_text, value` | Includes branch-aware parsing to avoid nested/outer path collisions |

### Practical Rule

- Use `zs2_export_enriched_params_to_parquet` when you want a canonical analysis-ready parameter table.
- Use `zs2_export_sample_results_to_parquet` when you want the closest representation of per-sample evaluated result entries.

## Naming and Deprecation

Preferred names:

- `zs2_export_enriched_params_to_parquet`
- `zs2_export_sample_results_to_parquet`

Legacy names remain supported but now emit runtime `DeprecationWarning`:

- `zs2_evaluated_params_to_parquet`
- `zs2_parameterliste_results_to_parquet`

Use the new names in notebooks and scripts going forward.

## Unit Resolution

The parser automatically resolves measurement units using a 3-tier strategy:

1. **Direct unit name** (`EinheitName` field) — Direct unit symbol (mm, N, MPa, etc.)
2. **Unit table key** (from `QS_ValSetting` binary blob) — References `/UnitTables` section (UT_Length → mm, UT_Force → N, etc.)
3. **Fallback inference** — Attempts to infer units from table key name

Channels typically use tier 1–2, while evaluated parameters primarily use tiers 2–3. This ensures maximum unit coverage across different .zs2 file structures.

## Development

### Build

```bash
maturin build --release
```

Note: for this PyO3 extension module on macOS, prefer `maturin build`/`maturin develop`.
Running plain `cargo build --release` can fail with unresolved Python symbols
(`_Py*`, `__Py_*`) during linking.

### Lint

```bash
cargo fmt
cargo clippy
```

### Test

```bash
cargo test
```

## License

See LICENSE file for details.

