Selection-aware calibration of scanned-lag dependence tests between two time series.
Analysts who scan several lags and report the strongest cross-correlation often test that winner as if its lag had been fixed in advance, and often ignore autocorrelation; both inflate false positives. SelCal implements the published remedy (repeat the whole lag search inside every circular-shift surrogate; Cannistra et al., eLife Reviewed Preprint 2025; Yuan & Shou, PLoS Biology 2024) as reusable software, and adds:
- a frozen analysis plan: candidate lags, statistic, selection rule, null model, number of surrogates and alpha are resolved before calibration and stored with every result (this does not show when the analyst first saw the data);
- exact enumeration of the complete circular group (
circular_shift_exact_v1), removing Monte Carlo loss; - an attainable-p guard: in the circular Pearson lag scan, at least L of the n circular states
reach or exceed the observed maximum, so the exact p-value cannot fall below L/n;
selcal validatereports this andselcal runrefuses unattainable exact-enumeration plans; - a three-level preflight separating input validity, plan executability and the scientific assumptions the analyst must justify;
- verifiable, replayable records: one SQLite file with input, plan, full result and software
identity;
selcal verify --replayrecomputes it byte for byte.
SelCal tests one pair of series over a small, pre-declared lag set. It does not perform causal discovery, estimate effect sizes, align or detrend series, or correct across many pairs.
| Command line or Python | Local browser interface (selcal ui) |
|
|---|---|---|
| You provide | Two aligned numeric series (CSV with two columns, or NPZ) and a JSON plan: candidate lags, statistic, selection rule, null model, number of surrogates, alpha, seed | The same two files, chosen in the page; or the included example |
| You get | One SQLite record (input, plan, full result, software identity); an HTML report; an eleven-file evidence folder with summary.csv, candidates.csv and replicates.csv for spreadsheets |
The same three files, downloaded from the page after a size and SHA-256 check |
| Main result | Selected lag, its statistic, exceedance count E over B surrogates, p = (1 + E) / (B + 1), decision at alpha, and the plan's smallest attainable p |
Shown on the page and in the report |
| Typical time | Included example (n = 100, 3 lags, 199 surrogates) on an Apple M4 Pro: validate 0.11 s, run 0.31 s, verify --replay 0.33 s, report 0.13 s, export 0.14 s (median of 3) |
Same computations; one click per step |
How to read the numbers, when a plan is refused and what a non-significant result does and does not mean: Interpreting SelCal results. The browser interface is shown in docs/guide/interface.md.
The source repository is public at https://github.com/lbiceice/selcal-software; the latest
release is tag v0.1.3, archived on Zenodo at the version DOI
https://doi.org/10.5281/zenodo.23448533 (also in CITATION.cff and codemeta.json); the concept DOI
https://doi.org/10.5281/zenodo.23261952 always resolves to the latest version. For day-to-day use without a source checkout, the release carries two
ready-to-run user packages, SelCal_0.1.3_Windows_user_package.zip and
SelCal_0.1.3_macOS_user_package.zip (the same wheel, the NumPy 2.4.6 wheels, an offline
installer, an example runner, the saved-download checker and a one-page guide); their SHA-256
digests are in the release notes. See Install from source. The source route
below uses a fresh virtual environment (standard CPython 3.11-3.13; free-threaded builds are not
supported). The macOS/Linux instructions have local test evidence. Native Windows results are
available for the limited configurations recorded in
docs/guide/development.md; they are not a claim of
compatibility with every Windows installation.
macOS / Linux:
git clone https://github.com/lbiceice/selcal-software.git
cd selcal-software
python3 -m venv .venv
source .venv/bin/activate
python -m pip install .Windows (PowerShell 5.1 or 7; put the folder at a short path such as C:\src\selcal-software):
git clone -c core.autocrlf=false https://github.com/lbiceice/selcal-software.git
cd selcal-software
py -3.12 -m venv .venv
.venv\Scripts\Activate.ps1
python -m pip install .(core.autocrlf=false keeps source-file bytes unchanged; a downloaded source ZIP also works.
If PowerShell blocks activation, no policy change is needed: run
.venv\Scripts\python.exe -m pip install . and use .venv\Scripts\python.exe in place of
python, or .venv\Scripts\python.exe -m selcal in place of selcal below.)
The runtime installation needs Python and NumPy, but no API key, GPU, Java, or paid service. The first installation needs network access unless the dependencies are already cached. The commands below use files in the source folder; keep that folder available after installation.
After installation (check your environment with selcal doctor):
selcal doctor
python scripts/acceptance_check.py
selcal validate examples/workflow/series.csv examples/workflow/pearson.json
selcal run examples/workflow/series.csv examples/workflow/pearson.json run.sqlite --max-bytes 1048576
selcal verify run.sqlite --max-bytes 1048576 --replay
selcal report run.sqlite report.html --max-bytes 1048576selcal doctor saves and reads back a small record in the temporary folder and exits with 4 if
records cannot be used; selcal doctor --folder DIR checks the folder where you will keep records
(for example a synchronised or network folder).
scripts/acceptance_check.py runs the whole workflow on both example plans and checks the results
(selected lag 2; p = 0.015 with 199 sampled surrogates, p = 0.03 with exact enumeration; null
rejected; replay MATCH; the HTML report shows the same values). It prints PASS/FAIL per check and
exits 0 only if everything passed. Open report.html in a browser to read the result.
The exact-enumeration plan of the software paper (Section 3.1) is shipped as
examples/workflow/pearson_exact.json; see the exact-enumeration example.
-
Prepare a UTF-8 CSV with exactly two numeric columns and one header, for example
temperature,cases. Each row must be one aligned observation at the same sampling interval. Resolve missing observations, alignment and preprocessing before using SelCal; it does not silently drop rows, fill gaps, resample or detrend. -
Copy
examples/workflow/pearson.jsontomy-plan.json. Setsource_columntotemperatureandtarget_columntocases(or your actual header names). Choose the lag set, null model and other plan settings before inspecting which result is strongest. Lag units are rows: with monthly data, lag 2 means two months. -
Run
selcal validate my-data.csv my-plan.json. Correct any named input or plan problem first.EXECUTABLEis not evidence that the null-model assumptions hold: review the separatescientific_assumptionsfield. Do not bypass a refusal just to obtain a p-value. -
Run and retain the record, then make a report:
selcal run my-data.csv my-plan.json my-run.sqlite --max-bytes 1048576 selcal verify my-run.sqlite --max-bytes 1048576 --replay selcal report my-run.sqlite my-report.html --max-bytes 1048576
Use new output filenames for another run. An existing-file error protects the previous result;
it is not a reason to delete that record. Exit 7 (NOT_EVALUABLE) means no valid p-value was
computed, not evidence of no relationship. A non-significant valid result also does not prove
absence of a relationship. Reuse across domains requires the same input structure and a
defensible null model, not just renamed columns.
Requirements: Python 3.11 or newer (tested: 3.11-3.13) and NumPy (numpy>=1.26,<2.5). Platform
test rounds, including the native Windows results and what they do not establish, are recorded in
docs/guide/development.md.
- Correctness checks shipped with the source: the product test suite (run it with
uv run --locked --all-extras python -m pytest), the runnable examples inexamples/andscripts/acceptance_check.py, which checks the documented workflow end to end. The test suite includes an internal finite-state algorithm oracle; agreement with it is an algorithm check, not scientific validation. - Records:
selcal verifychecks a saved record;--replayrecomputes it byte for byte in the recording environment, and--replay-decisionacross platforms with the same NumPy. - Statistical operating characteristics: the bounded synthetic studies were executed internally and are reported in the accompanying manuscript; see the evidence boundary below.
This repository holds the software, runnable examples, API documentation, product tests and benchmark fixtures. The protocols (frozen before execution), synthetic inputs, per-run results, comparator logs and test receipts behind the accompanying software paper are archived separately at https://doi.org/10.5281/zenodo.23332143 (CC BY 4.0), with checksums and reproduction notes. Third-party data used in the paper's software example are available from their original deposit and are not redistributed.
| Page | Contents |
|---|---|
| Interpreting results | What the numbers mean, refusals, exit codes, what a result does not show |
| Exact-enumeration example | The software paper's Section 3.1 example, step by step |
| Local interface | The browser interface, with screenshots |
| User reference | File workflow, attainability guard, recovery, interface details, evidence export, input limits, examples, Python API |
| Development and platform record | Locked environment, CI, containers, API reference build, performance, platform test rounds |
| API reference | Build with Sphinx from docs/api (see the development page) |
- Cite the software with
CITATION.cff; it names the Zenodo version DOI of release 0.1.3. The software paper's claims are mapped to tests, examples and archived records indocs/paper/selcal_softwarex_manifest.json. - Licence: BSD 3-Clause (
LICENSE.txt;Licence.txtis an identical copy required by SoftwareX). - Questions and problems: the issue tracker of the public repository, or software support at
vincentdsnail@gmail.com. The author e-mail in
CITATION.cffis the institutional contact.
Version 0.1.3 (tagged v0.1.3 on 2026-10-18, UTC-7) corrects the wording about refused plans in the
guide, the interface, the command-line help and the refusal messages. Version 0.1.2 (2026-10-16)
corrected the scientific-assumption advisory and added the exact-enumeration example and the paper
manifest. The calibration code of both is that of 0.1.1, a bug-fix release (tagged v0.1.1 on 2026-10-12, UTC-7). See CHANGELOG.md.
Version 0.1.0 was the first release: tagged v0.1.0 on 2026-10-09 (UTC-7), published as a
GitHub release on 2026-10-10 (UTC) and archived on Zenodo (DOI in CITATION.cff). Changes made
after a tag are listed under Unreleased in CHANGELOG.md; contribution and maintenance rules
are in CONTRIBUTING.md.
- Scientific evidence. Protocol-frozen synthetic studies and one software example on publicly archived series (records at the DOI above; it does not reproduce the original analysis) describe the operating characteristics under the tested conditions only. Independent users have not yet evaluated the software.
- Interface. The local browser interface covers input, validation, run, resume, record checks, reports, evidence export and checked downloads; it runs the same command-line process and adds no statistical function.
- Long runs. An interrupted run resumes only after the retained surrogates have been recomputed and matched in the same code and environment.
- Platforms. Tested platforms and their limits are listed in docs/guide/development.md.
SelCal is not a causal-edge inference product. Records are terminal results that can be verified and replayed; portable evidence folders can be exported and checked without replay.
