rexafs 0.2.3__tar.gz → 0.2.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {rexafs-0.2.3 → rexafs-0.2.4}/Cargo.lock +10 -10
- {rexafs-0.2.3 → rexafs-0.2.4}/Cargo.toml +2 -2
- {rexafs-0.2.3 → rexafs-0.2.4}/PKG-INFO +6 -2
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/Cargo.toml +2 -1
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/benches/autobk_stage_benchmark.rs +5 -6
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/benches/feff_fitting_batch_benchmark.rs +5 -6
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/benches/perf.rs +2 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/lib.rs +1 -1
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/prelude.rs +1 -1
- rexafs-0.2.4/crates/rexafs/src/xafs/background/legacy_clamp_tests.rs +120 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/background.rs +44 -13
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/background_ndarray.rs +44 -13
- rexafs-0.2.4/crates/rexafs/src/xafs/fft_grid.rs +13 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/mod.rs +1 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xasspectrum.rs +16 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xrayfft.rs +69 -14
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xrayfft_ndarray.rs +42 -7
- rexafs-0.2.4/crates/rexafs/tests/fft_grid.rs +156 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/processing_api.rs +21 -0
- rexafs-0.2.4/crates/rexafs/tests/testfiles/fft_grid_larch_reference.json +1 -0
- {rexafs-0.2.3 → rexafs-0.2.4/py-rexafs}/LICENSE-MIT +1 -1
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/README.md +5 -1
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/python/rexafs/__init__.pyi +3 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/src/lib.rs +27 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/tests/test_api.py +23 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/LICENSE +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/LICENSE-APACHE +0 -0
- {rexafs-0.2.3/crates/rexafs → rexafs-0.2.4}/LICENSE-MIT +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/.gitignore +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/LICENSE-APACHE +0 -0
- {rexafs-0.2.3/py-rexafs → rexafs-0.2.4/crates/rexafs}/LICENSE-MIT +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/README.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/benches/xas_group_benchmark_parallel.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/benches/xas_group_benchmark_single.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/benchmarks/baseline.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ag.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ag.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ag2o.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ag2o.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/al.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/al.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/al2o3_corundum.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/al2o3_corundum.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/aspirin.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/aspirin.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/au.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/au.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/caf2_fluorite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/caf2_fluorite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/catalog.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ceo2.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ceo2.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/co3o4.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/co3o4.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/co_hcp.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/co_hcp.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/coo.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/coo.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cos2_cattierite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cos2_cattierite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cr.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cr.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cr2o3_eskolaite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cr2o3_eskolaite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cu.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cu.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cu2o_cuprite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cu2o_cuprite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cufes2_chalcopyrite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cufes2_chalcopyrite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cuo_tenorite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/cuo_tenorite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fe2o3_hematite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fe2o3_hematite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fe3o4_magnetite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fe3o4_magnetite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fe_bcc.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fe_bcc.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/feo_wustite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/feo_wustite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fes2_pyrite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/fes2_pyrite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ir.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ir.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/licoo2.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/licoo2.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/lifepo4_triphylite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/lifepo4_triphylite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mn2o3_bixbyite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mn2o3_bixbyite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mn_alpha.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mn_alpha.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mno.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mno.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mno2_pyrolusite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mno2_pyrolusite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mo.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mo.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/moo3.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/moo3.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mos2_2h.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/mos2_2h.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nacl_halite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nacl_halite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nb.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nb.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ni.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ni.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nio.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nio.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nis_millerite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/nis_millerite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/os.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/os.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pd.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pd.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pdo.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pdo.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pt.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pt.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pto2_alpha.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/pto2_alpha.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/re.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/re.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/rh.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/rh.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ru_hcp.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ru_hcp.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ruo2.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ruo2.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/sn_beta.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/sn_beta.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/sno2_cassiterite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/sno2_cassiterite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ta.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ta.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ti_hcp.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/ti_hcp.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/tio2_anatase.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/tio2_anatase.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/tio2_rutile.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/tio2_rutile.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/urea.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/urea.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/v.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/v.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/v2o5.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/v2o5.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/w.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/w.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/wo3_monoclinic.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/wo3_monoclinic.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zn.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zn.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zno_wurtzite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zno_wurtzite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zns_sphalerite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zns_sphalerite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zro2_monoclinic.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/data/builtin_cifs/zro2_monoclinic.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/doc/feff-fitting-mvp.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/doc/img/flamegraph_rexafs_analytical_optimization.svg +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/doc/img/flamegraph_rexafs_numerical_optimization.svg +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/doc/img/flamegraph_xraylarch.svg +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/doc/migration-performance-logic-hardening.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/doc/profiling.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/examples/alloc_baseline.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/examples/feff_backend_probe.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/examples/feff_compare_export.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/examples/plot_demo.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/flamegraph.svg +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/pythontest.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/bench_regression_gate.sh +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/build_builtin_library.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/fetch_builtin_cifs.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/generate_element_table.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/generate_larch_fit_references.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/generate_larch_fitspace_references.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/generate_spacegroup_table.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/scripts/generate_structure_fixtures.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/parser/mod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/builder.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/config.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/errors.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/fitting_plots.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/group_plots.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/mod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/panels.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/spectrum_plots.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/plot/traits.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/analysis/lcf.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/analysis/mod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/analysis/pca.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/background/fixed.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/bessel_i0.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/constants.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/errors.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/builder.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/errors.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/expression.pest +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/expression.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/feffdat.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/mod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/path_model.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/runner.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/solver.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/template.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/transform.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/types.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/fitting/variables.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/inverse_fft.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/QAS.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/athena.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/mod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/xafs_bson.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/xafs_json.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/xasdatatype.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/io/xdi.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/lmutils.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/mathutils.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/mathutils_ndarray.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/normalization.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/normalization_ndarray.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/nshare.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/spline.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/builtin.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/builtin_library.json.gz +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/cif.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/cluster.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/db/amcsd.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/db/cod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/db/mp.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/db.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/element.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/element_table.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/feffinp.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/lattice.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/mod.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/model.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/pathrank.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/paths.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/spacegroups.json.gz +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/symmetry.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/structure/xyz.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/tools.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xafsutils.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xafsutils_ndarray.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xasgroup.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/src/xafs/xasparameters.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/supportinginfo/uncertainty.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/supportinginfo/uncertainty.pdf +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/supportinginfo/uncertainty2.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/supportinginfo/uncertainty2.pdf +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/analysis.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/athena_prj.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/feff10_s02k_parity.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/feff_builder_examples.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/feff_larch_fitspace_parity.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/feff_larch_parity.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/inverse_fft.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/.gitignore +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/README.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/generate_spline_reference.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/generate_test.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/pyproject.toml +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/requirements.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/pythonscript/uv.lock +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/refeff_runner.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/structure.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_athena.prj +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_athena_k_chi.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_autobk_bkg_larch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_autobk_k_larch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_pre_post_edge_expected.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_preedge_larch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_smooth.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_smooth_larch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/Ru_QAS_xftf_larch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/amcsd_subset.db +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/athena.chir +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/autobk_fixed_reference.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/fes2_pyrite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/fes2_pyrite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/fes2_pyrite_nosymops.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/fes2_pyrite_p1.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ru_hcp.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ru_hcp.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ru_hcp_nosymops.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ru_hcp_p1.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ruo2_rutile.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ruo2_rutile.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ruo2_rutile_nosymops.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/ruo2_rutile_p1.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/zro2_baddeleyite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/zro2_baddeleyite.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/zro2_baddeleyite_nosymops.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cif/zro2_baddeleyite_p1.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cod_9000594_pyrite.cif +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/cod_result_fes2.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/feff0002.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/feff_ff2chi_larch_ref.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/feff_fit_target_larch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/feff_path_chi_larch_ref.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/feffcu01.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/README.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/cu_fit_kspace.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/cu_fit_qspace.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/cu_fit_rspace.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/fitspace_metadata.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/metadata.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/znse_fit_kspace.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/larch_fit_refs/znse_fit_rspace.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/mp_summary_ru.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/spline_scipy_reference.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/test.bson +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/test.json +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/test.json.gz +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/window_Gaussian.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/window_Hanning.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/window_Kaiser-Bessel.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/window_Parzen.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/window_Sine.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/window_Welch.txt +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/README.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feff8l/Co/feff.inp +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feff8l/FeO_withPb/README +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feff8l/FeO_withPb/feff.inp +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feff8l/MnO2/feff.inp +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0001.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0002.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0003.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0004.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0005.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0006.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0007.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0008.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0009.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0010.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0011.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0012.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_Cu/feff0013.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff.inp +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znas.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znbr.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znga.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znge.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znkr.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znrb.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znse.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/feffit/Feff_ZnSe/feff_znzn.dat +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/xafsdata/cu_150k.xmu +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/xafsdata/ni_metal_rt.xdi +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/crates/rexafs/tests/testfiles/xraylarch_d867/xafsdata/znse_zn_xafs.001 +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/.github/workflows/CI.yml +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/.gitignore +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/Cargo.toml +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/LICENSE-APACHE +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/python/rexafs/__init__.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/python/rexafs/io.py +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/python/rexafs/io.pyi +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/py-rexafs/python/rexafs/py.typed +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/pyproject.toml +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/Cargo.toml +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/LICENSE-APACHE +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/README.rexafs.md +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/src/cursor.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/src/property_test.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/src/sum_tree.rs +0 -0
- {rexafs-0.2.3 → rexafs-0.2.4}/vendor/sum_tree/src/tree_map.rs +0 -0
|
@@ -6887,7 +6887,7 @@ checksum = "d55d956fa96f5ec02be2e13af0e20391a5aa83d6a074e3ad368959d0fab299ea"
|
|
|
6887
6887
|
|
|
6888
6888
|
[[package]]
|
|
6889
6889
|
name = "py-rexafs"
|
|
6890
|
-
version = "0.2.
|
|
6890
|
+
version = "0.2.4"
|
|
6891
6891
|
dependencies = [
|
|
6892
6892
|
"ndarray",
|
|
6893
6893
|
"numpy",
|
|
@@ -7484,7 +7484,7 @@ dependencies = [
|
|
|
7484
7484
|
|
|
7485
7485
|
[[package]]
|
|
7486
7486
|
name = "rexafs"
|
|
7487
|
-
version = "0.2.
|
|
7487
|
+
version = "0.2.4"
|
|
7488
7488
|
dependencies = [
|
|
7489
7489
|
"apex-solver",
|
|
7490
7490
|
"approx",
|
|
@@ -7517,13 +7517,13 @@ dependencies = [
|
|
|
7517
7517
|
"serde",
|
|
7518
7518
|
"serde_json",
|
|
7519
7519
|
"thiserror 2.0.20",
|
|
7520
|
-
"ureq 3.4.
|
|
7520
|
+
"ureq 3.4.1",
|
|
7521
7521
|
"version",
|
|
7522
7522
|
]
|
|
7523
7523
|
|
|
7524
7524
|
[[package]]
|
|
7525
7525
|
name = "rexafs-gui"
|
|
7526
|
-
version = "0.2.
|
|
7526
|
+
version = "0.2.4"
|
|
7527
7527
|
dependencies = [
|
|
7528
7528
|
"accesskit",
|
|
7529
7529
|
"accesskit_macos",
|
|
@@ -7549,7 +7549,7 @@ dependencies = [
|
|
|
7549
7549
|
"serde_json",
|
|
7550
7550
|
"sha2 0.11.0",
|
|
7551
7551
|
"unicode-segmentation",
|
|
7552
|
-
"ureq 3.4.
|
|
7552
|
+
"ureq 3.4.1",
|
|
7553
7553
|
"walkdir",
|
|
7554
7554
|
"windows 0.62.2",
|
|
7555
7555
|
"xraydb",
|
|
@@ -7557,7 +7557,7 @@ dependencies = [
|
|
|
7557
7557
|
|
|
7558
7558
|
[[package]]
|
|
7559
7559
|
name = "rexafs-wasm"
|
|
7560
|
-
version = "0.2.
|
|
7560
|
+
version = "0.2.4"
|
|
7561
7561
|
dependencies = [
|
|
7562
7562
|
"js-sys",
|
|
7563
7563
|
"rexafs",
|
|
@@ -9730,9 +9730,9 @@ dependencies = [
|
|
|
9730
9730
|
|
|
9731
9731
|
[[package]]
|
|
9732
9732
|
name = "ureq"
|
|
9733
|
-
version = "3.4.
|
|
9733
|
+
version = "3.4.1"
|
|
9734
9734
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9735
|
-
checksum = "
|
|
9735
|
+
checksum = "af5546be8f5378d5414f83733f5c9a2526f4645829edbc1c41790aeef1b38e8b"
|
|
9736
9736
|
dependencies = [
|
|
9737
9737
|
"base64 0.23.1",
|
|
9738
9738
|
"cookie_store",
|
|
@@ -9750,9 +9750,9 @@ dependencies = [
|
|
|
9750
9750
|
|
|
9751
9751
|
[[package]]
|
|
9752
9752
|
name = "ureq-proto"
|
|
9753
|
-
version = "0.6.
|
|
9753
|
+
version = "0.6.2"
|
|
9754
9754
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
9755
|
-
checksum = "
|
|
9755
|
+
checksum = "fabc3e92916c89c95b20eef7b06b00b066bc217ef9ea3a4ac9bf1a7e35261e10"
|
|
9756
9756
|
dependencies = [
|
|
9757
9757
|
"base64 0.23.1",
|
|
9758
9758
|
"http",
|
|
@@ -10,7 +10,7 @@ exclude = [
|
|
|
10
10
|
]
|
|
11
11
|
|
|
12
12
|
[workspace.package]
|
|
13
|
-
version = "0.2.
|
|
13
|
+
version = "0.2.4"
|
|
14
14
|
edition = "2021"
|
|
15
15
|
rust-version = "1.98"
|
|
16
16
|
authors = ["Ameyanagi <contact@ameyanagi.com>"]
|
|
@@ -62,7 +62,7 @@ ruviz-gpui = { version = "0.14.1", features = ["gpu", "3d"] }
|
|
|
62
62
|
refeff = { version = "0.3.0", default-features = false, features = ["exafs"] }
|
|
63
63
|
feff10 = { version = "0.2.3", features = ["prebuilt"] }
|
|
64
64
|
|
|
65
|
-
rexafs = { version = "0.2.
|
|
65
|
+
rexafs = { version = "0.2.4", path = "crates/rexafs" }
|
|
66
66
|
|
|
67
67
|
[patch.crates-io]
|
|
68
68
|
gpui = { git = "https://github.com/zed-industries/zed", rev = "3060e4170ea5ef0e6886b9ac1853aaead9ddd59f" }
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: rexafs
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Classifier: Programming Language :: Rust
|
|
5
5
|
Classifier: Programming Language :: Python :: 3
|
|
6
6
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
@@ -62,7 +62,7 @@ still unimplemented placeholders; selecting them raises an error.
|
|
|
62
62
|
|
|
63
63
|
## Build
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
Build from the repository root with CPython
|
|
66
66
|
3.10–3.14:
|
|
67
67
|
|
|
68
68
|
```bash
|
|
@@ -80,3 +80,7 @@ is `clamp_lo = 0`, the high-end weight is `clamp_hi = 1`, and `nclamp = 3`.
|
|
|
80
80
|
The `FixedPenalty` model does not add a separate ridge penalty on coefficients.
|
|
81
81
|
See the [full definition](../doc/autobk-fixed-penalty.md).
|
|
82
82
|
|
|
83
|
+
`XrayFFTF.grid` defaults to `"Input"`. Set it to `"Larch"` to resample on the
|
|
84
|
+
extended FFT window grid used by XrayLarch. `Spectrum.kwin_k()` and `.kwin()`
|
|
85
|
+
return the matching window axis and values. See [compatibility and migration](../doc/fft-grid-compatibility.md).
|
|
86
|
+
|
|
@@ -61,9 +61,10 @@ http = ["dep:ureq"]
|
|
|
61
61
|
materials-project = ["http"]
|
|
62
62
|
cod = ["http"]
|
|
63
63
|
|
|
64
|
-
[dev-dependencies]
|
|
64
|
+
[target.'cfg(unix)'.dev-dependencies]
|
|
65
65
|
pprof = { version = "0.15", features = ["flamegraph"] }
|
|
66
66
|
|
|
67
|
+
[dev-dependencies]
|
|
67
68
|
criterion = { version = "0.8.2", features = ["html_reports"] }
|
|
68
69
|
|
|
69
70
|
[[bench]]
|
|
@@ -3,6 +3,7 @@ mod perf;
|
|
|
3
3
|
use criterion::{criterion_group, criterion_main, Criterion};
|
|
4
4
|
use std::hint::black_box;
|
|
5
5
|
|
|
6
|
+
#[cfg(unix)]
|
|
6
7
|
use perf::FlamegraphProfiler;
|
|
7
8
|
use rexafs::xafs::background::{AUTOBKClampScalePolicy, AUTOBKSolver, AUTOBK};
|
|
8
9
|
use rexafs::xafs::normalization::{NormalizationMethod, PrePostEdge};
|
|
@@ -73,13 +74,11 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|
|
73
74
|
|
|
74
75
|
fn custom() -> Criterion {
|
|
75
76
|
let base = Criterion::default().sample_size(20);
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
base.with_profiler(FlamegraphProfiler::new(1000))
|
|
80
|
-
} else {
|
|
81
|
-
base
|
|
77
|
+
#[cfg(unix)]
|
|
78
|
+
if std::env::args().any(|arg| arg == "--profile-time" || arg.starts_with("--profile-time=")) {
|
|
79
|
+
return base.with_profiler(FlamegraphProfiler::new(1000));
|
|
82
80
|
}
|
|
81
|
+
base
|
|
83
82
|
}
|
|
84
83
|
|
|
85
84
|
criterion_group! {
|
|
@@ -2,6 +2,7 @@ mod perf;
|
|
|
2
2
|
|
|
3
3
|
use criterion::{criterion_group, criterion_main, Criterion, Throughput};
|
|
4
4
|
use nalgebra::DVector;
|
|
5
|
+
#[cfg(unix)]
|
|
5
6
|
use perf::FlamegraphProfiler;
|
|
6
7
|
use rexafs::xafs::fitting::{
|
|
7
8
|
feffit_independent, feffit_joint_with_options, feffpath, ff2chi, FeffBatchOptions,
|
|
@@ -160,13 +161,11 @@ fn criterion_benchmark(c: &mut Criterion) {
|
|
|
160
161
|
|
|
161
162
|
fn custom() -> Criterion {
|
|
162
163
|
let base = Criterion::default().sample_size(10);
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
base.with_profiler(FlamegraphProfiler::new(1000))
|
|
167
|
-
} else {
|
|
168
|
-
base
|
|
164
|
+
#[cfg(unix)]
|
|
165
|
+
if std::env::args().any(|arg| arg == "--profile-time" || arg.starts_with("--profile-time=")) {
|
|
166
|
+
return base.with_profiler(FlamegraphProfiler::new(1000));
|
|
169
167
|
}
|
|
168
|
+
base
|
|
170
169
|
}
|
|
171
170
|
|
|
172
171
|
criterion_group! {
|
|
@@ -14,5 +14,5 @@ pub use xafs::background::{BackgroundMethod, AUTOBK};
|
|
|
14
14
|
pub use xafs::normalization::{NormalizationMethod, PrePostEdge};
|
|
15
15
|
pub use xafs::xasgroup::XASGroup as Group;
|
|
16
16
|
pub use xafs::xasspectrum::XASSpectrum as Spectrum;
|
|
17
|
-
pub use xafs::xrayfft::XrayFFTF;
|
|
17
|
+
pub use xafs::xrayfft::{FFTGrid, XrayFFTF};
|
|
18
18
|
pub use xafs::{analysis, fitting, io, structure, tools, Result, XAFSError as Error};
|
|
@@ -20,7 +20,7 @@ pub use crate::xafs::normalization::{Normalization, NormalizationMethod};
|
|
|
20
20
|
#[cfg(feature = "ndarray-compat")]
|
|
21
21
|
pub use crate::xafs::nshare::{ToNalgebra, ToNdarray1};
|
|
22
22
|
pub use crate::xafs::xafsutils::{FTWindow, XAFSUtils};
|
|
23
|
-
pub use crate::xafs::xrayfft::{FFTUtils, XrayFFTF, XrayFFTR};
|
|
23
|
+
pub use crate::xafs::xrayfft::{FFTGrid, FFTUtils, XrayFFTF, XrayFFTR};
|
|
24
24
|
|
|
25
25
|
#[cfg(feature = "plotting")]
|
|
26
26
|
pub use crate::plot::{PlotError, PlotXAS, XASPlotBuilder};
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
//! Regression for issue #20. This exercises the legacy objective independently
|
|
2
|
+
//! of the fixed-penalty solver, for both array backends.
|
|
3
|
+
use super::*;
|
|
4
|
+
|
|
5
|
+
fn problem() -> AUTOBKSpline {
|
|
6
|
+
let x: Vec<f64> = (0..9).map(|i| i as f64 * 1.5).collect();
|
|
7
|
+
let y: Vec<f64> = x.iter().map(|v| 1.0 + 0.03 * v.cos()).collect();
|
|
8
|
+
let (knots, coefs) = spline::interpolate(&x, &y, 3).unwrap();
|
|
9
|
+
let k = DVector::from_iterator(241, (0..241).map(|i| i as f64 * 0.05));
|
|
10
|
+
AUTOBKSpline {
|
|
11
|
+
coefs: DVector::from_vec(coefs),
|
|
12
|
+
knots: DVector::from_vec(knots),
|
|
13
|
+
kraw: k.clone(),
|
|
14
|
+
kout: k.clone(),
|
|
15
|
+
mu: k.map(|v| 1.0 + 0.1 * (2.0 * v).sin()),
|
|
16
|
+
chi_std: Some(k.map(|v| 0.01 * v.cos())),
|
|
17
|
+
ftwin: k,
|
|
18
|
+
nclamp: 3,
|
|
19
|
+
clamp_lo: 2,
|
|
20
|
+
clamp_hi: 1,
|
|
21
|
+
irbkg: 35,
|
|
22
|
+
..Default::default()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
fn numerical_jacobian(p: &AUTOBKSpline, scale: Option<f64>) -> DMatrix<f64> {
|
|
27
|
+
DMatrix::from_columns(
|
|
28
|
+
&(0..p.coefs.len())
|
|
29
|
+
.map(|j| {
|
|
30
|
+
let mut plus = p.coefs.clone();
|
|
31
|
+
let mut minus = p.coefs.clone();
|
|
32
|
+
plus[j] += 1e-6;
|
|
33
|
+
minus[j] -= 1e-6;
|
|
34
|
+
(p.residual_vec_with_scale(&plus, scale) - p.residual_vec_with_scale(&minus, scale))
|
|
35
|
+
/ 2e-6
|
|
36
|
+
})
|
|
37
|
+
.collect::<Vec<_>>(),
|
|
38
|
+
)
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
#[test]
|
|
42
|
+
fn legacy_clamp_jacobian_matches_central_differences() {
|
|
43
|
+
for nclamp in [0, 1, 3, 500] {
|
|
44
|
+
for weights in [(0, 0), (0, 1), (2, 0), (2, 3)] {
|
|
45
|
+
for irbkg in [0, 35] {
|
|
46
|
+
let mut p = problem();
|
|
47
|
+
p.nclamp = nclamp;
|
|
48
|
+
(p.clamp_lo, p.clamp_hi) = weights;
|
|
49
|
+
p.irbkg = irbkg;
|
|
50
|
+
#[cfg(not(feature = "ndarray-compat"))]
|
|
51
|
+
if nclamp == 3 {
|
|
52
|
+
p.ensure_precomputed_basis();
|
|
53
|
+
}
|
|
54
|
+
for scale in [None, Some(1.7)] {
|
|
55
|
+
let analytic = p.residual_jacobian_with_scale(&p.coefs, scale);
|
|
56
|
+
let numeric = numerical_jacobian(&p, scale);
|
|
57
|
+
let error = (&analytic - &numeric).norm() / numeric.norm().max(1.0);
|
|
58
|
+
assert!(
|
|
59
|
+
error < 1e-7,
|
|
60
|
+
"n={nclamp}, weights={weights:?}, R={irbkg}, scale={scale:?}: {error}"
|
|
61
|
+
);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
#[derive(Clone)]
|
|
69
|
+
struct NumericProblem(AUTOBKSpline, bool);
|
|
70
|
+
impl LeastSquaresProblem<f64, Dyn, Dyn> for NumericProblem {
|
|
71
|
+
type ParameterStorage = Owned<f64, Dyn>;
|
|
72
|
+
type ResidualStorage = Owned<f64, Dyn>;
|
|
73
|
+
type JacobianStorage = Owned<f64, Dyn, Dyn>;
|
|
74
|
+
fn set_params(&mut self, p: &DVector<f64>) {
|
|
75
|
+
self.0.coefs.copy_from(p);
|
|
76
|
+
}
|
|
77
|
+
fn params(&self) -> DVector<f64> {
|
|
78
|
+
self.0.coefs.clone()
|
|
79
|
+
}
|
|
80
|
+
fn residuals(&self) -> Option<DVector<f64>> {
|
|
81
|
+
Some(self.0.residual_vec(&self.0.coefs))
|
|
82
|
+
}
|
|
83
|
+
fn jacobian(&self) -> Option<DMatrix<f64>> {
|
|
84
|
+
if self.1 {
|
|
85
|
+
Some(self.0.residual_jacobian_with_scale(
|
|
86
|
+
&self.0.coefs,
|
|
87
|
+
Some(self.0.clamp_scale(&self.0.coefs)),
|
|
88
|
+
))
|
|
89
|
+
} else {
|
|
90
|
+
Some(numerical_jacobian(&self.0, None))
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
#[test]
|
|
96
|
+
fn legacy_lm_agrees_with_numerical_derivative_solution() {
|
|
97
|
+
let solver = LevenbergMarquardt::new()
|
|
98
|
+
.with_tol(1e-10)
|
|
99
|
+
.with_patience(1000);
|
|
100
|
+
let (analytic, report) = solver.minimize(problem());
|
|
101
|
+
let (numeric, reference) = solver.minimize(NumericProblem(problem(), false));
|
|
102
|
+
let (old, old_report) = solver.minimize(NumericProblem(problem(), true));
|
|
103
|
+
let old_chi = old.0.chi_for_coefs(&old.0.coefs);
|
|
104
|
+
let new_chi = analytic.chi_for_coefs(&analytic.coefs);
|
|
105
|
+
println!("analytic: {report:?}; numerical: {reference:?}; omitted-chain-rule: {old_report:?}; old/new chi relative L2: {}", (&old_chi - &new_chi).norm()/new_chi.norm());
|
|
106
|
+
assert!(report.termination.was_successful());
|
|
107
|
+
assert!(reference.termination.was_successful());
|
|
108
|
+
let a = analytic.chi_for_coefs(&analytic.coefs);
|
|
109
|
+
let n = numeric.0.chi_for_coefs(&numeric.0.coefs);
|
|
110
|
+
let error = (&a - &n).norm() / n.norm();
|
|
111
|
+
assert!(error < 1e-6, "chi relative L2: {error}");
|
|
112
|
+
assert!((report.objective_function - reference.objective_function).abs() < 1e-10);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
#[test]
|
|
116
|
+
fn legacy_lm_does_not_return_nonfinite_fit_as_success() {
|
|
117
|
+
let mut invalid = problem();
|
|
118
|
+
invalid.mu[0] = f64::NAN;
|
|
119
|
+
assert!(AUTOBK::solve_lm_problem(invalid).is_err());
|
|
120
|
+
}
|
|
@@ -442,13 +442,20 @@ impl AUTOBK {
|
|
|
442
442
|
}
|
|
443
443
|
|
|
444
444
|
fn solve_lm_problem(problem: AUTOBKSpline) -> Result<AUTOBKSpline, BackgroundError> {
|
|
445
|
-
let (fit_result,
|
|
445
|
+
let (fit_result, report) = LevenbergMarquardt::new()
|
|
446
446
|
.with_gtol(1.0e-5)
|
|
447
447
|
.with_ftol(1.0e-5)
|
|
448
448
|
.with_xtol(1.0e-5)
|
|
449
449
|
.with_stepbound(1.0e-5)
|
|
450
450
|
.minimize(problem);
|
|
451
|
-
|
|
451
|
+
if !report.termination.was_successful() || !report.objective_function.is_finite() {
|
|
452
|
+
return Err(BackgroundError::OptimizationFailed {
|
|
453
|
+
reason: format!(
|
|
454
|
+
"legacy LM terminated with {:?} after {} evaluations",
|
|
455
|
+
report.termination, report.number_of_evaluations
|
|
456
|
+
),
|
|
457
|
+
});
|
|
458
|
+
}
|
|
452
459
|
Ok(fit_result)
|
|
453
460
|
}
|
|
454
461
|
|
|
@@ -1215,11 +1222,24 @@ impl AUTOBKSpline {
|
|
|
1215
1222
|
coefs: &DVector<f64>,
|
|
1216
1223
|
clamp_scale_override: Option<f64>,
|
|
1217
1224
|
) -> DMatrix<f64> {
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
|
|
1221
|
-
|
|
1222
|
-
|
|
1225
|
+
// For a dynamic clamp s(c) * chi(c), include both terms of the
|
|
1226
|
+
// product rule. A frozen scale is used by the linear solver and has
|
|
1227
|
+
// zero derivative. Compute the shared residual only once per Jacobian.
|
|
1228
|
+
let dynamic =
|
|
1229
|
+
(self.clamp_len(self.kout.len()) > 0 && clamp_scale_override.is_none()).then(|| {
|
|
1230
|
+
let chi = self.chi_for_coefs(coefs);
|
|
1231
|
+
let head = self.fft_residual_head(&chi);
|
|
1232
|
+
(chi, head)
|
|
1233
|
+
});
|
|
1234
|
+
let scale = clamp_scale_override.unwrap_or_else(|| {
|
|
1235
|
+
dynamic.as_ref().map_or(1.0, |(_, head)| {
|
|
1236
|
+
if head.is_empty() {
|
|
1237
|
+
1.0
|
|
1238
|
+
} else {
|
|
1239
|
+
1.0 + 100.0 * head.norm_squared() / head.len() as f64
|
|
1240
|
+
}
|
|
1241
|
+
})
|
|
1242
|
+
});
|
|
1223
1243
|
|
|
1224
1244
|
// `splev_jacobian` reads `coefs` only for its length (it sizes the
|
|
1225
1245
|
// output and bounds-checks the write); every entry comes from
|
|
@@ -1262,13 +1282,20 @@ impl AUTOBKSpline {
|
|
|
1262
1282
|
return out;
|
|
1263
1283
|
}
|
|
1264
1284
|
|
|
1265
|
-
let
|
|
1285
|
+
let scale_der = dynamic.as_ref().map_or(0.0, |(_, head)| {
|
|
1286
|
+
if head.is_empty() {
|
|
1287
|
+
0.0
|
|
1288
|
+
} else {
|
|
1289
|
+
200.0 * head.dot(&out) / head.len() as f64
|
|
1290
|
+
}
|
|
1291
|
+
});
|
|
1266
1292
|
let high_start = chi_der.len() - nclamp - 1;
|
|
1267
|
-
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1271
|
-
|
|
1293
|
+
for (start, weight) in [(0, self.clamp_lo), (high_start, self.clamp_hi)] {
|
|
1294
|
+
out.extend((start..start + nclamp).map(|i| {
|
|
1295
|
+
let chi = dynamic.as_ref().map_or(0.0, |(chi, _)| chi[i]);
|
|
1296
|
+
weight as f64 * (scale * chi_der[i] + scale_der * chi)
|
|
1297
|
+
}));
|
|
1298
|
+
}
|
|
1272
1299
|
out
|
|
1273
1300
|
})
|
|
1274
1301
|
.collect::<Vec<DVector<f64>>>();
|
|
@@ -2035,3 +2062,7 @@ mod tests {
|
|
|
2035
2062
|
Ok(())
|
|
2036
2063
|
}
|
|
2037
2064
|
}
|
|
2065
|
+
|
|
2066
|
+
#[cfg(test)]
|
|
2067
|
+
#[path = "background/legacy_clamp_tests.rs"]
|
|
2068
|
+
mod legacy_clamp_tests;
|
|
@@ -446,13 +446,20 @@ impl AUTOBK {
|
|
|
446
446
|
}
|
|
447
447
|
|
|
448
448
|
fn solve_lm_problem(problem: AUTOBKSpline) -> Result<AUTOBKSpline, BackgroundError> {
|
|
449
|
-
let (fit_result,
|
|
449
|
+
let (fit_result, report) = LevenbergMarquardt::new()
|
|
450
450
|
.with_gtol(1.0e-5)
|
|
451
451
|
.with_ftol(1.0e-5)
|
|
452
452
|
.with_xtol(1.0e-5)
|
|
453
453
|
.with_stepbound(1.0e-5)
|
|
454
454
|
.minimize(problem);
|
|
455
|
-
|
|
455
|
+
if !report.termination.was_successful() || !report.objective_function.is_finite() {
|
|
456
|
+
return Err(BackgroundError::OptimizationFailed {
|
|
457
|
+
reason: format!(
|
|
458
|
+
"legacy LM terminated with {:?} after {} evaluations",
|
|
459
|
+
report.termination, report.number_of_evaluations
|
|
460
|
+
),
|
|
461
|
+
});
|
|
462
|
+
}
|
|
456
463
|
Ok(fit_result)
|
|
457
464
|
}
|
|
458
465
|
|
|
@@ -1155,11 +1162,24 @@ impl AUTOBKSpline {
|
|
|
1155
1162
|
coefs: &DVector<f64>,
|
|
1156
1163
|
clamp_scale_override: Option<f64>,
|
|
1157
1164
|
) -> DMatrix<f64> {
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1165
|
+
// For a dynamic clamp s(c) * chi(c), include both terms of the
|
|
1166
|
+
// product rule. A frozen scale is used by the linear solver and has
|
|
1167
|
+
// zero derivative. Compute the shared residual only once per Jacobian.
|
|
1168
|
+
let dynamic =
|
|
1169
|
+
(self.clamp_len(self.kout.len()) > 0 && clamp_scale_override.is_none()).then(|| {
|
|
1170
|
+
let chi = self.chi_for_coefs(coefs);
|
|
1171
|
+
let head = self.fft_residual_head(&chi);
|
|
1172
|
+
(chi, head)
|
|
1173
|
+
});
|
|
1174
|
+
let scale = clamp_scale_override.unwrap_or_else(|| {
|
|
1175
|
+
dynamic.as_ref().map_or(1.0, |(_, head)| {
|
|
1176
|
+
if head.is_empty() {
|
|
1177
|
+
1.0
|
|
1178
|
+
} else {
|
|
1179
|
+
1.0 + 100.0 * head.norm_squared() / head.len() as f64
|
|
1180
|
+
}
|
|
1181
|
+
})
|
|
1182
|
+
});
|
|
1163
1183
|
|
|
1164
1184
|
let spline_jacobian = -splev_jacobian(
|
|
1165
1185
|
self.knots.data.as_vec().clone(),
|
|
@@ -1187,13 +1207,20 @@ impl AUTOBKSpline {
|
|
|
1187
1207
|
return out;
|
|
1188
1208
|
}
|
|
1189
1209
|
|
|
1190
|
-
let
|
|
1210
|
+
let scale_der = dynamic.as_ref().map_or(0.0, |(_, head)| {
|
|
1211
|
+
if head.is_empty() {
|
|
1212
|
+
0.0
|
|
1213
|
+
} else {
|
|
1214
|
+
200.0 * head.dot(&out) / head.len() as f64
|
|
1215
|
+
}
|
|
1216
|
+
});
|
|
1191
1217
|
let high_start = chi_der.len() - nclamp - 1;
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1218
|
+
for (start, weight) in [(0, self.clamp_lo), (high_start, self.clamp_hi)] {
|
|
1219
|
+
out.extend((start..start + nclamp).map(|i| {
|
|
1220
|
+
let chi = dynamic.as_ref().map_or(0.0, |(chi, _)| chi[i]);
|
|
1221
|
+
weight as f64 * (scale * chi_der[i] + scale_der * chi)
|
|
1222
|
+
}));
|
|
1223
|
+
}
|
|
1197
1224
|
out
|
|
1198
1225
|
})
|
|
1199
1226
|
.collect::<Vec<DVector<f64>>>();
|
|
@@ -1907,3 +1934,7 @@ mod tests {
|
|
|
1907
1934
|
Ok(())
|
|
1908
1935
|
}
|
|
1909
1936
|
}
|
|
1937
|
+
|
|
1938
|
+
#[cfg(test)]
|
|
1939
|
+
#[path = "background/legacy_clamp_tests.rs"]
|
|
1940
|
+
mod legacy_clamp_tests;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
use serde::{Deserialize, Serialize};
|
|
2
|
+
|
|
3
|
+
/// Forward-transform sampling and window domain. The default backend retains
|
|
4
|
+
/// `Input`; the optional ndarray backend retains its extended `Larch` grid.
|
|
5
|
+
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
|
6
|
+
pub enum FFTGrid {
|
|
7
|
+
/// Weight/window the supplied grid without resampling (historical default).
|
|
8
|
+
#[default]
|
|
9
|
+
Input,
|
|
10
|
+
/// Resample from k=0, extend the window through kmax+dk2, then truncate
|
|
11
|
+
/// the weighted chi and window to the measured range, as in Larch.
|
|
12
|
+
Larch,
|
|
13
|
+
}
|
|
@@ -1006,6 +1006,22 @@ impl XASSpectrum {
|
|
|
1006
1006
|
}
|
|
1007
1007
|
}
|
|
1008
1008
|
|
|
1009
|
+
/// Wavenumbers for `kwin()`. In Larch mode these follow the resampled
|
|
1010
|
+
/// FFT grid, which can differ from the background's `k()` spacing.
|
|
1011
|
+
pub fn kwin_k(&self) -> Option<DVector<f64>> {
|
|
1012
|
+
let ft = self.xftf.as_ref()?;
|
|
1013
|
+
let len = ft.get_kwin()?.len();
|
|
1014
|
+
if ft.grid == super::xrayfft::FFTGrid::Larch {
|
|
1015
|
+
let step = *ft.get_kstep()?;
|
|
1016
|
+
Some(DVector::from_iterator(
|
|
1017
|
+
len,
|
|
1018
|
+
(0..len).map(|i| i as f64 * step),
|
|
1019
|
+
))
|
|
1020
|
+
} else {
|
|
1021
|
+
Some(DVector::from_column_slice(self.k()?))
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1009
1025
|
pub fn kwin(&self) -> Option<DVector<f64>> {
|
|
1010
1026
|
#[cfg(feature = "ndarray-compat")]
|
|
1011
1027
|
{
|