clophfit.prtecan.export#

Export data and fit results from Titration objects.

Functions#

generate_combinations()

Generate parameter combinations for export and fitting.

apply_combination(titration, combination)

Apply a combination of parameters to the Titration.

prepare_output_folder(titration, base_path)

Prepare the output folder for a given combination of parameters.

likelihood_residual_table(fit_results)

Build the residual table of fit_results, standardized by each fit's likelihood.

export_residuals(outfit, fit_results, index)

Export fit residuals and their statistics to files.

export_trace_summary(trace, outfit, tag)

Write posterior statistics and the trace of a sampled model.

screen_atypical_wells(titration)

Screen every well on the plate, before anything is discarded or fitted.

run_pre_fit_detection(titration, outfit)

Discard unusable wells and record everything atypical beside them.

undetermined_k(fit, *, is_ph, max_k_se)

Flag the wells whose fitted K the data do not pin down.

kd_lower_bound(fit)

Lower edge of each well's 94% Kd interval.

no_binding_k(fit, *, x_max)

Flag chloride wells whose Kd lies beyond the titration: they do not bind.

record_post_fit(outfit, sections)

Append the reported fit's verdicts to discarded_wells.txt.

k_verdicts(fit, *, is_ph, max_k_se, x_max)

Post-fit verdicts on each well's K, as boolean columns.

fit_single_mcmc(titration, datasets, outfit, spec)

Run optional PyMC fits for export, per well or jointly.

export_plate_fit(titration, datasets, outfit, method, *)

Fit the whole plate at once, classically, and write K per well.

export_fit(titration, subfolder, config[, spec, plate_fit])

Export all fitted parameters, plots, and data files.

export_data_fit(titration, tecan_config[, mcmc, plate_fit])

Export dat files [x,y1,..,yN] from copy of titration.data.

Module Contents#

clophfit.prtecan.export.generate_combinations()#

Generate parameter combinations for export and fitting.

Return type:

list[tuple[tuple[bool, …], str]]

clophfit.prtecan.export.apply_combination(titration, combination)#

Apply a combination of parameters to the Titration.

Parameters:
Return type:

None

clophfit.prtecan.export.prepare_output_folder(titration, base_path)#

Prepare the output folder for a given combination of parameters.

Parameters:
Return type:

pathlib.Path

clophfit.prtecan.export.likelihood_residual_table(fit_results)#

Build the residual table of fit_results, standardized by each fit’s likelihood.

Called without its likelihood, residuals_from_fit_results standardizes every residual as Normal: a Student-t fit’s (y - mu) / sigma then shows t tails (5.8% beyond |3| at nu = 3) as if they were outliers, and a mixture’s wide component likewise. Here the family, nu and the mixture weights are read from each fit’s own trace. One call per distinct trace: a multi-well fit shares one, while single-well samples each carry their own, whose nu, mixture weights and outlier probabilities must not be pooled.

Parameters:

fit_results (Mapping[str, FitResult]) – Well to fit result; least-squares results carry no trace and stay Normal.

Returns:

The concatenated canonical residual tables.

Return type:

pd.DataFrame

clophfit.prtecan.export.export_residuals(outfit, fit_results, index)#

Export fit residuals and their statistics to files.

Writes nothing when no fit produced residuals: the plots are sized by the labels present, and an empty table used to raise inside matplotlib (“Number of columns must be a positive integer, not 0”), aborting a chloride run after its fits had succeeded. A diagnostic must not be able to destroy the run it describes.

Parameters:
Return type:

None

clophfit.prtecan.export.export_trace_summary(trace, outfit, tag)#

Write posterior statistics and the trace of a sampled model.

Sampling and then keeping nothing from it is not a usable result: the multi-well path inferred x_true, a per-well K and the whole ye_mag family, and dropped the trace on return, so a run could be performed but not inspected. This writes trace_summary_<tag>.csv - mean, sd, HDI, r_hat and ESS per variable, the numbers that say whether to trust the rest - and the full trace as NetCDF for anything the summary does not cover.

Failures here are logged and swallowed. The summary describes a fit that has already succeeded, and a diagnostic must not be able to destroy the run it reports on.

