Cut.cxx
Go to the documentation of this file.
1 #include "CAFAna/Core/Cut.h"
2 
3 #include "CAFAna/Core/DepMan.h"
4 
5 #include <iostream>
6 #include <map>
7 
8 namespace ana
9 {
10  //----------------------------------------------------------------------
11  template<class T> _Cut<T>::
12  _Cut(const std::function<CutFunc_t>& func,
13  const std::function<ExposureFunc_t>& liveFunc,
14  const std::function<ExposureFunc_t>& potFunc)
15  : fFunc(func), fLiveFunc(liveFunc), fPOTFunc(potFunc),
16  fID(fgNextID++)
17  {
18  DepMan<_Cut<T>>::Instance().RegisterConstruction(this);
19  }
20 
21  //----------------------------------------------------------------------
22  template<class T> _Cut<T>::
23  _Cut(const std::function<CutFunc_t>& fun,
24  const std::function<ExposureFunc_t>& liveFunc,
25  const std::function<ExposureFunc_t>& potFunc,
26  int id)
27  : fFunc(fun), fLiveFunc(liveFunc), fPOTFunc(potFunc), fID(id)
28  {
29  DepMan<_Cut<T>>::Instance().RegisterConstruction(this);
30  }
31 
32  //----------------------------------------------------------------------
33  template<class T> _Cut<T>::~_Cut()
34  {
35  DepMan<_Cut<T>>::Instance().RegisterDestruction(this);
36  }
37 
38  //----------------------------------------------------------------------
39  template<class T> _Cut<T>::_Cut(const _Cut<T>& c)
40  : fFunc(0), fLiveFunc(0), fPOTFunc(0), fID(-1)
41  {
42  if(&c == this) return;
43 
44  if(c.fFunc){
45  fFunc = c.fFunc;
46  fLiveFunc = c.fLiveFunc;
47  fPOTFunc = c.fPOTFunc;
48  fID = c.fID;
49 
50  DepMan<_Cut<T>>::Instance().RegisterConstruction(this);
51  }
52  else{
53  // If we are copying from a Cut with NULL func, that is probably because
54  // it is all zero because it hasn't been statically constructed
55  // yet. Register our interest of getting constructed in turn once it is.
56  DepMan<_Cut<T>>::Instance().RegisterDependency(&c, this);
57  }
58  }
59 
60  //----------------------------------------------------------------------
61  template<class T> _Cut<T>& _Cut<T>::
63  {
64  if(&c == this) return *this;
65 
66  if(c.fFunc){
67  fFunc = c.fFunc;
68  fLiveFunc = c.fLiveFunc;
69  fPOTFunc = c.fPOTFunc;
70  fID = c.fID;
71 
72  DepMan<_Cut<T>>::Instance().RegisterConstruction(this);
73  }
74  else{
75  fFunc = 0;
76  fLiveFunc = 0;
77  fPOTFunc = 0;
78  fID = -1;
79 
80  // If we are copying from a Cut with NULL func, that is probably because
81  // it is all zero because it hasn't been statically constructed
82  // yet. Register our interest of getting constructed in turn once it is.
83  DepMan<_Cut<T>>::Instance().RegisterDependency(&c, this);
84  }
85 
86  return *this;
87  }
88 
89  // Make sure all three versions get generated
90  template class _Cut<caf::SRProxy>;
91  template class _Cut<caf::SRSpillProxy>;
92  template class _Cut<caf::SRNeutrinoProxy>;
93 
94  template<class T> int _Cut<T>::fgNextID = 0;
95 
96  //----------------------------------------------------------------------
97  std::function<ExposureFunc_t>
98  CombineExposures(const std::function<ExposureFunc_t>& a,
99  const std::function<ExposureFunc_t>& b)
100  {
101  if(!a && !b) return 0;
102  if(!a) return b;
103  if(!b) return a;
104 
105  struct ExposureCombiner
106  {
107  std::function<ExposureFunc_t> a, b;
108  double operator()(const caf::SRSpillProxy* spill)
109  {
110  const double va = a(spill);
111  const double vb = b(spill);
112 
113  if(va >= 0 && vb >= 0){
114  std::cout << "Inconsistent pot/livetime values of "
115  << va << " and " << vb
116  << " from two cuts being combined." << std::endl;
117  abort();
118  }
119 
120  return std::max(va, vb);
121  }
122  };
123 
124  return ExposureCombiner{a, b};
125  }
126 
127  //----------------------------------------------------------------------
128  template<class T> _Cut<T> _Cut<T>::
129  operator&&(const _Cut<T>& c) const
130  {
131  // The same pairs of cuts are frequently and-ed together. Make sure those
132  // duplicates get the same IDs by remembering what we've done in the past.
133  static std::map<std::pair<int, int>, int> ids;
134  const std::pair<int, int> key(ID(), c.ID());
135 
136  struct And
137  {
138  const _Cut<T> a, b;
139  bool operator()(const T* sr) const {return a(sr) && b(sr);}
140  };
141 
142  if(ids.count(key) == 0) ids[key] = fgNextID++;
143  return _Cut<T>(And{*this, c},
146  ids[key]);
147  }
148 
149  //----------------------------------------------------------------------
150  template<class T> _Cut<T> _Cut<T>::
151  operator||(const _Cut<T>& c) const
152  {
153  static std::map<std::pair<int, int>, int> ids;
154  const std::pair<int, int> key(ID(), c.ID());
155 
156  struct Or
157  {
158  const _Cut<T> a, b;
159  bool operator()(const T* sr) const {return a(sr) || b(sr);}
160  };
161 
162  if(ids.count(key) == 0) ids[key] = fgNextID++;
163  return _Cut<T>(Or{*this, c},
166  ids[key]);
167  }
168 
169  //----------------------------------------------------------------------
170  template<class T> _Cut<T> _Cut<T>::operator!() const
171  {
172  static std::map<int, int> ids;
173 
174  struct Not
175  {
176  const _Cut<T> a;
177  bool operator()(const T* sr) const {return !a(sr);}
178  };
179 
180  if(ids.count(ID()) == 0) ids[ID()] = fgNextID++;
181  return _Cut<T>(Not{*this}, 0, 0, ids[ID()]);
182  }
183 
184  //----------------------------------------------------------------------
185  template<class T> _Cut<T>::operator bool() const
186  {
187  std::cout << "*** A Cut object is being evaluated for truth-iness. "
188  << "This very likely means you are using python and attempted "
189  << "to use one of the 'and', 'or', or 'not' operators. Python "
190  << "does not allow these to be overloaded. You should use the "
191  << "corresponding bitwise operators '&', '|', '~' instead."
192  << std::endl;
193  abort();
194  }
195 } // namespace
T max(const caf::Proxy< T > &a, T b)
std::function< ExposureFunc_t > fPOTFunc
Definition: Cut.h:81
Cuts and Vars for the 2020 FD DiF Study.
Definition: vars.h:6
std::function< ExposureFunc_t > CombineExposures(const std::function< ExposureFunc_t > &a, const std::function< ExposureFunc_t > &b)
Definition: Cut.cxx:98
static int fgNextID
The next ID that hasn&#39;t yet been assigned.
Definition: Cut.h:85
_Cut(const std::function< CutFunc_t > &func, const std::function< ExposureFunc_t > &liveFunc=0, const std::function< ExposureFunc_t > &potFunc=0)
std::function can wrap a real function, function object, or lambda
Definition: Cut.cxx:12
Deep magic to fix static initialization order. Here Be Dragons!
Definition: DepMan.h:12
_Cut< T > operator&&(const _Cut< T > &c) const
Definition: Cut.cxx:129
const double a
int ID() const
Cuts with the same definition will have the same ID.
Definition: Cut.h:55
caf::StandardRecord * sr
double func(double x, double y)
void RegisterDependency(const T *parent, T *child)
Call from copy constructor and assignment operator.
Definition: DepMan.cxx:122
std::function< ExposureFunc_t > fLiveFunc
Definition: Cut.h:81
_Cut & operator=(const _Cut< T > &c)
Definition: Cut.cxx:62
_Cut< T > operator||(const _Cut< T > &b) const
Definition: Cut.cxx:151
Proxy for caf::SRSpill.
Definition: SRProxy.h:1346
OStream cout
Definition: OStream.cxx:6
void RegisterDestruction(T *x)
Call from destructor.
Definition: DepMan.cxx:97
_Cut< T > operator!() const
Definition: Cut.cxx:170
const hit & b
Definition: hits.cxx:21
~_Cut()
Definition: Cut.cxx:33
void RegisterConstruction(T *x)
Call from constructor (in the success case)
Definition: DepMan.cxx:73
double T
Definition: Xdiff_gwt.C:5
Template for Cut and SpillCut.
Definition: Cut.h:15
std::function< CutFunc_t > fFunc
Definition: Cut.h:80
bool operator()(const T *sr) const
Allows a cut to be called with bool result = myCut(sr) syntax.
Definition: Cut.h:33
int fID
Definition: Cut.h:83