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