CMS 3D CMS Logo

MuonRPCDetLayerGeometryBuilder.cc
Go to the documentation of this file.
2 
9 
13 
15 
16 #include <iostream>
17 
18 using namespace std;
19 
21  template <class T, class Scalar = typename T::Scalar>
24  Scalar operator()(const T* p) const { return fabs(p->specificSurface().innerRadius()); }
25  Scalar operator()(const T& p) const { return fabs(p.specificSurface().innerRadius()); }
26  };
27 } // namespace rpcdetlayergeomsort
28 
30 
31 // Builds the forward (first) and backward (second) layers
32 pair<vector<DetLayer*>, vector<DetLayer*> > MuonRPCDetLayerGeometryBuilder::buildEndcapLayers(const RPCGeometry& geo) {
33  vector<DetLayer*> result[2];
34 
35  for (int endcap = -1; endcap <= 1; endcap += 2) {
36  int iendcap = (endcap == 1) ? 0 : 1; // +1: forward, -1: backward
37 
38  // ME 1
39  int firstStation = 1;
40 
41  // ME 1/1
42  for (int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
43  vector<int> rolls;
44  std::vector<int> rings;
45  int FirstStationRing = 1;
46  rings.push_back(FirstStationRing);
47  for (int roll = RPCDetId::minRollId + 1; roll <= RPCDetId::maxRollId; ++roll) {
48  rolls.push_back(roll);
49  }
50 
51  MuRingForwardDoubleLayer* ringLayer = buildLayer(endcap, rings, firstStation, layer, rolls, geo);
52  if (ringLayer)
53  result[iendcap].push_back(ringLayer);
54  }
55 
56  // ME 1/2 and ME1/3
57  for (int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
58  vector<int> rolls;
59  std::vector<int> rings;
60  for (int ring = 2; ring <= 3; ++ring) {
61  rings.push_back(ring);
62  }
63  for (int roll = RPCDetId::minRollId + 1; roll <= RPCDetId::maxRollId; ++roll) {
64  rolls.push_back(roll);
65  }
66 
67  MuRingForwardDoubleLayer* ringLayer = buildLayer(endcap, rings, firstStation, layer, rolls, geo);
68  if (ringLayer)
69  result[iendcap].push_back(ringLayer);
70  }
71 
72  // ME 2 and ME 3
73  for (int station = 2; station <= RPCDetId::maxStationId; ++station) {
74  for (int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
75  vector<int> rolls;
76  std::vector<int> rings;
78  rings.push_back(ring);
79  }
80  for (int roll = RPCDetId::minRollId + 1; roll <= RPCDetId::maxRollId; ++roll) {
81  rolls.push_back(roll);
82  }
83 
84  MuRingForwardDoubleLayer* ringLayer = buildLayer(endcap, rings, station, layer, rolls, geo);
85  if (ringLayer)
86  result[iendcap].push_back(ringLayer);
87  }
88  }
89  }
90  pair<vector<DetLayer*>, vector<DetLayer*> > res_pair(result[0], result[1]);
91  return res_pair;
92 }
93 
95  int endcap, const std::vector<int>& rings, int station, int layer, vector<int>& rolls, const RPCGeometry& geo) {
96  const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
97 
98  vector<const ForwardDetRing*> frontRings, backRings;
99 
100  for (std::vector<int>::const_iterator ring = rings.begin(); ring < rings.end(); ++ring) {
101  for (vector<int>::iterator roll = rolls.begin(); roll != rolls.end(); ++roll) {
102  vector<const GeomDet*> frontDets, backDets;
103  for (int sector = RPCDetId::minSectorForwardId; sector <= RPCDetId::maxSectorForwardId; ++sector) {
104  for (int subsector = RPCDetId::minSubSectorForwardId; subsector <= RPCDetId::maxSectorForwardId; ++subsector) {
105  RPCDetId rpcId(endcap, *ring, station, sector, layer, subsector, (*roll));
106  bool isInFront = isFront(rpcId);
107  const GeomDet* geomDet = geo.idToDet(rpcId);
108  if (geomDet) {
109  if (isInFront) {
110  frontDets.push_back(geomDet);
111  } else {
112  backDets.push_back(geomDet);
113  }
114  LogTrace(metname) << "get RPC Endcap roll " << rpcId << (isInFront ? "front" : "back ")
115  << " at R=" << geomDet->position().perp() << ", phi=" << geomDet->position().phi()
116  << ", Z=" << geomDet->position().z();
117  }
118  }
119  }
120  if (!frontDets.empty()) {
121  precomputed_value_sort(frontDets.begin(), frontDets.end(), geomsort::DetPhi());
122  frontRings.push_back(new MuDetRing(frontDets));
123  LogTrace(metname) << "New front ring with " << frontDets.size()
124  << " chambers at z=" << frontRings.back()->position().z();
125  }
126  if (!backDets.empty()) {
127  precomputed_value_sort(backDets.begin(), backDets.end(), geomsort::DetPhi());
128  backRings.push_back(new MuDetRing(backDets));
129  LogTrace(metname) << "New back ring with " << backDets.size()
130  << " chambers at z=" << backRings.back()->position().z();
131  }
132  }
133  }
134 
135  MuRingForwardDoubleLayer* result = nullptr;
136 
137  if (!backRings.empty() || !frontRings.empty()) {
139  precomputed_value_sort(frontRings.begin(), frontRings.end(), SortRingByInnerR());
140  precomputed_value_sort(backRings.begin(), backRings.end(), SortRingByInnerR());
141 
142  result = new MuRingForwardDoubleLayer(frontRings, backRings);
143  LogTrace(metname) << "New layer with " << frontRings.size() << " front rings and " << backRings.size()
144  << " back rings, at Z " << result->position().z();
145  }
146 
147  return result;
148 }
149 
151  const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
152 
153  vector<DetLayer*> detlayers;
154  vector<MuRodBarrelLayer*> result;
155  int region = 0;
156 
158  vector<const GeomDet*> geomDets;
159 
160  for (int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
161  for (int sector = RPCDetId::minSectorId; sector <= RPCDetId::maxSectorId; sector++) {
162  for (int subsector = RPCDetId::minSubSectorId; subsector <= RPCDetId::maxSubSectorId; subsector++) {
164  for (int roll = RPCDetId::minRollId + 1; roll <= RPCDetId::maxRollId; roll++) {
165  const GeomDet* geomDet = geo.idToDet(RPCDetId(region, wheel, station, sector, layer, subsector, roll));
166  if (geomDet) {
167  geomDets.push_back(geomDet);
168  LogTrace(metname) << "get RPC Barrel roll "
169  << RPCDetId(region, wheel, station, sector, layer, subsector, roll)
170  << " at R=" << geomDet->position().perp() << ", phi=" << geomDet->position().phi();
171  }
172  }
173  }
174  }
175  }
176  }
177  makeBarrelLayers(geomDets, result);
178  }
179 
180  for (vector<MuRodBarrelLayer*>::const_iterator it = result.begin(); it != result.end(); it++)
181  detlayers.push_back((DetLayer*)(*it));
182 
183  return detlayers;
184 }
185 
186 void MuonRPCDetLayerGeometryBuilder::makeBarrelLayers(vector<const GeomDet*>& geomDets,
187  vector<MuRodBarrelLayer*>& result) {
188  const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
189 
190  //Sort in R
191  precomputed_value_sort(geomDets.begin(), geomDets.end(), geomsort::DetR());
192 
193  // Clusterize in phi - phi0
194  float resolution(25); // cm
195  float r0 = float(geomDets.front()->position().perp());
196  float rMin = -float(resolution);
197  float rMax = float(geomDets.back()->position().perp()) - r0 + resolution;
198 
199  ClusterizingHistogram hisR(int((rMax - rMin) / resolution) + 1, rMin, rMax);
200 
201  vector<const GeomDet*>::iterator first = geomDets.begin();
202  vector<const GeomDet*>::iterator last = geomDets.end();
203 
204  for (vector<const GeomDet*>::iterator i = first; i != last; i++) {
205  hisR.fill(float((*i)->position().perp()) - r0);
206  LogTrace(metname) << "R " << float((*i)->position().perp()) - r0;
207  }
208  vector<float> rClust = hisR.clusterize(resolution);
209 
210  // LogTrace(metname) << " Found " << phiClust.size() << " clusters in Phi, ";
211 
212  vector<const GeomDet*>::iterator layerStart = first;
213  vector<const GeomDet*>::iterator separ = first;
214 
215  for (unsigned int i = 0; i < rClust.size(); i++) {
216  float rSepar;
217  if (i < rClust.size() - 1) {
218  rSepar = (rClust[i] + rClust[i + 1]) / 2.f;
219  } else {
220  rSepar = rMax;
221  }
222 
223  // LogTrace(metname) << " cluster " << i
224  // << " phisepar " << phiSepar <<endl;
225  while (separ < last && float((*separ)->position().perp()) - r0 < rSepar) {
226  // LogTrace(metname) << " roll at dphi: " << float((*separ)->position().phi())-phi0;
227  separ++;
228  }
229 
230  if (int(separ - layerStart) > 0) {
231  // we have a layer in R. Now separate it into rods
232  vector<const DetRod*> rods;
233  vector<const GeomDet*> layerDets(layerStart, separ);
234  makeBarrelRods(layerDets, rods);
235 
236  if (!rods.empty()) {
237  result.push_back(new MuRodBarrelLayer(rods));
238  LogTrace(metname) << " New MuRodBarrelLayer with " << rods.size() << " rods, at R "
239  << result.back()->specificSurface().radius();
240  }
241  }
242  layerStart = separ;
243  }
244 }
245 
246 void MuonRPCDetLayerGeometryBuilder::makeBarrelRods(vector<const GeomDet*>& geomDets, vector<const DetRod*>& result) {
247  const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
248 
249  //Sort in phi
250  precomputed_value_sort(geomDets.begin(), geomDets.end(), geomsort::DetPhi());
251 
252  // Clusterize in phi - phi0
253  float resolution(0.01); // rad
254  float phi0 = float(geomDets.front()->position().phi());
255  float phiMin = -float(resolution);
256  float phiMax = float(geomDets.back()->position().phi()) - phi0 + resolution;
257 
258  ClusterizingHistogram hisPhi(int((phiMax - phiMin) / resolution) + 1, phiMin, phiMax);
259 
260  vector<const GeomDet*>::iterator first = geomDets.begin();
261  vector<const GeomDet*>::iterator last = geomDets.end();
262 
263  for (vector<const GeomDet*>::iterator i = first; i != last; i++) {
264  hisPhi.fill(float((*i)->position().phi()) - phi0);
265  LogTrace(metname) << "C " << float((*i)->position().phi()) - phi0;
266  }
267  vector<float> phiClust = hisPhi.clusterize(resolution);
268 
269  // LogTrace(metname) << " Found " << phiClust.size() << " clusters in Phi, ";
270 
271  vector<const GeomDet*>::iterator rodStart = first;
272  vector<const GeomDet*>::iterator separ = first;
273 
274  for (unsigned int i = 0; i < phiClust.size(); i++) {
275  float phiSepar;
276  if (i < phiClust.size() - 1) {
277  phiSepar = (phiClust[i] + phiClust[i + 1]) / 2.f;
278  } else {
279  phiSepar = phiMax;
280  }
281 
282  // LogTrace(metname) << " cluster " << i
283  // << " phisepar " << phiSepar <<endl;
284  while (separ < last && float((*separ)->position().phi()) - phi0 < phiSepar) {
285  // LogTrace(metname) << " roll at dphi: " << float((*separ)->position().phi())-phi0;
286  separ++;
287  }
288 
289  if (int(separ - rodStart) > 0) {
290  result.push_back(new MuDetRod(rodStart, separ));
291  LogTrace(metname) << " New MuDetRod with " << int(separ - rodStart)
292  << " rolls at R=" << (*rodStart)->position().perp()
293  << ", phi=" << float((*rodStart)->position().phi());
294  }
295  rodStart = separ;
296  }
297 }
298 
300  // ME1/2 is always in back
301  // if(rpcId.station() == 1 && rpcId.ring() == 2) return false;
302 
303  bool result = false;
304  int ring = rpcId.ring();
305  int station = rpcId.station();
306  // 20 degree rings are a little weird! not anymore from 17x
307  if (ring == 1 && station > 1) {
308  // RE2/1 RE3/1 Upscope Geometry
309  /* goes (sector) (subsector) 1/3
310  1 1 back // front
311  1 2 front // back
312  1 3 front // front
313  2 1 front // back
314  2 2 back // from
315  2 3 back // back
316 
317  */
318  result = (rpcId.subsector() != 2);
319  if (rpcId.sector() % 2 == 0)
320  result = !result;
321  return result;
322  } else {
323  // 10 degree rings have odd subsectors in front
324  result = (rpcId.subsector() % 2 == 0);
325  }
326  return result;
327 }
int sector() const
Sector id: the group of chambers at same phi (and increasing r)
Definition: RPCDetId.h:81
static void makeBarrelRods(std::vector< const GeomDet *> &geomDets, std::vector< const DetRod *> &result)
static constexpr int minLayerId
Definition: RPCDetId.h:120
T perp() const
Definition: PV3DBase.h:69
ExtractPhi< GeomDet, float > DetPhi
Definition: DetSorting.h:37
double Scalar
Definition: Definitions.h:25
T z() const
Definition: PV3DBase.h:61
const std::string metname
static constexpr int minRingForwardId
Definition: RPCDetId.h:104
static constexpr int minRingBarrelId
Definition: RPCDetId.h:106
Geom::Phi< T > phi() const
Definition: PV3DBase.h:66
static constexpr int maxSectorForwardId
Definition: RPCDetId.h:118
static constexpr int minSubSectorForwardId
Definition: RPCDetId.h:127
int ring() const
Definition: RPCDetId.h:59
static constexpr int minSectorForwardId
Definition: RPCDetId.h:117
#define LogTrace(id)
static constexpr int maxSectorId
Definition: RPCDetId.h:114
static constexpr int maxRingBarrelId
Definition: RPCDetId.h:107
ExtractR< GeomDet, float > DetR
Definition: DetSorting.h:20
static constexpr int maxRollId
Definition: RPCDetId.h:131
static constexpr int minSubSectorId
Definition: RPCDetId.h:123
static constexpr int maxRingForwardId
Definition: RPCDetId.h:105
static bool isFront(const RPCDetId &rpcId)
double f[11][100]
int subsector() const
SubSector id : some sectors are divided along the phi direction in subsectors (from 1 to 4 in Barrel...
Definition: RPCDetId.h:88
static constexpr int minStationId
Definition: RPCDetId.h:110
static constexpr int minSectorId
Definition: RPCDetId.h:113
static constexpr int maxLayerId
Definition: RPCDetId.h:121
void precomputed_value_sort(RandomAccessIterator begin, RandomAccessIterator end, const Extractor &extr, const Compare &comp)
static void makeBarrelLayers(std::vector< const GeomDet *> &geomDets, std::vector< MuRodBarrelLayer *> &result)
int station() const
Definition: RPCDetId.h:78
const Surface::PositionType & position() const
The position (origin of the R.F.)
Definition: GeomDet.h:43
static std::pair< std::vector< DetLayer * >, std::vector< DetLayer * > > buildEndcapLayers(const RPCGeometry &geo)
constexpr uint32_t layerStart[numberOfLayers+1]
static constexpr int minRollId
Definition: RPCDetId.h:130
long double T
static constexpr int maxSubSectorId
Definition: RPCDetId.h:124
const GeomDet * idToDet(DetId) const override
Definition: RPCGeometry.cc:32
static constexpr int maxStationId
Definition: RPCDetId.h:111
static MuRingForwardDoubleLayer * buildLayer(int endcap, const std::vector< int > &rings, int station, int layer, std::vector< int > &rolls, const RPCGeometry &geo)
static std::vector< DetLayer * > buildBarrelLayers(const RPCGeometry &geo)
Builds the barrel layers. Result vector is sorted inside-out.