CMS 3D CMS Logo

HICSimpleNavigationSchool.cc

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

Generated on Tue Jun 9 17:43:37 2009 for CMSSW by  doxygen 1.5.4