142 MACH3LOG_ERROR(
"No arguments! Usage: {} <config.yaml> <file1.root> <file2.root> ...", argv[0]);
147 YAML::Node Settings =
M3OpenConfig(std::string(argv[1]));
148 auto OutFileName = GetFromManager<std::string>(Settings[
"General"][
"OutputFile"],
"LLHMap.root", __FILE__, __LINE__);
149 auto Plot2D = GetFromManager<bool>(Settings[
"LLHScan"][
"Plot2D"],
false, __FILE__, __LINE__);
151 auto OutFile =
new TFile(
OutFileName.c_str(),
"UPDATE");
155 TDirectory* DirProfile1D = OutFile->mkdir(
"Profiled1D_LLH",
"profile1D",
true);
156 TDirectory* DirProfile2D =
nullptr;
157 if (Plot2D) DirProfile2D = OutFile->mkdir(
"Profiled2D_LLH",
"profile2D",
true);
159 TDirectory* DirMarginal1D = OutFile->mkdir(
"Marginal1D_L",
"marginal1D",
true);
160 TDirectory* DirMarginal2D =
nullptr;
161 if (Plot2D) DirMarginal2D = OutFile->mkdir(
"Marginal2D_L",
"marginal2D",
true);
166 for(
int i = 2; i < argc; ++i)
173 auto Map = ROOT::RDataFrame(
"llhmap",
inpFileList);
177 auto LLHMap = Map.Define(
"L",
"exp(-0.5*Total_LLH)");
180 auto ParamsOfInterest = GetFromManager<std::vector<std::string>>(Settings[
"LLHScan"][
"LLHParameters"],{}, __FILE__, __LINE__);
181 std::vector<std::string> ParamsToProfile =
GetParams(ParamsOfInterest, Map);
183 MACH3LOG_INFO(
"... Starting generating 1D profiled and marginalized likelihoods ...");
184 MACH3LOG_WARN(
"!!! LLHMap numerical marginalization assumes uncorrelated priors !!!");
186 std::map<std::string, std::unique_ptr<TH1D>> hProfiles1d;
187 std::map<std::string, std::unique_ptr<TH1D>> hMarginals1d;
188 for(
auto p = ParamsToProfile.begin(); p != ParamsToProfile.end(); ++p)
193 std::pair<bool, std::vector<double>> binning =
ExtractBinning(*p, Settings, Map);
195 std::string hProfTitle = *p+
" profiled -2LogL";
196 std::string hProfName = *p+
"_LLHProf1D";
197 std::string hMargTitle = *p+
" marginalized L";
198 std::string hMargName = *p+
"_LMarg1D";
201 auto hprof1d = std::make_unique<TH1D>(hProfName.c_str(), hProfTitle.c_str(),
int(binning.second.size()-1), binning.second.data());
202 hprof1d->SetDirectory(
nullptr);
204 auto hmarg1d = std::make_unique<TH1D>(hMargName.c_str(), hMargTitle.c_str(),
int(binning.second.size()-1), binning.second.data());
205 hmarg1d->SetDirectory(
nullptr);
209 MACH3LOG_INFO(
"Initializing 1D profiled -2LogL and marginalized L histograms for {} of {} bins from {:.3e} to {:.3e} (bin center at {:.3e} and {:.3e})", *p, hprof1d->GetNbinsX(), hprof1d->GetXaxis()->GetXmin(), hprof1d->GetXaxis()->GetXmax(), hprof1d->GetBinCenter(1), hprof1d->GetBinCenter(hprof1d->GetNbinsX()));
213 for (
auto binnie : binning.second)
215 std::ostringstream os;
216 os << std::scientific << std::setprecision(4) << binnie;
217 binnies +=
" "+os.str();
220 MACH3LOG_INFO(
"Initializing 1D profiled -2LogL and marginalized L histograms of {} bins with edges{}.", binning.second.size(), binnies);
223 hProfiles1d[*p] = std::move(hprof1d);
224 hMarginals1d[*p] = std::move(hmarg1d);
227 for(
auto p = ParamsToProfile.begin(); p != ParamsToProfile.end(); ++p)
231 const int count = hProfiles1d[*p]->GetNbinsX() > 5 ? int(
double(hProfiles1d[*p]->GetNbinsX())/
double(5)) : 1;
234 MACH3LOG_INFO(
"Profiling 1D -2LogL and numerically profiling 1D L for parameter {}!", *p);
235 for(
int bidx = 1; bidx < hProfiles1d[*p]->GetNbinsX() + 1; ++bidx)
237 if (bidx % count == 0)
240 auto b_lo = hProfiles1d[*p]->GetXaxis()->GetBinLowEdge(bidx);
241 auto b_hi = b_lo + hProfiles1d[*p]->GetXaxis()->GetBinWidth(bidx);
243 double llhmin = LLHMap.Filter(*p+
">"+std::to_string(b_lo)+
"&&"+*p+
"<"+std::to_string(b_hi)).Min(
"Total_LLH").GetValue();
247 hProfiles1d[*p]->SetBinContent(bidx, llhmin);
249 auto L = LLHMap.Filter(*p+
">"+std::to_string(b_lo)+
"&&"+*p+
"<"+std::to_string(b_hi)).Sum(
"L");
251 hMarginals1d[*p]->SetBinContent(bidx, *L);
256 hProfiles1d[*p]->Write(hProfiles1d[*p]->GetName(), TObject::kOverwrite);
259 hMarginals1d[*p]->Scale(1./hMarginals1d[*p]->Integral());
260 hMarginals1d[*p]->Write(hMarginals1d[*p]->GetName(), TObject::kOverwrite);
266 MACH3LOG_INFO(
"... Starting generating 2D profiled and marginalized likelihoods ...");
268 MACH3LOG_WARN(
"!!! LLHMap numerical marginalization assumes uncorrelated priors !!!");
270 std::vector<std::string> Keys2D;
271 std::vector<std::string> ParamsFiltered;
272 std::map<std::string, std::unique_ptr<TH2D>> hProfiles2d;
273 std::map<std::string, std::unique_ptr<TH2D>> hMarginals2d;
275 for(
auto p : ParamsToProfile)
277 auto h = DirProfile1D->Get<TH1D>((p+
"_LLHProf1D").c_str());
280 MACH3LOG_WARN(
"There is less than 2 bins for {}, 2D is equivalent to 1D! Removing from 2D plots ...", p);
282 ParamsFiltered.push_back(p);
287 for(
auto p1 = ParamsFiltered.begin(); p1 != ParamsFiltered.end(); ++p1)
289 for(
auto p2 = std::next(p1); p2 != ParamsFiltered.end(); ++p2)
291 auto h1 = DirProfile1D->Get<TH1D>((*p1+
"_LLHProf1D").c_str());
292 auto h2 = DirProfile1D->Get<TH1D>((*p2+
"_LLHProf1D").c_str());
294 std::string key = *p1+
"_"+*p2;
295 Keys2D.push_back(key);
297 MACH3LOG_INFO(
"Initializing 2D profiled -2LogL and marginalized L histograms for {} vs. {} based on previously generated 1D histograms.", *p1, *p2);
299 std::string hProfTitle = *p1+
" vs. "+*p2+
" profiled -2LogL";
300 std::string hProfName = key+
"_LLHProf2D";
301 auto hprof2d = std::make_unique<TH2D>(
302 hProfName.c_str(), hProfTitle.c_str(),
303 h1->GetXaxis()->GetNbins(), h1->GetXaxis()->GetXbins()->GetArray(),
304 h2->GetXaxis()->GetNbins(), h2->GetXaxis()->GetXbins()->GetArray()
306 hprof2d->SetDirectory(
nullptr);
308 hProfiles2d[key] = std::move(hprof2d);
310 std::string hMargTitle = *p1+
" vs. "+*p2+
" marginalized L";
311 std::string hMargName = key+
"_LMarg1D";
312 auto hmarg2d = std::make_unique<TH2D>(
313 hMargName.c_str(), hMargTitle.c_str(),
314 h1->GetXaxis()->GetNbins(), h1->GetXaxis()->GetXbins()->GetArray(),
315 h2->GetXaxis()->GetNbins(), h2->GetXaxis()->GetXbins()->GetArray()
317 hmarg2d->SetDirectory(
nullptr);
319 hMarginals2d[key] = std::move(hmarg2d);
323 for(
auto p1 = ParamsFiltered.begin(); p1 != ParamsFiltered.end(); ++p1)
325 for(
auto p2 = std::next(p1); p2 != ParamsFiltered.end(); ++p2)
327 std::string key = *p1+
"_"+*p2;
329 MACH3LOG_INFO(
"Numerically profiling 2D -2LogL and marginalizing 2D L for parameters {} and {}!",*p1, *p2);
330 const Long64_t nBinsX =
static_cast<Long64_t
>(hProfiles2d[key]->GetNbinsX());
331 const Long64_t nBinsY =
static_cast<Long64_t
>(hProfiles2d[key]->GetNbinsY());
333 const Long64_t TotalBins = nBinsX * nBinsY;
334 const int count = TotalBins > 5 ? int(
double(TotalBins)/
double(5)) : 1;
336 for(
int bidx = 1; bidx < nBinsX + 1; ++bidx)
338 for(
int bidy = 1; bidy < nBinsY + 1; ++bidy)
340 if ( ((bidx-1)*hProfiles2d[key]->GetNbinsY() + bidy) % count == 0)
343 auto bx_lo = hProfiles2d[key]->GetXaxis()->GetBinLowEdge(bidx);
344 auto bx_hi = bx_lo + hProfiles2d[key]->GetXaxis()->GetBinWidth(bidx);
346 auto by_lo = hProfiles2d[key]->GetYaxis()->GetBinLowEdge(bidy);
347 auto by_hi = by_lo + hProfiles2d[key]->GetYaxis()->GetBinWidth(bidy);
350 double llhmin = LLHMap.Filter(*p1+
">"+std::to_string(bx_lo)+
"&&"+*p1+
"<"+std::to_string(bx_hi)+
"&&"+*p2+
">"+std::to_string(by_lo)+
"&&"+*p2+
"<"+std::to_string(by_hi)).Min(
"Total_LLH").GetValue();
354 hProfiles2d[key]->SetBinContent(bidx, bidy, llhmin);
356 auto L = LLHMap.Filter(*p1+
">"+std::to_string(bx_lo)+
"&&"+*p1+
"<"+std::to_string(bx_hi)
357 +
"&&"+*p2+
">"+std::to_string(by_lo)+
"&&"+*p2+
"<"+std::to_string(by_hi)).Sum(
"L");
359 hMarginals2d[key]->SetBinContent(bidx,bidy, *L);
365 hProfiles2d[key]->Write(hProfiles2d[key]->GetName(), TObject::kOverwrite);
368 hMarginals2d[key]->Scale(1./hMarginals2d[key]->Integral());
369 hMarginals2d[key]->Write(hMarginals2d[key]->GetName(), TObject::kOverwrite);
std::vector< std::string > inpFileList
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
std::pair< bool, std::vector< double > > ExtractBinning(std::string param, YAML::Node Settings, ROOT::RDataFrame Map)
std::vector< std::string > GetParams(std::vector< std::string > &PoIs, ROOT::RDataFrame Map)
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Custom exception class used throughout MaCh3.
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
constexpr static const double _LARGE_LOGL_
Large Likelihood is used it parameter go out of physical boundary, this indicates in MCMC that such s...