SC‑WBD

Engineering · 11

Two montages are two views of one carrier

A support could say how many elements it had, never what one was. That distinction turned out to be the difference between 5.6% and 51.7% of the whitened lead field — so the algebra that relates supports refuses to treat it as a reshape.

The question this came from

Take readings from electrode montage A and readings from montage B. Can they inform one higher-dimensional underlying representation, together with a high-resolution connectome?

The honest answer had been not without hand-writing something. Support — the object describing what a datum physically integrates over — carried kind, frame, units, psf, extent, n_elements, resolution and no operators. Two supports could not be related without a bespoke map. That is why the restriction/prolongation pair in Engineering · 04 had to be declared as a one-off rather than derived.

What the algebra refuses, and why that is the design

The first instinct is an algebra that always returns a map. That is worse than having none. A fabricated correspondence between two parcellations is indistinguishable at the type level from a real one — it has the same shape, passes the same checks, and silently becomes part of the result.

So maps are derived only from what the supports actually declare, and everything else raises an error naming the missing declaration:

situationoutcome
different framesrefuse — supply a registration
different unitsrefuse — convert first
vector components in different framesrefuse — rotate first
two named clocks, no declared relationrefuse — supply a synchronisation record
scalar ↔ vector, no orientation fieldrefuse — see below
same frame, finer → coarserrestriction, marked lossy
same frame, coarser → finerprolongation, marked invents

The refusal that was measured, not assumed

A support says how many elements it has. It never said what one element is. We had no way to express the difference between one number per parcel and three.

That difference is not bookkeeping. Measured on real data: a per-parcel scalar carries 5.6% of the whitened lead field, where three numbers per parcel carry 51.7%.

So collapsing a 3-vector per parcel to a scalar is not a reshape. It is a projection onto an orientation — and which orientation is a physical fact about the cortex, not a layout choice. The algebra refuses to do it unless you hand it an orientation field, and then reports the discarded normal component as the uncertainty it is.

A support whose elements are scalars is a different kind of object from one whose elements are vectors. Anything that cannot tell them apart will eventually average one into the other.

Lossy and invents are different fields

Restriction discards information and is honest about it. Prolongation asserts structure no measurement supports. A pipeline can reasonably tolerate the first; it must declare the second.

They are separate flags, and the constructor enforces the pairing — a prolongation declaring invents=False cannot be built, because it would be claiming that upsampling is free:

SupportMap(kind="prolongation", n_in=1, n_out=4, invents=False, ...)
# ValueError: prolongation asserts structure no measurement supports;
#             invents=False would claim upsampling is free

Point-spread composes, or it refuses

Mapping through a support smears the datum, so the kernels compose. Two Gaussians compose in closed form — FWHM adds in quadrature. Two opaque kernel_refs do not compose from their descriptions; that needs the assets. Refusing beats approximating, because an approximated point-spread is exactly the "nominal coordinate substituted for a physical support" the thesis rejects.

Nominality is contagious: a composed kernel is no more real than its least real factor.

Clocks

5000 Hz EEG against 0.5 Hz BOLD refines onto the faster clock. The fast signal is already there; the slow one is held across the gap — which is invention, and the map says so rather than presenting interpolated values as measurements.

Why the algebra alone does not answer the question

An algebra for relating supports is necessary and not sufficient, and counting the current model says why:

whathow many
source cards declared on disk9
of those, involving EEG9
EEG views the model can hold1

The lead field is a buffer registered inside the EEG head — one L, one L_vec, on a single module. So:

Montage A and montage B cannot coexist, because there is exactly one L. Adding the second means adding a second head or overwriting the first — and neither of those is "two views of one carrier."

The number of views is fixed by the model's module list rather than by the sources. That is backwards: sources are data and arrive over time, modules are code and should not have to change when they do.

The fix is not to delete the heads — EEGHead holds real physics. It is that ownership is misplaced. An L describes a montage; a montage belongs to a source; a source is a card. Move the operator to the card, leave the head as the thing that applies a view, and the two montages stop being two modules and become two rows.

That is also the point at which this algebra stops being decorative. Once each source carries its own operator and support, relating two of them is exactly the computation above — and the refusals are what stop two montages being quietly averaged into one another.

What is actually blocking the other sources

"Nine sources, one view" is the abstract statement. The concrete one is a list of three missing operators, each blocking a specific dataset that is already sitting on disk:

sourcewhat it isblocked byneeds
eegmmidb64-channel EEGenabled
ds002336EEG and fMRI, CC0BOLD is in scanner space; model state is parcelsa registration
ds0001137 T fMRIa 116 mm slab — parcels outside it are unmeasured in every subjecta coverage mask
sleepedf2 EEG derivations2 channels cannot constrain a 64-channel heada montage adapter

Three of the four measured sources are switched off, and not one of them is switched off by policy. Each is waiting on an operator nobody has written.

These blockers are not interchangeable with permission. A likelihood term over parcels outside the acquisition slab is an imputation. A parcel-space likelihood computed from scanner-space voxels with no registration is not a weaker claim — it is a different quantity. Enabling those sources without the transforms would not be a relaxed standard; it would be a wrong number.

The third row is the one this page is about. Two derivations against sixty-four is literally montage A and montage B — so sleepedf is the cheapest of the three to unlock, and the natural first consumer of the algebra. It is what turns this module from something with no importers into the thing that admits a second measured dataset.

What this is not, yet

Two limits, stated because an entry marked done is how a half-delivered change stops being visible:

  • Nothing imports it. It was written during a live training run and deliberately kept free of consumers, so that a relaunch could not pick up changed code mid-flight. Wiring the observation heads onto it is later work.
  • It derives maps; it does not compute them. You get a typed map with element counts, composed point-spread, and uncertainty — not the matrix. For two arbitrary parcellations it refuses rather than inventing a correspondence, so real geometric overlap is still to come.

The refusal is the honest placeholder. The one-off is now visible as a refusal instead of hidden as a hand-written map.

How it was checked

21 tests, most of them watching a refusal fire — and mutation-tested three ways, because a file that is mostly error paths and passes on the first run is the exact thing our register distrusts. Allowing a rank change through, replacing quadrature with a naive sum, and letting opaque kernels be silently approximated each failed the intended test and only that one.