ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtContainerManip.h
Go to the documentation of this file.
1 #ifndef ATCONTAINERMANIP_H
2 #define ATCONTAINERMANIP_H
3 
4 #include <FairLogger.h>
5 
6 #include <TH1.h> // for TH1, TH1D (ptr only)
7 
8 #include <algorithm> // IWYU pragma: keep
9 #include <iterator> // for make_move_iterator
10 #include <memory>
11 #include <string> // for string
12 #include <type_traits> // for remove_const_t
13 #include <vector>
14 
15 namespace ContainerManip {
16 
23 template <typename T>
24 void SetHistFromData(TH1 &hist, const T &data, double xMin = 0, double xMax = 0)
25 {
26  if (xMin == 0 && xMax == 0)
27  xMax = data.size();
28  hist.Reset();
29  hist.SetBins(data.size(), xMin, xMax);
30  for (int i = 0; i < hist.GetNbinsX(); ++i)
31  hist.SetBinContent(i + 1, data.at(i));
32 }
33 
41 template <typename Hist = TH1D, typename T>
42 std::unique_ptr<Hist> CreateHistFromData(const std::string &name, const T &data, double xMin = 0, double xMax = 0)
43 {
44  if (xMin == 0 && xMax == 0)
45  xMax = data.size();
46 
47  TH1::AddDirectory(false); // Make sure pointer has ownership
48  auto ret = std::make_unique<Hist>(name.data(), name.data(), data.size(), 0, data.size());
49  for (int i = 0; i < ret->GetNbinsX(); ++i)
50  ret->SetBinContent(i + 1, data.at(i));
51  // ret->SetDirectory(nullptr);
52  TH1::AddDirectory(true);
53  return ret;
54 }
55 
56 template <typename T>
57 T GetMedian(std::vector<T> &vec)
58 {
59  if (vec.empty())
60  return 0;
61 
62  auto n = vec.size() / 2;
63 
64  std::nth_element(vec.begin(), vec.begin() + n, vec.end());
65  auto med = vec[n];
66  if (vec.size() % 2 == 0) { // if even, get average of middle two entries
67  med = (*std::max_element(vec.begin(), vec.begin() + n) + med) / 2.0;
68  }
69  return med;
70 }
71 
72 template <typename T>
73 T *GetPointer(T &t)
74 {
75  return &t;
76 }
77 
78 template <typename T>
79 std::remove_const_t<T> *GetPointerNonConst(T &t)
80 {
81  return const_cast<T *>(&t);
82 }
83 
84 template <typename T>
85 std::vector<const T *> GetConstPointerVector(const std::vector<T> &vec)
86 {
87  LOG(debug) << "Transforming object -> pointer.";
88  std::vector<const T *> ret;
89  ret.resize(vec.size());
90  std::transform(vec.begin(), vec.end(), ret.begin(), [](const T &a) { return GetPointer(a); });
91  return ret;
92 }
93 
94 template <typename T>
95 std::vector<const T *> GetConstPointerVector(const std::vector<std::unique_ptr<T>> &vec)
96 {
97  LOG(debug) << "Transforming unique pointer -> pointer.";
98  std::vector<const T *> ret;
99  ret.resize(vec.size());
100  std::transform(vec.begin(), vec.end(), ret.begin(), [](const std::unique_ptr<T> &a) { return a.get(); });
101  return ret;
102 }
103 
104 template <typename T>
105 std::vector<T *> GetPointerVector(const std::vector<T> &vec)
106 {
107  LOG(debug) << "Transforming object -> pointer.";
108  std::vector<T *> ret;
109  ret.resize(vec.size());
110  std::transform(vec.begin(), vec.end(), ret.begin(), [](const T &a) { return GetPointer(a); });
111  return ret;
112 }
113 
114 template <typename T>
115 std::vector<T *> GetPointerVector(const std::vector<std::unique_ptr<T>> &vec)
116 {
117  LOG(debug) << "Transforming unique pointer -> pointer.";
118  std::vector<T *> ret;
119  ret.resize(vec.size());
120  std::transform(vec.begin(), vec.end(), ret.begin(), [](const std::unique_ptr<T> &a) { return a.get(); });
121  return ret;
122 }
123 
124 template <typename T>
125 std::vector<T> GetObjectVector(const std::vector<std::unique_ptr<T>> &vec)
126 {
127  LOG(debug) << "Transforming unique pointer -> object.";
128  std::vector<T> ret;
129  ret.resize(vec.size());
130  std::transform(vec.begin(), vec.end(), ret.begin(), [](const std::unique_ptr<T> &a) { return *a; });
131  return ret;
132 }
133 
134 template <typename T>
135 std::vector<T &> GetReferenceVector(const std::vector<std::unique_ptr<T>> &vec)
136 {
137  LOG(debug) << "Transforming unique pointer -> object.";
138  std::vector<T &> ret;
139  ret.resize(vec.size());
140  std::transform(vec.begin(), vec.end(), ret.begin(), [](const std::unique_ptr<T> &a) { return *a; });
141  return ret;
142 }
143 
150 template <typename T, typename Operator>
151 std::vector<T> MoveFromVector(std::vector<T> &vec, Operator op)
152 {
153  std::vector<T> retVec;
154  auto itStartEqualRange = vec.end();
155 
156  for (auto it = vec.begin(); it != vec.end(); ++it) {
157 
158  bool isInPattern = op(*it);
159 
160  // Start of sub-vector with vec in pattern
161  if (isInPattern && itStartEqualRange == vec.end()) {
162  itStartEqualRange = it;
163  continue;
164  }
165 
166  // End of sub-vector with vec in pattern.
167  // Move vec in this range to retVec then delete the empty entries
168  if (itStartEqualRange != vec.end() && !isInPattern) {
169  retVec.insert(retVec.end(), std::make_move_iterator(itStartEqualRange), std::make_move_iterator(it));
170  vec.erase(itStartEqualRange, it);
171  it = itStartEqualRange;
172  itStartEqualRange = vec.end();
173  continue;
174  }
175  }
176 
177  // If the last chunk of the array was in the pattern, move it and delete empty entries
178  if (itStartEqualRange != vec.end()) {
179  auto it = vec.end();
180  retVec.insert(retVec.end(), std::make_move_iterator(itStartEqualRange), std::make_move_iterator(it));
181  vec.erase(itStartEqualRange, it);
182  }
183  return retVec;
184 }
185 
186 } // namespace ContainerManip
187 
188 #endif //#ifndef ATCONTAINERMANIP_H
ContainerManip::GetObjectVector
std::vector< T > GetObjectVector(const std::vector< std::unique_ptr< T >> &vec)
Definition: AtContainerManip.h:125
ContainerManip::CreateHistFromData
std::unique_ptr< Hist > CreateHistFromData(const std::string &name, const T &data, double xMin=0, double xMax=0)
Use contents of data to create a histogram with the given name.
Definition: AtContainerManip.h:42
ContainerManip::GetPointer
T * GetPointer(T &t)
Definition: AtContainerManip.h:73
ContainerManip::GetConstPointerVector
std::vector< const T * > GetConstPointerVector(const std::vector< T > &vec)
Definition: AtContainerManip.h:85
ContainerManip::GetPointerNonConst
std::remove_const_t< T > * GetPointerNonConst(T &t)
Definition: AtContainerManip.h:79
ContainerManip::MoveFromVector
std::vector< T > MoveFromVector(std::vector< T > &vec, Operator op)
Definition: AtContainerManip.h:151
ContainerManip
Definition: AtContainerManip.h:15
ContainerManip::GetPointerVector
std::vector< T * > GetPointerVector(const std::vector< T > &vec)
Definition: AtContainerManip.h:105
ContainerManip::SetHistFromData
void SetHistFromData(TH1 &hist, const T &data, double xMin=0, double xMax=0)
Use contents of data to set the bin contents of hist.
Definition: AtContainerManip.h:24
ContainerManip::GetReferenceVector
std::vector< T & > GetReferenceVector(const std::vector< std::unique_ptr< T >> &vec)
Definition: AtContainerManip.h:135
ContainerManip::GetMedian
T GetMedian(std::vector< T > &vec)
Definition: AtContainerManip.h:57