00001 #include <RecoMuon/DetLayers/src/MuonRPCDetLayerGeometryBuilder.h>
00002
00003 #include <DataFormats/MuonDetId/interface/RPCDetId.h>
00004 #include <Geometry/CommonDetUnit/interface/GeomDet.h>
00005 #include <RecoMuon/DetLayers/interface/MuRingForwardDoubleLayer.h>
00006 #include <RecoMuon/DetLayers/interface/MuRodBarrelLayer.h>
00007 #include <RecoMuon/DetLayers/interface/MuDetRing.h>
00008 #include <RecoMuon/DetLayers/interface/MuDetRod.h>
00009
00010 #include <Utilities/General/interface/precomputed_value_sort.h>
00011 #include <Geometry/CommonDetUnit/interface/DetSorting.h>
00012 #include "Utilities/BinningTools/interface/ClusterizingHistogram.h"
00013
00014 #include <FWCore/MessageLogger/interface/MessageLogger.h>
00015
00016 #include <iostream>
00017
00018 using namespace std;
00019
00020 namespace rpcdetlayergeomsort {
00021 template <class T, class Scalar = typename T::Scalar>
00022 struct ExtractInnerRadius {
00023 typedef Scalar result_type;
00024 Scalar operator()(const T* p) const {return fabs(p->specificSurface().innerRadius());}
00025 Scalar operator()(const T& p) const {return fabs(p.specificSurface().innerRadius());}
00026 };
00027 }
00028
00029
00030 MuonRPCDetLayerGeometryBuilder::~MuonRPCDetLayerGeometryBuilder() {
00031 }
00032
00033
00034
00035 pair<vector<DetLayer*>, vector<DetLayer*> >
00036 MuonRPCDetLayerGeometryBuilder::buildEndcapLayers(const RPCGeometry& geo) {
00037
00038 vector<DetLayer*> result[2];
00039
00040 for (int endcap = -1; endcap<=1; endcap+=2) {
00041 int iendcap = (endcap==1) ? 0 : 1;
00042
00043
00044 int firstStation=1;
00045
00046
00047 for (int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
00048 vector<int> rolls;
00049 std::vector<int> rings;
00050 int FirstStationRing = 1;
00051 rings.push_back(FirstStationRing);
00052 for(int roll = RPCDetId::minRollId+1;
00053 roll <= RPCDetId::maxRollId; ++roll) {
00054 rolls.push_back(roll);
00055 }
00056
00057
00058
00059 MuRingForwardDoubleLayer* ringLayer = buildLayer(endcap, rings,
00060 firstStation , layer,
00061 rolls, geo);
00062 if (ringLayer) result[iendcap].push_back(ringLayer);
00063
00064 }
00065
00066
00067 for(int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
00068 vector<int> rolls;
00069 std::vector<int> rings;
00070 for(int ring = 2; ring <= 3; ++ring) {
00071 rings.push_back(ring);
00072 }
00073 for(int roll = RPCDetId::minRollId+1; roll <= RPCDetId::maxRollId;
00074 ++roll) {
00075 rolls.push_back(roll);
00076 }
00077
00078 MuRingForwardDoubleLayer* ringLayer = buildLayer(endcap, rings, firstStation , layer, rolls, geo);
00079 if (ringLayer) result[iendcap].push_back(ringLayer);
00080 }
00081
00082
00083
00084 for(int station = 2; station <= RPCDetId::maxStationId; ++station) {
00085 for(int layer = RPCDetId::minLayerId; layer <= RPCDetId::maxLayerId; ++layer) {
00086 vector<int> rolls;
00087 std::vector<int> rings;
00088 for(int ring = RPCDetId::minRingForwardId; ring <= RPCDetId::maxRingForwardId; ++ring) {
00089 rings.push_back(ring);
00090 }
00091 for(int roll = RPCDetId::minRollId+1; roll <= RPCDetId::maxRollId; ++roll) {
00092 rolls.push_back(roll);
00093 }
00094
00095 MuRingForwardDoubleLayer* ringLayer = buildLayer(endcap, rings, station, layer, rolls, geo);
00096 if (ringLayer) result[iendcap].push_back(ringLayer);
00097 }
00098 }
00099
00100 }
00101 pair<vector<DetLayer*>, vector<DetLayer*> > res_pair(result[0], result[1]);
00102 return res_pair;
00103
00104 }
00105
00106
00107
00108 MuRingForwardDoubleLayer*
00109 MuonRPCDetLayerGeometryBuilder::buildLayer(int endcap,std::vector<int> rings, int station,
00110 int layer,
00111 vector<int>& rolls,
00112 const RPCGeometry& geo) {
00113
00114 const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
00115
00116 vector<const ForwardDetRing*> frontRings, backRings;
00117
00118
00119 for (std::vector<int>::iterator ring=rings.begin(); ring<rings.end();++ring){
00120 for (vector<int>::iterator roll = rolls.begin(); roll!=rolls.end(); ++roll) {
00121 vector<const GeomDet*> frontDets, backDets;
00122 for(int sector = RPCDetId::minSectorForwardId; sector <= RPCDetId::maxSectorForwardId; ++sector) {
00123 for(int subsector = RPCDetId::minSubSectorForwardId; subsector <= RPCDetId::maxSectorForwardId; ++subsector) {
00124 RPCDetId rpcId(endcap,*ring, station,sector,layer,subsector, (*roll));
00125 bool isInFront = isFront(rpcId);
00126 const GeomDet* geomDet = geo.idToDet(rpcId);
00127 if (geomDet) {
00128
00129 if(isInFront)
00130 {
00131 frontDets.push_back(geomDet);
00132 }
00133 else
00134 {
00135 backDets.push_back(geomDet);
00136 }
00137 LogTrace(metname) << "get RPC Endcap roll "
00138 << rpcId
00139 << (isInFront ? "front" : "back ")
00140 << " at R=" << geomDet->position().perp()
00141 << ", phi=" << geomDet->position().phi()
00142 << ", Z=" << geomDet->position().z();
00143
00144 }
00145 }
00146 }
00147 if (frontDets.size()!=0) {
00148 precomputed_value_sort(frontDets.begin(), frontDets.end(), geomsort::DetPhi());
00149 frontRings.push_back(new MuDetRing(frontDets));
00150 LogTrace(metname) << "New front ring with " << frontDets.size()
00151 << " chambers at z="<< frontRings.back()->position().z();
00152 }
00153 if (backDets.size()!=0) {
00154 precomputed_value_sort(backDets.begin(), backDets.end(), geomsort::DetPhi());
00155 backRings.push_back(new MuDetRing(backDets));
00156 LogTrace(metname) << "New back ring with " << backDets.size()
00157 << " chambers at z="<< backRings.back()->position().z();
00158 }
00159 }
00160 }
00161
00162 MuRingForwardDoubleLayer * result = 0;
00163
00164 if(!backRings.empty() || !frontRings.empty())
00165 {
00166 typedef rpcdetlayergeomsort::ExtractInnerRadius<ForwardDetRing, float> SortRingByInnerR;
00167 precomputed_value_sort(frontRings.begin(), frontRings.end(), SortRingByInnerR());
00168 precomputed_value_sort(backRings.begin(), backRings.end(), SortRingByInnerR());
00169
00170 result = new MuRingForwardDoubleLayer(frontRings, backRings);
00171 LogTrace(metname) << "New layer with " << frontRings.size()
00172 << " front rings and " << backRings.size()
00173 << " back rings, at Z " << result->position().z();
00174 }
00175
00176 return result;
00177 }
00178
00179
00180 vector<DetLayer*>
00181 MuonRPCDetLayerGeometryBuilder::buildBarrelLayers(const RPCGeometry& geo) {
00182 const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
00183
00184 vector<DetLayer*> detlayers;
00185 vector<MuRodBarrelLayer*> result;
00186 int region =0;
00187
00188 for(int station = RPCDetId::minStationId; station <= RPCDetId::maxStationId; station++) {
00189
00190 vector<const GeomDet*> geomDets;
00191
00192 for(int layer=RPCDetId::minLayerId; layer<= RPCDetId::maxLayerId;++layer){
00193 for(int sector = RPCDetId::minSectorId; sector <= RPCDetId::maxSectorId; sector++) {
00194 for(int subsector = RPCDetId::minSubSectorId; subsector <= RPCDetId::maxSubSectorId; subsector++) {
00195 for(int wheel = RPCDetId::minRingBarrelId; wheel <= RPCDetId::maxRingBarrelId; wheel++) {
00196 for(int roll=RPCDetId::minRollId+1; roll <= RPCDetId::maxRollId; roll++){
00197 const GeomDet* geomDet = geo.idToDet(RPCDetId(region,wheel,station,sector,layer,subsector,roll));
00198 if (geomDet) {
00199 geomDets.push_back(geomDet);
00200 LogTrace(metname) << "get RPC Barrel roll " << RPCDetId(region,wheel,station,sector,layer,subsector,roll)
00201 << " at R=" << geomDet->position().perp()
00202 << ", phi=" << geomDet->position().phi() ;
00203 }
00204 }
00205 }
00206 }
00207 }
00208 }
00209 makeBarrelLayers(geomDets, result);
00210 }
00211
00212
00213 for(vector<MuRodBarrelLayer*>::const_iterator it = result.begin(); it != result.end(); it++)
00214 detlayers.push_back((DetLayer*)(*it));
00215
00216 return detlayers;
00217 }
00218
00219
00220 void MuonRPCDetLayerGeometryBuilder::makeBarrelLayers(vector<const GeomDet *> & geomDets,
00221 vector<MuRodBarrelLayer*> & result)
00222 {
00223 const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
00224
00225
00226 precomputed_value_sort(geomDets.begin(), geomDets.end(),geomsort::DetR());
00227
00228
00229 float resolution(25);
00230 float r0 = float(geomDets.front()->position().perp());
00231 float rMin = - float(resolution);
00232 float rMax = float(geomDets.back()->position().perp()) - r0 + resolution;
00233
00234 ClusterizingHistogram hisR( int((rMax-rMin)/resolution) + 1,
00235 rMin, rMax);
00236
00237 vector<const GeomDet*>::iterator first = geomDets.begin();
00238 vector<const GeomDet*>::iterator last = geomDets.end();
00239
00240 for (vector<const GeomDet*>::iterator i=first; i!=last; i++){
00241 hisR.fill(float((*i)->position().perp())-r0);
00242 LogTrace(metname) << "R " << float((*i)->position().perp())-r0;
00243 }
00244 vector<float> rClust = hisR.clusterize(resolution);
00245
00246
00247
00248 vector<const GeomDet*>::iterator layerStart = first;
00249 vector<const GeomDet*>::iterator separ = first;
00250
00251 for (unsigned int i=0; i<rClust.size(); i++) {
00252 float rSepar;
00253 if (i<rClust.size()-1) {
00254 rSepar = (rClust[i] + rClust[i+1])/2.f;
00255 } else {
00256 rSepar = rMax;
00257 }
00258
00259
00260
00261 while (separ < last && float((*separ)->position().perp())-r0 < rSepar ) {
00262
00263 separ++;
00264 }
00265
00266 if (int(separ-layerStart) > 0) {
00267
00268 vector<const DetRod*> rods;
00269 vector<const GeomDet*> layerDets(layerStart, separ);
00270 makeBarrelRods(layerDets, rods);
00271
00272 if (rods.size()!=0) {
00273 result.push_back(new MuRodBarrelLayer(rods));
00274 LogTrace(metname) << " New MuRodBarrelLayer with " << rods.size()
00275 << " rods, at R " << result.back()->specificSurface().radius();
00276 }
00277 }
00278 layerStart = separ;
00279 }
00280 }
00281
00282
00283 void
00284 MuonRPCDetLayerGeometryBuilder::makeBarrelRods(vector<const GeomDet *> & geomDets,
00285 vector<const DetRod*> & result)
00286 {
00287 const std::string metname = "Muon|RPC|RecoMuon|RecoMuonDetLayers|MuonRPCDetLayerGeometryBuilder";
00288
00289
00290 precomputed_value_sort(geomDets.begin(), geomDets.end(),geomsort::DetPhi());
00291
00292
00293 float resolution(0.01);
00294 float phi0 = float(geomDets.front()->position().phi());
00295 float phiMin = - float(resolution);
00296 float phiMax = float(geomDets.back()->position().phi()) - phi0 + resolution;
00297
00298 ClusterizingHistogram hisPhi( int((phiMax-phiMin)/resolution) + 1,
00299 phiMin, phiMax);
00300
00301 vector<const GeomDet*>::iterator first = geomDets.begin();
00302 vector<const GeomDet*>::iterator last = geomDets.end();
00303
00304 for (vector<const GeomDet*>::iterator i=first; i!=last; i++){
00305 hisPhi.fill(float((*i)->position().phi())-phi0);
00306 LogTrace(metname) << "C " << float((*i)->position().phi())-phi0;
00307 }
00308 vector<float> phiClust = hisPhi.clusterize(resolution);
00309
00310
00311
00312 vector<const GeomDet*>::iterator rodStart = first;
00313 vector<const GeomDet*>::iterator separ = first;
00314
00315 for (unsigned int i=0; i<phiClust.size(); i++) {
00316 float phiSepar;
00317 if (i<phiClust.size()-1) {
00318 phiSepar = (phiClust[i] + phiClust[i+1])/2.f;
00319 } else {
00320 phiSepar = phiMax;
00321 }
00322
00323
00324
00325 while (separ < last && float((*separ)->position().phi())-phi0 < phiSepar ) {
00326
00327 separ++;
00328 }
00329
00330 if (int(separ-rodStart) > 0) {
00331 result.push_back(new MuDetRod(rodStart, separ));
00332 LogTrace(metname) << " New MuDetRod with " << int(separ-rodStart)
00333 << " rolls at R=" << (*rodStart)->position().perp()
00334 << ", phi=" << float((*rodStart)->position().phi());
00335
00336 }
00337 rodStart = separ;
00338 }
00339 }
00340
00341
00342 bool MuonRPCDetLayerGeometryBuilder::isFront(const RPCDetId & rpcId)
00343 {
00344
00345
00346
00347 bool result = false;
00348
00349 if(rpcId.ring() == 1 && rpcId.station() > 1)
00350 {
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 result = (rpcId.subsector() != 2);
00362 if(rpcId.sector()%2 == 0) result = !result;
00363 return result;
00364 }
00365 else
00366 {
00367
00368 result = (rpcId.subsector()%2 == 0);
00369 }
00370 return result;
00371 }
00372
00373