Parameters:
  • trace (object) – PyMC/ArviZ inference data from the fit. None writes nothing.

  • outfit (Path) – Directory to write into.

  • tag (str) – Suffix identifying the model, e.g. "multi".

Return type:

None

clophfit.prtecan.export.screen_atypical_wells(titration)#

Screen every well on the plate, before anything is discarded or fitted.

Replaces bad_wells.csv, which was unusable: it ORed a single expected polarity across two channels that move oppositely by design, so on a real plate it reported all 88 of 88 wells as bad, and its “low signal” and “flat curve” columns were the same Series under two names.

“Atypical” rather than “bad” because most of what lands here is not a fault. A flat 400 nm channel and a concordant pair are properties of the construct; only the dim ones are quality problems, and even those are highlighted rather than discarded.

Parameters:

titration (Titration) – Titration whose data and background levels are screened.

Returns:

The atypical wells only, empty when the plate is unremarkable.

Return type:

pd.DataFrame

clophfit.prtecan.export.run_pre_fit_detection(titration, outfit)#

Discard unusable wells and record everything atypical beside them.

Both files land in the fit folder, and the discard list carries the highlighted wells under their own heading: one file then answers “what happened to my wells” without joining it to another.

Parameters:
  • titration (Titration) – Titration to screen and then discard from.

  • outfit (Path) – Fit output folder.

Return type:

None

clophfit.prtecan.export.undetermined_k(fit, *, is_ph, max_k_se)#

Flag the wells whose fitted K the data do not pin down.

The pre-fit rule (Titration._k_is_unconstrained) judges a cheap fit against the whole x span, about 4 pH; a well can pass it and still come out of the final fit at 14 +/- 9, or widen only once sampled. This judges the fit actually reported.

Parameters:
  • fit (pd.DataFrame) – Per-well fit table indexed by well, with K, sK and, for a sampled fit, Khdi03.

  • is_ph (bool) – A pH titration (K is a pKa, an interval scale) rather than chloride (K is a Kd, a ratio scale).

  • max_k_se (float) – Largest acceptable standard error of a pKa, in pH.

Returns:

Boolean, indexed like fit. A missing or non-finite K or sK is undetermined. pH: sK > max_k_se. Chloride: Kd <= 0, sKd > Kd, or a 94% HDI whose lower edge is the KD_MIN floor (within 10%): the data then bound Kd only from above, and the lower edge is the prior’s - as a well saturated by the first addition is.

Return type:

pd.Series

clophfit.prtecan.export.kd_lower_bound(fit)#

Lower edge of each well’s 94% Kd interval.

The sampled HDI (Khdi03) where there is one, otherwise the Normal bound K - 1.88 sK; NaN where neither can be formed.

Parameters:

fit (pd.DataFrame) – Per-well fit table indexed by well, with K and sK.

Returns:

Float, indexed like fit.

Return type:

pd.Series

clophfit.prtecan.export.no_binding_k(fit, *, x_max)#

Flag chloride wells whose Kd lies beyond the titration: they do not bind.

A construct that does not bind has a flat curve, and a Kd the data place only above the highest concentration titrated. That is a result - “does not bind”, Kd > the top concentration - not a failed fit, and it is kept apart from undetermined_k(), which would call it undetermined (its sampled Kd spans the range up to the kd_bounds ceiling, so SE > Kd).

Parameters:
  • fit (pd.DataFrame) – Per-well Kd table indexed by well, with K, sK and, for a sampled fit, Khdi03.

  • x_max (float) – Highest ligand concentration titrated.

Returns:

Boolean, indexed like fit: the 94% lower bound (see kd_lower_bound()) is above x_max; or a least-squares Kd is pinned at the kd_bounds ceiling, where a flat curve drives it (its SE there is meaningless, 1e6 mM on a test plate), or sits above x_max with no finite SE.

Return type:

pd.Series

clophfit.prtecan.export.record_post_fit(outfit, sections)#

Append the reported fit’s verdicts to discarded_wells.txt.

