Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
32fef32
Blinding groups and opt-in Gaussian priors on ParamModel parameters
lucalavezzo Jun 11, 2026
81f73c7
Address review: drop --paramModelPriors, the ParamModel decides
lucalavezzo Jun 12, 2026
81e1802
Address review: drop _np prior attributes, use .numpy() on TF constants
lucalavezzo Jun 12, 2026
b3fcb60
Apply pre-commit hook formatting
lucalavezzo Jun 12, 2026
212a835
CompositeParamModel: preserve the [POIs | POUs] parameter layout
lucalavezzo Jun 12, 2026
2bbbb90
Unify ParamModel priors with the nuisance constraint structure
lucalavezzo Jun 12, 2026
65164bb
Propagate ParamModel priors through the global impacts
lucalavezzo Jun 12, 2026
c674aae
Single constraint term over the full parameter vector
lucalavezzo Jun 12, 2026
6433ad7
Unified cw / x0 over the full parameter vector, replacing theta0
lucalavezzo Jun 12, 2026
3f2341b
Parameter matching via re.fullmatch, log resolved unblind parameters
lucalavezzo Jun 12, 2026
32b8d3c
Fix nonprofiled variation width for non-unit constraint weights
lucalavezzo Jun 12, 2026
7bd0d81
Preserve blinding groups and prior centers across the saturated re-init
lucalavezzo Jun 12, 2026
1c8e4f6
Address review: build prior arrays in indata dtype, center free x0 at…
lucalavezzo Jun 15, 2026
68c6f0e
Differentiate global impacts only w.r.t. constraint sources; scan pri…
lucalavezzo Jun 15, 2026
002f8da
Carry global-impact sources as one collection (address review)
lucalavezzo Jun 22, 2026
933dde1
Merge origin/main into param-priors-blinding
lucalavezzo Jun 23, 2026
32902cd
Address review: work with the full x0 everywhere, drop the source subset
lucalavezzo Jun 23, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 43 additions & 4 deletions bin/rabbit_fit.py
Original file line number Diff line number Diff line change
Expand Up @@ -305,9 +305,9 @@ def make_parser():
default=False,
action="store_true",
help="EXPERIMENTAL: warm-start each --globalAsymImpacts refit at the "
"Gaussian-approximation new minimum x_nom + dxdtheta0[:, i] * shift "
"Gaussian-approximation new minimum x_nom + dxdx0[:, source] * shift "
"(same Jacobian as --gaussianGlobalImpacts). On near-Gaussian "
"nuisances this should reduce per-nuisance refit cost by 10-50x. "
"sources this should reduce per-source refit cost by 10-50x. "
"Adds one --gaussianGlobalImpacts-equivalent precompute up front. "
"Off by default until validated on real tensors.",
)
Expand Down Expand Up @@ -410,16 +410,34 @@ def save_hists(args, mappings, fitter, ws, prefit=True, profile=False):

fitter_saturated = copy.deepcopy(fitter)

toy_theta0 = tf.identity(fitter_saturated.theta0)
# preserve the (possibly toy-randomized) constraint centers
# across the re-init: the theta block maps 1:1, and the
# original model's prior centers land at [0:npoi] and
# [composite.npoi : composite.npoi+npou] in the composite
# [POIs | POUs] layout; the saturated model's own params keep
# the freshly initialized centers
orig_model = fitter_saturated.param_model
toy_x0 = tf.identity(fitter_saturated.x0.value())
saved_regularizers = fitter_saturated.regularizers
saved_tau = float(fitter_saturated.tau.numpy())
fitter_saturated.init_fit_parms(
composite_model,
args.setConstraintMinimum,
unblind=args.unblind,
blinding_group=args.blindingGroup,
freeze_parameters=args.freezeParameters,
)
fitter_saturated.theta0.assign(toy_theta0)
fitter_saturated.x0[composite_model.nparams :].assign(
toy_x0[orig_model.nparams :]
)
if orig_model.npoi > 0:
fitter_saturated.x0[: orig_model.npoi].assign(
toy_x0[: orig_model.npoi]
)
if orig_model.npou > 0:
fitter_saturated.x0[
composite_model.npoi : composite_model.npoi + orig_model.npou
Comment thread
lucalavezzo marked this conversation as resolved.
].assign(toy_x0[orig_model.npoi : orig_model.nparams])
fitter_saturated.regularizers = saved_regularizers
fitter_saturated.tau.assign(saved_tau)

Expand Down Expand Up @@ -859,6 +877,27 @@ def main():
"nois": ifitter.parms[ifitter.param_model.nparams :][indata.noiidxs],
}

# ParamModel Gaussian priors (if the model declared sigmas). Read straight
# from the model (the single source of truth) so downstream tooling can see
# what was applied without parsing the rabbit log.
if getattr(ifitter, "param_prior_active", False):
pm = ifitter.param_model
np_dtype = ifitter.indata.dtype.as_numpy_dtype
sigmas = np.asarray(pm.prior_sigmas, dtype=np_dtype)
mask = np.isfinite(sigmas) & (sigmas > 0)
means = getattr(pm, "prior_means", None)
means = (
np.asarray(pm.xparamdefault).astype(np_dtype)
if means is None
else np.asarray(means, dtype=np_dtype)
)
meta["param_priors"] = {
"params": pm.params, # all nparams names
"mask": mask, # bool array
"sigmas": np.where(mask, sigmas, np.nan), # NaN where no prior
"means": np.where(mask, means, np.nan), # NaN where no prior
}

with workspace.Workspace(
args.outpath,
args.outname,
Expand Down
Loading