use feffit::xasdata::{
ColumnFile, FtParams, MuSpec, XasGroup, autobk_group, build_mu, normalize, xftf_group,
};
use feffit::xasproc::{AutobkParams, PreEdgeParams};
const CU_XMU: &str = include_str!("data/cu.xmu");
fn cu_group() -> XasGroup {
let cf = ColumnFile::from_text(CU_XMU).expect("parse cu.xmu");
let (energy, mu) = build_mu(&cf, &MuSpec::Raw { energy: 0, mu: 1 }).unwrap();
XasGroup::from_mu("cu", energy, mu)
}
#[test]
fn normalize_fills_edge_and_norm() {
let mut g = cu_group();
let params = PreEdgeParams::default();
normalize(&mut g, ¶ms);
let e0 = g.e0.expect("e0");
assert!(
(8960.0..9000.0).contains(&e0),
"Cu K edge e0 should be ~8979 eV, got {e0}"
);
assert!(g.edge_step.unwrap() > 0.0, "edge step must be positive");
let norm = g.norm.as_ref().unwrap();
assert_eq!(norm.len(), g.energy.len());
let (mut sum, mut cnt) = (0.0_f64, 0usize);
for (e, n) in g.energy.iter().zip(norm) {
if *e >= e0 + 50.0 && *e <= e0 + 400.0 {
sum += *n;
cnt += 1;
}
}
let mean = sum / cnt.max(1) as f64;
assert!(
cnt > 0 && (0.7..1.3).contains(&mean),
"post-edge mean normalized mu should be ~1, got {mean:.3} over {cnt} pts"
);
let direct = feffit::xasproc::pre_edge(&g.energy, &g.mu, ¶ms);
assert_eq!(g.norm.as_ref().unwrap(), &direct.norm);
assert_eq!(g.flat.as_ref().unwrap(), &direct.flat);
assert_eq!(g.dmude.as_ref().unwrap(), &direct.dmude);
assert_eq!(g.e0, Some(direct.e0));
assert_eq!(g.edge_step, Some(direct.edge_step));
}
#[test]
fn autobk_then_xftf_gives_cu_first_shell_peak() {
let mut g = cu_group();
normalize(&mut g, &PreEdgeParams::default());
autobk_group(&mut g, &AutobkParams::default(), 1.0);
let k = g.k.as_ref().expect("k grid");
let chi = g.chi.as_ref().expect("chi");
assert_eq!(k.len(), chi.len());
assert!(k.len() > 100, "expected a populated k grid");
assert!(g.bkg.as_ref().unwrap().len() == g.energy.len());
assert!(
g.delta_chi.as_ref().is_some_and(|d| d.len() == k.len()),
"uncertainty band delta_chi should be filled and k-length"
);
let did = xftf_group(
&mut g,
&FtParams {
kmin: 2.0,
kmax: 15.0,
kweight: 2,
..FtParams::default()
},
);
assert!(did, "xftf should run once k/chi exist");
let r = g.r.as_ref().unwrap();
let mag = g.chir_mag.as_ref().unwrap();
assert_eq!(r.len(), mag.len());
let (imax, _) = mag
.iter()
.enumerate()
.max_by(|a, b| a.1.partial_cmp(b.1).unwrap())
.unwrap();
let r_peak = r[imax];
assert!(
(1.8..2.8).contains(&r_peak),
"Cu first-shell |chi(R)| peak should be ~2.2–2.5 Å, got {r_peak:.3} Å"
);
}