One heading per verdict (# undetermined_k, # no_binding), after the pre-fit sections: the wells were fitted and are reported, so they are highlighted rather than discarded.

Parameters:
  • outfit (Path) – Fit output folder.

  • sections (Mapping[str, Sequence[str]]) – Heading to wells; an empty one is omitted, and nothing is written when all are.

Return type:

None

clophfit.prtecan.export.k_verdicts(fit, *, is_ph, max_k_se, x_max)#

Post-fit verdicts on each well’s K, as boolean columns.

Parameters:
  • fit (pd.DataFrame) – Per-well fit table indexed by well.

  • is_ph (bool) – A pH titration rather than chloride.

  • max_k_se (float) – Largest acceptable SE of a pKa (pH); see undetermined_k().

  • x_max (float) – Highest concentration titrated; see no_binding_k().

Returns:

undetermined for pH; undetermined and no_binding for chloride, exclusive: a well that does not bind is a result, not an undetermined one.

Return type:

pd.DataFrame

clophfit.prtecan.export.fit_single_mcmc(titration, datasets, outfit, spec)#

Run optional PyMC fits for export, per well or jointly.

Parameters:
  • titration (Titration) – Titration object containing the plate scheme, fit keys, and background noise.

  • datasets (dict[str, Any]) – Mapping from well identifiers to datasets to fit.

  • outfit (Path) – Output directory used for residual-refit diagnostic CSV files.

  • spec (McmcSpec | None) – Sampling request deciding whether and how to run MCMC. None disables MCMC export.

Returns:

Per-well PyMC fit results when spec is provided. Returns None when spec is None.

Return type:

TitrationResults | None

clophfit.prtecan.export.export_plate_fit(titration, datasets, outfit, method, *, png=True, calibrate_noise=False, screen_z=None, frac_threshold=None, ctr_free_k=False, calibrate_screen=True, gain_terms=None)#

Fit the whole plate at once, classically, and write K per well.

The per-well fits above give each well its own noise scale; this fits every well in one least-squares problem with the observation-noise scale profiled per label across the plate, and each control group pooled onto one K. It is Its results are wrapped as ordinary per-well fit results, so it produces the same K plot and per-well figures as every other fitter in the run rather than a bare CSV.

Parameters:
  • titration (Titration) – Supplies the plate scheme, whose control groups set which wells pool.

  • datasets (dict[str, Any]) – Well identifier to global Dataset, as built for the other fits.

  • outfit (Path) – Fit output directory.

  • method (str) – "lm" for the plate-wide least squares, "odr" to also let each titration step’s x move within its recorded uncertainty.

  • png (bool) – Write per-well figures as well as the K plot.

  • calibrate_noise (bool) – Estimate gain and alpha per label from the fit’s own residuals and refit under them, instead of taking y_err as built.

  • screen_z (float | None) – Drop points whose calibrated standardised residual exceeds this and refit. None fits once.

  • frac_threshold (float | None) – Also screen the first label on |y - yhat| / yhat exceeding this, sparing points the other channel moves with. See fractional_outliers().

  • ctr_free_k (bool) – Give every well its own K instead of pooling each control group onto a shared one. The plate fitters pool by default, exactly as --mcmc multi does, so the flag has to reach here or the two fitters answer different questions from the same command line.

  • calibrate_screen (bool) – With screen_z, judge points on the calibrated ruler (default) rather than on the weights as built. The weights K is then fitted with follow calibrate_noise, screened or not.

  • gain_terms (str | None) – "gain" or "floor-gain": weight by floor^2 + gain * yhat with alpha 0, the gain (and with "floor-gain" the floor) calibrated from the plate’s residuals between refits, corrected for the degrees of freedom the fit used (calibrate_plate_lm()). Takes the place of calibrate_noise; after a screen it calibrates on the screened points. None leaves the weights to calibrate_noise.

Returns:

The fit, or None when no wells were fitted. The result rather than the path it wrote, because the caller needs excluded_points to hand the screen’s verdict to whatever fits next.

Return type:

PlateLMResult | PlateODRResult | None

clophfit.prtecan.export.export_fit(titration, subfolder, config, spec=None, plate_fit=None)#

Export all fitted parameters, plots, and data files.

Parameters:
Return type:

None

clophfit.prtecan.export.export_data_fit(titration, tecan_config, mcmc=None, plate_fit=None)#

Export dat files [x,y1,..,yN] from copy of titration.data.

Parameters:
Return type:

None