rexafs 0.2.12

Rust-powered X-ray absorption spectroscopy analysis and EXAFS fitting
Documentation
use super::*;
#[test]
fn references_are_identified_and_out_of_range_is_not_clamped() {
    let db = AtomicData::new().unwrap();
    let curve = db.f2("Cu", &[8978., 8979., 8980.]).unwrap();
    assert_eq!(curve.reference.table, AtomicTable::ChantlerF2LogLogV1);
    assert_eq!(curve.reference.data.data_sha256.len(), 64);
    assert_eq!(db.edge("Cu", "k").unwrap().energy_ev, 8979.);
    for e in [0., -1., f64::NAN, f64::INFINITY, 1e10] {
        assert!(db.f2("Cu", &[e]).is_err());
    }
    for e in [99., 800001., f64::NAN] {
        assert!(db.attenuation("Cu", &[e]).is_err());
    }
    assert!(db.f2("unobtainium", &[1000.]).is_err());
    assert!(db.f2("Cu", &[]).is_err());
    let mut reference = curve.reference;
    db.require_reference(&reference).unwrap();
    reference.data.data_sha256 = "different-data".into();
    assert!(matches!(
        db.require_reference(&reference),
        Err(AtomicDataError::VersionMismatch)
    ));
    assert_eq!(db.identity().data_version, "9.2");
    assert_eq!(
        db.identity().data_sha256,
        "fb29697588bd24ffafac8e2d5bfcf808df9a66b05987ef35b1224d3b8fb7c67e"
    );
}
#[test]
fn formula_retains_mass_fraction_arithmetic_and_rejects_unsupported_notation() {
    let db = AtomicData::new().unwrap();
    let result = db
        .compound_attenuation("Cu2O", &[8000., 9000., 10000.])
        .unwrap();
    assert_eq!(
        result
            .composition
            .iter()
            .map(|c| (&*c.element, c.atoms))
            .collect::<Vec<_>>(),
        vec![("Cu", 2.), ("O", 1.)]
    );
    let sum = result
        .composition
        .iter()
        .map(|c| c.mass_fraction)
        .sum::<f64>();
    assert!((sum - 1.).abs() < 1e-15);
    let cu = db.attenuation("Cu", &result.curve.energy_ev).unwrap();
    let o = db.attenuation("O", &result.curve.energy_ev).unwrap();
    for (i, &v) in result.curve.values.iter().enumerate() {
        assert_eq!(
            v,
            result.composition[0].mass_fraction * cu.values[i]
                + result.composition[1].mass_fraction * o.values[i]
        );
    }
    let nested = db.compound_attenuation("CuSO4(H2O)5", &[10000.]).unwrap();
    assert_eq!(
        nested
            .composition
            .iter()
            .find(|c| c.element == "H")
            .unwrap()
            .atoms,
        10.
    );
    assert_eq!(
        nested
            .composition
            .iter()
            .find(|c| c.element == "O")
            .unwrap()
            .atoms,
        9.
    );
    let fractional = db.compound_attenuation("Fe0.7Mg0.3O", &[10000.]).unwrap();
    assert_eq!(fractional.composition[0].atoms, 0.7);
    for formula in [
        "Cu0O",
        "Cu(OH",
        "Cu[OH]2",
        "CuSO4ยท5H2O",
        "D2O",
        "Cu1e-3O",
        "water",
        "Cu2+",
        "Cu O",
        "()",
        "XxO",
    ] {
        let message = db
            .compound_attenuation(formula, &[10000.])
            .unwrap_err()
            .to_string();
        assert!(message.contains("byte"), "{formula}: {message}");
    }
}
#[test]
fn explicit_line_and_family_have_distinct_retained_members() {
    let db = AtomicData::new().unwrap();
    let individual = db
        .emission("Cu", &EmissionSelection::Line("Ka1".into()))
        .unwrap();
    let family = db
        .emission("Cu", &EmissionSelection::Family("Ka".into()))
        .unwrap();
    assert_eq!(individual.lines.len(), 1);
    assert!(family.lines.len() > 1);
    assert_ne!(individual.energy_ev, family.energy_ev);
    let intensity = family.lines.iter().map(|l| l.intensity).sum::<f64>();
    assert_eq!(
        family.energy_ev,
        family
            .lines
            .iter()
            .map(|l| l.energy_ev * (l.intensity / intensity))
            .sum::<f64>()
    );
    assert!(db
        .emission("Cu", &EmissionSelection::Line("Ka".into()))
        .is_err());
    assert!(db
        .emission("Cu", &EmissionSelection::Family("".into()))
        .is_err());
}