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
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
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
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
00080 for ( BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
00081 BDLC reachableBL;
00082 FDLC leftFL;
00083 FDLC rightFL;
00084
00085
00086 if ( i+1 != theBarrelLayers.end()) reachableBL.push_back(*(i+1));
00087
00088
00089 if (i != theBarrelLayers.end() - 1) {
00090 linkNextForwardLayer( *i, rightFL);
00091 }
00092
00093
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
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
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
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
00158 linkNextBarrelLayer( *i, reachableBL);
00159
00160
00161
00162 linkNextLayerInGroup( i, *group, reachableFL);
00163
00164
00165 if ( group+1 != groups.end()) {
00166 linkOuterGroup( *i, *(group+1), reachableFL);
00167 }
00168
00169
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
00186
00187
00188
00189
00190
00191
00192
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
00218 if ( fli+1 != group.end()) {
00219 reachableFL.push_back( *(fli+1));
00220
00221
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
00228
00229
00230 int i = 2;
00231 while ( (fli+i) != group.end()) {
00232 if ( (**(fli+i)).specificSurface().innerRadius() <
00233 innerRNext + epsilon) {
00234
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
00252
00253 ConstFDLI first = find_if( group.begin(), group.end(),
00254 not1( DetBelowZ( fl->position().z())));
00255 if ( first != group.end()) {
00256
00257
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
00291
00292 FDLC myRightLayers( theRightLayers);
00293 FDLI begin = myRightLayers.begin();
00294 FDLI end = myRightLayers.end();
00295
00296
00297 sort ( begin, end, DiskLessInnerRadius());
00298
00299
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
00311 if ( (**i).specificSurface().innerRadius() >
00312 (**(i-1)).specificSurface().outerRadius()) {
00313
00314 LogDebug("TkNavigation") << "found break between groups" ;
00315
00316
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);
00325
00326
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
00353
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