CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/RecoMuon/GlobalTrackingTools/src/MuonTkNavigationSchool.cc

Go to the documentation of this file.
00001 
00017 #include "RecoMuon/GlobalTrackingTools/interface/MuonTkNavigationSchool.h"
00018 
00019 //---------------
00020 // C++ Headers --
00021 //---------------
00022 
00023 #include <functional>
00024 #include <algorithm>
00025 #include <map>
00026 #include <cmath>
00027 
00028 //-------------------------------
00029 // Collaborating Class Headers --
00030 //-------------------------------
00031 
00032 #include "RecoTracker/TkNavigation/interface/SimpleBarrelNavigableLayer.h"
00033 #include "RecoTracker/TkNavigation/interface/SimpleForwardNavigableLayer.h"
00034 #include "RecoTracker/TkNavigation/interface/DiskLessInnerRadius.h"
00035 #include "RecoTracker/TkNavigation/interface/SymmetricLayerFinder.h"
00036 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00037 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00038 #include "TrackingTools/DetLayers/interface/NavigationSetter.h"
00039 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
00040 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
00041 #include "TrackingTools/DetLayers/src/DetBelowZ.h"
00042 #include "TrackingTools/DetLayers/src/DetLessZ.h"
00043 #include "RecoMuon/Navigation/interface/MuonNavigationSchool.h"
00044 #include "RecoMuon/Navigation/interface/MuonBarrelNavigableLayer.h"
00045 #include "RecoMuon/Navigation/interface/MuonForwardNavigableLayer.h"
00046 #include "RecoMuon/Navigation/interface/MuonDetLayerMap.h"
00047 #include "RecoTracker/TkNavigation/interface/SimpleNavigationSchool.h"
00048 #include "Utilities/General/interface/CMSexception.h"
00049 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00050 
00051 using namespace std;
00052 
00053 typedef std::vector<DetLayer*> LayerContainer;
00054 
00055 //
00056 // constructor
00057 //
00058 MuonTkNavigationSchool::MuonTkNavigationSchool(const MuonDetLayerGeometry* muonGeom, 
00059                                                const GeometricSearchTracker* trackerGeom, 
00060                                                const MagneticField* field) : 
00061    theMuonDetLayerGeometry(muonGeom), theGeometricSearchTracker(trackerGeom), theMagneticField(field) {
00062 
00063   // need to allocate the vector of DetLayers, to concatenate the two vectors of DetLayers
00064   // it has to be deleted in the destructor
00065   std::vector<DetLayer*> * allLayers = new std::vector<DetLayer*>();
00066   allLayers->reserve(muonGeom->allLayers().size()+trackerGeom->allLayers().size());
00067   allLayers->insert(allLayers->end(), muonGeom->allLayers().begin(), muonGeom->allLayers().end());
00068   allLayers->insert(allLayers->end(), trackerGeom->allLayers().begin(), trackerGeom->allLayers().end());
00069   theAllDetLayersInSystem = allLayers;
00070   
00071   // get tracker barrel layers
00072   std::vector<BarrelDetLayer*> blc = trackerGeom->barrelLayers();
00073   for ( std::vector<BarrelDetLayer*>::const_iterator i = blc.begin(); i != blc.end(); i++ ) {
00074      addBarrelLayer(*i);
00075   }
00076 
00077   // get tracker forward layers
00078   std::vector<ForwardDetLayer*> flc = trackerGeom->forwardLayers();
00079   for (std::vector<ForwardDetLayer*>::const_iterator i = flc.begin(); i != flc.end(); i++) {
00080     addEndcapLayer(*i); 
00081   }
00082 
00083   // get all muon barrel DetLayers (DT + RPC)
00084   vector<DetLayer*> barrel = muonGeom->allBarrelLayers();
00085   for ( vector<DetLayer*>::const_iterator i = barrel.begin(); i != barrel.end(); i++ ) {
00086     BarrelDetLayer* mbp = dynamic_cast<BarrelDetLayer*>(*i);
00087     if ( mbp == 0 ) throw Genexception("Bad BarrelDetLayer");
00088     addBarrelLayer(mbp);
00089   }
00090 
00091   // get all muon forward (+z) DetLayers (CSC + RPC)
00092   vector<DetLayer*> endcap = muonGeom->allEndcapLayers();
00093   for ( vector<DetLayer*>::const_iterator i = endcap.begin(); i != endcap.end(); i++ ) {
00094     ForwardDetLayer* mep = dynamic_cast<ForwardDetLayer*>(*i);
00095     if ( mep == 0 ) throw Genexception("Bad ForwardDetLayer");
00096     addEndcapLayer(mep);
00097   }
00098 
00099   // create outward links for all DetLayers
00100   linkBarrelLayers();
00101   linkEndcapLayers(theForwardLayers,theMuonForwardNLC, theTkForwardNLC);
00102   linkEndcapLayers(theBackwardLayers,theMuonBackwardNLC, theTkBackwardNLC);
00103 
00104 }
00105 
00106 
00107 //
00108 // destructor
00109 //
00110 MuonTkNavigationSchool::~MuonTkNavigationSchool() {
00111 
00112    for_each(theTkBarrelNLC.begin(),theTkBarrelNLC.end(), delete_layer());
00113    for_each(theTkForwardNLC.begin(),theTkForwardNLC.end(), delete_layer());
00114    for_each(theTkBackwardNLC.begin(),theTkBackwardNLC.end(), delete_layer());
00115    for_each(theMuonBarrelNLC.begin(),theMuonBarrelNLC.end(), delete_layer());
00116    for_each(theMuonForwardNLC.begin(),theMuonForwardNLC.end(), delete_layer());
00117    for_each(theMuonBackwardNLC.begin(),theMuonBackwardNLC.end(), delete_layer());
00118 
00119    // delete the vector containing all the detlayers
00120    delete theAllDetLayersInSystem;
00121 
00122 }
00123 
00124 
00125 /* Operations as NavigationSchool */
00126 
00127 //
00128 //
00129 //
00130 vector<NavigableLayer*> MuonTkNavigationSchool::navigableLayers() const {
00131  
00132   vector<NavigableLayer*> result;
00133   
00134   for ( vector< SimpleBarrelNavigableLayer*>::const_iterator 
00135           ib = theTkBarrelNLC.begin(); ib != theTkBarrelNLC.end(); ib++) {
00136     result.push_back( *ib);
00137   }
00138   for ( vector< SimpleForwardNavigableLayer*>::const_iterator 
00139           ifl = theTkForwardNLC.begin(); ifl != theTkForwardNLC.end(); ifl++) {
00140     result.push_back( *ifl);
00141   }
00142 
00143   for ( vector< SimpleForwardNavigableLayer*>::const_iterator
00144           ifl = theTkBackwardNLC.begin(); ifl != theTkBackwardNLC.end(); ifl++) {
00145     result.push_back( *ifl);
00146   }
00147 
00148   vector<MuonBarrelNavigableLayer*>::const_iterator ib;
00149   vector<MuonForwardNavigableLayer*>::const_iterator ie;
00150 
00151   for ( ib = theMuonBarrelNLC.begin(); ib != theMuonBarrelNLC.end(); ib++ ) {
00152     result.push_back(*ib);
00153   }
00154 
00155   for ( ie = theMuonForwardNLC.begin(); ie != theMuonForwardNLC.end(); ie++ ) {
00156     result.push_back(*ie);
00157   }
00158 
00159   for ( ie = theMuonBackwardNLC.begin(); ie != theMuonBackwardNLC.end(); ie++ ) {
00160     result.push_back(*ie);
00161   }
00162 
00163   return result;
00164 
00165 }
00166 
00167 
00168 //
00169 //
00170 //
00171 void MuonTkNavigationSchool::addBarrelLayer(BarrelDetLayer* mbp) {
00172 
00173   const BoundCylinder& bc = mbp->specificSurface();
00174   float radius = bc.radius();
00175   float length = bc.bounds().length()/2.;
00176   float eta_max = calculateEta(radius, length);
00177   float eta_min = -eta_max;
00178   edm::LogInfo("MuonTkNavigationSchool")<<"BarrelLayer eta: ("<<eta_min<<", "<<eta_max<<"). Radius "<<radius<<", Length "<<length;
00179   theBarrelLayers[mbp] = MuonEtaRange(eta_max, eta_min);
00180 
00181 }
00182 
00183 
00184 //
00185 // create forwrad/backward layer maps
00186 //
00187 void MuonTkNavigationSchool::addEndcapLayer(ForwardDetLayer* mep) {
00188 
00189   const BoundDisk& bd = mep->specificSurface();
00190   float outRadius = bd.outerRadius();
00191   float inRadius = bd.innerRadius();
00192   float thick = bd.bounds().length()/2.;
00193   float z = bd.position().z();
00194 
00195   if ( z > 0. ) {
00196     float eta_min = calculateEta(outRadius, z-thick);
00197     float eta_max = calculateEta(inRadius, z+thick);
00198     edm::LogInfo("MuonTkNavigationSchool")<<"ForwardLayer eta: ("<<eta_min<<", "<<eta_max<<"). Radius ("<<inRadius<<", "<<outRadius<<"), Z "<<z;
00199     theForwardLayers[mep] = MuonEtaRange(eta_max, eta_min);
00200   } else {
00201     float eta_max = calculateEta(outRadius, z+thick);
00202     float eta_min = calculateEta(inRadius, z-thick);
00203     edm::LogInfo("MuonTkNavigationSchool")<<"BackwardLayer eta: ("<<eta_min<<", "<<eta_max<<"). Radius ("<<inRadius<<", "<<outRadius<<"), Z "<<z;
00204     theBackwardLayers[mep] = MuonEtaRange(eta_max, eta_min);
00205   }
00206 
00207 }
00208 
00209 
00210 //
00211 //
00212 //
00213 void MuonTkNavigationSchool::linkBarrelLayers() {
00214 
00215   for (MapBI bl  = theBarrelLayers.begin(); bl != theBarrelLayers.end(); bl++) {
00216 
00217     MuonEtaRange range = (*bl).second;
00218 
00219     float length = fabs((*bl).first->specificSurface().bounds().length()/2.);
00220     // first add next barrel layer
00221     MapBI plusOne(bl);
00222     plusOne++;
00223     MapB outerBarrel;
00224     MapB allOuterBarrel;
00225     if ( plusOne != theBarrelLayers.end() ) { outerBarrel.insert(*plusOne); }
00226     // add all outer barrel layers
00227     for ( MapBI iMBI = plusOne; iMBI!= theBarrelLayers.end(); iMBI++) {
00228       allOuterBarrel.insert(*iMBI);
00229     }
00230     // then add all compatible backward layers with an eta criteria
00231     MapE allOuterBackward;
00232     for (MapEI el  = theBackwardLayers.begin();
00233                el != theBackwardLayers.end(); el++) {
00234       if ( (*el).second.isCompatible(range) ) {
00235         float z = (*el).first->specificSurface().position().z();
00236         if (fabs(z) < length) continue;
00237         allOuterBackward.insert(*el);
00238       }
00239     }
00240 
00241     // add the backward next layer with an eta criteria
00242     MapE outerBackward;
00243     for (MapEI el  = theBackwardLayers.begin();
00244                el != theBackwardLayers.end(); el++) {
00245       if ( (*el).second.isCompatible(range) ) {
00246         float z = (*el).first->specificSurface().position().z();
00247         if (fabs(z) < length) continue;
00248         outerBackward.insert(*el);
00249         break;
00250       }
00251     }
00252 
00253     // then add all compatible forward layers with an eta criteria
00254     MapE allOuterForward;
00255     for (MapEI el  = theForwardLayers.begin();
00256                el != theForwardLayers.end(); el++) {
00257       if ( (*el).second.isCompatible(range) ) {
00258         float z = (*el).first->specificSurface().position().z();
00259         if (fabs(z) < length) continue;
00260         allOuterForward.insert(*el);
00261       }
00262     }
00263 
00264     // then add forward next layer with an eta criteria
00265     MapE outerForward;
00266     for (MapEI el  = theForwardLayers.begin();
00267                el != theForwardLayers.end(); el++) {
00268       if ( (*el).second.isCompatible(range) ) {
00269         float z = (*el).first->specificSurface().position().z();
00270         if (fabs(z) < length) continue;
00271         outerForward.insert(*el);
00272         break;
00273       }
00274     }
00275 
00276     // first add next inner barrel layer
00277     MapBI minusOne(bl);
00278     MapB innerBarrel;
00279     MapB allInnerBarrel;
00280     MapE allInnerBackward;
00281     MapE innerBackward;
00282     MapE allInnerForward;
00283     MapE innerForward;
00284 
00285     if ( bl != theBarrelLayers.begin() ) {
00286       minusOne--;
00287       innerBarrel.insert(*minusOne);
00288         // add all inner barrel layers
00289       for ( MapBI iMBI = minusOne; iMBI != theBarrelLayers.begin(); iMBI--) {
00290         allInnerBarrel.insert(*iMBI);
00291       }
00292       allInnerBarrel.insert(*theBarrelLayers.begin());
00293 
00294       // then add all compatible backward layers with an eta criteria
00295       for (MapEI el  = theBackwardLayers.end();
00296                  el != theBackwardLayers.begin(); el--) {
00297         if (el == theBackwardLayers.end()) continue;  //C.L @@: no -/+ for map iterator
00298         if ( (*el).second.isCompatible(range) ) {
00299           float z = (*el).first->specificSurface().position().z();
00300           if (fabs(z) > length) continue;
00301           allInnerBackward.insert(*el);
00302         }
00303       }
00304       MapEI el = theBackwardLayers.begin();
00305       if (el->second.isCompatible(range)) {
00306         float z = (*el).first->specificSurface().position().z();
00307         if (fabs(z) < length) {
00308           allInnerBackward.insert(*el);
00309         }
00310       }
00311 
00312       // then add all compatible forward layers with an eta criteria
00313       for (MapEI el  = theForwardLayers.end();
00314                  el != theForwardLayers.begin(); el--) {
00315         if (el == theForwardLayers.end()) continue;
00316         if ( (*el).second.isCompatible(range) ) {
00317           float z = (*el).first->specificSurface().position().z();
00318           if (fabs(z) > length) continue;
00319           allInnerForward.insert(*el);
00320         }
00321       }
00322 
00323       el = theForwardLayers.begin();
00324       if (el->second.isCompatible(range)) {
00325         float z = (*el).first->specificSurface().position().z();
00326         if (fabs(z) < length)  {
00327           allInnerForward.insert(*el);
00328         }
00329       }
00330 
00331       if ( !range.isInside((*minusOne).second) ) {
00332         MuonEtaRange backwardRange(range.min(), (*minusOne).second.min());
00333         MuonEtaRange forwardRange((*minusOne).second.max(),range.max());
00334 
00335         // add the backward next layer with an eta criteria
00336         for (MapEI el  = theBackwardLayers.end();
00337                    el != theBackwardLayers.begin(); el--) {
00338           if ( el == theBackwardLayers.end() ) continue; 
00339           if ( (*el).second.isCompatible(backwardRange) ) {
00340             float z = (*el).first->specificSurface().position().z();
00341             if (fabs(z) > length) continue;
00342             innerBackward.insert(*el);
00343             backwardRange = backwardRange.subtract((*el).second);
00344           }
00345         }
00346 
00347         MapEI el = theBackwardLayers.begin();
00348         if (el->second.isCompatible(backwardRange)) {
00349           float z = (*el).first->specificSurface().position().z();
00350           if (fabs(z) < length)  {
00351             innerBackward.insert(*el);
00352           }
00353         }
00354       
00355         // then add forward next layer with an eta criteria
00356         for (MapEI el  = theForwardLayers.end();
00357                    el != theForwardLayers.begin(); el--) {
00358           if ( el == theForwardLayers.end() ) continue; 
00359           if ( (*el).second.isCompatible(forwardRange) ) {
00360             float z = (*el).first->specificSurface().position().z();
00361             if (fabs(z) > length) continue;
00362             innerForward.insert(*el);
00363             forwardRange = forwardRange.subtract((*el).second);
00364 
00365           }
00366         }
00367         el = theForwardLayers.begin();
00368         if (el->second.isCompatible(forwardRange)) {
00369           float z = (*el).first->specificSurface().position().z();
00370           if (fabs(z) < length) innerForward.insert(*el);
00371         }
00372       }
00373     }
00374 
00375     BarrelDetLayer* mbp = (*bl).first;
00376     if ( mbp->subDetector() == GeomDetEnumerators::DT || mbp->subDetector() == GeomDetEnumerators::RPCBarrel ) {
00377       theMuonBarrelNLC.push_back(new MuonBarrelNavigableLayer(mbp,
00378                                                               outerBarrel, 
00379                                                               innerBarrel, 
00380                                                               outerBackward, 
00381                                                               outerForward, 
00382                                                               innerBackward, 
00383                                                               innerForward, 
00384                                                               allOuterBarrel,
00385                                                               allInnerBarrel, 
00386                                                               allOuterBackward,
00387                                                               allOuterForward, 
00388                                                               allInnerBackward, 
00389                                                               allInnerForward));
00390     }                                                          
00391     else if ( mbp->subDetector() == GeomDetEnumerators::PixelBarrel || mbp->subDetector() == GeomDetEnumerators::TIB || mbp->subDetector() == GeomDetEnumerators::TOB ) {
00392       BDLC outerBarrelLayers;
00393       BDLC innerBarrelLayers;
00394       BDLC allOuterBarrelLayers;
00395       BDLC allInnerBarrelLayers;
00396       FDLC outerBackwardLayers;
00397       FDLC outerForwardLayers;
00398       FDLC allOuterBackwardLayers;
00399       FDLC allOuterForwardLayers;
00400       FDLC innerBackwardLayers;
00401       FDLC innerForwardLayers;
00402       FDLC allInnerBackwardLayers;
00403       FDLC allInnerForwardLayers;
00404 
00405      for (MapBI ib = outerBarrel.begin(); ib != outerBarrel.end(); ib++) {
00406        BarrelDetLayer* ibdl = (*ib).first;
00407        outerBarrelLayers.push_back(ibdl);
00408      }
00409 
00410      for (MapBI ib = innerBarrel.begin(); ib != innerBarrel.end(); ib++) {
00411        BarrelDetLayer* ibdl = (*ib).first;
00412        innerBarrelLayers.push_back(ibdl);
00413      }
00414    
00415      for (MapBI ib = allOuterBarrel.begin(); ib != allOuterBarrel.end(); ib++) {
00416        BarrelDetLayer* ibdl = (*ib).first;
00417        allOuterBarrelLayers.push_back(ibdl);
00418      }
00419 
00420      for (MapBI ib = allInnerBarrel.begin(); ib != allInnerBarrel.end(); ib++) {
00421        BarrelDetLayer* ibdl = (*ib).first;
00422        allInnerBarrelLayers.push_back(ibdl);
00423      }
00424 
00425      for (MapEI ie = outerBackward.begin(); ie != outerBackward.end(); ie++) {
00426        ForwardDetLayer* ifdl = (*ie).first;
00427        outerBackwardLayers.push_back(ifdl);
00428      }
00429 
00430      for (MapEI ie = outerForward.begin(); ie != outerForward.end(); ie++) {
00431        ForwardDetLayer* ifdl = (*ie).first;
00432        outerForwardLayers.push_back(ifdl);
00433      }
00434 
00435      for (MapEI ie = allOuterBackward.begin(); ie != allOuterBackward.end(); ie++) {
00436        ForwardDetLayer* ifdl = (*ie).first;
00437        allOuterBackwardLayers.push_back(ifdl);
00438      }
00439 
00440      for (MapEI ie = allOuterForward.begin(); ie != allOuterForward.end(); ie++) {
00441        ForwardDetLayer* ifdl = (*ie).first;
00442        allOuterForwardLayers.push_back(ifdl);
00443      }
00444 
00445      for (MapEI ie = innerBackward.begin(); ie != innerBackward.end(); ie++) {
00446        ForwardDetLayer* ifdl = (*ie).first;
00447        innerBackwardLayers.push_back(ifdl);
00448      }
00449 
00450      for (MapEI ie = innerForward.begin(); ie != innerForward.end(); ie++) {
00451        ForwardDetLayer* ifdl = (*ie).first;
00452        innerForwardLayers.push_back(ifdl);
00453      }
00454 
00455      for (MapEI ie = allInnerBackward.begin(); ie != allInnerBackward.end(); ie++) {
00456        ForwardDetLayer* ifdl = (*ie).first;
00457        allInnerBackwardLayers.push_back(ifdl);
00458      }
00459 
00460      for (MapEI ie = allInnerForward.begin(); ie != allInnerForward.end(); ie++) {
00461        ForwardDetLayer* ifdl = (*ie).first;
00462        allInnerForwardLayers.push_back(ifdl);
00463      }
00464 
00465      theTkBarrelNLC.push_back(new SimpleBarrelNavigableLayer(mbp,outerBarrelLayers,
00466                                                                  innerBarrelLayers, 
00467                                                                  allOuterBarrelLayers, 
00468                                                                  allInnerBarrelLayers,
00469                                                                  outerBackwardLayers, 
00470                                                                  outerForwardLayers, 
00471                                                                  allOuterBackwardLayers, 
00472                                                                  allOuterForwardLayers, 
00473                                                                  innerBackwardLayers, 
00474                                                                  innerForwardLayers, 
00475                                                                  allInnerBackwardLayers, 
00476                                                                  allInnerForwardLayers,
00477                                                                  theMagneticField, 5.));
00478 
00479     }
00480 
00481   }
00482 
00483 }
00484 
00485 
00486 //
00487 //
00488 //
00489 void MuonTkNavigationSchool::linkEndcapLayers(const MapE& layers,
00490                                               std::vector<MuonForwardNavigableLayer*>& resultM, 
00491                                               std::vector<SimpleForwardNavigableLayer*>& resultT) {
00492 
00493   for (MapEI el = layers.begin(); el != layers.end(); el++) {
00494 
00495     MuonEtaRange range = (*el).second;
00496     float z = (*el).first->specificSurface().position().z();
00497     // first add next endcap layer (if compatible)
00498     MapEI plusOne(el); 
00499     plusOne++;
00500     MuonEtaRange tempR(range);
00501     MuonEtaRange secondOR(range);
00502     MapEI outerOne(plusOne);
00503     bool outerDoubleCheck = false;
00504     MapE outerELayers;
00505     if ( plusOne != layers.end()) {
00506         for ( MapEI l = plusOne; l != layers.end(); l++ ) {
00507           if ( (*l).second.isCompatible(tempR)) {
00508             outerELayers.insert(*l);
00509             if ( tempR.isInside((*l).second) ) break;
00510             if ((*l).second.isInside(tempR)) {
00511                   // split into 2 pieces
00512                   outerOne = l;
00513                   outerOne++;
00514                   if (tempR.max() > 0 ) {
00515                     secondOR = MuonEtaRange(tempR.max(),(*l).second.max());
00516                     tempR = MuonEtaRange((*l).second.min(),tempR.min());
00517                   }else {
00518                     secondOR = MuonEtaRange((*l).second.min(),tempR.min());
00519                     tempR = MuonEtaRange(tempR.max(),(*l).second.max());
00520                   }
00521                   outerDoubleCheck = true;
00522                   break;
00523              }
00524             tempR = tempR.subtract((*l).second);
00525           } //if ( (*l).second.isCompatible(tempR))
00526       }//for
00527 
00528       if (outerDoubleCheck) {
00529         for ( MapEI l = outerOne; l != layers.end(); l++ ) {
00530           if ( (*l).second.isCompatible(tempR)) {
00531             outerELayers.insert(*l);
00532             if ( tempR.isInside((*l).second) ) break;
00533             tempR = tempR.subtract((*l).second);
00534           } //if ( (*l).second.isCompatible(tempR))
00535         }//for
00536 
00537         for ( MapEI l = outerOne; l != layers.end(); l++ ) {
00538           if ( (*l).second.isCompatible(secondOR)) {
00539             outerELayers.insert(*l);
00540             if ( secondOR.isInside((*l).second) ) break;
00541             secondOR = secondOR.subtract((*l).second);
00542           } //if ( (*l).second.isCompatible(tempR))
00543         }//for
00544       }
00545     }//if end
00546 
00547     MapE allOuterELayers;
00548     for (MapEI iMEI = plusOne; iMEI!=layers.end(); iMEI++){
00549       if ((*iMEI).second.isCompatible(range)) allOuterELayers.insert(*iMEI);
00550     }
00551     // to avoid overlap
00552     int i = 0;
00553     bool hasOverlap = false; 
00554     MapB outerBLayers; 
00555     MapB allOuterBLayers;
00556     for (MapBI iMBI = theBarrelLayers.begin(); iMBI!=theBarrelLayers.end(); iMBI++){
00557       if ((*iMBI).second.isCompatible(tempR)) {
00558         float length = fabs((*iMBI).first->specificSurface().bounds().length()/2.);
00559         if (length > fabs(z)) {
00560            if ( (i==0) && (tempR.isInside((*iMBI).second)) ) hasOverlap = true;
00561            i++;
00562            outerBLayers.insert(*iMBI);
00563            if (tempR.isInside((*iMBI).second)) break;
00564            tempR = tempR.subtract((*iMBI).second);
00565          }
00566        }
00567     }
00568 
00569     for (MapBI iMBI = theBarrelLayers.begin(); iMBI!=theBarrelLayers.end(); iMBI++){
00570       float length = fabs((*iMBI).first->specificSurface().bounds().length()/2.);
00571       if (length < fabs(z)) continue; 
00572       if ((*iMBI).second.isCompatible(range)) allOuterBLayers.insert(*iMBI);
00573     }
00574 
00575     MapE innerELayers;
00576     MapE allInnerELayers;
00577     MapB innerBLayers;
00578     MapB allInnerBLayers;
00579     MuonEtaRange itempR(range);
00580     bool checkFurther = true;
00581     bool doubleCheck = false;
00582     MuonEtaRange secondR;
00583     float outRadius = 0;
00584     MapEI minusOne(el);
00585     if (el != layers.begin()) {
00586       minusOne--;
00587       outRadius = minusOne->first->specificSurface().outerRadius();
00588       MapEI innerOne;
00589       for (MapEI iMEI = minusOne; iMEI!=layers.begin(); iMEI--){
00590         if ( (*iMEI).second.isCompatible(itempR) ) {
00591           innerELayers.insert(*iMEI);
00592 
00593           if (itempR.isInside((*iMEI).second)) { checkFurther = false; break; }
00594           if ((*iMEI).second.isInside(itempR)) { 
00595                   // split into 2 pieces
00596                   doubleCheck = true; 
00597                   innerOne = iMEI; 
00598                   innerOne--; 
00599                   if (itempR.max() > 0 ) {
00600                     secondR = MuonEtaRange(itempR.max(),(*iMEI).second.max());
00601                     itempR = MuonEtaRange((*iMEI).second.min(),itempR.min());
00602                   }else {
00603                     itempR = MuonEtaRange(itempR.max(),(*iMEI).second.max());
00604                     secondR = MuonEtaRange((*iMEI).second.min(),itempR.min());
00605                   }
00606                   break; 
00607             }
00608           else itempR = itempR.subtract((*iMEI).second);  
00609         }//if ( (*iMEI).second.isCompatible(itempR) ) 
00610       }//for MapEI
00611       if (doubleCheck ) {
00612 
00613         for (MapEI iMEI = innerOne; iMEI!=layers.begin(); iMEI--){
00614           if ( (*iMEI).second.isCompatible(itempR) ) {
00615             innerELayers.insert(*iMEI);
00616             if (itempR.isInside((*iMEI).second)) { checkFurther = false; break; }
00617             else itempR = itempR.subtract((*iMEI).second);
00618           }//if ( (*iMEI).second.isCompatible(itempR) )
00619         }//for MapEI
00620 
00621         for (MapEI iMEI = innerOne; iMEI!=layers.begin(); iMEI--){
00622           if ( (*iMEI).second.isCompatible(secondR) ) {
00623             innerELayers.insert(*iMEI);
00624             if (secondR.isInside((*iMEI).second)) { checkFurther = false; break; }
00625             else secondR = secondR.subtract((*iMEI).second);
00626           }//if ( (*iMEI).second.isCompatible(itempR) )
00627         }//for MapEI
00628       }// if doubleCheck
00629 
00630       if (checkFurther && (*layers.begin()).second.isCompatible(itempR)) {
00631           innerELayers.insert(*layers.begin());
00632           itempR = itempR.subtract((*layers.begin()).second);
00633        }
00634 
00635       for (MapEI iMEI = minusOne; iMEI!=layers.begin(); iMEI--) {
00636         if ((*iMEI).second.isCompatible(range)) allInnerELayers.insert(*iMEI);
00637       }
00638       if ((*layers.begin()).second.isCompatible(range)) allInnerELayers.insert(*layers.begin());
00639     } 
00640     
00641 
00642     for (MapBI iMBI = theBarrelLayers.end(); iMBI!=theBarrelLayers.begin(); iMBI--) {
00643       if (iMBI == theBarrelLayers.end()) continue;
00644       float length = fabs((*iMBI).first->specificSurface().bounds().length()/2.);
00645       if (length > fabs(z)) continue;
00646       if ((*iMBI).second.isCompatible(range)) allInnerBLayers.insert(*iMBI);
00647     }
00648     if ((*theBarrelLayers.begin()).second.isCompatible(range)) allInnerBLayers.insert(*theBarrelLayers.begin());
00649 
00650     int k = 0;
00651     bool hasOverlap2 = false;
00652     bool hasInsideE = false;
00653     for (MapBI iMBI = theBarrelLayers.end(); iMBI!=theBarrelLayers.begin(); iMBI--) {
00654       if (iMBI == theBarrelLayers.end()) continue;
00655       float length = fabs((*iMBI).first->specificSurface().bounds().length()/2.);
00656       if (length > fabs(z)) continue;
00657       float radius = (*iMBI).first->specificSurface().radius();
00658 
00659       bool compatible = false;
00660       if (radius > outRadius) { 
00661              compatible = (*iMBI).second.isCompatible(range);
00662              if (compatible && outRadius > 40) hasInsideE = true;//CL: no general rule
00663       }
00664       else compatible = (*iMBI).second.isCompatible(itempR);
00665       if (!checkFurther && (radius < outRadius)) break;
00666       if (compatible) {
00667         if ((k==0) && (itempR.isInside((*iMBI).second)) && (radius < outRadius)) hasOverlap2 = true;
00668         if (radius < outRadius) k++;
00669         innerBLayers.insert(*iMBI);
00670         if (itempR.isInside((*iMBI).second) && (radius < outRadius)) break;
00671         itempR = itempR.subtract((*iMBI).second);
00672        }
00673     }
00674     
00675     if (el == layers.begin() && (*theBarrelLayers.begin()).second.isCompatible(itempR)) innerBLayers.insert(*theBarrelLayers.begin());
00676     
00677     ForwardDetLayer* mbp = (*el).first;
00678     if ( mbp->subDetector() == GeomDetEnumerators::CSC || mbp->subDetector() == GeomDetEnumerators::RPCEndcap ) {
00679       resultM.push_back(new MuonForwardNavigableLayer(mbp, 
00680                                                       innerBLayers, 
00681                                                       outerELayers, 
00682                                                       innerELayers, 
00683                                                       allInnerBLayers, 
00684                                                       allOuterELayers, 
00685                                                       allInnerELayers));
00686     }
00687     else if ( mbp->subDetector() == GeomDetEnumerators::PixelEndcap || mbp->subDetector() == GeomDetEnumerators::TEC || mbp->subDetector() ==  GeomDetEnumerators::TID ) {
00688       BDLC outerBarrelLayers;
00689       FDLC outerForwardLayers;
00690       BDLC allOuterBarrelLayers;
00691       FDLC allOuterForwardLayers;
00692       BDLC innerBarrelLayers;
00693       FDLC innerForwardLayers;
00694       BDLC allInnerBarrelLayers;
00695       FDLC allInnerForwardLayers;
00696 
00697      unsigned int j = 0;
00698      unsigned int l = 0;
00699      unsigned int m = 0;
00700 
00701      for (MapBI ib = outerBLayers.begin(); ib != outerBLayers.end(); ib++) {
00702        BarrelDetLayer* ibdl = (*ib).first;
00703        outerBarrelLayers.push_back(ibdl);
00704      }
00705 
00706      for (MapEI ie = outerELayers.begin(); ie != outerELayers.end(); ie++) {
00707        j++;
00708        if ( hasOverlap && j==outerELayers.size() ) break; 
00709        ForwardDetLayer* ifdl = (*ie).first;
00710        outerForwardLayers.push_back(ifdl);
00711      }
00712 
00713      for (MapBI ib = allOuterBLayers.begin(); ib != allOuterBLayers.end(); ib++) {
00714        BarrelDetLayer* ibdl = (*ib).first;
00715        allOuterBarrelLayers.push_back(ibdl);
00716      }
00717 
00718      for (MapEI ie = allOuterELayers.begin(); ie != allOuterELayers.end(); ie++) {
00719        ForwardDetLayer* ifdl = (*ie).first;
00720        allOuterForwardLayers.push_back(ifdl);
00721      }
00722 
00723      for (MapBI ib = innerBLayers.begin(); ib != innerBLayers.end(); ib++) {
00724        l++;
00725        if (hasOverlap2 && l==innerBLayers.size() ) continue;
00726        BarrelDetLayer* ibdl = (*ib).first;
00727        innerBarrelLayers.push_back(ibdl);
00728      }
00729 
00730      for (MapEI ie = innerELayers.begin(); ie != innerELayers.end(); ie++) {
00731        m++;
00732        if (hasInsideE && m==innerELayers.size()-2 ) continue;
00733        ForwardDetLayer* ifdl = (*ie).first;
00734        innerForwardLayers.push_back(ifdl);
00735      }
00736 
00737      for (MapBI ib = allInnerBLayers.begin(); ib != allInnerBLayers.end(); ib++) {
00738        BarrelDetLayer* ibdl = (*ib).first;
00739        allInnerBarrelLayers.push_back(ibdl);
00740      }
00741 
00742      for (MapEI ie = allInnerELayers.begin(); ie != allInnerELayers.end(); ie++) {
00743        ForwardDetLayer* ifdl = (*ie).first;
00744        allInnerForwardLayers.push_back(ifdl);
00745      }
00746 
00747      resultT.push_back(new SimpleForwardNavigableLayer(mbp, 
00748                                                        outerBarrelLayers,
00749                                                        allOuterBarrelLayers, 
00750                                                        innerBarrelLayers, 
00751                                                        allInnerBarrelLayers, 
00752                                                        outerForwardLayers,
00753                                                        allOuterForwardLayers, 
00754                                                        innerForwardLayers, 
00755                                                        allInnerForwardLayers,
00756                                                        theMagneticField, 5.));
00757     }
00758 
00759   }
00760 
00761 }
00762 
00763 
00764 //
00765 // calculate the length of the barrel
00766 //
00767 float MuonTkNavigationSchool::barrelLength() const {
00768 
00769   float length = 0.0;
00770   for (MapBI i= theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
00771     if ((*i).first->subDetector() != GeomDetEnumerators::PixelBarrel && (*i).first->subDetector() != GeomDetEnumerators::TIB && (*i).first->subDetector() != GeomDetEnumerators::TOB) continue;
00772     length = max(length,(*i).first->surface().bounds().length()/2.f);
00773   }
00774 
00775   return length;
00776 
00777 }
00778 
00779 
00780 //
00781 // calculate pseudorapidity from r and z
00782 //
00783 float MuonTkNavigationSchool::calculateEta(float r, float z) const {
00784 
00785   if ( z > 0 ) return -log((tan(atan(r/z)/2.)));
00786   return log(-(tan(atan(r/z)/2.)));
00787 
00788 }