Part of #118 (dedx_extra.c migration) · Phase E. Depends on Phase C/D and a stoichiometry decision (below).
Problem
To evaluate a user-defined compound, dedx_web builds a dedx_config by hand in wasm/dedx_extra.c (dedx_internal_setup_custom_compound / _cleanup): allocate elements_id[] / elements_atoms[], set rho and optional i_value, set ion_a, then load/evaluate/free. The forward table, inverse STP/CSDA, and Bragg-peak for custom compounds are all flat wrappers around that. None of this is public libdedx API, so every binding re-implements the dedx_config plumbing (and can get the lifecycle/free wrong).
Proposed change
- Promote a public config-builder + matching teardown to
dedx.h:
int dedx_config_set_compound(dedx_config *cfg, int program, int ion,
const int *elements_z, const double *elements_atoms,
int n_elements, double density, double i_value, int *err);
void dedx_config_free_compound(dedx_config *cfg, int *err);
- Add flat one-call wrappers to
dedx_wrappers.h: forward STP+CSDA table, inverse STP, inverse CSDA, Bragg-peak STP — each taking the compound spec directly.
Open decision — fractional stoichiometry
dedx_config.elements_atoms is currently int. The web wrapper accepts double atom counts and lround()s them (rejecting ≤0), which loses precision for non-integer formulas (e.g. H2.5O). Phase E is the moment to decide whether libdedx should accept fractional stoichiometry or mass fractions natively. This also intersects #6 (per-element I-value override) — decide whether the public builder takes per-element I-values.
Acceptance criteria
Reference
dedx_web wasm/dedx_extra.c (lines ~463–808); recent custom-compound fixes #105, #107.
Filed via Claude Code as part of the dedx_extra.c → libdedx migration plan.
Part of #118 (dedx_extra.c migration) · Phase E. Depends on Phase C/D and a stoichiometry decision (below).
Problem
To evaluate a user-defined compound, dedx_web builds a
dedx_configby hand inwasm/dedx_extra.c(dedx_internal_setup_custom_compound/_cleanup): allocateelements_id[]/elements_atoms[], setrhoand optionali_value, setion_a, then load/evaluate/free. The forward table, inverse STP/CSDA, and Bragg-peak for custom compounds are all flat wrappers around that. None of this is public libdedx API, so every binding re-implements thededx_configplumbing (and can get the lifecycle/freewrong).Proposed change
dedx.h:dedx_wrappers.h: forward STP+CSDA table, inverse STP, inverse CSDA, Bragg-peak STP — each taking the compound spec directly.Open decision — fractional stoichiometry
dedx_config.elements_atomsis currentlyint. The web wrapper acceptsdoubleatom counts andlround()s them (rejecting ≤0), which loses precision for non-integer formulas (e.g.H2.5O). Phase E is the moment to decide whether libdedx should accept fractional stoichiometry or mass fractions natively. This also intersects #6 (per-element I-value override) — decide whether the public builder takes per-element I-values.Acceptance criteria
dedx_config_set_compound/dedx_config_free_compoundindedx.h, documented, with the int-vs-fractional decision recorded.dedx_wrappers.h(forward / inverse STP / inverse CSDA / Bragg-peak).examples/dedx_custom_compound.c; no leaks under the existing Valgrind CI.wasm/dedx_extra.cand updateswasm/contract-manifest.json+docs/06-wasm-api-contract.md. At this pointdedx_extra.cis empty/removed.Reference
dedx_web
wasm/dedx_extra.c(lines ~463–808); recent custom-compound fixes #105, #107.Filed via Claude Code as part of the
dedx_extra.c→ libdedx migration plan.