ATLAS Offline Software
CutFlow.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
10 #ifndef _IDPVM_CutFlow_h_
11 #define _IDPVM_CutFlow_h_
12 #include <functional>
13 #include <algorithm>
14 #include <string>
15 #include <vector>
16 
17 
27 template<class A>
28 class Accept {
29 public:
31  Accept() : m_predicate([](A) {
32  return false;
33  }), m_name {}, m_desc {} {
34  // nop
35  }
41  Accept(const std::function<bool(const A&)>& predicate, const std::string& name = "",
42  const std::string& description = "") : m_predicate(predicate), m_name(name), m_desc(description)
43  {
44  // nop
45  }
46 
48  bool
49  operator () (const A& i) const {
50  return pass(i);
51  }
52 
54  bool
55  pass(const A& i) const {
56  const bool passed = m_predicate(i);
57  return passed;
58  }
59 
60 
62  const std::string&
63  name() const {
64  return m_name;
65  }
66 
68  const std::string&
69  description() const {
70  return m_desc;
71  }
72 
74  typedef A value_type;
76  typedef const std::function<bool (const A&)> func_type;
77 private:
78  // std::function<bool(A)> m_predicate;
80  std::string m_name;
81  std::string m_desc;
82 };
83 
92 template<class A>
93 class CutList {
94 public:
95 
97  CutList(const std::vector<Accept<A> >& cuts) : m_cuts(cuts) {
98  // nop
99  }
100 
102  CutList() : m_cuts{} {
103  // nop
104  }
105 
106 
108  void
109  add(const Accept<A>& newCut) {
110  m_cuts.push_back(newCut);
111  }
112 
114  unsigned int
115  accept(const A& value) const {
116  unsigned int missing_cuts = m_cuts.size();
117 
118  for (auto& thisCut:m_cuts) {
119  if (not thisCut.pass(value)) {
120  break;
121  }
122  --missing_cuts;
123  }
124  return missing_cuts;
125  }
126 
127  unsigned int
128  testAllCuts(const A& value, std::vector<unsigned int> &counter) const {
129  unsigned int idx = 0;
130  ++(counter[idx++]);
131  if (counter.size() != m_cuts.size()+2 /* CutFlow::kNReserved */) {
132  throw std::logic_error("Number of cuts and counters do not match." );
133  }
134  unsigned int missing_cuts = 0;
135  ++(counter[idx++]);
136  for (auto& thisCut:m_cuts) {
137  if (!thisCut.pass(value)) { ++missing_cuts; }
138  else { ++(counter[idx]); }
139  ++idx;
140  }
141  return missing_cuts;
142  }
143 
145  unsigned int
146  size() const {
147  return m_cuts.size();
148  }
149 
151  std::vector<std::string>
152  names() const {
153  std::vector<std::string> result(m_cuts.size());
154  unsigned int idx(0);
155  for (const auto& i:m_cuts) {
156  result[idx++] = i.name();
157  }
158  return result; // return-value-optimisation is invoked
159  }
160 
161 private:
162  std::vector<Accept<A> > m_cuts;
163 };
164 
165 class CutFlow
166 {
167 public:
168 
169  enum CutMode {
171  };
172 
176  kNReserved
177  };
178 
179  CutFlow() {}
180 
181  CutFlow(unsigned int n_cuts, CutMode cut_mode = UNTIL_FAIL)
182  : m_counter(n_cuts+kNReserved,0) ,
183  m_integrated( cut_mode == ALL ),
184  m_accumulateIntegrated( cut_mode == ALL )
185  {}
186 
187  std::vector<unsigned int> &counter() {return m_counter; }
188  const std::vector<unsigned int> &counter() const {return m_counter; }
189 
190  private:
191  // disallow implicit conversion of CutResult
192  void update(bool) {
193  }
194 
195  public:
196  //@TODO event weights ?
197  void update(unsigned int missing_cuts) {
198  assert( m_integrated == false);
199  ++(m_counter.at(m_counter.size()-missing_cuts-1) );
200  }
201 
202  void merge(CutFlow &&a_cutflow) {
203  if (m_counter.empty()) {
204  m_counter = std::move(a_cutflow.m_counter);
205  m_integrated = a_cutflow.m_integrated;
206  m_accumulateIntegrated = a_cutflow.m_accumulateIntegrated;
207  }
208  else {
209  if (m_counter.size() != a_cutflow.m_counter.size() || m_integrated != a_cutflow.m_integrated) {
210  throw std::logic_error("Tried to merge non matching cut_flows.");
211  }
213  for(unsigned int count : a_cutflow.m_counter) {
214  *(iter++) += count;
215  }
216  }
217  }
218 
219  void clear() {
220  for(unsigned int &count : m_counter) {count=0; }
221  }
222 
224  std::string
225  report(const std::vector<std::string> &names) {
226  if (not m_integrated) {
227  unsigned int sum=0;
228  for(std::vector<unsigned int>::reverse_iterator iter = m_counter.rbegin();
229  iter != m_counter.rend();
230  ++iter) {
231  *iter += sum;
232  sum = *iter;
233  };
234  m_integrated=true;
235  }
236 
237  std::string op = "\nCutList Report; Total processed: " + std::to_string(m_counter[kIsValidParticle]);
238  op += "\nTotal passed: " + std::to_string(m_counter[m_counter.size()-1]);
239  std::string modeString = (m_accumulateIntegrated) ? "\nAll cuts were applied\n" : "\nCuts were applied until one fails\n";
240  op += modeString;
241  for (unsigned int idx=0; idx<names.size(); ++idx) {
242  op += names[idx] + ": " + std::to_string( idx+kNReserved<m_counter.size() ? m_counter[idx+kNReserved] : -1) + " passed\n";
243  }
244  if (names.size()+kNReserved != m_counter.size()) {
245  throw std::logic_error(std::string( "Number of cuts and counters do not match. Resulting report:\n") + op );
246  }
247  return op;
248  }
249 
250 private:
251  std::vector<unsigned int> m_counter;
252  bool m_integrated = false;
254 };
255 #endif
xAOD::iterator
JetConstituentVector::iterator iterator
Definition: JetConstituentVector.cxx:68
CutFlow::clear
void clear()
Definition: CutFlow.h:219
Accept::name
const std::string & name() const
Return cut name.
Definition: CutFlow.h:63
CutFlow::merge
void merge(CutFlow &&a_cutflow)
Definition: CutFlow.h:202
CutList::accept
unsigned int accept(const A &value) const
Apply cuts and return the boolean result; keep count of number of calls and passes.
Definition: CutFlow.h:115
get_generator_info.result
result
Definition: get_generator_info.py:21
TrigCompositeUtils::passed
bool passed(DecisionID id, const DecisionIDContainer &idSet)
checks if required decision ID is in the set of IDs in the container
Definition: TrigCompositeUtilsRoot.cxx:117
CutFlow::CutFlow
CutFlow()
Definition: CutFlow.h:179
CutFlow::UNTIL_FAIL
@ UNTIL_FAIL
Definition: CutFlow.h:170
CutFlow::m_counter
std::vector< unsigned int > m_counter
Definition: CutFlow.h:251
athena.value
value
Definition: athena.py:122
CutList::add
void add(const Accept< A > &newCut)
Add one cut.
Definition: CutFlow.h:109
Accept::m_desc
std::string m_desc
Definition: CutFlow.h:81
CutFlow::counter
std::vector< unsigned int > & counter()
Definition: CutFlow.h:187
CutList
Templated CutList class to contain a group of cuts.
Definition: CutFlow.h:93
CutFlow::update
void update(bool)
Definition: CutFlow.h:192
XMLtoHeader.count
count
Definition: XMLtoHeader.py:85
CutFlow::m_integrated
bool m_integrated
Definition: CutFlow.h:252
CutFlow::CutFlow
CutFlow(unsigned int n_cuts, CutMode cut_mode=UNTIL_FAIL)
Definition: CutFlow.h:181
dqt_zlumi_alleff_HIST.A
A
Definition: dqt_zlumi_alleff_HIST.py:110
CutFlow::counter
const std::vector< unsigned int > & counter() const
Definition: CutFlow.h:188
CutFlow::update
void update(unsigned int missing_cuts)
Definition: CutFlow.h:197
CutFlow::ALL
@ ALL
Definition: CutFlow.h:170
CutFlow::kIsValidParticle
@ kIsValidParticle
Definition: CutFlow.h:175
convertTimingResiduals.sum
sum
Definition: convertTimingResiduals.py:55
CutFlow::EReservedCuts
EReservedCuts
Definition: CutFlow.h:173
lumiFormat.i
int i
Definition: lumiFormat.py:92
Accept::m_name
std::string m_name
Definition: CutFlow.h:80
python.subdetectors.mmg.names
names
Definition: mmg.py:8
CutFlow::kNReserved
@ kNReserved
Definition: CutFlow.h:176
Accept::func_type
const std::function< bool(const A &)> func_type
Utility typedefs to help callers: the function type.
Definition: CutFlow.h:76
CutFlow::report
std::string report(const std::vector< std::string > &names)
Produce a formatted string report of the results.
Definition: CutFlow.h:225
Accept::description
const std::string & description() const
Return cut description.
Definition: CutFlow.h:69
CutFlow::kAll
@ kAll
Definition: CutFlow.h:174
plotBeamSpotVert.cuts
string cuts
Definition: plotBeamSpotVert.py:93
CutFlow
Definition: CutFlow.h:166
Accept::Accept
Accept(const std::function< bool(const A &)> &predicate, const std::string &name="", const std::string &description="")
Normal constructor.
Definition: CutFlow.h:41
CutList::size
unsigned int size() const
Return the number of cuts.
Definition: CutFlow.h:146
Accept::operator()
bool operator()(const A &i) const
Overloading the () operator allows the class to be used as a functional.
Definition: CutFlow.h:49
ActsTrk::to_string
std::string to_string(const DetectorType &type)
Definition: GeometryDefs.h:34
Accept::pass
bool pass(const A &i) const
Apply the predicate function and return the value, also updating an internal counter.
Definition: CutFlow.h:55
Accept::value_type
A value_type
Utility typedefs to help callers: the value type.
Definition: CutFlow.h:74
CutFlow::m_accumulateIntegrated
bool m_accumulateIntegrated
Definition: CutFlow.h:253
CutList::CutList
CutList()
Default constructor with no cuts implemented.
Definition: CutFlow.h:102
CutFlow::CutMode
CutMode
Definition: CutFlow.h:169
LArNewCalib_DelayDump_OFC_Cali.idx
idx
Definition: LArNewCalib_DelayDump_OFC_Cali.py:69
CutList::CutList
CutList(const std::vector< Accept< A > > &cuts)
Normal constructor takes a vector<Accept>. Note default mode is 'ALL'.
Definition: CutFlow.h:97
Accept
Templated class containing a cut, name of cut and description of cut(optional) Typically,...
Definition: CutFlow.h:28
test_pyathena.counter
counter
Definition: test_pyathena.py:15
Accept::Accept
Accept()
Default constructor with a simple predicate returning false.
Definition: CutFlow.h:31
xAOD::bool
setBGCode setTAP setLVL2ErrorBits bool
Definition: TrigDecision_v1.cxx:60
CutList::names
std::vector< std::string > names() const
Return a vector of the cut names.
Definition: CutFlow.h:152
CutList::testAllCuts
unsigned int testAllCuts(const A &value, std::vector< unsigned int > &counter) const
Definition: CutFlow.h:128
CutList::m_cuts
std::vector< Accept< A > > m_cuts
Definition: CutFlow.h:162
Accept::m_predicate
func_type m_predicate
Definition: CutFlow.h:79