FairRoot/PandaRoot
PndLmdAlignStructs.h
Go to the documentation of this file.
1 /*
2  * PndLmdAlignStructs.h
3  *
4  * Header-only file to collect all structs used during SensorAlignment
5  *
6  * Created on: Jul 20, 2017
7  * Author: Roman Klasen, roklasen@uni-mainz.de or klasen@kph.uni-mainz.de
8  */
9 
10 #ifndef LMD_LMDSENSORALIGNMENT_PNDLMDALIGNSTRUCTS_H_
11 #define LMD_LMDSENSORALIGNMENT_PNDLMDALIGNSTRUCTS_H_
12 
13 #include "PndLmdHitPair.h"
14 
15 #include <TH1D.h>
16 #include <TCanvas.h>
17 
18 #include <cmath>
19 #include <iostream>
20 #include <string>
21 #include <vector>
22 
23 using std::max;
24 using std::min;
25 using std::cout;
26 using std::vector;
27 
28 //calculates dynamic cut parameters for each overlapping area
31  bool _ready;
32 
33  std::vector<double> samples;
34 
36 
38  _overlapID = 0;
39  _minDist = _maxDist = 0.0;
40  _hardMax = 32 * 80e-4; //sensors should not be farther than 32 pixels, 2,5mm!
41  _ready = false;
42  _mean = 0;
43  _RMS = 0;
44  }
45 
47 
48  //set first sample data
49  if (samples.size() == 0) {
50  _overlapID = pair.getOverlapId();
51  _minDist = pair.getDistance();
52  }
53  else {
54  if (_overlapID != pair.getOverlapId()) {
55  cout << "something is wrong! stored OverlapID does not match added ID!\n";
56  return;
57  }
58  }
59 
60  //100 should suffice, but more is always better
61  if (samples.size() > 150) {
62  _ready = true;
63  }
64 
65  double thisDistance = pair.getDistance();
66 
67  _minDist = std::min(_minDist, thisDistance);
68  _maxDist = std::max(_maxDist, std::min(thisDistance, _hardMax)); //never choose maximum higher than hardMax
69 
70  // store distance only if in valid range, some distances are too large
71  if (thisDistance >= _minDist && thisDistance <= _maxDist) {
72  samples.push_back(pair.getDistance());
73  }
74 
75  return;
76  }
77 
78  void calcMinAndMax() {
79 
80  // choose 80 percent confidence interval:
81  std::sort(samples.begin(), samples.end());
82  int quantileMargin = samples.size() / 10; // shave 10% from front and back
83 
84  vector<double>::const_iterator first = samples.begin() + quantileMargin;
85  vector<double>::const_iterator last = samples.end() - quantileMargin;
86  vector<double> confidenceInterval(first, last);
87 
88  _minDist = confidenceInterval[0];
89  _maxDist = confidenceInterval[confidenceInterval.size() - 1];
90 
91  // leave a little safety margin:
92  double spread = _maxDist - _minDist;
93  _minDist = std::max(0.0, confidenceInterval[0] - spread); //should not underflow 0
94  _maxDist = std::min(_hardMax, confidenceInterval[confidenceInterval.size() - 1] + spread); //should not overflow _hardMax
95 
96  return;
97 
98  }
99 
100  bool ready() {
101  return _ready;
102  }
103 
104  double getMinDist() {
105  return _minDist;
106  }
107  double getMaxDist() {
108  return _maxDist;
109  }
110 };
111 
112 //simple pixel hit, maybe not even necessary
113 struct pixelHit {
115  double _col;
116  double _row;
117 
118  double x() const {
119  return _col;
120  }
121 
122  pixelHit(int idVal, double colVal, double rowVal) {
123  _sensorId = idVal;
124  _col = colVal;
125  _row = rowVal;
126  }
127 
129  _col = -1;
130  _row = -1;
131  _sensorId = -1;
132  }
133 };
134 
135 /*
136  * contains multiple pixelHits that form a cluster. most routines are for checking,
137  * if two separate pixelHits belong to the same cluster
138  */
139 struct pixelCluster {
141  double centerCol, centerRow; //,centerZ;
142  double clusterSize;
143  vector<pixelHit> pixelHits;
145 
147  _sensorId = -1;
148  centerCol = -1;
149  centerRow = -1; //centerZ=-1;
150  clusterSize = -1;
151  clusterReady = false;
152  }
153 
155  _sensorId = hit._sensorId;
156  pixelHits.push_back(hit);
157 
158  centerCol = -1;
159  centerRow = -1; //centerZ=-1;
160  clusterSize = -1;
161  clusterReady = false;
162  }
163 
164  pixelCluster(const pixelCluster &copy) {
165  _sensorId = copy._sensorId;
166  for (size_t i = 0; i < copy.pixelHits.size(); i++) {
167  pixelHits.push_back(copy.pixelHits[i]);
168  }
169 
170  centerCol = -1;
171  centerRow = -1; //centerZ=-1;
172  clusterSize = -1;
173  clusterReady = false;
174  }
175 
176  //checks, if two clusters lie DIRECTLY next to each other, that means any two pixels
177  //must be directly next to each other
178  //TODO: inefficient code, may be improved
179  bool isNeighbour(pixelCluster &other) {
180  //first, they must be on same sensor
181  if (_sensorId != other._sensorId) {
182  return false;
183  }
184  double _col1, _col2, _row1, _row2;
185  for (size_t i = 0; i < this->pixelHits.size(); i++) {
186  _col1 = this->pixelHits[i]._col;
187  _row1 = this->pixelHits[i]._row;
188  for (size_t j = 0; j < other.pixelHits.size(); j++) {
189  _col2 = other.pixelHits[j]._col;
190  _row2 = other.pixelHits[j]._row;
191  //check if neighboring, that means distance of pixels is smaller than 1.5 pixels
192  if ((_col2 - _col1) * (_col2 - _col1) + (_row2 - _row1) * (_row2 - _row1) < 2.25) {
193  return true;
194  }
195  }
196  }
197  return false;
198  }
199 
200  //merges other to this one
201  void merge(pixelCluster &other) {
202  for (size_t i = 0; i < other.pixelHits.size(); i++) {
203  pixelHits.push_back(other.pixelHits[i]);
204  }
205  }
206 
208  centerCol = 0;
209  centerRow = 0;
210  for (size_t i = 0; i < pixelHits.size(); i++) {
211  centerCol += pixelHits[i]._col;
212  centerRow += pixelHits[i]._row;
213  }
214  centerCol /= pixelHits.size();
215  centerRow /= pixelHits.size();
216  double tempDistance;
217  //calculate size, go from corner to corner for clusters larger than 2 pixels
218  if (pixelHits.size() == 1) {
219  clusterSize = 1;
220  }
221  else {
222  for (size_t i = 0; i < pixelHits.size(); i++) {
223  for (size_t j = i + 1; j < pixelHits.size(); j++) {
224  double deltax = (pixelHits[i]._col - pixelHits[j]._col);
225  if (deltax > 0) {
226  deltax = deltax + 1;
227  }
228  if (deltax < 0) {
229  deltax = deltax - 1;
230  }
231  double deltay = (pixelHits[i]._row - pixelHits[j]._row);
232  if (deltay > 0) {
233  deltay = deltay + 1;
234  }
235  if (deltay < 0) {
236  deltay = deltay - 1;
237  }
238  tempDistance = sqrt(deltax * deltax + deltay * deltay);
239  clusterSize = max(clusterSize, tempDistance);
240  }
241  }
242  }
243  clusterReady = true;
244  }
245 
246  void printPixels() {
247  for (size_t i = 0; i < pixelHits.size(); i++) {
248  cout << "pixelHit x:" << pixelHits[i]._col << ", y:" << pixelHits[i]._row << " on sensor "
249  << pixelHits[i]._sensorId << "\n";
250  }
251  }
252  void printCenter() {
253  cout << "clusterCenter x:" << centerCol << ", y:" << centerRow << " on sensor " << _sensorId
254  << ", contains " << pixelHits.size() << " pixels and is " << clusterSize
255  << " pixels in diameter." << "\n";
256  }
257 };
258 
259 #endif /* LMD_LMDSENSORALIGNMENT_PNDLMDALIGNSTRUCTS_H_ */
pixelHit(int idVal, double colVal, double rowVal)
Int_t i
Definition: run_full.C:25
friend F32vec4 sqrt(const F32vec4 &a)
Definition: P4_F32vec4.h:29
friend F32vec4 max(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:26
pixelCluster(const pixelHit &hit)
Int_t getOverlapId() const
Double_t getDistance() const
friend F32vec4 min(const F32vec4 &a, const F32vec4 &b)
Definition: P4_F32vec4.h:25
void addToSamples(PndLmdHitPair pair)
bool isNeighbour(pixelCluster &other)
double x() const
std::vector< double > samples
vector< pixelHit > pixelHits
PndSdsMCPoint * hit
Definition: anasim.C:70
void merge(pixelCluster &other)
pixelCluster(const pixelCluster &copy)