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 {
26  std::string text;
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;
48  std::string & n;
51  };
52 
53  CachingVariable(std::string m, std::string n, const edm::ParameterSet & iConfig) :
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 
80  std::string method_;
81  std::string name_;
82  mutable std::string holderName_;
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 (edm::Service<UpdaterService>()->checkOnce(name_+":"+holderName_)){
91  LogDebug("CachingVariable")<<name_+":"+holderName_<<" is checking once";
92  cache_=eval(iEvent);
93  }
94  return cache_;
95  }
96  //cannot be made purely virtual otherwise one cannot have purely CachingVariableObjects
97  virtual evalType eval(const edm::Event & iEvent) const {return std::make_pair(false,0);};
98 
101  friend class VariableComputer;
102 };
103 
104 
105 class ComputedVariable;
107  public:
109  virtual ~VariableComputer(){}
110 
111  virtual void compute(const edm::Event & iEvent) const = 0;
112  const std::string & name() const { return name_;}
113  void declare(std::string var);
114  void assign(std::string var, double & value) const;
115  void doesNotCompute() const;
116  void doesNotCompute(std::string var) const;
117 
118  protected:
120  std::string name_;
121  std::string method_;
122  mutable std::map<std::string ,const ComputedVariable *> iCompute_;
123  std::string separator_;
124 };
125 
126 
129 
132 
134  public:
136  ComputedVariable(const std::string & M, std::string & N, edm::ParameterSet & P, const VariableComputer * c) :
137  CachingVariable(M,N,P), myComputer(c){}
138  virtual ~ComputedVariable(){};
139 
140  virtual evalType eval(const edm::Event & iEvent) const {
141  if (edm::Service<UpdaterService>()->checkOnce(myComputer->name()+":"+holderName_))
142  myComputer->compute(iEvent);
143  return cache_;
144  }
145  private:
147 };
148 
150  public:
153 
154  void compute(const edm::Event & iEvent) const;
155 };
156 
157 class Splitter : public CachingVariable {
158  public:
159  Splitter(std::string method, std::string n, const edm::ParameterSet & iConfig) :
160  CachingVariable(method,n,iConfig) {}
161 
162  //purely virtual here
163  virtual CachingVariable::evalType eval(const edm::Event & iEvent) const =0;
164 
165  unsigned int maxIndex() const { return maxSlots()-1;}
166 
167  //maximum NUMBER of slots: counting over/under flows
168  virtual unsigned int maxSlots() const { return labels_.size();}
169 
170  const std::string shortLabel(unsigned int i) const{
171  if (i>=short_labels_.size()){
172  edm::LogError("Splitter")<<"trying to access slots short_label at index: "<<i<<"while of size: "<<short_labels_.size()<<"\n"<<conf_.dump();
173  return short_labels_.back(); }
174  else return short_labels_[i];}
175 
176  const std::string & label(unsigned int i) const{
177  if (i>=labels_.size()){
178  edm::LogError("Splitter")<<"trying to access slots label at index: "<<i<<"while of size: "<<labels_.size()<<"\n"<<conf_.dump();
179  return labels_.back(); }
180  else return labels_[i];}
181 
182  protected:
183  std::vector<std::string> labels_;
184  std::vector<std::string> short_labels_;
185 };
186 
187 
188 class VarSplitter : public Splitter{
189  public:
191  Splitter("VarSplitter",arg.n,arg.iConfig) {
192  var_=arg.iConfig.getParameter<std::string>("var");
193  useUnderFlow_=arg.iConfig.getParameter<bool>("useUnderFlow");
194  useOverFlow_=arg.iConfig.getParameter<bool>("useOverFlow");
195  slots_=arg.iConfig.getParameter<std::vector<double> >("slots");
196  if (useUnderFlow_){
197  labels_.push_back("underflow");
198  short_labels_.push_back("_"+arg.n+"_underflow");}
199  std::vector<std::string> confLabels;
200  if (arg.iConfig.exists("labels")){
201  confLabels=arg.iConfig.getParameter<std::vector<std::string> >("labels");
202  }
203  else{
204  std::string labelFormat = arg.iConfig.getParameter<std::string>("labelsFormat");
205  for (unsigned int is=0;is!=slots_.size()-1;++is){
206  std::string l(Form(labelFormat.c_str(),slots_[is],slots_[is+1]));
207  confLabels.push_back(l);
208  }
209  }
210  for (unsigned int i=0;i!=confLabels.size();++i){
211  labels_.push_back(confLabels[i]);
212  std::stringstream ss;
213  ss<<"_"<<arg.n<<"_"<<i;
214  short_labels_.push_back(ss.str());
215  }
216  if (useOverFlow_)
217  { labels_.push_back("overFlow");
218  short_labels_.push_back("_"+arg.n+"_overFlow");}
219 
220  //check consistency
221  if (labels_.size()!=maxSlots())
222  edm::LogError("Splitter")<<"splitter with name: "<<name()<<" has inconsistent configuration\n"<<conf_.dump();
223 
224  arg.m[arg.n]=this;
225  }
226 
228 
229  //redefine the maximum number of slots
230  unsigned int maxSlots() const{
231  unsigned int s=slots_.size()-1;
232  if (useUnderFlow_) s++;
233  if (useOverFlow_) s++;
234  return s;}
235 
236  protected:
237  std::string var_;
240  std::vector<double> slots_;
241 };
242 
243 template <typename Object> class sortByStringFunction {
244  public:
247 
248  bool operator() (const Object * o1, const Object * o2) {
249  return (*f_)(*o1) > (*f_)(*o2);
250  }
251  private:
253 };
254 
255 template <typename Object, const char * label>
257  public:
259  CachingVariable(std::string(label)+"ExpressionVariable",arg.n,arg.iConfig) , f_(0), forder_(0) {
261  //old style constructor
262  if (arg.iConfig.exists("expr") && arg.iConfig.exists("index")){
263  std::string expr=arg.iConfig.getParameter<std::string>("expr");
264  index_=arg.iConfig.getParameter<unsigned int>("index");
265  f_ = new StringObjectFunction<Object>(expr);
266  addDescriptionLine("calculating: "+expr);
267  std::stringstream ss;
268  ss<<"on object at index: "<<index_<<" of: "<<src_;
269 
270  if (arg.iConfig.exists("order")){
271  std::string order=arg.iConfig.getParameter<std::string>("order");
273  ss<<" after sorting according to: "<<order;
274  }else forder_ =0;
275 
276  if (arg.iConfig.exists("selection")){
277  std::string selection=arg.iConfig.getParameter<std::string>("selection");
279  ss<<" and selecting only: "<<selection;
280  }else selector_=0;
281 
282 
283 
284  addDescriptionLine(ss.str()); ss.str("");
285  arg.m[arg.n] = this;
286  }
287  else{
288  //multiple instance constructor
289  std::map<std::string, edm::Entry> indexEntry;
290  if (arg.n.find("_N")!=std::string::npos){
291  //will have to loop over indexes
292  std::vector<unsigned int> indexes = arg.iConfig.getParameter<std::vector<unsigned int> >("indexes");
293  for (unsigned int iI=0;iI!=indexes.size();++iI){
294  edm::ParameterSet toUse = arg.iConfig;
295  edm::Entry e("unsigned int",indexes[iI],true);
296  std::stringstream ss;
297  //add +1 0->1, 1->2, ... in the variable label
298  ss<<indexes[iI]+1;
299  indexEntry.insert(std::make_pair(ss.str(),e));
300  }
301  }//contains "_N"
302 
303  std::map< std::string, edm::Entry> varEntry;
304  if (arg.n.find("_V")!=std::string::npos){
305  //do something fancy for multiple variable from one PSet
306  std::vector<std::string> vars = arg.iConfig.getParameter<std::vector<std::string> >("vars");
307  for (unsigned int v=0;v!=vars.size();++v){
308  unsigned int sep=vars[v].find(":");
309  std::string name=vars[v].substr(0,sep);
310  std::string expr=vars[v].substr(sep+1);
311 
312  edm::Entry e("string",expr,true);
313  varEntry.insert(std::make_pair(name,e));
314  }
315  }//contains "_V"
316 
317  std::string radical = arg.n;
318  //remove the "_V";
319  if (!varEntry.empty())
320  radical = radical.substr(0,radical.size()-2);
321  //remove the "_N";
322  if (!indexEntry.empty())
323  radical = radical.substr(0,radical.size()-2);
324 
325  if(varEntry.empty()){
326  //loop only the indexes
327  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
328  edm::ParameterSet toUse = arg.iConfig;
329  toUse.insert(true,"index",iIt->second);
330  std::string newVname = radical+iIt->first;
331  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
332  // the constructor auto log the new variable in the map
334  }
335  }else{
336  for (std::map< std::string, edm::Entry>::iterator vIt=varEntry.begin();vIt!=varEntry.end();++vIt){
337  if (indexEntry.empty()){
338  edm::ParameterSet toUse = arg.iConfig;
339  toUse.insert(true,"expr",vIt->second);
340  std::string newVname = radical+vIt->first;
341  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
342  // the constructor auto log the new variable in the map
344  }else{
345  for(std::map< std::string, edm::Entry>::iterator iIt=indexEntry.begin();iIt!=indexEntry.end();++iIt){
346  edm::ParameterSet toUse = arg.iConfig;
347  toUse.insert(true,"expr",vIt->second);
348  toUse.insert(true,"index",iIt->second);
349  std::string newVname = radical+iIt->first+vIt->first;
350  // std::cout<<"in the loop, creating variable with name: "<<newVname<<std::endl;
351  // the constructor auto log the new variable in the map
353  }}
354  }
355  }
356  //there is a memory leak here, because the object we are in is not logged in the arg.m, the variable is not valid
357  // anyways, but reside in memory with no ways of de-allocating it.
358  // since the caching variables are actually "global" objects, it does not matter.
359  // we cannot add it to the map, otherwise, it would be considered for eventV ntupler
360  }
361  }
363  if (f_) delete f_;
364  if (forder_) delete forder_;
365  if (selector_) delete selector_;
366  }
367 
369  if (!f_) {
370  edm::LogError(method())<<" no parser attached.";
371  return std::make_pair(false,0);
372  }
374  iEvent.getByLabel(src_,oH);
375  if (index_>=oH->size()){
376  LogDebug(method())<<"fail to get object at index: "<<index_<<" in collection: "<<src_;
377  return std::make_pair(false,0);
378  }
379 
380  //get the ordering right first. if required
381  if (selector_ || forder_){
382  std::vector<const Object*> copyToSort(0);
383  copyToSort.reserve(oH->size());
384  for (unsigned int i=0;i!=oH->size();++i){
385  if (selector_ && !((*selector_)((*oH)[i]))) continue;
386  copyToSort.push_back(&(*oH)[i]);
387  }
388  if (index_ >= copyToSort.size()) return std::make_pair(false,0);
389  if (forder_) std::sort(copyToSort.begin(), copyToSort.end(), sortByStringFunction<Object>(forder_));
390 
391  const Object * o = copyToSort[index_];
392  return std::make_pair(true,(*f_)(*o));
393  }
394  else{
395  const Object & o = (*oH)[index_];
396  return std::make_pair(true,(*f_)(o));
397  }
398  }
399 
400  private:
402  unsigned int index_;
406 };
407 
408 
409 template< typename LHS,const char * lLHS, typename RHS,const char * lRHS, typename Calculator>
411 public:
413  CachingVariable(Calculator::calculationType()+std::string(lLHS)+std::string(lRHS),arg.n,arg.iConfig),
414  srcLhs_(edm::Service<InputTagDistributorService>()->retrieve("srcLhs",arg.iConfig)),
415  indexLhs_(arg.iConfig.getParameter<unsigned int>("indexLhs")),
416  srcRhs_(edm::Service<InputTagDistributorService>()->retrieve("srcRhs",arg.iConfig)),
417  indexRhs_(arg.iConfig.getParameter<unsigned int>("indexRhs"))
418  {
419  std::stringstream ss;
421  ss<<"with Obj1 at index: "<<indexLhs_<<" of: "<<srcLhs_;
422  addDescriptionLine(ss.str()); ss.str("");
423  ss<<"with Obj2 at index: "<<indexRhs_<<" of: "<<srcRhs_;
424  addDescriptionLine(ss.str()); ss.str("");
425  arg.m[arg.n]=this;
426  }
427 
428  class getObject{
429  public:
430  getObject() : test(false),lhs(0),rhs(0){}
431  bool test;
432  const LHS * lhs;
433  const RHS * rhs;
434  };
436  getObject failed;
438  iEvent.getByLabel(srcLhs_, lhsH);
439  if (lhsH.failedToGet()){
440  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhs_;
441  return failed;}
442  if (indexLhs_>=lhsH->size()){
443  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexLhs_<<" of: "<<srcLhs_<<" with: "<<lhsH->size()<<" entries.";
444  return failed;}
445  const LHS & lhs = (*lhsH)[indexLhs_];
446 
448  iEvent.getByLabel(srcRhs_, rhsH);
449  if (rhsH.failedToGet()){
450  LogDebug("TwoObjectVariable")<<name()<<" could not get a collection with label: "<<srcLhs_;
451  return failed;}
452 
453  if (indexRhs_>=rhsH->size()){
454  LogDebug("TwoObjectVariable")<<name()<<" tries to access index: "<<indexRhs_<<" of: "<<srcRhs_<<" with: "<<rhsH->size()<<" entries.";
455  return failed;}
456  const RHS & rhs = (*rhsH)[indexRhs_];
457 
458  failed.test=true;
459  failed.lhs=&lhs;
460  failed.rhs=&rhs;
461  return failed;
462  }
463 
464  //to be overloaded by the user
466  Calculator calc;
467  return calc(*o.lhs,*o.rhs);
468  }
470  getObject o=objects(iEvent);
471  if (!o.test) return std::make_pair(false,0);
472  return std::make_pair(true,calculate(o));
473  }
474 private:
476  unsigned int indexLhs_;
478  unsigned int indexRhs_;
479 };
480 
481 
483  public:
485  CachingVariable("Power",arg.n,arg.iConfig){
486  power_=arg.iConfig.getParameter<double>("power");
487  var_=arg.iConfig.getParameter<std::string>("var");
488  std::stringstream ss("Calculare X^Y, with X=");
489  ss<<var_<<" and Y="<<power_;
490  addDescriptionLine(ss.str());
491  arg.m[arg.n]=this;
492  }
494 
495  //concrete calculation of the variable
497 
498  private:
499  double power_;
500  std::string var_;
501 };
502 
503 
504 template <typename TYPE>
506  public:
508  CachingVariable("SimpleValueVariable",arg.n,arg.iConfig),
509  src_(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig)) { arg.m[arg.n]=this;}
512  try{ iEvent.getByLabel(src_,value); }
513  catch(...){ return std::make_pair(false,0); }
514  if (value.failedToGet() || !value.isValid()) return std::make_pair(false,0);
515  else return std::make_pair(true, *value);
516  }
517  private:
519 };
520 
521 template <typename TYPE>
523  public:
525  CachingVariable("SimpleValueVectorVariable",arg.n,arg.iConfig),
526  src_(edm::Service<InputTagDistributorService>()->retrieve("src",arg.iConfig)),
527  index_(arg.iConfig.getParameter<unsigned int>("index")) { arg.m[arg.n]=this;}
530  try { iEvent.getByLabel(src_,values);}
531  catch(...){ return std::make_pair(false,0); }
532  if (values.failedToGet() || !values.isValid()) return std::make_pair(false,0);
533  else if (index_>=values->size()) return std::make_pair(false,0);
534  else return std::make_pair(true, (*values)[index_]);
535  }
536 
537  private:
539  unsigned int index_;
540 };
541 
542 
543 
544 
545 
546 
547 
548 #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
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
VarSplitter(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
const VariableComputer * myComputer
edmplugin::PluginFactory< CachingVariable *(CachingVariable::CachingVariableFactoryArg) > CachingVariableFactory
edm::InputTag srcRhs_
const std::string & holderName() const
ExpressionVariable(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
edmplugin::PluginFactory< VariableComputer *(CachingVariable::CachingVariableFactoryArg) > VariableComputerFactory
A arg
Definition: Factorize.h:36
valueType operator()(const edm::Event &iEvent) const
CachingVariable::evalType eval(const edm::Event &iEvent) const
std::vector< double > slots_
unsigned int maxIndex() const
virtual ~ComputedVariable()
virtual ~VariableComputer()
SimpleValueVectorVariable(CachingVariableFactoryArg arg)
TwoObjectVariable(CachingVariableFactoryArg arg)
std::string text() const
ComputedVariable(CachingVariableFactoryArg arg)
void assign(std::string var, double &value) const
int iEvent
Definition: GenABIO.cc:243
const std::string shortLabel(unsigned int i) const
StringObjectFunction< Object > * f_
evalType & baseEval(const edm::Event &iEvent) const
virtual unsigned int maxSlots() const
VariableComputer(CachingVariable::CachingVariableFactoryArg arg)
unsigned int indexLhs_
virtual ~CachingVariable()
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]
CachingVariable::CachingVariableFactoryArg & arg_
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:356
Splitter(std::string method, std::string n, const edm::ParameterSet &iConfig)
std::map< std::string,const ComputedVariable * > iCompute_
bool failedToGet() const
Definition: HandleBase.h:80
tuple description
Definition: idDealer.py:66
StringObjectFunction< Object > * forder_
VariableComputerTest(CachingVariable::CachingVariableFactoryArg arg)
#define N
Definition: blowfish.cc:9
std::vector< std::string > d_
bool operator()(const Object *o1, const Object *o2)
SimpleValueVariable(CachingVariableFactoryArg arg)
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)
VariablePower(CachingVariableFactoryArg arg)
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
void doesNotCompute() const
std::string method_
void compute(const edm::Event &iEvent) const
CachingVariable(std::string m, std::string n, const edm::ParameterSet &iConfig)
Description d_
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
std::string dump() const
void setCache(valueType &v) const
mathSSE::Vec4< T > v
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)
virtual CachingVariable::valueType calculate(getObject &o) const