MyMarlinTPC  170316
RowBasedFastHoughTransformationProcessor.cc
Go to the documentation of this file.
1 // #ifdef USE_ROWFHT
3 
5 
6 #include <iostream>
7 #include <string>
8 #include <ctime>
9 #include <cmath>
10 
11 //GEAR
12 #include <gear/TPCParameters.h>
13 #include <gear/BField.h>
14 #include <gearimpl/Vector3D.h>
15 
16 // include what you need from lcio
17 #include <EVENT/LCEvent.h>
18 #include <IMPL/LCCollectionVec.h>
19 #include <UTIL/BitField64.h>
20 #include <UTIL/ILDConf.h>
21 #include <IMPL/TrackerHitImpl.h>
22 #include <IMPL/TrackImpl.h>
23 #include <IMPL/LCFlagImpl.h>
24 #include <Exceptions.h>
25 
26 // this is the inserted part
27 
28 using namespace lcio;
29 using namespace marlin;
30 using namespace std;
31 using namespace gear;
32 
33 namespace marlintpc {
34 
35 static bool compare(pair<unsigned int, float> one, pair<unsigned int, float> two) {
36  return ((one.second) > (two.second));
37 }
38 
40 
42 RowBasedFastHoughTransformationProcessor::RowBasedFastHoughTransformationProcessor() :
43  Processor("RowBasedFastHoughTransformationProcessor") {
44  // the processor description
45  _description = "RowBasedFastHoughTransformationProcessor is intended to ...";
46 
47  registerInputCollection(LCIO::TRACKERHIT, "InputHits", "Name of the input Hit Collection", _inputColName, string("TPCHits"));
48  registerOutputCollection(LCIO::TRACK, "OutputTracks", "Name of the output Track Collection", _outputColName, string("FHTTracks"));
49 
50  registerOptionalParameter("BFieldScaleFactor", "Scales magnetic field (map), use 1.0 (default) for field ON or 0.0 for field OFF",
51  _bfieldScaleFactor, double(1.0));
52 
53  registerProcessorParameter("CenterXYMeasurement", "Center of XY (anode plane) measurement", _centerXY, double(60.));
54 
55  registerProcessorParameter("RangeXYMeasurement", "Range of XY (anode plane) measurement", _rangeXY, double(200.));
56 
57  registerProcessorParameter("CenterXZMeasurement", "Center of XZ (drift time) measurement", _centerXZ, double(300.));
58 
59  registerProcessorParameter("RangeXZMeasurement", "Range of XZ (drift time) measurement", _rangeXZ, double(600.));
60 
61  registerOptionalParameter("UseXYMeasurement", "Use XY (anode plane) measurement", _useXY, bool(true));
62 
63  registerOptionalParameter("UseXZMeasurement", "Use XZ (drift time) measurement", _useXZ, bool(true));
64 
65  registerOptionalParameter("MinimumRows", "Minimal number of (correlated) rows ", _minRow, int(8));
66 
67  registerOptionalParameter("MaximumRowDifference", "Row correation parameter ", _maxRowDiff, int(1));
68 
69  registerOptionalParameter("FractionOfRows", "Relative minimum cube content (rows >= fraction * (correlated) rows) ", _fracRow,
70  float(0.8));
71 
72  registerOptionalParameter("MaximumCubes", "Maximum number of (hyper) cubes to check ", _maxCube, int(250));
73 
74  registerOptionalParameter("MinimumLevel", "Minimum number of (hyper) cubes splittings ", _minLevel, int(5));
75 
76  registerOptionalParameter("MaximumLevel", "Maximum number of (hyper) cubes splittings ", _maxLevel, int(8));
77 
78  registerOptionalParameter("EfficienyCut", "Minimum hit density (hits/tracklength) ", _effCut, float(0.8));
79 
80  registerOptionalParameter("PurityCut", "Maximum hit density (hits/tracklength) ", _purCut, float(1.1));
81 
82  registerOptionalParameter("MaxHitsPerRow", "Maximum number of hits per row ", _maxHitsPerRow, int(1));
83 
84  registerOptionalParameter("UnusedHitMatchingChi2Cut", "Chi2 cut for matching unused hits in XY and Z", _unusedCut, double(20.0));
85 
86  registerOptionalParameter("UnusedHitMaxGapCut", "Maximal (row) gap for matching unused hits in XY and Z", _maxGap, int(4));
87 
88  registerOptionalParameter("EncodedModuleID", "Module ID encoded in CellID0", _encodedModuleID, bool(true));
89 
90  registerOptionalParameter("ReferencePointAtPca", "Use PCA as reference point, else 1. hit", _refAtPCA, bool(false));
91 
92  registerOptionalParameter("TimePixFlag", "Is timepix data", _timePixFlag, bool(false));
93 
94 }
95 
98  m_out(DEBUG) << " init() called " << endl;
99 
100 }
101 
103  // do something for each run
104 }
105 
108  std::clock_t start1 = std::clock();
109 
110  m_out(DEBUG) << "Event Number: " << evt->getEventNumber() << endl;
111 
112  //get input collection
113  LCCollection* inputCol = 0;
114 
115  LCCollectionVec* outputCol = new LCCollectionVec(LCIO::TRACK);
116  LCFlagImpl trkFlag(0);
117  trkFlag.setBit(LCIO::TRBIT_HITS);
118  outputCol->setFlag(trkFlag.getFlag());
119 
120  // do a try / catch in case there is an empty event
121  try {
122  inputCol = evt->getCollection(_inputColName);
123  } catch (DataNotAvailableException &e) {
124  // no input data, just return and process the next event
125  return;
126  }
127 
128  Vector3D theTPCCenter(_Xcenter, _Ycenter, 0.);
129  Vector3D bfield = marlin::Global::GEAR->getBField().at(theTPCCenter);
130 
131  const bool bOff(bfield.z() * _bfieldScaleFactor == 0.);
132  if (bOff) {
133  m_out(DEBUG) << "BField(GEAR) is OFF" << std::endl;
134  } else {
135  m_out(DEBUG) << "BField(GEAR) is ON" << std::endl;
136  }
137  // constant magnetic field (in z direction)
138  _Bzc = bfield.z() * _bfieldScaleFactor * 0.0002998; // Bz*c
139 
140  // setup (number of parameters per measurement direction)
141  unsigned int setup[] = { 3, 2 };
142  if (bOff) setup[0] = 2;
143  if (!_useXY) setup[0] = 0;
144  if (!_useXZ) setup[1] = 0;
145  if (setup[0] + setup[1] == 0) {
146  m_out(ERROR) << " No active parameters ";
147  return;
148  }
149  unsigned int dimension = (_useXY and _useXZ) ? 2 : 1; // dimension of measurements
150  _scaleBits = _maxLevel + (_maxLevel % 2) + 8; // even number
151 
153  rowHitMapType hitData;
154 
155  UTIL::BitField64 encoder(lcio::ILDCellID0::encoder_string);
156  int nInput = inputCol->getNumberOfElements();
157  m_out(DEBUG) << "Event " << evt->getEventNumber() << " in run " << evt->getRunNumber() << ", number of input hits: " << nInput
158  << endl;
159 
160  if (_timePixFlag) {
161  for (int iInput = 0; iInput < nInput; iInput++) {
162  TrackerHit* Hit = dynamic_cast<TrackerHit*>(inputCol->getElementAt(iInput));
163  encoder.setValue(Hit->getCellID0());
164  int mod = Hit->getCellID1();
165  int rowLoc = Hit->getCellID0() % 256 + mod * 256;
166  int row = (rowLoc > 1023) ? rowLoc - 1024 : 1023 - rowLoc; // simple row count in x direction
167  rb_Hit* someHit = new rb_Hit(iInput, mod, row, *Hit);
168  hitData[row].push_back(someHit);
169  }
170  } else {
171  for (int iInput = 0; iInput < nInput; iInput++) {
172  TrackerHit* Hit = dynamic_cast<TrackerHit*>(inputCol->getElementAt(iInput));
173  encoder.setValue(Hit->getCellID0());
174  int mod =
176  encoder[ILDCellID0::module] :
177  Global::GEAR->getTPCParameters().getNearestModule(Hit->getPosition()[0], Hit->getPosition()[1]).getModuleID();
178  int row = encoder[ILDCellID0::layer];
179  rb_Hit* someHit = new rb_Hit(iInput, mod, row, *Hit);
180  hitData[row].push_back(someHit);
181  }
182  }
183 
184  // list of track candidates (segments)
185  segListType trackCandidates;
186  double scale = double(1 << _scaleBits);
187 
189  bool more = true;
190  while (more) {
192  int numRows = 0;
193  int numRows2 = 0;
194  int lastRow = -1;
195  double xMin = 0., xMax = 0.;
196  for (rowHitMapType::iterator itRow = hitData.begin(); itRow != hitData.end(); ++itRow) {
197  const int row = itRow->first;
198  //std::cout << " row " << row << std::endl;
199  for (hitListType::iterator itHit = itRow->second.begin(); itHit != itRow->second.end(); ++itHit) {
200  if (!(*itHit)->getUsed()) {
201  double x = (*itHit)->getX();
202  if (numRows == 0) {
203  xMax = xMin = x;
204  numRows++;
205  numRows2++;
206  } else {
207  xMax = max(xMax, x);
208  xMin = min(xMin, x);
209  if (row > lastRow) {
210  numRows++;
211  if (row <= lastRow + _maxRowDiff) numRows2++;
212  }
213  }
214  lastRow = row;
215  }
216  }
217  }
218  m_out(DEBUG) << " ... rows " << numRows << " " << numRows2 << endl;
219  if (numRows2 < _minRow) break;
221  const double xCenter = 0.5 * (xMin + xMax);
222  const double xRange = 0.5 * (xMax - xMin);
223  intListType rootDistances;
224  rootDistances.reserve(nInput * dimension);
225  hyperPlaneListType rootPlanes;
226  rootPlanes.reserve(nInput);
227  //
228 
229  for (rowHitMapType::iterator itRow = hitData.begin(); itRow != hitData.end(); ++itRow) {
230  //int row = itRow->first;
231  //std::cout << " row " << row << std::endl;
232  for (hitListType::iterator itHit = itRow->second.begin(); itHit != itRow->second.end(); ++itHit) {
233  if (!(*itHit)->getUsed()) {
234  const double u = ((*itHit)->getX() - xCenter) / xRange;
235  const double v[] = { ((*itHit)->getY() - _centerXY) / _rangeXY, ((*itHit)->getZ() - _centerXZ) / _rangeXZ };
236  // calculate unit normals
237  directionsType dirs;
238  bool inside = true;
239  int dist[2];
240  unsigned int ndim = 0;
241  for (unsigned int idim = 0; idim < 2; idim++) {
242  if (setup[idim] > 0) {
243  doubleListType vec(setup[idim]);
244  vec[0] = 1.;
245  vec[1] = u;
246  if (setup[idim] > 2) vec[2] = 1.5 * u * u - 0.5;
247  double sum2 = 0.;
248  for (doubleListType::iterator i = vec.begin(); i != vec.end(); ++i)
249  sum2 += (*i) * (*i);
250  const double norm = sqrt(sum2);
251  for (doubleListType::iterator i = vec.begin(); i != vec.end(); ++i)
252  *i /= norm;
253  dirs.push_back(vec);
254  double r = -v[idim] / norm;
255  inside = inside and (abs(r * vec[0]) < 0.5);
256  dist[ndim++] = int(scale * r);
257  }
258  }
259  if (inside) {
260  rb_HyperPlane* hp = new rb_HyperPlane(_scaleBits, *itHit, dirs);
261  for (unsigned int idim = 0; idim < ndim; idim++)
262  rootDistances.push_back(dist[idim]);
263  rootPlanes.push_back(hp);
264  }
265  }
266  }
267  }
268  m_out(DEBUG) << "rootPlanes " << rootPlanes.size() << endl;
269  if (rootPlanes.size() < static_cast<unsigned int>(_minRow)) break;
270 
272  rb_HyperCube root(setup, rootPlanes, rootDistances);
273  int minCubeRows = int(float(numRows2) * _fracRow);
274  m_out(DEBUG) << "minCubeRows " << minCubeRows << endl;
275  hitListType candidate = root.divide(_maxCube, minCubeRows, _minLevel, _maxLevel, _effCut, _purCut);
276  //root.print();
277  m_out(DEBUG) << "Candidate " << candidate.size() << endl;
278  more = false;
279  if (candidate.size() > 0) {
280  unsigned int maxHitsPerRow = _maxHitsPerRow;
282  rb_Segment* aSegment = new rb_Segment(_Bzc, candidate, maxHitsPerRow);
283  if (aSegment->getNdf() < 0)
284  delete aSegment;
285  else {
286  if (_unusedCut > 0.) {
287  // link unused hits
288  map<int, int> rowMap;
289  aSegment->fillRowMap(rowMap);
290  int centerRow = (aSegment->getFirstRow() + aSegment->getLastRow()) / 2;
291  // look forward
292  for (int row = centerRow + 1; row <= hitData.rbegin()->first; ++row) {
293  if (row > aSegment->getLastRow() + _maxGap) break; // too far away
294  if (rowMap.count(row) > 0) continue; // row already contained in segment
295  hitListType hits;
296  aSegment->match(hitData[row], hits, _unusedCut); // match list of hits
297  if (hits.size() <= maxHitsPerRow) for (hitListType::iterator itHit = hits.begin(); itHit != hits.end(); ++itHit)
298  aSegment->addHit(*itHit); // additional hit(s)?
299  }
300  // look backward
301  for (int row = centerRow; row >= hitData.begin()->first; --row) {
302  if (row < aSegment->getFirstRow() - _maxGap) break; // too far away
303  if (rowMap.count(row) > 0) continue; // row already contained in segment
304  hitListType hits;
305  aSegment->match(hitData[row], hits, _unusedCut); // match list of hits
306  if (hits.size() <= maxHitsPerRow) for (hitListType::iterator itHit = hits.begin(); itHit != hits.end(); ++itHit)
307  aSegment->addHit(*itHit); // additional hit(s)?
308  }
309  }
310  trackCandidates.push_back(aSegment); // keep valid segments
311  m_out(DEBUG) << "Segment " << trackCandidates.size() << " " << aSegment->getHitList().size() << endl;
312  more = true;
313  }
314  }
315  // cleanup
316  for (hyperPlaneListType::iterator itHp = rootPlanes.begin(); itHp != rootPlanes.end(); ++itHp)
317  delete *itHp;
318  rootPlanes.clear();
319  rootDistances.clear();
320  }
321 
322  m_out(DEBUG) << " found " << trackCandidates.size() << " track candidates " << endl;
323 
325  for (segListType::iterator itSeg = trackCandidates.begin(); itSeg != trackCandidates.end(); ++itSeg) {
326  // new track
327  TrackImpl* theTrack = new TrackImpl();
328  // get hits
329  hitListType hits = (*itSeg)->getHitList();
330  // position of 1. hit
331  double posFirst[3];
332  hits.front()->getPos(posFirst);
333  // reference point, 1. hit or PCA (point of closest approach (to origin))
334  double refPos[] = { 0., 0., 0. };
335  if (!_refAtPCA) {
336  refPos[0] = posFirst[0];
337  refPos[1] = posFirst[1];
338  refPos[2] = posFirst[2];
339  }
340  float refPoint[3];
341  for (int i = 0; i < 3; ++i)
342  refPoint[i] = refPos[i];
343  // track parameters and covariance matrix
344  TVectorD parameters(5);
345  TMatrixDSym covariance(5);
346  (*itSeg)->getLCIOStateAtRefPoint(refPos, parameters, covariance); // ( d0, phi0, Omega, z0, tanLambda)
347 
348  theTrack->setOmega(parameters[2]);
349  theTrack->setTanLambda(parameters[4]);
350  theTrack->setPhi(parameters[1]);
351  theTrack->setD0(parameters[0]);
352  theTrack->setZ0(parameters[3]);
353  theTrack->setChi2((*itSeg)->getChi2());
354  theTrack->setNdf((*itSeg)->getNdf());
355  theTrack->setReferencePoint(refPoint);
356  /* prepare LCIO output; unknown parts:
357  *
358  * theTrack->setTypeBit (int index, bool val=true) // ?
359  * theTrack->setdEdx (float dEdx)
360  * theTrack->setdEdxError (float dEdxError) */
361  float rInner = sqrt(pow(posFirst[0], 2) + pow(posFirst[1], 2));
362  theTrack->setRadiusOfInnermostHit(rInner);
363  // compressed covariance matrix
364  float compressedCovariance[15];
365  int ind = 0;
366  for (int i = 0; i < 5; ++i)
367  for (int j = 0; j <= i; ++j)
368  compressedCovariance[ind++] = covariance[i][j];
369  theTrack->setCovMatrix(compressedCovariance);
370  // and finally add the hits to the track
371  for (hitListType::iterator itH = hits.begin(); itH != hits.end(); ++itH) {
372  TrackerHit* Hit = dynamic_cast<TrackerHit*>(inputCol->getElementAt((*itH)->getHitNum()));
373  theTrack->addHit(Hit);
374  }
375 
376  m_out(DEBUG) << " +++ the found track has a chi^2 value of " << theTrack->getChi2() << " for ndf = " << theTrack->getNdf()
377  << " and the parameters [omega, tanLambda, phi0, d0, z0] = [" << theTrack->getOmega() << "," << theTrack->getTanLambda()
378  << "," << theTrack->getPhi() << "," << theTrack->getD0() << "," << theTrack->getZ0() << "] at the reference position ["
379  << refPoint[0] << "," << refPoint[1] << "," << refPoint[2] << "]." << endl;
380 
381  outputCol->addElement(theTrack);
382  }
383 
384  m_out(DEBUG) << "RowBasedFastHoughTransformation ... done!" << endl;
385 
386  if (!outputCol->empty()) {
387  evt->addCollection(outputCol, _outputColName);
388  }
389 
390  m_out(DEBUG) << ((std::clock() - start1) / (double) CLOCKS_PER_SEC) << " sec" << endl;
391 
392  // cleanup
393  for (rowHitMapType::iterator itRow = hitData.begin(); itRow != hitData.end(); ++itRow) {
394  for (hitListType::iterator itH = itRow->second.begin(); itH != itRow->second.end(); ++itH) {
395  delete *itH;
396  }
397  }
398  hitData.clear();
399 
400  // get rid of segments
401  for (segListType::iterator itSeg = trackCandidates.begin(); itSeg != trackCandidates.end(); ++itSeg) {
402  delete *itSeg;
403  }
404  trackCandidates.clear();
405 
406 }
407 
409  // check what is needed here
410 }
411 
413  // do something at the end of the processing, e.g. cleaning up
414 
415 }
416 
418 
424 rb_HyperPlane::rb_HyperPlane(int scaleBits, rb_Hit* hit, directionsType& dirList, double distCut) :
425  _scaleBits(scaleBits), _hit(hit), _cut(), _steps() {
426  double scale = double(1 << _scaleBits);
427  for (directionsType::iterator itDir = dirList.begin(); itDir != dirList.end(); ++itDir) {
428  _cut.push_back(int(scale * distCut / (*itDir)[0])); // first is max component
429  const unsigned int nSteps = 1 << itDir->size();
430  intListType aSteps(nSteps);
431  for (unsigned int i = 0; i < nSteps; i++) {
432  unsigned int ii = i;
433  double step = 0.;
434  for (doubleListType::iterator itNum = itDir->begin(); itNum != itDir->end(); ++itNum) {
435  step += (ii % 2 == 1) ? 0.5 * (*itNum) : -0.5 * (*itNum);
436  ii >>= 1;
437  }
438  aSteps[i] = int(scale * step);
439  }
440  _steps.push_back(aSteps);
441  }
442 }
443 
445 void rb_HyperPlane::print() const {
446  cout << " HyperPlane " << _hit->getHitNum() << " " << _hit->getRow() << " " << _cut.size() << " " << _cut.front() << " "
447  << _cut.back() << endl;
448 }
449 
452  return _hit->getRow();
453 }
454 
457  return _scaleBits;
458 }
459 
462  return _hit;
463 }
464 
467  return _cut;
468 }
469 
471 int rb_HyperPlane::getCut(int idim) const {
472  return _cut[idim];
473 }
474 
476 std::vector<intListType> rb_HyperPlane::getSteps() const {
477  return _steps;
478 }
479 
481 int rb_HyperPlane::getStep(int idim, int b) const {
482  return _steps[idim][b];
483 }
484 
486 
492 rb_HyperCube::rb_HyperCube(unsigned int* setup, hyperPlaneListType& planes, intListType& distances, unsigned int level) :
493  _planes(planes), _distances(distances), _level(level) {
494  _setup[0] = setup[0];
495  _setup[1] = setup[1];
496  _numChild = 1 << (setup[0] + setup[1]);
497  _dimension = (setup[0] > 0 and setup[1] > 0) ? 2 : 1;
498  if (level == 0) nCube = 0;
499  nCube++;
500 }
501 
503 void rb_HyperCube::print() const {
504  cout << " HyperCube " << nCube << " " << _level << " " << _numChild << endl;
505 }
506 
508 
518 hitListType rb_HyperCube::divide(int maxCube, int minRows, int minLevel, int maxLevel, float effCut, float purCut) {
519  vector<int> numHits(_numChild, 0);
520  vector<int> numRows(_numChild, 0);
521  vector<int> lastRow(_numChild, -1);
522  vector<int> sum2(_numChild, 0);
523 
524  hitListType hits(0);
525 
526  int scaleBits = _planes.front()->getScaleBits();
527  int halfScale = scaleBits / 2;
528  int nChild0 = 1 << _setup[0];
529  int nChild1 = 1 << _setup[1];
531  unsigned int iOff = 0;
532  for (hyperPlaneListType::iterator itHp = _planes.begin(); itHp != _planes.end(); ++itHp) {
533  rb_HyperPlane* hp = *itHp;
534  int row = hp->getRow();
535  // factorized subspaces?
536  if (_dimension == 2) {
537  // two factorized subspaces
538  vector<pair<int, int> > distNew1;
539  distNew1.reserve(nChild1);
540  for (int b1 = 0; b1 < nChild1; b1++) {
541  int distChild1 = _distances[iOff + 1] * 2 + hp->getStep(1, b1);
542  if (abs(distChild1) < hp->getCut(1)) distNew1.push_back(make_pair(b1, distChild1));
543  }
544  for (int b0 = 0; b0 < nChild0; b0++) {
545  int distChild0 = _distances[iOff] * 2 + hp->getStep(0, b0);
546  if (abs(distChild0) < hp->getCut(0)) {
547  distChild0 >>= halfScale;
548  for (vector<pair<int, int> >::iterator itP = distNew1.begin(); itP != distNew1.end(); ++itP) {
549  int distChild1 = itP->second >> halfScale;
550  int b = b0 + (itP->first << _setup[0]);
551  numHits[b]++;
552  if (row > lastRow[b]) {
553  lastRow[b] = row;
554  numRows[b]++;
555  }
556  sum2[b] += distChild0 * distChild0 + distChild1 * distChild1;
557  }
558  }
559  }
560  } else {
561  // single subspace
562  for (int b = 0; b < _numChild; b++) {
563  int distChild = _distances[iOff] * 2 + hp->getStep(0, b);
564  if (abs(distChild) < hp->getCut(0)) {
565  distChild >>= halfScale;
566  numHits[b]++;
567  if (row > lastRow[b]) {
568  lastRow[b] = row;
569  numRows[b]++;
570  }
571  sum2[b] += distChild * distChild;
572  }
573  }
574  }
575  iOff += _dimension;
576  }
578  vector<pair<unsigned int, int> > childList;
579  for (int b = 0; b < _numChild; b++) {
580  //cout << " child " << _level << " " << b << " " << numRows[b] << " " << numHits[b] << endl;
581  if (numRows[b] >= minRows) {
582  int weight = (numRows[b] << scaleBits) - (sum2[b] / numHits[b]);
583  childList.push_back(make_pair(b, weight));
584  }
585  }
586  sort(childList.begin(), childList.end(), compare);
588  for (vector<pair<unsigned int, int> >::iterator itP = childList.begin(); itP != childList.end(); ++itP) {
589  unsigned int b = itP->first;
590  // calculate child planes and distances
591  hyperPlaneListType childPlanes;
592  childPlanes.reserve(numHits[b]);
593  intListType childDistances;
594  childDistances.reserve(numHits[b] * _dimension);
595  int b0 = b % (1 << _setup[0]);
596  int b1 = b >> _setup[0];
597  iOff = 0;
598  for (hyperPlaneListType::iterator itHp = _planes.begin(); itHp != _planes.end(); ++itHp) {
599  rb_HyperPlane* hp = *itHp;
600  if (_dimension == 2) {
601  int distNew0 = _distances[iOff] * 2 + hp->getStep(0, b0);
602  int distNew1 = _distances[iOff + 1] * 2 + hp->getStep(1, b1);
603  if (abs(distNew0) < hp->getCut(0) and abs(distNew1) < hp->getCut(1)) {
604  childPlanes.push_back(hp);
605  childDistances.push_back(distNew0);
606  childDistances.push_back(distNew1);
607  }
608  } else {
609  int distNew0 = _distances[iOff] * 2 + hp->getStep(0, b0);
610  if (abs(distNew0) < hp->getCut(0)) {
611  childPlanes.push_back(hp);
612  childDistances.push_back(distNew0);
613  }
614  }
615  iOff += _dimension;
616  }
617  // calculate hit density (number of hits / length (in rows))
618  int rowLength = childPlanes.back()->getRow() - childPlanes.front()->getRow() + 1;
619  float density = float(numHits[b]) / float(rowLength);
620  //cout << " sorted child cubes " << itP->first << " " << itP->second << " " << rowLength << " " << density << endl;
621  // minimum level reached ?
622  if (_level >= minLevel) {
623  if ((effCut < density) && (density < purCut)) {
625  for (hyperPlaneListType::iterator itHp = childPlanes.begin(); itHp != childPlanes.end(); ++itHp)
626  hits.push_back((*itHp)->getHit());
627  return hits;
628  }
629  }
631  if (_level < maxLevel) {
632  rb_HyperCube newCube(_setup, childPlanes, childDistances, _level + 1);
633  if (nCube > maxCube) return hits;
634  hitListType candidate = newCube.divide(maxCube, minRows, minLevel, maxLevel, effCut, purCut);
635  if (candidate.size() > 0) return candidate;
636  }
637  }
638  return hits;
639 }
640 
641 } // close namespace brackets
642 
643 // #endif //#ifdef USE_ROWFHT
int getNdf() const
Get number of degrees of freedom (of segment fit).
int getLastRow() const
Get first last number.
std::vector< rb_HyperPlane * > _planes
list of hyperplanes
unsigned int _setup[2]
setup (number of parameters for pad plane (3), drift time measurement (2))
std::vector< double > doubleListType
intListType getCut() const
Get distance cut(s).
bool match(rb_Segment *, const double, const int) const
Match segment with other segment.
void fillRowMap(std::map< int, int > &) const
Fill row map.
double _bfieldScaleFactor
scale factor for magnetic field (default: 1.0)
rb_HyperPlane(int, rb_Hit *, directionsType &, double=0.75)
Construct row based hyperplane.
unsigned int _dimension
(measurement) dimension (1 or 2)
rb_Hit * getHit() const
Get hit (pointer).
const hitListType & getHitList() const
Get list of hits.
int getRow() const
Get row number.
int _scaleBits
number of scale bits (2^(_scaleBits) = 1.0)
double _unusedCut
Chi2 cut for matching unused hits in XY and Z.
std::vector< intListType > _steps
steps (distance to childs projected on normal)
RowBasedFastHoughTransformationProcessor aRowBasedFastHoughTransformationProcessor
rb_HyperCube(unsigned int *, hyperPlaneListType &, intListType &, unsigned int=0)
Construct row based hypercube.
std::vector< rb_Segment * > segListType
std::vector< rb_Hit * > hitListType
int getStep(int, int) const
Get step (distances of child to mother hypercube center projected on normal).
std::vector< rb_HyperPlane * > hyperPlaneListType
int _maxGap
Cut for (row) distance to segment for matching unused hits in XY and Z.
intListType _cut
distance cut for maximal component
int getHitNum() const
Get index to input hit collection.
std::vector< doubleListType > directionsType
hitListType divide(int, int, int, int, float, float)
Divide hypercube (recursively).
void addHit(rb_Hit *)
Add (unused) hit to segment.
int getFirstRow() const
Get first row number.
std::map< int, hitListType > rowHitMapType
std::vector< intListType > getSteps() const
Get steps (distances of child to mother hypercube center).