CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
CachingVariable.h
Go to the documentation of this file.
1 #ifndef ConfigurableAnalysis_CachingVariable_H
2 #define ConfigurableAnalysis_CachingVariable_H
3 
11 
13 
14 namespace edm {
15  class EventSetup;
16 }
17 #include <vector>
18 #include "TString.h"
19 
20 class Description {
21  public:
23  Description(std::vector<std::string> & d) : d_(d){}
24  std::string text() const {
26  for (unsigned int i=0;i!=d_.size();++i)
27  text+=d_[i]+"\n";
28  return text;
29  }
30  const std::vector<std::string> lines(){return d_;}
31  void addLine(const std::string & l){d_.push_back(l);}
32  private :
33  std::vector<std::string> d_;
34 };
35 
36 class VariableComputer;
37 
39  public:
40  //every variable return double values
41  typedef double valueType;
42  typedef std::pair<bool, valueType> evalType;
43  typedef std::map<std::string, const CachingVariable*> vMap;
50  };
51 
53  cache_(std::make_pair(false,0)),method_(m),
54  name_(n),conf_(iConfig) {}
55 
56  virtual ~CachingVariable() {}
57 
58  //does the variable computes
59  bool compute(const edm::Event & iEvent) const { return baseEval(iEvent).first; }
60 
61  //accessor to the computed/cached value
62  valueType operator()(const edm::Event & iEvent) const { return baseEval(iEvent).second; }
63 
64  const std::string & name() const {return name_;}
65  const std::string & method() const { return method_;}
66  const Description & description()const { return d_;}
68  const std::string & holderName() const { return holderName_;}
69  void setHolder(std::string hn) const { holderName_=hn;}
70 
71  void print() const {
72  edm::LogVerbatim("CachingVariable")<<name()
73  <<"\n"<<description().text();
74  }
75  protected:
76 
77  mutable evalType cache_;
79 
83  void setCache(valueType & v) const {
85  cache_.first=true; cache_.second = v;}
86  void setNotCompute() const {
88  cache_.first=false; cache_.second = 0;}
89  evalType & baseEval(const edm::Event & iEvent) const {
90  if(notSeenThisEventAlready(iEvent)) {
91  LogDebug("CachingVariable")<<name_+":"+holderName_<<" is checking once";
92  cache_=eval(iEvent);
93  }
94  return cache_;
95  }
98  eventCacheID_ != iEvent.cacheIdentifier());
99  if(retValue) {
101  }
102  return retValue;
103  }
104 
105  //cannot be made purely virtual otherwise one cannot have purely CachingVariableObjects
106  virtual evalType eval(const edm::Event & iEvent) const {return std::make_pair(false,0);};
107 
108  Description d_;
110  friend class VariableComputer;
111 };
112 
113 
114 class ComputedVariable;
116  public:
118  virtual ~VariableComputer(){}
119 
120  virtual void compute(const edm::Event & iEvent) const = 0;
121  const std::string & name() const { return name_;}
122  void declare(std::string var);
123  void assign(std::string var, double & value) const;
124  void doesNotCompute() const;
125  void doesNotCompute(std::string var) const;
126 
128  bool retValue = eventCacheID_ != iEvent.cacheIdentifier();
129  if(retValue) {
131  }
132  return retValue;
133  }
134 
135  protected:
139  mutable std::map<std::string ,const ComputedVariable *> iCompute_;
141 
143 
144 };
145 
146 
149 
152 
154  public:
157  CachingVariable(M,N,P), myComputer(c){}
158  virtual ~ComputedVariable(){};
159 
160  virtual evalType eval(const edm::Event & iEvent) const {
161  if (myComputer->notSeenThisEventAlready(iEvent))
162  myComputer->compute(iEvent);
163  return cache_;
164  }
165  private:
167 };
168 
170  public:
173 
174  void compute(const edm::Event & iEvent) const;
175 };
176 
177 class Splitter : public CachingVariable {
178  public:
180  CachingVariable(method,n,iConfig) {}
181 
182  //purely virtual here
183  virtual CachingVariable::evalType eval(const edm::Event & iEvent) const =0;
184 
185  unsigned int maxIndex() const { return maxSlots()-1;}
186 
187  //maximum NUMBER of slots: counting over/under flows
188  virtual unsigned int maxSlots() const { return labels_.size();}
189 
190  const std::string shortLabel(unsigned int i) const{
191  if (i>=short_labels_.size()){
192  edm::LogError("Splitter")<<"trying to access slots short_label at index: "<<i<<"while of size: "<<short_labels_.size()<<"\n"<<conf_.dump();
193  return short_labels_.back(); }
194  else return short_labels_[i];}
195 
196  const std::string & label(unsigned int i) const{
197  if (i>=labels_.size()){
198  edm::LogError("Splitter")<<"trying to access slots label at index: "<<i<<"while of size: "<<labels_.size()<<"\n"<<conf_.dump();
199  return labels_.back(); }
200  else return labels_[i];}
201 
202  protected:
203  std::vector<std::string> labels_;
204  std::vector<std::string> short_labels_;
205 };
206 
207 
208 class VarSplitter : public Splitter{
209  public:
211  Splitter("VarSplitter",arg.n,arg.iConfig) {
212  var_=arg.iConfig.getParameter<std::string>("var");
213  useUnderFlow_=arg.iConfig.getParameter<bool>("useUnderFlow");
214  useOverFlow_=arg.iConfig.getParameter<bool>("useOverFlow");
215  slots_=arg.iConfig.getParameter<std::vector<double> >("slots");
216  if (useUnderFlow_){
217  labels_.push_back("underflow");
218  short_labels_.push_back("_"+arg.n+"_underflow");}
219  std::vector<std::string> confLabels;
220  if (arg.iConfig.exists("labels")){
221  confLabels=arg.iConfig.getParameter<std::vector<std::string> >("labels");
222  }
223  else{
224  std::string labelFormat = arg.iConfig.getParameter<std::string>("labelsFormat");
225  for (unsigned int is=0;is!=slots_.size()-1;++is){
226  std::string l(Form(labelFormat.c_str(),slots_[is],slots_[is+1]));
227  confLabels.push_back(l);
228  }
229  }
230  for (unsigned int i=0;i!=confLabels.size();++i){
231  labels_.push_back(confLabels[i]);
232  std::stringstream ss;
233  ss<<"_"<<arg.n<<"_"<<i;
234  short_labels_.push_back(ss.str());
235  }
236  if (useOverFlow_)
237  { labels_.push_back("overFlow");
238  short_labels_.push_back("_"+arg.n+"_overFlow");}
239 
240  //check consistency
241  if (labels_.size()!=maxSlots())
242  edm::LogError("Splitter")<<"splitter with name: "<<name()<<" has inconsistent configuration\n"<<conf_.dump();
243 
244  arg.m[arg.n]=this;
245  }
246 
248 
249  //redefine the maximum number of slots
250  unsigned int maxSlots() const{
251  unsigned int s=slots_.size()-1;
252  if (useUnderFlow_) s++;
253  if (useOverFlow_) s++;
254  return s;}
255 
256  protected:
260  std::vector<double> slots_;
261 };
262 
263 template <typename Object> class sortByStringFunction {
264  public:
267 
268  bool operator() (const Object * o1, const Object * o2) {
269  return (*f_)(*o1) > (*f_)(*o2);
270  }
271  private:
273 };
274 
275 template <typename Object, const char * label>
277  public:
279  CachingVariable(std::string(label)+"ExpressionVariable",arg.n,arg.iConfig) , f_(0), forder_(0) {
281  //old style constructor
282  if (arg.iConfig.exists("expr") && arg.iConfig.exists("index")){
283  std::string expr=arg.iConfig.getParameter<std::string>("expr");
284  index_=arg.iConfig.getParameter<unsigned int>("index");
285  f_ = new StringObjectFunction<Object>(expr);
286  addDescriptionLine("calculating: "+expr);
287  std::stringstream ss;
288  ss<<"on object at index: "<<index_<<" of: "<<src_;
289 
290  if (arg.iConfig.exists("order")){
291  std::string order=arg.iConfig.getParameter<std::string>("order");
293  ss<<" after sorting according to: "<<order;
294  }else forder_ =0;
295 
296  if (arg.iConfig.exists("selection")){
299  ss<<" and selecting only: "<<selection;
300  }else selector_=0;
301 
302 
303 
304  addDescriptionLine(ss.str()); ss.str("");
305  arg.m[arg.n] = this;
306  }
307  else{
308  //multiple instance constructor
309  std::map<std::string, edm::Entry> indexEntry;
310  if (arg.n.find("_N")!=std::string::npos){
311  //will have to loop over indexes
312  std::vector<unsigned int> indexes = arg.iConfig.getParameter<std::vector<unsigned int> >("indexes");
313  for (unsigned int iI=0;iI!=indexes.size();++iI){
314  edm::ParameterSet toUse = arg.iConfig;
315  edm::Entry e("unsigned int",indexes[iI],true);
316  std::stringstream ss;
317  //add +1 0->1, 1->2, ... in the variable label
318  ss<<indexes[iI]+1;
319  indexEntry.insert(std::make_pair(ss.str(),e));
320  }
321  }//contains "_N"
322 
323  std::map< std::string, edm::Entry> varEntry;
324  if (arg.n.find("_V")!=std::string::npos){
325  //do something fancy for multiple variable from one PSet
326  std::vector<std::string> vars = arg.iConfig.getParameter<std::vector<std::string> >("vars");
327  for (unsigned int v=0;v!=vars.size();++v){
328  unsigned int sep=vars[v].find(":");
329  std::string name=vars[v].substr(0,sep);
330  std::string expr=vars[v].substr(sep+1);
331 
332  edm::Entry e("string",expr,true);
333  varEntry.insert(std::make_pair(name,e));
334  }
335  }//contains "_V"
336 
337  std::string radical = arg.n;
338  //remove the "_V";
339  if (!varEntry.empty())
340  radical = radical.substr(0,radical.size()-2);
341  //remove the "_N";
342  if (!indexEntry.empty())
343  radical = radical.substr(0,radical.size()-2);
344 
345  if(varEntry.empty()){
346  //loop only the indexes
347  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
348  edm::ParameterSet toUse = arg.iConfig;
349  toUse.insert(true,"index",iIt->second);
350  std::string newVname = radical+iIt->first;
351  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
352  // the constructor auto log the new variable in the map
354  }
355  }else{
356  for (std::map< std::string, edm::Entry>::iterator vIt=varEntry.begin();vIt!=varEntry.end();++vIt){
357  if (indexEntry.empty()){
358  edm::ParameterSet toUse = arg.iConfig;
359  toUse.insert(true,"expr",vIt->second);
360  std::string newVname = radical+vIt->first;
361  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
362  // the constructor auto log the new variable in the map
364  }else{
365  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
366  edm::ParameterSet toUse = arg.iConfig;
367  toUse.insert(true,"expr",vIt->second);
368  toUse.insert(true,"index",iIt->second);
369  std::string newVname = radical+iIt->first+vIt->first;
370  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
371  // the constructor auto log the new variable in the map
373  }}
374  }
375  }
376  //there is a memory leak here, because the object we are in is not logged in the arg.m, the variable is not valid
377  // anyways, but reside in memory with no ways of de-allocating it.
378  // since the caching variables are actually "global" objects, it does not matter.
379  // we cannot add it to the map, otherwise, it would be considered for eventV ntupler
380  }
381  }
383  if (f_) delete f_;
384  if (forder_) delete forder_;
385  if (selector_) delete selector_;
386  }
387 
389  if (!f_) {
390  edm::LogError(method())<<" no parser attached.";
391  return std::make_pair(false,0);
392  }
394  iEvent.getByLabel(src_,oH);
395  if (index_>=oH->size()){
396  LogDebug(method())<<"fail to get object at index: "<<index_<<" in collection: "<<src_;
397  return std::make_pair(false,0);
398  }
399 
400  //get the ordering right first. if required
401  if (selector_ || forder_){
402  std::vector<const Object*> copyToSort(0);
403  copyToSort.reserve(oH->size());
404  for (unsigned int i=0;i!=oH->size();++i){
405  if (selector_ && !((*selector_)((*oH)[i]))) continue;
406  copyToSort.push_back(&(*oH)[i]);
407  }
408  if (index_ >= copyToSort.size()) return std::make_pair(false,0);
409  if (forder_) std::sort(copyToSort.begin(), copyToSort.end(), sortByStringFunction<Object>(forder_));
410 
411  const Object * o = copyToSort[index_];
412  return std::make_pair(true,(*f_)(*o));
413  }
414  else{
415  const Object & o = (*oH)[index_];
416  return std::make_pair(true,(*f_)(o));
417  }
418  }
419 
420  private:
422  unsigned int index_;
426 };
427 
428 
429 template< typename LHS,const char * lLHS, typename RHS,const char * lRHS, typename Calculator>
431 public:
433  CachingVariable(Calculator::calculationType()+std::string(lLHS)+std::string(lRHS),arg.n,arg.iConfig),
434  srcLhs_(edm::Service<InputTagDistributorService>()->retrieve("srcLhs",arg.iConfig)),
435  indexLhs_(arg.iConfig.getParameter<unsigned int>("indexLhs")),
436  srcRhs_(edm::Service<InputTagDistributorService>()->retrieve("srcRhs",arg.iConfig)),
437  indexRhs_(arg.iConfig.getParameter<unsigned int>("indexRhs"))
438  {
439  std::stringstream ss;
441  ss<<"with Obj1 at index: "<<indexLhs_<<" of: "<<srcLhs_;
442  addDescriptionLine(ss.str()); ss.str("");
443  ss<<"with Obj2 at index: "<<indexRhs_<<" of: "<<srcRhs_;
444  addDescriptionLine(ss.str()); ss.str("");
445  arg.m[arg.n]=this;
446  }
447 
448  class getObject{
449  public:
450  getObject() : test(false),lhs(0),rhs(0){}
451  bool test;
452  const LHS * lhs;
453  const RHS * rhs;
454  };
456  getObject failed;
458  iEvent.getByLabel(srcLhs_, lhsH);
459  if (lhsH.failedToGet()){
460  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhs_;
461  return failed;}
462  if (indexLhs_>=lhsH->size()){
463  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexLhs_<<" of: "<<srcLhs_<<" with: "<<lhsH->size()<<" entries.";
464  return failed;}
465  const LHS & lhs = (*lhsH)[indexLhs_];
466 
468  iEvent.getByLabel(srcRhs_, rhsH);
469  if (rhsH.failedToGet()){
470  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhs_;
471  return failed;}
472 
473  if (indexRhs_>=rhsH->size()){
474  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexRhs_<<" of: "<<srcRhs_<<" with: "<<rhsH->size()<<" entries.";
475  return failed;}
476  const RHS & rhs = (*rhsH)[indexRhs_];
477 
478  failed.test=true;
479  failed.lhs=&lhs;
480  failed.rhs=&rhs;
481  return failed;
482  }
483 
484  //to be overloaded by the user
486  Calculator calc;
487  return calc(*o.lhs,*o.rhs);
488  }
490  getObject o=objects(iEvent);
491  if (!o.test) return std::make_pair(false,0);
492  return std::make_pair(true,calculate(o));
493  }
494 private:
496  unsigned int indexLhs_;
498  unsigned int indexRhs_;
499 };
500 
501 
503  public:
505  CachingVariable("Power",arg.n,arg.iConfig){
506  power_=arg.iConfig.getParameter<double>("power");
507  var_=arg.iConfig.getParameter<std::string>("var");
508  std::stringstream ss("Calculare X^Y, with X=");
509  ss<<var_<<" and Y="<<power_;
510  addDescriptionLine(ss.str());
511  arg.m[arg.n]=this;
512  }
514 
515  //concrete calculation of the variable
517 
518  private:
519  double power_;
521 };
522 
523 
524 template <typename TYPE>
526  public:
528  CachingVariable("SimpleValueVariable",arg.n,arg.iConfig),
529  src_(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig)) { arg.m[arg.n]=this;}
532  try{ iEvent.getByLabel(src_,value); }
533  catch(...){ return std::make_pair(false,0); }
534  if (value.failedToGet() || !value.isValid()) return std::make_pair(false,0);
535  else return std::make_pair(true, *value);
536  }
537  private:
539 };
540 
541 template <typename TYPE>
543  public:
545  CachingVariable("SimpleValueVectorVariable",arg.n,arg.iConfig),
546  src_(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig)),
547  index_(arg.iConfig.getParameter<unsigned int>("index")) { arg.m[arg.n]=this;}
550  try { iEvent.getByLabel(src_,values);}
551  catch(...){ return std::make_pair(false,0); }
552  if (values.failedToGet() || !values.isValid()) return std::make_pair(false,0);
553  else if (index_>=values->size()) return std::make_pair(false,0);
554  else return std::make_pair(true, (*values)[index_]);
555  }
556 
557  private:
559  unsigned int index_;
560 };
561 
562 
563 
564 
565 
566 
567 
568 #endif
#define LogDebug(id)
ComputedVariable(const std::string &M, std::string &N, edm::ParameterSet &P, const VariableComputer *c)
CachingVariable::evalType eval(const edm::Event &iEvent) const
T getParameter(std::string const &) const
unsigned long CacheIdentifier_t
Definition: Event.h:96
const Description & description() const
std::string separator_
std::string method_
int i
Definition: DBlmapReader.cc:9
virtual CachingVariable::evalType eval(const edm::Event &iEvent) const =0
ComputedVariable(const CachingVariableFactoryArg &arg)
CachingVariable::evalType eval(const edm::Event &iEvent) const
std::string holderName_
virtual evalType eval(const edm::Event &iEvent) const
unsigned int maxSlots() const
std::string dump(unsigned int indent=0) const
const VariableComputer * myComputer
VariableComputerTest(const CachingVariable::CachingVariableFactoryArg &arg)
edmplugin::PluginFactory< CachingVariable *(CachingVariable::CachingVariableFactoryArg) > CachingVariableFactory
edm::InputTag srcRhs_
const std::string & holderName() const
VariablePower(const CachingVariableFactoryArg &arg)
selection
main part
Definition: corrVsCorr.py:98
void setHolder(std::string hn) const
bool exists(std::string const &parameterName) const
checks if a parameter exists
StringCutObjectSelector< Object > * selector_
#define P
getObject objects(const edm::Event &iEvent) const
void insert(bool ok_to_replace, char const *, Entry const &)
std::vector< std::string > short_labels_
CachingVariable::evalType eval(const edm::Event &iEvent) const
CachingVariable::evalType eval(const edm::Event &iEvent) const
VarSplitter(const CachingVariableFactoryArg &arg)
edmplugin::PluginFactory< VariableComputer *(CachingVariable::CachingVariableFactoryArg) > VariableComputerFactory
A arg
Definition: Factorize.h:36
edm::Event::CacheIdentifier_t eventCacheID_
valueType operator()(const edm::Event &iEvent) const
CachingVariable::evalType eval(const edm::Event &iEvent) const
const CachingVariable::CachingVariableFactoryArg & arg_
std::vector< double > slots_
unsigned int maxIndex() const
virtual ~ComputedVariable()
virtual ~VariableComputer()
std::string text() const
void assign(std::string var, double &value) const
int iEvent
Definition: GenABIO.cc:243
SimpleValueVectorVariable(const CachingVariableFactoryArg &arg)
const T & max(const T &a, const T &b)
const std::string shortLabel(unsigned int i) const
StringObjectFunction< Object > * f_
evalType & baseEval(const edm::Event &iEvent) const
virtual unsigned int maxSlots() const
unsigned int indexLhs_
virtual ~CachingVariable()
CacheIdentifier_t cacheIdentifier() const
Definition: Event.cc:35
void addDescriptionLine(const std::string &s)
const std::string & label(unsigned int i) const
Description(std::vector< std::string > &d)
void print() const
double f[11][100]
edm::InputTag srcLhs_
void setNotCompute() const
bool isValid() const
Definition: HandleBase.h:76
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:390
VariableComputer(const CachingVariable::CachingVariableFactoryArg &arg)
Splitter(std::string method, std::string n, const edm::ParameterSet &iConfig)
edm::Event::CacheIdentifier_t eventCacheID_
std::map< std::string,const ComputedVariable * > iCompute_
ExpressionVariable(const CachingVariableFactoryArg &arg)
bool failedToGet() const
Definition: HandleBase.h:80
tuple description
Definition: idDealer.py:66
tuple s
Definition: Splitter.py:199
StringObjectFunction< Object > * forder_
#define N
Definition: blowfish.cc:9
std::vector< std::string > d_
bool operator()(const Object *o1, const Object *o2)
edm::ParameterSet conf_
unsigned int indexRhs_
std::vector< std::string > labels_
const std::vector< std::string > lines()
bool compute(const edm::Event &iEvent) const
std::string name_
void addLine(const std::string &l)
virtual void compute(const edm::Event &iEvent) const =0
virtual evalType eval(const edm::Event &iEvent) const
std::string var_
edm::InputTag src_
CachingVariable::evalType eval(const edm::Event &iEvent) const
bool notSeenThisEventAlready(const edm::Event &iEvent) const
void doesNotCompute() const
std::string method_
void compute(const edm::Event &iEvent) const
volatile std::atomic< bool > shutdown_flag false
CachingVariable(std::string m, std::string n, const edm::ParameterSet &iConfig)
CachingVariableFactoryArg(std::string &N, CachingVariable::vMap &M, edm::ParameterSet &P)
std::string var_
StringObjectFunction< Object > * f_
CachingVariableFactoryArg(const CachingVariableFactoryArg &copy)
TwoObjectVariable(const CachingVariableFactoryArg &arg)
const std::string & name() const
const std::string & name() const
SimpleValueVariable(const CachingVariableFactoryArg &arg)
void setCache(valueType &v) const
std::map< std::string, const CachingVariable * > vMap
const std::string & method() const
std::pair< bool, valueType > evalType
sortByStringFunction(StringObjectFunction< Object > *f)
void declare(std::string var)
bool notSeenThisEventAlready(const edm::Event &iEvent) const
virtual CachingVariable::valueType calculate(getObject &o) const