CMS 3D CMS Logo

SimpleNavigationSchool.cc
Go to the documentation of this file.
2 
4 
7 #include "SimpleNavigableLayer.h"
8 #include "DiskLessInnerRadius.h"
9 #include "SymmetricLayerFinder.h"
10 
15 // #include "TrackingTools/DetLayers/interface/NavigationSetter.h"
16 
19 
21 
22 #include <functional>
23 #include <algorithm>
24 #include <map>
25 #include <cmath>
26 
27 using namespace std;
28 
30  const MagneticField* field) :
31  theBarrelLength(0),theField(field), theTracker(theInputTracker)
32 {
33 
34  theAllDetLayersInSystem=&theInputTracker->allLayers();
35  theAllNavigableLayer.resize(theInputTracker->allLayers().size(),nullptr);
36 
37 
38  // Get barrel layers
39  for( auto i : theTracker->barrelLayers()) {
40  theBarrelLayers.push_back( i );
41  }
42 
43  // get forward layers
44  for( auto i : theTracker->forwardLayers()) {
45  theForwardLayers.push_back( i );
46  }
47 
48  FDLI middle = find_if( theForwardLayers.begin(), theForwardLayers.end(),
49  not1(DetBelowZ(0)));
50  theLeftLayers = FDLC( theForwardLayers.begin(), middle);
51  theRightLayers = FDLC( middle, theForwardLayers.end());
52 
54 
55  // only work on positive Z side; negative by mirror symmetry later
56  linkBarrelLayers( symFinder);
57  linkForwardLayers( symFinder);
59 }
60 
62  // free the memory allocated to the SimpleNavigableLayers
63  for ( vector< SimpleBarrelNavigableLayer*>::const_iterator
64  ib = theBarrelNLC.begin(); ib != theBarrelNLC.end(); ib++) {
65  delete (*ib);
66  }
67  theBarrelNLC.clear();
68  for ( vector< SimpleForwardNavigableLayer*>::const_iterator
69  ifl = theForwardNLC.begin(); ifl != theForwardNLC.end(); ifl++) {
70  delete (*ifl);
71  }
72  theForwardNLC.clear();
73 }
74 
77 {
79  for ( vector< SimpleBarrelNavigableLayer*>::const_iterator
80  ib = theBarrelNLC.begin(); ib != theBarrelNLC.end(); ib++) {
81  result.push_back( *ib);
82  }
83  for ( vector< SimpleForwardNavigableLayer*>::const_iterator
84  ifl = theForwardNLC.begin(); ifl != theForwardNLC.end(); ifl++) {
85  result.push_back( *ifl);
86  }
87  return result;
88 }
89 
92 {
93  // Link barrel layers outwards
94  for ( BDLI i = theBarrelLayers.begin(); i != theBarrelLayers.end(); i++) {
95  BDLC reachableBL;
96  FDLC leftFL;
97  FDLC rightFL;
98 
99  // always add next barrel layer first
100  if ( i+1 != theBarrelLayers.end()) reachableBL.push_back(*(i+1));
101 
102  // Add closest reachable forward layer (except for last BarrelLayer)
103  if (i != theBarrelLayers.end() - 1) {
104  linkNextForwardLayer( *i, rightFL);
105  }
106 
107  // Add next BarrelLayer with length larger than the current BL
108  if ( i+2 < theBarrelLayers.end()) {
109  linkNextLargerLayer( i, theBarrelLayers.end(), reachableBL);
110  }
111 
112  theBarrelNLC.push_back( new
113  SimpleBarrelNavigableLayer( *i, reachableBL,
114  symFinder.mirror(rightFL),
115  rightFL,theField, 5.));
116  }
117 }
118 
120  FDLC& rightFL)
121 {
122  // find first forward layer with larger Z and larger outer radius
123  float length = bl->surface().bounds().length() / 2.;
124  float radius = bl->specificSurface().radius();
125  for ( FDLI fli = theRightLayers.begin();
126  fli != theRightLayers.end(); fli++) {
127  if ( length < (**fli).position().z() &&
128  radius < (**fli).specificSurface().outerRadius()) {
129  //search if there are any sovrapposition between forward layers
130  for ( FDLI fliNext = fli; fliNext != theRightLayers.end(); fliNext++) {
131  if ( (**fliNext).position().z() < (**fli).position().z() && (**fliNext).specificSurface().innerRadius() < (**fli).specificSurface().outerRadius()) {
132  rightFL.push_back( *fliNext);
133  return;
134  }
135  }
136  rightFL.push_back( *fli);
137  return;
138  }
139  }
140 }
141 
143  BDLC& reachableBL)
144 {
145  // compare length of next layer with length of following ones
146  float length = (**(bli+1)).surface().bounds().length();
147  float epsilon = 0.1;
148 
149  for ( BDLI i = bli+2; i < end; i++) {
150  if ( length + epsilon < (**i).surface().bounds().length()) {
151  reachableBL.push_back( *i);
152  return;
153  }
154  }
155 }
156 
159 {
160 
161  // handle right side first, groups are only on the right
162  vector<FDLC> groups = splitForwardLayers();
163 
164  LogDebug("TkNavigation") << "SimpleNavigationSchool, Forward groups size = " << groups.size() ;
165  for (vector<FDLC>::iterator g = groups.begin(); g != groups.end(); g++) {
166  LogDebug("TkNavigation") << "group " << g - groups.begin() << " has "
167  << g->size() << " layers " ;
168  }
169 
170  for ( vector<FDLC>::iterator group = groups.begin();
171  group != groups.end(); group++) {
172 
173  for ( FDLI i = group->begin(); i != group->end(); i++) {
174 
175  BDLC reachableBL;
176  FDLC reachableFL;
177 
178  // Always connect to next barrel layer first, if exists
179  linkNextBarrelLayer( *i, reachableBL);
180 
181  // Then always connect to next forward layer of "same" size,
182  // and layers of larger inner Radius
183  linkNextLayerInGroup( i, *group, reachableFL);
184 
185  // Then connect to next N fw layers of next size
186  if ( group+1 != groups.end()) {
187  linkOuterGroup( *i, *(group+1), reachableFL);
188  }
189 
190  // or connect within the group if outer radius increases
191  linkWithinGroup( i, *group, reachableFL);
192 
193  theForwardNLC.push_back( new SimpleForwardNavigableLayer( *i,reachableBL,
194  reachableFL,
195  theField,
196  5.));
197  theForwardNLC.push_back( new SimpleForwardNavigableLayer( symFinder.mirror(*i),
198  reachableBL,
199  symFinder.mirror(reachableFL),
200  theField,
201  5.));
202 
203  }
204  }
205 
206 // // now the left side by symmetry
207 // for ( FDLI ileft = theLeftLayers.begin();
208 // ileft != theLeftLayers.end(); ileft++) {
209 // ForwardDetLayer* right = symFinder.mirror( *ileft);
210 
211 // theForwardNLC.push_back( new
212 // SimpleForwardNavigableLayer( *ileft , right->nextBarrelLayers(),
213 // symFinder.mirror(right->nextForwardLayers())));
214 // }
215 }
216 
218  BDLC& reachableBL)
219 {
220  if ( fl->position().z() > barrelLength()) return;
221 
222  float outerRadius = fl->specificSurface().outerRadius();
223  float zpos = fl->position().z();
224  for ( BDLI bli = theBarrelLayers.begin(); bli != theBarrelLayers.end(); bli++) {
225  if ( outerRadius < (**bli).specificSurface().radius() &&
226  zpos < (**bli).surface().bounds().length() / 2.) {
227  reachableBL.push_back( *bli);
228  return;
229  }
230  }
231 }
232 
233 
235  const FDLC& group,
236  FDLC& reachableFL)
237 {
238  // Always connect to next forward layer of "same" size, if exists
239  if ( fli+1 != group.end()) {
240  reachableFL.push_back( *(fli+1));
241  // If that layer has an inner radius larger then the current one
242  // also connect ALL next disks of same radius.
243  float innerRThis = (**fli).specificSurface().innerRadius();
244  float innerRNext = (**(fli+1)).specificSurface().innerRadius();
245  const float epsilon = 2.f;
246 
247  if (innerRNext > innerRThis + epsilon) {
248  // next disk is smaller, so it doesn't cover fully subsequent ones
249  // of same radius
250 
251  int i = 2;
252  while ( (fli+i) != group.end()) {
253  if ( (**(fli+i)).specificSurface().innerRadius() <
254  innerRNext + epsilon) {
255  // following disk has not increased in ineer radius
256  reachableFL.push_back( *(fli+i));
257  i++;
258  } else {
259  break;
260  }
261  }
262  }
263  }
264 }
265 
266 
268  const FDLC& group,
269  FDLC& reachableFL)
270 {
271 
272  // insert N layers with Z grater than fl
273 
274  ConstFDLI first = find_if( group.begin(), group.end(),
275  not1( DetBelowZ( fl->position().z())));
276  if ( first != group.end()) {
277 
278  // Hard-wired constant!!!!!!
279  ConstFDLI last = min( first + 7, group.end());
280 
281  reachableFL.insert( reachableFL.end(), first, last);
282  }
283 }
284 
286  const FDLC& group,
287  FDLC& reachableFL)
288 {
289  ConstFDLI biggerLayer = outerRadiusIncrease( fl, group);
290  if ( biggerLayer != group.end() && biggerLayer != fl+1) {
291  reachableFL.push_back( *biggerLayer);
292  }
293 }
294 
297 {
298  const float epsilon = 5.f;
299  float outerRadius = (**fl).specificSurface().outerRadius();
300  while ( ++fl != group.end()) {
301  if ( (**fl).specificSurface().outerRadius() > outerRadius + epsilon) {
302  return fl;
303  }
304  }
305  return fl;
306 }
307 
308 vector<SimpleNavigationSchool::FDLC>
310 {
311  // only work on positive Z side; negative by mirror symmetry later
312 
313  FDLC myRightLayers( theRightLayers);
314  FDLI begin = myRightLayers.begin();
315  FDLI end = myRightLayers.end();
316 
317  // sort according to inner radius, but keeping the ordering in z!
318  stable_sort ( begin, end, DiskLessInnerRadius());
319 
320  // partition in cylinders
321  vector<FDLC> result;
322  FDLC current;
323  current.push_back( *begin);
324  for ( FDLI i = begin+1; i != end; i++) {
325 
326 #ifdef EDM_ML_DEBUG
327  LogDebug("TkNavigation") << "(**i).specificSurface().innerRadius() = "
328  << (**i).specificSurface().innerRadius() << endl
329  << "(**(i-1)).specificSurface().outerRadius()) = "
330  << (**(i-1)).specificSurface().outerRadius() ;
331  LogDebug("TkNavigation") << "(**i).specificSurface().position().z() = "
332  << (**i).specificSurface().position().z() << endl
333  << "(**(i-1)).specificSurface().position().z() = "
334  << (**(i-1)).specificSurface().position().z() ;
335 #endif
336 
337  // if inner radius of i is larger than outer radius of i-1 then split!
338  // FIXME: The solution found for phase2 is a bit dirty, we can do better.
339  // For phase2 we compare the EXTENDED pixel with the TID to get the assignment right!
340  if ( (**i).specificSurface().innerRadius() > (**(i-1)).specificSurface().outerRadius() ||
341  (theTracker->posPixelForwardLayers().back()->specificSurface().position().z() > theTracker->posTidLayers().front()->specificSurface().position().z() &&
342  (**i).specificSurface().position().z() < (**(i-1)).specificSurface().position().z()) ){
343 
344  LogDebug("TkNavigation") << "found break between groups" ;
345 
346  // sort layers in group along Z
347  stable_sort ( current.begin(), current.end(), DetLessZ());
348 
349  result.push_back(current);
350  current.clear();
351  }
352  current.push_back(*i);
353  }
354  result.push_back(current); // save last one too
355 
356  // now sort subsets in Z
357  for ( vector<FDLC>::iterator ivec = result.begin();
358  ivec != result.end(); ivec++) {
359  stable_sort( ivec->begin(), ivec->end(), DetLessZ());
360  }
361 
362  return result;
363 }
364 
366 {
367  if ( theBarrelLength < 1.) {
368  for (BDLI i=theBarrelLayers.begin(); i!=theBarrelLayers.end(); i++) {
370  (**i).surface().bounds().length() / 2.f);
371  }
372 
373  LogDebug("TkNavigation") << "The barrel length is " << theBarrelLength ;
374  }
375  return theBarrelLength;
376 }
377 
379 
380  // NavigationSetter setter(*this);
381 
383 
384  // find for each layer which are the barrel and forward
385  // layers that point to it
386  typedef map<const DetLayer*, vector<const BarrelDetLayer*>, less<const DetLayer*> > BarrelMapType;
387  typedef map<const DetLayer*, vector<const ForwardDetLayer*>, less<const DetLayer*> > ForwardMapType;
388 
389 
390  BarrelMapType reachedBarrelLayersMap;
391  ForwardMapType reachedForwardLayersMap;
392 
393 
394  for ( auto bli : theBarrelLayers) {
395  auto reachedLC = nextLayers(*bli, insideOut);
396  for ( auto i : reachedLC) {
397  reachedBarrelLayersMap[i].push_back(bli);
398  }
399  }
400 
401  for ( auto fli : theForwardLayers) {
402  auto reachedLC = nextLayers(*fli, insideOut);
403  for ( auto i : reachedLC) {
404  reachedForwardLayersMap[i].push_back(fli);
405  }
406  }
407 
408  /*
409  vector<DetLayer*> lc = theTracker->allLayers();
410  for ( vector<DetLayer*>::iterator i = lc.begin(); i != lc.end(); i++) {
411  SimpleNavigableLayer* navigableLayer =
412  dynamic_cast<SimpleNavigableLayer*>((**i).navigableLayer());
413  navigableLayer->setInwardLinks( reachedBarrelLayersMap[*i],reachedForwardLayersMap[*i] );
414  }
415  */
416 
417 
418  for(auto nl : theAllNavigableLayer) {
419  if (!nl) continue;
420  auto navigableLayer = static_cast<SimpleNavigableLayer*>(nl);
421  auto dl = nl->detLayer();
422  navigableLayer->setInwardLinks( reachedBarrelLayersMap[dl],reachedForwardLayersMap[dl] );
423  }
424 
425 
426 }
427 
430 
431 
432 #include "NavigationSchoolFactory.h"
435 
#define LogDebug(id)
virtual float length() const =0
std::vector< DetLayer const * > const & allLayers() const
std::vector< const BarrelDetLayer * > BDLC
std::vector< ForwardDetLayer const * > const & posPixelForwardLayers() const
virtual void linkNextBarrelLayer(ForwardDetLayer const *fl, BDLC &)
virtual const BoundSurface & surface() const final
GeometricSearchDet interface.
std::vector< ForwardDetLayer const * > const & forwardLayers() const
const Bounds & bounds() const
Definition: Surface.h:120
virtual StateType navigableLayers() override
virtual const BoundCylinder & specificSurface() const final
Extension of the interface.
const GeometricSearchTracker * theTracker
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
const ForwardDetLayer * mirror(const ForwardDetLayer *layer)
FDLC::const_iterator ConstFDLI
virtual void linkNextLayerInGroup(FDLI fli, const FDLC &group, FDLC &reachableFL)
T z() const
Definition: PV3DBase.h:64
StateType theAllNavigableLayer
std::vector< NavigableLayer * > StateType
#define end
Definition: vmac.h:37
T min(T a, T b)
Definition: MathUtil.h:58
virtual void linkWithinGroup(FDLI fl, const FDLC &group, FDLC &reachableFL)
virtual void linkForwardLayers(SymmetricLayerFinder &symFinder)
virtual void establishInverseRelations()
std::vector< const ForwardDetLayer * > FDLC
const std::vector< const DetLayer * > * theAllDetLayersInSystem
const MagneticField * theField
virtual void linkBarrelLayers(SymmetricLayerFinder &symFinder)
virtual const BoundDisk & specificSurface() const final
virtual const Surface::PositionType & position() const
Returns position of the surface.
virtual ConstFDLI outerRadiusIncrease(FDLI fl, const FDLC &group)
std::vector< const DetLayer * > nextLayers(const DetLayer &detLayer, Args &&...args) const
NavigationDirection.
virtual std::vector< FDLC > splitForwardLayers()
std::vector< ForwardDetLayer const * > const & posTidLayers() const
virtual void linkNextLargerLayer(BDLI, BDLI, BDLC &)
virtual DetLayer const * detLayer() const =0
#define begin
Definition: vmac.h:30
#define DEFINE_EDM_PLUGIN(factory, type, name)
virtual void linkNextForwardLayer(BarrelDetLayer const *, FDLC &)
void setState(const StateType &state)
virtual void linkOuterGroup(ForwardDetLayer const *fl, const FDLC &group, FDLC &reachableFL)
std::vector< BarrelDetLayer const * > const & barrelLayers() const
ib
Definition: cuy.py:660