CMS 3D CMS Logo

bSector.cc
Go to the documentation of this file.
1 /*
2  * See header file for a description of this class.
3  *
4  * \author N. Amapane - INFN Torino
5  */
6 
7 #include "bSector.h"
8 #include "printUniqueNames.h"
13 
14 #include <algorithm>
15 #include <iostream>
16 
17 using namespace SurfaceOrientation;
18 using namespace std;
19 using namespace magneticfield;
20 
21 // Default ctor needed to have arrays.
22 bSector::bSector() : debug(false) {}
23 
24 // The ctor is in charge of finding rods inside the sector.
25 bSector::bSector(handles::const_iterator begin, handles::const_iterator end, bool debugVal)
26  : volumes(begin, end), msector(nullptr), debug(debugVal) {
27  if (debug)
28  cout << " Sector at Phi " << volumes.front()->center().phi() << " " << volumes.back()->center().phi() << endl;
29 
30  if (volumes.size() == 1) {
31  if (debug) {
32  cout << " Rod at: 0 elements: " << end - begin << " unique volumes: ";
33  printUniqueNames(begin, end);
34  }
35  rods.push_back(bRod(begin, end, debug));
36  } else {
37  // Clusterize in phi. Use bin edge so that complete clusters can be
38  // easily found (not trivial using bin centers!)
39  // Unfortunately this makes the result more sensitive to the
40  // "resolution" parameter...
41  // To avoid +-pi boundary problems, take phi distance from min phi.
42  // Caveat of implicit conversions of Geom::Phi!!!
43 
44  // Sort volumes in DELTA phi - i.e. phi(j)-phi(i) > 0 if j>1.
46 
47  const float resolution(0.01); // rad
48  Geom::Phi<float> phi0 = volumes.front()->maxPhi();
49  float phiMin = -resolution;
50 
51  // Careful -- Phi overloads arithmetic operators and will wrap around each step of a calculation,
52  // so use casts to prevent intermediate value wrap-arounds.
53  float phiTmp = static_cast<float>(volumes.back()->maxPhi()) - static_cast<float>(phi0) + resolution;
54  const float phiMax = angle0to2pi::make0To2pi(phiTmp); // Ensure 0-2pi
55 
56  if (debug) {
57  cout << "volumes size = " << volumes.size();
58  cout << ", phi0 = " << phi0 << ", volumes.back()->maxPhi() = " << volumes.back()->maxPhi();
59  cout << ", phiMin = " << phiMin << endl << "phiMax = " << phiMax;
60  cout << ", int((phiMax - phiMin) / resolution) + 1 = " << int((phiMax - phiMin) / resolution) + 1 << endl;
61  }
62  ClusterizingHistogram hisPhi(int((phiMax - phiMin) / resolution) + 1, phiMin, phiMax);
63 
64  handles::const_iterator first = volumes.begin();
65  handles::const_iterator last = volumes.end();
66 
67  for (handles::const_iterator i = first; i != last; ++i) {
68  hisPhi.fill((*i)->maxPhi() - phi0);
69  }
70  vector<float> phiClust = hisPhi.clusterize(resolution);
71 
72  if (debug)
73  cout << " Found " << phiClust.size() << " clusters in Phi, "
74  << " rods: " << endl;
75 
76  handles::const_iterator rodStart = first;
77  handles::const_iterator separ = first;
78 
79  float DZ = (*max_element(first, last, LessZ()))->maxZ() - (*min_element(first, last, LessZ()))->minZ();
80 
81  float DZ1 = 0.;
82  for (unsigned int i = 0; i < phiClust.size(); ++i) {
83  float phiSepar;
84  if (i < phiClust.size() - 1) {
85  phiSepar = (phiClust[i] + phiClust[i + 1]) / 2.f;
86  } else {
87  phiSepar = phiMax;
88  }
89  if (debug)
90  cout << " cluster " << i << " phisepar " << phiSepar << endl;
91  while (separ < last && (*separ)->maxPhi() - phi0 < phiSepar) {
92  DZ1 += ((*separ)->maxZ() - (*separ)->minZ());
93  if (debug)
94  cout << " " << (*separ)->name << " " << (*separ)->maxPhi() - phi0 << " " << (*separ)->maxZ() << " "
95  << (*separ)->minZ() << " " << DZ1 << endl;
96  ++separ;
97  }
98 
99  // FIXME: print warning for small discrepancies. Tolerance (below)
100  // had to be increased since discrepancies sum to up to ~ 2 mm.
101  if (fabs(DZ - DZ1) > 0.001 && fabs(DZ - DZ1) < 0.5) {
102  if (debug)
103  cout << "*** WARNING: Z lenght mismatch by " << DZ - DZ1 << " " << DZ << " " << DZ1 << endl;
104  }
105  if (fabs(DZ - DZ1) > 0.25) { // FIXME hardcoded tolerance
106  if (debug)
107  cout << " Incomplete, use also next cluster: " << DZ << " " << DZ1 << " " << DZ - DZ1 << endl;
108  DZ1 = 0.;
109  continue;
110  } else if (DZ1 > DZ + 0.05) { // Wrong: went past max lenght // FIXME hardcoded tolerance
111  cout << " *** ERROR: bSector finding messed up." << endl;
112  printUniqueNames(rodStart, separ);
113  DZ1 = 0.;
114  } else {
115  if (debug) {
116  cout << " Rod at: " << phiClust[i] << " elements: " << separ - rodStart << " unique volumes: ";
117  printUniqueNames(rodStart, separ);
118  }
119 
120  rods.push_back(bRod(rodStart, separ, debug));
121  rodStart = separ;
122  DZ1 = 0.;
123  }
124  }
125 
126  if (rods.empty())
127  cout << " *** ERROR: bSector has no rods " << DZ << " " << DZ1 << endl;
128  if (debug)
129  cout << "-----------------------" << endl;
130  }
131 }
132 
134  if (msector == nullptr) {
135  vector<MagBRod*> mRods;
136  for (vector<bRod>::const_iterator rod = rods.begin(); rod != rods.end(); ++rod) {
137  mRods.push_back((*rod).buildMagBRod());
138  }
139  msector = new MagBSector(mRods, volumes.front()->minPhi()); //FIXME
140  // Never deleted. When is it safe to delete it?
141  }
142  return msector;
143 }
void printUniqueNames(handles::const_iterator begin, handles::const_iterator end, bool uniq=true)
Just for debugging...
MagBSector * buildMagBSector() const
Construct the MagBSector upon request.
Definition: bSector.cc:133
MagBSector * msector
Definition: bSector.h:40
std::vector< float > clusterize(float resolution)
double f[11][100]
bSector()
Default ctor is needed to have arrays.
Definition: bSector.cc:22
#define debug
Definition: HDRShower.cc:19
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
std::vector< bRod > rods
Definition: bSector.h:38
constexpr valType make0To2pi(valType angle)
Definition: deltaPhi.h:67