Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-06 12:28:52

0001 #include "SimpleNavigationSchool.h"
0002 
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 
0005 #include "SimpleBarrelNavigableLayer.h"
0006 #include "SimpleForwardNavigableLayer.h"
0007 #include "SimpleNavigableLayer.h"
0008 #include "SymmetricLayerFinder.h"
0009 
0010 #include "TrackingTools/DetLayers/interface/BarrelDetLayer.h"
0011 #include "TrackingTools/DetLayers/interface/ForwardDetLayer.h"
0012 #include "TrackingTools/DetLayers/interface/DetLessZ.h"
0013 
0014 #include "DataFormats/GeometrySurface/interface/BoundCylinder.h"
0015 #include "DataFormats/GeometrySurface/interface/BoundDisk.h"
0016 
0017 #include "FWCore/Utilities/interface/Exception.h"
0018 
0019 #include <algorithm>
0020 #include <map>
0021 #include <cmath>
0022 
0023 using namespace std;
0024 
0025 void SimpleNavigationSchool::init() {
0026   theAllDetLayersInSystem = &theTracker->allLayers();
0027   theAllNavigableLayer.resize(theTracker->allLayers().size(), nullptr);
0028 
0029   // Get barrel layers
0030   for (auto i : theTracker->barrelLayers()) {
0031     theBarrelLayers.push_back(i);
0032   }
0033 
0034   // get forward layers
0035   for (auto i : theTracker->forwardLayers()) {
0036     theForwardLayers.push_back(i);
0037   }
0038 
0039   FDLI middle = find_if(theForwardLayers.begin(), theForwardLayers.end(), [](const GeometricSearchDet* a) {
0040     return a->position().z() >= 0.0;
0041   });
0042   theLeftLayers = FDLC(theForwardLayers.begin(), middle);
0043   theRightLayers = FDLC(middle, theForwardLayers.end());
0044 
0045   SymmetricLayerFinder symFinder(theForwardLayers);
0046 
0047   // only work on positive Z side; negative by mirror symmetry later
0048   linkBarrelLayers(symFinder);
0049   linkForwardLayers(symFinder);
0050   establishInverseRelations();
0051 }
0052 
0053 void SimpleNavigationSchool::cleanMemory() {
0054   // free the memory allocated to the SimpleNavigableLayers
0055   for (vector<SimpleBarrelNavigableLayer*>::const_iterator ib = theBarrelNLC.begin(); ib != theBarrelNLC.end(); ib++) {
0056     delete (*ib);
0057   }
0058   theBarrelNLC.clear();
0059   for (vector<SimpleForwardNavigableLayer*>::const_iterator ifl = theForwardNLC.begin(); ifl != theForwardNLC.end();
0060        ifl++) {
0061     delete (*ifl);
0062   }
0063   theForwardNLC.clear();
0064 }
0065 
0066 SimpleNavigationSchool::StateType SimpleNavigationSchool::navigableLayers() {
0067   StateType result;
0068   for (vector<SimpleBarrelNavigableLayer*>::const_iterator ib = theBarrelNLC.begin(); ib != theBarrelNLC.end(); ib++) {
0069     result.push_back(*ib);
0070   }
0071   for (vector<SimpleForwardNavigableLayer*>::const_iterator ifl = theForwardNLC.begin(); ifl != theForwardNLC.end();
0072        ifl++) {
0073     result.push_back(*ifl);
0074   }
0075   return result;
0076 }
0077 
0078 void SimpleNavigationSchool::linkBarrelLayers(SymmetricLayerFinder& symFinder) {
0079   // Link barrel layers outwards
0080   for (BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
0081     BDLC reachableBL;
0082     FDLC leftFL;
0083     FDLC rightFL;
0084 
0085     //always add next barrel layer first
0086     if (i + 1 != theBarrelLayers.end()) {
0087       reachableBL.push_back(*(i + 1));
0088     }
0089 
0090     // Add closest reachable forward layer (except for last BarrelLayer)
0091     if (i != theBarrelLayers.end() - 1) {
0092       linkNextForwardLayer(*i, rightFL);
0093     }
0094 
0095     // Add next BarrelLayer with length larger than the current BL
0096     if (i + 2 < theBarrelLayers.end()) {
0097       linkNextLargerLayer(i, theBarrelLayers.end(), reachableBL);
0098     }
0099 
0100     theBarrelNLC.push_back(
0101         new SimpleBarrelNavigableLayer(*i, reachableBL, symFinder.mirror(rightFL), rightFL, theField, 5.));
0102   }
0103 }
0104 
0105 void SimpleNavigationSchool::linkNextForwardLayer(const BarrelDetLayer* bl, FDLC& rightFL) {
0106   // find first forward layer with larger Z and larger outer radius
0107   float length = bl->surface().bounds().length() / 2.;
0108   float radius = bl->specificSurface().radius();
0109   for (FDLI fli = theRightLayers.begin(); fli != theRightLayers.end(); fli++) {
0110     if (length < (**fli).position().z() && radius < (**fli).specificSurface().outerRadius()) {
0111       //search if there are any sovrapposition between forward layers
0112       for (FDLI fliNext = fli; fliNext != theRightLayers.end(); fliNext++) {
0113         if ((**fliNext).position().z() < (**fli).position().z() &&
0114             (**fliNext).specificSurface().innerRadius() < (**fli).specificSurface().outerRadius()) {
0115           rightFL.push_back(*fliNext);
0116           return;
0117         }
0118       }
0119       rightFL.push_back(*fli);
0120       return;
0121     }
0122   }
0123 }
0124 
0125 void SimpleNavigationSchool::linkNextLargerLayer(BDLI bli, BDLI end, BDLC& reachableBL) {
0126   // compare length of next layer with length of following ones
0127   float length = (**(bli + 1)).surface().bounds().length();
0128   float epsilon = 0.1;
0129 
0130   for (BDLI i = bli + 2; i < end; i++) {
0131     if (length + epsilon < (**i).surface().bounds().length()) {
0132       reachableBL.push_back(*i);
0133       return;
0134     }
0135   }
0136 }
0137 
0138 void SimpleNavigationSchool::linkForwardLayers(SymmetricLayerFinder& symFinder) {
0139   // handle right side first, groups are only on the right
0140   vector<FDLC> groups = splitForwardLayers();
0141 
0142   LogDebug("TkNavigation") << "SimpleNavigationSchool, Forward groups size = " << groups.size();
0143   for (vector<FDLC>::iterator g = groups.begin(); g != groups.end(); g++) {
0144     LogDebug("TkNavigation") << "group " << g - groups.begin() << " has " << g->size() << " layers ";
0145   }
0146 
0147   for (vector<FDLC>::iterator group = groups.begin(); group != groups.end(); group++) {
0148     for (FDLI i = group->begin(); i != group->end(); i++) {
0149       BDLC reachableBL;
0150       FDLC reachableFL;
0151 
0152       // Always connect to next barrel layer first, if exists
0153       linkNextBarrelLayer(*i, reachableBL);
0154 
0155       // Then always connect to next forward layer of "same" size,
0156       // and layers of larger inner Radius
0157       linkNextLayerInGroup(i, *group, reachableFL);
0158 
0159       // Then connect to next N fw layers of next size
0160       if (group + 1 != groups.end()) {
0161         linkOuterGroup(*i, *(group + 1), reachableFL);
0162       }
0163 
0164       // or connect within the group if outer radius increases
0165       linkWithinGroup(i, *group, reachableFL);
0166 
0167       theForwardNLC.push_back(new SimpleForwardNavigableLayer(*i, reachableBL, reachableFL, theField, 5.));
0168       theForwardNLC.push_back(new SimpleForwardNavigableLayer(
0169           symFinder.mirror(*i), reachableBL, symFinder.mirror(reachableFL), theField, 5.));
0170     }
0171   }
0172 
0173   //    // now the left side by symmetry
0174   //    for ( FDLI ileft = theLeftLayers.begin();
0175   //    ileft != theLeftLayers.end(); ileft++) {
0176   //      ForwardDetLayer* right = symFinder.mirror( *ileft);
0177 
0178   //      theForwardNLC.push_back( new
0179   //         SimpleForwardNavigableLayer( *ileft , right->nextBarrelLayers(),
0180   //                          symFinder.mirror(right->nextForwardLayers())));
0181   //    }
0182 }
0183 
0184 void SimpleNavigationSchool::linkNextBarrelLayer(const ForwardDetLayer* fl, BDLC& reachableBL) {
0185   if (fl->position().z() > barrelLength())
0186     return;
0187 
0188   float outerRadius = fl->specificSurface().outerRadius();
0189   float zpos = fl->position().z();
0190   for (BDLI bli = theBarrelLayers.begin(); bli != theBarrelLayers.end(); bli++) {
0191     if (outerRadius < (**bli).specificSurface().radius() && zpos < (**bli).surface().bounds().length() / 2.) {
0192       reachableBL.push_back(*bli);
0193       return;
0194     }
0195   }
0196 }
0197 
0198 void SimpleNavigationSchool::linkNextLayerInGroup(FDLI fli, const FDLC& group, FDLC& reachableFL) {
0199   // Always connect to next forward layer of "same" size, if exists
0200   if (fli + 1 != group.end()) {
0201     reachableFL.push_back(*(fli + 1));
0202     // If that layer has an inner radius larger then the current one
0203     // also connect ALL next disks of same radius.
0204     float innerRThis = (**fli).specificSurface().innerRadius();
0205     float innerRNext = (**(fli + 1)).specificSurface().innerRadius();
0206     const float epsilon = 2.f;
0207 
0208     if (innerRNext > innerRThis + epsilon) {
0209       // next disk is smaller, so it doesn't cover fully subsequent ones
0210       // of same radius
0211 
0212       int i = 2;
0213       while ((fli + i) != group.end()) {
0214         if ((**(fli + i)).specificSurface().innerRadius() < innerRNext + epsilon) {
0215           // following disk has not increased in ineer radius
0216           reachableFL.push_back(*(fli + i));
0217           i++;
0218         } else {
0219           break;
0220         }
0221       }
0222     }
0223   }
0224 }
0225 
0226 void SimpleNavigationSchool::linkOuterGroup(const ForwardDetLayer* fl, const FDLC& group, FDLC& reachableFL) {
0227   // insert N layers with Z grater than fl
0228 
0229   ConstFDLI first = find_if(group.begin(), group.end(), [fl](const GeometricSearchDet* a) {
0230     return a->position().z() >= fl->position().z();
0231   });
0232   if (first != group.end()) {
0233     // Hard-wired constant!!!!!!
0234     ConstFDLI last = min(first + 7, group.end());
0235 
0236     reachableFL.insert(reachableFL.end(), first, last);
0237   }
0238 }
0239 
0240 void SimpleNavigationSchool::linkWithinGroup(FDLI fl, const FDLC& group, FDLC& reachableFL) {
0241   ConstFDLI biggerLayer = outerRadiusIncrease(fl, group);
0242   if (biggerLayer != group.end() && biggerLayer != fl + 1) {
0243     reachableFL.push_back(*biggerLayer);
0244   }
0245 }
0246 
0247 SimpleNavigationSchool::ConstFDLI SimpleNavigationSchool::outerRadiusIncrease(FDLI fl, const FDLC& group) {
0248   const float epsilon = 5.f;
0249   float outerRadius = (**fl).specificSurface().outerRadius();
0250   while (++fl != group.end()) {
0251     if ((**fl).specificSurface().outerRadius() > outerRadius + epsilon) {
0252       return fl;
0253     }
0254   }
0255   return fl;
0256 }
0257 
0258 vector<SimpleNavigationSchool::FDLC> SimpleNavigationSchool::splitForwardLayers() {
0259   // only work on positive Z side; negative by mirror symmetry later
0260 
0261   FDLC myRightLayers(theRightLayers);
0262   FDLI begin = myRightLayers.begin();
0263   FDLI end = myRightLayers.end();
0264 
0265   // sort according to inner radius, but keeping the ordering in z!
0266   std::stable_sort(begin, end, [](const ForwardDetLayer* a, const ForwardDetLayer* b) {
0267     return a->specificSurface().innerRadius() < b->specificSurface().innerRadius();
0268   });
0269 
0270   // partition in cylinders
0271   vector<FDLC> result;
0272   FDLC current;
0273   current.push_back(*begin);
0274   for (FDLI i = begin + 1; i != end; i++) {
0275 #ifdef EDM_ML_DEBUG
0276     LogDebug("TkNavigation") << "(**i).specificSurface().innerRadius()      = " << (**i).specificSurface().innerRadius()
0277                              << endl
0278                              << "(**(i-1)).specificSurface().outerRadius()) = "
0279                              << (**(i - 1)).specificSurface().outerRadius();
0280     LogDebug("TkNavigation") << "(**i).specificSurface().position().z()      = "
0281                              << (**i).specificSurface().position().z() << endl
0282                              << "(**(i-1)).specificSurface().position().z() = "
0283                              << (**(i - 1)).specificSurface().position().z();
0284 #endif
0285 
0286     // if inner radius of i is larger than outer radius of i-1 then split!
0287     // FIXME: The solution found for phase2 is a bit dirty, we can do better.
0288     // For phase2 we compare the EXTENDED pixel with the TID to get the assignment right!
0289     if ((**i).specificSurface().innerRadius() > (**(i - 1)).specificSurface().outerRadius() ||
0290         (theTracker->posPixelForwardLayers().back()->specificSurface().position().z() >
0291              theTracker->posTidLayers().front()->specificSurface().position().z() &&
0292          (**i).specificSurface().position().z() < (**(i - 1)).specificSurface().position().z())) {
0293       LogDebug("TkNavigation") << "found break between groups";
0294 
0295       // sort layers in group along Z
0296       std::stable_sort(current.begin(), current.end(), isDetLessZ);
0297 
0298       result.push_back(current);
0299       current.clear();
0300     }
0301     current.push_back(*i);
0302   }
0303   result.push_back(current);  // save last one too
0304 
0305   // now sort subsets in Z
0306   for (vector<FDLC>::iterator ivec = result.begin(); ivec != result.end(); ivec++) {
0307     std::stable_sort(ivec->begin(), ivec->end(), isDetLessZ);
0308   }
0309 
0310   return result;
0311 }
0312 
0313 float SimpleNavigationSchool::barrelLength() {
0314   if (theBarrelLength < 1.) {
0315     for (BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
0316       theBarrelLength = max(theBarrelLength, (**i).surface().bounds().length() / 2.f);
0317     }
0318 
0319     LogDebug("TkNavigation") << "The barrel length is " << theBarrelLength;
0320   }
0321   return theBarrelLength;
0322 }
0323 
0324 void SimpleNavigationSchool::establishInverseRelations() {
0325   // NavigationSetter setter(*this);
0326 
0327   setState(navigableLayers());
0328 
0329   // find for each layer which are the barrel and forward
0330   // layers that point to it
0331   typedef map<const DetLayer*, vector<const BarrelDetLayer*>, less<const DetLayer*> > BarrelMapType;
0332   typedef map<const DetLayer*, vector<const ForwardDetLayer*>, less<const DetLayer*> > ForwardMapType;
0333 
0334   BarrelMapType reachedBarrelLayersMap;
0335   ForwardMapType reachedForwardLayersMap;
0336 
0337   for (auto bli : theBarrelLayers) {
0338     auto reachedLC = nextLayers(*bli, insideOut);
0339     for (auto i : reachedLC) {
0340       reachedBarrelLayersMap[i].push_back(bli);
0341     }
0342   }
0343 
0344   for (auto fli : theForwardLayers) {
0345     auto reachedLC = nextLayers(*fli, insideOut);
0346     for (auto i : reachedLC) {
0347       reachedForwardLayersMap[i].push_back(fli);
0348     }
0349   }
0350 
0351   /*
0352     vector<DetLayer*> lc = theTracker->allLayers();
0353     for ( vector<DetLayer*>::iterator i = lc.begin(); i != lc.end(); i++) {
0354       SimpleNavigableLayer* navigableLayer =
0355     dynamic_cast<SimpleNavigableLayer*>((**i).navigableLayer());
0356       navigableLayer->setInwardLinks( reachedBarrelLayersMap[*i],reachedForwardLayersMap[*i] );
0357     }
0358     */
0359 
0360   for (auto nl : theAllNavigableLayer) {
0361     if (!nl)
0362       continue;
0363     auto navigableLayer = static_cast<SimpleNavigableLayer*>(nl);
0364     auto dl = nl->detLayer();
0365     navigableLayer->setInwardLinks(reachedBarrelLayersMap[dl], reachedForwardLayersMap[dl]);
0366   }
0367 }
0368 
0369 #include "FWCore/PluginManager/interface/ModuleDef.h"
0370 #include "FWCore/Framework/interface/MakerMacros.h"
0371 
0372 #include "NavigationSchoolFactory.h"
0373 #include "TrackingTools/DetLayers/interface/NavigationSchool.h"
0374 DEFINE_EDM_PLUGIN(NavigationSchoolFactory, SimpleNavigationSchool, "SimpleNavigationSchool");