clophfit.prenspire.thermo#

Joint van’t Hoff fit of an EnSpire titration across temperatures.

Instead of fitting pKa at each temperature independently, fit every well of every temperature as one model tied by the van’t Hoff relation:

pKa(T) = dH / (2.303 R T) - dS / (2.303 R)      (T in kelvin)

The plateaus S0, S1 stay free per (band, temperature) - brightness is not comparable across temperatures - while the two thermodynamic parameters are shared by all bands and all temperatures. Both reported pKa values therefore come from one fit over all the data, and dH of chromophore deprotonation falls out as a fitted quantity, not a two-point difference.

pKa(T) = A + B (1/T - m) with the inverse-temperature axis centred on its mean m decorrelates the fitted pair; the reported constants are dH = 2.303 R B and dS = -2.303 R (A - B m).

Hill slope is fixed to 1 (Henderson-Hasselbalch); see clophfit.prenspire.bands.band_rho() for the readout gate.

Classes#

VanthoffFit

The joint fit of one sample: pKa per temperature plus the pair behind it.

VanthoffModel

Everything needed to redraw one sample's joint fit.

Functions#

titrant_kind(note)

Decide per sample whether its titrant axis is pH or chloride.

fit_vanthoff_model(data, *[, is_ph])

Fit (band, temp) curves jointly; pKa(T) = A + B (1/T - m).

vanthoff_titration(ef, note, *[, buffer, is_ph, ...])

Joint van't Hoff fit per sample of the note; one row per (sample, temp).

Module Contents#

clophfit.prenspire.thermo.titrant_kind(note)#

Decide per sample whether its titrant axis is pH or chloride.

The titrant is the column that varies within a sample: a pH titration steps the pH and leaves the chloride alone, a chloride titration the other way round. Deciding once for the whole note would fit a chloride sample against its constant pH column and report a meaningless K.

Parameters:

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

Returns:

Sample name to True when the sample is a pH titration.

Return type:

dict[str, bool]

class clophfit.prenspire.thermo.VanthoffFit#

Bases: NamedTuple

The joint fit of one sample: pKa per temperature plus the pair behind it.

ok: bool#

Whether the fit converged.

k_by_temp: dict[str, tuple[float, float]]#

Temperature label to (pKa, standard error).

b: float#

Centred coefficients, pKa = A + B (1/T - m).

ds: float#

Enthalpy (J/mol) and entropy (J/mol/K) of deprotonation.

n: int#

Wells fitted.

plateaus: dict[tuple[str, str], tuple[float, float]]#

Fitted (S0, S1) per (band, temperature), for plotting.

m: float#

Inverse temperatures [1/K] and their centring mean.

class clophfit.prenspire.thermo.VanthoffModel#

Bases: NamedTuple

Everything needed to redraw one sample’s joint fit.

is_ph: bool = True#

Whether the sample was fitted as a pH (else ligand) titration.

clophfit.prenspire.thermo.fit_vanthoff_model(data, *, is_ph=True)#

Fit (band, temp) curves jointly; pKa(T) = A + B (1/T - m).

Parameters:
  • data (dict[tuple[str, str], tuple[ArrayF, ArrayF]]) – Band name and temperature label to its (x, y) curve, y already normalised and scaled by the caller.

  • is_ph (bool) – pH titration (fit pKa(T) against a Henderson-Hasselbalch fraction) or ligand titration (fit pKd(T) against a Langmuir fraction and report Kd on the x scale).

Returns:

The joint fit; ok=False when it did not converge or fewer than two temperatures were given.

Return type:

VanthoffFit

clophfit.prenspire.thermo.vanthoff_titration(ef, note, *, buffer=True, is_ph=None, wanted=DIRECT_BANDS, min_rho=0.8)#

Joint van’t Hoff fit per sample of the note; one row per (sample, temp).

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

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

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

  • is_ph (bool | None) – Force the titrant column for every sample. None decides per sample with titrant_kind(), which is what a note mixing a pH and a chloride titration needs.

  • wanted (Sequence[str]) – Band names entering the joint fit; default the two direct readouts.

  • min_rho (float) – Monotonicity gate below which a band is dropped, as in the band path.

Returns:

One row per (sample, temperature): K, se, plus per-sample A, B, dH_J_mol, dS_J_molK, n; and per sample the fitted pieces needed to redraw the joint model.

Return type:

tuple[pd.DataFrame, dict[str, VanthoffModel]]

Notes

pH titrations: pKa is the fitted midpoint (linear in 1/T). Ligand titrations (is_ph=False): pKd = -log10 Kd is what is linear in 1/T, so the model carries pKd(T) internally and the table reports Kd on its native mM scale (errors propagated log -> linear). The enthalpy is that of deprotonation / ligand dissociation respectively.