ATLAS Offline Software
Loading...
Searching...
No Matches
DataBin.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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
11using namespace MuonCalib;
12
13//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
14//:: IMPLEMENTATION OF METHODS DEFINED IN THE CLASS DataBin ::
15//::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
16
17//*****************************************************************************
18
19//:::::::::::::::::
20//:: CONSTRUCTOR ::
21//:::::::::::::::::
22
25
26//*****************************************************************************
27
28//:::::::::::::::::
29//:: CONSTRUCTOR ::
30//:::::::::::::::::
31
32DataBin::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
46DataBin::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
74double 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
141
142}
143
144//*****************************************************************************
145
146//:::::::::::::::::::::::::::::::
147//:: METHOD numberOfDataPoints ::
148//:::::::::::::::::::::::::::::::
149
150unsigned int DataBin::numberOfDataPoints() const {
151
152 return m_points.size();
153
154}
155
156//*****************************************************************************
157
158//:::::::::::::::::::::::
159//:: METHOD dataPoints ::
160//:::::::::::::::::::::::
161
162const std::vector<DataPoint> & DataBin::dataPoints() const {
163
164 return m_points;
165
166}
167
168//*****************************************************************************
169
170//:::::::::::::::::::::
171//:: METHOD splitBin ::
172//:::::::::::::::::::::
173
174DataBin * 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 //
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 //
220 bin_2_low[ref_coord] = (m_points[k_split]).dataVector()[ref_coord];
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 = std::move(bin_1_low);
233 m_upper_boundaries = std::move(bin_2_up);
234 setPoints(bin_1_points);
235
236 return bin_2;
237
238}
239
240//*****************************************************************************
241
242//:::::::::::::::::::::
243//:: METHOD addPoint ::
244//:::::::::::::::::::::
245
246bool 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
295void 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) {
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
358void 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}
void sort(typename DataModel_detail::iterator< DVL > beg, typename DataModel_detail::iterator< DVL > end)
Specialization of sort for DataVector/List.
const Amg::VectorX & centreOfBin() const
get the centre of the bin
Definition DataBin.cxx:90
Amg::VectorX m_centre_of_gravity
Definition DataBin.h:111
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
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
Amg::VectorX m_lower_boundaries
Definition DataBin.h:109
std::vector< DataPoint > m_points
Definition DataBin.h:107
const Amg::VectorX & lowerBinBoundaries() const
get the lower boundaries of the bin
Definition DataBin.cxx:102
const std::vector< DataPoint > & dataPoints() const
get the data points filling this bin
Definition DataBin.cxx:162
Amg::VectorX m_upper_boundaries
Definition DataBin.h:110
Amg::VectorX m_standard_deviations
Definition DataBin.h:113
const Amg::VectorX & centreOfGravity() const
get the centre of gravity of the data points
Definition DataBin.cxx:126
DataBin()
Default constructor. Give a bin with 0 content and no extensions.
Definition DataBin.cxx:23
double density() const
get the data point density in the bin
Definition DataBin.cxx:74
const Amg::VectorX & upperbinBoundaries() const
get the upper boundaries of the bin
Definition DataBin.cxx:114
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
Amg::VectorX m_bin_centre
Definition DataBin.h:108
unsigned int numberOfDataPoints() const
get the number of data points
Definition DataBin.cxx:150
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
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
const Amg::VectorX & dataVector() const
get the data vector
Definition DataPoint.cxx:75
Eigen::Matrix< double, Eigen::Dynamic, 1 > VectorX
Dynamic Vector - dynamic allocation.
CscCalcPed - algorithm that finds the Cathode Strip Chamber pedestals from an RDO.