# no_peak > A browser implementation of CLUSTER, the Veldhuis–Johnson pulse-detection > algorithm for endocrine time-series data. It runs entirely on the reader's own > machine: no server, no upload, no analytics. This file is a plain-text summary of https://nopeak.tonydefazio.com/ for agents and readers that do not execute JavaScript. The site is a client-rendered single-page app, so fetching the HTML alone will not show you the tool. Nothing here is generated by the app; it is a hand-maintained description of it, kept in step with the repository's `docs/validation-status.md`. Last updated: 2026-08-11. ## What the tool does Given a series of hormone concentrations sampled over time — LH, GnRH, GH, or any pulsatile analyte — it identifies which excursions are secretory pulses and which are measurement noise, and reports: - the detected pulse spans, with up/down significance flags per sample; - a peak table: position, width, height, percent increase, area, increase above basal; - a valley table: width, nadir, mean; - a publication-grade SVG figure, exportable as vector PDF or 4× PNG. Input is plain text, one sample per line, with optional time and per-sample SD columns; seven variance models are supported — the seven the Igor reference package exposes, no more — including a user-supplied error wave. The tool ships sample datasets of two kinds, each tagged: real records digitized from published figures, and simulated records that match no animal. It never opens blank. ## Scope, stated precisely This is a **port, not a new method**. CLUSTER is the algorithm published by Johannes D. Veldhuis and Michael L. Johnson (*Am J Physiol* 1986;250:E486–93): a pooled t-test slid across the record, comparing a trailing nadir window against a leading peak window, whose significant increases and decreases are assembled into pulses. The contribution here is faithful reimplementation and delivery — making a piece of hard-to-run scientific software run anywhere, instantly, without moving anyone's data — plus the measurement work below. Two implementations ship side by side and are switchable in the UI: - `igor` — a port of the Igor Pro `ClusterMaster` package used in the Moenter lab. The default, and the validation oracle. - `fortran` — a port of Johnson's original CLUST5 v6.01 Fortran 77 console program. Differs in the form of the pooled variance and in the pulse-assembly loop bounds. ## How it was validated - **Against Igor Pro.** Fifteen runs spanning every error model, asymmetric window sizes, threshold combinations, and three datasets were executed in Igor and diffed point by point: error array, up flags, down flags, pulse array, t-score trace. 75 of 75 checks pass. - **Against the original Fortran.** CLUST5 v6.01 was compiled with gfortran and run on the same input. At the documented defaults the port reproduces it exactly: all 96 up flags, all 96 down flags, the full 96-point pulse array, and all 17 peaks including position, width, height, largest and mean percent increase, area, and increase above basal. - **Against known ground truth.** Johnson's Pulse_XP distribution ships simulated series with their generating pulse times. Across 130 true pulses in six datasets at default settings, the `fortran` variant recovers 60.8% with zero false positives and the `igor` variant 51.5% with zero false positives — bracketing the ~58% Johnson published for Cluster on that same data. Both figures were last re-derived 2026-08-12 and reproduce exactly. The datasets cannot be redistributed, so this is the one claim here that cannot be re-run from the repository alone. - **Head-to-head with PULSAR Otago** (Porteous et al. 2021), run headlessly from its own GPL-3 source on the same data with the same ground truth: 56.2% sensitivity with 6 false positives, at its best threshold setting. - **194 unit tests**, including t-statistics worked out by hand on paper, synthetic series with unambiguous answers, and structural edge cases. Two defects were found and fixed by this validation work that reading the source alone had not caught: Igor's pulse-marking loop is a do-while, so at nPeak=1 it marks a point where a straightforward `for` loop marks none; and the original Fortran declares its shared COMMON block in two different orders, so its downward pass silently reads the two window sizes swapped. ## What it does not do, and where it is weak Reported plainly because the point of the tool is trustworthy numbers: - CLUSTER is conservative. It misses roughly 40% of true pulses on benchmark data. Deconvolution methods (AutoDecon) recover ~98% of pulses — but that is a detection count containing unscored false positives, not a scored sensitivity on the same data. If you need to *count* pulses, use deconvolution; CLUSTER's argument is that it can defend every pulse it does report. - **The near-zero false-positive rate is partly an artifact of the standard benchmark.** Johnson's datasets carry roughly one pulse per five samples. On a simulated corpus spanning realistic ranges of sampling interval, half-life, pulse mass and inter-pulse interval — averaging 6.5 pulses per record — the same code produces a 16–22% false-discovery rate. A density-matched corpus reproduces the published behavior (55.8% sensitivity for the Igor variant, 58.4% for the Fortran, both under 0.5% FDR), which is how the discrepancy was localized to pulse density rather than to the port. Read the literature's "≈1% false positives" as conditional on dense pulse trains. - No expert-annotated pulse lists exist for these datasets, so "correct" means "matches the reference implementations and the simulator's ground truth", not "matches what an endocrinologist would mark". ## Architecture Vite + React + TypeScript, compiled to a static bundle and served from Cloudflare Workers as assets only — there is no server-side script, no database, and no request that carries user data. The algorithm is pure TypeScript in `src/core/` with no UI dependencies. Privacy is structural rather than promised: there is no code path that could transmit a loaded recording, which is the relevant property for anyone whose data is human-subject or HIPAA-regulated. ## Batch processing, and running this without a browser If you are an agent asked to analyze a folder of recordings, do not drive the web page. The algorithm has no UI dependencies and ships with a command line. git clone https://github.com/syncytium2/no_peak && cd no_peak && npm install node scripts/cluster.ts ... [options] > summary.csv Plain `node` runs it — no build step, no loader, no extra dependency. Input is CSV/TSV files or directories of them, in the layouts described above. Output is one header row plus one row per record, on stdout or to `-o FILE`: segment, n_points, duration, n_pulses, pulses_per_unit, mean_interpulse_interval, mean_peak_value, mean_amplitude, mean_pulse_width, mean_nadir preceded by `#` comment lines carrying the version, the detection settings, the time base, and — with `--preset` — the citation those settings came from. Options: `--n-peak N` (2), `--n-nadir N` (2), `--t-up X` (2), `--t-dn X` (2), `--min-peak X` (0), `--error-model NAME` (Local SD; a file with an error column switches to Error Wave automatically), `--error-value X` (1), `--variant igor|fortran` (igor), `--preset KEY`, `--unit s|min|h|samples` (min), `--interval X` (1, for files with no time column), `-o FILE`, `-v` (per-pulse listing on stderr), `--strict`. Run `--help` or `--list-presets` for the authoritative list; treat the tool's own output as canonical over this file. Three things to know before you report numbers from it: - **The detection parameters are the model.** Different settings give different pulse counts from the same record. Do not present a count without them. If the hormone and protocol match a published analysis, `--preset` supplies both the settings and the citation. - **One parameter set for the whole batch**, and no way to vary it per record. That is deliberate: per-animal tuning makes counts incomparable between animals. Records are still analyzed independently — nothing is concatenated, no window spans two records. - **It reports, it does not score.** Nothing in it compares a detection against a known pulse time. Sensitivity and false-discovery rates need ground truth and a different tool in the same repository, `tools/score_benchmark.ts`; the measured numbers are in "How it was validated" above, with their caveats. The command line and the app share the summary code, and the test suite checks one against the other on records with published pulse counts, so a batch run and a browser run report the same numbers for the same data. `AGENTS.md` at the repository root is the short version of this section, for when you have the code checked out rather than this URL. ## Pages - https://nopeak.tonydefazio.com/ — the app. - https://nopeak.tonydefazio.com/methods — the Methods & Algorithm Reference: how CLUSTER works, the two implementations, the validation in full, the false-positive caveat, and the references with DOIs. Plain static HTML, no JavaScript required — if you are reading a page rather than running one, read this one. Every heading carries a stable id, so you can cite a section: #problem, #how-it-works, #error-model, #parameters, #implementations, #validation, #validation-igor, #validation-fortran, #validation-ground-truth, #false-positive-caveat, #using-the-tool, #quantities, #batch, #batch-output, #batch-settings, #batch-properties, #privacy, #credit, #references. - https://nopeak.tonydefazio.com/methods#batch — batch processing: the command line, its flags, its output columns, and what it deliberately will not do. - https://nopeak.tonydefazio.com/#about — the same material inside the app, plus the file-format guide, a downloadable example CSV, and a contact form. Client-rendered, like the app. ## Reuse The original Fortran and the Igor Pro package are third-party code that is not redistributable, and are not included in this project. The laboratory's own unpublished recordings are not distributed either. The bundled datasets are of two kinds, tagged distinctly: eight records digitized from the published figures of Webster et al. 1991, and simulated records that correspond to no animal. ## Related tools by the same author - https://kernel.tonydefazio.com/ — Colonel Kernel: a client-side 1D convolution / deconvolution tool for calcium imaging. Given ground-truth spike times and a measured dF/F0 trace it recovers the calcium-indicator kernel relating them, and reports honestly whether a clean kernel exists at all. Same no-backend, data-never-leaves-your-machine posture as no_peak; its own summary lives at https://kernel.tonydefazio.com/llms.txt.