Rivet  3.1.2
RivetYODA.hh
1 #ifndef RIVET_RIVETYODA_HH
2 #define RIVET_RIVETYODA_HH
3 
4 #include "Rivet/Config/RivetCommon.hh"
5 #include "YODA/AnalysisObject.h"
6 #include "YODA/Counter.h"
7 #include "YODA/Histo1D.h"
8 #include "YODA/Histo2D.h"
9 #include "YODA/Profile1D.h"
10 #include "YODA/Profile2D.h"
11 #include "YODA/Scatter1D.h"
12 #include "YODA/Scatter2D.h"
13 #include "YODA/Scatter3D.h"
14 
15 #include <map>
16 #include <valarray>
17 
18 namespace YODA {
19 
20  typedef std::shared_ptr<YODA::AnalysisObject> AnalysisObjectPtr;
21 
22  typedef std::shared_ptr<YODA::Counter> CounterPtr;
23  typedef std::shared_ptr<YODA::Histo1D> Histo1DPtr;
24  typedef std::shared_ptr<YODA::Histo2D> Histo2DPtr;
25  typedef std::shared_ptr<YODA::Profile1D> Profile1DPtr;
26  typedef std::shared_ptr<YODA::Profile2D> Profile2DPtr;
27  typedef std::shared_ptr<YODA::Scatter1D> Scatter1DPtr;
28  typedef std::shared_ptr<YODA::Scatter2D> Scatter2DPtr;
29  typedef std::shared_ptr<YODA::Scatter3D> Scatter3DPtr;
30 
31 }
32 
33 
34 namespace Rivet {
35 
36 
37  class AnalysisObjectWrapper {
38  public:
39  virtual ~AnalysisObjectWrapper() {}
40 
41  virtual YODA::AnalysisObject* operator->() = 0;
42  virtual YODA::AnalysisObject* operator->() const = 0;
43  virtual const YODA::AnalysisObject & operator*() const = 0;
44 
46  virtual void setActiveWeightIdx(unsigned int iWeight) = 0;
47 
49  virtual void setActiveFinalWeightIdx(unsigned int iWeight) = 0;
50 
51  virtual void unsetActiveWeight() = 0;
52 
53  bool operator ==(const AnalysisObjectWrapper& p) { return (this == &p); }
54  bool operator !=(const AnalysisObjectWrapper& p) { return (this != &p); }
55 
56  protected:
58  // virtual void reset() = 0;
59  };
60 
64  /*
65  class Scatter1DPtr : public AnalysisObjectPtr {
66  public:
67  Scatter1DPtr() : _persistent() { }
68 
69  Scatter1DPtr(size_t len_of_weightvec, const YODA::Scatter1D& p) {
70  for (size_t m = 0; m < len_of_weightvec; ++m)
71  _persistent.push_back(make_shared<YODA::Scatter1D>(p));
72  }
73 
74  bool operator!() const { return !_persistent; }
75  explicit operator bool() const { return bool(_persistent); }
76 
77  YODA::Scatter1D* operator->() { return _persistent.get(); }
78 
79  YODA::Scatter1D* operator->() const { return _persistent.get(); }
80 
81  YODA::Scatter1D & operator*() { return *_persistent; }
82 
83  const YODA::Scatter1D & operator*() const { return *_persistent; }
84 
85  protected:
86  vector<YODA::Scatter1DPtr> _persistent;
87  };
88 
89  class Scatter2DPtr : public AnalysisObjectPtr {
90  public:
91  Scatter2DPtr(size_t len_of_weightvec, const YODA::Scatter2D& p) {
92  for (size_t m = 0; m < len_of_weightvec; ++m)
93  _persistent.push_back(make_shared<YODA::Scatter2D>(p));
94  }
95 
96  Scatter2DPtr() : _persistent() { }
97 
98  bool operator!() { return !_persistent; }
99  explicit operator bool() { return bool(_persistent); }
100 
101  YODA::Scatter2D* operator->() { return _persistent.get(); }
102 
103  YODA::Scatter2D* operator->() const { return _persistent.get(); }
104 
105  YODA::Scatter2D & operator*() { return *_persistent; }
106 
107  const YODA::Scatter2D & operator*() const { return *_persistent; }
108 
109  protected:
110  vector<YODA::Scatter2DPtr> _persistent;
111  };
112 
113  class Scatter3DPtr : public AnalysisObjectPtr {
114  public:
115  Scatter3DPtr(size_t len_of_weightvec, const YODA::Scatter3D& p) {
116  for (size_t m = 0; m < len_of_weightvec; ++m)
117  _persistent.push_back(make_shared<YODA::Scatter3D>(p));
118  }
119 
120  Scatter3DPtr() : _persistent() { }
121 
122  bool operator!() { return !_persistent; }
123  explicit operator bool() { return bool(_persistent); }
124 
125  YODA::Scatter3D* operator->() { return _persistent.get(); }
126 
127  YODA::Scatter3D* operator->() const { return _persistent.get(); }
128 
129  YODA::Scatter3D & operator*() { return *_persistent; }
130 
131  const YODA::Scatter3D & operator*() const { return *_persistent; }
132 
133  protected:
134  vector<YODA::Scatter3DPtr> _persistent;
135  };
136  */
137 
138 
139  class MultiweightAOWrapper : public AnalysisObjectWrapper {
140 
141  public:
142  using Inner = YODA::AnalysisObject;
143 
144  virtual void newSubEvent() = 0;
145 
146  virtual void pushToPersistent(const vector<std::valarray<double> >& weight,
147  double nlowfrac = 0.0) = 0;
148  virtual void pushToFinal() = 0;
149 
150  virtual YODA::AnalysisObjectPtr activeYODAPtr() const = 0;
151 
152  virtual string basePath() const = 0;
153  };
154 
155 
156  using Weight = double;
157 
158  template <class T>
159  using Fill = pair<typename T::FillType, Weight>;
160 
161  template <class T>
162  using Fills = multiset<Fill<T>>;
163 
164 
165  // TODO TODO TODO
166  // need to override the old fill method too!
167  // otherwise we can't intercept existing fill calls in analysis code
168  // TODO TODO TODO
169 
170 
172  template <class T>
173  class TupleWrapper;
174 
175  template<>
176  class TupleWrapper<YODA::Counter> : public YODA::Counter {
177  public:
178  typedef shared_ptr<TupleWrapper<YODA::Counter>> Ptr;
179  TupleWrapper(const YODA::Counter & h) : YODA::Counter(h) {}
180  // todo: do we need to deal with users using fractions directly?
181  void fill( double weight=1.0, double fraction=1.0 ) {
182  (void)fraction;
183  fills_.insert( {YODA::Counter::FillType(),weight} );
184  }
185  void reset() { fills_.clear(); }
186  const Fills<YODA::Counter> & fills() const { return fills_; }
187  private:
188  // x / weight pairs
189  Fills<YODA::Counter> fills_;
190  };
191 
192  template<>
193  class TupleWrapper<YODA::Histo1D> : public YODA::Histo1D {
194  public:
195  typedef shared_ptr<TupleWrapper<YODA::Histo1D>> Ptr;
196  TupleWrapper(const YODA::Histo1D & h) : YODA::Histo1D(h) {}
197  // todo: do we need to deal with users using fractions directly?
198  void fill( double x, double weight=1.0, double fraction=1.0 ) {
199  (void)fraction;
200  if ( std::isnan(x) ) throw YODA::RangeError("X is NaN");
201  fills_.insert( { x , weight } );
202  }
203  void reset() { fills_.clear(); }
204  const Fills<YODA::Histo1D> & fills() const { return fills_; }
205  private:
206  // x / weight pairs
207  Fills<YODA::Histo1D> fills_;
208  };
209 
210  template<>
211  class TupleWrapper<YODA::Profile1D> : public YODA::Profile1D {
212  public:
213  typedef shared_ptr<TupleWrapper<YODA::Profile1D>> Ptr;
214  TupleWrapper(const YODA::Profile1D & h) : YODA::Profile1D(h) {}
215  // todo: do we need to deal with users using fractions directly?
216  void fill( double x, double y, double weight=1.0, double fraction=1.0 ) {
217  (void)fraction;
218  if ( std::isnan(x) ) throw YODA::RangeError("X is NaN");
219  if ( std::isnan(y) ) throw YODA::RangeError("Y is NaN");
220  fills_.insert( { YODA::Profile1D::FillType{x,y}, weight } );
221  }
222  void reset() { fills_.clear(); }
223  const Fills<YODA::Profile1D> & fills() const { return fills_; }
224  private:
225  // x / weight pairs
226  Fills<YODA::Profile1D> fills_;
227  };
228 
229 
230  template<>
231  class TupleWrapper<YODA::Histo2D> : public YODA::Histo2D {
232  public:
233  typedef shared_ptr<TupleWrapper<YODA::Histo2D>> Ptr;
234  TupleWrapper(const YODA::Histo2D & h) : YODA::Histo2D(h) {}
235  // todo: do we need to deal with users using fractions directly?
236  void fill( double x, double y, double weight=1.0, double fraction=1.0 ) {
237  (void)fraction;
238  if ( std::isnan(x) ) throw YODA::RangeError("X is NaN");
239  if ( std::isnan(y) ) throw YODA::RangeError("Y is NaN");
240  fills_.insert( { YODA::Histo2D::FillType{x,y}, weight } );
241  }
242  void reset() { fills_.clear(); }
243  const Fills<YODA::Histo2D> & fills() const { return fills_; }
244  private:
245  // x / weight pairs
246  Fills<YODA::Histo2D> fills_;
247  };
248 
249  template<>
250  class TupleWrapper<YODA::Profile2D> : public YODA::Profile2D {
251  public:
252  typedef shared_ptr<TupleWrapper<YODA::Profile2D>> Ptr;
253  TupleWrapper(const YODA::Profile2D & h) : YODA::Profile2D(h) {}
254  // todo: do we need to deal with users using fractions directly?
255  void fill( double x, double y, double z, double weight=1.0, double fraction=1.0 ) {
256  (void)fraction;
257  if ( std::isnan(x) ) throw YODA::RangeError("X is NaN");
258  if ( std::isnan(y) ) throw YODA::RangeError("Y is NaN");
259  if ( std::isnan(z) ) throw YODA::RangeError("Z is NaN");
260  fills_.insert( { YODA::Profile2D::FillType{x,y,z}, weight } );
261  }
262  void reset() { fills_.clear(); }
263  const Fills<YODA::Profile2D> & fills() const { return fills_; }
264  private:
265  // x / weight pairs
266  Fills<YODA::Profile2D> fills_;
267  };
268 
269  template<>
270  class TupleWrapper<YODA::Scatter1D> : public YODA::Scatter1D {
271  public:
272  typedef shared_ptr<TupleWrapper<YODA::Scatter1D>> Ptr;
273  TupleWrapper(const YODA::Scatter1D & h) : YODA::Scatter1D(h) {}
274  };
275 
276  template<>
277  class TupleWrapper<YODA::Scatter2D> : public YODA::Scatter2D {
278  public:
279  typedef shared_ptr<TupleWrapper<YODA::Scatter2D>> Ptr;
280  TupleWrapper(const YODA::Scatter2D & h) : YODA::Scatter2D(h) {}
281  };
282 
283  template<>
284  class TupleWrapper<YODA::Scatter3D> : public YODA::Scatter3D {
285  public:
286  typedef shared_ptr<TupleWrapper<YODA::Scatter3D>> Ptr;
287  TupleWrapper(const YODA::Scatter3D & h) : YODA::Scatter3D(h) {}
288  };
289 
290 
291 
292  template <class T>
293  class Wrapper : public MultiweightAOWrapper {
294  friend class Analysis;
295 
296  public:
297 
298  using Inner = T;
299  /* @todo
300  * some things are not really well-defined here
301  * for instance: fill() in the finalize() method and integral() in
302  * the analyze() method.
303  */
304 
305  Wrapper() = default;
306 
307  Wrapper(const vector<string>& weightnames, const T & p);
308 
309  ~Wrapper();
310 
311  typename T::Ptr active() const;
312 
313  /* @todo this probably need to loop over all? */
314  bool operator!() const { return !_active; } // Don't use active() here, assert will catch
315 
316  explicit operator bool() const { return static_cast<bool>(_active); } // Don't use active() here, assert will catch
317 
318  T * operator->() { return active().get(); }
319 
320  T * operator->() const { return active().get(); }
321 
322  T & operator*() { return *active(); }
323 
324  const T & operator*() const { return *active(); }
325 
326  // can be useful for weight analysis (see e.g. MC_WEIGHTS for use)
327  T * _getPersistent (unsigned int iWeight) { return _persistent.at(iWeight).get(); }
328 
329  string basePath() const { return _basePath; }
330 
331  string baseName() const { return _baseName; }
332 
333 
334  /* @todo
335  * these need to be re-thought out.
336 
337  void reset() { active()->reset(); }
338  */
339 
340  /* @todo
341  * these probably need to loop over all?
342  * do we even want to provide equality?
343  */
344  /* @todo
345  * how about no.
346  friend bool operator==(Wrapper a, Wrapper b){
347  if (a._persistent.size() != b._persistent.size())
348  return false;
349 
350  for (size_t i = 0; i < a._persistent.size(); i++) {
351  if (a._persistent.at(i) != b._persistent.at(i)) {
352  return false;
353  }
354  }
355 
356  return true;
357  }
358 
359  friend bool operator!=(Wrapper a, Wrapper b){
360  return !(a == b);
361  }
362 
363 
364  friend bool operator<(Wrapper a, Wrapper b){
365  if (a._persistent.size() >= b._persistent.size())
366  return false;
367 
368  for (size_t i = 0; i < a._persistent.size(); i++) {
369  if (*(a._persistent.at(i)) >= *(b._persistent.at(i))) {
370  return false;
371  }
372  }
373 
374  return true;
375  }
376  */
377 
378 
379  private:
380  void setActiveWeightIdx(unsigned int iWeight) {
381  _active = _persistent.at(iWeight);
382  }
383 
384  void setActiveFinalWeightIdx(unsigned int iWeight) {
385  _active = _final.at(iWeight);
386  }
387 
388 
389  /* this is for dev only---we shouldn't need this in real runs. */
390  void unsetActiveWeight() { _active.reset(); }
391 
392  void newSubEvent();
393 
394  virtual YODA::AnalysisObjectPtr activeYODAPtr() const { return _active; }
395 
396  const vector<typename T::Ptr> & persistent() const { return _persistent; }
397 
398  const vector<typename T::Ptr> & final() const { return _final; }
399 
400  /* to be implemented for each type */
401  void pushToPersistent(const vector<std::valarray<double> >& weight,
402  double nlowfrac = 0.0);
403  void pushToFinal();
404 
405 
406  /* M of these, one for each weight */
407  vector<typename T::Ptr> _persistent;
408 
409  /* This is the copy of _persistent that will be passed to finalize(). */
410  vector<typename T::Ptr> _final;
411 
412  /* N of these, one for each event in evgroup */
413  vector<typename TupleWrapper<T>::Ptr> _evgroup;
414 
415  typename T::Ptr _active;
416 
417  string _basePath;
418 
419  string _baseName;
420 
421  // do we need implicit cast?
422  // operator typename T::Ptr () {
423  // return _active;
424  // }
425 
426  friend class AnalysisHandler;
427  };
428 
429 
435  template <typename T>
436  class rivet_shared_ptr {
437  public:
438  typedef T value_type;
439 
440  rivet_shared_ptr() = default;
441 
442  rivet_shared_ptr(decltype(nullptr)) : _p(nullptr) {}
443 
445  rivet_shared_ptr(const vector<string>& weightNames, const typename T::Inner & p)
446  : _p( make_shared<T>(weightNames, p) )
447  {}
448 
449  template <typename U>
450  rivet_shared_ptr(const shared_ptr<U> & p)
451  : _p(p)
452  {}
453 
454  template <typename U>
455  rivet_shared_ptr(const rivet_shared_ptr<U> & p)
456  : _p(p.get())
457  {}
458 
459  // Goes right through to the active Wrapper<YODA> object's members
460  T & operator->() {
461  if (_p == nullptr) throw Error("Dereferencing null AnalysisObject pointer. Is there an unbooked histogram variable?");
462  return *_p;
463  }
464  const T & operator->() const {
465  if (_p == nullptr) throw Error("Dereferencing null AnalysisObject pointer. Is there an unbooked histogram variable?");
466  return *_p;
467  }
468 
469  // The active YODA object
470  typename T::Inner & operator*() { return **_p; }
471  const typename T::Inner & operator*() const { return **_p; }
472 
473  bool operator!() const { return !_p || !(*_p); }
474  explicit operator bool() const { return _p && bool(*_p); }
475 
476  template <typename U>
477  bool operator==(const rivet_shared_ptr<U> & other) const {
478  return _p == other._p;
479  }
480 
481  template <typename U>
482  bool operator!=(const rivet_shared_ptr<U> & other) const {
483  return _p != other._p;
484  }
485 
486  template <typename U>
487  bool operator<(const rivet_shared_ptr<U> & other) const {
488  return _p < other._p;
489  }
490 
491  template <typename U>
492  bool operator>(const rivet_shared_ptr<U> & other) const {
493  return _p > other._p;
494  }
495 
496  template <typename U>
497  bool operator<=(const rivet_shared_ptr<U> & other) const {
498  return _p <= other._p;
499  }
500 
501  template <typename U>
502  bool operator>=(const rivet_shared_ptr<U> & other) const {
503  return _p >= other._p;
504  }
505 
506  shared_ptr<T> get() const { return _p; }
507 
508  private:
509  shared_ptr<T> _p;
510 
511  };
512 
513 
514 
515  // every object listed here needs a virtual fill method in YODA,
516  // otherwise the Tuple fakery won't work.
517 
518  using MultiweightAOPtr = rivet_shared_ptr<MultiweightAOWrapper>;
519 
520  using Histo1DPtr = rivet_shared_ptr<Wrapper<YODA::Histo1D>>;
521  using Histo2DPtr = rivet_shared_ptr<Wrapper<YODA::Histo2D>>;
522  using Profile1DPtr = rivet_shared_ptr<Wrapper<YODA::Profile1D>>;
523  using Profile2DPtr = rivet_shared_ptr<Wrapper<YODA::Profile2D>>;
524  using CounterPtr = rivet_shared_ptr<Wrapper<YODA::Counter>>;
525  using Scatter1DPtr = rivet_shared_ptr<Wrapper<YODA::Scatter1D>>;
526  using Scatter2DPtr = rivet_shared_ptr<Wrapper<YODA::Scatter2D>>;
527  using Scatter3DPtr = rivet_shared_ptr<Wrapper<YODA::Scatter3D>>;
528 
529  using YODA::Counter;
530  using YODA::Histo1D;
531  using YODA::HistoBin1D;
532  using YODA::Histo2D;
533  using YODA::HistoBin2D;
534  using YODA::Profile1D;
535  using YODA::ProfileBin1D;
536  using YODA::Profile2D;
537  using YODA::ProfileBin2D;
538  using YODA::Scatter1D;
539  using YODA::Point1D;
540  using YODA::Scatter2D;
541  using YODA::Point2D;
542  using YODA::Scatter3D;
543  using YODA::Point3D;
544 
547  map<string, YODA::AnalysisObjectPtr> getRefData(const string& papername);
548 
550 
552  string getDatafilePath(const string& papername);
553 
554 
557  template<typename T> struct ReferenceTraits {};
558  template<> struct ReferenceTraits<Counter> { typedef Counter RefT; };
559  template<> struct ReferenceTraits<Scatter1D> { typedef Scatter1D RefT; };
560  template<> struct ReferenceTraits<Histo1D> { typedef Scatter2D RefT; };
561  template<> struct ReferenceTraits<Profile1D> { typedef Scatter2D RefT; };
562  template<> struct ReferenceTraits<Scatter2D> { typedef Scatter2D RefT; };
563  template<> struct ReferenceTraits<Histo2D> { typedef Scatter3D RefT; };
564  template<> struct ReferenceTraits<Profile2D> { typedef Scatter3D RefT; };
565  template<> struct ReferenceTraits<Scatter3D> { typedef Scatter3D RefT; };
566 
567 
571  template <typename T>
572  inline bool aocopy(YODA::AnalysisObjectPtr src, YODA::AnalysisObjectPtr dst) {
573  shared_ptr<T> tsrc = dynamic_pointer_cast<T>(src);
574  if ( !tsrc ) return false;
575  shared_ptr<T> tdst = dynamic_pointer_cast<T>(dst);
576  if ( !tdst ) return false;
577  *tdst = *tsrc;
578  return true;
579  }
580 
584  template <typename T>
585  inline bool aoadd(YODA::AnalysisObjectPtr dst, YODA::AnalysisObjectPtr src, double scale) {
586  shared_ptr<T> tsrc = dynamic_pointer_cast<T>(src);
587  if ( !tsrc ) return false;
588  shared_ptr<T> tdst = dynamic_pointer_cast<T>(dst);
589  if ( !tdst ) return false;
590  tsrc->scaleW(scale);
591  *tdst += *tsrc;
592  return true;
593  }
594 
597  bool copyao(YODA::AnalysisObjectPtr src, YODA::AnalysisObjectPtr dst);
598 
602  bool addaos(YODA::AnalysisObjectPtr dst, YODA::AnalysisObjectPtr src, double scale);
603 
606  template <typename TPtr>
607  inline bool bookingCompatible(TPtr a, TPtr b) {
608  return a->sameBinning(*b);
609  }
610  inline bool bookingCompatible(CounterPtr, CounterPtr) {
611  return true;
612  }
613  inline bool bookingCompatible(Scatter1DPtr a, Scatter1DPtr b) {
614  return a->numPoints() == b->numPoints();
615  }
616  inline bool bookingCompatible(Scatter2DPtr a, Scatter2DPtr b) {
617  return a->numPoints() == b->numPoints();
618  }
619  inline bool bookingCompatible(Scatter3DPtr a, Scatter3DPtr b) {
620  return a->numPoints() == b->numPoints();
621  }
622  inline bool bookingCompatible(YODA::CounterPtr, YODA::CounterPtr) {
623  return true;
624  }
625  inline bool bookingCompatible(YODA::Scatter1DPtr a, YODA::Scatter1DPtr b) {
626  return a->numPoints() == b->numPoints();
627  }
628  inline bool bookingCompatible(YODA::Scatter2DPtr a, YODA::Scatter2DPtr b) {
629  return a->numPoints() == b->numPoints();
630  }
631  inline bool bookingCompatible(YODA::Scatter3DPtr a, YODA::Scatter3DPtr b) {
632  return a->numPoints() == b->numPoints();
633  }
634 
636 class AOPath {
637 
638  public:
639 
641  AOPath(string fullpath)
642  : _valid(false), _path(fullpath), _raw(false), _tmp(false), _ref(false) {
643  _valid = init(fullpath);
644  }
645 
647  string path() const { return _path; }
648 
650  string analysis() const { return _analysis; }
651 
653  string analysisWithOptions() const { return _analysis + _optionstring; }
654 
656  string name() const { return _name; }
657 
659  string weight() const { return _weight; }
660 
662  bool isRaw() const { return _raw; }
663 
664  // Is This a temporary (filling) object?
665  bool isTmp() const { return _tmp; }
666 
668  bool isRef() const { return _ref; }
669 
671  string optionString() const { return _optionstring; }
672 
674  bool hasOptions() const { return !_options.empty(); }
675 
677  void removeOption(string opt) { _options.erase(opt); fixOptionString(); }
678 
680  void setOption(string opt, string val) { _options[opt] = val; fixOptionString();}
681 
683  bool hasOption(string opt) const { return _options.find(opt) != _options.end(); }
684 
686  string getOption(string opt) const {
687  auto it = _options.find(opt);
688  if ( it != _options.end() ) return it->second;
689  return "";
690  }
691 
693  void fixOptionString();
694 
696  string mkPath() const;
697  string setPath() { return _path = mkPath(); }
698 
700  void debug() const;
701 
703  bool operator<(const AOPath & other) const {
704  return _path < other._path;
705  }
706 
708  bool valid() const { return _valid; };
709  bool operator!() const { return !valid(); }
710 
711  private:
712 
714  bool init(string fullpath);
715  bool chopweight(string & fullpath);
716  bool chopoptions(string & anal);
717 
718  bool _valid;
719  string _path;
720  string _analysis;
721  string _optionstring;
722  string _name;
723  string _weight;
724  bool _raw;
725  bool _tmp;
726  bool _ref;
727  map<string,string> _options;
728 
729  };
730 
731 }
732 
733 #endif
Definition: MC_Cent_pPb.hh:10
bool bookingCompatible(TPtr a, TPtr b)
Definition: RivetYODA.hh:607
bool operator==(const Cut &a, const Cut &b)
Compare two cuts for equality, forwards to the cut-specific implementation.
Definition: Cuts.hh:44
map< string, YODA::AnalysisObjectPtr > getRefData(const string &papername)
string getDatafilePath(const string &papername)
Get the file system path to the reference file for this paper.
bool addaos(YODA::AnalysisObjectPtr dst, YODA::AnalysisObjectPtr src, double scale)
Definition: RivetYODA.hh:18
bool aoadd(YODA::AnalysisObjectPtr dst, YODA::AnalysisObjectPtr src, double scale)
Definition: RivetYODA.hh:585
bool aocopy(YODA::AnalysisObjectPtr src, YODA::AnalysisObjectPtr dst)
Definition: RivetYODA.hh:572
BoolJetNOT operator!(const JetSelector &a)
Operator syntactic sugar for NOT construction.
Definition: JetUtils.hh:97
bool copyao(YODA::AnalysisObjectPtr src, YODA::AnalysisObjectPtr dst)