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 
12 
14 
15 namespace edm {
16  class EventSetup;
17 }
18 #include <vector>
19 #include "TString.h"
20 
21 class Description {
22  public:
24  Description(std::vector<std::string> & d) : d_(d){}
25  std::string text() const {
27  for (unsigned int i=0;i!=d_.size();++i)
28  text+=d_[i]+"\n";
29  return text;
30  }
31  const std::vector<std::string> lines(){return d_;}
32  void addLine(const std::string & l){d_.push_back(l);}
33  private :
34  std::vector<std::string> d_;
35 };
36 
37 class VariableComputer;
38 
40  public:
41  //every variable return double values
42  typedef double valueType;
43  typedef std::pair<bool, valueType> evalType;
44  typedef std::map<std::string, const CachingVariable*> vMap;
51  };
52 
54  cache_(std::make_pair(false,0)),method_(m),
55  name_(n),conf_(iConfig) {}
56 
57  virtual ~CachingVariable() {}
58 
59  //does the variable computes
60  bool compute(const edm::Event & iEvent) const { return baseEval(iEvent).first; }
61 
62  //accessor to the computed/cached value
63  valueType operator()(const edm::Event & iEvent) const { return baseEval(iEvent).second; }
64 
65  const std::string & name() const {return name_;}
66  const std::string & method() const { return method_;}
67  const Description & description()const { return d_;}
69  const std::string & holderName() const { return holderName_;}
70  void setHolder(std::string hn) const { holderName_=hn;}
71 
72  void print() const {
73  edm::LogVerbatim("CachingVariable")<<name()
74  <<"\n"<<description().text();
75  }
76  protected:
77 
78  mutable evalType cache_;
80 
84  void setCache(valueType & v) const {
86  cache_.first=true; cache_.second = v;}
87  void setNotCompute() const {
89  cache_.first=false; cache_.second = 0;}
90  evalType & baseEval(const edm::Event & iEvent) const {
91  if(notSeenThisEventAlready(iEvent)) {
92  LogDebug("CachingVariable")<<name_+":"+holderName_<<" is checking once";
93  cache_=eval(iEvent);
94  }
95  return cache_;
96  }
99  eventCacheID_ != iEvent.cacheIdentifier());
100  if(retValue) {
102  }
103  return retValue;
104  }
105 
106  //cannot be made purely virtual otherwise one cannot have purely CachingVariableObjects
107  virtual evalType eval(const edm::Event & iEvent) const {return std::make_pair(false,0);};
108 
109  Description d_;
111  friend class VariableComputer;
112 };
113 
114 
115 class ComputedVariable;
117  public:
119  virtual ~VariableComputer(){}
120 
121  virtual void compute(const edm::Event & iEvent) const = 0;
122  const std::string & name() const { return name_;}
124  void assign(std::string var, double & value) const;
125  void doesNotCompute() const;
126  void doesNotCompute(std::string var) const;
127 
129  bool retValue = eventCacheID_ != iEvent.cacheIdentifier();
130  if(retValue) {
132  }
133  return retValue;
134  }
135 
136  protected:
140  mutable std::map<std::string ,const ComputedVariable *> iCompute_;
142 
144 
145 };
146 
147 
150 
153 
155  public:
158  CachingVariable(M,N,P,iC), myComputer(c){}
159  virtual ~ComputedVariable(){};
160 
161  virtual evalType eval(const edm::Event & iEvent) const {
162  if (myComputer->notSeenThisEventAlready(iEvent))
163  myComputer->compute(iEvent);
164  return cache_;
165  }
166  private:
168 };
169 
171  public:
174 
175  void compute(const edm::Event & iEvent) const;
176 };
177 
178 class Splitter : public CachingVariable {
179  public:
181  CachingVariable(method,n,iConfig,iC) {}
182 
183  //purely virtual here
184  virtual CachingVariable::evalType eval(const edm::Event & iEvent) const =0;
185 
186  unsigned int maxIndex() const { return maxSlots()-1;}
187 
188  //maximum NUMBER of slots: counting over/under flows
189  virtual unsigned int maxSlots() const { return labels_.size();}
190 
191  const std::string shortLabel(unsigned int i) const{
192  if (i>=short_labels_.size()){
193  edm::LogError("Splitter")<<"trying to access slots short_label at index: "<<i<<"while of size: "<<short_labels_.size()<<"\n"<<conf_.dump();
194  return short_labels_.back(); }
195  else return short_labels_[i];}
196 
197  const std::string & label(unsigned int i) const{
198  if (i>=labels_.size()){
199  edm::LogError("Splitter")<<"trying to access slots label at index: "<<i<<"while of size: "<<labels_.size()<<"\n"<<conf_.dump();
200  return labels_.back(); }
201  else return labels_[i];}
202 
203  protected:
204  std::vector<std::string> labels_;
205  std::vector<std::string> short_labels_;
206 };
207 
208 
209 class VarSplitter : public Splitter{
210  public:
212  Splitter("VarSplitter",arg.n,arg.iConfig,iC) {
213  var_=arg.iConfig.getParameter<std::string>("var");
214  useUnderFlow_=arg.iConfig.getParameter<bool>("useUnderFlow");
215  useOverFlow_=arg.iConfig.getParameter<bool>("useOverFlow");
216  slots_=arg.iConfig.getParameter<std::vector<double> >("slots");
217  if (useUnderFlow_){
218  labels_.push_back("underflow");
219  short_labels_.push_back("_"+arg.n+"_underflow");}
220  std::vector<std::string> confLabels;
221  if (arg.iConfig.exists("labels")){
222  confLabels=arg.iConfig.getParameter<std::vector<std::string> >("labels");
223  }
224  else{
225  std::string labelFormat = arg.iConfig.getParameter<std::string>("labelsFormat");
226  for (unsigned int is=0;is!=slots_.size()-1;++is){
227  std::string l(Form(labelFormat.c_str(),slots_[is],slots_[is+1]));
228  confLabels.push_back(l);
229  }
230  }
231  for (unsigned int i=0;i!=confLabels.size();++i){
232  labels_.push_back(confLabels[i]);
233  std::stringstream ss;
234  ss<<"_"<<arg.n<<"_"<<i;
235  short_labels_.push_back(ss.str());
236  }
237  if (useOverFlow_)
238  { labels_.push_back("overFlow");
239  short_labels_.push_back("_"+arg.n+"_overFlow");}
240 
241  //check consistency
242  if (labels_.size()!=maxSlots())
243  edm::LogError("Splitter")<<"splitter with name: "<<name()<<" has inconsistent configuration\n"<<conf_.dump();
244 
245  arg.m[arg.n]=this;
246  }
247 
249 
250  //redefine the maximum number of slots
251  unsigned int maxSlots() const{
252  unsigned int s=slots_.size()-1;
253  if (useUnderFlow_) s++;
254  if (useOverFlow_) s++;
255  return s;}
256 
257  protected:
261  std::vector<double> slots_;
262 };
263 
264 template <typename Object> class sortByStringFunction {
265  public:
268 
269  bool operator() (const Object * o1, const Object * o2) {
270  return (*f_)(*o1) > (*f_)(*o2);
271  }
272  private:
274 };
275 
276 template <typename Object, const char * label>
278  public:
280  CachingVariable(std::string(label)+"ExpressionVariable",arg.n,arg.iConfig,iC) , f_(0), forder_(0) {
283  //old style constructor
284  if (arg.iConfig.exists("expr") && arg.iConfig.exists("index")){
285  std::string expr=arg.iConfig.getParameter<std::string>("expr");
286  index_=arg.iConfig.getParameter<unsigned int>("index");
287  f_ = new StringObjectFunction<Object>(expr);
288  addDescriptionLine("calculating: "+expr);
289  std::stringstream ss;
290  ss<<"on object at index: "<<index_<<" of: "<<srcTag_;
291 
292  if (arg.iConfig.exists("order")){
293  std::string order=arg.iConfig.getParameter<std::string>("order");
295  ss<<" after sorting according to: "<<order;
296  }else forder_ =0;
297 
298  if (arg.iConfig.exists("selection")){
301  ss<<" and selecting only: "<<selection;
302  }else selector_=0;
303 
304 
305 
306  addDescriptionLine(ss.str()); ss.str("");
307  arg.m[arg.n] = this;
308  }
309  else{
310  //multiple instance constructor
311  std::map<std::string, edm::Entry> indexEntry;
312  if (arg.n.find("_N")!=std::string::npos){
313  //will have to loop over indexes
314  std::vector<unsigned int> indexes = arg.iConfig.getParameter<std::vector<unsigned int> >("indexes");
315  for (unsigned int iI=0;iI!=indexes.size();++iI){
316  edm::ParameterSet toUse = arg.iConfig;
317  edm::Entry e("unsigned int",indexes[iI],true);
318  std::stringstream ss;
319  //add +1 0->1, 1->2, ... in the variable label
320  ss<<indexes[iI]+1;
321  indexEntry.insert(std::make_pair(ss.str(),e));
322  }
323  }//contains "_N"
324 
325  std::map< std::string, edm::Entry> varEntry;
326  if (arg.n.find("_V")!=std::string::npos){
327  //do something fancy for multiple variable from one PSet
328  std::vector<std::string> vars = arg.iConfig.getParameter<std::vector<std::string> >("vars");
329  for (unsigned int v=0;v!=vars.size();++v){
330  unsigned int sep=vars[v].find(":");
331  std::string name=vars[v].substr(0,sep);
332  std::string expr=vars[v].substr(sep+1);
333 
334  edm::Entry e("string",expr,true);
335  varEntry.insert(std::make_pair(name,e));
336  }
337  }//contains "_V"
338 
339  std::string radical = arg.n;
340  //remove the "_V";
341  if (!varEntry.empty())
342  radical = radical.substr(0,radical.size()-2);
343  //remove the "_N";
344  if (!indexEntry.empty())
345  radical = radical.substr(0,radical.size()-2);
346 
347  if(varEntry.empty()){
348  //loop only the indexes
349  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
350  edm::ParameterSet toUse = arg.iConfig;
351  toUse.insert(true,"index",iIt->second);
352  std::string newVname = radical+iIt->first;
353  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
354  // the constructor auto log the new variable in the map
356  }
357  }else{
358  for (std::map< std::string, edm::Entry>::iterator vIt=varEntry.begin();vIt!=varEntry.end();++vIt){
359  if (indexEntry.empty()){
360  edm::ParameterSet toUse = arg.iConfig;
361  toUse.insert(true,"expr",vIt->second);
362  std::string newVname = radical+vIt->first;
363  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
364  // the constructor auto log the new variable in the map
366  }else{
367  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
368  edm::ParameterSet toUse = arg.iConfig;
369  toUse.insert(true,"expr",vIt->second);
370  toUse.insert(true,"index",iIt->second);
371  std::string newVname = radical+iIt->first+vIt->first;
372  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
373  // the constructor auto log the new variable in the map
375  }}
376  }
377  }
378  //there is a memory leak here, because the object we are in is not logged in the arg.m, the variable is not valid
379  // anyways, but reside in memory with no ways of de-allocating it.
380  // since the caching variables are actually "global" objects, it does not matter.
381  // we cannot add it to the map, otherwise, it would be considered for eventV ntupler
382  }
383  }
385  if (f_) delete f_;
386  if (forder_) delete forder_;
387  if (selector_) delete selector_;
388  }
389 
391  if (!f_) {
392  edm::LogError(method())<<" no parser attached.";
393  return std::make_pair(false,0);
394  }
396  iEvent.getByToken(src_,oH);
397  if (index_>=oH->size()){
398  LogDebug(method())<<"fail to get object at index: "<<index_<<" in collection: "<<src_;
399  return std::make_pair(false,0);
400  }
401 
402  //get the ordering right first. if required
403  if (selector_ || forder_){
404  std::vector<const Object*> copyToSort(0);
405  copyToSort.reserve(oH->size());
406  for (unsigned int i=0;i!=oH->size();++i){
407  if (selector_ && !((*selector_)((*oH)[i]))) continue;
408  copyToSort.push_back(&(*oH)[i]);
409  }
410  if (index_ >= copyToSort.size()) return std::make_pair(false,0);
411  if (forder_) std::sort(copyToSort.begin(), copyToSort.end(), sortByStringFunction<Object>(forder_));
412 
413  const Object * o = copyToSort[index_];
414  return std::make_pair(true,(*f_)(*o));
415  }
416  else{
417  const Object & o = (*oH)[index_];
418  return std::make_pair(true,(*f_)(o));
419  }
420  }
421 
422  private:
425  unsigned int index_;
429 };
430 
431 
432 template< typename LHS,const char * lLHS, typename RHS,const char * lRHS, typename Calculator>
434 public:
436  CachingVariable(Calculator::calculationType()+std::string(lLHS)+std::string(lRHS),arg.n,arg.iConfig,iC),
437  srcLhsTag_(edm::Service<InputTagDistributorService>()->retrieve("srcLhs",arg.iConfig)),
438  srcLhs_(iC.consumes<std::vector<LHS> >(srcLhsTag_)),
439  indexLhs_(arg.iConfig.getParameter<unsigned int>("indexLhs")),
440  srcRhsTag_(edm::Service<InputTagDistributorService>()->retrieve("srcRhs",arg.iConfig)),
441  srcRhs_(iC.consumes<std::vector<RHS> >(srcRhsTag_)),
442  indexRhs_(arg.iConfig.getParameter<unsigned int>("indexRhs"))
443  {
444  std::stringstream ss;
446  ss<<"with Obj1 at index: "<<indexLhs_<<" of: "<<srcLhs_;
447  addDescriptionLine(ss.str()); ss.str("");
448  ss<<"with Obj2 at index: "<<indexRhs_<<" of: "<<srcRhs_;
449  addDescriptionLine(ss.str()); ss.str("");
450  arg.m[arg.n]=this;
451  }
452 
453  class getObject{
454  public:
455  getObject() : test(false),lhs(0),rhs(0){}
456  bool test;
457  const LHS * lhs;
458  const RHS * rhs;
459  };
461  getObject failed;
463  iEvent.getByToken(srcLhs_, lhsH);
464  if (lhsH.failedToGet()){
465  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhsTag_;
466  return failed;}
467  if (indexLhs_>=lhsH->size()){
468  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexLhs_<<" of: "<<srcLhsTag_<<" with: "<<lhsH->size()<<" entries.";
469  return failed;}
470  const LHS & lhs = (*lhsH)[indexLhs_];
471 
473  iEvent.getByToken(srcRhs_, rhsH);
474  if (rhsH.failedToGet()){
475  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhsTag_;
476  return failed;}
477 
478  if (indexRhs_>=rhsH->size()){
479  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexRhs_<<" of: "<<srcRhsTag_<<" with: "<<rhsH->size()<<" entries.";
480  return failed;}
481  const RHS & rhs = (*rhsH)[indexRhs_];
482 
483  failed.test=true;
484  failed.lhs=&lhs;
485  failed.rhs=&rhs;
486  return failed;
487  }
488 
489  //to be overloaded by the user
491  Calculator calc;
492  return calc(*o.lhs,*o.rhs);
493  }
495  getObject o=objects(iEvent);
496  if (!o.test) return std::make_pair(false,0);
497  return std::make_pair(true,calculate(o));
498  }
499 private:
502  unsigned int indexLhs_;
505  unsigned int indexRhs_;
506 };
507 
508 
510  public:
512  CachingVariable("Power",arg.n,arg.iConfig,iC){
513  power_=arg.iConfig.getParameter<double>("power");
514  var_=arg.iConfig.getParameter<std::string>("var");
515  std::stringstream ss("Calculare X^Y, with X=");
516  ss<<var_<<" and Y="<<power_;
517  addDescriptionLine(ss.str());
518  arg.m[arg.n]=this;
519  }
521 
522  //concrete calculation of the variable
524 
525  private:
526  double power_;
528 };
529 
530 
531 template <typename TYPE>
533  public:
535  CachingVariable("SimpleValueVariable",arg.n,arg.iConfig,iC),
536  src_(iC.consumes<TYPE>(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig))) { arg.m[arg.n]=this;}
539  try{ iEvent.getByToken(src_,value); }
540  catch(...){ return std::make_pair(false,0); }
541  if (value.failedToGet() || !value.isValid()) return std::make_pair(false,0);
542  else return std::make_pair(true, *value);
543  }
544  private:
546 };
547 
548 template <typename TYPE>
550  public:
552  CachingVariable("SimpleValueVectorVariable",arg.n,arg.iConfig,iC),
553  src_(iC.consumes<TYPE>(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig))),
554  index_(arg.iConfig.getParameter<unsigned int>("index")) { arg.m[arg.n]=this;}
557  try { iEvent.getByToken(src_,values);}
558  catch(...){ return std::make_pair(false,0); }
559  if (values.failedToGet() || !values.isValid()) return std::make_pair(false,0);
560  else if (index_>=values->size()) return std::make_pair(false,0);
561  else return std::make_pair(true, (*values)[index_]);
562  }
563 
564  private:
566  unsigned int index_;
567 };
568 
569 
570 
571 
572 
573 
574 
575 #endif
#define LogDebug(id)
CachingVariable(std::string m, std::string n, const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
CachingVariable::evalType eval(const edm::Event &iEvent) const
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
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
list TYPE
Definition: runonSM.py:20
CachingVariable::evalType eval(const edm::Event &iEvent) const
std::string holderName_
virtual evalType eval(const edm::Event &iEvent) const
unsigned int maxSlots() const
ComputedVariable(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
std::string dump(unsigned int indent=0) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:434
edm::InputTag srcTag_
const VariableComputer * myComputer
edm::EDGetTokenT< std::vector< LHS > > srcLhs_
const std::string & holderName() const
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
VarSplitter(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
StringCutObjectSelector< Object > * selector_
#define P
getObject objects(const edm::Event &iEvent) const
VariableComputer(const CachingVariable::CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
edmplugin::PluginFactory< CachingVariable *(CachingVariable::CachingVariableFactoryArg, edm::ConsumesCollector &iC) > CachingVariableFactory
void insert(bool ok_to_replace, char const *, Entry const &)
std::vector< std::string > short_labels_
CachingVariable::evalType eval(const edm::Event &iEvent) const
edmplugin::PluginFactory< VariableComputer *(CachingVariable::CachingVariableFactoryArg, edm::ConsumesCollector &iC) > VariableComputerFactory
CachingVariable::evalType eval(const edm::Event &iEvent) const
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_
VariablePower(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
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:230
TwoObjectVariable(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
const T & max(const T &a, const T &b)
edm::InputTag srcLhsTag_
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)
edm::EDGetTokenT< TYPE > src_
void print() const
double f[11][100]
VariableComputerTest(const CachingVariable::CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
edm::InputTag srcRhsTag_
void setNotCompute() const
bool isValid() const
Definition: HandleBase.h:76
edm::EDGetTokenT< edm::View< Object > > src_
edm::Event::CacheIdentifier_t eventCacheID_
SimpleValueVariable(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
std::map< std::string,const ComputedVariable * > iCompute_
SimpleValueVectorVariable(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
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)
Splitter(std::string method, std::string n, const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
edm::ParameterSet conf_
unsigned int indexRhs_
std::vector< std::string > labels_
edm::EDGetTokenT< TYPE > src_
const std::vector< std::string > lines()
bool compute(const edm::Event &iEvent) const
std::string name_
ExpressionVariable(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
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_
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
void declare(std::string var, edm::ConsumesCollector &iC)
CachingVariableFactoryArg(std::string &N, CachingVariable::vMap &M, edm::ParameterSet &P)
std::string var_
StringObjectFunction< Object > * f_
CachingVariableFactoryArg(const CachingVariableFactoryArg &copy)
const std::string & name() const
const std::string & name() const
edm::EDGetTokenT< std::vector< RHS > > srcRhs_
ComputedVariable(const std::string &M, std::string &N, edm::ParameterSet &P, const VariableComputer *c, edm::ConsumesCollector &iC)
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)
bool notSeenThisEventAlready(const edm::Event &iEvent) const
virtual CachingVariable::valueType calculate(getObject &o) const