TimeDistribution.h
Go to the documentation of this file.
1 #ifndef _utl_TimeDistribution_h_
2 #define _utl_TimeDistribution_h_
3 
4 #include <utl/ErrorLogger.h>
5 #include <utl/AugerException.h>
6 #include <utl/IteratorRange.h>
7 
8 #include <boost/tuple/tuple_io.hpp>
9 #include <boost/iterator/transform_iterator.hpp>
10 
11 #include <map>
12 #include <cmath>
13 #include <iostream>
14 
15 
16 namespace utl {
17 
18  class TimeDistributionAlgorithm;
19 
20 
37  template<typename T>
38  class TimeDistribution {
39 
40  private:
41  typedef std::map<int, T> InternalMap;
42  typedef typename InternalMap::value_type InternalMapValue;
43  typedef typename InternalMap::iterator InternalIterator;
44  typedef typename InternalMap::const_iterator InternalConstIterator;
45 
46  public:
47  typedef T ValueType;
48  typedef boost::tuple<const int, const T> Tuple;
49 
51  Tuple operator()(const InternalMapValue& pair) const
52  { return Tuple(pair.first, pair.second); }
53  };
54 
70  typedef boost::transform_iterator<InternalMapFunctor,
73 
75  TimeDistribution(const double slotSize) : fSlotSize(slotSize) { }
76 
78  void Clear() { decltype(fData)().swap(fData); }
79 
81  int
83  {
84  int n = 0;
85  for (InternalIterator it = fData.begin(); it != fData.end(); ) {
86  if (it->second == T()) {
87  it = fData.erase(it);
88  ++n;
89  } else
90  ++it;
91  }
92  return n;
93  }
94 
96  void
97  AddTime(const int slot, const T weight = T(1))
98  {
99  if (!weight)
100  return;
101  const std::pair<InternalIterator, bool> ins = fData.insert(InternalMapValue(slot, weight));
102  if (!ins.second) {
103  const InternalIterator& it = ins.first;
104  const T w = (it->second += weight);
105  if (!w)
106  fData.erase(it);
107  }
108  }
109 
111 
112  void AddTime(const double time, const T weight = T(1))
113  { AddTime(int(std::floor(time/fSlotSize)), weight); }
114 
115  void
116  SetTime(const int slot, const T weight = T(1))
117  {
118  if (weight)
119  fData[slot] = weight;
120  else {
121  const InternalIterator it = fData.find(slot);
122  if (it != fData.end())
123  fData.erase(it);
124  }
125  }
126 
127  void SetTime(const double time, const T weight = T(1))
128  { SetTime(int(std::floor(time/fSlotSize)), weight); }
129 
131 
132  T& operator[](const int index) { return fData[index]; }
133 
135 
137  const T&
138  operator[](const int index)
139  const
140  {
141  static const T zero = T(0);
142  const InternalConstIterator it = fData.find(index);
143  return it == fData.end() ? zero : it->second;
144  }
145 
147 
148  T& operator[](const double time)
149  { return operator[](int(std::floor(time/fSlotSize))); }
150 
151  const T& operator[](const double time) const
152  { return operator[](int(std::floor(time/fSlotSize))); }
153 
155  T
156  At(const int index)
157  const
158  {
159  const InternalConstIterator it = fData.find(index);
160  return it == fData.end() ? 0 : it->second;
161  }
162 
163  T At(const double time) const
164  { return At(int(std::floor(time/fSlotSize))); }
165 
169  const
170  {
171  if (GetBinning() == td.GetBinning()) {
172  TimeDistribution<T> val(*this);
173  for (const auto& kv : td.fData)
174  if (kv.second)
175  val[kv.first] += kv.second;
176  return val;
177  }
178  const std::string msg = "Cannot add two TimeDistributions with unequal binning.";
179  ERROR(msg);
180  throw AugerException(msg); // not sure what kind of exception to throw here.
181  }
182 
185  {
186  if (GetBinning() == td.GetBinning()) {
187  for (const auto& kv : td.fData)
188  if (kv.second)
189  (*this)[kv.first] += kv.second;
190  return *this;
191  }
192  const std::string msg = "Cannot add two TimeDistributions with unequal binning.";
193  ERROR(msg);
194  throw AugerException(msg); // not sure what kind of exception to throw here.
195  }
196 
197  bool operator==(const TimeDistribution& td) const
198  { return fSlotSize == td.fSlotSize && fData == td.fData; }
199 
200  bool operator!=(const TimeDistribution& td) const
201  { return !operator==(td); }
202 
204  double GetBinning() const { return fSlotSize; }
205 
207  int GetStart() const { return fData.empty() ? 0 : fData.begin()->first; }
208 
210  int GetStop() const { return fData.empty() ? -1 : fData.rbegin()->first; }
211 
213  int GetNumSlots() const
214  { return fData.empty() ? 0 : fData.rbegin()->first - fData.begin()->first + 1; }
215 
217  SparseIterator SparseBegin() const { return SparseIterator(fData.begin()); }
218 
219  SparseIterator SparseEnd() const { return SparseIterator(fData.end()); }
220 
222 
223  private:
225  double fSlotSize = 0;
226 
228 
229  };
230 
231 
232  typedef TimeDistribution<double> TimeDistributionD;
233  typedef TimeDistribution<int> TimeDistributionI;
234 
235 
236  template<typename T>
237  void Print(std::ostream& os, const TimeDistribution<T>& td);
238 
239 }
240 
241 
242 #endif
T At(const double time) const
int GetStart() const
First slot with data.
Tuple operator()(const InternalMapValue &pair) const
TimeDistribution(const double slotSize)
Constructor takes the bin size as an argument.
Base class for all exceptions used in the auger offline code.
void swap(utl::TabulatedFunction &t1, utl::TabulatedFunction &t2)
bool operator==(const TimeDistribution &td) const
Histogram class for time distributions with suppressed empty bins.
InternalMap::const_iterator InternalConstIterator
void Clear()
Remove contents of the TimeDistribution.
boost::tuple< const int, const T > Tuple
void SetTime(const double time, const T weight=T(1))
TimeDistribution< T > operator+(const TimeDistribution< T > &td) const
Add two traces. Adds only bins that have data in them.
const std::pair< InternalIterator, bool > ins
double GetBinning() const
Size of one slot.
const T & operator[](const int index) const
Return slot content.
T const
Query value without slot creation.
int GetStop() const
Last slot with data (1 less than First slot if no data)
T & operator[](const double time)
Return contents for slot containing the specified time.
std::map< int, T > InternalMap
#define OFFLINE_MAKE_CONST_ITERATOR_RANGE(_ConstIterator_, _NamePrefix_)
Definition: IteratorRange.h:28
void Print(ostream &os, const TimeDistribution< T > &td)
bool operator!=(const TimeDistribution &td) const
SparseIterator SparseEnd() const
TimeDistribution< T > & operator+=(const TimeDistribution< T > &td)
T & operator[](const int index)
Return slot content.
int GetNumSlots() const
Number of slots from first slot with data up to last slot with data, including empty slots...
Utility class for returning properties of a TimeDistribution.
SparseIterator SparseBegin() const
Iterator over time slots with data in them (skips empty slots).
const T & operator[](const double time) const
#define ERROR(message)
Macro for logging error messages.
Definition: ErrorLogger.h:165
void AddTime(const double time, const T weight=T(1))
Add an entry (optionally weighted) for the given time. Slot will be computed.
InternalMap::value_type InternalMapValue
boost::transform_iterator< InternalMapFunctor, InternalConstIterator, Tuple > SparseIterator
InternalMap::iterator InternalIterator
int Purge()
Remove empty slots and return their number.

, generated on Tue Sep 26 2023.