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 "FWCore/Utilities/interface/Exception.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 void SimpleNavigationSchool::cleanMemory(){
00062
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
00094 for ( BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
00095 BDLC reachableBL;
00096 FDLC leftFL;
00097 FDLC rightFL;
00098
00099
00100 if ( i+1 != theBarrelLayers.end()) reachableBL.push_back(*(i+1));
00101
00102
00103 if (i != theBarrelLayers.end() - 1) {
00104 linkNextForwardLayer( *i, rightFL);
00105 }
00106
00107
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
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
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
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
00172 linkNextBarrelLayer( *i, reachableBL);
00173
00174
00175
00176 linkNextLayerInGroup( i, *group, reachableFL);
00177
00178
00179 if ( group+1 != groups.end()) {
00180 linkOuterGroup( *i, *(group+1), reachableFL);
00181 }
00182
00183
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
00200
00201
00202
00203
00204
00205
00206
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
00232 if ( fli+1 != group.end()) {
00233 reachableFL.push_back( *(fli+1));
00234
00235
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
00242
00243
00244 int i = 2;
00245 while ( (fli+i) != group.end()) {
00246 if ( (**(fli+i)).specificSurface().innerRadius() <
00247 innerRNext + epsilon) {
00248
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
00266
00267 ConstFDLI first = find_if( group.begin(), group.end(),
00268 not1( DetBelowZ( fl->position().z())));
00269 if ( first != group.end()) {
00270
00271
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
00305
00306 FDLC myRightLayers( theRightLayers);
00307 FDLI begin = myRightLayers.begin();
00308 FDLI end = myRightLayers.end();
00309
00310
00311 sort ( begin, end, DiskLessInnerRadius());
00312
00313
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
00325 if ( (**i).specificSurface().innerRadius() >
00326 (**(i-1)).specificSurface().outerRadius()) {
00327
00328 LogDebug("TkNavigation") << "found break between groups" ;
00329
00330
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);
00339
00340
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
00367
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