CMS 3D CMS Logo

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;
46  CachingVariableFactoryArg( const CachingVariableFactoryArg & copy) : n(copy.n),m(copy.m),iConfig(copy.iConfig){}
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_;}
68  void addDescriptionLine(const std::string & s){ d_.addLine(s);}
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_;
79  mutable edm::Event::CacheIdentifier_t eventCacheID_=0;
80 
84  void setCache(valueType & v) const {
85  cache_.first=true; cache_.second = v;}
86  void setNotCompute() const {
87  cache_.first=false; cache_.second = 0;}
88  evalType & baseEval(const edm::Event & iEvent) const {
89  if(notSeenThisEventAlready(iEvent)) {
90  LogDebug("CachingVariable")<<name_+":"+holderName_<<" is checking once";
91  cache_=eval(iEvent);
92  }
93  return cache_;
94  }
96  bool retValue = (std::numeric_limits<edm::Event::CacheIdentifier_t>::max() != eventCacheID_ and
97  eventCacheID_ != iEvent.cacheIdentifier());
98  if(retValue) {
99  eventCacheID_=iEvent.cacheIdentifier();
100  }
101  return retValue;
102  }
103 
104  //cannot be made purely virtual otherwise one cannot have purely CachingVariableObjects
105  virtual evalType eval(const edm::Event & iEvent) const {return std::make_pair(false,0);};
106 
107  Description d_;
109  friend class VariableComputer;
110 };
111 
112 
113 class ComputedVariable;
115  public:
117  virtual ~VariableComputer(){}
118 
119  virtual void compute(const edm::Event & iEvent) const = 0;
120  const std::string & name() const { return name_;}
121  void declare(std::string var, edm::ConsumesCollector& iC);
122  void assign(std::string var, double & value) const;
123  void doesNotCompute() const;
124  void doesNotCompute(std::string var) const;
125 
126  bool notSeenThisEventAlready(const edm::Event& iEvent) const {
127  bool retValue = (std::numeric_limits<edm::Event::CacheIdentifier_t>::max() != eventCacheID_ and
128  eventCacheID_ != iEvent.cacheIdentifier());
129  if(retValue) {
130  eventCacheID_=iEvent.cacheIdentifier();
131  }
132  return retValue;
133  }
134 
135  protected:
139  mutable std::map<std::string ,const ComputedVariable *> iCompute_;
141 
142  mutable edm::Event::CacheIdentifier_t eventCacheID_=0;
143 
144 };
145 
146 
149 
152 
154  public:
157  CachingVariable(M,N,P,iC), 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,iC) {}
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,iC) {
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 
247  CachingVariable::evalType eval(const edm::Event & iEvent) const;
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,iC) , f_(0), forder_(0) {
280  srcTag_=edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig);
281  src_=iC.consumes<edm::View<Object> >(srcTag_);
282  //old style constructor
283  if (arg.iConfig.exists("expr") && arg.iConfig.exists("index")){
284  std::string expr=arg.iConfig.getParameter<std::string>("expr");
285  index_=arg.iConfig.getParameter<unsigned int>("index");
286  f_ = new StringObjectFunction<Object>(expr);
287  addDescriptionLine("calculating: "+expr);
288  std::stringstream ss;
289  ss<<"on object at index: "<<index_<<" of: "<<srcTag_;
290 
291  if (arg.iConfig.exists("order")){
292  std::string order=arg.iConfig.getParameter<std::string>("order");
293  forder_ = new StringObjectFunction<Object>(order);
294  ss<<" after sorting according to: "<<order;
295  }else forder_ =0;
296 
297  if (arg.iConfig.exists("selection")){
300  ss<<" and selecting only: "<<selection;
301  }else selector_=0;
302 
303 
304 
305  addDescriptionLine(ss.str()); ss.str("");
306  arg.m[arg.n] = this;
307  }
308  else{
309  //multiple instance constructor
310  std::map<std::string, edm::Entry> indexEntry;
311  if (arg.n.find("_N")!=std::string::npos){
312  //will have to loop over indexes
313  std::vector<unsigned int> indexes = arg.iConfig.getParameter<std::vector<unsigned int> >("indexes");
314  for (unsigned int iI=0;iI!=indexes.size();++iI){
315  edm::ParameterSet toUse = arg.iConfig;
316  edm::Entry e("unsigned int",indexes[iI],true);
317  std::stringstream ss;
318  //add +1 0->1, 1->2, ... in the variable label
319  ss<<indexes[iI]+1;
320  indexEntry.insert(std::make_pair(ss.str(),e));
321  }
322  }//contains "_N"
323 
324  std::map< std::string, edm::Entry> varEntry;
325  if (arg.n.find("_V")!=std::string::npos){
326  //do something fancy for multiple variable from one PSet
327  std::vector<std::string> vars = arg.iConfig.getParameter<std::vector<std::string> >("vars");
328  for (unsigned int v=0;v!=vars.size();++v){
329  unsigned int sep=vars[v].find(":");
330  std::string name=vars[v].substr(0,sep);
331  std::string expr=vars[v].substr(sep+1);
332 
333  edm::Entry e("string",expr,true);
334  varEntry.insert(std::make_pair(name,e));
335  }
336  }//contains "_V"
337 
338  std::string radical = arg.n;
339  //remove the "_V";
340  if (!varEntry.empty())
341  radical = radical.substr(0,radical.size()-2);
342  //remove the "_N";
343  if (!indexEntry.empty())
344  radical = radical.substr(0,radical.size()-2);
345 
346  if(varEntry.empty()){
347  //loop only the indexes
348  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
349  edm::ParameterSet toUse = arg.iConfig;
350  toUse.insert(true,"index",iIt->second);
351  std::string newVname = radical+iIt->first;
352  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
353  // the constructor auto log the new variable in the map
355  }
356  }else{
357  for (std::map< std::string, edm::Entry>::iterator vIt=varEntry.begin();vIt!=varEntry.end();++vIt){
358  if (indexEntry.empty()){
359  edm::ParameterSet toUse = arg.iConfig;
360  toUse.insert(true,"expr",vIt->second);
361  std::string newVname = radical+vIt->first;
362  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
363  // the constructor auto log the new variable in the map
365  }else{
366  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
367  edm::ParameterSet toUse = arg.iConfig;
368  toUse.insert(true,"expr",vIt->second);
369  toUse.insert(true,"index",iIt->second);
370  std::string newVname = radical+iIt->first+vIt->first;
371  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
372  // the constructor auto log the new variable in the map
374  }}
375  }
376  }
377  //there is a memory leak here, because the object we are in is not logged in the arg.m, the variable is not valid
378  // anyways, but reside in memory with no ways of de-allocating it.
379  // since the caching variables are actually "global" objects, it does not matter.
380  // we cannot add it to the map, otherwise, it would be considered for eventV ntupler
381  }
382  }
384  if (f_) delete f_;
385  if (forder_) delete forder_;
386  if (selector_) delete selector_;
387  }
388 
390  if (!f_) {
391  edm::LogError(method())<<" no parser attached.";
392  return std::make_pair(false,0);
393  }
395  iEvent.getByToken(src_,oH);
396  if (index_>=oH->size()){
397  LogDebug(method())<<"fail to get object at index: "<<index_<<" in collection: "<<srcTag_;
398  return std::make_pair(false,0);
399  }
400 
401  //get the ordering right first. if required
402  if (selector_ || forder_){
403  std::vector<const Object*> copyToSort(0);
404  copyToSort.reserve(oH->size());
405  for (unsigned int i=0;i!=oH->size();++i){
406  if (selector_ && !((*selector_)((*oH)[i]))) continue;
407  copyToSort.push_back(&(*oH)[i]);
408  }
409  if (index_ >= copyToSort.size()) return std::make_pair(false,0);
410  if (forder_) std::sort(copyToSort.begin(), copyToSort.end(), sortByStringFunction<Object>(forder_));
411 
412  const Object * o = copyToSort[index_];
413  return std::make_pair(true,(*f_)(*o));
414  }
415  else{
416  const Object & o = (*oH)[index_];
417  return std::make_pair(true,(*f_)(o));
418  }
419  }
420 
421  private:
424  unsigned int index_;
428 };
429 
430 
431 template< typename LHS,const char * lLHS, typename RHS,const char * lRHS, typename Calculator>
433 public:
435  CachingVariable(Calculator::calculationType()+std::string(lLHS)+std::string(lRHS),arg.n,arg.iConfig,iC),
436  srcLhsTag_(edm::Service<InputTagDistributorService>()->retrieve("srcLhs",arg.iConfig)),
437  srcLhs_(iC.consumes<std::vector<LHS> >(srcLhsTag_)),
438  indexLhs_(arg.iConfig.getParameter<unsigned int>("indexLhs")),
439  srcRhsTag_(edm::Service<InputTagDistributorService>()->retrieve("srcRhs",arg.iConfig)),
440  srcRhs_(iC.consumes<std::vector<RHS> >(srcRhsTag_)),
441  indexRhs_(arg.iConfig.getParameter<unsigned int>("indexRhs"))
442  {
443  std::stringstream ss;
444  addDescriptionLine(Calculator::description());
445  ss<<"with Obj1 at index: "<<indexLhs_<<" of: "<<srcLhs_;
446  addDescriptionLine(ss.str()); ss.str("");
447  ss<<"with Obj2 at index: "<<indexRhs_<<" of: "<<srcRhs_;
448  addDescriptionLine(ss.str()); ss.str("");
449  arg.m[arg.n]=this;
450  }
451 
452  class getObject{
453  public:
454  getObject() : test(false),lhs(0),rhs(0){}
455  bool test;
456  const LHS * lhs;
457  const RHS * rhs;
458  };
462  iEvent.getByToken(srcLhs_, lhsH);
463  if (lhsH.failedToGet()){
464  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhsTag_;
465  return failed;}
466  if (indexLhs_>=lhsH->size()){
467  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexLhs_<<" of: "<<srcLhsTag_<<" with: "<<lhsH->size()<<" entries.";
468  return failed;}
469  const LHS & lhs = (*lhsH)[indexLhs_];
470 
472  iEvent.getByToken(srcRhs_, rhsH);
473  if (rhsH.failedToGet()){
474  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhsTag_;
475  return failed;}
476 
477  if (indexRhs_>=rhsH->size()){
478  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexRhs_<<" of: "<<srcRhsTag_<<" with: "<<rhsH->size()<<" entries.";
479  return failed;}
480  const RHS & rhs = (*rhsH)[indexRhs_];
481 
482  failed.test=true;
483  failed.lhs=&lhs;
484  failed.rhs=&rhs;
485  return failed;
486  }
487 
488  //to be overloaded by the user
490  Calculator calc;
491  return calc(*o.lhs,*o.rhs);
492  }
494  getObject o=objects(iEvent);
495  if (!o.test) return std::make_pair(false,0);
496  return std::make_pair(true,calculate(o));
497  }
498 private:
501  unsigned int indexLhs_;
504  unsigned int indexRhs_;
505 };
506 
507 
509  public:
511  CachingVariable("Power",arg.n,arg.iConfig,iC){
512  power_=arg.iConfig.getParameter<double>("power");
513  var_=arg.iConfig.getParameter<std::string>("var");
514  std::stringstream ss("Calculare X^Y, with X=");
515  ss<<var_<<" and Y="<<power_;
516  addDescriptionLine(ss.str());
517  arg.m[arg.n]=this;
518  }
520 
521  //concrete calculation of the variable
522  CachingVariable::evalType eval(const edm::Event & iEvent) const;
523 
524  private:
525  double power_;
527 };
528 
529 
530 template <typename TYPE>
532  public:
534  CachingVariable("SimpleValueVariable",arg.n,arg.iConfig,iC),
535  src_(iC.consumes<TYPE>(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig))) { arg.m[arg.n]=this;}
538  try{ iEvent.getByToken(src_,value); }
539  catch(...){ return std::make_pair(false,0); }
540  if (value.failedToGet() || !value.isValid()) return std::make_pair(false,0);
541  else return std::make_pair(true, *value);
542  }
543  private:
545 };
546 
547 template <typename TYPE>
549  public:
551  CachingVariable("SimpleValueVectorVariable",arg.n,arg.iConfig,iC),
552  src_(iC.consumes<TYPE>(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig))),
553  index_(arg.iConfig.getParameter<unsigned int>("index")) { arg.m[arg.n]=this;}
556  try { iEvent.getByToken(src_,values);}
557  catch(...){ return std::make_pair(false,0); }
558  if (values.failedToGet() || !values.isValid()) return std::make_pair(false,0);
559  else if (index_>=values->size()) return std::make_pair(false,0);
560  else return std::make_pair(true, (*values)[index_]);
561  }
562 
563  private:
565  unsigned int index_;
566 };
567 
568 
569 
570 
571 
572 
573 
574 #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:102
const Description & description() const
std::string separator_
std::string method_
int i
Definition: DBlmapReader.cc:9
CachingVariable::evalType eval(const edm::Event &iEvent) const
std::string holderName_
virtual evalType eval(const edm::Event &iEvent) const
unsigned int maxSlots() const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:457
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_
getObject objects(const edm::Event &iEvent) const
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_
edmplugin::PluginFactory< VariableComputer *(CachingVariable::CachingVariableFactoryArg, edm::ConsumesCollector &iC) > VariableComputerFactory
CachingVariable::evalType eval(const edm::Event &iEvent) const
A arg
Definition: Factorize.h:36
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
int iEvent
Definition: GenABIO.cc:230
TwoObjectVariable(const CachingVariableFactoryArg &arg, edm::ConsumesCollector &iC)
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:33
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]
void assign(const std::vector< float > &vec, float &a, float &b, float &c, float &d)
edm::InputTag srcRhsTag_
Definition: value.py:1
void setNotCompute() const
bool isValid() const
Definition: HandleBase.h:75
edm::EDGetTokenT< edm::View< Object > > src_
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:79
StringObjectFunction< Object > * forder_
#define N
Definition: blowfish.cc:9
std::vector< std::string > d_
def compute(min, max)
Splitter(std::string method, std::string n, const edm::ParameterSet &iConfig, edm::ConsumesCollector &iC)
edm::ParameterSet conf_
std::pair< OmniClusterRef, TrackingParticleRef > P
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)
HLT enums.
virtual evalType eval(const edm::Event &iEvent) const
std::string var_
bool notSeenThisEventAlready(const edm::Event &iEvent) const
std::string method_
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