ATLAS Offline Software
DataBin.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
6 #include <algorithm>
7 #include <iostream>
8 #include "cmath"
9 #include <TString.h> // for Form
10 
11 using namespace MuonCalib;
12 
13 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
14 //:: IMPLEMENTATION OF METHODS DEFINED IN THE CLASS DataBin ::
15 //::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
16 
17 //*****************************************************************************
18 
19 //:::::::::::::::::
20 //:: CONSTRUCTOR ::
21 //:::::::::::::::::
22 
24 }
25 
26 //*****************************************************************************
27 
28 //:::::::::::::::::
29 //:: CONSTRUCTOR ::
30 //:::::::::::::::::
31 
32 DataBin::DataBin(const std::vector<DataPoint>& points, const double epsilon) {
33 
34  for (unsigned int k=0; k<points.size(); k++) {
35  addPointAndResize(points[k], epsilon);
36  }
37 
38 }
39 
40 //*****************************************************************************
41 
42 //:::::::::::::::::
43 //:: CONSTRUCTOR ::
44 //:::::::::::::::::
45 
46 DataBin::DataBin(const Amg::VectorX & lower_boundaries,
47  const Amg::VectorX & upper_boundaries) {
48 
50 // CHECK WHETHER BOUNDARIES DIMENSIONS ARE CONSISTENT //
52 
53  if (lower_boundaries.rows()!=upper_boundaries.rows()) {
54  throw std::runtime_error(Form("File: %s, Line: %d\nDataBin::DataBin - Dimensions of lower and upper bin boundaries disagree.", __FILE__, __LINE__));
55  }
56 
58 // COPY THE BOUNDARIES AND CALCULATE THE BIN CENTRE //
60 
61  m_lower_boundaries = lower_boundaries;
62  m_upper_boundaries = upper_boundaries;
63 
65 
66 }
67 
68 //*****************************************************************************
69 
70 //::::::::::::::::::::
71 //:: METHOD DataBin ::
72 //::::::::::::::::::::
73 
74 double DataBin::density() const {
75 
76  double volume(1.0);
77  for (int k=0; k<m_lower_boundaries.cols(); k++) {
78  volume = volume*(m_upper_boundaries[k]-m_lower_boundaries[k]);
79  }
80  return m_points.size()/volume;
81 
82 }
83 
84 //*****************************************************************************
85 
86 //::::::::::::::::::::::::
87 //:: METHOD centreOfBin ::
88 //::::::::::::::::::::::::
89 
91 
92  return m_bin_centre;
93 
94 }
95 
96 //*****************************************************************************
97 
98 //:::::::::::::::::::::::::::::::
99 //:: METHOD lowerBinBoundaries ::
100 //:::::::::::::::::::::::::::::::
101 
103 
104  return m_lower_boundaries;
105 
106 }
107 
108 //*****************************************************************************
109 
110 //:::::::::::::::::::::::::::::::
111 //:: METHOD upperbinBoundaries ::
112 //:::::::::::::::::::::::::::::::
113 
115 
116  return m_upper_boundaries;
117 
118 }
119 
120 //*****************************************************************************
121 
122 //::::::::::::::::::::::::::::
123 //:: METHOD centreOfGravity ::
124 //::::::::::::::::::::::::::::
125 
127 
128  return m_centre_of_gravity;
129 
130 }
131 
132 //*****************************************************************************
133 
134 //:::::::::::::::::::::::::::::::
135 //:: METHOD standardDeviations ::
136 //:::::::::::::::::::::::::::::::
137 
139 
140  return m_standard_deviations;
141 
142 }
143 
144 //*****************************************************************************
145 
146 //:::::::::::::::::::::::::::::::
147 //:: METHOD numberOfDataPoints ::
148 //:::::::::::::::::::::::::::::::
149 
150 unsigned int DataBin::numberOfDataPoints() const {
151 
152  return m_points.size();
153 
154 }
155 
156 //*****************************************************************************
157 
158 //:::::::::::::::::::::::
159 //:: METHOD dataPoints ::
160 //:::::::::::::::::::::::
161 
162 const std::vector<DataPoint> & DataBin::dataPoints() const {
163 
164  return m_points;
165 
166 }
167 
168 //*****************************************************************************
169 
170 //:::::::::::::::::::::
171 //:: METHOD splitBin ::
172 //:::::::::::::::::::::
173 
174 DataBin * DataBin::splitBin(const unsigned int & ref_coord) {
175 
177 // CHECK WHETHER THE REFERENCE COORDINATE IS IN THE ALLOWED RANGE //
179 
180  if (ref_coord>=static_cast<unsigned int >(m_bin_centre.rows())) {
181  throw std::runtime_error(Form("File: %s, Line: %d\nDataBin::splitBin - Reference coordinate out of range!", __FILE__, __LINE__));
182  }
183 
185 // CHECK WHETHER THERE ARE AT LEAST 4 DATA POINTS //
187 
188  if (m_points.size()<4) {
189  throw std::runtime_error(Form("File: %s, Line: %d\nDataBin::splitBin - Less than 4 points in the bin!", __FILE__, __LINE__));
190  }
191 
193 // SORT THE DATA POINTS ALONG THE SELECTED COORDINATE AXIS //
195 
196  for (unsigned int k=0; k<m_points.size(); k++) {
197  m_points[k].setReferenceComponent(ref_coord);
198  }
199 
200  sort(m_points.begin(), m_points.end());
201 
203 // MAKE TWO NEW BINS //
205 
206 // event dividing the splitting position //
207  unsigned int k_split((m_points.size()/2)+m_points.size()%2);
208 
209 // bin 1 data //
210  Amg::VectorX bin_1_low = m_lower_boundaries;
211  Amg::VectorX bin_1_up = m_upper_boundaries;
212  bin_1_up[ref_coord] = (m_points[k_split]).dataVector()[ref_coord];
213  std::vector<DataPoint> bin_1_points(k_split);
214  for (unsigned k=0; k<k_split; k++) {
215  bin_1_points[k] = m_points[k];
216  }
217 
218 // bin 2 data //
219  Amg::VectorX bin_2_low = m_lower_boundaries;
220  bin_2_low[ref_coord] = (m_points[k_split]).dataVector()[ref_coord];
221  Amg::VectorX bin_2_up = m_upper_boundaries;
222  std::vector<DataPoint> bin_2_points(m_points.size()-k_split);
223  for (unsigned int k=k_split; k<m_points.size(); k++) {
224  bin_2_points[k-k_split] = m_points[k];
225  }
226 
227 // create the second bin //
228  DataBin *bin_2 = new DataBin(bin_2_low, bin_2_up);
229  bin_2->setPoints(bin_2_points);
230 
231 // resize the current bin //
232  m_lower_boundaries = bin_1_low;
233  m_upper_boundaries = bin_2_up;
234  setPoints(bin_1_points);
235 
236  return bin_2;
237 
238 }
239 
240 //*****************************************************************************
241 
242 //:::::::::::::::::::::
243 //:: METHOD addPoint ::
244 //:::::::::::::::::::::
245 
246 bool DataBin::addPoint(const DataPoint & point) {
247 
248 // check whether the point can be added //
249  for (int k=0; k<point.dataVector().rows(); k++) {
250  if (point.dataVector()[k]<m_lower_boundaries[k] ||
251  point.dataVector()[k]>=m_upper_boundaries[k]) {
252  return false;
253  }
254  }
255 
256 // add the point //
257  m_points.push_back(point);
258 
259 // recalculate the centre of gravity and the standard deviations //
262  for (int k=0; k<m_centre_of_gravity.rows(); k++) {
263  m_centre_of_gravity[k] = 0.0;
264  m_standard_deviations[k] = 0.0;
265  for (unsigned int l=0; l<m_points.size(); l++) {
267  m_points[l].dataVector()[k];
268  }
270  static_cast<double>(m_points.size());
271  for (unsigned int l=0; l<m_points.size(); l++) {
273  std::pow(m_points[l].dataVector()[k]-m_centre_of_gravity[k], 2);
274  }
275  if (m_points.size()>2) {
277  static_cast<double>(m_points.size()-1);
278  } else {
280  static_cast<double>(m_points.size());
281  }
283  }
284 
285  return true;
286 
287 }
288 
289 //*****************************************************************************
290 
291 //::::::::::::::::::::::::::::::
292 //:: METHOD addPointAndResize ::
293 //::::::::::::::::::::::::::::::
294 
295 void DataBin::addPointAndResize(const DataPoint & point, const double epsilon) {
296 
297 // add the point //
298  m_points.push_back(point);
299 
300 // recalculate the centre of gravity and the standard deviations //
303  for (int k=0; k<m_centre_of_gravity.rows(); k++) {
304  m_centre_of_gravity[k] = 0.0;
305  m_standard_deviations[k] = 0.0;
306  for (unsigned int l=0; l<m_points.size(); l++) {
308  m_points[l].dataVector()[k];
309  }
311  static_cast<double>(m_points.size());
312  for (unsigned int l=0; l<m_points.size(); l++) {
314  std::pow(m_points[l].dataVector()[k]-m_centre_of_gravity[k], 2);
315  }
316  if (m_points.size()>2) {
318  static_cast<double>(m_points.size()-1);
319  } else {
321  static_cast<double>(m_points.size());
322  }
324  }
325 
326 // determine the bin boundaries //
327  if (m_points.size()==1) {
328  m_lower_boundaries = point.dataVector();
329  m_upper_boundaries = point.dataVector();
330  for (int k=0; k<m_lower_boundaries.rows(); k++) {
331  m_lower_boundaries[k]=point.dataVector()[k];
332  m_upper_boundaries[k]=point.dataVector()[k]+epsilon;
333  }
334  } else {
335  for (int k=0; k<m_lower_boundaries.rows(); k++) {
336  if (m_lower_boundaries[k]<point.dataVector()[k]) {
337  m_lower_boundaries[k]=point.dataVector()[k];
338  }
339  if (m_upper_boundaries[k]>=point.dataVector()[k]) {
340  m_upper_boundaries[k]=point.dataVector()[k]+epsilon;
341  }
342  }
343  }
344 
345 // calculate bin centre //
347 
348  return;
349 
350 }
351 
352 //*****************************************************************************
353 
354 //::::::::::::::::::::::
355 //:: METHOD setPoints ::
356 //::::::::::::::::::::::
357 
358 void DataBin::setPoints(const std::vector<DataPoint> & points) {
359 
360  m_points = points;
361 
362  if (m_points.empty()) {
363  return;
364  }
365 
366 // recalculate the centre of gravity and the standard deviations //
367  m_centre_of_gravity = m_points[0].dataVector();
368  m_standard_deviations = m_points[0].dataVector();
369  for (int k=0; k<m_centre_of_gravity.rows(); k++) {
370  m_centre_of_gravity[k] = 0.0;
371  m_standard_deviations[k] = 0.0;
372  for (unsigned int l=0; l<m_points.size(); l++) {
374  m_points[l].dataVector()[k];
375  }
377  static_cast<double>(m_points.size());
378  for (unsigned int l=0; l<m_points.size(); l++) {
380  std::pow(m_points[l].dataVector()[k]-m_centre_of_gravity[k], 2);
381  }
382  if (m_points.size()>2) {
384  static_cast<double>(m_points.size()-1);
385  } else {
387  static_cast<double>(m_points.size());
388  }
390  }
391 
392  return;
393 
394 }
MuonCalib::DataBin::m_bin_centre
Amg::VectorX m_bin_centre
Definition: DataBin.h:108
MuonCalib::DataBin::numberOfDataPoints
unsigned int numberOfDataPoints() const
get the number of data points
Definition: DataBin.cxx:150
Amg::VectorX
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
Definition: EventPrimitives.h:30
MuonCalib::DataBin::m_upper_boundaries
Amg::VectorX m_upper_boundaries
Definition: DataBin.h:110
MuonCalib::DataBin::density
double density() const
get the data point density in the bin
Definition: DataBin.cxx:74
MuonCalib::DataBin::m_centre_of_gravity
Amg::VectorX m_centre_of_gravity
Definition: DataBin.h:111
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
MuonCalib::DataBin::dataPoints
const std::vector< DataPoint > & dataPoints() const
get the data points filling this bin
Definition: DataBin.cxx:162
MuonCalib::DataBin::upperbinBoundaries
const Amg::VectorX & upperbinBoundaries() const
get the upper boundaries of the bin
Definition: DataBin.cxx:114
MuonCalib::DataBin::standardDeviations
const Amg::VectorX & standardDeviations() const
get the standard deviations of the data points from the centre of gravity in all dimensions
Definition: DataBin.cxx:138
MuonCalib::DataBin::splitBin
DataBin * splitBin(const unsigned int &ref_coord)
divide the bin into two of equal content; splitting is done along the coordinate ref_coord; the metho...
Definition: DataBin.cxx:174
MuonCalib::DataBin::lowerBinBoundaries
const Amg::VectorX & lowerBinBoundaries() const
get the lower boundaries of the bin
Definition: DataBin.cxx:102
MuonCalib::DataBin::centreOfBin
const Amg::VectorX & centreOfBin() const
get the centre of the bin
Definition: DataBin.cxx:90
MuonCalib::DataBin::centreOfGravity
const Amg::VectorX & centreOfGravity() const
get the centre of gravity of the data points
Definition: DataBin.cxx:126
MuonCalib::DataBin::addPointAndResize
void addPointAndResize(const DataPoint &point, const double epsilon)
add the data point to the bin; the bin will be resized if the point does not fit into the bin; the up...
Definition: DataBin.cxx:295
MuonCalib::DataBin::DataBin
DataBin()
Default constructor. Give a bin with 0 content and no extensions.
Definition: DataBin.cxx:23
MuonCalib::DataPoint::dataVector
const Amg::VectorX & dataVector() const
get the data vector
Definition: DataPoint.cxx:75
MuonCalib::DataPoint
Definition: DataPoint.h:32
MuonCalib
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.
Definition: CscCalcPed.cxx:22
beamspotnt.rows
list rows
Definition: bin/beamspotnt.py:1112
MuonCalib::DataBin::addPoint
bool addPoint(const DataPoint &point)
add the data point to the bin if possible; returns true if the point can be added,...
Definition: DataBin.cxx:246
MuonCalib::DataBin
Definition: DataBin.h:37
MuonCalib::DataBin::setPoints
void setPoints(const std::vector< DataPoint > &points)
fill the bin with the given points; the use of this method is highly discouraged, it is needed for th...
Definition: DataBin.cxx:358
MuonCalib::DataBin::m_standard_deviations
Amg::VectorX m_standard_deviations
Definition: DataBin.h:113
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15
MuonCalib::DataBin::m_points
std::vector< DataPoint > m_points
Definition: DataBin.h:107
jobOptions.points
points
Definition: jobOptions.GenevaPy8_Zmumu.py:97
DataBin.h
MuonCalib::DataBin::m_lower_boundaries
Amg::VectorX m_lower_boundaries
Definition: DataBin.h:109
fitman.k
k
Definition: fitman.py:528