clophfit.fitting.plate_odr#
Plate-wide fit that lets the pH axis move, not only the signal.
plate_lm takes x at face value. That is the wrong assumption here twice over: the recorded pH of each titration step carries its own measured uncertainty - list.pH.csv has it in the third column, 0.006 to 0.086 on L6a - and section 2 found that modelling x as uncertain is the single largest improvement anywhere in this campaign, with every latent-x arm beating every fixed-x one.
This is the classical counterpart: an errors-in-variables fit, which is what orthogonal distance regression is. Each titration step gets one shift, penalised by its recorded uncertainty, and the shift is shared across wells because the pH of a step is a property of the plate rather than of a well. Seven extra parameters for a seven-step titration, not one per point.
The scale behaves differently here than in plate_lm, and that is the reason to have both. A least-squares objective is invariant to scaling every weight, so the noise scale is not identifiable and has to be profiled. Once x errors enter, the ratio between the y and x penalties is part of the objective, so the balance between them is doing real work rather than cancelling.
Classes#
Outcome of one plate-wide errors-in-variables fit. |
Functions#
|
Fit a plate with the pH of each step free to move within its uncertainty. |
|
Leave one control out at a time, with the pH axis free to move. |
Module Contents#
- class clophfit.fitting.plate_odr.PlateODRResult#
Outcome of one plate-wide errors-in-variables fit.
- Parameters:
k (dict[str, float]) – Fitted K per well; control-group members share one value.
k_stderr (dict[str, float]) – Standard error per well from the Jacobian at the solution.
ye_mag (dict[str, float]) – Profiled noise multiplier per label.
dx (np.ndarray) – Fitted shift of each titration step, in pH, shared across wells.
n_points (int) – Unmasked observations entering the fit.
n_params (int) – Free parameters, structural shifts included.
success (bool) – Whether the final solve converged.
residuals (list[dict[str, Any]]) – One record per unmasked observation on the library’s canonical columns (
well,label,step,yhat,raw_res,sigma,std_res), taken on the shifted pH grid, so it reflects the model the fit actually settled on rather than the recorded axis.
- clophfit.fitting.plate_odr.fit_plate_odr(datasets, groups, *, x_err=None, max_iter=6, tol=0.001)#
Fit a plate with the pH of each step free to move within its uncertainty.
- Parameters:
datasets (Mapping[str, Any]) – Well identifier to Dataset.
groups (Mapping[str, Sequence[str]]) – Control group name to member wells; those wells share one K.
x_err (np.ndarray | None) – Recorded uncertainty per titration step.
Noneuses 0.015 pH, the pipetting scale section 2 settled on.max_iter (int) – Maximum alternations between solving and rescaling.
tol (float) – Stop when every scale moves by less than this, relatively.
- Returns:
Fitted K per well, the per-step pH shifts, and the profiled scales.
- Return type:
- Raises:
ValueError – If x_err does not carry one entry per titration step.
- clophfit.fitting.plate_odr.ctr_holdout_odr(datasets, groups, *, x_err=None, rope=0.1, plate='')#
Leave one control out at a time, with the pH axis free to move.
The same experiment as
clophfit.fitting.plate_lm.ctr_holdout(), fitted with errors in variables so a wrongly recorded step is corrected rather than pushed into K. Rows share the schema, so the two can be pooled together.- Parameters:
datasets (Mapping[str, Any]) – Well identifier to Dataset.
groups (Mapping[str, Sequence[str]]) – Control group name to member wells.
x_err (np.ndarray | None) – Recorded uncertainty per titration step, from the third column of
list.pH.csv.Nonefalls back to 0.015 pH.rope (float) – Half-width of the region of practical equivalence, in pH.
plate (str) – Recorded in each row, for pooling across plates.
- Returns:
One row per held-out control.
- Return type:
list[dict[str, Any]]