CMS 3D CMS Logo

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