use ndarray::{Array1, Array2, Array3, Array4};
use num_complex::Complex64;
use crate::error::{IoError, Result};
pub const PHASE_BIN_DEFAULT_PAD_WIDTH: usize = 8;
pub const PHASE_BIN_SCALARS: usize = 3;
pub const PHASE_BIN_DEFAULT_TRANSITION_COUNT: usize = 8;
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct PhaseBinScalars {
pub average_norman_radius: f64,
pub fermi_level: f64,
pub edge_energy: f64,
}
impl PhaseBinScalars {
#[must_use]
pub fn as_array(self) -> [f64; PHASE_BIN_SCALARS] {
[
self.average_norman_radius,
self.fermi_level,
self.edge_energy,
]
}
pub(super) fn from_slice(values: &[f64]) -> Result<Self> {
if values.len() != PHASE_BIN_SCALARS {
return Err(IoError::PhaseBinShape {
field: "dum",
actual: vec![values.len()],
expected: vec![PHASE_BIN_SCALARS],
});
}
Ok(Self {
average_norman_radius: values[0],
fermi_level: values[1],
edge_energy: values[2],
})
}
}
#[derive(Debug, Clone, PartialEq)]
pub struct PhaseBinPotential {
pub lmax: usize,
pub atomic_number: usize,
pub label: String,
pub phase_shifts: Array3<Complex64>,
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PhaseBinRawPads {
pub scalars: Option<String>,
pub energy_grid: Option<String>,
pub reference_energy: Option<String>,
pub phase_shifts: Vec<Vec<Option<String>>>,
pub transition_moments: Vec<Option<String>>,
}
#[derive(Debug, Clone, PartialEq)]
pub struct PhaseBinData {
pub spin_count: usize,
pub energy_count: usize,
pub main_energy_count: usize,
pub auxiliary_energy_count: usize,
pub ihole: i32,
pub fermi_index: i32,
pub pad_width: usize,
pub final_state_count: usize,
pub transition_count: usize,
pub q_count: usize,
pub scalars: PhaseBinScalars,
pub energy_grid: Array1<Complex64>,
pub reference_energy: Array2<Complex64>,
pub potentials: Vec<PhaseBinPotential>,
pub transition_moments: Array4<Complex64>,
pub raw_pads: Option<PhaseBinRawPads>,
}
impl PhaseBinData {
#[must_use]
pub fn potential_count(&self) -> usize {
self.potentials.len()
}
}
impl PhaseBinData {
pub fn reference_at(&self, energy: usize, spin: usize) -> Option<Complex64> {
self.reference_energy.get((energy, spin)).copied()
}
pub fn transition_at(
&self,
energy: usize,
q: usize,
transition: usize,
spin: usize,
) -> Option<Complex64> {
self.transition_moments
.get((energy, q, transition, spin))
.copied()
}
}