Skip to main content

Positron Annihilation Spectroscopy analysis tools

Project description

SciPAS: Positron Annihilation Spectroscopy in Python

A Python package for Doppler Broadening (DB) and Coincidence Doppler Broadening (CDB) analysis, positron implantation profiling, transport simulation, and variable-energy Doppler broadening (VEDB) diffusion-length fitting.

SciPAS provides a unified, modular workflow — from raw detector data to material parameters — built on standard scientific Python.


Features

  • DB spectrum analysis — S and W parameter extraction with Poisson uncertainty propagation; automatic 511 keV peak identification and axis centralization
  • CDB analysis — 2D coincidence histogram; DB and resolution projections from detector-pair data
  • Event filtering — time and energy coincidence filtering for synchronized detector pairs
  • Implantation profiles — Makhovian and Ghosh positron stopping profiles; multilayer cumulative stitching; support for external (MC-simulated) profiles
  • Positron transport solver — 1D finite-difference solver for the diffusion–drift–annihilation equation with electric fields and radiative boundary conditions
  • Layered sample modelSample / Layer / Material descriptors with depth-dependent diffusion, mobility, and annihilation rates
  • VEDB fitting — diffusion-length optimization with covariance estimation; single- and multi-layer support; weighted nonlinear least squares
  • xarray throughout — labeled, sliceable data with named coordinates
  • Uncertainty propagation via the uncertainties library

Installation

git clone https://github.com/achiyaAmrusi/scipas
cd scipas
pip install .

For a development install (includes test dependencies):

pip install ".[dev]"

The companion spectrum library scispectrum is installed automatically from PyPI.


Quick Start

Doppler Broadening — S and W parameters

import pandas as pd
from scispectrum.core import Spectrum
from scispectrum.calibration import AxisCalibration, ResolutionCalibration
from scipas.core import DB

calib = AxisCalibration(lambda ch: 0.5 * ch + 1.0, name="energy_keV")
res   = ResolutionCalibration(lambda e: 1.8)   # constant FWHM in keV
spec  = Spectrum.from_dataframe(df, channel_col="channel", counts_col="counts",
                                axis_calib=calib, resolution_calib=res)

# Identify the 511 keV peak automatically
db = DB.from_spectrum(spec)

# Extract S and W parameters (energy in keV, relative to 511 keV)
s = db.s_parameter_calculation(energy_domain_total=(-8, 8),
                                energy_domain_s=(-0.8, 0.8))
w = db.w_parameter_calculation(energy_domain_total=(-8, 8),
                                energy_domain_w_left=(-8, -2),
                                energy_domain_w_right=(2, 8))
print(s, w)  # ufloat values with propagated uncertainties

Coincidence Doppler Broadening

from scipas.filter import PasCoincidenceFilter
from scipas.core import CDB

# Step 1: find time-coincident events
pairs = PasCoincidenceFilter.time_coincidence_filter(
    det_1_df, det_2_df, max_time_interval=10)

# Step 2: apply energy-conservation window (keeps E1 + E2 ≈ 1022 keV)
energy_pairs = PasCoincidenceFilter.energy_coincidence_filter(
    pairs,
    axis_calibration_1=calib_1,
    axis_calibration_2=calib_2,
    local_fwhm_1=1.2,
    local_fwhm_2=1.2)

# Step 3: build CDB object (histogram computed once at construction)
cdb = CDB(energy_pairs, energy_min=-4, energy_max=4, mesh_interval=0.05)

db  = cdb.doppler_broadening()   # DB ready for S/W analysis
res = cdb.resolution()           # 1D resolution spectrum

Implantation profiles

import numpy as np
from scipas.transport import makhov_profile, makhov_material_parameters

depth  = np.arange(0, 5000, 1)   # nm
params = makhov_material_parameters()
si     = params[params["Material"] == "Si"].iloc[0]

profile = makhov_profile(positron_energy=10, depth_vector=depth,
                         density=si.density, makhov_parms=si)

Multilayer implantation profile

from scipas.transport import (multilayer_implantation_profile,
                              makhov_profile, makhov_material_parameters)

