SkillAgentSearch skills...

Spectrix

Interactive 1D/2D histogram fitter and data visualization tool for nuclear physics analysis — built in Rust with egui and polars.

Install / Use

/learn @alconley/Spectrix

README

Spectrix

Spectrix is a comprehensive software package for nuclear spectrum analysis. It provides tools for histogramming, Gaussian fitting, and interactive visualization of 1D and 2D histograms using the crates:
egui, egui-tiles, egui_plot, and polars.

Additionally, using uproot, you can view 1D and 2D ROOT histograms. Fitting is performed using Python’s lmfit library.

spectrix_screenshot


Features

  • Read and analyze .parquet and .root files
  • Background ROOT histogram retrieval/export so long uproot operations do not block the UI
  • Combine matching ROOT histograms across multiple files, or load them separately with per-file prefixes
  • Interactive histogramming (1D & 2D)
  • Interactive histogram-created cuts for 1D and 2D views
  • Gaussian fitting with Python’s lmfit, including total-fit uncertainty bands
  • Visible-range auto-Y scaling for 1D histograms, with log-Y support
  • UUID peak labels with configurable size/lift and optional guide lines
  • UI-based histogram and cut definition
  • Custom histogram scripting
  • Built-in screenshot capture from the top bar
  • Integration with Polars for high-performance data processing

Running Spectrix

Quick Start

If you want the simplest launch path, use:

./spectrix.sh

This script creates/activates .venv, installs Python dependencies, sets the required PyO3 environment variables, and runs cargo run --release.


Tested Platforms

  • macOS Sonoma 14.6.1 on Apple M3 MacBook Pro (18 GB RAM)
  • Ubuntu 22.04.5 LTS
  • Windows 10

⚠️ Tested with Python 3.13.
On Windows, ensure that Python is downloaded from python.org.


Install Rust

Ensure you’re using the latest stable version of Rust:

rustup update

If you don’t have Rust installed, visit the Rust website and follow the instructions.


System Dependencies

Linux (Ubuntu/Debian):

sudo apt-get install libxcb-render0-dev libxcb-shape0-dev libxcb-xfixes0-dev libxkbcommon-dev libssl-dev libgtk-3-dev

macOS:

Install equivalent libraries using Homebrew as needed for your local toolchain. If build/linking issues appear, run through ./spectrix.sh first to ensure the Python/PyO3 environment is configured correctly.


Installation Steps

Clone the repository

git clone https://github.com/alconley/spectrix.git
cd spectrix

Create a Python virtual environment and activate it

python3 -m venv .venv
source .venv/bin/activate

Install the required python packages

pip install -r requirements.txt

(Optional, but often required on macOS; see ./spectrix.sh) Set the Python environment for Rust (PyO3)

export PYO3_PYTHON=$(pwd)/.venv/bin/python
export PYTHONPATH=$(pwd)/.venv/lib/python3.*/site-packages

Run the Rust project in release mode

cargo run --release

Tips if the program doesn't run

rustup update
cargo clean
cargo update

Overview

The Spectrix program reads .parquet files using the Polars crate.
Typically, .parquet files are generated by Eventbuilder for me. These files store raw data as f64 in a dataframe format (similar to a ROOT tree).

Histograms can be configured in the left panel of the UI. New column creation and cuts can also be performed directly in the UI.

Additionally, users can read 1D and 2D histograms from ROOT files using the Python package uproot. ROOT trees can easily be converted to .parquet format using HEP-Convert.


Step 1: Getting Files

Use the Get Files/Directory button to select either a single file or a directory.

  • If you select a directory, Spectrix scans it and loads supported files (.parquet, .root).
  • If you select a single file, only that file is loaded.

Root Files

If one or more .root files are selected, Spectrix attempts to load all 1D and 2D histograms found in those files.

Histogram paths such as /name1/name2/histogram_name are preserved and used to organize views into nested container hierarchies.

ROOT retrieval runs in the background, so the UI remains responsive while Spectrix reads histograms through uproot. A spinner is shown while retrieval is active, and the operation can be canceled between files.

ROOT loading behavior depends on the Calculate/Get histograms separately toggle:

  • Off: histograms with the same full ROOT path/name are merged together across the selected files.
  • On: each file gets its own prefix using the file stem, so matching histograms are loaded as separate entries such as run_001/hEnergy and run_002/hEnergy.

