CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/RecoHI/HiMuonAlgos/src/HICSimpleNavigationSchool.cc

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