params = makhov_material_parameters()
cu     = params[params["Material"] == "Cu"].iloc[0]
si     = params[params["Material"] == "Si"].iloc[0]

profile = multilayer_implantation_profile(
    positron_energy=10,
    depth_vector=np.arange(0, 5000, 1),
    widths=[500],                          # 500 nm Cu film on Si substrate
    materials_parameters=[cu, si],
    densities=[cu.density, si.density],
    implantation_profile_function=makhov_profile)

Positron transport — diffusion solver

from scipas.model import Sample, Layer, Material
from scipas.transport import profile_solver

silicon = Material(name="Si", diffusion=1.0, mobility=0.0,
                   bulk_annihilation_rate=2.0)
layer   = Layer(width=10000.0, material=silicon)
sample  = Sample(layers=[layer], absorption_length=0.5)

# Returns xr.DataArray of c(z) on a uniform mesh
positron_profile = profile_solver(implantation_profile, sample)

VEDB diffusion-length fitting

from scipas.analysis import DiffusionLengthOptimization

optimizer = DiffusionLengthOptimization(
    positron_implantation_profiles=profiles,   # list of xr.DataArray, one per energy
    s_measurement=s_series,                    # pd.Series of ufloat
    initial_guess=initial_sample)

best_fit, covariance = optimizer.optimize_diffusion_length(bounds=(0, 1000))
sigma = np.sqrt(np.diag(covariance))
print(f"L+ = {best_fit} ± {sigma} nm")

Examples

Full worked examples are in the examples/ directory:

DB / CDB Analysis

VEDB Analysis

Implantation Profiles and Transport

  • Positron profile in Si — Makhov and Ghosh profiles, multilayer stitching, transport solver, annihilation fractions
  • Transport solver benchmark — validates profile_solver against two analytical results: exact surface fraction formula and closed-form full profile; confirms O(N⁻²) convergence

Requirements

Following the SPEC 0 support policy:

Package Version
Python ≥ 3.11
numpy ≥ 2.0, < 3
pandas ≥ 2.3, < 4
scipy ≥ 1.14
xarray ≥ 2024.6
uncertainties ≥ 3.1
scispectrum ≥ 0.3

Project Status

SciPAS is under active development. The DB/CDB analysis, implantation profiles, diffusion solver, and VEDB fitting are stable. Planned additions include positron lifetime spectrum analysis and extended Bayesian workflows for model comparison and uncertainty quantification.


License

MIT License. See LICENSE for details.


Author

Achiya Yosef Amrusi — GitHub

Contributions and issues are welcome. Please include a minimal reproducible example when reporting a bug.

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

scipas-0.3.0.tar.gz (35.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

scipas-0.3.0-py3-none-any.whl (41.4 kB view details)

Uploaded Python 3

File details

Details for the file scipas-0.3.0.tar.gz.

File metadata

  • Download URL: scipas-0.3.0.tar.gz
  • Upload date:
  • Size: 35.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scipas-0.3.0.tar.gz
Algorithm Hash digest
SHA256 556d1581a878644e0a4c5ec0326e425b5c4d69ab965e267b0285d228e65cfe75
MD5 f7d6a1d095f7e894b3b7cfdbd0f80cca
BLAKE2b-256 b783ef88e7997f2ba52c3e82dd1bd0826655ab10244a097923f5393bbc04e40f

See more details on using hashes here.

Provenance

The following attestation bundles were made for scipas-0.3.0.tar.gz:

Publisher: release.yml on achiyaAmrusi/scipas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file scipas-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: scipas-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 41.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.12

File hashes

Hashes for scipas-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 76666e613dc882eb3a55bf3020ce285794694b5313746e99f85cc66920dbbe45
MD5 a91a140cb45695de9649f22f9d0d0ef0
BLAKE2b-256 dc4bdd5380bab9d4488132c424876b50a9998cf2d9b0c45fb7a546fed20a04ee

See more details on using hashes here.

Provenance

The following attestation bundles were made for scipas-0.3.0-py3-none-any.whl:

Publisher: release.yml on achiyaAmrusi/scipas

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page