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
00036
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
00041 theBarrelLayers.push_back( (*i) );
00042 theDetLayers.push_back( (*i) );
00043 }
00044 }
00045
00046
00047
00048
00049
00050
00051
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
00056 theForwardLayers.push_back( (*i) );
00057 theDetLayers.push_back( (*i) );
00058 }
00059 }
00060
00061
00062
00063 FDLI middle = find_if( theForwardLayers.begin(), theForwardLayers.end(),
00064 not1(DetBelowZ(0)));
00065
00066 theLeftLayers = FDLC( theForwardLayers.begin(), middle);
00067
00068 theRightLayers = FDLC( middle, theForwardLayers.end());
00069
00070 SymmetricLayerFinder symFinder( theForwardLayers);
00071
00072
00073 linkBarrelLayers( symFinder);
00074
00075 linkForwardLayers( symFinder);
00076
00077 establishInverseRelations();
00078
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
00100 for ( BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
00101 BDLC reachableBL;
00102 FDLC leftFL;
00103 FDLC rightFL;
00104
00105
00106 if ( i+1 != theBarrelLayers.end()) reachableBL.push_back(*(i+1));
00107
00108
00109 if (i != theBarrelLayers.end() - 1) {
00110 linkNextForwardLayer( *i, rightFL);
00111 }
00112
00113
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
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
00134
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
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
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
00183 linkNextBarrelLayer( *i, reachableBL);
00184
00185
00186
00187 linkNextLayerInGroup( i, *group, reachableFL);
00188
00189
00190 if ( group+1 != groups.end()) {
00191 linkOuterGroup( *i, *(group+1), reachableFL);
00192 }
00193
00194
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
00211
00212
00213
00214
00215
00216
00217
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
00230
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
00246 if ( fli+1 != group.end()) {
00247 reachableFL.push_back( *(fli+1));
00248
00249
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
00256
00257
00258 int i = 2;
00259 while ( (fli+i) != group.end()) {
00260 if ( (**(fli+i)).specificSurface().innerRadius() <
00261 innerRNext + epsilon) {
00262
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
00280
00281 ConstFDLI first = find_if( group.begin(), group.end(),
00282 not1( DetBelowZ( fl->position().z())));
00283 if ( first != group.end()) {
00284
00285
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
00319
00320 FDLC myRightLayers( theRightLayers);
00321 FDLI begin = myRightLayers.begin();
00322 FDLI end = myRightLayers.end();
00323
00324
00325 sort ( begin, end, DiskLessInnerRadius());
00326
00327
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
00339 if ( (**i).specificSurface().innerRadius() >
00340 (**(i-1)).specificSurface().outerRadius()) {
00341
00342 LogDebug("TkNavigation") << "found break between groups" ;
00343
00344
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);
00353
00354
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
00381
00382 typedef map<const DetLayer*, vector<BarrelDetLayer*>, less<const DetLayer*> > BarrelMapType;
00383 typedef map<const DetLayer*, vector<ForwardDetLayer*>, less<const DetLayer*> > ForwardMapType;
00384
00385
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
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
00407
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
00414 }
00415