Directory structure
This chapter is an inventory: what lives where, and which of it is source, runtime data or legacy. Two of those distinctions matter more than the rest — the repository is not the same thing as a working directory (see How WebDAQ works), and a few paths are still present only so that old links and old setups keep working.
1. Top level
Path |
What it is |
|---|---|
|
The DAQ server: a Flask application served by waitress on port 5001. |
|
The web interface: Next.js 14 on port 3000. |
|
What you run from a shell: |
|
The Sphinx/MyST source of this manual. |
|
A |
|
Screenshots used by the README and the manual. |
|
The conda environment ( |
|
Installation helper: CAEN libraries, the environment, the native modules. |
|
Builds the documentation in CI. |
|
Project readme and licence. |
Two more things may be present without being tracked: manuals/, which holds the CAEN register manuals that app/utils/board_defaults.py cites and is gitignored because the PDFs are large, and CLAUDE.md/AGENTS.md, which are notes for coding agents.
There is no mobile client in this checkout. The React Native app that How WebDAQ works lists as an interface is a separate repository; nothing here builds, serves or configures it. It is a supported interface because it speaks the same JWT-authenticated REST API as the browser, not because its source is here.
2. server/ — the Flask backend
Path |
What it is |
|---|---|
|
The entry point. Refuses a second instance, brings the database schema up to date, writes a pid file, starts the alert watcher and serves the app. |
|
The Flask CLI app object, for management commands such as |
|
Secret keys, the database URL and the JWT policy. |
|
The application package — see below. |
|
Two git submodules: |
|
Alembic revisions for |
|
The server test suite — plain |
|
|
|
Offline analysis notebooks. Not part of the running DAQ. |
|
Runtime state of whichever working directory the server was started in — see section 4. |
server/app/routes/ — the HTTP surface
File |
Serves |
|---|---|
|
Registration, login, and a token check. |
|
Run control, run metadata, boards, data-saving settings, diagnostics, auto-restart, and the legacy Telegram settings. |
|
Board register reads and writes, the board scan, and online tuning. |
|
Spectra, PSD maps, waveforms, the dashboard/ROI configuration, batch ROI integrals, and |
|
The beam-current module: its type, settings, readings, history and accumulated charge. |
|
The Graphite server, the monitored metric list, the per-run |
|
Completed runs: inventory, current log, |
|
PSI ELOG: settings, entries, attributes, attachments and the run draft. |
|
Grafana settings and alert rules. |
|
Notification transports, alert rules, the event log, the alert watcher — and the |
|
Per-channel energy calibration. |
|
Dead code. A Faraday-cup blueprint that |
server/app/services/ — state and background work
File |
Owns |
|---|---|
|
The DAQ state: run number, saving, boards, run-state listeners, board-failure monitoring, auto-restart. |
|
The single in-process |
|
The persistent probe connections to the boards, released to caendaq during a run. |
|
The background sweep of USB, optical and VME links that discovers boards. |
|
What the daisy chain needs per board, read back from the registers. |
|
Online spectra, waveforms and ROI reads, plus the calibration applied to their axes. |
|
The server-owned histogram dashboard in |
|
Every ROI integral in one pass, and the per-run |
|
The Graphite metric list and the loop that writes a run’s |
|
Read-side Graphite access for everything that plots history. |
|
A finished run directory: its files, its current, its charge, and the ROOT conversion. |
|
Keeps each run’s |
|
Assembles a finished run into a draft ELOG entry. |
|
The alert rules, the watcher thread that evaluates them, and the dispatch to transports. |
|
The durable record of every alert and recovery, in |
|
The named recovery actions, whether each is currently needed, and running one on request. |
|
The two notification transports. |
|
Grafana’s alert-rule API, with the service-account token kept on the server. |
|
The PSI ELOG logbook, through py_elog. |
server/app/utils/ — hardware and helpers
File |
What it is |
|---|---|
|
The ctypes wrapper around CAENDigitizer: open, info, register access, register dumps. |
|
Which registers may be written to a board that is acquiring. |
|
Fabricated register dumps so test mode has something to configure and edit. |
|
Builds a ROOT histogram from a caendaq snapshot, on demand. |
|
The two picoammeter controllers. |
|
A beam-current module whose readings come from a monitored Graphite metric. |
|
The simulated picoammeter used when |
|
The Graphite render-API client. |
|
The guarded push to Carbon’s plaintext ingest, so a dead collector cannot stall an acquisition loop. |
|
The guard that stops a second backend reaching into running hardware. |
|
Token issue and the |
app/models/ holds the two SQLAlchemy models, user.py and run_metadata.py.
3. frontend/ — the web interface
Path |
What it is |
|---|---|
|
App Router pages: |
|
Route handlers that run in the Next.js process, not in the browser: |
|
The React components. Dashboards ( |
|
|
|
Zustand stores: auth, run control, histograms, stats, metrics, Grafana alerts, dashboard tab, visualisation settings. |
|
Runtime UI state written by the Next.js process ( |
|
Build and tooling configuration. |
4. The repository versus a working directory
Every relative path the server opens is relative to the directory it was started in, not to server/. conf/, calib/, data/, cache/ and app.db are therefore the state of one experiment, and the copies under server/ are simply the state of the experiment someone last ran from there.
Written into the working directory |
By |
|---|---|
|
The DAQ state: run number, saving, size limits, boards, auto-restart. |
|
One full register dump per board. Copied into each run directory at start. |
|
The histogram dashboard: histograms, ROIs, zooms, layout. |
|
The beam-current module, its per-device settings and the lifetime charge. |
|
The Graphite server, the monitored metrics and the sampling cadence. |
|
The alert rules, and the record of what they did. |
|
Transport credentials. |
|
Grafana and ELOG addresses and service tokens. |
|
Per-channel energy calibration. Not copied into the run directory. |
|
The run: |
|
The backend’s pid, so |
|
Run metadata and users. |
Nothing in this list needs to be created by hand; the server writes a default on first use and keeps an unreadable conf/settings.json aside rather than replacing it.
5. Legacy and dead paths
Each of these looks live until you look twice, so it is named here rather than left for you to find — the usual cost of the ones below is an afternoon spent changing code that nothing calls.
Path |
Status |
|---|---|
|
Never registered as a blueprint. |
|
Outside the App Router and imported by nothing — superseded by |
|
A redirect to |
|
Still works, but no longer in the navigation: the |
|
The dashboard’s old home in |
|
An empty directory no code refers to. |
Earlier releases also had server/json/ (per-model register templates) and conf/topology.xml (the XDAQ topology). Both are gone: a board’s register set is read from the hardware, or fabricated by app/utils/board_defaults.py in test mode, and there is no XDAQ to describe.