radiens_qc.compare
Cross-session comparative quality report.
Aggregates the per-recording report folders written by
:func:~radiens_qc.persist.save_report into a single comparison across
sessions -- how do my recordings compare over time and across the probe? It
answers four questions:
- Longitudinal trend -- is the prep maturing or the probe degrading as the experiment progresses (median SNR / noise floor / event rate / good-channel yield vs. time, each on its own panel)?
- Channel consistency -- which electrodes are persistently dead/noisy (hardware) versus which whole sessions dip (prep/handling)?
- Session leaderboard -- which recordings are the keepers (ranked grade + quality breakdown)?
- Metric distributions -- how do per-channel SNR / noise / event-rate spreads and outliers compare between sessions, not just their medians?
Built entirely from saved report folders -- no KPI recomputation and no live
server connection. That is also why this module reads folders rather than
:class:~radiens_qc.report.QualityReport objects: the folder format is the
contract, so a comparison can span reports produced by different runs, machines,
or versions.
Not re-exported from the package root; import it explicitly::
from radiens_qc.compare import ComparativeReport, load_session_summaries
Classes
ComparativeReport
dataclass
A cross-session comparison over a set of per-recording summaries.
Attributes:
| Name | Type | Description |
|---|---|---|
sessions |
list[SessionSummary]
|
Sessions included in the comparison, chronologically sorted. |
primary_metric |
str
|
Metric driving the trend/heatmap/leaderboard panels. |
noise_metric |
str
|
Metric treated as the noise floor. |
activity_metric |
str
|
Metric treated as the activity/event-rate trend. |
dropped |
list[str]
|
|
Attributes
probe_group
property
Sessions sharing the most common probe set (for the channel heatmap).
Methods:
from_summaries
classmethod
from_summaries(
summaries,
*,
primary_metric=PRIMARY_METRIC,
noise_metric=NOISE_METRIC,
activity_metric=ACTIVITY_METRIC,
)
Build a comparison, dropping (with a warning) sessions lacking the primary metric.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
summaries
|
list[SessionSummary]
|
Loaded per-recording summaries. |
required |
primary_metric
|
str
|
Metric that every comparison panel keys on. |
PRIMARY_METRIC
|
noise_metric
|
str
|
Metric treated as the noise floor. |
NOISE_METRIC
|
activity_metric
|
str
|
Metric treated as the activity/event-rate trend. |
ACTIVITY_METRIC
|
Returns:
| Type | Description |
|---|---|
ComparativeReport
|
The comparative report over the retained sessions. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If no session has the primary metric. |
SessionSummary
dataclass
One recording's quality summary, reloaded from its report folder.
Reconstructed from meta.json + channels.csv; grade and quality tiers
are read back as computed, never re-derived, so a comparison never depends
on the classification thresholds in effect when it runs.
Attributes:
| Name | Type | Description |
|---|---|---|
base_name |
str
|
Recording identifier. |
source |
str
|
Provenance string recorded with the report (a Drive path, an experiment id, a filesystem path). Displayed, never parsed. |
recorded_at |
datetime | None
|
Wall-clock recording start (UTC), or |
grade |
str
|
Single-letter overall grade ( |
num_channels |
int
|
Number of amplifier channels analyzed. |
probe_ids |
list[str]
|
Distinct probe identifiers present. |
quality_counts |
dict[str, int]
|
Channel count per tier (good/fair/poor/dead). |
summary_stats |
dict[str, dict[str, float]]
|
|
thresholds |
dict[str, float]
|
Quality thresholds used for the per-recording report. |
channels |
DataFrame
|
Per-channel table indexed by native channel index
( |
Attributes
short_label
property
Compact axis label -- recording date/time when known, else the name.
Methods:
metric_values
Finite per-channel values of metric (empty if the column is absent).
Functions:
load_session_summaries
Load every saved per-recording report under reports_dir.
Globs <reports_dir>/*/meta.json (skipping the _comparison output
directory) and reads each alongside its sibling channels.csv. Results are
sorted chronologically by recorded_at (sessions with an unknown time sort
last, then by base_name).
Note
Report directories are keyed by base_name alone, so two sessions
sharing a base_name would collide on disk. Recording base names are
uid/timestamp-qualified in practice (e.g. allego_0__uid0514-11-32-12),
so this is not a concern for real data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
reports_dir
|
Path
|
Parent directory holding one subdirectory per recording. |
required |
Returns:
| Type | Description |
|---|---|
list[SessionSummary]
|
The loaded summaries, chronologically sorted. |
plot_comparative_report
Build the single-page cross-session comparison figure.
Layout (top to bottom): a metadata/stat-card header, separate SNR / noise / event-rate trend panels, a good-channel yield trend, a channel x session SNR heatmap, a ranked session leaderboard, and per-session SNR/noise/event-rate distributions.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
comp
|
ComparativeReport
|
The comparison to plot. |
required |
Returns:
| Type | Description |
|---|---|
Figure
|
The figure. The caller owns it and is responsible for closing it. |
save_comparative_report
Persist the comparison under <out_dir>/_comparison/.
Writes sessions.csv (one row per session), channels_by_session.csv
(tidy per-channel), meta.json (span, grade distribution, skipped
sessions), and optionally the figure.
The output lands inside the reports directory it summarizes, and
:func:load_session_summaries skips the _comparison folder, so
re-running a comparison over the same directory is safe.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
comp
|
ComparativeReport
|
The comparison to persist. |
required |
out_dir
|
Path
|
Parent reports directory; a |
required |
figure
|
bool
|
Also render and save the comparison figure. |
True
|
dpi
|
int
|
Resolution for the rendered figure. |
150
|
Returns:
| Type | Description |
|---|---|
Path
|
The |