Every component, in Python AND R, runnable on your machine

The lab, downloadable

Each analysis component of this site as a standalone script in both languages — no packages beyond base R and the Python standard library (matplotlib only for the Python plots) — cross-validated against each other and against the browser engine by the site's own test suite.
Download the whole lab — Python + R (ZIP)
Independent · and honestly interdependent

Every script runs alone on a raw completed-test CSV — the shared cores are embedded verbatim in each file, so there are no imports between them and nothing to install. The real contingencies are drawn below, not hidden: the formal models take their RCI-P70 bridge threshold from the RCI component's baseline stage; the shared-Ki comparison is built on the formal trajectory layer; the plots draw what the analyses compute. normalized_assays.csv is the interchange format — every script accepts it in place of raw data, and this website exports the identical file. Each component below ships in both Python and R, and its "what differs" note says exactly where behavior departs from the workflow behind the published catalog — so nothing between the versions is left to guesswork. One rule everywhere: actual sown/tested + germinated counts, never an assumed sample size.

RAW CSV01 normalize→ normalized_assays.csvinterchange file — every script accepts it02 RCI analysisbaselines · intervals · rollup03 formal survivaltrajectories · fits · QCRCI-P70 threshold(--thresholds)04 shared-Ki5 °C vs −18 °C · tiers05 model comparisonAICc workbench (no RCI link)06 plotsdraws 02 + 03 + 0407 run_allchains 01→06 via files
01Python ↓R ↓

Normalize

The shared upload layer: completed-test CSV in, normalized_assays.csv out — counts required, exact time kept, Initial made explicit, protocol keys built, duplicates flagged (never merged).

Writes: normalized_assays.csv
Depends on: Nothing. Every other component builds on this one — its output is the suite's interchange file, and the website exports the identical format.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

None by design: one contract, two languages. Both are cross-validated against each other and the site engine on the verification fixtures by the site's test suite.

vs the workflow behind the catalog

The archival workflow rounded date-derived ages to whole years; here dates become exact elapsed days (a 1,740-day test is 4.76 y, never 5). Legacy storage="Initial" is recognized and mapped to an explicit flag. Protocol keys use trivial case/whitespace normalization only, and a row missing both substrate and treatment is keyed "unspecified" per the current specification. No sample size is ever assumed — percentage-only files are blocked, not padded.

02Python ↓R ↓

RCI analysis

The RCI management analysis: early-window baselines, RCI P70, observed intervals with GLM + Wilson support, Overall observed RCI kept separate from RCI at recommended storage, freeze flags, censoring-honest notation.

Writes: rci_results.csv · rci_accession_intervals.csv
Depends on: Independent (embeds 01). Its baseline stage is the one thing the formal component genuinely depends on.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

None by design. The R script's probit support-CIs come from stats::glm — the same IRLS family the archival workflow used — and agree with the Python and site fits to at least six decimal places on the fixtures.

vs the workflow behind the catalog

Three deliberate departures, all specification-mandated. (1) The baseline is always the highest observed germination in the early 5-year window — the archival snapshot forced the age-0/1 value for accessions with exactly two assay ages; that exception is preserved only in the site's frozen-snapshot regression and is guarded against here by verification fixture 11. (2) Notation keeps fractional precision ("4.8+", not "5+"). (3) Overall observed RCI and observed RCI at recommended storage are separate outputs — the archive published a single interval with storage attribution. Also: CI support is aggregated with a plain any() across accessions; the archival code preserves an any(isTRUE(·)) expression that can silently miss support when several accessions qualify (its own comments mark that as frozen-snapshot compatibility). The −18C-only rule matches the archive: such species record freeze-sensitive = FALSE with an explicit only-−18C reason.

03Python ↓R ↓

Formal survival

Protocol-specific formal survival models: taxon × accession × storage × germination protocol, matched same-protocol Initial at t = 0, Formal / Exploratory / Do-not-interpret / No-fit classes, raw AND display crossings.

Writes: formal_survival_results.csv
Depends on: Embeds 01–02. The RCI-P70 bridge threshold is its real contingency: recomputed internally, or chained explicitly with --thresholds rci_accession_intervals.csv.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

None by design; identical grouping, anchoring, tiers, and QC. Python fits with its own IRLS (validated against R-equivalent references); the R script fits with stats::glm itself.

