CMS 3D CMS Logo

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