An enterprise-grade, JIT-compiled time-series and nuclear physics analysis engine stress-tested on 100M+ row datasets.
Project description
⚡ triples-sigfast
A high-performance, Numba JIT-compiled data analysis engine for simulation-based physics research — built for scientists, by a scientist.
triples-sigfast bridges the gap between simulation codes (Geant4, FLUKA, MCNP, SERPENT) and publication-ready results — with C-level performance via Numba JIT compilation, zero C code required, and an API accessible to complete beginners.
Why triples-sigfast?
There is currently no Python library that simultaneously offers:
- High-performance JIT-compiled signal processing for large Monte Carlo datasets (100M+ rows)
- Built-in nuclear physics domain knowledge — ICRP 74 standards, NIST XCOM databases, ANSI/ANS-6.4.3 buildup factors
- Native readers for all major simulation code output formats — Geant4 ROOT, FLUKA, MCNP, SERPENT
- Monte Carlo statistical analysis — relative error, figure of merit, convergence checking, uncertainty propagation
- A beginner-friendly API designed for researchers new to programming
triples-sigfast fills this gap.
Installation
pip install triples-sigfast
Requirements: Python >= 3.10, NumPy, Numba, Pandas, uproot, awkward, matplotlib
Performance
Tested on real datasets using the JIT-compiled engine:
| Dataset Size | RAM | Execution Time | Peak RAM |
|---|---|---|---|
| 1,000,000 rows | 8 MB | 0.339s | 192 MB |
| 10,000,000 rows | 80 MB | 0.281s | 404 MB |
| 50,000,000 rows | 400 MB | 0.747s | 940 MB |
| 100,000,000 rows | 800 MB | 1.225s | 1,596 MB |
Survived the 100M row Crucible Test — processing 800 MB of data in just over 1 second.
Features
Signal Processing (triples_sigfast.core)
import numpy as np
from triples_sigfast import rolling_average, ema, detect_anomalies, ema_crossover_strategy
from triples_sigfast import savitzky_golay, find_peaks, flux_to_dose, attenuation
# JIT-compiled rolling average — 100M+ rows
data = np.random.randn(1_000_000)
result = rolling_average(data, window_size=50)
# Exponential moving average at C-speed
prices = np.random.randn(1_000_000).cumsum() + 100
smoothed = ema(prices, span=20)
# Z-score anomaly detection
data[500_000] = 999.0
anomalies = detect_anomalies(data, threshold=3.0)
# Savitzky-Golay spectrum smoother
counts = np.random.poisson(lam=500, size=1000).astype(float)
smooth = savitzky_golay(counts, window=11, polyorder=3)
# Gamma ray peak detection
peaks = find_peaks(smooth, min_height=50, min_distance=10)
# ICRP 74 flux-to-dose conversion
dose = flux_to_dose(flux=1e6, energy_mev=2.35, particle="neutron")
# Beer-Lambert shielding (9 materials, NIST data)
T = attenuation(thickness_cm=10, material="lead")
Monte Carlo Statistics (triples_sigfast.stats.mc)
from triples_sigfast.stats.mc import (
relative_error,
figure_of_merit,
is_converged,
propagate_error,
)
import numpy as np
counts = np.array([10_000.0, 5_000.0, 1_000.0, 250.0])
# Relative error R = 1/sqrt(N) per bin (MCNP standard)
R = relative_error(counts)
# Figure of Merit: FOM = 1 / (R^2 * T)
fom = figure_of_merit(R, cpu_time=3600.0)
# Convergence check (MCNP standard: R < 0.05)
converged = is_converged(counts, threshold=0.05)
print(f"{converged.sum()}/{len(counts)} bins converged")
# GUM uncertainty propagation through detector efficiency
sigma = propagate_error(counts, efficiency=0.35) # HPGe detector
Simulation File Readers (triples_sigfast.io)
One unified API regardless of simulation code:
from triples_sigfast.io import SimReader
# Geant4 ROOT output
reader = SimReader("simulation.root")
# FLUKA output
reader = SimReader("output.flair")
# MCNP MCTAL file
reader = SimReader("output.mctal")
# SERPENT detector file
reader = SimReader("output.det")
# Same API for all formats
spectrum, energies = reader.get_spectrum()
tally = reader.get_tally("neutron_flux")
reader.summary()
Geant4 ROOT Reader
from triples_sigfast.io import RootReader
reader = RootReader("simulation.root")
reader.summary() # auto-lists all histograms
counts, energies = reader.get_spectrum("neutron")
reader.export_csv("results.csv")
reader.export_hdf5("results.h5")
FLUKA Reader
from triples_sigfast.io import FlukaReader
reader = FlukaReader("output.flair")
reader.summary()
usrbin = reader.get_usrbin("neutron_fluence")
usrbdx = reader.get_usrbdx("boundary_crossing")
values, bins = reader.get_spectrum("gamma_dose")
MCNP Reader
from triples_sigfast.io import MCNPReader
reader = MCNPReader("mctal_file")
reader.summary()
tally = reader.get_tally(4) # by tally number
tally = reader.get_tally("tally_4") # by key string
fom = reader.get_fom() # figure of merit from TFC
values, bins = reader.get_spectrum()
SERPENT Reader
from triples_sigfast.io import SerpentReader
reader = SerpentReader("serpent_det.m")
reader.summary()
flux, energies = reader.get_detector("neutron_flux")
keff = reader.get_keff()
burnup = reader.get_burnup()
print(f"k-eff = {keff['ana_keff']:.5f} ± {keff['ana_err']:.5f}")
Nuclear Physics (triples_sigfast.nuclear)
Radiation Shielding
from triples_sigfast.nuclear.shielding import (
attenuation_with_buildup,
attenuation_series,
available_materials,
)
import numpy as np
# GP buildup-corrected attenuation (ANSI/ANS-6.4.3)
T = attenuation_with_buildup(
thickness_cm=10.0,
material="lead",
energy_mev=1.25,
geometry="point_source",
)
print(f"Transmission: {T:.4f} ({T*100:.2f}%)")
# Transmission curve across thickness range
thicknesses = np.linspace(0, 30, 100)
T_curve = attenuation_series(thicknesses, "concrete", 1.25)
# Available materials: lead, iron, concrete, water, polyethylene, aluminum
print(available_materials())
Neutron Source Spectra
from triples_sigfast.nuclear.sources import watt_spectrum, maxwell_spectrum
energies = np.linspace(0.01, 15, 1000) # MeV
# Watt fission spectrum (Cf-252, U-235, Pu-239, ...)
flux_cf252 = watt_spectrum(energies, source="Cf-252")
flux_u235 = watt_spectrum(energies, source="U-235")
# Maxwell-Boltzmann thermal spectrum
flux_thermal = maxwell_spectrum(energies, temperature_mev=0.0000253)
Isotope Database
from triples_sigfast.nuclear.isotope import Isotope
cf252 = Isotope("Cf-252")
print(f"Half-life: {cf252.half_life:.3f} years")
print(f"Activity (1g): {cf252.activity(mass_g=1.0):.3e} Bq")
print(f"Neutron yield: {cf252.neutron_yield:.3e} n/s/g")
print(f"Decay mode: {cf252.decay_mode}")
b10 = Isotope("B-10")
print(f"Thermal xs: {b10.thermal_cross_section:.0f} barns")
print(f"Res. integral: {b10.resonance_integral:.0f} barns")
Dose Calculations
from triples_sigfast.nuclear.dose import (
point_source,
point_source_shielded,
dose_rate_vs_distance,
inverse_square_distance,
)
# Unshielded point source dose rate (ICRP 74)
rate = point_source(
activity_bq=1e9,
energy_mev=1.25,
distance_cm=100,
particle="gamma",
photons_per_decay=2.0, # Co-60: 2 gammas per decay
)
print(f"Dose rate: {rate:.2f} uSv/hr")
# Shielded dose rate (GP buildup-corrected)
rate_shielded = point_source_shielded(
activity_bq=1e9,
energy_mev=1.25,
distance_cm=100,
shield_material="lead",
shield_thickness_cm=5.0,
)
# Dose profile vs distance
distances = np.linspace(10, 500, 200)
rates = dose_rate_vs_distance(1e9, 1.25, distances)
# Minimum safe distance for dose limit
d_safe = inverse_square_distance(1e9, 1.25, target_dose_usvhr=1.0)
print(f"Safe distance: {d_safe/100:.1f} m")
Complete Workflow Example
A full nuclear shielding analysis pipeline from simulation output to results:
import numpy as np
from triples_sigfast.io import RootReader
from triples_sigfast.stats.mc import relative_error, is_converged, propagate_error
from triples_sigfast.nuclear.isotope import Isotope
from triples_sigfast.nuclear.shielding import attenuation_with_buildup
from triples_sigfast.nuclear.dose import point_source_shielded
from triples_sigfast import savitzky_golay, find_peaks
# 1. Load Geant4 simulation output
reader = RootReader("shielding_simulation.root")
reader.summary()
counts, energies = reader.get_spectrum("neutron_spectrum")
# 2. Check Monte Carlo convergence
R = relative_error(counts)
converged = is_converged(counts, threshold=0.05)
print(f"Converged bins: {converged.sum()}/{len(counts)}")
# 3. Propagate uncertainty through HPGe detector efficiency
sigma = propagate_error(counts, efficiency=0.35)
# 4. Smooth spectrum and find peaks
smoothed = savitzky_golay(counts, window=11, polyorder=3)
peaks = find_peaks(smoothed, min_height=50, min_distance=10)
# 5. Compute shielded dose rate for Cf-252 source
cf = Isotope("Cf-252")
n_rate = cf.neutron_source_rate(mass_g=1e-3)
dose = point_source_shielded(
activity_bq=n_rate,
energy_mev=2.0,
distance_cm=100,
shield_material="polyethylene",
shield_thickness_cm=10.0,
particle="neutron",
)
print(f"Shielded dose rate: {dose:.4f} uSv/hr")
Running Tests
pip install triples-sigfast[dev]
pytest --cov=triples_sigfast
Test statistics (v1.4.0): 323 tests, 100% coverage, tested on Ubuntu / macOS / Windows across Python 3.10, 3.11, 3.12.
Architecture
triples_sigfast/
├── core/ # JIT-compiled signal processing (Numba)
├── stats/ # Monte Carlo statistics
├── io/ # Simulation file readers
│ ├── root_reader.py # Geant4 ROOT (uproot)
│ ├── fluka.py # FLUKA USRBIN/USRBDX/USRTRACK
│ ├── mcnp.py # MCNP6 MCTAL format
│ ├── serpent.py # SERPENT2 detector output
│ └── sim_reader.py # Universal auto-detecting reader
├── nuclear/ # Nuclear physics
│ ├── shielding.py # GP buildup factors (ANSI/ANS-6.4.3)
│ ├── sources.py # Watt / Maxwell fission spectra
│ ├── isotope.py # Isotope database (NUBASE2020)
│ └── dose.py # ICRP 74 dose calculations
├── viz/ # Publication-quality plots (coming v1.5.0)
├── cli/ # Command-line interface (coming v1.6.0)
├── detectors/ # Detector physics (planned)
└── plasma/ # Plasma physics (planned)
Roadmap
| Version | Status | Milestone |
|---|---|---|
| v1.1.1 | ✅ Released | Core signal processing, 86 tests |
| v1.2.0 | ✅ Released | Monte Carlo statistics, ROOT reader, SimReader |
| v1.3.0 | ✅ Released | Nuclear physics — buildup factors, Watt spectrum, isotope database, ICRP 74 dose |
| v1.4.0 | ✅ Released | Native FLUKA, MCNP, SERPENT readers — 323 tests, 100% coverage |
| v1.5.0 | 🔄 In progress | Visualization engine — publication-quality plots, LaTeX/PDF/SVG export |
| v1.6.0 | ⬜ Planned | CLI, auto-report generator, guided beginner mode |
| v2.0.0 | ⬜ Planned | Community launch, academic paper submission |
Origin
"I needed to analyze Geant4 ROOT files for my nuclear shielding research and nothing made it easy. So I built triples-sigfast."
The primary audience is physics researchers who are beginners in programming — graduate students, junior researchers, and academics who run simulations but struggle with data analysis pipelines. The library must be powerful enough for experts and simple enough for beginners.
Contributing
Contributions are welcome. Please read CONTRIBUTING.md first.
License
MIT License — see LICENSE for details.
Author
TripleS Studio
- PyPI: triples-sigfast
- GitHub: SamdaniSayam/triples-sigfast
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file triples_sigfast-1.6.0.tar.gz.
File metadata
- Download URL: triples_sigfast-1.6.0.tar.gz
- Upload date:
- Size: 75.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e827ed448df19e80dbff873d9e00640c20d7a90e90df2fabcbff99927517f5fd
|
|
| MD5 |
5ffa8af25aed29f08159dbfb58256424
|
|
| BLAKE2b-256 |
12febd6a7eb8c83d16803b680e17a0937302c398d85e2b5dd23554d619b643d3
|
File details
Details for the file triples_sigfast-1.6.0-py3-none-any.whl.
File metadata
- Download URL: triples_sigfast-1.6.0-py3-none-any.whl
- Upload date:
- Size: 58.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6ccaadb73cc45517cc2a0df9601226f2d9f5b9f7b33da6c6ac422595922d8f49
|
|
| MD5 |
4bca053abf53257bbaad978e1762c9e6
|
|
| BLAKE2b-256 |
535d0ee68633f58f1a7abb29f412d189a110020152d06fde93b4325cf311bee9
|