CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/src/RecoMuon/DetLayers/src/MuonRPCDetLayerGeometryBuilder.cc

Go to the documentation of this file.
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 // Builds the forward (first) and backward (second) layers
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; // +1: forward, -1: backward
00042     
00043     // ME 1
00044     int firstStation=1;
00045         
00046     // ME 1/1
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     // ME 1/2 and ME1/3       
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     // ME 2 and ME 3 
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   //Sort in R
00226   precomputed_value_sort(geomDets.begin(), geomDets.end(),geomsort::DetR());
00227 
00228   // Clusterize in phi - phi0
00229   float resolution(25); // cm
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   // LogTrace(metname) << "     Found " << phiClust.size() << " clusters in Phi, ";
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     // LogTrace(metname) << "       cluster " << i
00260     // << " phisepar " << phiSepar <<endl;
00261     while (separ < last && float((*separ)->position().perp())-r0 < rSepar ) {
00262       // LogTrace(metname) << "         roll at dphi:  " << float((*separ)->position().phi())-phi0;
00263       separ++;
00264     }
00265 
00266     if (int(separ-layerStart) > 0) {
00267       // we have a layer in R.  Now separate it into rods
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   //Sort in phi
00290   precomputed_value_sort(geomDets.begin(), geomDets.end(),geomsort::DetPhi());
00291 
00292   // Clusterize in phi - phi0
00293   float resolution(0.01); // rad
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   // LogTrace(metname) << "     Found " << phiClust.size() << " clusters in Phi, ";
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     // LogTrace(metname) << "       cluster " << i
00324     // << " phisepar " << phiSepar <<endl;
00325     while (separ < last && float((*separ)->position().phi())-phi0 < phiSepar ) {
00326       // LogTrace(metname) << "         roll at dphi:  " << float((*separ)->position().phi())-phi0;
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   // ME1/2 is always in back
00345   //  if(rpcId.station() == 1 && rpcId.ring() == 2)  return false;
00346 
00347   bool result = false;
00348   int ring = rpcId.ring();
00349   int station = rpcId.station();
00350   // 20 degree rings are a little weird! not anymore from 17x
00351   if(ring == 1 && station > 1)
00352   {
00353     // RE2/1 RE3/1  Upscope Geometry
00354     /* goes (sector) (subsector)            1/3
00355     1 1 back   // front 
00356     1 2 front  // back  
00357     1 3 front  // front 
00358     2 1 front  // back  
00359     2 2 back   // from  
00360     2 3 back   // back  
00361                         
00362     */
00363     result = (rpcId.subsector() != 2);
00364     if(rpcId.sector()%2 == 0) result = !result;
00365     return result;
00366   }
00367   else
00368   {
00369     // 10 degree rings have odd subsectors in front
00370     result = (rpcId.subsector()%2 == 0);
00371   }
00372   return result;
00373 }
00374 
00375