CMS 3D CMS Logo

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