CMS 3D CMS Logo

SimpleNavigationSchool.cc

Go to the documentation of this file.
00001 #include "RecoTracker/TkNavigation/interface/SimpleNavigationSchool.h"
00002 
00003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00004 
00005 #include "RecoTracker/TkNavigation/interface/SimpleBarrelNavigableLayer.h"
00006 #include "RecoTracker/TkNavigation/interface/SimpleForwardNavigableLayer.h"
00007 #include "RecoTracker/TkNavigation/interface/SimpleNavigableLayer.h"
00008 #include "RecoTracker/TkNavigation/interface/DiskLessInnerRadius.h"
00009 #include "RecoTracker/TkNavigation/interface/SymmetricLayerFinder.h"
00010 
00011 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
00012 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
00013 #include "TrackingTools/DetLayers/src/DetBelowZ.h"
00014 #include "TrackingTools/DetLayers/src/DetLessZ.h"
00015 #include "TrackingTools/DetLayers/interface/NavigationSetter.h"
00016 
00017 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
00018 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
00019 
00020 #include "Utilities/General/interface/CMSexception.h"
00021 
00022 #include <functional>
00023 #include <algorithm>
00024 #include <map>
00025 #include <cmath>
00026 
00027 using namespace std;
00028 
00029 SimpleNavigationSchool::SimpleNavigationSchool(const GeometricSearchTracker* theInputTracker,
00030                                                const MagneticField* field) : 
00031   theBarrelLength(0),theField(field), theTracker(theInputTracker)
00032 {
00033 
00034   theAllDetLayersInSystem=&theInputTracker->allLayers();
00035 
00036   // Get barrel layers
00037   vector<BarrelDetLayer*> blc = theTracker->barrelLayers(); 
00038   for ( vector<BarrelDetLayer*>::iterator i = blc.begin(); i != blc.end(); i++) {
00039     theBarrelLayers.push_back( (*i) );
00040   }
00041 
00042   // get forward layers
00043   vector<ForwardDetLayer*> flc = theTracker->forwardLayers(); 
00044   for ( vector<ForwardDetLayer*>::iterator i = flc.begin(); i != flc.end(); i++) {
00045     theForwardLayers.push_back( (*i) );
00046   }
00047   
00048   FDLI middle = find_if( theForwardLayers.begin(), theForwardLayers.end(),
00049                          not1(DetBelowZ(0)));
00050   theLeftLayers  = FDLC( theForwardLayers.begin(), middle);
00051   theRightLayers = FDLC( middle, theForwardLayers.end());
00052   
00053   SymmetricLayerFinder symFinder( theForwardLayers);
00054 
00055   // only work on positive Z side; negative by mirror symmetry later
00056   linkBarrelLayers( symFinder);
00057   linkForwardLayers( symFinder);
00058   establishInverseRelations();
00059 }
00060 
00061 SimpleNavigationSchool::StateType 
00062 SimpleNavigationSchool::navigableLayers() const
00063 {
00064   StateType result;
00065   for ( vector< SimpleBarrelNavigableLayer*>::const_iterator 
00066           ib = theBarrelNLC.begin(); ib != theBarrelNLC.end(); ib++) {
00067     result.push_back( *ib);
00068   }
00069   for ( vector< SimpleForwardNavigableLayer*>::const_iterator 
00070           ifl = theForwardNLC.begin(); ifl != theForwardNLC.end(); ifl++) {
00071     result.push_back( *ifl);
00072   }
00073   return result;
00074 }
00075 
00076 void SimpleNavigationSchool::
00077 linkBarrelLayers( SymmetricLayerFinder& symFinder)
00078 {
00079   // Link barrel layers outwards
00080   for ( BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
00081     BDLC reachableBL;
00082     FDLC leftFL;
00083     FDLC rightFL;
00084 
00085     // always add next barrel layer first
00086     if ( i+1 != theBarrelLayers.end()) reachableBL.push_back(*(i+1));
00087  
00088     // Add closest reachable forward layer (except for last BarrelLayer)
00089     if (i != theBarrelLayers.end() - 1) {
00090       linkNextForwardLayer( *i, rightFL);
00091     }
00092 
00093     // Add next BarrelLayer with length larger than the current BL
00094     if ( i+2 < theBarrelLayers.end()) {
00095       linkNextLargerLayer( i, theBarrelLayers.end(), reachableBL);
00096     }
00097 
00098     theBarrelNLC.push_back( new 
00099        SimpleBarrelNavigableLayer( *i, reachableBL,
00100                                    symFinder.mirror(rightFL),
00101                                    rightFL,theField, 5.));
00102   }
00103 }
00104 
00105 void SimpleNavigationSchool::linkNextForwardLayer( BarrelDetLayer* bl, 
00106                                                    FDLC& rightFL)
00107 {
00108   // find first forward layer with larger Z and larger outer radius
00109   float length = bl->surface().bounds().length() / 2.;
00110   float radius = bl->specificSurface().radius();
00111   for ( FDLI fli = theRightLayers.begin();
00112         fli != theRightLayers.end(); fli++) {
00113     if ( length < (**fli).position().z() &&
00114          radius < (**fli).specificSurface().outerRadius()) {
00115       rightFL.push_back( *fli);
00116       return;
00117     }
00118   }
00119 }
00120 
00121 void SimpleNavigationSchool::linkNextLargerLayer( BDLI bli, BDLI end,
00122                                                   BDLC& reachableBL)
00123 {
00124   // compare length of next layer with length of following ones
00125   float length = (**(bli+1)).surface().bounds().length();
00126   float epsilon = 0.1;
00127 
00128   for ( BDLI i = bli+2; i < end; i++) {
00129     if ( length + epsilon < (**i).surface().bounds().length()) {
00130       reachableBL.push_back( *i);
00131       return;
00132     }
00133   }
00134 }
00135 
00136 void SimpleNavigationSchool::
00137 linkForwardLayers( SymmetricLayerFinder& symFinder)
00138 {
00139 
00140   // handle right side first, groups are only on the right 
00141   vector<FDLC> groups = splitForwardLayers();
00142 
00143   LogDebug("TkNavigation") << "SimpleNavigationSchool, Forward groups size = " << groups.size() ;
00144   for (vector<FDLC>::iterator g = groups.begin(); g != groups.end(); g++) {
00145     LogDebug("TkNavigation") << "group " << g - groups.begin() << " has " 
00146                              << g->size() << " layers " ;
00147   }
00148 
00149   for ( vector<FDLC>::iterator group = groups.begin();
00150         group != groups.end(); group++) {
00151 
00152     for ( FDLI i = group->begin(); i != group->end(); i++) {
00153 
00154       BDLC reachableBL;
00155       FDLC reachableFL;
00156  
00157       // Always connect to next barrel layer first, if exists
00158       linkNextBarrelLayer( *i, reachableBL);
00159 
00160       // Then always connect to next forward layer of "same" size, 
00161       // and layers of larger inner Radius
00162       linkNextLayerInGroup( i, *group, reachableFL);
00163 
00164       // Then connect to next N fw layers of next size
00165       if ( group+1 != groups.end()) {
00166         linkOuterGroup( *i, *(group+1), reachableFL);
00167       }
00168 
00169       // or connect within the group if outer radius increases
00170       linkWithinGroup( i, *group, reachableFL);
00171 
00172       theForwardNLC.push_back( new SimpleForwardNavigableLayer( *i,reachableBL,
00173                                                                 reachableFL,
00174                                                                 theField,
00175                                                                 5.));
00176       theForwardNLC.push_back( new SimpleForwardNavigableLayer( symFinder.mirror(*i),
00177                                                                 reachableBL,
00178                                                                 symFinder.mirror(reachableFL),
00179                                                                 theField,
00180                                                                 5.));
00181 
00182     }
00183   }
00184 
00185 //    // now the left side by symmetry
00186 //    for ( FDLI ileft = theLeftLayers.begin(); 
00187 //      ileft != theLeftLayers.end(); ileft++) {
00188 //      ForwardDetLayer* right = symFinder.mirror( *ileft);
00189     
00190 //      theForwardNLC.push_back( new 
00191 //         SimpleForwardNavigableLayer( *ileft , right->nextBarrelLayers(),
00192 //                            symFinder.mirror(right->nextForwardLayers())));
00193 //    }
00194 }
00195 
00196 void SimpleNavigationSchool::linkNextBarrelLayer( ForwardDetLayer* fl,
00197                                                   BDLC& reachableBL)
00198 {
00199   if ( fl->position().z() > barrelLength()) return;
00200 
00201   float outerRadius = fl->specificSurface().outerRadius();
00202   float zpos        = fl->position().z();
00203   for ( BDLI bli = theBarrelLayers.begin(); bli != theBarrelLayers.end(); bli++) {
00204     if ( outerRadius < (**bli).specificSurface().radius() &&
00205          zpos        < (**bli).surface().bounds().length() / 2.) {
00206       reachableBL.push_back( *bli);
00207       return;
00208     }
00209   }
00210 }
00211 
00212 
00213 void SimpleNavigationSchool::linkNextLayerInGroup( FDLI fli,
00214                                                    const FDLC& group,
00215                                                    FDLC& reachableFL)
00216 {
00217   // Always connect to next forward layer of "same" size, if exists
00218   if ( fli+1 != group.end()) {
00219     reachableFL.push_back( *(fli+1));
00220     // If that layer has an inner radius larger then the current one
00221     // also connect ALL next disks of same radius.
00222     float innerRThis = (**fli).specificSurface().innerRadius();
00223     float innerRNext =  (**(fli+1)).specificSurface().innerRadius();
00224     const float epsilon = 2.f;
00225 
00226     if (innerRNext > innerRThis + epsilon) {
00227       // next disk is smaller, so it doesn't cover fully subsequent ones
00228       // of same radius
00229 
00230       int i = 2;
00231       while ( (fli+i) != group.end()) {
00232         if ( (**(fli+i)).specificSurface().innerRadius() < 
00233              innerRNext + epsilon) {
00234           // following disk has not increased in ineer radius 
00235           reachableFL.push_back( *(fli+i));
00236           i++;
00237         } else {
00238           break;
00239         }
00240       }
00241     }
00242   }
00243 }
00244 
00245 
00246 void SimpleNavigationSchool::linkOuterGroup( ForwardDetLayer* fl,
00247                                              const FDLC& group,
00248                                              FDLC& reachableFL)
00249 {
00250 
00251   // insert N layers with Z grater than fl
00252 
00253   ConstFDLI first = find_if( group.begin(), group.end(), 
00254                              not1( DetBelowZ( fl->position().z())));
00255   if ( first != group.end()) {
00256 
00257     // Hard-wired constant!!!!!!
00258     ConstFDLI last = min( first + 7, group.end());
00259 
00260     reachableFL.insert( reachableFL.end(), first, last);
00261   }
00262 }
00263 
00264 void SimpleNavigationSchool::linkWithinGroup( FDLI fl,
00265                                               const FDLC& group,
00266                                               FDLC& reachableFL)
00267 {
00268   ConstFDLI biggerLayer = outerRadiusIncrease( fl, group);
00269   if ( biggerLayer != group.end() && biggerLayer != fl+1) {
00270     reachableFL.push_back( *biggerLayer);
00271   }
00272 }
00273 
00274 SimpleNavigationSchool::ConstFDLI
00275 SimpleNavigationSchool::outerRadiusIncrease( FDLI fl, const FDLC& group)
00276 {
00277   const float epsilon = 5.f;
00278   float outerRadius = (**fl).specificSurface().outerRadius();
00279   while ( ++fl != group.end()) {
00280     if ( (**fl).specificSurface().outerRadius() > outerRadius + epsilon) {
00281       return fl;
00282     }
00283   }
00284   return fl;
00285 }
00286 
00287 vector<SimpleNavigationSchool::FDLC> 
00288 SimpleNavigationSchool::splitForwardLayers() 
00289 {
00290   // only work on positive Z side; negative by mirror symmetry later
00291 
00292   FDLC myRightLayers( theRightLayers);
00293   FDLI begin = myRightLayers.begin();
00294   FDLI end   = myRightLayers.end();
00295 
00296   // sort according to inner radius
00297   sort ( begin, end, DiskLessInnerRadius()); 
00298 
00299   // partition in cylinders
00300   vector<FDLC> result;
00301   FDLC current;
00302   current.push_back( *begin);
00303   for ( FDLI i = begin+1; i != end; i++) {
00304 
00305     LogDebug("TkNavigation") << "(**i).specificSurface().innerRadius()      = "
00306                              << (**i).specificSurface().innerRadius() << endl
00307                              << "(**(i-1)).specificSurface().outerRadius()) = "
00308                              << (**(i-1)).specificSurface().outerRadius() ;
00309 
00310     // if inner radius of i is larger than outer radius of i-1 then split!
00311     if ( (**i).specificSurface().innerRadius() > 
00312          (**(i-1)).specificSurface().outerRadius()) {
00313 
00314       LogDebug("TkNavigation") << "found break between groups" ;
00315 
00316       // sort layers in group along Z
00317       sort ( current.begin(), current.end(), DetLessZ());
00318 
00319       result.push_back(current);
00320       current.clear();
00321     }
00322     current.push_back(*i);
00323   }
00324   result.push_back(current); // save last one too 
00325 
00326   // now sort subsets in Z
00327   for ( vector<FDLC>::iterator ivec = result.begin();
00328         ivec != result.end(); ivec++) {
00329     sort( ivec->begin(), ivec->end(), DetLessZ());
00330   }
00331 
00332   return result;
00333 }
00334 
00335 float SimpleNavigationSchool::barrelLength() 
00336 {
00337   if ( theBarrelLength < 1.) {
00338     for (BDLI i=theBarrelLayers.begin(); i!=theBarrelLayers.end(); i++) {
00339       theBarrelLength = max( theBarrelLength,
00340                              (**i).surface().bounds().length() / 2.f);
00341     }
00342 
00343     LogDebug("TkNavigation") << "The barrel length is " << theBarrelLength ;
00344   }
00345   return theBarrelLength;
00346 }
00347 
00348 void SimpleNavigationSchool::establishInverseRelations() {
00349 
00350   NavigationSetter setter(*this);
00351 
00352     // find for each layer which are the barrel and forward
00353     // layers that point to it
00354     typedef map<const DetLayer*, vector<BarrelDetLayer*>, less<const DetLayer*> > BarrelMapType;
00355     typedef map<const DetLayer*, vector<ForwardDetLayer*>, less<const DetLayer*> > ForwardMapType;
00356 
00357 
00358     BarrelMapType reachedBarrelLayersMap;
00359     ForwardMapType reachedForwardLayersMap;
00360 
00361 
00362     for ( BDLI bli = theBarrelLayers.begin();
00363         bli!=theBarrelLayers.end(); bli++) {
00364       DLC reachedLC = (**bli).nextLayers( insideOut);
00365       for ( DLI i = reachedLC.begin(); i != reachedLC.end(); i++) {
00366         reachedBarrelLayersMap[*i].push_back( *bli);
00367       }
00368     }
00369 
00370     for ( FDLI fli = theForwardLayers.begin();
00371         fli!=theForwardLayers.end(); fli++) {
00372       DLC reachedLC = (**fli).nextLayers( insideOut);
00373       for ( DLI i = reachedLC.begin(); i != reachedLC.end(); i++) {
00374         reachedForwardLayersMap[*i].push_back( *fli);
00375       }
00376     }
00377 
00378 
00379     vector<DetLayer*> lc = theTracker->allLayers();
00380     for ( vector<DetLayer*>::iterator i = lc.begin(); i != lc.end(); i++) {
00381       SimpleNavigableLayer* navigableLayer =
00382         dynamic_cast<SimpleNavigableLayer*>((**i).navigableLayer());
00383       navigableLayer->setInwardLinks( reachedBarrelLayersMap[*i],reachedForwardLayersMap[*i] );
00384     }
00385     
00386 }
00387 

Generated on Tue Jun 9 17:45:56 2009 for CMSSW by  doxygen 1.5.4