clophfit.prenspire.bands#

Band readouts of EnSpire spectra, and the K fitted from them.

A spectral titration can be reduced to one number per well in two ways. The SVD path (clophfit.fitting.core.analyze_spectra()) projects each spectrum onto its first principal component; this module instead averages the intensity over a named window - the anionic and neutral excitation bands, the emission band - and lets several such bands share one K while keeping their own plateaus.

Neither readout is uniformly more precise: on replicate rows of the same plate they trade places. The band path is here for what it makes visible. Its plateaus are in the measured units, so S1/S0 = 0.01 reads as “the bound state is dark”; several bands give a consistency check that a single component cannot; and a band that has stopped reporting the transition (a flat neutral band, a readout that reverses sign between runs) is named and dropped rather than folded into a component that still returns a number.

Two corrections belong to the well, not to the readout, and are applied first: the buffer well of the same plate column is subtracted, and blank plate rows are removed by level. There is deliberately no tryptophan normalisation: on these plates that band is dominated by the medium’s scatter and Raman background (a buffer well keeps ~85 % of it), so dividing by it only adds well-to-well noise while shifting K by a third of a standard error.

Classes#

Readout

One band of one label.

BandFit

K with the interval and the residual scale it came with.

Functions#

classify(ef[, temp, is_ph])

Split a temperature's labels into the titrating bands their scans offer.

band_values(ef, readout, wells)

Mean intensity of one label over one window, per well.

subtract_buffer(values, buffer)

Subtract the buffer well of the same plate column from each sample well.

blank_rows(values, *[, frac])

Plate rows holding no protein, whatever the note calls them.

band_rho(x, y, wells)

Rank correlation of a band with the titrant, taken within replicate rows.

screen_bands(data, wells, *[, wanted, min_rho])

Keep the requested bands that titrate monotonically with the titrant.

fit_bands(data, *, is_ph[, screen])

Fit the given bands with one shared K and a plateau pair each.

fit_titrations(ef, note, *[, buffer, wanted, min_rho, ...])

Fit every sample of a note from its bands.

plot_sample(ax, sample, title)

Draw one sample's bands, their shared curve, and the screened points.

Module Contents#

class clophfit.prenspire.bands.Readout#

Bases: NamedTuple

One band of one label.

class clophfit.prenspire.bands.BandFit#

Bases: NamedTuple

K with the interval and the residual scale it came with.

masks: dict[str, numpy.ndarray]#

Per band, which points the screen kept.

clophfit.prenspire.bands.classify(ef, temp=None, *, is_ph=True)#

Split a temperature’s labels into the titrating bands their scans offer.

Each label declares its monochromator and the wavelength it holds fixed, so which windows it can offer is read from the file rather than configured: an excitation scan carries the anionic and neutral bands, an emission scan excited below 350 nm carries the emission band as seen from that excitation (em_exc278), and any other emission scan carries the emission band alone (em_exc420).

Parameters:
  • ef (EnspireFile) – The parsed EnSpire export.

  • temp (str | float | None) – Keep only labels measured at this temperature; None keeps every label.

  • is_ph (bool) – Which anionic-band window to use: ANIONIC (480-495 nm, where a pH titration’s own reproducibility is best) for a pH titration, or ANIONIC_CL (395-495 nm) for a chloride one - the two titrations respond over different parts of the excitation scan and one window does not serve both; see ANIONIC_CL’s definition for the numbers.

Returns:

The titrating bands the labels of this temperature offer, in scan order.

Return type:

list[Readout]

clophfit.prenspire.bands.band_values(ef, readout, wells)#

Mean intensity of one label over one window, per well.

Parameters:
  • ef (EnspireFile) – The parsed EnSpire export.

  • readout (Readout) – Label and window to average.

  • wells (Sequence[str]) – Wells to read, in order.

Returns:

One value per well, indexed by well.

Return type:

pd.Series

clophfit.prenspire.bands.subtract_buffer(values, buffer)#

Subtract the buffer well of the same plate column from each sample well.

Parameters:
  • values (pd.Series) – Sample values indexed by well.

  • buffer (pd.Series) – Buffer values indexed by well; the plate column is what pairs them, because a column is one titration step.

Returns:

values with the matching buffer removed.

Return type:

pd.Series

clophfit.prenspire.bands.blank_rows(values, *, frac=_BLANK_FRACTION)#

Plate rows holding no protein, whatever the note calls them.

Some notes name every well after the mutant while one row of the plate is buffer. Such a row sits at the instrument’s floor, so it is found by level: a row whose median is below frac of the brightest row’s median is blank.

Parameters:
  • values (pd.Series) – Raw band intensity per well, indexed by well.

  • frac (float) – Fraction of the brightest row’s median below which a row is blank.

Returns:

The blank plate rows, as single letters.

Return type:

list[str]

clophfit.prenspire.bands.band_rho(x, y, wells)#

Rank correlation of a band with the titrant, taken within replicate rows.

Replicate rows sit at slightly different levels, so ranking the pooled points can hide a perfectly monotone titration. Each row is ranked alone and the rows are pooled by median.

Parameters:
  • x (np.ndarray) – Titrant value per point.

  • y (np.ndarray) – Band value per point.

  • wells (Sequence[str]) – Well of each point; its plate row groups the replicates.

Returns:

Median within-row Spearman rho, or the pooled one if no row qualifies.

Return type:

float

clophfit.prenspire.bands.screen_bands(data, wells, *, wanted=DIRECT_BANDS, min_rho=0.8)#

Keep the requested bands that titrate monotonically with the titrant.

Parameters:
  • data (dict[str, tuple[np.ndarray, np.ndarray]]) – Band name to its (x, y).

  • wells (Sequence[str]) – Well of each point, in the same order.

  • wanted (Sequence[str]) – Bands allowed into the shared fit; the rest are reported only.

  • min_rho (float) – Smallest acceptable |rho| between a band and the titrant.

Returns:

The bands to fit, and why each of the others is out.

Return type:

tuple[list[str], dict[str, str]]

clophfit.prenspire.bands.fit_bands(data, *, is_ph, screen=DEFAULT_SCREEN)#

Fit the given bands with one shared K and a plateau pair each.

Parameters:
  • data (dict[str, tuple[np.ndarray, np.ndarray]]) – Band name to its (x, y).

  • is_ph (bool) – pH titration (else ligand concentration).

  • screen (str | None) – Outlier specification handed to fit_binding_glob(), or None.

Returns:

The fit, or None when it does not converge or has too few points to fit.

Return type:

BandFit | None

clophfit.prenspire.bands.fit_titrations(ef, note, *, buffer=True, wanted=DIRECT_BANDS, min_rho=0.8, screen=DEFAULT_SCREEN)#

Fit every sample of a note from its bands.

Parameters:
  • ef (EnspireFile) – The parsed EnSpire export.

  • note (pd.DataFrame) – Normalised note, with Well, pH, Cl, Name and Temp.

  • buffer (bool) – Subtract the buffer well of the same plate column.

  • wanted (Sequence[str]) – Bands allowed into the shared K; the others are reported only.

  • min_rho (float) – Monotonicity gate for a band.

  • screen (str | None) – Point screen handed to fit_binding_glob().

Returns:

The table of fits, the points the screen removed, and per sample the band data with its shared fit, for plotting.

Return type:

TitrationFits

clophfit.prenspire.bands.plot_sample(ax, sample, title)#

Draw one sample’s bands, their shared curve, and the screened points.

Parameters:
  • ax (Axes) – Where to draw.

  • sample (Sample) – Band data with the fit that shares K across them.

  • title (str) – Panel title; K and its interval are appended.

Return type:

None