CMS 3D CMS Logo

ConfigurableHisto.h
Go to the documentation of this file.
1 #ifndef ConfigurableAnalysis_ConfigurableHisto_H
2 #define ConfigurableAnalysis_ConfigurableHisto_H
3 
6 
7 #include "TH1.h"
8 #include "TH1F.h"
9 #include "TH2F.h"
10 #include "TProfile.h"
11 #include "THStack.h"
12 
15 
16 
18  public:
21  nBin_(0),Min_(0),Max_(0),Label_(""){
22  Label_=par.getParameter<std::string>("Label");
23 
24  if (par.exists("nBins")){
25  nBin_=par.getParameter<unsigned int>("nBins");
26  Min_=par.getParameter<double>("Min");
27  Max_=par.getParameter<double>("Max");
28  }else{
29  if (par.exists("vBins"))
30  vBins_=par.getParameter<std::vector<double> >("vBins");
31  else{
32  Min_=par.getParameter<double>("Min");
33  Max_=par.getParameter<double>("Max");
34  }
35  }
36  }
37  bool variableSize(){return !vBins_.empty();}
38  unsigned int nBin(){if (variableSize()) return vBins_.size()-1;else return nBin_;}
39  double Min(){if (variableSize()) return vBins_.front(); else return Min_;}
40  double Max(){if (variableSize()) return vBins_.back(); else return Max_;}
41  const std::string & Label(){ return Label_;}
42  const double * xBins(){ if (!vBins_.empty()) return &(vBins_.front()); else return nullptr;}
43 
44  private:
45  std::vector<double> vBins_;
46  unsigned int nBin_;
47  double Min_;
48  double Max_;
50 };
51 
52 
54  public:
55  enum HType { h1 ,h2, prof };
57  type_(t),h_(nullptr),name_(name), conf_(iConfig),x_(nullptr),y_(nullptr),z_(nullptr),w_(nullptr){}
58 
59  virtual ~ConfigurableHisto(){}
60 
61  virtual ConfigurableHisto * clone() const { return new ConfigurableHisto(*this);}
62 
63  virtual void book(TFileDirectory* dir){
64  std::string title=conf_.getParameter<std::string>("title");
65  edm::ParameterSet xAxisPSet=conf_.getParameter<edm::ParameterSet>("xAxis");
66  ConfigurableAxis xAxis(xAxisPSet);
67  x_=edm::Service<VariableHelperService>()->get().variable(xAxisPSet.getParameter<std::string>("var"));
68 
69  std::string yLabel="";
70  bool yVBin=false;
72  if (conf_.exists("yAxis")){
73  edm::ParameterSet yAxisPSet=conf_.getParameter<edm::ParameterSet>("yAxis");
74  yAxis=ConfigurableAxis(yAxisPSet);
75  yLabel=yAxis.Label();
76  //at least TH2 or TProfile
77  if (yAxisPSet.exists("var"))
78  y_=edm::Service<VariableHelperService>()->get().variable(yAxisPSet.getParameter<std::string>("var"));
79  yVBin=yAxis.variableSize();
80  }
81 
82  if (conf_.exists("zAxis")){
83  throw;
84  }
85 
86  bool xVBin=xAxis.variableSize();
87 
88 
89  if (type()==h1){
90  //make TH1F
91  if (xVBin)
92  h_=dir->make<TH1F>(name_.c_str(),title.c_str(),
93  xAxis.nBin(), xAxis.xBins());
94  else
95  h_=dir->make<TH1F>(name_.c_str(),title.c_str(),
96  xAxis.nBin(),xAxis.Min(),xAxis.Max());
97  }
98  else if (type()==h2){
99  //make TH2F
100  if (xVBin){
101  if (yVBin)
102  h_=dir->make<TH2F>(name_.c_str(),title.c_str(),
103  xAxis.nBin(),xAxis.xBins(),
104  yAxis.nBin(),yAxis.xBins());
105  else
106  h_=dir->make<TH2F>(name_.c_str(),title.c_str(),
107  xAxis.nBin(),xAxis.xBins(),
108  yAxis.nBin(),yAxis.Min(),yAxis.Max());
109  }else{
110  if (yVBin)
111  h_=dir->make<TH2F>(name_.c_str(),title.c_str(),
112  xAxis.nBin(),xAxis.Min(),xAxis.Max(),
113  yAxis.nBin(),yAxis.xBins());
114  else
115  h_=dir->make<TH2F>(name_.c_str(),title.c_str(),
116  xAxis.nBin(),xAxis.Min(),xAxis.Max(),
117  yAxis.nBin(),yAxis.Min(),yAxis.Max());
118  }
119  }
120  else if (type()==prof){
121  //make TProfile
122  std::string pFopt="";
123  if (conf_.exists("Option"))
124  pFopt=conf_.getParameter<std::string>("Option");
125 
126  if (xVBin)
127  h_=dir->make<TProfile>(name_.c_str(),title.c_str(),
128  xAxis.nBin(), xAxis.xBins(),
129  yAxis.Min(),yAxis.Max(),
130  pFopt.c_str());
131  else
132  h_=dir->make<TProfile>(name_.c_str(),title.c_str(),
133  xAxis.nBin(),xAxis.Min(),xAxis.Max(),
134  yAxis.Min(),yAxis.Max(),
135  pFopt.c_str());
136 
137  }
138  else {
139  edm::LogError("ConfigurableHisto")<<"cannot book: "<<name_<<"\n"<<conf_.dump();
140  throw;
141  }
142 
143  //cosmetics
144  h_->GetXaxis()->SetTitle(xAxis.Label().c_str());
145  h_->SetYTitle(yLabel.c_str());
146 
147  if (conf_.exists("weight"))
148  {
149  w_=edm::Service<VariableHelperService>()->get().variable(conf_.getParameter<std::string>("weight"));
150  }
151  }
152 
153  virtual void fill(const edm::Event &iEvent) {
154  if (!h_) return;
155 
156  double weight=1.0;
157  if (w_){
158  if (w_->compute(iEvent))
159  weight=(*w_)(iEvent);
160  else{
161  edm::LogInfo("ConfigurableHisto")<<"could not compute the weight for: "<<name_
162  <<" with config:\n"<<conf_.dump()
163  <<" default to 1.0";
164  }
165  }
166 
167  TProfile * pcast(nullptr);
168  TH2 * h2cast(nullptr);
169  switch(type_){
170  case h1:
171  if (!h_) throw;
172  if (x_->compute(iEvent)) h_->Fill((*x_)(iEvent),weight);
173  else{
174  edm::LogInfo("ConfigurableHisto")<<"could not fill: "<<name_
175  <<" with config:\n"<<conf_.dump();
176  }
177  break;
178  case prof:
179  pcast=dynamic_cast<TProfile*>(h_);
180  if (!pcast) throw;
181  if (x_->compute(iEvent) && y_->compute(iEvent)) pcast->Fill((*x_)(iEvent),(*y_)(iEvent),weight);
182  else{
183  edm::LogInfo("ConfigurableHisto")<<"could not fill: "<<name_
184  <<" with config:\n"<<conf_.dump();
185  }
186  break;
187  case h2:
188  h2cast=dynamic_cast<TH2*>(h_);
189  if (!h2cast) throw;
190  if (x_->compute(iEvent) && y_->compute(iEvent)) h2cast->Fill((*x_)(iEvent),(*y_)(iEvent),weight);
191  else{
192  edm::LogInfo("ConfigurableHisto")<<"could not fill: "<<name_
193  <<" with config:\n"<<conf_.dump();
194  }
195  break;
196  }
197  }
198  const HType & type() { return type_;}
199 
200  void complete() {}
201  TH1 * h() {return h_;}
202 
203  protected:
205  type_=master.type_;
206  h_=nullptr; //no histogram attached in copy constructor
207  name_=master.name_;
208  conf_=master.conf_;
209  x_=master.x_;
210  y_=master.y_;
211  z_=master.z_;
212  w_=master.w_;
213  }
215  TH1 * h_;
218 
223 };
224 
226  public:
228  ConfigurableHisto(t,name,pset) , splitter_(nullptr) {
229  std::string title=pset.getParameter<std::string>("title");
230 
231  //allow for many splitters ...
232  if (pset.exists("splitters")){
233  //you want more than one splitter
234  std::vector<std::string> splitters = pset.getParameter<std::vector<std::string> >("splitters");
235  for (unsigned int s=0;s!=splitters.size();++s){
236  const CachingVariable * v=edm::Service<VariableHelperService>()->get().variable(splitters[s]);
237  const Splitter * splitter = dynamic_cast<const Splitter*>(v);
238  if (!splitter){
239  edm::LogError("SplittingConfigurableHisto")<<"for: "<<name_<<" the splitting variable: "<<splitters[s]<<" is not a Splitter";
240  continue;
241  }
242 
243  //insert in the map
244  std::vector<ConfigurableHisto*> & insertedHisto=subHistoMap_[splitter];
245  //now configure the histograms
246  unsigned int mSlots=splitter->maxSlots();
247  for (unsigned int i=0;i!=mSlots;++i){
248  //--- std::cout<<" slot: "<<i<<std::endl;
249  const std::string & slabel=splitter->shortLabel(i);
250  const std::string & label=splitter->label(i);
251  edm::ParameterSet mPset=pset;
252  edm::Entry e("string",title+" for "+label,true);
253  mPset.insert(true,"title",e);
254  insertedHisto.push_back(new ConfigurableHisto(t,name+slabel ,mPset));
255  }//loop on slots
256  }//loop on splitters
257 
258  }//if splitters exists
259  else{
260  //single splitter
261  //get the splitting variable
262  const CachingVariable * v=edm::Service<VariableHelperService>()->get().variable(pset.getParameter<std::string>("splitter"));
263  splitter_ = dynamic_cast<const Splitter*>(v);
264  if (!splitter_){
265  edm::LogError("SplittingConfigurableHisto")<<"for: "<<name_<<" the splitting variable: "<<v->name()<<" is not a Splitter";
266  }
267  else{
268  //configure the splitted plots
269  unsigned int mSlots=splitter_->maxSlots();
270  for (unsigned int i=0;i!=mSlots;i++){
271  const std::string & slabel=splitter_->shortLabel(i);
272  const std::string & label=splitter_->label(i);
273  edm::ParameterSet mPset=pset;
274  edm::Entry e("string",title+" for "+label,true);
275  mPset.insert(true,"title",e);
276  subHistos_.push_back(new ConfigurableHisto(t,name+slabel, mPset));
277  }
278  }
279  }
280  }//end of ctor
281 
282  void book(TFileDirectory* dir) override{
283  //book the base histogram
285 
286  if (!subHistoMap_.empty()){
287  SubHistoMap::iterator i=subHistoMap_.begin();
288  SubHistoMap::iterator i_end=subHistoMap_.end();
289  for (;i!=i_end;++i){for (unsigned int h=0;h!=i->second.size();++h){
290  i->second[h]->book(dir);}
291  //book the THStack
292  std::string sName= name_+"_"+i->first->name();
293  std::string sTitle="Stack histogram of "+name_+" for splitter "+i->first->name();
294  subHistoStacks_[i->first]= dir->make<THStack>(sName.c_str(),sTitle.c_str());
295  }
296  }else{
297  for (unsigned int h=0;h!=subHistos_.size();h++){subHistos_[h]->book(dir);}
298  //book a THStack
299  std::string sName= name_+"_"+splitter_->name();
300  std::string sTitle="Stack histogram of "+name_+" for splitter "+splitter_->name();
301  stack_ = dir->make<THStack>(sName.c_str(),sTitle.c_str());
302  }
303 
304  }
305 
306  ConfigurableHisto * clone() const override { return new SplittingConfigurableHisto(*this); }
307 
308  void fill(const edm::Event & e) override {
309  //fill the base histogram
311 
312  if (!subHistoMap_.empty()){
313  SubHistoMap::iterator i=subHistoMap_.begin();
314  SubHistoMap::iterator i_end=subHistoMap_.end();
315  for (;i!=i_end;++i){
316  const Splitter * splitter=i->first;
317  if (!splitter) continue;
318  if (!splitter->compute(e)) continue;
319  unsigned int slot=(unsigned int) (*splitter)(e);
320  if (slot>=i->second.size()){
321  edm::LogError("SplittingConfigurableHisto")<<"slot index: "<<slot<<" is bigger than slots size: "<<i->second.size()<<" from variable value: "<<(*splitter)(e);
322  continue;}
323  //fill in the proper slot
324  i->second[slot]->fill(e);
325  }
326  }
327  else{
328  //fill the component histograms
329  if (!splitter_) return;
330  if (!splitter_->compute(e)){
331  return;}
332  unsigned int slot=(unsigned int) (*splitter_)(e);
333  if (slot>=subHistos_.size()){
334  edm::LogError("SplittingConfigurableHisto")<<"slot index: "<<slot<<" is bigger than slots size: "<< subHistos_.size() <<" from variable value: "<<(*splitter_)(e);
335  return;}
336  subHistos_[slot]->fill(e);
337  }
338  }
339 
340  void complete(){
341  if (!subHistoMap_.empty()){
342  //fill up the stacks
343  SubHistoMap::iterator i=subHistoMap_.begin();
344  SubHistoMap::iterator i_end=subHistoMap_.end();
345  for (;i!=i_end;++i){
346  for (unsigned int h=0;h!=i->second.size();h++){
347  // if (i->second[h]->h()->Integral==0) continue;// do not add empty histograms. NO, because it will be tough to merge two THStack
348  subHistoStacks_[i->first]->Add(i->second[h]->h(), i->first->label(h).c_str());
349  }
350  }
351 
352  }else{
353  //fill up the only stack
354  for (unsigned int i=0;i!=subHistos_.size();i++){ stack_->Add(subHistos_[i]->h(), splitter_->label(i).c_str()); }
355  }
356 
357 
358  }
359  private:
361  splitter_ = master.splitter_;
362  if (!master.subHistoMap_.empty()){
363  SubHistoMap::const_iterator i=master.subHistoMap_.begin();
364  SubHistoMap::const_iterator i_end=master.subHistoMap_.end();
365  for (;i!=i_end;++i){
366  const std::vector<ConfigurableHisto*> & masterHistos=i->second;
367  std::vector<ConfigurableHisto*> & clonedHistos=subHistoMap_[i->first];
368  for (unsigned int i=0;i!=masterHistos.size();i++){clonedHistos.push_back(masterHistos[i]->clone());}
369  }
370  }else{
371  for (unsigned int i=0;i!=master.subHistos_.size();i++){subHistos_.push_back(master.subHistos_[i]->clone());}
372  }
373  }
374 
375  typedef std::map<const Splitter *, std::vector<ConfigurableHisto* > > SubHistoMap;
376  typedef std::map<const Splitter *, THStack *> SubHistoStacks;
377  SubHistoStacks subHistoStacks_;
378  SubHistoMap subHistoMap_;
379 
381  std::vector<ConfigurableHisto* > subHistos_;
382  // do you want to have a stack already made from the splitted histos?
383  THStack * stack_;
384 };
385 
386 #endif
type
Definition: HCALResponse.h:21
T getParameter(std::string const &) const
Master< F > master(const F &f)
Definition: FunctClone.h:68
def splitter(iterator, n)
Definition: confdb.py:11
const HType & type()
void book(TFileDirectory *dir) override
FWCore Framework interface EventSetupRecordImplementation h
Helper function to determine trigger accepts.
std::vector< double > vBins_
SplittingConfigurableHisto(const SplittingConfigurableHisto &master)
void fill(const edm::Event &e) override
const std::string & Label()
bool exists(std::string const &parameterName) const
checks if a parameter exists
virtual ConfigurableHisto * clone() const
unsigned int nBin_
Definition: weight.py:1
void insert(bool ok_to_replace, char const *, Entry const &)
std::map< const Splitter *, THStack * > SubHistoStacks
#define nullptr
SplittingConfigurableHisto(HType t, std::string name, edm::ParameterSet &pset)
virtual void fill(const edm::Event &iEvent)
ConfigurableHisto(HType t, std::string name, edm::ParameterSet &iConfig)
const CachingVariable * y_
int iEvent
Definition: GenABIO.cc:230
std::vector< ConfigurableHisto * > subHistos_
std::map< const Splitter *, std::vector< ConfigurableHisto * > > SubHistoMap
const std::string shortLabel(unsigned int i) const
virtual ~ConfigurableHisto()
virtual unsigned int maxSlots() const
ConfigurableHisto(const ConfigurableHisto &master)
const std::string & label(unsigned int i) const
ConfigurableHisto * clone() const override
T * make(const Args &...args) const
make new ROOT object
unsigned int nBin()
const CachingVariable * x_
virtual void book(TFileDirectory *dir)
const CachingVariable * w_
TEveGeoShape * clone(const TEveElement *element, TEveElement *parent)
Definition: eve_macros.cc:135
const double * xBins()
bool compute(const edm::Event &iEvent) const
edm::ParameterSet conf_
const CachingVariable * z_
dbl *** dir
Definition: mlp_gen.cc:35
const std::string & name() const
ConfigurableAxis(const edm::ParameterSet &par)