clophfit.fitting.spectral#

Whole-spectrum global fit of a two-state titration (variable projection).

A titration of a two-state probe measured as spectra obeys a bilinear model: every spectrum is a mixture of two species spectra weighted by the fraction of each state,

Y_j(lambda, w) = E_j0(lambda) (1 - f(x_w)) + E_j1(lambda) f(x_w),

for each label (scan) j, well w and titrant value x_w, with f the single-site binding fraction (Henderson-Hasselbalch for pH). Given K (and optionally the Hill slope), the species spectra are the solution of a linear least-squares problem, so they are eliminated (variable projection, Golub & Pereyra 1973) and only K is fitted nonlinearly. This joins the two older readouts:

Here every wavelength of every label enters, each label weighted by its own residual variance, and the fitted species spectra are returned so that they can be checked against the expected neutral and anionic chromophore spectra. When pure-state reference spectra are known, fixing E turns the fit into the classical unmixing of the 1995 SPETTRI programs.

Neighbouring wavelengths of one spectrum share their errors (pipetting, lamp and gain drift act on the whole spectrum), so the covariance from the Jacobian treats far too many points as independent. The standard error reported is therefore the delete-one-well jackknife, with the naive value kept for comparison.

The species spectra are not principal components: for each trial K the fractions C(K) are fixed and E is the ordinary least-squares solution of Y = C E (with the per-well amplitude, alternating with it). SVD enters only as a diagnostic, on the residual matrix.

acid_state adds a third state with its own pK below K. On the IBF plates it is not supported: the well amplitudes are low (median 0.90) in each plate’s most acidic column whatever its pH (5.1-5.8), while on ten-column plates pH 5.4 and 4.7 are not dim; only below pH ~4.5 do they collapse (denaturation). That points to the last titration step rather than a protonation equilibrium, so the default stays two states with a per-well amplitude, which keeps K within 0.02 pH (median) of the fit without that column and limits the shift on a denatured plate to 0.13 pH (1.34 without it).

Classes#

Functions#

fit_spectra_global(x, spectra, *[, is_ph, fit_hill, ...])

Fit K to whole spectra of one or more labels, species spectra eliminated linearly.

Module Contents#

class clophfit.fitting.spectral.SpectralFit#

Result of fit_spectra_global().

K#

pKa (pH titration) or Kd (ligand titration).

Type:

float

se#

Delete-one-well jackknife standard error of K.

Type:

float

se_naive#

Standard error from the Jacobian, treating every wavelength as independent (too small).

Type:

float

hill#

Hill slope (1 unless fitted).

Type:

float

k_acid, se_acid

pK2 of the acid state and its jackknife error (nan without acid_state).

Type:

float

species#

Per label, the species spectra, shape (n_states, n_lambda), in the order of binding_1site()’s S0 and S1: for pH the deprotonated (basic) then the protonated (acidic) state, then the acid state if fitted; for a ligand the free then the bound state.

Type:

dict[str, ArrayF]

wavelengths#

Per label, the wavelengths used.

Type:

dict[str, ArrayF]

rms#

Per label, the residual root-mean-square (the label’s weight is its inverse square).

Type:

dict[str, float]

residual_sv#

Singular values of the weighted residual matrix (wells x all wavelengths). A first value well above the others points to a third species or a drift the two-state model misses.

Type:

ArrayF

n_wells#

Wells used.

Type:

int

well_scale#

Fitted per-well amplitudes (all 1 unless well_scale was requested).

Type:

ArrayF

clophfit.fitting.spectral.fit_spectra_global(x, spectra, *, is_ph=True, fit_hill=False, well_scale=False, acid_state=False, jackknife=True)#

Fit K to whole spectra of one or more labels, species spectra eliminated linearly.

Parameters:
  • x (ArrayF) – Titrant value (pH or concentration) per well.

  • spectra (Mapping[str, tuple[ArrayF, ArrayF]]) – Label to (wavelengths, Y) with Y of shape (n_lambda, n_wells), already corrected per well (buffer subtracted). Wavelengths holding a non-finite value in any well are dropped.

  • is_ph (bool) – pH titration (Henderson-Hasselbalch) or ligand binding.

  • fit_hill (bool) – Also fit the Hill slope (bounded to 0.2-5).

  • well_scale (bool) – Give each well a free amplitude shared by its labels (protein amount, mean 1). Use it to absorb what is left of the well-to-well amount error.

  • acid_state (bool) – Add a third state below the main transition (pH titrations only): sequential deprotonated <-> protonated <-> acid state with pK2 < K, its spectrum solved like the others. It models a change of brightness or colour at the acid end that a two-state model can only push into the well amplitudes (see the module notes on the IBF plates).

  • jackknife (bool) – Compute the delete-one-well jackknife standard error (one refit per well).

Returns:

K, its errors, the species spectra and residual diagnostics.

Return type:

SpectralFit

Raises:

ValueError – With fewer than four wells, no usable wavelength, or an acid state on a ligand titration.