CMS 3D CMS Logo

PixelInactiveAreaFinder.cc
Go to the documentation of this file.
2 
9 
11 
12 #include <fstream>
13 #include <queue>
14 #include <algorithm>
15 
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); })),
470  badPixelFEDChannelsTokens_(
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 
563  // clear the list of bad pixel modules at each event!
564  badPixelDetsBarrel_.clear();
565  badPixelDetsEndcap_.clear();
566  getBadPixelDets(iEvent, iSetup);
567 
568  //write files for plotting
569  if (createPlottingFiles_) {
571  }
572 
573  // find detGroupSpans ie phi,r,z limits for detector detGroups that are not working
574  // returns pair where first is barrel spans and second endcap spans
576 
577  // map spans to a vector with consistent indexing with inactiveLayers_ and inactiveLayerSetIndices_
578  // TODO: try to move the inner logic towards this direction as well
579  std::vector<DetGroupSpanContainer> spans(inactiveLayers_.size());
580 
581  auto doWork = [&](const DetGroupSpanContainer& container) {
582  for (const auto& span : container) {
583  const auto subdet = span.subdetId == PixelSubdetector::PixelBarrel ? GeomDetEnumerators::PixelBarrel
585  const auto side = (subdet == GeomDetEnumerators::PixelBarrel
587  : (span.zSpan.first < 0 ? TrackerDetSide::NegEndcap : TrackerDetSide::PosEndcap));
588  const auto layer = subdet == GeomDetEnumerators::PixelBarrel ? span.layer : span.disk;
589  auto found = std::find(inactiveLayers_.begin(), inactiveLayers_.end(), SeedingLayerId(subdet, side, layer));
590  if (found != inactiveLayers_.end()) { // it is possible that this layer is ignored by the configuration
591  spans[std::distance(inactiveLayers_.begin(), found)].push_back(span);
592  }
593  }
594  };
595  doWork(cspans.first);
596  doWork(cspans.second);
597 
598  auto ret =
600 
601  if (debug_) {
602  printOverlapSpans(ret);
603  }
604 
605  return ret;
606 }
607 
608 // Functions for fetching date from handles
610  if (!geometryWatcher_.check(iSetup))
611  return;
612 
613  // deduce the number of ladders per layer and the number of modules per ladder
614  {
615  // sanity checks
617  throw cms::Exception("NotImplemented")
618  << "This module supports only a detector with 4 pixel barrel layers, the current geometry has "
620  }
622  throw cms::Exception("NotImplemented")
623  << "This module supports only a detector with 3 pixel forward disks, the current geometry has "
625  }
626 
627  std::array<std::array<unsigned short, 100>, 4> counts = {}; // assume at most 100 ladders per layer
628  for (const auto& det : trackerGeometry_->detsPXB()) {
629  const auto layer = trackerTopology_->layer(det->geographicalId());
630  const auto ladder = trackerTopology_->pxbLadder(det->geographicalId());
631  if (ladder >= 100) {
632  throw cms::Exception("LogicError")
633  << "Got a ladder with number " << ladder
634  << " while the expected maximum was 100; either something is wrong or the maximum has to be increased.";
635  }
636  counts[layer - 1][ladder - 1] += 1; // numbering of layer and ladder starts at 1
637  }
638 
639  // take number of modules per ladder from the first ladder of the first layer (such better exist)
640  // other ladders better have the same number
641  nModulesPerLadder = counts[0][0];
642  if (nModulesPerLadder == 0) {
643  throw cms::Exception("LogicError") << "Ladder 1 of layer 1 has 0 modules, something fishy is going on.";
644  }
645 
646  LogDebug("PixelInactiveAreaFinder") << "Number of modules per ladder " << nModulesPerLadder
647  << "; below are number of ladders per layer";
648 
649  // number of ladders
650  for (unsigned layer = 0; layer < 4; ++layer) {
652  std::count_if(counts[layer].begin(), counts[layer].end(), [](unsigned short val) { return val > 0; });
653  LogTrace("PixelInactiveAreaFinder")
654  << "BPix layer " << (layer + 1) << " has " << nBPixLadders[layer] << " ladders";
655 
656  auto fail = std::count_if(counts[layer].begin(), counts[layer].end(), [&](unsigned short val) {
657  return val != nModulesPerLadder && val > 0;
658  });
659  if (fail != 0) {
660  throw cms::Exception("LogicError")
661  << "Layer " << (layer + 1) << " had " << fail
662  << " ladders whose number of modules/ladder differed from the ladder 1 of layer 1 (" << nModulesPerLadder
663  << "). Something fishy is going on.";
664  }
665  }
666  }
667 
668  // don't bother with the rest if not needed
670  return;
671 
672  pixelDetsBarrel_.clear();
673  pixelDetsEndcap_.clear();
674 
675  for (auto const& geomDetPtr : trackerGeometry_->detsPXB()) {
676  if (geomDetPtr->geographicalId().subdetId() == PixelSubdetector::PixelBarrel) {
677  pixelDetsBarrel_.push_back(geomDetPtr->geographicalId().rawId());
678  }
679  }
680  for (auto const& geomDetPtr : trackerGeometry_->detsPXF()) {
681  if (geomDetPtr->geographicalId().subdetId() == PixelSubdetector::PixelEndcap) {
682  pixelDetsEndcap_.push_back(geomDetPtr->geographicalId().rawId());
683  }
684  }
687 }
689  auto addDetId = [&](const auto id) {
690  const auto detid = DetId(id);
691  const auto subdet = detid.subdetId();
692  if (subdet == PixelSubdetector::PixelBarrel) {
693  badPixelDetsBarrel_.push_back(detid.rawId());
694  } else if (subdet == PixelSubdetector::PixelEndcap) {
695  badPixelDetsEndcap_.push_back(detid.rawId());
696  }
697  };
698 
699  // SiPixelQuality
700  auto const& pixelQuality = iSetup.getData(pixelQualityToken_);
701 
702  for (auto const& disabledModule : pixelQuality.getBadComponentList()) {
703  addDetId(disabledModule.DetID);
704  }
705 
706  // dynamic bad modules
707  for (const auto& token : inactivePixelDetectorTokens_) {
709  iEvent.getByToken(token, detIds);
710  for (const auto& id : *detIds) {
711  addDetId(id);
712  }
713  }
714 
715  // dynamic bad ROCs ("Fed25")
716  // TODO: consider moving to finer-grained areas for inactive ROCs
717  for (const auto& token : badPixelFEDChannelsTokens_) {
718  edm::Handle<PixelFEDChannelCollection> pixelFEDChannelCollectionHandle;
719  iEvent.getByToken(token, pixelFEDChannelCollectionHandle);
720  for (const auto& disabledChannels : *pixelFEDChannelCollectionHandle) {
721  addDetId(disabledChannels.detId());
722  }
723  }
724 
725  // remove duplicates
729  badPixelDetsBarrel_.end());
731  badPixelDetsEndcap_.end());
732 }
733 // Printing functions
735  using std::fixed;
736  using std::left;
737  using std::noshowpos;
738  using std::right;
739  using std::setfill;
740  using std::setprecision;
741  using std::setw;
742  using std::showpos;
743  using std::tie;
744  std::string deli = "; ";
745  ss << "id:[" << det << "]" << deli;
746  ss << "subdetid:[" << DetId(det).subdetId() << "]" << deli;
747  if (DetId(det).subdetId() == PixelSubdetector::PixelBarrel) {
748  unsigned int layer = trackerTopology_->pxbLayer(DetId(det));
749  unsigned int ladder = trackerTopology_->pxbLadder(DetId(det));
750  unsigned int module = trackerTopology_->pxbModule(DetId(det));
751  ss << "layer:[" << layer << "]" << deli << "ladder:[" << right << setw(2) << ladder << "]" << deli << "module:["
752  << module << "]" << deli;
753  } else if (DetId(det).subdetId() == PixelSubdetector::PixelEndcap) {
754  unsigned int disk = trackerTopology_->pxfDisk(DetId(det));
755  unsigned int blade = trackerTopology_->pxfBlade(DetId(det));
756  unsigned int panel = trackerTopology_->pxfPanel(DetId(det));
757  ss << left << setw(6) << "disk:"
758  << "[" << right << disk << "]" << deli << left << setw(7) << "blade:"
759  << "[" << setw(2) << right << blade << "]" << deli << left << setw(7) << "panel:"
760  << "[" << right << panel << "]" << deli;
761  }
762  float phiA, phiB, zA, zB, rA, rB;
763  auto detSurface = trackerGeometry_->idToDet(DetId(det))->surface();
764  tie(phiA, phiB) = detSurface.phiSpan();
765  tie(zA, zB) = detSurface.zSpan();
766  tie(rA, rB) = detSurface.rSpan();
767  ss << setprecision(16) << fixed << showpos << setfill(' ') << "phi:[" << right << setw(12) << phiA << "," << left
768  << setw(12) << phiB << "]" << deli << "z:[" << right << setw(7) << zA << "," << left << setw(7) << zB << "]"
769  << deli << noshowpos << "r:[" << right << setw(10) << rA << "," << left << setw(10) << rB << "]" << deli;
770 }
772  edm::LogPrint("PixelInactiveAreaFinder") << "Barrel detectors:";
773  Stream ss;
774  for (auto const& det : pixelDetsBarrel_) {
775  detInfo(det, ss);
776  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
777  ss.str(std::string());
778  }
779  edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
780  for (auto const& det : pixelDetsEndcap_) {
781  detInfo(det, ss);
782  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
783  ss.str(std::string());
784  }
785 }
787  edm::LogPrint("PixelInactiveAreaFinder") << "Bad barrel detectors:";
788  Stream ss;
789  for (auto const& det : badPixelDetsBarrel_) {
790  detInfo(det, ss);
791  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
792  ss.str(std::string());
793  }
794  edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
795  for (auto const& det : badPixelDetsEndcap_) {
796  detInfo(det, ss);
797  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
798  ss.str(std::string());
799  }
800 }
802  DetGroupContainer badDetGroupsBar = badDetGroupsBarrel();
803  DetGroupContainer badDetGroupsEnd = badDetGroupsEndcap();
804  Stream ss;
805  for (auto const& detGroup : badDetGroupsBar) {
806  ss << std::setfill(' ') << std::left << std::setw(16) << "DetGroup:";
807  DetGroupSpan cspan;
808  getPhiSpanBarrel(detGroup, cspan);
809  getZSpan(detGroup, cspan);
810  getRSpan(detGroup, cspan);
811  detGroupSpanInfo(cspan, ss);
812  ss << std::endl;
813  for (auto const& det : detGroup) {
814  detInfo(det, ss);
815  ss << std::endl;
816  }
817  ss << std::endl;
818  }
819  for (auto const& detGroup : badDetGroupsEnd) {
820  ss << std::setfill(' ') << std::left << std::setw(16) << "DetGroup:";
821  DetGroupSpan cspan;
822  getPhiSpanEndcap(detGroup, cspan);
823  getZSpan(detGroup, cspan);
824  getRSpan(detGroup, cspan);
825  detGroupSpanInfo(cspan, ss);
826  ss << std::endl;
827  for (auto const& det : detGroup) {
828  detInfo(det, ss);
829  ss << std::endl;
830  }
831  ss << std::endl;
832  }
833  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
834 }
837  Stream ss;
838  for (auto const& cspan : cspans.first) {
839  detGroupSpanInfo(cspan, ss);
840  ss << std::endl;
841  }
842  for (auto const& cspan : cspans.second) {
843  detGroupSpanInfo(cspan, ss);
844  ss << std::endl;
845  }
846  edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
847 }
849  // All detectors to file DETECTORS
850  Stream ss;
851  std::ofstream fsDet("DETECTORS.txt");
852  for (auto const& det : pixelDetsBarrel_) {
853  detInfo(det, ss);
854  ss << std::endl;
855  }
856  edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
857  for (auto const& det : pixelDetsEndcap_) {
858  detInfo(det, ss);
859  ss << std::endl;
860  }
861  fsDet << ss.rdbuf();
862  ss.str(std::string());
863  // Bad detectors
864  std::ofstream fsBadDet("BADDETECTORS.txt");
865  for (auto const& det : badPixelDetsBarrel_) {
866  detInfo(det, ss);
867  ss << std::endl;
868  }
869  for (auto const& det : badPixelDetsEndcap_) {
870  detInfo(det, ss);
871  ss << std::endl;
872  }
873  fsBadDet << ss.rdbuf();
874  ss.str(std::string());
875  // detgroupspans
876  std::ofstream fsSpans("DETGROUPSPANS.txt");
878  for (auto const& cspan : cspans.first) {
879  detGroupSpanInfo(cspan, ss);
880  ss << std::endl;
881  }
882  for (auto const& cspan : cspans.second) {
883  detGroupSpanInfo(cspan, ss);
884  ss << std::endl;
885  }
886  fsSpans << ss.rdbuf();
887  ss.str(std::string());
888 }
889 // Functions for finding bad detGroups
891  return std::find(badPixelDetsBarrel_.begin(), badPixelDetsBarrel_.end(), det) == badPixelDetsBarrel_.end() &&
893 }
895  using std::remove_if;
896 
897  DetGroup adj;
898  auto const tTopo = trackerTopology_;
899  auto const& detId = DetId(det);
900  unsigned int layer = tTopo->pxbLayer(detId);
901  unsigned int ladder = tTopo->pxbLadder(detId);
902  unsigned int module = tTopo->pxbModule(detId);
903  unsigned int nLads = nBPixLadders[layer];
904  //add detectors from next and previous ladder
905  adj.push_back(tTopo->pxbDetId(layer, ((ladder - 1) + 1) % nLads + 1, module)());
906  adj.push_back(tTopo->pxbDetId(layer, ((ladder - 1) - 1 + nLads) % nLads + 1, module)());
907  //add adjecent detectors from same ladder
908  if (module == 1) {
909  adj.push_back(tTopo->pxbDetId(layer, ladder, module + 1)());
910  } else if (module == nModulesPerLadder) {
911  adj.push_back(tTopo->pxbDetId(layer, ladder, module - 1)());
912  } else {
913  adj.push_back(tTopo->pxbDetId(layer, ladder, module + 1)());
914  adj.push_back(tTopo->pxbDetId(layer, ladder, module - 1)());
915  }
916  //remove working detectors from list
917  adj.erase(remove_if(adj.begin(), adj.end(), [&](auto c) { return this->detWorks(c); }), adj.end());
918  return adj;
919 }
921  // this might be faster if adjecent
922  using std::ignore;
923  using std::tie;
924  DetGroup adj;
925  Span_t phiSpan, phiSpanComp;
926  float z, zComp;
927  unsigned int disk, diskComp;
928  auto const& detSurf = trackerGeometry_->idToDet(DetId(det))->surface();
929  phiSpan = detSurf.phiSpan();
930  tie(z, ignore) = detSurf.zSpan();
931  disk = trackerTopology_->pxfDisk(DetId(det));
932  // add detectors from same disk whose phi ranges overlap to the adjecent list
933  for (auto const& detComp : badPixelDetsEndcap_) {
934  auto const& detIdComp = DetId(detComp);
935  auto const& detSurfComp = trackerGeometry_->idToDet(detIdComp)->surface();
936  diskComp = trackerTopology_->pxfDisk(detIdComp);
937  phiSpanComp = detSurfComp.phiSpan();
938  tie(zComp, ignore) = detSurfComp.zSpan();
939  if (det != detComp && disk == diskComp && z * zComp > 0 && phiRangesOverlap(phiSpan, phiSpanComp)) {
940  adj.push_back(detComp);
941  }
942  }
943  return adj;
944 }
946  DetectorSet& foundDets) {
948  std::queue<det_t> workQueue;
949  det_t workDet;
950  DetGroup badAdjDets;
951  foundDets.insert(initDet);
952  workQueue.push(initDet);
953  reachableDetGroup.push_back(initDet);
954  while (!workQueue.empty()) {
955  workDet = workQueue.front();
956  workQueue.pop();
957  if (DetId(workDet).subdetId() == PixelSubdetector::PixelBarrel) {
958  badAdjDets = this->badAdjecentDetsBarrel(workDet);
959  } else if (DetId(workDet).subdetId() == PixelSubdetector::PixelEndcap) {
960  badAdjDets = this->badAdjecentDetsEndcap(workDet);
961  } else {
962  badAdjDets = {};
963  }
964  for (auto const& badDet : badAdjDets) {
965  if (foundDets.find(badDet) == foundDets.end()) {
966  reachableDetGroup.push_back(badDet);
967  foundDets.insert(badDet);
968  workQueue.push(badDet);
969  }
970  }
971  }
972  return reachableDetGroup;
973 }
975  DetGroupContainer detGroups;
976  DetectorSet foundDets;
977  for (auto const& badDet : badPixelDetsBarrel_) {
978  if (foundDets.find(badDet) == foundDets.end()) {
979  detGroups.push_back(this->reachableDetGroup(badDet, foundDets));
980  }
981  }
982  return detGroups;
983 }
985  DetGroupContainer detGroups;
986  DetectorSet foundDets;
987  for (auto const& badDet : badPixelDetsEndcap_) {
988  if (foundDets.find(badDet) == foundDets.end()) {
989  auto adjacentDets = this->reachableDetGroup(badDet, foundDets);
990  if (ignoreSingleFPixPanelModules_ && adjacentDets.size() == 1) {
991  // size==1 means that only a single panel of a blade was inactive
992  // because of the large overlap with the other panel (i.e.
993  // redundancy in the detectory) ignoring these may help to decrease fakes
994  continue;
995  }
996  detGroups.push_back(adjacentDets);
997  }
998  }
999  return detGroups;
1000 }
1001 // Functions for finding DetGroupSpans
1003  // find phiSpan using ordered vector of unique ladders in detGroup
1004  if (detGroup.empty()) {
1005  cspan = DetGroupSpan();
1006  return;
1007  } else {
1008  cspan.layer = trackerTopology_->pxbLayer(DetId(detGroup[0]));
1009  cspan.disk = 0;
1010  }
1011  using uint = unsigned int;
1012  using LadderSet = std::set<uint>;
1013  using LadVec = std::vector<uint>;
1014  LadderSet lads;
1015  for (auto const& det : detGroup) {
1016  lads.insert(trackerTopology_->pxbLadder(DetId(det)));
1017  }
1018  LadVec ladv(lads.begin(), lads.end());
1019  uint nLadders = nBPixLadders[cspan.layer];
1020  // find start ladder of detGroup
1021  uint i = 0;
1022  uint currentLadder = ladv[0];
1023  uint previousLadder = ladv[(ladv.size() + i - 1) % ladv.size()];
1024  // loop until discontinuity is found from vector
1025  while ((nLadders + currentLadder - 1) % nLadders == previousLadder) {
1026  ++i;
1027  currentLadder = ladv[i % ladv.size()];
1028  previousLadder = ladv[(ladv.size() + i - 1) % ladv.size()];
1029  if (i == ladv.size()) {
1031  cspan.phiSpan.second = -std::numeric_limits<float>::epsilon();
1032  return;
1033  }
1034  }
1035  uint startLadder = currentLadder;
1036  uint endLadder = previousLadder;
1037  auto detStart = trackerTopology_->pxbDetId(cspan.layer, startLadder, 1);
1038  auto detEnd = trackerTopology_->pxbDetId(cspan.layer, endLadder, 1);
1039  cspan.phiSpan.first = trackerGeometry_->idToDet(detStart)->surface().phiSpan().first;
1040  cspan.phiSpan.second = trackerGeometry_->idToDet(detEnd)->surface().phiSpan().second;
1041 }
1043  // this is quite naive/bruteforce method
1044  // 1) it starts by taking one detector from detGroup and starts to compare it to others
1045  // 2) when it finds overlapping detector in clockwise direction it starts comparing
1046  // found detector to others
1047  // 3) search stops until no overlapping detectors in clockwise detector or all detectors
1048  // have been work detector
1049  Stream ss;
1050  bool found = false;
1051  auto const tGeom = trackerGeometry_;
1052  DetGroup::const_iterator startDetIter = detGroup.begin();
1053  Span_t phiSpan, phiSpanComp;
1054  unsigned int counter = 0;
1055  while (!found) {
1056  phiSpan = tGeom->idToDet(DetId(*startDetIter))->surface().phiSpan();
1057  for (DetGroup::const_iterator compDetIter = detGroup.begin(); compDetIter != detGroup.end(); ++compDetIter) {
1058  phiSpanComp = tGeom->idToDet(DetId(*compDetIter))->surface().phiSpan();
1059  if (phiRangesOverlap(phiSpan, phiSpanComp) && phiMoreClockwise(phiSpanComp.first, phiSpan.first) &&
1060  startDetIter != compDetIter) {
1061  ++counter;
1062  if (counter > detGroup.size()) {
1064  cspan.phiSpan.second = -std::numeric_limits<float>::epsilon();
1065  return;
1066  }
1067  startDetIter = compDetIter;
1068  break;
1069  } else if (compDetIter == detGroup.end() - 1) {
1070  found = true;
1071  }
1072  }
1073  }
1074  cspan.phiSpan.first = phiSpan.first;
1075  // second with same method}
1076  found = false;
1077  DetGroup::const_iterator endDetIter = detGroup.begin();
1078  counter = 0;
1079  while (!found) {
1080  phiSpan = tGeom->idToDet(DetId(*endDetIter))->surface().phiSpan();
1081  for (DetGroup::const_iterator compDetIter = detGroup.begin(); compDetIter != detGroup.end(); ++compDetIter) {
1082  phiSpanComp = tGeom->idToDet(DetId(*compDetIter))->surface().phiSpan();
1083  if (phiRangesOverlap(phiSpan, phiSpanComp) && phiMoreCounterclockwise(phiSpanComp.second, phiSpan.second) &&
1084  endDetIter != compDetIter) {
1085  ++counter;
1086  if (counter > detGroup.size()) {
1088  cspan.phiSpan.second = -std::numeric_limits<float>::epsilon();
1089  return;
1090  }
1091  endDetIter = compDetIter;
1092  break;
1093  } else if (compDetIter == detGroup.end() - 1) {
1094  found = true;
1095  }
1096  }
1097  }
1098  cspan.phiSpan.second = phiSpan.second;
1099 }
1101  auto cmpFun = [this](det_t detA, det_t detB) {
1102  return trackerGeometry_->idToDet(DetId(detA))->surface().zSpan().first <
1103  trackerGeometry_->idToDet(DetId(detB))->surface().zSpan().first;
1104  };
1105 
1106  auto minmaxIters = std::minmax_element(detGroup.begin(), detGroup.end(), cmpFun);
1107  cspan.zSpan.first = trackerGeometry_->idToDet(DetId(*(minmaxIters.first)))->surface().zSpan().first;
1108  cspan.zSpan.second = trackerGeometry_->idToDet(DetId(*(minmaxIters.second)))->surface().zSpan().second;
1109 }
1111  auto cmpFun = [this](det_t detA, det_t detB) {
1112  return trackerGeometry_->idToDet(DetId(detA))->surface().rSpan().first <
1113  trackerGeometry_->idToDet(DetId(detB))->surface().rSpan().first;
1114  };
1115 
1116  auto minmaxIters = std::minmax_element(detGroup.begin(), detGroup.end(), cmpFun);
1117  cspan.rSpan.first = trackerGeometry_->idToDet(DetId(*(minmaxIters.first)))->surface().rSpan().first;
1118  cspan.rSpan.second = trackerGeometry_->idToDet(DetId(*(minmaxIters.second)))->surface().rSpan().second;
1119 }
1121  auto firstDetIt = detGroup.begin();
1122  if (firstDetIt != detGroup.end()) {
1123  cspan.subdetId = DetId(*firstDetIt).subdetId();
1124  if (cspan.subdetId == 1) {
1125  cspan.layer = trackerTopology_->pxbLayer(DetId(*firstDetIt));
1126  cspan.disk = 0;
1127  getPhiSpanBarrel(detGroup, cspan);
1128  } else if (cspan.subdetId == 2) {
1129  cspan.disk = trackerTopology_->pxfDisk(DetId(*firstDetIt));
1130  cspan.layer = 0;
1131  getPhiSpanEndcap(detGroup, cspan);
1132  }
1133  getZSpan(detGroup, cspan);
1134  getRSpan(detGroup, cspan);
1135  }
1136 }
1138  DetGroupSpanContainer cspansBarrel;
1139  DetGroupSpanContainer cspansEndcap;
1140  DetGroupContainer badDetGroupsBar = badDetGroupsBarrel();
1141  DetGroupContainer badDetGroupsEnd = badDetGroupsEndcap();
1142  for (auto const& detGroup : badDetGroupsBar) {
1143  DetGroupSpan cspan;
1144  getSpan(detGroup, cspan);
1145  cspansBarrel.push_back(cspan);
1146  }
1147  for (auto const& detGroup : badDetGroupsEnd) {
1148  DetGroupSpan cspan;
1149  getSpan(detGroup, cspan);
1150  cspansEndcap.push_back(cspan);
1151  }
1152  return DetGroupSpanContainerPair(cspansBarrel, cspansEndcap);
1153 }
constexpr double deltaPhi(double phi1, double phi2)
Definition: deltaPhi.h:26
unsigned int pxbLayer(const DetId &id) const
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
SeedingLayerSetsBuilder::SeedingLayerId SeedingLayerId
unsigned int pxfBlade(const DetId &id) const
const DetContainer & detsPXB() const
std::vector< uint32_t > DetGroup
unsigned int numberOfLayers(int subdet) const
std::vector< edm::EDGetTokenT< DetIdCollection > > inactivePixelDetectorTokens_
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > trackerTopologyToken_
std::array< unsigned short, 4 > nBPixLadders
ret
prodAgent to be discontinued
Global3DPoint GlobalPoint
Definition: GlobalPoint.h:10
std::vector< std::pair< VecArray2< Area >, std::vector< LayerSetIndex > > > areasAndLayerSets(const GlobalPoint &point, float zwidth) const
std::ostream & operator<<(std::ostream &os, SeedingLayerSetsBuilder::SeedingLayerId layer)
const DetContainer & detsPXF() const
edm::ESGetToken< SiPixelQuality, SiPixelQualityRcd > pixelQualityToken_
unsigned int pxbLadder(const DetId &id) const
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
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)
static void fillDescriptions(edm::ParameterSetDescription &desc)
unsigned int layer(const DetId &id) const
#define LogTrace(id)
DetGroup reachableDetGroup(const det_t &initDet, DetectorSet &foundDets)
std::vector< std::pair< unsigned short, unsigned short > > inactiveLayerSetIndices_
void getRSpan(const DetGroup &detGroup, DetGroupSpan &cspan)
std::vector< std::pair< VecArray2< DetGroupSpan >, std::vector< LayerSetIndex > > > spansAndLayerSets(const GlobalPoint &point, float zwidth) const
DetGroupContainer badDetGroupsEndcap()
std::tuple< GeomDetEnumerators::SubDetector, TrackerDetSide, int > SeedingLayerId
int iEvent
Definition: GenABIO.cc:224
void getPhiSpanBarrel(const DetGroup &detGroup, DetGroupSpan &cspan)
std::pair< float, float > const & zSpan() const
Definition: Surface.h:91
def unique(seq, keepstr=True)
Definition: tier0.py:24
void detInfo(const det_t &det, Stream &ss)
unsigned int pxfDisk(const DetId &id) const
const double infinity
std::set< uint32_t > DetectorSet
DetGroupContainer badDetGroupsBarrel()
DetGroup badAdjecentDetsBarrel(const det_t &det)
std::pair< float, float > const & phiSpan() const
Definition: Surface.h:90
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
InactiveAreas inactiveAreas(const edm::Event &iEvent, const edm::EventSetup &iSetup)
std::pair< float, float > const & rSpan() const
Definition: Surface.h:92
const TrackerGeometry * trackerGeometry_
Log< level::Warning, true > LogPrint
DetId pxbDetId(uint32_t layer, uint32_t ladder, uint32_t module) const
const TrackerGeomDet * idToDet(DetId) const override
void getBadPixelDets(const edm::Event &iEvent, const edm::EventSetup &iSetup)
def ignore(seq)
std::vector< DetGroup > DetGroupContainer
std::vector< edm::EDGetTokenT< PixelFEDChannelCollection > > badPixelFEDChannelsTokens_
unsigned int pxfPanel(const DetId &id) const
Definition: DetId.h:17
PixelInactiveAreaFinder(const edm::ParameterSet &iConfig, const std::vector< SeedingLayerId > &seedingLayers, const SeedingLayerSetsLooper &seedingLayerSetsLooper, edm::ConsumesCollector &&iC)
std::vector< Frame > Stream
Definition: TTTypes.h:65
const Plane & surface() const
The nominal surface of the GeomDet.
Definition: GeomDet.h:37
const TrackerTopology * trackerTopology_
std::vector< DetGroupSpan > DetGroupSpanContainer
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > trackerGeometryToken_
void getSpan(const DetGroup &detGroup, DetGroupSpan &cspan)
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
deadvectors [0] push_back({0.0175431, 0.538005, 6.80997, 13.29})
void emplace_back(Args &&... args)
Definition: VecArray.h:90
HLT enums.
static std::atomic< unsigned int > counter
void getPhiSpanEndcap(const DetGroup &detGroup, DetGroupSpan &cspan)
DetGroupSpanContainerPair detGroupSpans()
DetGroup badAdjecentDetsEndcap(const det_t &det)
unsigned int pxbModule(const DetId &id) const
std::pair< DetGroupSpanContainer, DetGroupSpanContainer > DetGroupSpanContainerPair
std::vector< std::vector< LayerSetIndex > > layerSetIndexInactiveToActive_
def move(src, dest)
Definition: eostools.py:511
*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_
SeedingLayerSetsHits::LayerSetIndex LayerSetIndex
void getZSpan(const DetGroup &detGroup, DetGroupSpan &cspan)
#define LogDebug(id)
edm::ESWatcher< TrackerDigiGeometryRecord > geometryWatcher_