Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:27:14

0001 /** \class MuonNavigationSchool
0002  *
0003  * Description:
0004  *  Navigation school for the muon system
0005  *  This class defines which DetLayers are reacheable from each Muon DetLayer
0006  *  (DT, CSC and RPC). The reacheableness is based on an eta range criteria.
0007  *
0008  *
0009  * \author : Stefano Lacaprara - INFN Padova <stefano.lacaprara@pd.infn.it>
0010  *
0011  * Modification:
0012  *
0013  * Chang Liu:
0014  * The class links maps for nextLayers and compatibleLayers in the same time.
0015  *
0016  * Cesare Calabria:
0017  * GEMs implementation.
0018  * David Nash:
0019  * ME0s implementation.
0020  */
0021 
0022 #include "RecoMuon/Navigation/interface/MuonNavigationSchool.h"
0023 
0024 /* Collaborating Class Header */
0025 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
0026 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
0027 // #include "TrackingTools/DetLayers/interface/NavigationSetter.h"
0028 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
0029 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
0030 #include "RecoMuon/DetLayers/interface/MuonDetLayerGeometry.h"
0031 #include "RecoMuon/Navigation/interface/MuonBarrelNavigableLayer.h"
0032 #include "RecoMuon/Navigation/interface/MuonForwardNavigableLayer.h"
0033 #include "RecoMuon/Navigation/interface/MuonEtaRange.h"
0034 #include "RecoMuon/Navigation/interface/MuonDetLayerMap.h"
0035 #include "FWCore/Utilities/interface/Exception.h"
0036 
0037 #include <algorithm>
0038 #include <iostream>
0039 using namespace std;
0040 
0041 /// Constructor
0042 MuonNavigationSchool::MuonNavigationSchool(
0043     const MuonDetLayerGeometry* muonLayout, bool enableRPC, bool enableCSC, bool enableGEM, bool enableME0)
0044     : theMuonDetLayerGeometry(muonLayout) {
0045   theAllDetLayersInSystem = &muonLayout->allLayers();
0046   theAllNavigableLayer.resize(muonLayout->allLayers().size(), nullptr);
0047 
0048   // get all barrel DetLayers (DT + optional RPC)
0049   vector<const DetLayer*> barrel;
0050   if (enableRPC)
0051     barrel = muonLayout->allBarrelLayers();
0052   else
0053     barrel = muonLayout->allDTLayers();
0054 
0055   for (auto i = barrel.begin(); i != barrel.end(); i++) {
0056     const BarrelDetLayer* mbp = dynamic_cast<const BarrelDetLayer*>(*i);
0057     if (mbp == nullptr)
0058       throw cms::Exception("MuonNavigationSchool", "Bad BarrelDetLayer");
0059     addBarrelLayer(mbp);
0060   }
0061 
0062   // get all endcap DetLayers (CSC + optional RPC, GEM, ME0)
0063   vector<const DetLayer*> endcap;
0064   if (enableCSC & enableGEM & enableRPC & enableME0)
0065     endcap = muonLayout->allEndcapLayers();  //CSC + RPC + GEM +ME0
0066   else if (enableCSC & enableGEM & !enableRPC & !enableME0)
0067     endcap = muonLayout->allEndcapCscGemLayers();  // CSC + GEM
0068   else if (!enableCSC & enableGEM & !enableRPC & !enableME0)
0069     endcap = muonLayout->allGEMLayers();  //GEM only
0070   else if (enableCSC & !enableGEM & !enableRPC & !enableME0)
0071     endcap = muonLayout->allCSCLayers();  //CSC only
0072   else if (enableCSC & !enableGEM & !enableRPC & enableME0)
0073     endcap = muonLayout->allEndcapCscME0Layers();  // CSC + ME0
0074   else if (!enableCSC & !enableGEM & !enableRPC & enableME0)
0075     endcap = muonLayout->allME0Layers();  // ME0 only
0076   //else endcap = muonLayout->allCSCLayers(); //CSC only for all the remaining cases
0077   //Trying allEndcaplayers in all other cases, as in the GEM PR
0078   else
0079     endcap = muonLayout->allEndcapLayers();
0080 
0081   for (auto i = endcap.begin(); i != endcap.end(); i++) {
0082     const ForwardDetLayer* mep = dynamic_cast<const ForwardDetLayer*>(*i);
0083     if (mep == nullptr)
0084       throw cms::Exception("MuonNavigationSchool", "Bad ForwardDetLayer");
0085     addEndcapLayer(mep);
0086   }
0087 
0088   // create outward links for all DetLayers
0089   linkBarrelLayers();
0090   linkEndcapLayers(theForwardLayers, theForwardNLC);
0091   linkEndcapLayers(theBackwardLayers, theBackwardNLC);
0092 
0093   // create inverse links
0094   createInverseLinks();
0095 }
0096 
0097 /// Destructor
0098 MuonNavigationSchool::~MuonNavigationSchool() {
0099   for_each(theBarrelNLC.begin(), theBarrelNLC.end(), delete_layer());
0100   for_each(theForwardNLC.begin(), theForwardNLC.end(), delete_layer());
0101   for_each(theBackwardNLC.begin(), theBackwardNLC.end(), delete_layer());
0102 }
0103 
0104 /// return all Navigable layers
0105 MuonNavigationSchool::StateType MuonNavigationSchool::navigableLayers() {
0106   StateType result;
0107 
0108   vector<MuonBarrelNavigableLayer*>::const_iterator ib;
0109   vector<MuonForwardNavigableLayer*>::const_iterator ie;
0110 
0111   for (ib = theBarrelNLC.begin(); ib != theBarrelNLC.end(); ib++) {
0112     result.push_back(*ib);
0113   }
0114 
0115   for (ie = theForwardNLC.begin(); ie != theForwardNLC.end(); ie++) {
0116     result.push_back(*ie);
0117   }
0118 
0119   for (ie = theBackwardNLC.begin(); ie != theBackwardNLC.end(); ie++) {
0120     result.push_back(*ie);
0121   }
0122 
0123   return result;
0124 }
0125 
0126 /// create barrel layer map
0127 void MuonNavigationSchool::addBarrelLayer(const BarrelDetLayer* mbp) {
0128   const BoundCylinder& bc = mbp->specificSurface();
0129   float radius = bc.radius();
0130   float length = bc.bounds().length() / 2.;
0131 
0132   float eta_max = calculateEta(radius, length);
0133   float eta_min = -eta_max;
0134 
0135   theBarrelLayers[mbp] = MuonEtaRange(eta_max, eta_min);
0136 }
0137 
0138 /// create forwrad/backward layer maps
0139 void MuonNavigationSchool::addEndcapLayer(const ForwardDetLayer* mep) {
0140   const BoundDisk& bd = mep->specificSurface();
0141   float outRadius = bd.outerRadius();
0142   float inRadius = bd.innerRadius();
0143   float thick = bd.bounds().length() / 2.;
0144   float z = bd.position().z();
0145 
0146   if (z > 0.) {
0147     float eta_min = calculateEta(outRadius, z - thick);
0148     float eta_max = calculateEta(inRadius, z + thick);
0149     theForwardLayers[mep] = MuonEtaRange(eta_max, eta_min);
0150   } else {
0151     float eta_max = calculateEta(outRadius, z + thick);
0152     float eta_min = calculateEta(inRadius, z - thick);
0153     theBackwardLayers[mep] = MuonEtaRange(eta_max, eta_min);
0154   }
0155 }
0156 
0157 /// calculate pseudorapidity from r and z
0158 float MuonNavigationSchool::calculateEta(const float& r, const float& z) const {
0159   if (z > 0)
0160     return -log((tan(atan(r / z) / 2.)));
0161   return log(-(tan(atan(r / z) / 2.)));
0162 }
0163 
0164 /// linking barrel layers outwards
0165 void MuonNavigationSchool::linkBarrelLayers() {
0166   for (MapBI bl = theBarrelLayers.begin(); bl != theBarrelLayers.end(); bl++) {
0167     MuonEtaRange range = (*bl).second;
0168 
0169     // first add next barrel layer
0170     MapBI plusOne(bl);
0171     plusOne++;
0172     MapB outerBarrel;
0173     MapB allOuterBarrel;
0174     if (plusOne != theBarrelLayers.end()) {
0175       outerBarrel.insert(*plusOne);
0176     }
0177     // add all outer barrel layers
0178     for (MapBI iMBI = plusOne; iMBI != theBarrelLayers.end(); iMBI++) {
0179       allOuterBarrel.insert(*iMBI);
0180     }
0181     // then add all compatible backward layers with an eta criteria
0182     MapE allOuterBackward;
0183     for (MapEI el = theBackwardLayers.begin(); el != theBackwardLayers.end(); el++) {
0184       if ((*el).second.isCompatible(range)) {
0185         allOuterBackward.insert(*el);
0186       }
0187     }
0188     //add the backward next layer with an eta criteria
0189     MapE outerBackward;
0190     for (MapEI el = theBackwardLayers.begin(); el != theBackwardLayers.end(); el++) {
0191       if ((*el).second.isCompatible(range)) {
0192         outerBackward.insert(*el);
0193         break;
0194       }
0195     }
0196 
0197     // then add all compatible forward layers with an eta criteria
0198     MapE allOuterForward;
0199     for (MapEI el = theForwardLayers.begin(); el != theForwardLayers.end(); el++) {
0200       if ((*el).second.isCompatible(range)) {
0201         allOuterForward.insert(*el);
0202       }
0203     }
0204 
0205     // then add forward next layer with an eta criteria
0206     MapE outerForward;
0207     for (MapEI el = theForwardLayers.begin(); el != theForwardLayers.end(); el++) {
0208       if ((*el).second.isCompatible(range)) {
0209         outerForward.insert(*el);
0210         break;
0211       }
0212     }
0213 
0214     theBarrelNLC.push_back(new MuonBarrelNavigableLayer(
0215         (*bl).first, outerBarrel, outerBackward, outerForward, allOuterBarrel, allOuterBackward, allOuterForward));
0216   }
0217 }
0218 /// linking forward/backward layers outwards
0219 void MuonNavigationSchool::linkEndcapLayers(const MapE& layers, vector<MuonForwardNavigableLayer*>& result) {
0220   for (MapEI el = layers.begin(); el != layers.end(); el++) {
0221     MuonEtaRange range = (*el).second;
0222     // first add next endcap layer (if compatible)
0223     MapEI plusOne(el);
0224     plusOne++;
0225     MapE outerLayers;
0226     if (plusOne != layers.end() && (*plusOne).second.isCompatible(range)) {
0227       outerLayers.insert(*plusOne);
0228       if (!range.isInside((*plusOne).second)) {
0229         // then look if the next layer has a wider eta range, if so add it
0230         MapEI tmpel(plusOne);
0231         tmpel++;
0232         MuonEtaRange max((*plusOne).second);
0233         for (MapEI l = tmpel; l != layers.end(); l++) {
0234           MuonEtaRange next = (*l).second;
0235           if (next.isCompatible(max) && !range.isInside(next) && !next.isInside(max) &&
0236               next.subtract(max).isInside(range)) {
0237             max = max.add(next);
0238             outerLayers.insert(*l);
0239           }
0240         }
0241       }
0242     }
0243 
0244     MapE allOuterLayers;
0245     for (MapEI iMEI = plusOne; iMEI != layers.end(); iMEI++) {
0246       if ((*iMEI).second.isCompatible(range))
0247         allOuterLayers.insert(*iMEI);
0248     }
0249 
0250     result.push_back(new MuonForwardNavigableLayer((*el).first, outerLayers, allOuterLayers));
0251   }
0252 }
0253 
0254 /// create inverse links (i.e. inwards)
0255 void MuonNavigationSchool::createInverseLinks() {
0256   // set outward link
0257   // NavigationSetter setter(*this);
0258 
0259   setState(navigableLayers());
0260 
0261   // find for each layer which are the layers pointing to it
0262   typedef map<const DetLayer*, MapB, less<const DetLayer*> > BarrelMapType;
0263   typedef map<const DetLayer*, MapE, less<const DetLayer*> > ForwardMapType;
0264 
0265   // map of all DetLayers which can reach a specific DetLayer
0266   BarrelMapType reachedBarrelLayersMap;
0267   ForwardMapType reachedForwardLayersMap;
0268 
0269   // map of all DetLayers which is compatible with a specific DetLayer
0270   BarrelMapType compatibleBarrelLayersMap;
0271   ForwardMapType compatibleForwardLayersMap;
0272 
0273   // collect all reacheable layers starting from a barrel layer
0274   for (MapBI bli = theBarrelLayers.begin(); bli != theBarrelLayers.end(); bli++) {
0275     // barrel
0276     MuonBarrelNavigableLayer* mbnl =
0277         dynamic_cast<MuonBarrelNavigableLayer*>(theAllNavigableLayer[((*bli).first)->seqNum()]);
0278     MapB reacheableB = mbnl->getOuterBarrelLayers();
0279     for (MapBI i = reacheableB.begin(); i != reacheableB.end(); i++) {
0280       reachedBarrelLayersMap[(*i).first].insert(*bli);
0281     }
0282     MapB compatibleB = mbnl->getAllOuterBarrelLayers();
0283     for (MapBI i = compatibleB.begin(); i != compatibleB.end(); i++) {
0284       compatibleBarrelLayersMap[(*i).first].insert(*bli);
0285     }
0286     MapE reacheableE = mbnl->getOuterBackwardLayers();
0287     for (MapEI i = reacheableE.begin(); i != reacheableE.end(); i++) {
0288       reachedBarrelLayersMap[(*i).first].insert(*bli);
0289     }
0290     reacheableE = mbnl->getOuterForwardLayers();
0291     for (MapEI i = reacheableE.begin(); i != reacheableE.end(); i++) {
0292       reachedBarrelLayersMap[(*i).first].insert(*bli);
0293     }
0294     MapE compatibleE = mbnl->getAllOuterBackwardLayers();
0295     for (MapEI i = compatibleE.begin(); i != compatibleE.end(); i++) {
0296       compatibleBarrelLayersMap[(*i).first].insert(*bli);
0297     }
0298     compatibleE = mbnl->getAllOuterForwardLayers();
0299     for (MapEI i = compatibleE.begin(); i != compatibleE.end(); i++) {
0300       compatibleBarrelLayersMap[(*i).first].insert(*bli);
0301     }
0302   }
0303 
0304   // collect all reacheable layer starting from a backward layer
0305   for (MapEI eli = theBackwardLayers.begin(); eli != theBackwardLayers.end(); eli++) {
0306     MapE reacheableE =
0307         dynamic_cast<MuonForwardNavigableLayer*>(theAllNavigableLayer[((*eli).first)->seqNum()])->getOuterEndcapLayers();
0308     for (MapEI i = reacheableE.begin(); i != reacheableE.end(); i++) {
0309       reachedForwardLayersMap[(*i).first].insert(*eli);
0310     }
0311     // collect all compatible layer starting from a backward layer
0312     MapE compatibleE = dynamic_cast<MuonForwardNavigableLayer*>(theAllNavigableLayer[((*eli).first)->seqNum()])
0313                            ->getAllOuterEndcapLayers();
0314     for (MapEI i = compatibleE.begin(); i != compatibleE.end(); i++) {
0315       compatibleForwardLayersMap[(*i).first].insert(*eli);
0316     }
0317   }
0318 
0319   for (MapEI eli = theForwardLayers.begin(); eli != theForwardLayers.end(); eli++) {
0320     // collect all reacheable layer starting from a forward layer
0321     MapE reacheableE =
0322         dynamic_cast<MuonForwardNavigableLayer*>(theAllNavigableLayer[((*eli).first)->seqNum()])->getOuterEndcapLayers();
0323     for (MapEI i = reacheableE.begin(); i != reacheableE.end(); i++) {
0324       reachedForwardLayersMap[(*i).first].insert(*eli);
0325     }
0326     // collect all compatible layer starting from a forward layer
0327     MapE compatibleE = dynamic_cast<MuonForwardNavigableLayer*>(theAllNavigableLayer[((*eli).first)->seqNum()])
0328                            ->getAllOuterEndcapLayers();
0329     for (MapEI i = compatibleE.begin(); i != compatibleE.end(); i++) {
0330       compatibleForwardLayersMap[(*i).first].insert(*eli);
0331     }
0332   }
0333 
0334   // now set inverse link for barrel layers
0335   for (MapBI bli = theBarrelLayers.begin(); bli != theBarrelLayers.end(); bli++) {
0336     MuonBarrelNavigableLayer* mbnl =
0337         dynamic_cast<MuonBarrelNavigableLayer*>(theAllNavigableLayer[((*bli).first)->seqNum()]);
0338     mbnl->setInwardLinks(reachedBarrelLayersMap[(*bli).first]);
0339     mbnl->setInwardCompatibleLinks(compatibleBarrelLayersMap[(*bli).first]);
0340   }
0341   //BACKWARD
0342   for (MapEI eli = theBackwardLayers.begin(); eli != theBackwardLayers.end(); eli++) {
0343     MuonForwardNavigableLayer* mfnl =
0344         dynamic_cast<MuonForwardNavigableLayer*>(theAllNavigableLayer[((*eli).first)->seqNum()]);
0345     // for backward next layers
0346     mfnl->setInwardLinks(reachedBarrelLayersMap[(*eli).first], reachedForwardLayersMap[(*eli).first]);
0347     // for backward compatible layers
0348     mfnl->setInwardCompatibleLinks(compatibleBarrelLayersMap[(*eli).first], compatibleForwardLayersMap[(*eli).first]);
0349   }
0350   //FORWARD
0351   for (MapEI eli = theForwardLayers.begin(); eli != theForwardLayers.end(); eli++) {
0352     MuonForwardNavigableLayer* mfnl =
0353         dynamic_cast<MuonForwardNavigableLayer*>(theAllNavigableLayer[((*eli).first)->seqNum()]);
0354     // and for forward next layers
0355     mfnl->setInwardLinks(reachedBarrelLayersMap[(*eli).first], reachedForwardLayersMap[(*eli).first]);
0356     // and for forward compatible layers
0357     mfnl->setInwardCompatibleLinks(compatibleBarrelLayersMap[(*eli).first], compatibleForwardLayersMap[(*eli).first]);
0358   }
0359 }