CMS 3D CMS Logo

bSector.cc
Go to the documentation of this file.
1 // #include "Utilities/Configuration/interface/Architecture.h"
2 
3 /*
4  * See header file for a description of this class.
5  *
6  * \author N. Amapane - INFN Torino
7  */
8 
13 
15 
16 #include <algorithm>
17 
18 using namespace SurfaceOrientation;
19 using namespace std;
20 
21 
22 // Default ctor needed to have arrays.
24 
26 
27 // The ctor is in charge of finding rods inside the sector.
29  handles::const_iterator end) :
30  volumes(begin,end),
31  msector(nullptr)
32 {
33  if (MagGeoBuilderFromDDD::debug) cout << " Sector at Phi " << volumes.front()->center().phi() << " "
34  << volumes.back()->center().phi() << endl;
35 
36  if (volumes.size() == 1) {
38  cout << " Rod at: 0 elements: " << end-begin
39  << " unique volumes: ";
41  }
42  rods.push_back(bRod(begin,end));
43  } else {
44  // Clusterize in phi. Use bin edge so that complete clusters can be
45  // easily found (not trivial using bin centers!)
46  // Unfortunately this makes the result more sensitive to the
47  // "resolution" parameter...
48  // To avoid +-pi boundary problems, take phi distance from min phi.
49  // Caveat of implicit conversions of Geom::Phi!!!
50 
51  // Sort volumes in DELTA phi - i.e. phi(j)-phi(i) > 0 if j>1.
52  precomputed_value_sort(volumes.begin(), volumes.end(),
53  ExtractPhiMax(), LessDPhi());
54 
55  const Geom::Phi<float> resolution(0.01); // rad
56  Geom::Phi<float> phi0 = volumes.front()->maxPhi();
57  float phiMin = -(float) resolution;
58  float phiMax = volumes.back()->maxPhi() - phi0 + resolution;
59 
60  ClusterizingHistogram hisPhi( int((phiMax-phiMin)/resolution) + 1,
61  phiMin, phiMax);
62 
63  handles::const_iterator first = volumes.begin();
64  handles::const_iterator last = volumes.end();
65 
66  for (handles::const_iterator i=first; i!=last; ++i){
67  hisPhi.fill((*i)->maxPhi()-phi0);
68  }
69  vector<float> phiClust = hisPhi.clusterize(resolution);
70 
71  if (MagGeoBuilderFromDDD::debug) cout << " Found " << phiClust.size() << " clusters in Phi, "
72  << " rods: " << endl;
73 
74  handles::const_iterator rodStart = first;
75  handles::const_iterator separ = first;
76 
77  float DZ = (*max_element(first,last,LessZ()))->maxZ() -
78  (*min_element(first,last,LessZ()))->minZ();
79 
80  float DZ1 = 0.;
81  for (unsigned int i=0; i<phiClust.size(); ++i) {
82  float phiSepar;
83  if (i<phiClust.size()-1) {
84  phiSepar = (phiClust[i] + phiClust[i+1])/2.f;
85  } else {
86  phiSepar = phiMax;
87  }
88  if (MagGeoBuilderFromDDD::debug) cout << " cluster " << i
89  << " phisepar " << phiSepar <<endl;
90  while (separ < last && (*separ)->maxPhi()-phi0 < phiSepar ) {
91  DZ1 += ((*separ)->maxZ() - (*separ)->minZ());
92  if (MagGeoBuilderFromDDD::debug) cout << " " << (*separ)->name << " "
93  << (*separ)->maxPhi()-phi0 << " "
94  << (*separ)->maxZ() << " " << (*separ)->minZ() << " "
95  << 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 (MagGeoBuilderFromDDD::debug) cout << "*** WARNING: Z lenght mismatch by " << DZ-DZ1
103  << " " << DZ << " " << DZ1 << endl;
104 
105  }
106  if (fabs(DZ-DZ1) > 0.25 ) { // FIXME hardcoded tolerance
107  if (MagGeoBuilderFromDDD::debug) cout << " Incomplete, use also next cluster: "
108  << 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  volumeHandle::printUniqueNames(rodStart, separ);
114  DZ1 = 0.;
115  } else {
117  cout << " Rod at: " << phiClust[i] <<" elements: "
118  << separ-rodStart << " unique volumes: ";
119  volumeHandle::printUniqueNames(rodStart, separ);
120  }
121 
122  rods.push_back(bRod(rodStart, separ));
123  rodStart = separ;
124  DZ1 = 0.;
125  }
126  }
127 
128  if (rods.empty()) cout << " *** ERROR: bSector has no rods " << DZ << " " << DZ1 << endl;
129  if (MagGeoBuilderFromDDD::debug) cout << "-----------------------" << endl;
130 
131  }
132 }
133 
134 
136  if (msector==nullptr) {
137  vector<MagBRod*> mRods;
138  for (vector<bRod>::const_iterator rod = rods.begin();
139  rod!=rods.end(); ++rod) {
140  mRods.push_back((*rod).buildMagBRod());
141  }
142  msector = new MagBSector(mRods, volumes.front()->minPhi()); //FIXME
143  }
144  return msector;
145 }
std::vector< bRod > rods
Definition: bSector.h:40
#define nullptr
std::vector< float > clusterize(float resolution)
bSector()
Default ctor is needed to have arrays.
Definition: bSector.cc:23
double f[11][100]
#define end
Definition: vmac.h:39
MagBSector * buildMagBSector() const
Construct the MagBSector upon request.
Definition: bSector.cc:135
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
static void printUniqueNames(handles::const_iterator begin, handles::const_iterator end, bool uniq=true)
Just for debugging...
#define begin
Definition: vmac.h:32