clophfit.fitting.model_validation ================================= .. py:module:: clophfit.fitting.model_validation .. autoapi-nested-parse:: Reusable model-validation helpers for ClopHfit fitting workflows. These utilities are designed to live in :mod:`clophfit.fitting` and be reused by both package tests and manuscript-analysis scripts. They intentionally avoid any manuscript-specific paths, file formats, or plate names. Functions --------- .. autoapisummary:: clophfit.fitting.model_validation.residual_normal_scores clophfit.fitting.model_validation.robust_residual_outlier_mask clophfit.fitting.model_validation.excess_tail_outlier_mask clophfit.fitting.model_validation.mark_excess_residual_outliers clophfit.fitting.model_validation.masked_datasets_from_residual_outliers clophfit.fitting.model_validation.posterior_dataset clophfit.fitting.model_validation.sample_stats_dataset clophfit.fitting.model_validation.x_axis_sanity clophfit.fitting.model_validation.trace_diagnostics clophfit.fitting.model_validation.merge_log_likelihoods clophfit.fitting.model_validation.residuals_from_multifit clophfit.fitting.model_validation.residuals_from_fit_results clophfit.fitting.model_validation.model_residual_score_table Module Contents --------------- .. py:function:: residual_normal_scores(likelihood_residual, *, robust = False, student_t_nu = STUDENT_T_NU) Map likelihood-scale residuals onto a Normal diagnostic scale. For Normal likelihoods this is the identity. For Student-t likelihoods, ``(y - mu) / sigma`` follows a t distribution, so Normal QQ plots and ``abs(residual) > 2`` style diagnostics should use the probability integral transform to an equivalent standard-Normal score. .. py:function:: robust_residual_outlier_mask(likelihood_residual, *, threshold = 3.0, robust = False, student_t_nu = STUDENT_T_NU) Flag observations by calibrated Normal-score residual magnitude. .. py:function:: excess_tail_outlier_mask(likelihood_residual, *, threshold = 3.0, allowed_tail_fraction = 0.01, min_allowed_tail_count = 1, robust = False, student_t_nu = STUDENT_T_NU) Mask only residual outliers beyond an allowed tail fraction. The residuals are first mapped to the calibrated Normal diagnostic scale. Observations with ``abs(z) <= threshold`` are never removed. If more than ``allowed_tail_fraction`` of finite observations exceed the threshold, only the largest excess observations are marked for removal. .. py:function:: mark_excess_residual_outliers(residuals, *, residual_col = 'std_res', group_cols = ('trace_id', 'label'), threshold = 3.0, allowed_tail_fraction = 0.01, min_allowed_tail_count = 1, exclude_col = 'exclude_residual_outlier') Annotate residual rows to remove only excess calibrated tail outliers. .. py:function:: masked_datasets_from_residual_outliers(results, residuals, *, exclude_col = 'exclude_residual_outlier', min_keep = 3) Return datasets with residual rows marked by *exclude_col* masked out. This is intended for the second pass of a sensitivity analysis: fit once, compute residuals, annotate excess-tail outliers, mask those rows, then refit. .. py:function:: posterior_dataset(trace) Return the posterior xarray Dataset from ArviZ InferenceData or DataTree. PyMC/ArviZ versions differ in whether returned objects are InferenceData-like or xarray DataTree-like. This helper hides that difference for validation code. .. py:function:: sample_stats_dataset(trace) Return sample_stats Dataset from InferenceData or DataTree. .. py:function:: x_axis_sanity(trace) Check pH/x-axis invariants for traces with ``x_per_well``. For per-well x models with a shared start pH, all wells at step 0 should be identical within each draw. ``x_step0_max_abs_spread`` should therefore be close to zero. .. py:function:: trace_diagnostics(trace, *, compute_loo = False, summary_var_names = None) Collect basic MCMC and optional LOO diagnostics from a PyMC trace. .. py:function:: merge_log_likelihoods(trace) Merge multiple pointwise log-likelihood variables for ArviZ LOO/compare. .. py:function:: residuals_from_multifit(multi, trace_id, binding_function, *, include_fit_params = False, robust = False, student_t_nu = STUDENT_T_NU, outlier_threshold = 3.0) Build a long calibrated-residual table from a MultiFitResult. ``likelihood_res`` is always ``(observed - predicted) / sigma``. For Student-t robust fits, ``std_res`` is the equivalent standard-Normal score from the t CDF, suitable for Normal QQ plots and z-style outlier flags. .. py:function:: residuals_from_fit_results(results, trace_id, binding_function, *, include_fit_params = False, robust = False, student_t_nu = STUDENT_T_NU, outlier_threshold = 3.0) Build a long calibrated residual table from classical FitResult objects. .. py:function:: model_residual_score_table(res_df) Return model-level and detailed residual summary tables.