CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
PixelInactiveAreaFinder.cc
Go to the documentation of this file.
2 
9 
11 
12 #include <fstream>
13 #include <queue>
14 #include <algorithm>
15 
16 std::ostream& operator<<(std::ostream& os, SeedingLayerSetsBuilder::SeedingLayerId layer) {
17  if (std::get<0>(layer) == GeomDetEnumerators::PixelBarrel) {
18  os << "BPix";
19  } else {
20  os << "FPix";
21  }
22  os << std::get<2>(layer);
23  if (std::get<1>(layer) == TrackerDetSide::PosEndcap) {
24  os << "_pos";
25  } else if (std::get<1>(layer) == TrackerDetSide::NegEndcap) {
26  os << "_neg";
27  }
28  return os;
29 }
30 
31 namespace {
32  using LayerPair = std::pair<SeedingLayerSetsBuilder::SeedingLayerId, SeedingLayerSetsBuilder::SeedingLayerId>;
33  using ActiveLayerSetToInactiveSetsMap = std::map<LayerPair, edm::VecArray<LayerPair, 5>>;
34  using Stream = std::stringstream;
35  using Span_t = std::pair<float, float>;
36 
37  ActiveLayerSetToInactiveSetsMap createActiveToInactiveMap() {
38  ActiveLayerSetToInactiveSetsMap map;
39 
40  auto bpix = [](int layer) {
42  };
43  auto fpix_pos = [](int disk) {
45  };
46  auto fpix_neg = [](int disk) {
48  };
49 
50  auto add_permutations = [&](std::array<SeedingLayerSetsBuilder::SeedingLayerId, 4> quads) {
51  do {
52  // skip permutations like BPix2+BPix1 or FPix1+BPix1
53  // operator> works automatically
54  if (quads[0] > quads[1] || quads[2] > quads[3])
55  continue;
56 
57  map[std::make_pair(quads[0], quads[1])].emplace_back(quads[2], quads[3]);
58  } while (std::next_permutation(quads.begin(), quads.end()));
59  };
60 
61  // 4 barrel
62  add_permutations({{bpix(1), bpix(2), bpix(3), bpix(4)}});
63 
64  // 3 barrel, 1 forward
65  add_permutations({{bpix(1), bpix(2), bpix(3), fpix_pos(1)}});
66  add_permutations({{bpix(1), bpix(2), bpix(3), fpix_neg(1)}});
67 
68  // 2 barrel, 2 forward
69  add_permutations({{bpix(1), bpix(2), fpix_pos(1), fpix_pos(2)}});
70  add_permutations({{bpix(1), bpix(2), fpix_neg(1), fpix_neg(2)}});
71 
72  // 1 barrel, 3 forward
73  add_permutations({{bpix(1), fpix_pos(1), fpix_pos(2), fpix_pos(3)}});
74  add_permutations({{bpix(1), fpix_neg(1), fpix_neg(2), fpix_neg(3)}});
75 
76 #ifdef EDM_ML_DEBUG
77  LogDebug("PixelInactiveAreaFinder") << "Active to inactive mapping";
78  for (const auto& elem : map) {
79  std::stringstream ss;
80  for (const auto& layerPair : elem.second) {
81  ss << layerPair.first << "+" << layerPair.second << ",";
82  }
83  LogTrace("PixelInactiveAreaFinder") << " " << elem.first.first << "+" << elem.first.second << " => " << ss.str();
84  }
85 #endif
86 
87  return map;
88  }
89 
90  void detGroupSpanInfo(const PixelInactiveAreaFinder::DetGroupSpan& cspan, Stream& ss) {
91  using std::fixed;
92  using std::left;
93  using std::noshowpos;
94  using std::right;
95  using std::setfill;
96  using std::setprecision;
97  using std::setw;
98  using std::showpos;
99  std::string deli = "; ";
100  ss << "subdetid:[" << cspan.subdetId << "]" << deli;
102  ss << "layer:[" << cspan.layer << "]" << deli;
103  } else {
104  ss << "disk:[" << cspan.disk << "]" << deli;
105  }
106  ss
107  //<< setfill(' ') << setw(36) << " "
108  << setprecision(16) << showpos << "phi:<" << right << setw(12) << cspan.phiSpan.first << "," << left << setw(12)
109  << cspan.phiSpan.second << ">" << deli << "z:<" << right << setw(7) << cspan.zSpan.first << "," << left
110  << setw(7) << cspan.zSpan.second << ">" << deli << noshowpos << "r:<" << right << setw(10) << cspan.rSpan.first
111  << "," << left << setw(10) << cspan.rSpan.second << ">" << deli;
112  }
113  void printOverlapSpans(const PixelInactiveAreaFinder::InactiveAreas& areasLayers) {
114  auto spansLayerSets = areasLayers.spansAndLayerSets(GlobalPoint(0, 0, 0), std::numeric_limits<float>::infinity());
115 
116  Stream ss;
117  for (auto const& spansLayers : spansLayerSets) {
118  ss << "Overlapping detGroups:\n";
119  for (auto const& cspan : spansLayers.first) {
120  detGroupSpanInfo(cspan, ss);
121  ss << std::endl;
122  }
123  }
124  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
125  }
126 
127  // Functions for finding bad detGroups
128  bool phiRangesOverlap(const Span_t& phiSpanA, const Span_t& phiSpanB) {
129  float x1, x2, y1, y2;
130  std::tie(x1, x2) = phiSpanA;
131  std::tie(y1, y2) = phiSpanB;
132  // assuming phi ranges are [x1,x2] and [y1,y2] and xi,yi in [-pi,pi]
133  if (x1 <= x2 && y1 <= y2) {
134  return x1 <= y2 && y1 <= x2;
135  } else if ((x1 > x2 && y1 <= y2) || (y1 > y2 && x1 <= x2)) {
136  return y1 <= x2 || x1 <= y2;
137  } else if (x1 > x2 && y1 > y2) {
138  return true;
139  } else {
140  return false;
141  }
142  }
143 
144  // Functions for finding ranges that detGroups cover
145  bool phiMoreClockwise(float phiA, float phiB) {
146  // return true if a is more clockwise than b
147  return reco::deltaPhi(phiA, phiB) <= 0.f;
148  }
149  bool phiMoreCounterclockwise(float phiA, float phiB) {
150  // return true if a is more counterclockwise than b
151  return reco::deltaPhi(phiA, phiB) >= 0.f;
152  }
153 
154  // Functions for findind overlapping functions
155  float zAxisIntersection(const float zrPointA[2], const float zrPointB[2]) {
156  return (zrPointB[0] - zrPointA[0]) / (zrPointB[1] - zrPointA[1]) * (-zrPointA[1]) + zrPointA[0];
157  }
158  bool getZAxisOverlapRangeBarrel(const PixelInactiveAreaFinder::DetGroupSpan& cspanA,
160  std::pair<float, float>& range) {
163  if (cspanA.rSpan.second < cspanB.rSpan.first) {
164  cspanLower = cspanA;
165  cspanUpper = cspanB;
166  } else if (cspanA.rSpan.first > cspanB.rSpan.second) {
167  cspanUpper = cspanA;
168  cspanLower = cspanB;
169  } else {
170  return false;
171  }
172  float lower = 0;
173  float upper = 0;
174  if (cspanUpper.zSpan.second < cspanLower.zSpan.first) {
175  // lower intersectionpoint, point = {z,r} in cylindrical coordinates
176  const float pointUpperDetGroupL[2] = {cspanUpper.zSpan.second, cspanUpper.rSpan.second};
177  const float pointLowerDetGroupL[2] = {cspanLower.zSpan.first, cspanLower.rSpan.first};
178  lower = zAxisIntersection(pointUpperDetGroupL, pointLowerDetGroupL);
179  // upper intersectionpoint
180  const float pointUpperDetGroupU[2] = {cspanUpper.zSpan.first, cspanUpper.rSpan.first};
181  const float pointLowerDetGroupU[2] = {cspanLower.zSpan.second, cspanLower.rSpan.second};
182  upper = zAxisIntersection(pointUpperDetGroupU, pointLowerDetGroupU);
183  } else if (cspanUpper.zSpan.first <= cspanLower.zSpan.second && cspanLower.zSpan.first <= cspanUpper.zSpan.second) {
184  // lower intersectionpoint, point = {z,r} in cylindrical coordinates
185  const float pointUpperDetGroupL[2] = {cspanUpper.zSpan.second, cspanUpper.rSpan.first};
186  const float pointLowerDetGroupL[2] = {cspanLower.zSpan.first, cspanLower.rSpan.second};
187  lower = zAxisIntersection(pointUpperDetGroupL, pointLowerDetGroupL);
188  // upper intersectionpoint
189  const float pointUpperDetGroupU[2] = {cspanUpper.zSpan.first, cspanUpper.rSpan.first};
190  const float pointLowerDetGroupU[2] = {cspanLower.zSpan.second, cspanLower.rSpan.second};
191  upper = zAxisIntersection(pointUpperDetGroupU, pointLowerDetGroupU);
192  } else if (cspanUpper.zSpan.first > cspanLower.zSpan.second) {
193  // lower intersectionpoint, point = {z,r} in cylindrical coordinates
194  const float pointUpperDetGroupL[2] = {cspanUpper.zSpan.second, cspanUpper.rSpan.first};
195  const float pointLowerDetGroupL[2] = {cspanLower.zSpan.first, cspanLower.rSpan.second};
196  lower = zAxisIntersection(pointUpperDetGroupL, pointLowerDetGroupL);
197  // upper intersectionpoint
198  const float pointUpperDetGroupU[2] = {cspanUpper.zSpan.first, cspanUpper.rSpan.second};
199  const float pointLowerDetGroupU[2] = {cspanLower.zSpan.second, cspanLower.rSpan.first};
200  upper = zAxisIntersection(pointUpperDetGroupU, pointLowerDetGroupU);
201  } else {
202  //something wrong
203  return false;
204  }
205  range = std::pair<float, float>(lower, upper);
206  return true;
207  }
208  bool getZAxisOverlapRangeEndcap(const PixelInactiveAreaFinder::DetGroupSpan& cspanA,
210  std::pair<float, float>& range) {
211  // While on left hand side of pixel detector
214  float lower = 0;
215  float upper = 0;
216  if (cspanA.zSpan.first < 0 && cspanB.zSpan.first < 0) {
217  if (cspanA.zSpan.second < cspanB.zSpan.first) {
218  cspanFurther = cspanA;
219  cspanNearer = cspanB;
220  } else if (cspanB.zSpan.second < cspanA.zSpan.first) {
221  cspanFurther = cspanB;
222  cspanNearer = cspanA;
223  } else {
224 #ifdef EDM_ML_DEBUG
225  LogTrace("PixelInactiveAreaFinder") << "No overlap, same disk propably. Spans:";
226  Stream ss;
227  detGroupSpanInfo(cspanA, ss);
228  ss << std::endl;
229  detGroupSpanInfo(cspanB, ss);
230  ss << std::endl;
231  LogTrace("PixelInactiveAreaFinder") << ss.str();
232  ss.str(std::string());
233  LogTrace("PixelInactiveAreaFinder") << "**";
234 #endif
235  return false;
236  }
237  if (cspanFurther.rSpan.second > cspanNearer.rSpan.first) {
238  const float pointA[2] = {cspanFurther.zSpan.second, cspanFurther.rSpan.second};
239  const float pointB[2] = {cspanNearer.zSpan.first, cspanNearer.rSpan.first};
240  lower = zAxisIntersection(pointA, pointB);
241  if (cspanFurther.rSpan.first > cspanNearer.rSpan.second) {
242  const float pointC[2] = {cspanFurther.zSpan.first, cspanFurther.rSpan.first};
243  const float pointD[2] = {cspanNearer.zSpan.second, cspanFurther.rSpan.second};
244  upper = zAxisIntersection(pointC, pointD);
245  } else {
247  }
248  } else {
249 #ifdef EDM_ML_DEBUG
250  LogTrace("PixelInactiveAreaFinder") << "No overlap, further detGroup is lower. Spans:";
251  Stream ss;
252  detGroupSpanInfo(cspanA, ss);
253  ss << std::endl;
254  detGroupSpanInfo(cspanB, ss);
255  ss << std::endl;
256  LogTrace("PixelInactiveAreaFinder") << ss.str();
257  ss.str(std::string());
258  LogTrace("PixelInactiveAreaFinder") << "**";
259 #endif
260  return false;
261  }
262  } else if (cspanA.zSpan.first > 0 && cspanB.zSpan.first > 0) {
263  if (cspanA.zSpan.first > cspanB.zSpan.second) {
264  cspanFurther = cspanA;
265  cspanNearer = cspanB;
266  } else if (cspanB.zSpan.first > cspanA.zSpan.second) {
267  cspanFurther = cspanB;
268  cspanNearer = cspanA;
269  } else {
270 #ifdef EDM_ML_DEBUG
271  LogTrace("PixelInactiveAreaFinder") << "No overlap, same disk propably. Spans:";
272  Stream ss;
273  detGroupSpanInfo(cspanA, ss);
274  ss << std::endl;
275  detGroupSpanInfo(cspanB, ss);
276  ss << std::endl;
277  LogTrace("PixelInactiveAreaFinder") << ss.str();
278  ss.str(std::string());
279  LogTrace("PixelInactiveAreaFinder") << "**";
280 #endif
281  return false;
282  }
283  if (cspanFurther.rSpan.second > cspanNearer.rSpan.first) {
284  const float pointA[2] = {cspanFurther.zSpan.first, cspanFurther.rSpan.second};
285  const float pointB[2] = {cspanNearer.zSpan.second, cspanNearer.rSpan.first};
286  upper = zAxisIntersection(pointA, pointB);
287  if (cspanFurther.rSpan.first > cspanNearer.rSpan.second) {
288  const float pointC[2] = {cspanFurther.zSpan.second, cspanFurther.rSpan.first};
289  const float pointD[2] = {cspanNearer.zSpan.first, cspanFurther.rSpan.second};
290  lower = zAxisIntersection(pointC, pointD);
291  } else {
293  }
294  } else {
295 #ifdef EDM_ML_DEBUG
296  LogTrace("PixelInactiveAreaFinder") << "No overlap, further detGroup lower. Spans:";
297  Stream ss;
298  detGroupSpanInfo(cspanA, ss);
299  ss << std::endl;
300  detGroupSpanInfo(cspanB, ss);
301  ss << std::endl;
302  LogTrace("PixelInactiveAreaFinder") << ss.str();
303  ss.str(std::string());
304  LogTrace("PixelInactiveAreaFinder") << "**";
305 #endif
306  return false;
307  }
308  } else {
309 #ifdef EDM_ML_DEBUG
310  LogTrace("PixelInactiveAreaFinder") << "No overlap, different sides of z axis. Spans:";
311  Stream ss;
312  detGroupSpanInfo(cspanA, ss);
313  ss << std::endl;
314  detGroupSpanInfo(cspanB, ss);
315  ss << std::endl;
316  LogTrace("PixelInactiveAreaFinder") << ss.str();
317  ss.str(std::string());
318  LogTrace("PixelInactiveAreaFinder") << "**";
319 #endif
320  return false;
321  }
322  range = std::pair<float, float>(lower, upper);
323  return true;
324  }
325 
326  bool getZAxisOverlapRangeBarrelEndcap(const PixelInactiveAreaFinder::DetGroupSpan& cspanBar,
328  std::pair<float, float>& range) {
329  float lower = 0;
330  float upper = 0;
331  if (cspanEnd.rSpan.second > cspanBar.rSpan.first) {
332  if (cspanEnd.zSpan.second < cspanBar.zSpan.first) {
333  // if we are on the left hand side of pixel detector
334  const float pointA[2] = {cspanEnd.zSpan.second, cspanEnd.rSpan.second};
335  const float pointB[2] = {cspanBar.zSpan.first, cspanBar.rSpan.first};
336  lower = zAxisIntersection(pointA, pointB);
337  if (cspanEnd.rSpan.first > cspanBar.rSpan.second) {
338  // if does not overlap, then there is also upper limit
339  const float pointC[2] = {cspanEnd.zSpan.first, cspanEnd.rSpan.first};
340  const float pointD[2] = {cspanBar.zSpan.second, cspanBar.rSpan.second};
341  upper = zAxisIntersection(pointC, pointD);
342  } else {
344  }
345  } else if (cspanEnd.zSpan.first > cspanBar.zSpan.second) {
346  // if we are on the right hand side of pixel detector
347  const float pointA[2] = {cspanEnd.zSpan.first, cspanEnd.rSpan.second};
348  const float pointB[2] = {cspanBar.zSpan.second, cspanBar.rSpan.first};
349  upper = zAxisIntersection(pointA, pointB);
350  if (cspanEnd.rSpan.first > cspanBar.rSpan.second) {
351  const float pointC[2] = {cspanEnd.zSpan.second, cspanEnd.rSpan.first};
352  const float pointD[2] = {cspanBar.zSpan.first, cspanBar.rSpan.second};
353  lower = zAxisIntersection(pointC, pointD);
354  } else {
356  }
357  } else {
358  return false;
359  }
360  } else {
361  return false;
362  }
363  range = std::pair<float, float>(lower, upper);
364  return true;
365  }
366 } // namespace
367 
369  std::pair<edm::VecArray<PixelInactiveAreaFinder::Area, 2>, std::vector<PixelInactiveAreaFinder::LayerSetIndex>>>
371  auto spansLayerSets = spansAndLayerSets(point, zwidth);
372 
373  // TODO: try to remove this conversion...
374  std::vector<std::pair<VecArray2<Area>, std::vector<LayerSetIndex>>> ret;
375  for (auto& item : spansLayerSets) {
376  auto& innerSpan = item.first[0];
377  auto& outerSpan = item.first[1];
378  VecArray2<Area> areas;
379  areas.emplace_back(innerSpan.rSpan.first,
380  innerSpan.rSpan.second,
381  innerSpan.phiSpan.first,
382  innerSpan.phiSpan.second,
383  innerSpan.zSpan.first,
384  innerSpan.zSpan.second);
385  areas.emplace_back(outerSpan.rSpan.first,
386  outerSpan.rSpan.second,
387  outerSpan.phiSpan.first,
388  outerSpan.phiSpan.second,
389  outerSpan.zSpan.first,
390  outerSpan.zSpan.second);
391  ret.emplace_back(areas, std::move(item.second));
392  }
393 
394  return ret;
395 }
396 
397 std::vector<std::pair<edm::VecArray<PixelInactiveAreaFinder::DetGroupSpan, 2>,
398  std::vector<PixelInactiveAreaFinder::LayerSetIndex>>>
400  // TODO: in the future use 2D-r for the origin for the phi overlap check
401  const float zmin = point.z() - zwidth;
402  const float zmax = point.z() + zwidth;
403 
404  std::vector<std::pair<VecArray2<DetGroupSpan>, std::vector<LayerSetIndex>>> ret;
405 
406  LogDebug("PixelInactiveAreaFinder") << "Origin at " << point.x() << "," << point.y() << "," << point.z()
407  << " z half width " << zwidth;
408 
409  for (LayerSetIndex i = 0, end = inactiveLayerPairIndices_->size(); i < end; ++i) {
410  const auto& layerIdxPair = (*inactiveLayerPairIndices_)[i];
411  const auto& innerSpans = inactiveSpans_[layerIdxPair.first];
412  const auto& outerSpans = inactiveSpans_[layerIdxPair.second];
413 
414  for (const auto& innerSpan : innerSpans) {
415  for (const auto& outerSpan : outerSpans) {
416  if (phiRangesOverlap(innerSpan.phiSpan, outerSpan.phiSpan)) {
417  std::pair<float, float> range(0, 0);
418 
419  bool zOverlap = false;
420  const auto innerDet = std::get<0>((*inactiveLayers_)[layerIdxPair.first]);
421  const auto outerDet = std::get<0>((*inactiveLayers_)[layerIdxPair.second]);
422  if (innerDet == GeomDetEnumerators::PixelBarrel) {
423  if (outerDet == GeomDetEnumerators::PixelBarrel)
424  zOverlap = getZAxisOverlapRangeBarrel(innerSpan, outerSpan, range);
425  else
426  zOverlap = getZAxisOverlapRangeBarrelEndcap(innerSpan, outerSpan, range);
427  } else {
428  if (outerDet == GeomDetEnumerators::PixelEndcap)
429  zOverlap = getZAxisOverlapRangeEndcap(innerSpan, outerSpan, range);
430  else
431  throw cms::Exception("LogicError") << "Forward->barrel transition is not supported";
432  }
433 
434  if (zOverlap && zmin <= range.second && range.first <= zmax) {
435 #ifdef EDM_ML_DEBUG
436  Stream ss;
437  for (auto ind : (*layerSetIndexInactiveToActive_)[i]) {
438  ss << ind << ",";
439  }
440  ss << "\n ";
441  detGroupSpanInfo(innerSpan, ss);
442  ss << "\n ";
443  detGroupSpanInfo(outerSpan, ss);
444  LogTrace("PixelInactiveAreaFinder") << " adding areas for active layer sets " << ss.str();
445 #endif
447  vec.emplace_back(innerSpan);
448  vec.emplace_back(outerSpan);
449  ret.emplace_back(std::move(vec), (*layerSetIndexInactiveToActive_)[i]);
450  }
451  }
452  }
453  }
454  }
455 
456  return ret;
457 }
458 
460  const edm::ParameterSet& iConfig,
461  const std::vector<SeedingLayerSetsBuilder::SeedingLayerId>& seedingLayers,
462  const SeedingLayerSetsLooper& seedingLayerSetsLooper,
464  : debug_(iConfig.getUntrackedParameter<bool>("debug")),
465  createPlottingFiles_(iConfig.getUntrackedParameter<bool>("createPlottingFiles")),
466  ignoreSingleFPixPanelModules_(iConfig.getParameter<bool>("ignoreSingleFPixPanelModules")),
468  edm::vector_transform(iConfig.getParameter<std::vector<edm::InputTag>>("inactivePixelDetectorLabels"),
469  [&](const auto& tag) { return iC.consumes<DetIdCollection>(tag); })),
471  edm::vector_transform(iConfig.getParameter<std::vector<edm::InputTag>>("badPixelFEDChannelCollectionLabels"),
472  [&](const auto& tag) { return iC.consumes<PixelFEDChannelCollection>(tag); })),
473  trackerGeometryToken_(iC.esConsumes()),
474  trackerTopologyToken_(iC.esConsumes()),
475  pixelQualityToken_(iC.esConsumes()) {
476 #ifdef EDM_ML_DEBUG
477  for (const auto& layer : seedingLayers) {
478  LogTrace("PixelInactiveAreaFinder") << "Input layer subdet " << std::get<0>(layer) << " side "
479  << static_cast<unsigned int>(std::get<1>(layer)) << " layer "
480  << std::get<2>(layer);
481  }
482 #endif
483 
484  auto findOrAdd = [&](SeedingLayerId layer) -> unsigned short {
485  auto found = std::find(inactiveLayers_.cbegin(), inactiveLayers_.cend(), layer);
486  if (found == inactiveLayers_.cend()) {
487  auto ret = inactiveLayers_.size();
488  inactiveLayers_.push_back(layer);
489  return ret;
490  }
491  return std::distance(inactiveLayers_.cbegin(), found);
492  };
493 
494  // mapping from active layer pairs to inactive layer pairs
495  const auto activeToInactiveMap = createActiveToInactiveMap();
496 
497  // convert input layer pairs (that are for active layers) to layer
498  // pairs to look for inactive areas
499  LayerSetIndex i = 0;
500  for (const auto& layerSet : seedingLayerSetsLooper.makeRange(seedingLayers)) {
501  assert(layerSet.size() == 2);
502  auto found = activeToInactiveMap.find(std::make_pair(layerSet[0], layerSet[1]));
503  if (found == activeToInactiveMap.end()) {
504  throw cms::Exception("Configuration")
505  << "Encountered layer pair " << layerSet[0] << "+" << layerSet[1]
506  << " not found from the internal 'active layer pairs' to 'inactive layer pairs' mapping; either fix the "
507  "input or the mapping (in PixelInactiveAreaFinder.cc)";
508  }
509 
510  LogTrace("PixelInactiveAreaFinder") << "Input layer set " << layerSet[0] << "+" << layerSet[1];
511  for (const auto& inactiveLayerSet : found->second) {
512  auto innerInd = findOrAdd(inactiveLayerSet.first);
513  auto outerInd = findOrAdd(inactiveLayerSet.second);
514 
515  auto found = std::find(
516  inactiveLayerSetIndices_.cbegin(), inactiveLayerSetIndices_.cend(), std::make_pair(innerInd, outerInd));
517  if (found == inactiveLayerSetIndices_.end()) {
518  inactiveLayerSetIndices_.emplace_back(innerInd, outerInd);
519  layerSetIndexInactiveToActive_.push_back(std::vector<LayerSetIndex>{i});
520  } else {
521  layerSetIndexInactiveToActive_.at(std::distance(inactiveLayerSetIndices_.cbegin(), found))
522  .push_back(i); // TODO: move to operator[] once finished
523  }
524 
525  LogTrace("PixelInactiveAreaFinder")
526  << " inactive layer set " << inactiveLayerSet.first << "+" << inactiveLayerSet.second;
527  }
528 
529  ++i;
530  }
531 
532 #ifdef EDM_ML_DEBUG
533  LogDebug("PixelInactiveAreaFinder") << "All inactive layer sets";
534  for (const auto& idxPair : inactiveLayerSetIndices_) {
535  LogTrace("PixelInactiveAreaFinder") << " " << inactiveLayers_[idxPair.first] << "+"
536  << inactiveLayers_[idxPair.second];
537  }
538 #endif
539 }
540 
542  desc.add<std::vector<edm::InputTag>>("inactivePixelDetectorLabels",
543  std::vector<edm::InputTag>{{edm::InputTag("siPixelDigis")}})
544  ->setComment("One or more DetIdCollections of modules to mask on the fly for a given event");
545  desc.add<std::vector<edm::InputTag>>("badPixelFEDChannelCollectionLabels",
546  std::vector<edm::InputTag>{{edm::InputTag("siPixelDigis")}})
547  ->setComment("One or more PixelFEDChannelCollections of modules+ROCs to mask on the fly for a given event");
548  desc.add<bool>("ignoreSingleFPixPanelModules", false);
549 
550  desc.addUntracked<bool>("debug", false);
551  desc.addUntracked<bool>("createPlottingFiles", false);
552 }
553 
555  const edm::EventSetup& iSetup) {
556  // Set data to handles
559 
560  // assign data to instance variables
561  updatePixelDets(iSetup);
562  getBadPixelDets(iEvent, iSetup);
563 
564  //write files for plotting
565  if (createPlottingFiles_) {
567  }
568 
569  // find detGroupSpans ie phi,r,z limits for detector detGroups that are not working
570  // returns pair where first is barrel spans and second endcap spans
572 
573  // map spans to a vector with consistent indexing with inactiveLayers_ and inactiveLayerSetIndices_
574  // TODO: try to move the inner logic towards this direction as well
575  std::vector<DetGroupSpanContainer> spans(inactiveLayers_.size());
576 
577  auto doWork = [&](const DetGroupSpanContainer& container) {
578  for (const auto& span : container) {
579  const auto subdet = span.subdetId == PixelSubdetector::PixelBarrel ? GeomDetEnumerators::PixelBarrel
581  const auto side = (subdet == GeomDetEnumerators::PixelBarrel
583  : (span.zSpan.first < 0 ? TrackerDetSide::NegEndcap : TrackerDetSide::PosEndcap));
584  const auto layer = subdet == GeomDetEnumerators::PixelBarrel ? span.layer : span.disk;
585  auto found = std::find(inactiveLayers_.begin(), inactiveLayers_.end(), SeedingLayerId(subdet, side, layer));
586  if (found != inactiveLayers_.end()) { // it is possible that this layer is ignored by the configuration
587  spans[std::distance(inactiveLayers_.begin(), found)].push_back(span);
588  }
589  }
590  };
591  doWork(cspans.first);
592  doWork(cspans.second);
593 
594  auto ret =
596 
597  if (debug_) {
598  printOverlapSpans(ret);
599  }
600 
601  return ret;
602 }
603 
604 // Functions for fetching date from handles
606  if (!geometryWatcher_.check(iSetup))
607  return;
608 
609  // deduce the number of ladders per layer and the number of modules per ladder
610  {
611  // sanity checks
613  throw cms::Exception("NotImplemented")
614  << "This module supports only a detector with 4 pixel barrel layers, the current geometry has "
616  }
618  throw cms::Exception("NotImplemented")
619  << "This module supports only a detector with 3 pixel forward disks, the current geometry has "
621  }
622 
623  std::array<std::array<unsigned short, 100>, 4> counts = {}; // assume at most 100 ladders per layer
624  for (const auto& det : trackerGeometry_->detsPXB()) {
625  const auto layer = trackerTopology_->layer(det->geographicalId());
626  const auto ladder = trackerTopology_->pxbLadder(det->geographicalId());
627  if (ladder >= 100) {
628  throw cms::Exception("LogicError")
629  << "Got a ladder with number " << ladder
630  << " while the expected maximum was 100; either something is wrong or the maximum has to be increased.";
631  }
632  counts[layer - 1][ladder - 1] += 1; // numbering of layer and ladder starts at 1
633  }
634 
635  // take number of modules per ladder from the first ladder of the first layer (such better exist)
636  // other ladders better have the same number
637  nModulesPerLadder = counts[0][0];
638  if (nModulesPerLadder == 0) {
639  throw cms::Exception("LogicError") << "Ladder 1 of layer 1 has 0 modules, something fishy is going on.";
640  }
641 
642  LogDebug("PixelInactiveAreaFinder") << "Number of modules per ladder " << nModulesPerLadder
643  << "; below are number of ladders per layer";
644 
645  // number of ladders
646  for (unsigned layer = 0; layer < 4; ++layer) {
648  std::count_if(counts[layer].begin(), counts[layer].end(), [](unsigned short val) { return val > 0; });
649  LogTrace("PixelInactiveAreaFinder")
650  << "BPix layer " << (layer + 1) << " has " << nBPixLadders[layer] << " ladders";
651 
652  auto fail = std::count_if(counts[layer].begin(), counts[layer].end(), [&](unsigned short val) {
653  return val != nModulesPerLadder && val > 0;
654  });
655  if (fail != 0) {
656  throw cms::Exception("LogicError")
657  << "Layer " << (layer + 1) << " had " << fail
658  << " ladders whose number of modules/ladder differed from the ladder 1 of layer 1 (" << nModulesPerLadder
659  << "). Something fishy is going on.";
660  }
661  }
662  }
663 
664  // don't bother with the rest if not needed
666  return;
667 
668  pixelDetsBarrel_.clear();
669  pixelDetsEndcap_.clear();
670 
671  for (auto const& geomDetPtr : trackerGeometry_->detsPXB()) {
672  if (geomDetPtr->geographicalId().subdetId() == PixelSubdetector::PixelBarrel) {
673  pixelDetsBarrel_.push_back(geomDetPtr->geographicalId().rawId());
674  }
675  }
676  for (auto const& geomDetPtr : trackerGeometry_->detsPXF()) {
677  if (geomDetPtr->geographicalId().subdetId() == PixelSubdetector::PixelEndcap) {
678  pixelDetsEndcap_.push_back(geomDetPtr->geographicalId().rawId());
679  }
680  }
681  std::sort(pixelDetsBarrel_.begin(), pixelDetsBarrel_.end());
682  std::sort(pixelDetsEndcap_.begin(), pixelDetsEndcap_.end());
683 }
685  auto addDetId = [&](const auto id) {
686  const auto detid = DetId(id);
687  const auto subdet = detid.subdetId();
688  if (subdet == PixelSubdetector::PixelBarrel) {
689  badPixelDetsBarrel_.push_back(detid.rawId());
690  } else if (subdet == PixelSubdetector::PixelEndcap) {
691  badPixelDetsEndcap_.push_back(detid.rawId());
692  }
693  };
694 
695  // SiPixelQuality
696  auto const& pixelQuality = iSetup.getData(pixelQualityToken_);
697 
698  for (auto const& disabledModule : pixelQuality.getBadComponentList()) {
699  addDetId(disabledModule.DetID);
700  }
701 
702  // dynamic bad modules
703  for (const auto& token : inactivePixelDetectorTokens_) {
705  iEvent.getByToken(token, detIds);
706  for (const auto& id : *detIds) {
707  addDetId(id);
708  }
709  }
710 
711  // dynamic bad ROCs ("Fed25")
712  // TODO: consider moving to finer-grained areas for inactive ROCs
713  for (const auto& token : badPixelFEDChannelsTokens_) {
714  edm::Handle<PixelFEDChannelCollection> pixelFEDChannelCollectionHandle;
715  iEvent.getByToken(token, pixelFEDChannelCollectionHandle);
716  for (const auto& disabledChannels : *pixelFEDChannelCollectionHandle) {
717  addDetId(disabledChannels.detId());
718  }
719  }
720 
721  // remove duplicates
722  std::sort(badPixelDetsBarrel_.begin(), badPixelDetsBarrel_.end());
723  std::sort(badPixelDetsEndcap_.begin(), badPixelDetsEndcap_.end());
725  badPixelDetsBarrel_.end());
727  badPixelDetsEndcap_.end());
728 }
729 // Printing functions
731  using std::fixed;
732  using std::left;
733  using std::noshowpos;
734  using std::right;
735  using std::setfill;
736  using std::setprecision;
737  using std::setw;
738  using std::showpos;
739  using std::tie;
740  std::string deli = "; ";
741  ss << "id:[" << det << "]" << deli;
742  ss << "subdetid:[" << DetId(det).subdetId() << "]" << deli;
743  if (DetId(det).subdetId() == PixelSubdetector::PixelBarrel) {
744  unsigned int layer = trackerTopology_->pxbLayer(DetId(det));
745  unsigned int ladder = trackerTopology_->pxbLadder(DetId(det));
746  unsigned int module = trackerTopology_->pxbModule(DetId(det));
747  ss << "layer:[" << layer << "]" << deli << "ladder:[" << right << setw(2) << ladder << "]" << deli << "module:["
748  << module << "]" << deli;
749  } else if (DetId(det).subdetId() == PixelSubdetector::PixelEndcap) {
750  unsigned int disk = trackerTopology_->pxfDisk(DetId(det));
751  unsigned int blade = trackerTopology_->pxfBlade(DetId(det));
752  unsigned int panel = trackerTopology_->pxfPanel(DetId(det));
753  ss << left << setw(6) << "disk:"
754  << "[" << right << disk << "]" << deli << left << setw(7) << "blade:"
755  << "[" << setw(2) << right << blade << "]" << deli << left << setw(7) << "panel:"
756  << "[" << right << panel << "]" << deli;
757  }
758  float phiA, phiB, zA, zB, rA, rB;
759  auto detSurface = trackerGeometry_->idToDet(DetId(det))->surface();
760  tie(phiA, phiB) = detSurface.phiSpan();
761  tie(zA, zB) = detSurface.zSpan();
762  tie(rA, rB) = detSurface.rSpan();
763  ss << setprecision(16) << fixed << showpos << setfill(' ') << "phi:[" << right << setw(12) << phiA << "," << left
764  << setw(12) << phiB << "]" << deli << "z:[" << right << setw(7) << zA << "," << left << setw(7) << zB << "]"
765  << deli << noshowpos << "r:[" << right << setw(10) << rA << "," << left << setw(10) << rB << "]" << deli;
766 }
768  edm::LogPrint("PixelInactiveAreaFinder") << "Barrel detectors:";
769  Stream ss;
770  for (auto const& det : pixelDetsBarrel_) {
771  detInfo(det, ss);
772  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
773  ss.str(std::string());
774  }
775  edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
776  for (auto const& det : pixelDetsEndcap_) {
777  detInfo(det, ss);
778  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
779  ss.str(std::string());
780  }
781 }
783  edm::LogPrint("PixelInactiveAreaFinder") << "Bad barrel detectors:";
784  Stream ss;
785  for (auto const& det : badPixelDetsBarrel_) {
786  detInfo(det, ss);
787  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
788  ss.str(std::string());
789  }
790  edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
791  for (auto const& det : badPixelDetsEndcap_) {
792  detInfo(det, ss);
793  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
794  ss.str(std::string());
795  }
796 }
798  DetGroupContainer badDetGroupsBar = badDetGroupsBarrel();
799  DetGroupContainer badDetGroupsEnd = badDetGroupsEndcap();
800  Stream ss;
801  for (auto const& detGroup : badDetGroupsBar) {
802  ss << std::setfill(' ') << std::left << std::setw(16) << "DetGroup:";
803  DetGroupSpan cspan;
804  getPhiSpanBarrel(detGroup, cspan);
805  getZSpan(detGroup, cspan);
806  getRSpan(detGroup, cspan);
807  detGroupSpanInfo(cspan, ss);
808  ss << std::endl;
809  for (auto const& det : detGroup) {
810  detInfo(det, ss);
811  ss << std::endl;
812  }
813  ss << std::endl;
814  }
815  for (auto const& detGroup : badDetGroupsEnd) {
816  ss << std::setfill(' ') << std::left << std::setw(16) << "DetGroup:";
817  DetGroupSpan cspan;
818  getPhiSpanEndcap(detGroup, cspan);
819  getZSpan(detGroup, cspan);
820  getRSpan(detGroup, cspan);
821  detGroupSpanInfo(cspan, ss);
822  ss << std::endl;
823  for (auto const& det : detGroup) {
824  detInfo(det, ss);
825  ss << std::endl;
826  }
827  ss << std::endl;
828  }
829  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
830 }
833  Stream ss;
834  for (auto const& cspan : cspans.first) {
835  detGroupSpanInfo(cspan, ss);
836  ss << std::endl;
837  }
838  for (auto const& cspan : cspans.second) {
839  detGroupSpanInfo(cspan, ss);
840  ss << std::endl;
841  }
842  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
843 }
845  // All detectors to file DETECTORS
846  Stream ss;
847  std::ofstream fsDet("DETECTORS.txt");
848  for (auto const& det : pixelDetsBarrel_) {
849  detInfo(det, ss);
850  ss << std::endl;
851  }
852  edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
853  for (auto const& det : pixelDetsEndcap_) {
854  detInfo(det, ss);
855  ss << std::endl;
856  }
857  fsDet << ss.rdbuf();
858  ss.str(std::string());
859  // Bad detectors
860  std::ofstream fsBadDet("BADDETECTORS.txt");
861  for (auto const& det : badPixelDetsBarrel_) {
862  detInfo(det, ss);
863  ss << std::endl;
864  }
865  for (auto const& det : badPixelDetsEndcap_) {
866  detInfo(det, ss);
867  ss << std::endl;
868  }
869  fsBadDet << ss.rdbuf();
870  ss.str(std::string());
871  // detgroupspans
872  std::ofstream fsSpans("DETGROUPSPANS.txt");
874  for (auto const& cspan : cspans.first) {
875  detGroupSpanInfo(cspan, ss);
876  ss << std::endl;
877  }
878  for (auto const& cspan : cspans.second) {
879  detGroupSpanInfo(cspan, ss);
880  ss << std::endl;
881  }
882  fsSpans << ss.rdbuf();
883  ss.str(std::string());
884 }
885 // Functions for finding bad detGroups
887  return std::find(badPixelDetsBarrel_.begin(), badPixelDetsBarrel_.end(), det) == badPixelDetsBarrel_.end() &&
889 }
891  using std::remove_if;
892 
893  DetGroup adj;
894  auto const tTopo = trackerTopology_;
895  auto const& detId = DetId(det);
896  unsigned int layer = tTopo->pxbLayer(detId);
897  unsigned int ladder = tTopo->pxbLadder(detId);
898  unsigned int module = tTopo->pxbModule(detId);
899  unsigned int nLads = nBPixLadders[layer];
900  //add detectors from next and previous ladder
901  adj.push_back(tTopo->pxbDetId(layer, ((ladder - 1) + 1) % nLads + 1, module)());
902  adj.push_back(tTopo->pxbDetId(layer, ((ladder - 1) - 1 + nLads) % nLads + 1, module)());
903  //add adjecent detectors from same ladder
904  if (module == 1) {
905  adj.push_back(tTopo->pxbDetId(layer, ladder, module + 1)());
906  } else if (module == nModulesPerLadder) {
907  adj.push_back(tTopo->pxbDetId(layer, ladder, module - 1)());
908  } else {
909  adj.push_back(tTopo->pxbDetId(layer, ladder, module + 1)());
910  adj.push_back(tTopo->pxbDetId(layer, ladder, module - 1)());
911  }
912  //remove working detectors from list
913  adj.erase(remove_if(adj.begin(), adj.end(), [&](auto c) { return this->detWorks(c); }), adj.end());
914  return adj;
915 }
917  // this might be faster if adjecent
918  using std::ignore;
919  using std::tie;
920  DetGroup adj;
921  Span_t phiSpan, phiSpanComp;
922  float z, zComp;
923  unsigned int disk, diskComp;
924  auto const& detSurf = trackerGeometry_->idToDet(DetId(det))->surface();
925  phiSpan = detSurf.phiSpan();
926  tie(z, ignore) = detSurf.zSpan();
927  disk = trackerTopology_->pxfDisk(DetId(det));
928  // add detectors from same disk whose phi ranges overlap to the adjecent list
929  for (auto const& detComp : badPixelDetsEndcap_) {
930  auto const& detIdComp = DetId(detComp);
931  auto const& detSurfComp = trackerGeometry_->idToDet(detIdComp)->surface();
932  diskComp = trackerTopology_->pxfDisk(detIdComp);
933  phiSpanComp = detSurfComp.phiSpan();
934  tie(zComp, ignore) = detSurfComp.zSpan();
935  if (det != detComp && disk == diskComp && z * zComp > 0 && phiRangesOverlap(phiSpan, phiSpanComp)) {
936  adj.push_back(detComp);
937  }
938  }
939  return adj;
940 }
942  DetectorSet& foundDets) {
944  std::queue<det_t> workQueue;
945  det_t workDet;
946  DetGroup badAdjDets;
947  foundDets.insert(initDet);
948  workQueue.push(initDet);
949  reachableDetGroup.push_back(initDet);
950  while (!workQueue.empty()) {
951  workDet = workQueue.front();
952  workQueue.pop();
953  if (DetId(workDet).subdetId() == PixelSubdetector::PixelBarrel) {
954  badAdjDets = this->badAdjecentDetsBarrel(workDet);
955  } else if (DetId(workDet).subdetId() == PixelSubdetector::PixelEndcap) {
956  badAdjDets = this->badAdjecentDetsEndcap(workDet);
957  } else {
958  badAdjDets = {};
959  }
960  for (auto const& badDet : badAdjDets) {
961  if (foundDets.find(badDet) == foundDets.end()) {
962  reachableDetGroup.push_back(badDet);
963  foundDets.insert(badDet);
964  workQueue.push(badDet);
965  }
966  }
967  }
968  return reachableDetGroup;
969 }
971  DetGroupContainer detGroups;
972  DetectorSet foundDets;
973  for (auto const& badDet : badPixelDetsBarrel_) {
974  if (foundDets.find(badDet) == foundDets.end()) {
975  detGroups.push_back(this->reachableDetGroup(badDet, foundDets));
976  }
977  }
978  return detGroups;
979 }
981  DetGroupContainer detGroups;
982  DetectorSet foundDets;
983  for (auto const& badDet : badPixelDetsEndcap_) {
984  if (foundDets.find(badDet) == foundDets.end()) {
985  auto adjacentDets = this->reachableDetGroup(badDet, foundDets);
986  if (ignoreSingleFPixPanelModules_ && adjacentDets.size() == 1) {
987  // size==1 means that only a single panel of a blade was inactive
988  // because of the large overlap with the other panel (i.e.
989  // redundancy in the detectory) ignoring these may help to decrease fakes
990  continue;
991  }
992  detGroups.push_back(adjacentDets);
993  }
994  }
995  return detGroups;
996 }
997 // Functions for finding DetGroupSpans
999  // find phiSpan using ordered vector of unique ladders in detGroup
1000  if (detGroup.empty()) {
1001  cspan = DetGroupSpan();
1002  return;
1003  } else {
1004  cspan.layer = trackerTopology_->pxbLayer(DetId(detGroup[0]));
1005  cspan.disk = 0;
1006  }
1007  using uint = unsigned int;
1008  using LadderSet = std::set<uint>;
1009  using LadVec = std::vector<uint>;
1010  LadderSet lads;
1011  for (auto const& det : detGroup) {
1012  lads.insert(trackerTopology_->pxbLadder(DetId(det)));
1013  }
1014  LadVec ladv(lads.begin(), lads.end());
1015  uint nLadders = nBPixLadders[cspan.layer];
1016  // find start ladder of detGroup
1017  uint i = 0;
1018  uint currentLadder = ladv[0];
1019  uint previousLadder = ladv[(ladv.size() + i - 1) % ladv.size()];
1020  // loop until discontinuity is found from vector
1021  while ((nLadders + currentLadder - 1) % nLadders == previousLadder) {
1022  ++i;
1023  currentLadder = ladv[i % ladv.size()];
1024  previousLadder = ladv[(ladv.size() + i - 1) % ladv.size()];
1025  if (i == ladv.size()) {
1027  cspan.phiSpan.second = -std::numeric_limits<float>::epsilon();
1028  return;
1029  }
1030  }
1031  uint startLadder = currentLadder;
1032  uint endLadder = previousLadder;
1033  auto detStart = trackerTopology_->pxbDetId(cspan.layer, startLadder, 1);
1034  auto detEnd = trackerTopology_->pxbDetId(cspan.layer, endLadder, 1);
1035  cspan.phiSpan.first = trackerGeometry_->idToDet(detStart)->surface().phiSpan().first;
1036  cspan.phiSpan.second = trackerGeometry_->idToDet(detEnd)->surface().phiSpan().second;
1037 }
1039  // this is quite naive/bruteforce method
1040  // 1) it starts by taking one detector from detGroup and starts to compare it to others
1041  // 2) when it finds overlapping detector in clockwise direction it starts comparing
1042  // found detector to others
1043  // 3) search stops until no overlapping detectors in clockwise detector or all detectors
1044  // have been work detector
1045  Stream ss;
1046  bool found = false;
1047  auto const tGeom = trackerGeometry_;
1048  DetGroup::const_iterator startDetIter = detGroup.begin();
1049  Span_t phiSpan, phiSpanComp;
1050  unsigned int counter = 0;
1051  while (!found) {
1052  phiSpan = tGeom->idToDet(DetId(*startDetIter))->surface().phiSpan();
1053  for (DetGroup::const_iterator compDetIter = detGroup.begin(); compDetIter != detGroup.end(); ++compDetIter) {
1054  phiSpanComp = tGeom->idToDet(DetId(*compDetIter))->surface().phiSpan();
1055  if (phiRangesOverlap(phiSpan, phiSpanComp) && phiMoreClockwise(phiSpanComp.first, phiSpan.first) &&
1056  startDetIter != compDetIter) {
1057  ++counter;
1058  if (counter > detGroup.size()) {
1060  cspan.phiSpan.second = -std::numeric_limits<float>::epsilon();
1061  return;
1062  }
1063  startDetIter = compDetIter;
1064  break;
1065  } else if (compDetIter == detGroup.end() - 1) {
1066  found = true;
1067  }
1068  }
1069  }
1070  cspan.phiSpan.first = phiSpan.first;
1071  // second with same method}
1072  found = false;
1073  DetGroup::const_iterator endDetIter = detGroup.begin();
1074  counter = 0;
1075  while (!found) {
1076  phiSpan = tGeom->idToDet(DetId(*endDetIter))->surface().phiSpan();
1077  for (DetGroup::const_iterator compDetIter = detGroup.begin(); compDetIter != detGroup.end(); ++compDetIter) {
1078  phiSpanComp = tGeom->idToDet(DetId(*compDetIter))->surface().phiSpan();
1079  if (phiRangesOverlap(phiSpan, phiSpanComp) && phiMoreCounterclockwise(phiSpanComp.second, phiSpan.second) &&
1080  endDetIter != compDetIter) {
1081  ++counter;
1082  if (counter > detGroup.size()) {
1084  cspan.phiSpan.second = -std::numeric_limits<float>::epsilon();
1085  return;
1086  }
1087  endDetIter = compDetIter;
1088  break;
1089  } else if (compDetIter == detGroup.end() - 1) {
1090  found = true;
1091  }
1092  }
1093  }
1094  cspan.phiSpan.second = phiSpan.second;
1095 }
1097  auto cmpFun = [this](det_t detA, det_t detB) {
1098  return trackerGeometry_->idToDet(DetId(detA))->surface().zSpan().first <
1099  trackerGeometry_->idToDet(DetId(detB))->surface().zSpan().first;
1100  };
1101 
1102  auto minmaxIters = std::minmax_element(detGroup.begin(), detGroup.end(), cmpFun);
1103  cspan.zSpan.first = trackerGeometry_->idToDet(DetId(*(minmaxIters.first)))->surface().zSpan().first;
1104  cspan.zSpan.second = trackerGeometry_->idToDet(DetId(*(minmaxIters.second)))->surface().zSpan().second;
1105 }
1107  auto cmpFun = [this](det_t detA, det_t detB) {
1108  return trackerGeometry_->idToDet(DetId(detA))->surface().rSpan().first <
1109  trackerGeometry_->idToDet(DetId(detB))->surface().rSpan().first;
1110  };
1111 
1112  auto minmaxIters = std::minmax_element(detGroup.begin(), detGroup.end(), cmpFun);
1113  cspan.rSpan.first = trackerGeometry_->idToDet(DetId(*(minmaxIters.first)))->surface().rSpan().first;
1114  cspan.rSpan.second = trackerGeometry_->idToDet(DetId(*(minmaxIters.second)))->surface().rSpan().second;
1115 }
1117  auto firstDetIt = detGroup.begin();
1118  if (firstDetIt != detGroup.end()) {
1119  cspan.subdetId = DetId(*firstDetIt).subdetId();
1120  if (cspan.subdetId == 1) {
1121  cspan.layer = trackerTopology_->pxbLayer(DetId(*firstDetIt));
1122  cspan.disk = 0;
1123  getPhiSpanBarrel(detGroup, cspan);
1124  } else if (cspan.subdetId == 2) {
1125  cspan.disk = trackerTopology_->pxfDisk(DetId(*firstDetIt));
1126  cspan.layer = 0;
1127  getPhiSpanEndcap(detGroup, cspan);
1128  }
1129  getZSpan(detGroup, cspan);
1130  getRSpan(detGroup, cspan);
1131  }
1132 }
1134  DetGroupSpanContainer cspansBarrel;
1135  DetGroupSpanContainer cspansEndcap;
1136  DetGroupContainer badDetGroupsBar = badDetGroupsBarrel();
1137  DetGroupContainer badDetGroupsEnd = badDetGroupsEndcap();
1138  for (auto const& detGroup : badDetGroupsBar) {
1139  DetGroupSpan cspan;
1140  getSpan(detGroup, cspan);
1141  cspansBarrel.push_back(cspan);
1142  }
1143  for (auto const& detGroup : badDetGroupsEnd) {
1144  DetGroupSpan cspan;
1145  getSpan(detGroup, cspan);
1146  cspansEndcap.push_back(cspan);
1147  }
1148  return DetGroupSpanContainerPair(cspansBarrel, cspansEndcap);
1149 }
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
tuple ret
prodAgent to be discontinued
const edm::EventSetup & c
ParameterDescriptionBase * addUntracked(U const &iLabel, T const &value)
SeedingLayerSetsBuilder::SeedingLayerId SeedingLayerId
uint16_t *__restrict__ id
std::vector< std::pair< VecArray2< Area >, std::vector< LayerSetIndex > > > areasAndLayerSets(const GlobalPoint &point, float zwidth) const
std::vector< uint32_t > DetGroup
std::vector< edm::EDGetTokenT< DetIdCollection > > inactivePixelDetectorTokens_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > trackerTopologyToken_
std::array< unsigned short, 4 > nBPixLadders
unsigned int pxfDisk(const DetId &id) const
std::pair< float, float > const & zSpan() const
Definition: Surface.h:91
unsigned int pxbLadder(const DetId &id) const
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
def unique
Definition: tier0.py:24
T y() const
Definition: PV3DBase.h:60
unsigned int pxbModule(const DetId &id) const
edm::ESGetToken< SiPixelQuality, SiPixelQualityRcd > pixelQualityToken_
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
std::ostream & operator<<(std::ostream &out, const ALILine &li)
Definition: ALILine.cc:167
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
void updatePixelDets(const edm::EventSetup &iSetup)
badPixelFEDChannelsTokens_(edm::vector_transform(iConfig.getParameter< std::vector< edm::InputTag >>("badPixelFEDChannelCollectionLabels"), [&](const auto &tag){return iC.consumes< PixelFEDChannelCollection >(tag);}))
void emplace_back(Args &&...args)
Definition: VecArray.h:90
static void fillDescriptions(edm::ParameterSetDescription &desc)
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
#define LogTrace(id)
DetGroup reachableDetGroup(const det_t &initDet, DetectorSet &foundDets)
unsigned int numberOfLayers(int subdet) const
constexpr std::array< uint8_t, layerIndexSize > layer
std::vector< std::pair< unsigned short, unsigned short > > inactiveLayerSetIndices_
void getRSpan(const DetGroup &detGroup, DetGroupSpan &cspan)
const uint16_t range(const Frame &aFrame)
bool getData(T &iHolder) const
Definition: EventSetup.h:122
DetGroupContainer badDetGroupsEndcap()
std::tuple< GeomDetEnumerators::SubDetector, TrackerDetSide, int > SeedingLayerId
int iEvent
Definition: GenABIO.cc:224
std::pair< float, float > const & rSpan() const
Definition: Surface.h:92
void getPhiSpanBarrel(const DetGroup &detGroup, DetGroupSpan &cspan)
T z() const
Definition: PV3DBase.h:61
void detInfo(const det_t &det, Stream &ss)
def move
Definition: eostools.py:511
const DetContainer & detsPXB() const
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
const double infinity
std::pair< float, float > const & phiSpan() const
Definition: Surface.h:90
std::set< uint32_t > DetectorSet
DetGroupContainer badDetGroupsBarrel()
DetGroup badAdjecentDetsBarrel(const det_t &det)
InactiveAreas inactiveAreas(const edm::Event &iEvent, const edm::EventSetup &iSetup)
const TrackerGeometry * trackerGeometry_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Log< level::Warning, true > LogPrint
const TrackerGeomDet * idToDet(DetId) const override
void getBadPixelDets(const edm::Event &iEvent, const edm::EventSetup &iSetup)
std::vector< DetGroup > DetGroupContainer
std::vector< edm::EDGetTokenT< PixelFEDChannelCollection > > badPixelFEDChannelsTokens_
unsigned int pxbLayer(const DetId &id) const
Definition: DetId.h:17
pixelQualityToken_(iC.esConsumes())
PixelInactiveAreaFinder(const edm::ParameterSet &iConfig, const std::vector< SeedingLayerId > &seedingLayers, const SeedingLayerSetsLooper &seedingLayerSetsLooper, edm::ConsumesCollector &&iC)
const TrackerTopology * trackerTopology_
std::vector< DetGroupSpan > DetGroupSpanContainer
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometryToken_
void getSpan(const DetGroup &detGroup, DetGroupSpan &cspan)
trackerTopologyToken_(iC.esConsumes())
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
unsigned int layer(const DetId &id) const
deadvectors[0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
static std::atomic< unsigned int > counter
string end
Definition: dataset.py:937
const DetContainer & detsPXF() const
void getPhiSpanEndcap(const DetGroup &detGroup, DetGroupSpan &cspan)
DetGroupSpanContainerPair detGroupSpans()
trackerGeometryToken_(iC.esConsumes())
DetGroup badAdjecentDetsEndcap(const det_t &det)
DetId pxbDetId(uint32_t layer, uint32_t ladder, uint32_t module) const
T x() const
Definition: PV3DBase.h:59
std::pair< DetGroupSpanContainer, DetGroupSpanContainer > DetGroupSpanContainerPair
unsigned int pxfPanel(const DetId &id) const
unsigned int pxfBlade(const DetId &id) const
std::vector< std::vector< LayerSetIndex > > layerSetIndexInactiveToActive_
*vegas h *****************************************************used in the default bin number in original ***version of VEGAS is ***a higher bin number might help to derive a more precise ***grade subtle point
Definition: invegas.h:5
std::vector< SeedingLayerId > inactiveLayers_
std::vector< std::pair< VecArray2< DetGroupSpan >, std::vector< LayerSetIndex > > > spansAndLayerSets(const GlobalPoint &point, float zwidth) const
SeedingLayerSetsHits::LayerSetIndex LayerSetIndex
tuple module
Definition: callgraph.py:69
void getZSpan(const DetGroup &detGroup, DetGroupSpan &cspan)
#define LogDebug(id)
edm::ESWatcher< TrackerDigiGeometryRecord > geometryWatcher_