MaCh3  2.4.2
Reference Guide
Functions
PlotLLHMap.cpp File Reference

Processing n-dimensional LLHMap outputs generating 1D and 2D profiled likelihoods as defined in config. More...

#include "Manager/Manager.h"
#include <ROOT/RDataFrame.hxx>
Include dependency graph for PlotLLHMap.cpp:

Go to the source code of this file.

Functions

std::vector< std::string > GetParams (std::vector< std::string > &PoIs, ROOT::RDataFrame Map)
 
int main (int argc, char *argv[])
 

Detailed Description

Processing n-dimensional LLHMap outputs generating 1D and 2D profiled likelihoods as defined in config.

Author
Tomas Nosek

Definition in file PlotLLHMap.cpp.

Function Documentation

◆ GetParams()

std::vector<std::string> GetParams ( std::vector< std::string > &  PoIs,
ROOT::RDataFrame  Map 
)

Definition at line 17 of file PlotLLHMap.cpp.

19 {
20  std::vector<std::string> PtPs;
21 
22  if(PoIs.empty())
23  MACH3LOG_INFO("No parameters requested, processing all parameters found in the LLHMap!");
24 
25  // First, filter out all non-parametric (LLH) columns of LLHMap
26  for(auto p : Map.GetColumnNames())
27  {
28  if(p.find("_LLH") != std::string::npos)
29  continue;
30 
31  PtPs.push_back(p);
32  }
33 
34  // Check if the parameters user wants to plot, actually live in the LLHMap
35  // Remove from the list if not
36  for(auto pit = PoIs.begin(); pit != PoIs.end();)
37  {
38  if(std::find(PtPs.begin(), PtPs.end(), *pit) != PtPs.end())
39  {
40  ++pit;
41  } else {
42  MACH3LOG_WARN("Parameter {} not found in the LLHMap!", *pit);
43  pit = PoIs.erase(pit);
44  }
45  }
46 
47  // Check what LLHMap parameters the user wants to plot
48  // Remove from the list if not
49  for(auto pit = PtPs.begin(); pit != PtPs.end();)
50  {
51  if(std::find(PoIs.begin(), PoIs.end(), *pit) != PoIs.end() || PoIs.empty())
52  ++pit;
53  else
54  pit = PtPs.erase(pit);
55  }
56 
57  // Return the vector of parameters we are about to plot
58  return PtPs;
59 }
#define MACH3LOG_INFO
Definition: MaCh3Logger.h:35
#define MACH3LOG_WARN
Definition: MaCh3Logger.h:36

◆ main()

int main ( int  argc,
char *  argv[] 
)

Definition at line 62 of file PlotLLHMap.cpp.

