12 if (biasFunctionName ==
"gaussian") {
15 if (biasFunctionName ==
"vonMises") {
18 if (biasFunctionName ==
"generalisedGaussian") {
22 throw MaCh3Exception(__FILE__, __LINE__,
"Unknown multicanonical bias function: " + biasFunctionName);
56 void MulticanonicalMCMCHandler::setDebugStream(std::ostream* os,
bool enabled) {
58 debugEnabled = enabled;
63 bool foundDeltaCP =
false;
64 bool foundDelm23 =
false;
67 MACH3LOG_INFO(
"Looping over systematics to find delta_cp parameter");
68 MACH3LOG_INFO(
"Number of systematics: {}", systematics.size());
70 for (
size_t iCov = 0; iCov < systematics.size(); iCov++){
71 auto* syst = systematics[
static_cast<int>(iCov)];
72 for (
int i = 0; i < syst->GetNumParams(); i++) {
73 if (syst->GetParName(i) ==
"delta_cp") {
74 MACH3LOG_INFO(
"Found delta_cp parameter in systematic {} at index {}", syst->GetName(), i);
79 if (syst->GetParName(i) ==
"delm2_23") {
80 MACH3LOG_INFO(
"Found delm2_23 parameter in systematic {} at index {}", syst->GetName(), i);
89 MACH3LOG_ERROR(
"Could not find delta_cp parameter in osc_cov systematic");
90 throw MaCh3Exception(__FILE__, __LINE__,
"Could not find delta_cp parameter in osc_cov systematic");
93 MACH3LOG_ERROR(
"Could not find delm2_23 parameter in osc_cov systematic");
94 throw MaCh3Exception(__FILE__, __LINE__,
"Could not find delm2_23 parameter in osc_cov systematic");
101 const auto mcmcConfig = fitMan->
raw()[
"General"][
"MCMC"];
105 multicanonicalBeta = Get<double>(mcmcConfig[
"Multicanonical"][
"Beta"], __FILE__, __LINE__);
110 multicanonicalSpline = GetFromManager<bool>(mcmcConfig[
"Multicanonical"][
"Spline"][
"SplineMode"],
false, __FILE__, __LINE__);
112 const std::string biasFunctionName = GetFromManager<std::string>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaBiasFunction"],
"", __FILE__, __LINE__);
113 const bool hasBiasFunction = !biasFunctionName.empty();
117 MACH3LOG_ERROR(
"Cannot use multicanonical spline together with umbrella bias function selection.");
118 throw MaCh3Exception(__FILE__, __LINE__,
"Cannot use multicanonical spline together with umbrella bias function selection.");
123 MACH3LOG_ERROR(
"Multicanonical umbrella mode requires UmbrellaBiasFunction to be set (gaussian, vonMises, or generalisedGaussian).");
124 throw MaCh3Exception(__FILE__, __LINE__,
"Multicanonical umbrella mode requires UmbrellaBiasFunction to be set.");
128 if (hasBiasFunction) {
136 auto splineFileName = Get<std::string>(mcmcConfig[
"Multicanonical"][
"Spline"][
"SplineFile"], __FILE__, __LINE__);
137 TFile* splineFile =
M3::Open(splineFileName.c_str(),
"READ",__FILE__, __LINE__);
140 TSpline3* dcp_spline_IO_fromfile =
static_cast<TSpline3*
>(splineFile->Get(
"dcp_spline_IO"));
141 dcp_spline_IO =
static_cast<TSpline3*
>(dcp_spline_IO_fromfile->Clone(
"dcp_spline_IO"));
142 MACH3LOG_INFO(
"Using multicanonical spline from file {}", splineFileName);
146 TSpline3* dcp_spline_NO_fromfile =
static_cast<TSpline3*
>(splineFile->Get(
"dcp_spline_NO"));
147 dcp_spline_NO =
static_cast<TSpline3*
>(dcp_spline_NO_fromfile->Clone(
"dcp_spline_NO"));
148 MACH3LOG_INFO(
"Using multicanonical spline from file {}", splineFileName);
153 splineFile =
nullptr;
157 umbrellaMean = GetFromManager<double>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaMean"], 0, __FILE__, __LINE__);
160 umbrellaNumber = GetFromManager<int>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaNumber"], 5, __FILE__, __LINE__);
165 umbrellaOverlapMode = GetFromManager<bool>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"AutoOverlapMode"],
false, __FILE__, __LINE__);
168 MACH3LOG_INFO(
"Setting width based on # of sigma overlapping between umbrellas");
169 umbrellaSigmaOverlap = GetFromManager<double>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"SigmaOverlap"], 3.0, __FILE__, __LINE__);
174 umbrellaWidth = GetFromManager<double>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaWidth"], (2 * TMath::Pi()) /
umbrellaNumber, __FILE__, __LINE__);
180 umbrellaAdjustStepScale = GetFromManager<bool>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaAdjustStepScale"],
false, __FILE__, __LINE__);
181 umbrellaStepScaleFactor = GetFromManager<double>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaStepScaleFactor"], 1.0, __FILE__, __LINE__);
193 double temp_vonMises_sigma;
194 temp_vonMises_sigma = GetFromManager<double>(mcmcConfig[
"Multicanonical"][
"Umbrella"][
"UmbrellaWidth"],
umbrellaWidth, __FILE__, __LINE__);
195 vonMises_kappa = 1.0 / (temp_vonMises_sigma * temp_vonMises_sigma);
207 MACH3LOG_INFO(
"Adjusting umbrella step scale to keep ratio of step scale to multicanonical sigma constant");
210 MACH3LOG_INFO(
"Setting individual step scale for multicanonical separate to {}", stepScale);
214 MACH3LOG_INFO(
"Not adjusting umbrella step scale, using value in OscCov config");
221 systematics[
oscCovVar]->PrintPreFitCurrPropValues();
232 systematics[
oscCovVar]->PrintPreFitCurrPropValues();
264 double dcp_spline_val;
279 const double inv_sqrt_2pi = 1 / std::sqrt(2 * TMath::Pi());
289 double likelihood = normFactor * std::exp(-std::pow((std::pow(x - mean, 2) / (2 * std::pow(width, 2))), n));
302 if (debugStream && debugEnabled) (*debugStream) <<
" g0: " << g0 <<
" g1: " << g1 <<
" g2: " << g2 << std::endl;
309 constexpr
double inv_sqrt_2pi = 0.3989422804014337;
311 const double neg_half_sigma_sq = -1 / (2 * sigma * sigma);
313 double exp1 = std::exp(neg_half_sigma_sq * (deltacp - TMath::Pi()) * (deltacp - TMath::Pi()));
314 double exp2 = std::exp(neg_half_sigma_sq * (deltacp) * (deltacp));
315 double exp3 = std::exp(neg_half_sigma_sq * (deltacp + TMath::Pi()) * (deltacp + TMath::Pi()));
320 return -std::log(inv_sqrt_2pi * (1 / sigma) * (exp1 + exp2 + exp3)) * (
multicanonicalBeta);
M3::BiasFunction ParseBiasFunction(const std::string &biasFunctionName)
Custom exception class used throughout MaCh3.
The manager class is responsible for managing configurations and settings.
YAML::Node const & raw() const
Return config.
double vonMises_I0_kappa
Cached I0(kappa) value for the von Mises form.
double umbrellaSigmaOverlap
Requested overlap for evenly spaced umbrellas.
void InitializeMulticanonicalParams(std::vector< ParameterHandlerBase * > &systematics)
Initialise the starting values used by the multicanonical parameter handling.
void InitializeMulticanonicalHandlerConfig(Manager *fitMan, std::vector< ParameterHandlerBase * > &systematics)
Read multicanonical configuration from the yaml via manager and initialise handler state.
double delm23_value
delm2_23 value used during proposal evaluation.
double umbrellaWidth
Umbrella width used for the current configuration.
TSpline3 * dcp_spline_IO
Spline for the IO branch, if spline mode is enabled.
void AdjustUmbrellaStepScale(const std::vector< ParameterHandlerBase * > &systematics)
Adjust the parameter-of-interest's step scale according to the width of the umbrella bias function.
int multicanonicalVar_dm23
Parameter index used for the multicanonical delm2_23 weight.
M3::BiasFunction umbrellaBiasFunction
Selected bias function for multicanonical weights.
double GetMulticanonicalWeightVonMises(double deltacp)
Compute a von Mises multicanonical penalty.
TSpline3 * dcp_spline_NO
Spline for the NO branch, if spline mode is enabled.
bool multicanonicalSpline
Toggle for spline-based multicanonical weights.
bool umbrellaOverlapMode
Toggle for deriving umbrella widths from a desired # of sigma overlaps between umbrellas.
void FindOscCovParams(const std::vector< ParameterHandlerBase * > &systematics)
Locate the systematic object which contains the parameters used by the handler. Stores the parameter ...
double vonMises_kappa
Von Mises kappa parameter. Analogue of sigma for a gaussian.
bool flipWindow
Optional flip-window control.
double delta_cp_value
delta_cp value used during proposal evaluation.
MulticanonicalMCMCHandler()
Constructor.
double GetMulticanonicalWeight(double deltacp, double delm23_value)
Compute the multicanonical penalty for the configured bias mode.
std::string umbrellaBiasFunctionName
Configured bias function name for logging.
double GetMulticanonicalWeightSpline(double deltacp, double delm23_value)
Compute the multicanonical penalty using a spline.
double umbrellaMean
Umbrella centre used for the current configuration.
virtual ~MulticanonicalMCMCHandler()
Destructor.
double GetMulticanonicalWeightTripleGaussian(double deltacp)
Compute a triple-Gaussian multicanonical penalty.
double umbrellaStepScaleFactor
Additional scale factor applied when rescaling the step size. This is for fine tuning.
int oscCovVar
Index of the oscillation-covariance systematic in the current fit.
int multicanonicalVar
Parameter index used for the multicanonical delta_cp weight.
int umbrellaNumber
Number of total umbrellas used for the current configuration.
double generalisedGaussian2(double x, double mean, double width)
Wraps the generalised gaussian function for a given x, mean, and width. Required to handle the wrappi...
double GetMulticanonicalWeightGenGaussian(double deltacp)
Compute a generalised-Gaussian multicanonical penalty.
bool umbrellaAdjustStepScale
Toggle for rescaling the step size based on the umbrella width.
double GetMulticanonicalWeightGaussian(double deltacp)
Compute a Gaussian multicanonical penalty.
double multicanonicalBeta
Global scale factor applied to the multicanonical penalty. 1 is full strength, 0 is no penalty.
double circularDistance(double x, double mean)
Compute the circular distance between two angles.
TFile * Open(const std::string &Name, const std::string &Type, const std::string &File, const int Line)
Opens a ROOT file with the given name and mode.
constexpr double UmbrellaGaussianNormFactor
@ kGaussian
Assumes gaussian prior.