When you start a new ROOT retrieval, Spectrix clears the current histogram contents first so repeated clicks on Get Histograms do not double the loaded counts.

After 1D ROOT histograms are loaded, their axes are reset automatically so the plot opens around the imported data instead of staying zoomed near zero.

Parquet Files

Parquet is the preferred format for analysis, since Spectrix can build histograms directly from raw columns using the Histogram Script system.

If you are unsure of available columns, open Selected File Settings and click Get Column Names.

Spectrix will list columns from the selected parquet files.

In the same section, you can:

  • Save filtered versions of your .parquet files.
  • Combine multiple files into one.

You can also load 2D cuts in this area; those cuts are then available as active cuts and are used when filtering saved .parquet outputs.

When saving filtered files, Spectrix applies all enabled active 1D/2D cuts from the Histogram Script cut sections and writes output using filename_{suffix}.parquet naming.

Interactive cuts created directly on 1D and 2D histograms also appear in the same active-cuts area, so they can be enabled/disabled for histogram generation and parquet filtering before being added manually to the script.

When combining parquet files, Spectrix scans the selected inputs lazily and streams the merged result directly to the output parquet sink. It does not collect the full combined dataset into memory first.

Large combines can still take time and produce large output files, so reducing files with cuts first can still be a useful workflow when you only need a subset of the data.


Histogram Script

The Histogram Script panel can be opened or closed using the “Histograms” button under the “Get Files” button.

This tool allows you to:

  • Define new analysis columns from existing parquet columns.
  • Define and manage 1D and 2D cuts.
  • Define 1D and 2D histograms (name, columns, bins, range, and applied cuts).
  • Save/load complete histogram-script setups as .json configuration files.

Typical Workflow

  1. Load one or more parquet files and inspect available column names.
  2. Create any derived columns you need (for example timing differences or calibrated values).
  3. Define cuts (1D expressions and/or 2D graphical cuts).
  4. Create histogram definitions and attach active cuts.
  5. Save the configuration to JSON so the same analysis can be reused.

Example

Below are example images of Spectrix using the sample file located at
./example/run_83_reduced.parquet.

This dataset comes from a one-hour measurement of the 52Cr(d,pγ)53Cr reaction.
The file is pre-filtered to include only proton data (the full dataset was too large for GitHub).

Invalid detector values are stored as -1e6, which marks cases where a detector did not register a hit within an event window.
This ensures that all columns have the same length.
The file was generated using Eventbuilder.


The following subsections assume you are in the “General” section of the Histogram Script panel.

Column Creation

You can create derived columns such as time differences, sums, averages, or calibrated variants of existing columns.

Derived columns can then be used exactly like native columns in cuts and histogram definitions.

⚠️ Tip:
Define column aliases (names) without spaces.
This is required for correct parsing in string-based 1D cut expressions.

Cuts

You can define:

  • 1D cuts by providing a cut name and a logical expression, or by loading saved 1D cut JSON files with +1D Load.
  • 2D cuts as graphical polygons in the 2D histogram view.

For cut management in the Histogram Script UI, you can:

  • Add a blank 1D cut with +1D Manual.
  • Load a saved 1D cut with +1D Load.
  • Load a cut JSON individually for 2D cuts with +2D.
  • Add a cut folder to load multiple cut files.
  • Use Active Histogram Cuts created interactively in 1D or 2D plots, even before saving them to disk.

For expression-based 1D cuts, use valid column names and logical operators such as & to combine conditions.

Common operators in 1D cut expressions include:

  • & for AND
  • | for OR
  • ==, !=, >, >=, <, <= for comparisons

Example:

  • (Column1Energy > 400) & (Column1Energy < 1200) & (Column2Time != -1e6)

If a 1D cut parses as a simple range, its Info menu shows the extracted column name and the >= / <= bounds.

Cuts that were loaded from disk or explicitly saved to disk remember their save path. If you later edit the cut name or cut values inside Spectrix, the cut is automatically re-saved back to that same file.

Only cuts enabled in the corresponding UI checkboxes are applied during histogram generation and parquet filtering.

Histogram Definitions

Enter the histogram name and select the input column(s), bin count, and axis range.

Using slashes (/) in histogram

Related Skills

View on GitHub
GitHub Stars10
CategoryProduct
Updated3d ago
Forks2

Languages

Rust

Security Score

95/100

Audited on Apr 4, 2026

No findings