CMS 3D CMS Logo

MergeableCounterTable.h
Go to the documentation of this file.
1 #ifndef DataFormats_NanoAOD_MergeableCounterTable_h
2 #define DataFormats_NanoAOD_MergeableCounterTable_h
3 
5 #include <vector>
6 #include <string>
7 #include <algorithm>
8 
9 namespace nanoaod {
10 
12  public:
14  typedef long long int_accumulator; // we accumulate in long long int, to avoid overflow
15  typedef double float_accumulator; // we accumulate in double, to preserve precision
16 
17  template <typename T>
18  struct SingleColumn {
19  typedef T value_type;
21  SingleColumn(const std::string& aname, const std::string& adoc, T avalue = T())
22  : name(aname), doc(adoc), value(avalue) {}
26  if (!compatible(other))
27  throw cms::Exception("LogicError",
28  "Trying to merge " + name + " with " + other.name + " failed compatibility test.\n");
29  value += other.value;
30  }
32  return name == other.name; // we don't check the doc, not needed
33  }
34  };
37 
38  template <typename T>
41  SingleWithNormColumn(const std::string& aname, const std::string& adoc, T avalue = T(), const double anorm = 0)
42  : SingleColumn<T>(aname, adoc, avalue), norm(anorm) {}
43  double norm;
45  if (!this->compatible(other))
46  throw cms::Exception(
47  "LogicError", "Trying to merge " + this->name + " with " + other.name + " failed compatibility test.\n");
48  auto newNorm = norm + other.norm;
49  this->value = (newNorm != 0) ? (this->value * norm + other.value * other.norm) / newNorm : 0;
50  norm = newNorm;
51  }
52  };
54 
55  template <typename T>
56  struct VectorColumn {
57  typedef T element_type;
59  VectorColumn(const std::string& aname, const std::string& adoc, unsigned int size)
60  : name(aname), doc(adoc), values(size, T()) {}
61  VectorColumn(const std::string& aname, const std::string& adoc, const std::vector<T>& somevalues)
62  : name(aname), doc(adoc), values(somevalues) {}
64  std::vector<T> values;
66  if (!compatible(other))
67  throw cms::Exception("LogicError",
68  "Trying to merge " + name + " with " + other.name + " failed compatibility test.\n");
69  for (unsigned int i = 0, n = values.size(); i < n; ++i) {
70  values[i] += other.values[i];
71  }
72  }
74  return name == other.name && values.size() == other.values.size(); // we don't check the doc, not needed
75  }
76  };
79 
80  template <typename T>
82  double norm;
84  VectorWithNormColumn(const std::string& aname, const std::string& adoc, unsigned int size, double anorm = 0)
85  : VectorColumn<T>(aname, adoc, size), norm(anorm) {}
87  const std::string& adoc,
88  const std::vector<T>& somevalues,
89  double anorm = 0)
90  : VectorColumn<T>(aname, adoc, somevalues), norm(anorm) {}
92  if (!this->compatible(other))
93  throw cms::Exception(
94  "LogicError", "Trying to merge " + this->name + " with " + other.name + " failed compatibility test.\n");
95  auto newNorm = norm + other.norm;
96  for (unsigned int i = 0, n = this->values.size(); i < n; ++i) {
97  this->values[i] =
98  (newNorm != 0) ? (this->values[i] * norm + other.values[i] * other.norm) / (norm + other.norm) : 0;
99  }
100  norm = newNorm;
101  }
102  };
104 
105  const std::vector<FloatColumn>& floatCols() const { return floatCols_; }
106  const std::vector<VFloatColumn>& vfloatCols() const { return vfloatCols_; }
107  const std::vector<FloatWithNormColumn>& floatWithNormCols() const { return floatWithNormCols_; }
108  const std::vector<VFloatWithNormColumn>& vfloatWithNormCols() const { return vfloatWithNormCols_; }
109  const std::vector<IntColumn>& intCols() const { return intCols_; }
110  const std::vector<VIntColumn>& vintCols() const { return vintCols_; }
111 
112  template <typename F>
113  void addFloat(const std::string& name, const std::string& doc, F value) {
114  floatCols_.push_back(FloatColumn(name, doc, value));
115  }
116 
117  template <typename F>
118  void addFloatWithNorm(const std::string& name, const std::string& doc, F value, double norm) {
120  }
121 
122  template <typename I>
123  void addInt(const std::string& name, const std::string& doc, I value) {
124  intCols_.push_back(IntColumn(name, doc, value));
125  }
126 
127  template <typename F>
128  void addVFloat(const std::string& name, const std::string& doc, const std::vector<F> values) {
129  vfloatCols_.push_back(VFloatColumn(name, doc, values.size()));
130  std::copy(values.begin(), values.end(), vfloatCols_.back().values.begin());
131  }
132 
133  template <typename F>
134  void addVFloatWithNorm(const std::string& name, const std::string& doc, const std::vector<F> values, double norm) {
135  vfloatWithNormCols_.push_back(VFloatWithNormColumn(name, doc, values.size(), norm));
136  std::copy(values.begin(), values.end(), vfloatWithNormCols_.back().values.begin());
137  }
138 
139  template <typename I>
140  void addVInt(const std::string& name, const std::string& doc, const std::vector<I> values) {
141  vintCols_.push_back(VIntColumn(name, doc, values.size()));
142  std::copy(values.begin(), values.end(), vintCols_.back().values.begin());
143  }
144 
146  if (!tryMerge(intCols_, other.intCols_))
147  return false;
148  if (!tryMerge(vintCols_, other.vintCols_))
149  return false;
150  if (!tryMerge(floatCols_, other.floatCols_))
151  return false;
152  if (!tryMerge(vfloatCols_, other.vfloatCols_))
153  return false;
154  if (!tryMerge(floatWithNormCols_, other.floatWithNormCols_))
155  return false;
156  if (!tryMerge(vfloatWithNormCols_, other.vfloatWithNormCols_))
157  return false;
158  return true;
159  }
160 
161  void swap(MergeableCounterTable& iOther) {
162  floatCols_.swap(iOther.floatCols_);
163  vfloatCols_.swap(iOther.vfloatCols_);
166  intCols_.swap(iOther.intCols_);
167  vintCols_.swap(iOther.vintCols_);
168  }
169 
170  private:
171  std::vector<FloatColumn> floatCols_;
172  std::vector<VFloatColumn> vfloatCols_;
173  std::vector<FloatWithNormColumn> floatWithNormCols_;
174  std::vector<VFloatWithNormColumn> vfloatWithNormCols_;
175  std::vector<IntColumn> intCols_;
176  std::vector<VIntColumn> vintCols_;
177 
178  template <typename T>
179  bool tryMerge(std::vector<T>& one, const std::vector<T>& two) {
180  for (auto y : two) {
181  auto x = std::find_if(one.begin(), one.end(), [&y](const T& x) { return x.name == y.name; });
182  if (x == one.end())
183  one.push_back(y);
184  else
185  (*x) += y;
186  }
187  return true;
188  }
189  };
190 
191 } // namespace nanoaod
192 
193 #endif
SingleColumn< float_accumulator > FloatColumn
void addInt(const std::string &name, const std::string &doc, I value)
void operator+=(const SingleColumn< T > &other)
bool compatible(const VectorColumn< T > &other)
VectorColumn(const std::string &aname, const std::string &adoc, unsigned int size)
void addFloat(const std::string &name, const std::string &doc, F value)
void operator+=(const VectorWithNormColumn< T > &other)
std::vector< VFloatWithNormColumn > vfloatWithNormCols_
const std::vector< VFloatColumn > & vfloatCols() const
std::vector< IntColumn > intCols_
void addVInt(const std::string &name, const std::string &doc, const std::vector< I > values)
const std::vector< FloatWithNormColumn > & floatWithNormCols() const
const std::vector< IntColumn > & intCols() const
void operator+=(const SingleWithNormColumn< T > &other)
void swap(MergeableCounterTable &iOther)
void addVFloatWithNorm(const std::string &name, const std::string &doc, const std::vector< F > values, double norm)
VectorWithNormColumn(const std::string &aname, const std::string &adoc, unsigned int size, double anorm=0)
VectorColumn(const std::string &aname, const std::string &adoc, const std::vector< T > &somevalues)
void operator+=(const VectorColumn< T > &other)
const std::vector< VFloatWithNormColumn > & vfloatWithNormCols() const
SingleWithNormColumn< float_accumulator > FloatWithNormColumn
void addVFloat(const std::string &name, const std::string &doc, const std::vector< F > values)
const std::vector< FloatColumn > & floatCols() const
VectorWithNormColumn< float_accumulator > VFloatWithNormColumn
bool tryMerge(std::vector< T > &one, const std::vector< T > &two)
std::vector< FloatWithNormColumn > floatWithNormCols_
const std::complex< double > I
Definition: I.h:8
std::vector< VIntColumn > vintCols_
Definition: value.py:1
std::vector< VFloatColumn > vfloatCols_
bool compatible(const SingleColumn< T > &other)
const std::vector< VIntColumn > & vintCols() const
std::vector< FloatColumn > floatCols_
void addFloatWithNorm(const std::string &name, const std::string &doc, F value, double norm)
VectorColumn< float_accumulator > VFloatColumn
float x
SingleWithNormColumn(const std::string &aname, const std::string &adoc, T avalue=T(), const double anorm=0)
VectorColumn< int_accumulator > VIntColumn
VectorWithNormColumn(const std::string &aname, const std::string &adoc, const std::vector< T > &somevalues, double anorm=0)
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
SingleColumn< int_accumulator > IntColumn
long double T
bool mergeProduct(const MergeableCounterTable &other)
SingleColumn(const std::string &aname, const std::string &adoc, T avalue=T())