Metadata-Version: 2.4
Name: phasmanet
Version: 0.1.0
Summary: PhasmaNet: a staged spectral token-refinement architecture for tabular regression and classification, with a pretrained gravitational-wave SNR surrogate.
Author: Ioannis Tsioulis, Anastasios Tefas, Nikolaos Stergioulas
License-Expression: MIT
Project-URL: Homepage, https://github.com/giannis00/PhasmaNet-SNR
Project-URL: Source, https://github.com/giannis00/PhasmaNet-SNR
Project-URL: Issues, https://github.com/giannis00/PhasmaNet-SNR/issues
Keywords: deep learning,tabular data,neural surrogate,pytorch,gravitational waves,signal-to-noise ratio,selection effects
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3 :: Only
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Scientific/Engineering :: Astronomy
Classifier: Topic :: Scientific/Engineering :: Physics
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Requires-Dist: scipy>=1.7
Requires-Dist: torch>=1.13
Provides-Extra: sklearn
Requires-Dist: scikit-learn>=1.0; extra == "sklearn"
Provides-Extra: test
Requires-Dist: pytest>=7; extra == "test"
Requires-Dist: scikit-learn>=1.0; extra == "test"
Requires-Dist: pandas>=1.3; extra == "test"
Dynamic: license-file

<p align="center">
  <img src="https://raw.githubusercontent.com/giannis00/PhasmaNet-SNR/main/assets/phasmanet_symbol.png" alt="PhasmaNet symbol" width="140">
</p>

<h1 align="center">PhasmaNet</h1>

PhasmaNet (from Greek *φάσμα*, spectrum) is a compact neural architecture for structured
tabular data. Learned input tokens are refined by an ordered cascade of attention-based
**Φ-Stages**, each followed by a **Φ-Refractor** subspace-mixing module, and then revisited
through gated top-down **Φ-Feedback** passes.

This package provides:

* `PhasmaNetRegressor` and `PhasmaNetClassifier`: estimators with the familiar
  `fit` / `predict` interface, usable on any table of numerical features and compatible
  with scikit-learn tools (`cross_val_score`, `Pipeline`, `clone`).
* `phasmanet.gw.optimal_snr`: a pretrained surrogate for the phase-averaged optimal
  signal-to-noise ratio of precessing, higher-mode binary black hole signals.
* `PhasmaNet`, the PyTorch module itself, and `MonotoneCalibrator`, the rank-preserving
  PCHIP calibration used in the paper.

## Installation

```bash
pip install phasmanet
```

PhasmaNet needs PyTorch. For GPU support, install the PyTorch build that matches your
system first, following https://pytorch.org/get-started/locally/, and then install
`phasmanet`. scikit-learn is optional (`pip install "phasmanet[sklearn]"`).

## Regression and classification on your own data

```python
from phasmanet import PhasmaNetRegressor

reg = PhasmaNetRegressor(random_state=0)          # architecture of the paper by default
reg.fit(X_train, y_train)                         # early stopping on a 15% validation split
y_pred = reg.predict(X_test)
print(reg.score(X_test, y_test))                  # R^2

reg.save("model.pt")
reg = PhasmaNetRegressor.load("model.pt")
```

```python
from phasmanet import PhasmaNetClassifier

clf = PhasmaNetClassifier(random_state=0).fit(X_train, y_train)
proba = clf.predict_proba(X_test)
```

Inputs are standardised internally, so raw features can be passed directly.

### Hyperparameters

Every hyperparameter is a constructor argument; the defaults are the configuration used in
the paper (about 0.73 M parameters).

| Group | Argument (default) |
|---|---|
| Architecture | `num_stages` (3), `num_feedback` (2), `num_tokens` (8), `hidden_dim` (128), `heads` (4), `num_refractor_subspaces` (4), `use_refractor` (True), `ffn_mult` (4), `activation` ("gelu"; also "relu", "silu", "tanh", "elu", "leaky_relu"), `dropout` (0.1), `attn_dropout` (0.0) |
| Optimisation | `optimizer` ("adamw", "adam", "sgd"), `lr` (1e-3), `weight_decay` (1e-4), `momentum` (0.9, SGD), `batch_size` (128), `grad_clip` (None) |
| Schedule and stopping | `max_epochs` (150), `patience` (20), `min_delta` (1e-6), `scheduler` ("plateau", "cosine", "none"), `lr_patience` (5), `lr_factor` (0.5), `validation_fraction` (0.15) |
| Regression only | `loss` ("mse" or "huber"), `huber_delta` (1.0), `weighting` ("none", "by_hist", "inverse_freq"), `hist_bins` (20), `wmin` (0.2), `wmax` (5.0), `calibrate` (False), `calibration_bins` (60), `calibration_min_bin` (20) |
| Classification only | `class_weight` (None or "balanced") |
| Other | `device` ("auto"), `random_state` (None), `verbose` (0) |

`fit` also accepts `sample_weight` and `validation_data=(X_val, y_val)`. After fitting,
`history_` holds the training and validation loss and the learning rate per epoch.
Because the estimators follow the scikit-learn conventions, hyperparameters can be
searched with `GridSearchCV`, `RandomizedSearchCV` or Optuna.

The defaults were chosen for smooth, low-noise targets such as simulator outputs; for
other data, tune at least `hidden_dim`, `num_tokens`, `lr` and `max_epochs`.

## Optimal SNR of binary black hole signals

```python
import numpy as np
from phasmanet.gw import optimal_snr, chirp_mass, mass_ratio, spins_from_spherical

m1, m2 = np.array([36.0, 10.0]), np.array([29.0, 8.0])     # detector-frame masses, Msun
rho = optimal_snr(
    mchirp=chirp_mass(m1, m2),
    q=mass_ratio(m1, m2),                                    # m_heavy / m_light >= 1
    cos_inclination=np.array([0.3, -0.8]),
    spin1=spins_from_spherical([0.5, 0.1], [0.4, 2.0], [1.0, 3.0]),
    spin2=spins_from_spherical([0.2, 0.0], [1.0, 0.0], [0.0, 0.0]),
    f_plus=np.array([0.4, -0.2]),
    f_cross=np.array([0.1, 0.6]),
    distance=np.array([410.0, 800.0]),                      # luminosity distance, Mpc
)
```

Configuration of the pretrained model: single LIGO-Hanford detector, Advanced LIGO
zero-detuned high-power PSD, IMRPhenomXPHM waveforms, f_low = 10 Hz, SNR averaged over
the coalescence phase. Training covered component masses 3 to 170 Msun (detector frame),
spin magnitudes up to 0.99 and SNR below 200 at 1000 Mpc. The optimal SNR scales exactly
as 1/d_L, which `optimal_snr` applies for the given distance. Inputs outside the training
domain produce a warning. Throughput depends strongly on the hardware: a GPU is
recommended for catalogue-scale evaluations (millions of injections). Antenna patterns `f_plus`, `f_cross` can be computed with
PyCBC, Bilby or LALSuite for any sky position, polarisation and time.

## Reproducing the paper

The training scripts, baselines and diagnostics used in the paper are in the
repository: https://github.com/giannis00/PhasmaNet-SNR

## Citation

If you use PhasmaNet, please cite the paper (see `CITATION.cff`):

> I. Tsioulis, A. Tefas, N. Stergioulas, *ΦasmaNet: A Staged Spectral Token-Refinement
> Architecture for Fast Gravitational-Wave Signal-to-Noise Ratio Prediction*, arXiv (2026).

## License

MIT. See `LICENSE`.
