尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
個人 GitHub 帳號下公開儲存庫的擁有者可以登入並驗證所有權,自行管理介紹,無需管理員核准。
登入並產生驗證檔案,在 30 分鐘內將其提交至此儲存庫的預設分支。其他分支或分叉儲存庫中的檔案無效。然後在下方檢查檔案,即可無需管理員核准直接管理專案。請保留檔案以維持管理權限。
如需登入,將前往登入頁面。登入後請回到此處,再次點擊所選的驗證按鈕。
在專案資料夾中執行 /nomorevibe verify,即可驗證所有權並自行管理介紹。
一分鐘完成驗證VoltEPIC — Explainable Prediction of Individual Concentrations: an analysis site for square-wave voltammograms (ENG Peak Deconvolution · Team 2)
翻譯準備中
取自儲存庫 README
正在載入完整 README。
檢視完整 README ↗An analysis site that reads a square-wave voltammogram and decides, for each of four biomarkers — ascorbic acid (AA), serotonin (5-HT), estradiol (2E) and melatonin (Mela) — whether it is present, and shows why. The detection model runs entirely in the browser; nothing is uploaded anywhere, unless you ask the assistant for a chemist report (below).
Live: https://eng-peak-deconvolution-team2.github.io/voltepic/
ENG Peak Deconvolution project · Team 2 (machine learning) · work package 6, web interface.
The model behind it today is a detector: it says whether each analyte is present, not how much. Concentration estimates are the part of the name a regression model will fill in.
| Page | What it is |
|---|---|
index.html — Overview | Live readout cycling through held-out curves, key numbers, the pipeline computed on a real curve, where the model looks |
app.html — Analyzer | A sticky instrument (chart + four verdict cards) beside a live report that drives the chart as you scroll: 01 Measurement · 02 Preprocess · 03 Detect · 04 Explain. Library sheet with thumbnails, drag-and-drop upload anywhere, slide-over assistant, deep links #s=<index>, #s=random, #upload, #ask |
method.html — Method | Scroll-driven walk-through: raw scan → wavelet denoising → seven bands → 228 z-scores → 4 × 300 trees building the log-odds → threshold, recomputed for the chosen example curve |
explainability.html — Explainability | The WP5 XAI results: four methods, five tests (verdict matrix), PFI of this model against the E3 peak windows, the edge-coefficient finding recomputed from the filters, and what the analyzer shows as a result |
data.html — Dataset | Source, acquisition, the 1,239-curve cohort, the two coatings, the split, the held-out library and a gallery of all 125 curves |
model.html — Model card | Recipe, held-out results and the browser ↔ Python reference check computed live, limits, reproduction |
about.html — About | The ENG project, its work packages, Team 2 |
Everywhere: light and dark themes (follows the system, remembers a choice), a command palette
(Ctrl/⌘ K or /) over pages, actions and all 125 curves, responsive down to 390 px.
The analysis assistant answers quick questions by rules from the current analysis, and writes a chemist report with the lab's language model on request (next section).
Chosen from the ENG WP5 XAI run by what landed on the peaks in its tests:
data/kimyager.json, 20,000 coalitions); other widths come from the XAI run (xai.json).assets/js/engine/shap.js, 20 mV, 20,000 coalitions, about 4–6 s) and the blank fill R2 is offered.The assistant has two modes, switched in its header: Quick (answers composed by rules) and Lab LLM. In Lab LLM mode
Write the chemist report turns the current result into a 3–5 sentence report in plain English: what the model said,
whether its basis is chemically sound, anything suspicious, what to check in the lab. Follow-up questions are answered
(1–4 sentences) from the same evidence file, with the report as context. It is the pipeline of
literature/xai_llm_rag/kimyager_raporu/rapor.py, ported to the browser and to English; the language model only writes,
everything it may say is computed first:
assets/js/llm/kanit.js, degerlendir) — code sets one label per decision from the XAI tests
(strong, moderate, weak, suspect, sound, not shown; güçlü … gösterilemedi in rapor.py): do SHAP and occlusion
against the blank point to the same 20 mV slice, does it fall in the analyte's peak window and among the model's PFI
top 3, is it a scan edge, is the decision near the threshold, does the blank itself get the same decision. The model
never sets a label.kanitDosyasi, then assets/js/llm/evidence_en.js) — about 93 records in six branches: the
decisions with their labels and reasons, the regions both explanations point to toward and against each decision (top
3 and top 2 slices), where the model generally looks (PFI, SAGE), the expected peak windows, the peaks seen in the
curve, check suggestions and general notes. It is computed in Turkish exactly as rapor.py does, then translated rule by
rule: every text in it comes from a fixed set of templates, and a key or text without a rule stops the report instead
of reaching the model in Turkish. Library curves use data/kimyager.json (rapor.py's explanations, exported by
tools/export_kimyager.py); uploads need a blank and the coating (01 · Measurement; the coating is read from the chip
name when it is a known training chip). The file name, the raw curve and the blank curve are not sent.assets/js/llm/relay.js → worker/ → relay/server.mjs) — the browser leaves the evidence file in
VoltEPIC's mailbox, a Cloudflare Worker at the address in SERVER (relay.js), and asks for the answer every 3 s.
The mailbox checks that the request is the analyzer's (origin, evidence-file shape, short texts, a Cloudflare Turnstile
token, 4 requests a minute per IP, at most 6 waiting, one report an hour for the whole site with up to 5 follow-up
calls on it) and keeps it in a Durable Object. The report server, a Node
script on the project's lab PC, collects requests over outbound HTTPS with a secret (PC_SECRET), at most 2 at once;
it builds the message with the same check.js code and the system prompt of data/chemist_prompts.json, asks the
AI-LAB model (local-llm, OpenAI-compatible, lab network only) with reasoning_effort: xhigh, streamed, and leaves
the answer in the mailbox. Nothing connects to the PC: no port is opened and no tunnel runs. No key is in the site;
the lab key stays on the PC. While the PC is off, the mailbox tells the site the report server is offline;
relay/switch.ps1 turns it on or off. A visitor who stops asking for 60 s has left, and the lab call is stopped.
Every page carries a Content-Security-Policy: scripts only from the site and Turnstile, connections only to the site
and the mailbox. Measured on this report
(): xhigh 3.3–10.6 min a report;
on the 7 inputs where Gemini 3.8 Flash made no wrong claim, 3 of 7 Turkish outputs had one. In English
(, the same 7 inputs, read by one non-blind reader): 7/7 passed the check
on the first attempt, 1 of 7 had a wrong claim (a decision tied to one method's second slice), reports 2.5–5.5 min.node tools/evidence_en_check.mjs every Turkish evidence file at hand translates, keeps its numbers, leaves no Turkish
node tools/check_en_test.mjs each English check rule on a text written to trip it, and a clean report
node tools/kimyager_parity.mjs [--shap]
Last run of the first two (2026-10-28): 130/130 evidence files (125 library curves + the five 2026-10-21 examples)
translated with identical numbers and no Turkish left; 13/13 check cases. The third compares the Turkish evidence file,
the labels, the check and the messages with rapor.py. Its fixture
(tools/fixtures/kimyager_parity.json, written by export_kimyager.py --fixture) holds unpublished LLM outputs and is
not part of this repository. Last run (2026-10-21): evidence file identical JSON text on 125/125 library curves, basis
labels 125/125, check findings identical on 170/170 texts (the runs' real reports and altered copies), report and question
messages identical. --shap: the browser's KernelSHAP (its own sampler) against Python's on 5 curves — 4.1–4.3 s each,
max |Δ| 0.17–0.27 against a largest |φ| of 3.3–5.4, the same basis labels on 5/5. In the browser (headless Edge,
2026-10-21): library curve 12 report and one question with Gemini 3.8 Flash, both passed the check; an MC333 upload with
three blanks (a chip the model was not trained on), blank SHAP in 4–6 s, also with the page in a background tab, and its
report passed the check on the first attempt, flagging the ascorbic acid decision (wrong by the file's composition) as
weak. Measured on the report task with rapor.py: Gemini 3.8 Flash 7/7 texts passed the
check and made no wrong claim (literature/xai_llm_rag/kimyager_raporu/kosu_gemini_2026-10-21/). The earlier packet
pipeline (v0.3) is archived in literature/xai_llm_rag/prototip/site_paket_v03_2026-10-21/.
.txt
export (both working electrodes are offered when present). Curves are linearly resampled to the
model grid: 200 points, 0.004–0.800 V, 4 mV steps.The model has only seen ACS-ML-Biomarker chips (P4VP or PVDF coating, CHI760F, SWV 25 mV, 5 Hz). For curves recorded under other conditions its probabilities are not calibrated, and it cannot tell.
LightGBM, one binary classifier per analyte (learning rate 0.10, 31 leaves, 300 trees), on the full
rbio1.3 level-6 DWT of the sym4-denoised raw curve, trained with augmentation poly16_smix1_d5_x20
on 1,114 curves (seed 0 outer-training partition). Thresholds: MaxSSS (Youden) cut on the real
training rows. It is the model explained in the project's XAI work package (ENG/xai/recipe.py).
assets/js/engine/ reimplements PyWavelets (wavedec/waverec, symmetric mode) and LightGBM tree
traversal in plain JavaScript; trees, filters, scaler and thresholds come from data/model.json.
node tools/parity.mjs
compares every stage against the Python outputs in tools/fixtures/parity.json for all 125 library
curves. Last run: max |Δ features| 2.7e-15, max |Δ probability| 8.7e-19, 0 of 500 decisions differ.
The analyzer and the model card repeat the decision check on every load.
*.html one file per page; <pd-nav>/<pd-footer> come from assets/js/shell.js
assets/css/site.css design system: tokens (light/dark), type, layout, components
assets/css/pages.css home, method, explainability; page-*.css for dataset, model card, about
assets/css/analyzer.css the analyzer
assets/js/shell.js theme before first paint, nav and footer
assets/js/site.js theme toggle, scroll reveals, command palette
assets/js/data.js analyte identities, cached loaders, library records
assets/js/viz.js SVG chart kit for the editorial pages
assets/js/chart.js analyzer charts (voltammogram with crosshair, coefficients, strip, heat map)
assets/js/app/ analyzer: main.js (state, run, instrument), report.js (four sections)
assets/js/pages/ one module per page
assets/js/io.js CSV / CHI parsing and resampling
assets/js/assistant.js assistant: scripted answers + the Gemini report
assets/js/llm/ chemist report: kanit (labels, evidence file, Turkish as rapor.py), evidence_en (English evidence file),
check (English check, messages), denetim (rapor.py's Turkish check), relay (mailbox), report
worker/ Cloudflare Worker: the mailbox between the site and the lab PC (README there)
assets/js/engine/ wavelet transform, model, occlusion, KernelSHAP (shap.js)
data/model.json exported model
data/library.json held-out curves, metadata, mean blanks, Python reference scores
data/xai.json XAI run results for this model: per-curve SHAP (R2), PFI, E3 windows, test numbers
data/kimyager.json chemist report: per library curve SHAP / occlusion against the blank, the blank, model-level notes
data/chemist_prompts.json chemist report system prompts in English (report, question), used by the report server
data/kimyager_istem.json rapor.py's Turkish system prompts (report, question), for the parity test
tools/export_model.py regenerates model.json / library.json from the research workspace
tools/export_xai.py regenerates xai.json; checks that the run's rows and model are the site's
tools/parity.mjs JS ↔ Python parity test
tools/export_kimyager.py regenerates kimyager.json / kimyager_istem.json (+ --fixture: tools/fixtures/kimyager_parity.json)
tools/kimyager_parity.mjs chemist report ↔ rapor.py parity test
tools/evidence_en_check.mjs English evidence file: every Turkish file translates, same numbers, no Turkish left
tools/check_en_test.mjs English check: each rule on a text written to trip it
relay/server.mjs the report server on the lab PC: collects requests from the mailbox (relay/switch.ps1 turns it on or off)
No build step: any static server works (python -m http.server), and GitHub Pages serves main.
Fonts: Geist, Geist Mono and Instrument Serif from Google Fonts.
Curves: ML-Biomarker-Sensing — Duesselberg A. L. M., Weber I. C., Zosso Y., Salah P., Bao Z., Machine Learning-Driven Multiplexed Biomarker Detection with Polymer-Enhanced Electrochemical Sensors, ACS Electrochemistry 2 (2026) 1444–1452, doi:10.1021/acselectrochem.6c00079. Source repository github.com/esemsc-ald24/ML-Biomarker-Sensing, MIT licence.
literature/xai_llm_rag/kimyager_raporu/yerel_llm_deney_sonuclari_2026-10-22.md…/ingilizce_deney_sonuclari_2026-10-28.mdassets/js/llm/check.js) — the 8 rules of rapor.py's check (denetim.js, Turkish), written for English:
sentence count and length, technical terms, record IDs, numbers not in the evidence file, "peak is here" claims,
contradicted decisions, scan-edge regions, first person. With findings, the model gets one rewrite with them; what is
left is listed under the text. The report bubble also shows the basis labels and the full evidence file sent.