Metadata-Version: 2.4
Name: aci_rssa
Version: 0.0.5
Requires-Dist: polars>=1.0
Requires-Dist: matplotlib>=3.7
Requires-Dist: ty>=0.0.60 ; extra == 'dev'
Requires-Dist: pytest>=8.0 ; extra == 'test'
Provides-Extra: dev
Provides-Extra: test
License-File: LICENSE
Summary: Fast, streaming reader for MCNP RSSA (surface source) files, with a Rust core and Polars-based Python API
License-Expression: EUPL-1.2
Requires-Python: >=3.10
Description-Content-Type: text/markdown; charset=UTF-8; variant=GFM

<p align="center">
  <picture>
    <source media="(prefers-color-scheme: dark)" srcset="assets/logo-wordmark-dark.svg">
    <source media="(prefers-color-scheme: light)" srcset="assets/logo-wordmark-light.svg">
    <img alt="aci_rssa" src="assets/logo-wordmark-light.svg" width="360">
  </picture>
</p>

[![CI](https://github.com/AlvaroCubi/aci_rssa/actions/workflows/ci.yml/badge.svg)](https://github.com/AlvaroCubi/aci_rssa/actions/workflows/ci.yml)
[![PyPI](https://img.shields.io/pypi/v/aci_rssa)](https://pypi.org/project/aci_rssa/)
[![License: EUPL-1.2](https://img.shields.io/badge/license-EUPL--1.2-blue)](LICENSE)

Fast, streaming reader for MCNP RSSA (surface source) files, with a Rust core and a
[Polars](https://pola.rs/)-based Python API.

RSSA files record every particle that crosses a given surface during an MCNP (or
D1S-UNED) simulation, and can easily reach tens or hundreds of gigabytes. `aci_rssa`
memory-maps the file and decodes track records in parallel (via [rayon](https://docs.rs/rayon)),
handing the result to Python as a Polars `DataFrame` — either all at once, or as a lazy,
batch-at-a-time stream for files too large to fit in memory.

## Installation

```bash
pip install aci_rssa
```

Prebuilt wheels are published for Linux, macOS, and Windows (x86_64/arm64) on
CPython ≥3.10 — no Rust toolchain needed to install.

## Quickstart

```python
from aci_rssa import RSSA

rssa = RSSA.read_from_file("surface_source.w")
print(rssa)  # summary: surfaces, track/history counts, source code

rssa.tracks          # polars.DataFrame: history, particle_type, weight, energy,
                      # time, x, y, z, u, v, w, surface_id
rssa.neutron_tracks   # tracks filtered to neutrons
rssa.photon_tracks    # tracks filtered to everything else (typically photons)
```

Reading only the header (fast, never touches the potentially huge track data):

```python
from aci_rssa import FileParameters

parameters = FileParameters.read_from_file("surface_source.w")
parameters.nrss       # number of tracks recorded
parameters.surfaces   # surfaces tracks were recorded on
```

### Very large files

For files too large to load eagerly, `scan_tracks` returns a Polars `LazyFrame` backed
by a Rust reader that decodes the file batch by batch, driven by Polars' query engine —
filters and column selection are pushed down so you only decode what you need:

```python
from aci_rssa import scan_tracks
import polars as pl

(
    scan_tracks("surface_source.w")
    .filter(pl.col("energy") > 1.0)
    .select("x", "y", "z", "energy")
    .collect(engine="streaming")
)
```

### Plotting

```python
rssa.plot_cyl(axis="z").show()      # particle density on a cylindrical surface
rssa.plot_plane(x="x", y="y").show()  # particle density on a planar surface
rssa.plot_spectra().show()            # energy spectrum
```

## Development

This is a Cargo workspace (`rssa-core`, the pure-Rust parsing/decoding library, and
`rssa-python`, its PyO3 bindings) plus a Python package in `python/`, built together
with [maturin](https://www.maturin.rs/).

```bash
python -m venv .venv && source .venv/bin/activate
pip install "maturin>=1.9.4,<2.0"
maturin develop --extras test,dev   # builds the extension module, installs test/dev deps

cargo test                          # Rust tests (rssa-core)
pytest                              # Python tests
ty check python/aci_rssa            # type checking
```

## License

Licensed under the [European Union Public Licence v1.2 (EUPL-1.2)](LICENSE).