62  {
63 // *******************
66 
67  if(argc < 3)
68  {
69  MACH3LOG_ERROR("No arguments! Usage: {} <config.yaml> <file1.root> <file2.root> ...", argv[0]);
70  throw MaCh3Exception(__FILE__ , __LINE__ );
71  }
72 
73  // Open the settings and output file
74  YAML::Node Settings = M3OpenConfig(std::string(argv[1]));
75  auto OutFileName = GetFromManager<std::string>(Settings["General"]["OutputFile"], "LLHMap.root");
76 
77  auto OutFile = new TFile(OutFileName.c_str(),"UPDATE");
78  OutFile->cd();
79 
80  // Prepare dirs for profiled LLHs
81  TDirectory* DirProfile1D = OutFile->mkdir("Profiled1D_LLH", "profile1D", true);
82  TDirectory* DirProfile2D = OutFile->mkdir("Profiled2D_LLH", "profile2D", true);
83 
84  // Get the list of input files
85  std::vector<std::string> inpFileList;
86  for(int i = 2; i < argc; ++i)
87  {
88  inpFileList.push_back(std::string(argv[i]));
89  MACH3LOG_INFO("Adding file(s): {}", inpFileList.back().c_str());
90  }
91 
92  // Read the llhmap trees from the input files
93  ROOT::RDataFrame LLHMap("llhmap", inpFileList);
94 
95  // Process what parameters to plot
96  auto ParamsOfInterest = GetFromManager<std::vector<std::string>>(Settings["LLHScan"]["LLHParameters"],{});
97  std::vector<std::string> ParamsToProfile = GetParams(ParamsOfInterest, LLHMap);
98 
99  // This now only works for uniform LLHMaps
100  // TODO: Think how to allow for non-uniform LLHMaps
101  MACH3LOG_INFO("!!Assuming a uniform binning of the LLHScan!!");
102 
103  MACH3LOG_INFO("... Starting generating 1D profiled log likelihoods ...");
104 
105  DirProfile1D->cd();
106  for(auto p : ParamsToProfile)
107  {
108  // Find the binning for each histogram
109 
110  // Expected number of bins based on the config
111  int nExpBins = GetFromManager<int>(Settings["LLHScan"]["LLHScanPoints"], 20, __FILE__, __LINE__);
112  if(CheckNodeExists(Settings,"LLHScan","ScanPoints"))
113  nExpBins = GetFromManager<int>(Settings["LLHScan"]["ScanPoints"][p], nExpBins, __FILE__, __LINE__);
114 
115  // Calculate the number of bins from the LLHMap
116  std::set<double> cBins;
117  auto checkBin = [&cBins](double var) {
118  if(!(std::find(cBins.begin(), cBins.end(), var) != cBins.end())) cBins.emplace(var);
119  };
120 
121  LLHMap.Foreach(checkBin, {p.c_str()});
122 
123  if(nExpBins != int(cBins.size())) {
124  MACH3LOG_WARN("The config expects different number of {} bins for parameter {} than {} values included in LLHMap!", nExpBins, p, cBins.size());
125  nExpBins = int(cBins.size());
126  }
127 
128  MACH3LOG_INFO("There are {} values (bins) for parameter {} inside LLHMap.", nExpBins, p);
129 
130  // Preparing a histogram. Again, this now works only with uniform steps in LLHMap
131  double minx = LLHMap.Min(p.c_str()).GetValue();
132  double maxx = LLHMap.Max(p.c_str()).GetValue();
133  double binw = std::abs(maxx-minx)/double(nExpBins-1);
134 
135  minx = minx-.5*binw;
136  maxx = maxx+.5*binw;
137 
138  MACH3LOG_INFO("Generating a Profile1DLLH histogram for {} of {} bins from {} to {} (bin center at {} and {})", p, nExpBins, minx, maxx, minx+.5*binw, maxx-.5*binw);
139 
140  std::string hTitle = p+" profiled LLH";
141  std::string hName = p+"_LLHProf1D";
142  TH1D* hprof1d = new TH1D(hName.c_str(), hTitle.c_str(), nExpBins, minx, maxx);
143 
144  // Now loop over the bins. For each bin, find the minimal Total_LLH over the rest of the parameter space.
145  // TODO: Switch between different LLHs (sample, xsec, etc.)
146  for(int bidx = 1; bidx < hprof1d->GetNbinsX() + 1; ++bidx)
147  {
148  const int count = int(double(hprof1d->GetNbinsX())/double(5));
149  if (bidx % count == 0)
150  MaCh3Utils::PrintProgressBar(bidx, hprof1d->GetNbinsX());
151 
152  auto b_lo = hprof1d->GetXaxis()->GetBinLowEdge(bidx);
153  auto b_hi = b_lo + hprof1d->GetXaxis()->GetBinWidth(bidx);
154 
155  double llhmin = LLHMap.Filter(p+">"+std::to_string(b_lo)+"&&"+p+"<"+std::to_string(b_hi)).Min("Total_LLH").GetValue();
156 
157  if(llhmin > M3::_LARGE_LOGL_) llhmin = M3::_LARGE_LOGL_;
158  hprof1d->SetBinContent(bidx, llhmin);
159  }
160 
161  // Save the 1D profiled histogram
162  hprof1d->Write(hName.c_str(), TObject::kOverwrite);
163  }
164 
165  MACH3LOG_INFO("... Starting generating 2D profiled log likelihoods ...");
166 
167  DirProfile2D->cd();
168  std::vector<std::string> Strings2D;
169 
170  // Similar as with 1D profiles, but looping over parameters twice
171  for(auto p1 : ParamsToProfile)
172  {
173  for(auto p2 : ParamsToProfile)
174  {
175  // Skip whenever p1 == p2 or already profiled in reversed order (p1-p2 or p2-p1)
176  if(p1 == p2)
177  continue;
178  if(std::find(Strings2D.begin(), Strings2D.end(), p2+"_"+p1) != Strings2D.end())
179  continue;
180 
181  std::string h1Name = p1+"_LLHProf1D";
182  std::string h2Name = p2+"_LLHProf1D";
183 
184  // Get the binning info from 1D histograms
185  auto h1 = DirProfile1D->Get<TH1D>(h1Name.c_str());
186  auto h2 = DirProfile1D->Get<TH1D>(h2Name.c_str());
187 
188  // Auxiliary
189  int nx = h1->GetNbinsX();
190  double minx = h1->GetBinLowEdge(1);
191  double maxx = h1->GetBinLowEdge(nx)+h1->GetBinWidth(nx);
192 
193  int ny = h2->GetNbinsX();
194  double miny = h2->GetBinLowEdge(1);
195  double maxy = h2->GetBinLowEdge(ny)+h2->GetBinWidth(ny);
196 
197  std::string hTitle = p1+" vs. "+p2+" profiled LLH";
198  std::string hName = p1+"_"+p2+"_LLHProf2D";
199  TH2D* hprof2d = new TH2D(hName.c_str(), hTitle.c_str(), nx, minx, maxx, ny, miny, maxy);
200 
201  MACH3LOG_INFO("The 2D histogram has {} x-bins from {} to {} and {} y-bins from {} to {}", nx, minx, maxx, ny, miny, maxy);
202 
203  for(int bidx = 1; bidx < hprof2d->GetNbinsX() + 1; ++bidx)
204  {
205  for(int bidy = 1; bidy < hprof2d->GetNbinsY() + 1; ++bidy)
206  {
207  const int count = int(double(hprof2d->GetNbinsX()*hprof2d->GetNbinsY())/double(5));
208  if ( ((bidx-1)*hprof2d->GetNbinsY() + bidy) % count == 0)
209  MaCh3Utils::PrintProgressBar((bidx-1)*hprof2d->GetNbinsY() + bidy, hprof2d->GetNbinsX()*hprof2d->GetNbinsY());
210 
211  auto bx_lo = hprof2d->GetXaxis()->GetBinLowEdge(bidx);
212  auto bx_hi = bx_lo + hprof2d->GetXaxis()->GetBinWidth(bidx);
213 
214  auto by_lo = hprof2d->GetYaxis()->GetBinLowEdge(bidy);
215  auto by_hi = by_lo + hprof2d->GetYaxis()->GetBinWidth(bidy);
216 
217  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();
218 
219  if(llhmin > M3::_LARGE_LOGL_) llhmin = M3::_LARGE_LOGL_;
220  hprof2d->SetBinContent(bidx, bidy, llhmin);
221  }
222  }
223 
224  hprof2d->Write(hName.c_str(), TObject::kOverwrite);
225 
226  Strings2D.push_back(p1+"_"+p2);
227  }
228  }
229 
230  OutFile->Close();
231 
232  return 0;
233 }
std::string OutFileName
std::vector< std::string > inpFileList
#define MACH3LOG_ERROR
Definition: MaCh3Logger.h:37
void SetMaCh3LoggerFormat()
Set messaging format of the logger.
Definition: MaCh3Logger.h:61
std::vector< std::string > GetParams(std::vector< std::string > &PoIs, ROOT::RDataFrame Map)
Definition: PlotLLHMap.cpp:17
bool CheckNodeExists(const YAML::Node &node, Args... args)
KS: Wrapper function to call the recursive helper.
Definition: YamlHelper.h:60
#define M3OpenConfig(filename)
Macro to simplify calling LoadYaml with file and line info.
Definition: YamlHelper.h:589
Custom exception class used throughout MaCh3.
constexpr static const double _LARGE_LOGL_
Large Likelihood is used it parameter go out of physical boundary, this indicates in MCMC that such s...
Definition: Core.h:80
void PrintProgressBar(const Long64_t Done, const Long64_t All)
KS: Simply print progress bar.
Definition: Monitor.cpp:228
void MaCh3Welcome()
KS: Prints welcome message with MaCh3 logo.
Definition: Monitor.cpp:12