vs the workflow behind the catalog

Trajectory unit, matched-Initial rule (≤1 y, never borrowed across protocols, late Initials excluded and reported), early-rise and plateau QC, and the bridge-tier classification reproduce the reference. One deliberate difference: on separated or extreme fits the reference falls back to a bias-reduced estimator (brglm2); these scripts and the site flag the fit and downgrade its tier instead of substituting a different estimator — flagged, not faked. Plateau flags are computed, but the reference's plateau-trimmed sensitivity refits are not included.

04Python ↓R ↓

Shared-Ki comparison

Paired 5 °C vs −18 °C: one shared Ki, temperature-specific decline slopes, slope-difference CI/p, LRT, evidence tiers (Primary / Review / Exploratory — different caution types), neutral wording.

Writes: shared_ki_results.csv
Depends on: Embeds 01–03 — pairing and QC flags come from the formal trajectory layer by construction.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

None by design; joint coefficients, slope-difference statistics, and LRTs agree to at least six decimals on the fixtures.

vs the workflow behind the catalog

The joint model, LRT semantics (non-inferential under extreme-fit warnings), tier precedence, and CI-based direction call reproduce the reference exactly. The same no-bias-reduction stance as component 03 applies. Evidence-tier wording follows the current specification (Primary / Review / Exploratory); the reference retained development-era labels. Two audit columns the reference emitted (shifts of the joint fit versus the independent per-temperature fits) are not written — both sides of that subtraction are in this CSV and component 03's.

05Python ↓R ↓

Model comparison

The AICc workbench: Ellis–Roberts, control-viability, resistant-fraction and Avrami fit to every trajectory on the same counts; the data picks the winner, near-ties go to the simpler model.

Writes: model_comparison.csv
Depends on: Embeds 01 + 03's grouping; entirely independent of the RCI component — it answers a different question and overrides nothing.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

None by design; the same coordinate-descent optimizer in both, same winners, same AICc to the fixture tolerance.

vs the workflow behind the catalog

No counterpart exists: the reference workflow fits one model family. This component is a site-native extension for asking which decay shape a trajectory follows, and its result never overrides the observed RCI, the storage recommendation, or the shared-Ki comparison.

06Python ↓R ↓

Plots

The three finalized plot families: RCI management per accession, formal survival per trajectory, shared-Ki per pair — line style encodes evidence tier; uninterpretable comparisons get no fitted curves.

Writes: plots/*.png or *.svg
Depends on: Contingent on 02–04 by construction — it draws their analyses (recomputed internally, so the file still runs alone). Python needs matplotlib; the R script uses base graphics.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

Same plot semantics; different renderers (matplotlib vs base R graphics), so typography and spacing differ. The R script keeps plot text ASCII-safe so it renders identically in any locale.

vs the workflow behind the catalog

Markers, the baseline ring with its source, RCI P70 labeling, plotting-only probit overlays, tier line styles (solid / long-dash / dash), and curve suppression for uninterpretable comparisons follow the finalized plot definitions. The reference plot library skipped accessions with fewer than two non-zero observations; these scripts (like the site) plot every RCI-evaluable accession.

07Python ↓R ↓

Run everything

The orchestrator: normalize → RCI → formal (reusing the RCI thresholds file) → shared-Ki → models → plots, one command, one output folder.

Writes: longevity_lab_output/ with everything above
Depends on: Pure interdependence — calls the sibling scripts and passes files between them. Each sibling still runs alone.
What differs here — Python vs R vs the catalog workflow

Python ↔ R

Identical chains; python run_all.py and Rscript run_all.R produce the same set of CSVs from the same input.

vs the workflow behind the catalog

The reference's master runners orchestrated the full historical archive (provenance, cross-source dedup, master workbook). Those stages are institutional-archive machinery, deliberately out of scope for the public lab.

How faithful are these to the site? The site's test suite assembles these exact files, runs both languages on the handoff's synthetic verification fixtures, and compares every coefficient against the browser engine — Python and R agree with it, and with each other, to better than 10⁻⁵ on every fixture. Where behavior deliberately departs from the archival workflow behind the catalog (the public baseline rule, exact storage time, no bias-reduced fallback on separated fits), each component's "what differs" note above says so explicitly.