# Cardiac and neuron comparison: methods and validation

This addition implements a Beeler-Reuter ventricular cell alongside the existing Hodgkin-Huxley neuron. It tests how action-potential duration and recovery change across these model systems and under a reduction of the ventricular slow inward conductance.

## Run locally

From the repository root:

```sh
python3 -m http.server 8765 --bind 127.0.0.1
```

Open `http://127.0.0.1:8765/cardiac.html`. The cardiac page needs HTTP because experiments run in a Web Worker. There is no build step, package installation, backend, or account requirement. Fonts have local fallbacks.

Run the checks:

```sh
node home.test.js
node cardiac.test.js
node electrophysiology.test.js
node orbitals.test.js
node tdse.test.js
node wave2d.test.js
```

Regenerate the experiment results:

```sh
node validation/run-experiments.js
```

## Model provenance and attribution

The cardiac equations and published initial state are adapted from the Physiome Model Repository's **Beeler, Reuter, 1977**, revision `45ac0567d00fa0510830d6e418cbc7d26244c909`, exposure `e/1`:

- Original article: G. W. Beeler and H. Reuter (1977), *Reconstruction of the action potential of ventricular myocardial fibres*, Journal of Physiology 268:177–210. DOI: [10.1113/jphysiol.1977.sp011853](https://doi.org/10.1113/jphysiol.1977.sp011853).
- [Pinned model documentation](https://models.physiomeproject.org/e/1).
- [Generated Python reference](https://models.physiomeproject.org/e/1/beeler_reuter_1977.cellml/@@cellml_codegen/Python/raw), retained unmodified in `beeler-reuter-reference.py`.
- Repository model documentation credits Catherine Lloyd and curation by Penny Noble using Flavio Fenton's implementation as a reference.
- This source is licensed under [Creative Commons Attribution 3.0 Unported](https://creativecommons.org/licenses/by/3.0/). The JavaScript adaptation changes units, numerical singularity handling, solver, and stimulus protocol. This attribution applies to the adapted model and retained reference.

The pinned exposure is older than the repository's latest exposure. It was selected for reproducibility, not as a claim that it is the latest physiological model.

The neuronal equations retain this project's existing Hodgkin-Huxley parameters: Cm=1 µF/cm², gNa=120, gK=36, gL=0.3 mS/cm², ENa=50, EK=−77, EL=−54.4 mV. These are original squid-axon kinetics at 6.3 °C, without temperature scaling. See [Hodgkin and Huxley (1952)](https://doi.org/10.1113/jphysiol.1952.sp004764). The cardiac model uses the published mammalian ventricular kinetics, associated with approximately 37 °C. This is not a temperature-matched comparison or a human-specific model.

## Unit reconciliation

The reference expresses membrane current, conductance, and capacitance per mm². The application multiplies all these area densities by 100 to express them per cm². Thus 0.01 µF/mm² becomes 1 µF/cm², gNa becomes 4 mS/cm², the background sodium conductance becomes 0.003 mS/cm², and gs becomes 0.09 mS/cm². Scaling all numerator currents and capacitance identically preserves dV/dt.

Cai is stored in mM. The reference reversal potential uses `log(Cai * 0.001)` to convert to molar concentration. Its calcium source term `−0.01 * Is_mm2` becomes `−0.0001 * Is_cm2`; the relaxation term is unchanged. The current is labeled “slow inward, primarily calcium” rather than represented as a modern, fully selective L-type calcium-channel model.

The source repository reports a dimensional-consistency warning. This adaptation preserves the source's numerical calcium relation, makes its unit conversions explicit, and checks all eight states against that source. Numerical agreement does not resolve every dimensional annotation in the original CellML or validate the model against new biological data.

## Experimental protocol

- Both models use RK4 with a maximum timestep of 0.01 ms. Steps split at pulse edges and output times. Samples are saved every 0.05 ms.
- Cardiac trials condition the published initial state for 1,000 ms without stimulation. Neuronal trials condition their initial state for 100 ms. Conditioning is repeated from the same state for every trial, with cached identical preparations for efficiency. This is a resting preparation, not a paced steady state.
- S1 begins at 10 ms. S2 begins at 10 ms plus the selected onset-to-onset interval. Pulse widths range from 0.5 to 5 ms. Overlap is rejected.
- Threshold is bracketed by doubling from 1 to at most 100 µA/cm², followed by 15 bisections at the chosen duration and model condition. “Threshold” here means a protocol-specific resting excitation threshold, not rheobase.
- Default S1 and S2 each use twice that threshold. In strength sweeps S1 stays fixed and S2 varies. Every conductance condition recalibrates its threshold.
- A full response must first rearm below −40 mV, then cross −20 mV with intrinsic dV/dt >5 mV/ms and reach at least 0 mV before a later pulse. Intrinsic slope excludes injected current. Onset must occur within 30 ms of the pulse. A second pulse before a distinguishable first response is marked indeterminate.
- This operational criterion excludes passive plateau bumps and some partial regenerative responses. It does not prove an absolute refractory period. No fixed spike-counting dead time is used.
- APD50 and APD90 run from the maximum intrinsic upstroke to the falling crossing of 50% or 90% repolarization toward the pre-pulse voltage. Crossings use linear interpolation. A subsequent pulse before repolarization makes the corresponding APD incomplete. The first peak is measured before the next pulse.
- Interval grid: 2, 4, 6, 8, 10, 12, 15, 20, 30, 50, 75, 100, 150, 200, 225, 250, 275, 300, 325, 350, 400, 500, 600 ms, excluding values smaller than pulse width. Strength grid: 1, 1.5, 2, 3, 4 times threshold.
- The “first successful tested interval” is a grid result. No monotonic recovery or precise boundary is inferred between samples. All outcomes remain available in the table and CSV.
- The cardiac and neuron waveform comparison uses the same observation window. Batch trials use shorter model-appropriate windows to reduce computation; these include the 30 ms response window and cardiac recovery.

## Independent numerical validation

`generate-reference.py` integrates the unmodified generated Python equations with SciPy DOP853, adaptive tolerance rtol=1e−10 and atol=1e−12, maximum step 0.1 ms. It splits at stimulus discontinuities and generates 700 ms traces from published initial conditions for gs scales 1, 0.5, and 0.25, with a 50 µA/cm² stimulus at 10–11 ms.

To rebuild the checked-in fixture, install NumPy and SciPy in a disposable environment, or use:

```sh
UV_CACHE_DIR=/tmp/simulationed-uv-cache uv run --python 3.12 --with numpy --with scipy python validation/generate-reference.py
```

The JavaScript RK4 solution at 0.01 ms agrees with sampled independent reference voltages to better than 0.00004 mV across these conditions. Maximum gate error is below 0.0000031 and calcium error is below 6e−11 mM. Tests enforce looser tolerances to accommodate platform rounding. Removable singularities at −47 and −23 mV are evaluated with analytic limits. Invalid calcium, nonfinite state, or escaped gates stops the cardiac integration instead of silently clamping it.

Additional tests cover:

- Neuronal voltage agreement with immutable pre-refactor traces, across single pulses, paired pulses, and a train. Both the original page wrapper and homepage use the shared implementation.
- Resting state and absence of spontaneous baseline firing.
- APD, peak, threshold, and response convergence at 0.01, 0.005, and 0.0025 ms.
- Early failed and later successful second responses for both models.
- Exclusion of plateau bumps, first-peak contamination, exact reset reproducibility, and overlapping-pulse rejection.
- Supported pulse-duration, stimulus-strength, and conductance corners.
- Monotonic APD shortening across the four selected conductance conditions.

## Export and interpretation

Trace CSV includes model, conductance scale, time, voltage, injected and ionic currents, intrinsic voltage slope, and state variables. The metadata JSON records model revisions, parameters, units, solver, initial state, conditioning, pulse schedule, threshold method, response criteria, detected events, and sweep settings and outcomes. A separate sweep CSV contains every tested result.

Edits to controls do not relabel existing results: the page prompts the user to run again, and exports continue to describe the completed run. Playback changes only which precomputed samples are visible. Sweeps run off the main thread and can be cancelled without replacing the previous completed results.

See `results.json` for reproducible measured results. These are computational results from historical models, not evidence of a newly discovered biological mechanism. Excluded: tissue conduction, ECG generation, contraction, modern calcium cycling, drug binding, patient prediction, and clinical recommendations.


## Measured baseline results

For 1 ms pulses at twice each model's calibrated threshold, with the conditioning described above:

| Measure | Ventricular model | Neuron model |
| --- | ---: | ---: |
| Resting excitation threshold (µA/cm²) | 25.1665 | 6.9214 |
| First peak (mV) | 32.37 | 39.86 |
| APD50 (ms) | 231.07 | 1.40 |
| APD90 (ms) | 288.21 | 2.25 |
| S2 at 50 ms | No full response | Full response |
| First successful tested interval at 2× (ms) | 325 | 15 |

For the ventricular model, APD90 was 288.21, 222.96, 126.59, and 62.86 ms at 100%, 75%, 50%, and 25% slow inward conductance. These selected conditions support the model-level conclusion that reducing this inward current shortens the plateau and action potential. They do not establish a universal monotonic relationship outside the tested settings.

A defensible project description is: “Implemented and numerically validated a ventricular action-potential model, then compared action-potential duration and paired-pulse recovery with a Hodgkin-Huxley neuron using reproducible stimulus protocols.” Numerical findings should be accompanied by the model names and protocol assumptions above.


## Browser verification

Verified in Yab/WebKit: initial load, the 50 ms paired-pulse example, 46-trial interval sweep, the full 230-trial strength map, cancellation with prior results retained, trace play/pause, and all four calcium conditions. Inspected generated CSV and JSON download payloads. Checked the layout in a 390 px iframe viewport, including the waveform and controls, with no horizontal document overflow. The original neuron page still generated a spike after a single pulse. This checks responsive layout; it is not a physical-device or cross-browser certification.
