File indexing completed on 2024-04-06 12:28:57
0001 #include "PixelInactiveAreaFinder.h"
0002
0003 #include "FWCore/Utilities/interface/VecArray.h"
0004 #include "FWCore/Utilities/interface/transform.h"
0005 #include "CondFormats/SiPixelObjects/interface/SiPixelQuality.h"
0006 #include "DataFormats/Math/interface/deltaPhi.h"
0007 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0008 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0009
0010 #include "TrackingTools/TransientTrackingRecHit/interface/SeedingLayerSetsLooper.h"
0011
0012 #include <fstream>
0013 #include <queue>
0014 #include <algorithm>
0015
0016 std::ostream& operator<<(std::ostream& os, SeedingLayerSetsBuilder::SeedingLayerId layer) {
0017 if (std::get<0>(layer) == GeomDetEnumerators::PixelBarrel) {
0018 os << "BPix";
0019 } else {
0020 os << "FPix";
0021 }
0022 os << std::get<2>(layer);
0023 if (std::get<1>(layer) == TrackerDetSide::PosEndcap) {
0024 os << "_pos";
0025 } else if (std::get<1>(layer) == TrackerDetSide::NegEndcap) {
0026 os << "_neg";
0027 }
0028 return os;
0029 }
0030
0031 namespace {
0032 using LayerPair = std::pair<SeedingLayerSetsBuilder::SeedingLayerId, SeedingLayerSetsBuilder::SeedingLayerId>;
0033 using ActiveLayerSetToInactiveSetsMap = std::map<LayerPair, edm::VecArray<LayerPair, 5>>;
0034 using Stream = std::stringstream;
0035 using Span_t = std::pair<float, float>;
0036
0037 ActiveLayerSetToInactiveSetsMap createActiveToInactiveMap() {
0038 ActiveLayerSetToInactiveSetsMap map;
0039
0040 auto bpix = [](int layer) {
0041 return SeedingLayerSetsBuilder::SeedingLayerId(GeomDetEnumerators::PixelBarrel, TrackerDetSide::Barrel, layer);
0042 };
0043 auto fpix_pos = [](int disk) {
0044 return SeedingLayerSetsBuilder::SeedingLayerId(GeomDetEnumerators::PixelEndcap, TrackerDetSide::PosEndcap, disk);
0045 };
0046 auto fpix_neg = [](int disk) {
0047 return SeedingLayerSetsBuilder::SeedingLayerId(GeomDetEnumerators::PixelEndcap, TrackerDetSide::NegEndcap, disk);
0048 };
0049
0050 auto add_permutations = [&](std::array<SeedingLayerSetsBuilder::SeedingLayerId, 4> quads) {
0051 do {
0052
0053
0054 if (quads[0] > quads[1] || quads[2] > quads[3])
0055 continue;
0056
0057 map[std::make_pair(quads[0], quads[1])].emplace_back(quads[2], quads[3]);
0058 } while (std::next_permutation(quads.begin(), quads.end()));
0059 };
0060
0061
0062 add_permutations({{bpix(1), bpix(2), bpix(3), bpix(4)}});
0063
0064
0065 add_permutations({{bpix(1), bpix(2), bpix(3), fpix_pos(1)}});
0066 add_permutations({{bpix(1), bpix(2), bpix(3), fpix_neg(1)}});
0067
0068
0069 add_permutations({{bpix(1), bpix(2), fpix_pos(1), fpix_pos(2)}});
0070 add_permutations({{bpix(1), bpix(2), fpix_neg(1), fpix_neg(2)}});
0071
0072
0073 add_permutations({{bpix(1), fpix_pos(1), fpix_pos(2), fpix_pos(3)}});
0074 add_permutations({{bpix(1), fpix_neg(1), fpix_neg(2), fpix_neg(3)}});
0075
0076 #ifdef EDM_ML_DEBUG
0077 LogDebug("PixelInactiveAreaFinder") << "Active to inactive mapping";
0078 for (const auto& elem : map) {
0079 std::stringstream ss;
0080 for (const auto& layerPair : elem.second) {
0081 ss << layerPair.first << "+" << layerPair.second << ",";
0082 }
0083 LogTrace("PixelInactiveAreaFinder") << " " << elem.first.first << "+" << elem.first.second << " => " << ss.str();
0084 }
0085 #endif
0086
0087 return map;
0088 }
0089
0090 void detGroupSpanInfo(const PixelInactiveAreaFinder::DetGroupSpan& cspan, Stream& ss) {
0091 using std::fixed;
0092 using std::left;
0093 using std::noshowpos;
0094 using std::right;
0095 using std::setfill;
0096 using std::setprecision;
0097 using std::setw;
0098 using std::showpos;
0099 std::string deli = "; ";
0100 ss << "subdetid:[" << cspan.subdetId << "]" << deli;
0101 if (cspan.subdetId == PixelSubdetector::PixelBarrel) {
0102 ss << "layer:[" << cspan.layer << "]" << deli;
0103 } else {
0104 ss << "disk:[" << cspan.disk << "]" << deli;
0105 }
0106 ss
0107
0108 << setprecision(16) << showpos << "phi:<" << right << setw(12) << cspan.phiSpan.first << "," << left << setw(12)
0109 << cspan.phiSpan.second << ">" << deli << "z:<" << right << setw(7) << cspan.zSpan.first << "," << left
0110 << setw(7) << cspan.zSpan.second << ">" << deli << noshowpos << "r:<" << right << setw(10) << cspan.rSpan.first
0111 << "," << left << setw(10) << cspan.rSpan.second << ">" << deli;
0112 }
0113 void printOverlapSpans(const PixelInactiveAreaFinder::InactiveAreas& areasLayers) {
0114 auto spansLayerSets = areasLayers.spansAndLayerSets(GlobalPoint(0, 0, 0), std::numeric_limits<float>::infinity());
0115
0116 Stream ss;
0117 for (auto const& spansLayers : spansLayerSets) {
0118 ss << "Overlapping detGroups:\n";
0119 for (auto const& cspan : spansLayers.first) {
0120 detGroupSpanInfo(cspan, ss);
0121 ss << std::endl;
0122 }
0123 }
0124 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0125 }
0126
0127
0128 bool phiRangesOverlap(const Span_t& phiSpanA, const Span_t& phiSpanB) {
0129 float x1, x2, y1, y2;
0130 std::tie(x1, x2) = phiSpanA;
0131 std::tie(y1, y2) = phiSpanB;
0132
0133 if (x1 <= x2 && y1 <= y2) {
0134 return x1 <= y2 && y1 <= x2;
0135 } else if ((x1 > x2 && y1 <= y2) || (y1 > y2 && x1 <= x2)) {
0136 return y1 <= x2 || x1 <= y2;
0137 } else if (x1 > x2 && y1 > y2) {
0138 return true;
0139 } else {
0140 return false;
0141 }
0142 }
0143
0144
0145 bool phiMoreClockwise(float phiA, float phiB) {
0146
0147 return reco::deltaPhi(phiA, phiB) <= 0.f;
0148 }
0149 bool phiMoreCounterclockwise(float phiA, float phiB) {
0150
0151 return reco::deltaPhi(phiA, phiB) >= 0.f;
0152 }
0153
0154
0155 float zAxisIntersection(const float zrPointA[2], const float zrPointB[2]) {
0156 return (zrPointB[0] - zrPointA[0]) / (zrPointB[1] - zrPointA[1]) * (-zrPointA[1]) + zrPointA[0];
0157 }
0158 bool getZAxisOverlapRangeBarrel(const PixelInactiveAreaFinder::DetGroupSpan& cspanA,
0159 const PixelInactiveAreaFinder::DetGroupSpan& cspanB,
0160 std::pair<float, float>& range) {
0161 PixelInactiveAreaFinder::DetGroupSpan cspanUpper;
0162 PixelInactiveAreaFinder::DetGroupSpan cspanLower;
0163 if (cspanA.rSpan.second < cspanB.rSpan.first) {
0164 cspanLower = cspanA;
0165 cspanUpper = cspanB;
0166 } else if (cspanA.rSpan.first > cspanB.rSpan.second) {
0167 cspanUpper = cspanA;
0168 cspanLower = cspanB;
0169 } else {
0170 return false;
0171 }
0172 float lower = 0;
0173 float upper = 0;
0174 if (cspanUpper.zSpan.second < cspanLower.zSpan.first) {
0175
0176 const float pointUpperDetGroupL[2] = {cspanUpper.zSpan.second, cspanUpper.rSpan.second};
0177 const float pointLowerDetGroupL[2] = {cspanLower.zSpan.first, cspanLower.rSpan.first};
0178 lower = zAxisIntersection(pointUpperDetGroupL, pointLowerDetGroupL);
0179
0180 const float pointUpperDetGroupU[2] = {cspanUpper.zSpan.first, cspanUpper.rSpan.first};
0181 const float pointLowerDetGroupU[2] = {cspanLower.zSpan.second, cspanLower.rSpan.second};
0182 upper = zAxisIntersection(pointUpperDetGroupU, pointLowerDetGroupU);
0183 } else if (cspanUpper.zSpan.first <= cspanLower.zSpan.second && cspanLower.zSpan.first <= cspanUpper.zSpan.second) {
0184
0185 const float pointUpperDetGroupL[2] = {cspanUpper.zSpan.second, cspanUpper.rSpan.first};
0186 const float pointLowerDetGroupL[2] = {cspanLower.zSpan.first, cspanLower.rSpan.second};
0187 lower = zAxisIntersection(pointUpperDetGroupL, pointLowerDetGroupL);
0188
0189 const float pointUpperDetGroupU[2] = {cspanUpper.zSpan.first, cspanUpper.rSpan.first};
0190 const float pointLowerDetGroupU[2] = {cspanLower.zSpan.second, cspanLower.rSpan.second};
0191 upper = zAxisIntersection(pointUpperDetGroupU, pointLowerDetGroupU);
0192 } else if (cspanUpper.zSpan.first > cspanLower.zSpan.second) {
0193
0194 const float pointUpperDetGroupL[2] = {cspanUpper.zSpan.second, cspanUpper.rSpan.first};
0195 const float pointLowerDetGroupL[2] = {cspanLower.zSpan.first, cspanLower.rSpan.second};
0196 lower = zAxisIntersection(pointUpperDetGroupL, pointLowerDetGroupL);
0197
0198 const float pointUpperDetGroupU[2] = {cspanUpper.zSpan.first, cspanUpper.rSpan.second};
0199 const float pointLowerDetGroupU[2] = {cspanLower.zSpan.second, cspanLower.rSpan.first};
0200 upper = zAxisIntersection(pointUpperDetGroupU, pointLowerDetGroupU);
0201 } else {
0202
0203 return false;
0204 }
0205 range = std::pair<float, float>(lower, upper);
0206 return true;
0207 }
0208 bool getZAxisOverlapRangeEndcap(const PixelInactiveAreaFinder::DetGroupSpan& cspanA,
0209 const PixelInactiveAreaFinder::DetGroupSpan& cspanB,
0210 std::pair<float, float>& range) {
0211
0212 PixelInactiveAreaFinder::DetGroupSpan cspanNearer;
0213 PixelInactiveAreaFinder::DetGroupSpan cspanFurther;
0214 float lower = 0;
0215 float upper = 0;
0216 if (cspanA.zSpan.first < 0 && cspanB.zSpan.first < 0) {
0217 if (cspanA.zSpan.second < cspanB.zSpan.first) {
0218 cspanFurther = cspanA;
0219 cspanNearer = cspanB;
0220 } else if (cspanB.zSpan.second < cspanA.zSpan.first) {
0221 cspanFurther = cspanB;
0222 cspanNearer = cspanA;
0223 } else {
0224 #ifdef EDM_ML_DEBUG
0225 LogTrace("PixelInactiveAreaFinder") << "No overlap, same disk propably. Spans:";
0226 Stream ss;
0227 detGroupSpanInfo(cspanA, ss);
0228 ss << std::endl;
0229 detGroupSpanInfo(cspanB, ss);
0230 ss << std::endl;
0231 LogTrace("PixelInactiveAreaFinder") << ss.str();
0232 ss.str(std::string());
0233 LogTrace("PixelInactiveAreaFinder") << "**";
0234 #endif
0235 return false;
0236 }
0237 if (cspanFurther.rSpan.second > cspanNearer.rSpan.first) {
0238 const float pointA[2] = {cspanFurther.zSpan.second, cspanFurther.rSpan.second};
0239 const float pointB[2] = {cspanNearer.zSpan.first, cspanNearer.rSpan.first};
0240 lower = zAxisIntersection(pointA, pointB);
0241 if (cspanFurther.rSpan.first > cspanNearer.rSpan.second) {
0242 const float pointC[2] = {cspanFurther.zSpan.first, cspanFurther.rSpan.first};
0243 const float pointD[2] = {cspanNearer.zSpan.second, cspanFurther.rSpan.second};
0244 upper = zAxisIntersection(pointC, pointD);
0245 } else {
0246 upper = std::numeric_limits<float>::infinity();
0247 }
0248 } else {
0249 #ifdef EDM_ML_DEBUG
0250 LogTrace("PixelInactiveAreaFinder") << "No overlap, further detGroup is lower. Spans:";
0251 Stream ss;
0252 detGroupSpanInfo(cspanA, ss);
0253 ss << std::endl;
0254 detGroupSpanInfo(cspanB, ss);
0255 ss << std::endl;
0256 LogTrace("PixelInactiveAreaFinder") << ss.str();
0257 ss.str(std::string());
0258 LogTrace("PixelInactiveAreaFinder") << "**";
0259 #endif
0260 return false;
0261 }
0262 } else if (cspanA.zSpan.first > 0 && cspanB.zSpan.first > 0) {
0263 if (cspanA.zSpan.first > cspanB.zSpan.second) {
0264 cspanFurther = cspanA;
0265 cspanNearer = cspanB;
0266 } else if (cspanB.zSpan.first > cspanA.zSpan.second) {
0267 cspanFurther = cspanB;
0268 cspanNearer = cspanA;
0269 } else {
0270 #ifdef EDM_ML_DEBUG
0271 LogTrace("PixelInactiveAreaFinder") << "No overlap, same disk propably. Spans:";
0272 Stream ss;
0273 detGroupSpanInfo(cspanA, ss);
0274 ss << std::endl;
0275 detGroupSpanInfo(cspanB, ss);
0276 ss << std::endl;
0277 LogTrace("PixelInactiveAreaFinder") << ss.str();
0278 ss.str(std::string());
0279 LogTrace("PixelInactiveAreaFinder") << "**";
0280 #endif
0281 return false;
0282 }
0283 if (cspanFurther.rSpan.second > cspanNearer.rSpan.first) {
0284 const float pointA[2] = {cspanFurther.zSpan.first, cspanFurther.rSpan.second};
0285 const float pointB[2] = {cspanNearer.zSpan.second, cspanNearer.rSpan.first};
0286 upper = zAxisIntersection(pointA, pointB);
0287 if (cspanFurther.rSpan.first > cspanNearer.rSpan.second) {
0288 const float pointC[2] = {cspanFurther.zSpan.second, cspanFurther.rSpan.first};
0289 const float pointD[2] = {cspanNearer.zSpan.first, cspanFurther.rSpan.second};
0290 lower = zAxisIntersection(pointC, pointD);
0291 } else {
0292 lower = -std::numeric_limits<float>::infinity();
0293 }
0294 } else {
0295 #ifdef EDM_ML_DEBUG
0296 LogTrace("PixelInactiveAreaFinder") << "No overlap, further detGroup lower. Spans:";
0297 Stream ss;
0298 detGroupSpanInfo(cspanA, ss);
0299 ss << std::endl;
0300 detGroupSpanInfo(cspanB, ss);
0301 ss << std::endl;
0302 LogTrace("PixelInactiveAreaFinder") << ss.str();
0303 ss.str(std::string());
0304 LogTrace("PixelInactiveAreaFinder") << "**";
0305 #endif
0306 return false;
0307 }
0308 } else {
0309 #ifdef EDM_ML_DEBUG
0310 LogTrace("PixelInactiveAreaFinder") << "No overlap, different sides of z axis. Spans:";
0311 Stream ss;
0312 detGroupSpanInfo(cspanA, ss);
0313 ss << std::endl;
0314 detGroupSpanInfo(cspanB, ss);
0315 ss << std::endl;
0316 LogTrace("PixelInactiveAreaFinder") << ss.str();
0317 ss.str(std::string());
0318 LogTrace("PixelInactiveAreaFinder") << "**";
0319 #endif
0320 return false;
0321 }
0322 range = std::pair<float, float>(lower, upper);
0323 return true;
0324 }
0325
0326 bool getZAxisOverlapRangeBarrelEndcap(const PixelInactiveAreaFinder::DetGroupSpan& cspanBar,
0327 const PixelInactiveAreaFinder::DetGroupSpan& cspanEnd,
0328 std::pair<float, float>& range) {
0329 float lower = 0;
0330 float upper = 0;
0331 if (cspanEnd.rSpan.second > cspanBar.rSpan.first) {
0332 if (cspanEnd.zSpan.second < cspanBar.zSpan.first) {
0333
0334 const float pointA[2] = {cspanEnd.zSpan.second, cspanEnd.rSpan.second};
0335 const float pointB[2] = {cspanBar.zSpan.first, cspanBar.rSpan.first};
0336 lower = zAxisIntersection(pointA, pointB);
0337 if (cspanEnd.rSpan.first > cspanBar.rSpan.second) {
0338
0339 const float pointC[2] = {cspanEnd.zSpan.first, cspanEnd.rSpan.first};
0340 const float pointD[2] = {cspanBar.zSpan.second, cspanBar.rSpan.second};
0341 upper = zAxisIntersection(pointC, pointD);
0342 } else {
0343 upper = std::numeric_limits<float>::infinity();
0344 }
0345 } else if (cspanEnd.zSpan.first > cspanBar.zSpan.second) {
0346
0347 const float pointA[2] = {cspanEnd.zSpan.first, cspanEnd.rSpan.second};
0348 const float pointB[2] = {cspanBar.zSpan.second, cspanBar.rSpan.first};
0349 upper = zAxisIntersection(pointA, pointB);
0350 if (cspanEnd.rSpan.first > cspanBar.rSpan.second) {
0351 const float pointC[2] = {cspanEnd.zSpan.second, cspanEnd.rSpan.first};
0352 const float pointD[2] = {cspanBar.zSpan.first, cspanBar.rSpan.second};
0353 lower = zAxisIntersection(pointC, pointD);
0354 } else {
0355 lower = -std::numeric_limits<float>::infinity();
0356 }
0357 } else {
0358 return false;
0359 }
0360 } else {
0361 return false;
0362 }
0363 range = std::pair<float, float>(lower, upper);
0364 return true;
0365 }
0366 }
0367
0368 std::vector<
0369 std::pair<edm::VecArray<PixelInactiveAreaFinder::Area, 2>, std::vector<PixelInactiveAreaFinder::LayerSetIndex>>>
0370 PixelInactiveAreaFinder::InactiveAreas::areasAndLayerSets(const GlobalPoint& point, float zwidth) const {
0371 auto spansLayerSets = spansAndLayerSets(point, zwidth);
0372
0373
0374 std::vector<std::pair<VecArray2<Area>, std::vector<LayerSetIndex>>> ret;
0375 for (auto& item : spansLayerSets) {
0376 auto& innerSpan = item.first[0];
0377 auto& outerSpan = item.first[1];
0378 VecArray2<Area> areas;
0379 areas.emplace_back(innerSpan.rSpan.first,
0380 innerSpan.rSpan.second,
0381 innerSpan.phiSpan.first,
0382 innerSpan.phiSpan.second,
0383 innerSpan.zSpan.first,
0384 innerSpan.zSpan.second);
0385 areas.emplace_back(outerSpan.rSpan.first,
0386 outerSpan.rSpan.second,
0387 outerSpan.phiSpan.first,
0388 outerSpan.phiSpan.second,
0389 outerSpan.zSpan.first,
0390 outerSpan.zSpan.second);
0391 ret.emplace_back(areas, std::move(item.second));
0392 }
0393
0394 return ret;
0395 }
0396
0397 std::vector<std::pair<edm::VecArray<PixelInactiveAreaFinder::DetGroupSpan, 2>,
0398 std::vector<PixelInactiveAreaFinder::LayerSetIndex>>>
0399 PixelInactiveAreaFinder::InactiveAreas::spansAndLayerSets(const GlobalPoint& point, float zwidth) const {
0400
0401 const float zmin = point.z() - zwidth;
0402 const float zmax = point.z() + zwidth;
0403
0404 std::vector<std::pair<VecArray2<DetGroupSpan>, std::vector<LayerSetIndex>>> ret;
0405
0406 LogDebug("PixelInactiveAreaFinder") << "Origin at " << point.x() << "," << point.y() << "," << point.z()
0407 << " z half width " << zwidth;
0408
0409 for (LayerSetIndex i = 0, end = inactiveLayerPairIndices_->size(); i < end; ++i) {
0410 const auto& layerIdxPair = (*inactiveLayerPairIndices_)[i];
0411 const auto& innerSpans = inactiveSpans_[layerIdxPair.first];
0412 const auto& outerSpans = inactiveSpans_[layerIdxPair.second];
0413
0414 for (const auto& innerSpan : innerSpans) {
0415 for (const auto& outerSpan : outerSpans) {
0416 if (phiRangesOverlap(innerSpan.phiSpan, outerSpan.phiSpan)) {
0417 std::pair<float, float> range(0, 0);
0418
0419 bool zOverlap = false;
0420 const auto innerDet = std::get<0>((*inactiveLayers_)[layerIdxPair.first]);
0421 const auto outerDet = std::get<0>((*inactiveLayers_)[layerIdxPair.second]);
0422 if (innerDet == GeomDetEnumerators::PixelBarrel) {
0423 if (outerDet == GeomDetEnumerators::PixelBarrel)
0424 zOverlap = getZAxisOverlapRangeBarrel(innerSpan, outerSpan, range);
0425 else
0426 zOverlap = getZAxisOverlapRangeBarrelEndcap(innerSpan, outerSpan, range);
0427 } else {
0428 if (outerDet == GeomDetEnumerators::PixelEndcap)
0429 zOverlap = getZAxisOverlapRangeEndcap(innerSpan, outerSpan, range);
0430 else
0431 throw cms::Exception("LogicError") << "Forward->barrel transition is not supported";
0432 }
0433
0434 if (zOverlap && zmin <= range.second && range.first <= zmax) {
0435 #ifdef EDM_ML_DEBUG
0436 Stream ss;
0437 for (auto ind : (*layerSetIndexInactiveToActive_)[i]) {
0438 ss << ind << ",";
0439 }
0440 ss << "\n ";
0441 detGroupSpanInfo(innerSpan, ss);
0442 ss << "\n ";
0443 detGroupSpanInfo(outerSpan, ss);
0444 LogTrace("PixelInactiveAreaFinder") << " adding areas for active layer sets " << ss.str();
0445 #endif
0446 VecArray2<DetGroupSpan> vec;
0447 vec.emplace_back(innerSpan);
0448 vec.emplace_back(outerSpan);
0449 ret.emplace_back(std::move(vec), (*layerSetIndexInactiveToActive_)[i]);
0450 }
0451 }
0452 }
0453 }
0454 }
0455
0456 return ret;
0457 }
0458
0459 PixelInactiveAreaFinder::PixelInactiveAreaFinder(
0460 const edm::ParameterSet& iConfig,
0461 const std::vector<SeedingLayerSetsBuilder::SeedingLayerId>& seedingLayers,
0462 const SeedingLayerSetsLooper& seedingLayerSetsLooper,
0463 edm::ConsumesCollector&& iC)
0464 : debug_(iConfig.getUntrackedParameter<bool>("debug")),
0465 createPlottingFiles_(iConfig.getUntrackedParameter<bool>("createPlottingFiles")),
0466 ignoreSingleFPixPanelModules_(iConfig.getParameter<bool>("ignoreSingleFPixPanelModules")),
0467 inactivePixelDetectorTokens_(
0468 edm::vector_transform(iConfig.getParameter<std::vector<edm::InputTag>>("inactivePixelDetectorLabels"),
0469 [&](const auto& tag) { return iC.consumes<DetIdCollection>(tag); })),
0470 badPixelFEDChannelsTokens_(
0471 edm::vector_transform(iConfig.getParameter<std::vector<edm::InputTag>>("badPixelFEDChannelCollectionLabels"),
0472 [&](const auto& tag) { return iC.consumes<PixelFEDChannelCollection>(tag); })),
0473 trackerGeometryToken_(iC.esConsumes()),
0474 trackerTopologyToken_(iC.esConsumes()),
0475 pixelQualityToken_(iC.esConsumes()) {
0476 #ifdef EDM_ML_DEBUG
0477 for (const auto& layer : seedingLayers) {
0478 LogTrace("PixelInactiveAreaFinder") << "Input layer subdet " << std::get<0>(layer) << " side "
0479 << static_cast<unsigned int>(std::get<1>(layer)) << " layer "
0480 << std::get<2>(layer);
0481 }
0482 #endif
0483
0484 auto findOrAdd = [&](SeedingLayerId layer) -> unsigned short {
0485 auto found = std::find(inactiveLayers_.cbegin(), inactiveLayers_.cend(), layer);
0486 if (found == inactiveLayers_.cend()) {
0487 auto ret = inactiveLayers_.size();
0488 inactiveLayers_.push_back(layer);
0489 return ret;
0490 }
0491 return std::distance(inactiveLayers_.cbegin(), found);
0492 };
0493
0494
0495 const auto activeToInactiveMap = createActiveToInactiveMap();
0496
0497
0498
0499 LayerSetIndex i = 0;
0500 for (const auto& layerSet : seedingLayerSetsLooper.makeRange(seedingLayers)) {
0501 assert(layerSet.size() == 2);
0502 auto found = activeToInactiveMap.find(std::make_pair(layerSet[0], layerSet[1]));
0503 if (found == activeToInactiveMap.end()) {
0504 throw cms::Exception("Configuration")
0505 << "Encountered layer pair " << layerSet[0] << "+" << layerSet[1]
0506 << " not found from the internal 'active layer pairs' to 'inactive layer pairs' mapping; either fix the "
0507 "input or the mapping (in PixelInactiveAreaFinder.cc)";
0508 }
0509
0510 LogTrace("PixelInactiveAreaFinder") << "Input layer set " << layerSet[0] << "+" << layerSet[1];
0511 for (const auto& inactiveLayerSet : found->second) {
0512 auto innerInd = findOrAdd(inactiveLayerSet.first);
0513 auto outerInd = findOrAdd(inactiveLayerSet.second);
0514
0515 auto found = std::find(
0516 inactiveLayerSetIndices_.cbegin(), inactiveLayerSetIndices_.cend(), std::make_pair(innerInd, outerInd));
0517 if (found == inactiveLayerSetIndices_.end()) {
0518 inactiveLayerSetIndices_.emplace_back(innerInd, outerInd);
0519 layerSetIndexInactiveToActive_.push_back(std::vector<LayerSetIndex>{i});
0520 } else {
0521 layerSetIndexInactiveToActive_.at(std::distance(inactiveLayerSetIndices_.cbegin(), found))
0522 .push_back(i);
0523 }
0524
0525 LogTrace("PixelInactiveAreaFinder")
0526 << " inactive layer set " << inactiveLayerSet.first << "+" << inactiveLayerSet.second;
0527 }
0528
0529 ++i;
0530 }
0531
0532 #ifdef EDM_ML_DEBUG
0533 LogDebug("PixelInactiveAreaFinder") << "All inactive layer sets";
0534 for (const auto& idxPair : inactiveLayerSetIndices_) {
0535 LogTrace("PixelInactiveAreaFinder") << " " << inactiveLayers_[idxPair.first] << "+"
0536 << inactiveLayers_[idxPair.second];
0537 }
0538 #endif
0539 }
0540
0541 void PixelInactiveAreaFinder::fillDescriptions(edm::ParameterSetDescription& desc) {
0542 desc.add<std::vector<edm::InputTag>>("inactivePixelDetectorLabels",
0543 std::vector<edm::InputTag>{{edm::InputTag("siPixelDigis")}})
0544 ->setComment("One or more DetIdCollections of modules to mask on the fly for a given event");
0545 desc.add<std::vector<edm::InputTag>>("badPixelFEDChannelCollectionLabels",
0546 std::vector<edm::InputTag>{{edm::InputTag("siPixelDigis")}})
0547 ->setComment("One or more PixelFEDChannelCollections of modules+ROCs to mask on the fly for a given event");
0548 desc.add<bool>("ignoreSingleFPixPanelModules", false);
0549
0550 desc.addUntracked<bool>("debug", false);
0551 desc.addUntracked<bool>("createPlottingFiles", false);
0552 }
0553
0554 PixelInactiveAreaFinder::InactiveAreas PixelInactiveAreaFinder::inactiveAreas(const edm::Event& iEvent,
0555 const edm::EventSetup& iSetup) {
0556
0557 trackerGeometry_ = &iSetup.getData(trackerGeometryToken_);
0558 trackerTopology_ = &iSetup.getData(trackerTopologyToken_);
0559
0560
0561 updatePixelDets(iSetup);
0562
0563
0564 badPixelDetsBarrel_.clear();
0565 badPixelDetsEndcap_.clear();
0566 getBadPixelDets(iEvent, iSetup);
0567
0568
0569 if (createPlottingFiles_) {
0570 createPlottingFiles();
0571 }
0572
0573
0574
0575 DetGroupSpanContainerPair cspans = detGroupSpans();
0576
0577
0578
0579 std::vector<DetGroupSpanContainer> spans(inactiveLayers_.size());
0580
0581 auto doWork = [&](const DetGroupSpanContainer& container) {
0582 for (const auto& span : container) {
0583 const auto subdet = span.subdetId == PixelSubdetector::PixelBarrel ? GeomDetEnumerators::PixelBarrel
0584 : GeomDetEnumerators::PixelEndcap;
0585 const auto side = (subdet == GeomDetEnumerators::PixelBarrel
0586 ? TrackerDetSide::Barrel
0587 : (span.zSpan.first < 0 ? TrackerDetSide::NegEndcap : TrackerDetSide::PosEndcap));
0588 const auto layer = subdet == GeomDetEnumerators::PixelBarrel ? span.layer : span.disk;
0589 auto found = std::find(inactiveLayers_.begin(), inactiveLayers_.end(), SeedingLayerId(subdet, side, layer));
0590 if (found != inactiveLayers_.end()) {
0591 spans[std::distance(inactiveLayers_.begin(), found)].push_back(span);
0592 }
0593 }
0594 };
0595 doWork(cspans.first);
0596 doWork(cspans.second);
0597
0598 auto ret =
0599 InactiveAreas(&inactiveLayers_, std::move(spans), &inactiveLayerSetIndices_, &layerSetIndexInactiveToActive_);
0600
0601 if (debug_) {
0602 printOverlapSpans(ret);
0603 }
0604
0605 return ret;
0606 }
0607
0608
0609 void PixelInactiveAreaFinder::updatePixelDets(const edm::EventSetup& iSetup) {
0610 if (!geometryWatcher_.check(iSetup))
0611 return;
0612
0613
0614 {
0615
0616 if (trackerGeometry_->numberOfLayers(PixelSubdetector::PixelBarrel) != 4) {
0617 throw cms::Exception("NotImplemented")
0618 << "This module supports only a detector with 4 pixel barrel layers, the current geometry has "
0619 << trackerGeometry_->numberOfLayers(PixelSubdetector::PixelBarrel);
0620 }
0621 if (trackerGeometry_->numberOfLayers(PixelSubdetector::PixelEndcap) != 3) {
0622 throw cms::Exception("NotImplemented")
0623 << "This module supports only a detector with 3 pixel forward disks, the current geometry has "
0624 << trackerGeometry_->numberOfLayers(PixelSubdetector::PixelEndcap);
0625 }
0626
0627 std::array<std::array<unsigned short, 100>, 4> counts = {};
0628 for (const auto& det : trackerGeometry_->detsPXB()) {
0629 const auto layer = trackerTopology_->layer(det->geographicalId());
0630 const auto ladder = trackerTopology_->pxbLadder(det->geographicalId());
0631 if (ladder >= 100) {
0632 throw cms::Exception("LogicError")
0633 << "Got a ladder with number " << ladder
0634 << " while the expected maximum was 100; either something is wrong or the maximum has to be increased.";
0635 }
0636 counts[layer - 1][ladder - 1] += 1;
0637 }
0638
0639
0640
0641 nModulesPerLadder = counts[0][0];
0642 if (nModulesPerLadder == 0) {
0643 throw cms::Exception("LogicError") << "Ladder 1 of layer 1 has 0 modules, something fishy is going on.";
0644 }
0645
0646 LogDebug("PixelInactiveAreaFinder") << "Number of modules per ladder " << nModulesPerLadder
0647 << "; below are number of ladders per layer";
0648
0649
0650 for (unsigned layer = 0; layer < 4; ++layer) {
0651 nBPixLadders[layer] =
0652 std::count_if(counts[layer].begin(), counts[layer].end(), [](unsigned short val) { return val > 0; });
0653 LogTrace("PixelInactiveAreaFinder")
0654 << "BPix layer " << (layer + 1) << " has " << nBPixLadders[layer] << " ladders";
0655
0656 auto fail = std::count_if(counts[layer].begin(), counts[layer].end(), [&](unsigned short val) {
0657 return val != nModulesPerLadder && val > 0;
0658 });
0659 if (fail != 0) {
0660 throw cms::Exception("LogicError")
0661 << "Layer " << (layer + 1) << " had " << fail
0662 << " ladders whose number of modules/ladder differed from the ladder 1 of layer 1 (" << nModulesPerLadder
0663 << "). Something fishy is going on.";
0664 }
0665 }
0666 }
0667
0668
0669 if (!createPlottingFiles_)
0670 return;
0671
0672 pixelDetsBarrel_.clear();
0673 pixelDetsEndcap_.clear();
0674
0675 for (auto const& geomDetPtr : trackerGeometry_->detsPXB()) {
0676 if (geomDetPtr->geographicalId().subdetId() == PixelSubdetector::PixelBarrel) {
0677 pixelDetsBarrel_.push_back(geomDetPtr->geographicalId().rawId());
0678 }
0679 }
0680 for (auto const& geomDetPtr : trackerGeometry_->detsPXF()) {
0681 if (geomDetPtr->geographicalId().subdetId() == PixelSubdetector::PixelEndcap) {
0682 pixelDetsEndcap_.push_back(geomDetPtr->geographicalId().rawId());
0683 }
0684 }
0685 std::sort(pixelDetsBarrel_.begin(), pixelDetsBarrel_.end());
0686 std::sort(pixelDetsEndcap_.begin(), pixelDetsEndcap_.end());
0687 }
0688 void PixelInactiveAreaFinder::getBadPixelDets(const edm::Event& iEvent, const edm::EventSetup& iSetup) {
0689 auto addDetId = [&](const auto id) {
0690 const auto detid = DetId(id);
0691 const auto subdet = detid.subdetId();
0692 if (subdet == PixelSubdetector::PixelBarrel) {
0693 badPixelDetsBarrel_.push_back(detid.rawId());
0694 } else if (subdet == PixelSubdetector::PixelEndcap) {
0695 badPixelDetsEndcap_.push_back(detid.rawId());
0696 }
0697 };
0698
0699
0700 auto const& pixelQuality = iSetup.getData(pixelQualityToken_);
0701
0702 for (auto const& disabledModule : pixelQuality.getBadComponentList()) {
0703 addDetId(disabledModule.DetID);
0704 }
0705
0706
0707 for (const auto& token : inactivePixelDetectorTokens_) {
0708 edm::Handle<DetIdCollection> detIds;
0709 iEvent.getByToken(token, detIds);
0710 for (const auto& id : *detIds) {
0711 addDetId(id);
0712 }
0713 }
0714
0715
0716
0717 for (const auto& token : badPixelFEDChannelsTokens_) {
0718 edm::Handle<PixelFEDChannelCollection> pixelFEDChannelCollectionHandle;
0719 iEvent.getByToken(token, pixelFEDChannelCollectionHandle);
0720 for (const auto& disabledChannels : *pixelFEDChannelCollectionHandle) {
0721 addDetId(disabledChannels.detId());
0722 }
0723 }
0724
0725
0726 std::sort(badPixelDetsBarrel_.begin(), badPixelDetsBarrel_.end());
0727 std::sort(badPixelDetsEndcap_.begin(), badPixelDetsEndcap_.end());
0728 badPixelDetsBarrel_.erase(std::unique(badPixelDetsBarrel_.begin(), badPixelDetsBarrel_.end()),
0729 badPixelDetsBarrel_.end());
0730 badPixelDetsEndcap_.erase(std::unique(badPixelDetsEndcap_.begin(), badPixelDetsEndcap_.end()),
0731 badPixelDetsEndcap_.end());
0732 }
0733
0734 void PixelInactiveAreaFinder::detInfo(const det_t& det, Stream& ss) {
0735 using std::fixed;
0736 using std::left;
0737 using std::noshowpos;
0738 using std::right;
0739 using std::setfill;
0740 using std::setprecision;
0741 using std::setw;
0742 using std::showpos;
0743 using std::tie;
0744 std::string deli = "; ";
0745 ss << "id:[" << det << "]" << deli;
0746 ss << "subdetid:[" << DetId(det).subdetId() << "]" << deli;
0747 if (DetId(det).subdetId() == PixelSubdetector::PixelBarrel) {
0748 unsigned int layer = trackerTopology_->pxbLayer(DetId(det));
0749 unsigned int ladder = trackerTopology_->pxbLadder(DetId(det));
0750 unsigned int module = trackerTopology_->pxbModule(DetId(det));
0751 ss << "layer:[" << layer << "]" << deli << "ladder:[" << right << setw(2) << ladder << "]" << deli << "module:["
0752 << module << "]" << deli;
0753 } else if (DetId(det).subdetId() == PixelSubdetector::PixelEndcap) {
0754 unsigned int disk = trackerTopology_->pxfDisk(DetId(det));
0755 unsigned int blade = trackerTopology_->pxfBlade(DetId(det));
0756 unsigned int panel = trackerTopology_->pxfPanel(DetId(det));
0757 ss << left << setw(6) << "disk:"
0758 << "[" << right << disk << "]" << deli << left << setw(7) << "blade:"
0759 << "[" << setw(2) << right << blade << "]" << deli << left << setw(7) << "panel:"
0760 << "[" << right << panel << "]" << deli;
0761 }
0762 float phiA, phiB, zA, zB, rA, rB;
0763 auto detSurface = trackerGeometry_->idToDet(DetId(det))->surface();
0764 tie(phiA, phiB) = detSurface.phiSpan();
0765 tie(zA, zB) = detSurface.zSpan();
0766 tie(rA, rB) = detSurface.rSpan();
0767 ss << setprecision(16) << fixed << showpos << setfill(' ') << "phi:[" << right << setw(12) << phiA << "," << left
0768 << setw(12) << phiB << "]" << deli << "z:[" << right << setw(7) << zA << "," << left << setw(7) << zB << "]"
0769 << deli << noshowpos << "r:[" << right << setw(10) << rA << "," << left << setw(10) << rB << "]" << deli;
0770 }
0771 void PixelInactiveAreaFinder::printPixelDets() {
0772 edm::LogPrint("PixelInactiveAreaFinder") << "Barrel detectors:";
0773 Stream ss;
0774 for (auto const& det : pixelDetsBarrel_) {
0775 detInfo(det, ss);
0776 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0777 ss.str(std::string());
0778 }
0779 edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
0780 for (auto const& det : pixelDetsEndcap_) {
0781 detInfo(det, ss);
0782 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0783 ss.str(std::string());
0784 }
0785 }
0786 void PixelInactiveAreaFinder::printBadPixelDets() {
0787 edm::LogPrint("PixelInactiveAreaFinder") << "Bad barrel detectors:";
0788 Stream ss;
0789 for (auto const& det : badPixelDetsBarrel_) {
0790 detInfo(det, ss);
0791 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0792 ss.str(std::string());
0793 }
0794 edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
0795 for (auto const& det : badPixelDetsEndcap_) {
0796 detInfo(det, ss);
0797 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0798 ss.str(std::string());
0799 }
0800 }
0801 void PixelInactiveAreaFinder::printBadDetGroups() {
0802 DetGroupContainer badDetGroupsBar = badDetGroupsBarrel();
0803 DetGroupContainer badDetGroupsEnd = badDetGroupsEndcap();
0804 Stream ss;
0805 for (auto const& detGroup : badDetGroupsBar) {
0806 ss << std::setfill(' ') << std::left << std::setw(16) << "DetGroup:";
0807 DetGroupSpan cspan;
0808 getPhiSpanBarrel(detGroup, cspan);
0809 getZSpan(detGroup, cspan);
0810 getRSpan(detGroup, cspan);
0811 detGroupSpanInfo(cspan, ss);
0812 ss << std::endl;
0813 for (auto const& det : detGroup) {
0814 detInfo(det, ss);
0815 ss << std::endl;
0816 }
0817 ss << std::endl;
0818 }
0819 for (auto const& detGroup : badDetGroupsEnd) {
0820 ss << std::setfill(' ') << std::left << std::setw(16) << "DetGroup:";
0821 DetGroupSpan cspan;
0822 getPhiSpanEndcap(detGroup, cspan);
0823 getZSpan(detGroup, cspan);
0824 getRSpan(detGroup, cspan);
0825 detGroupSpanInfo(cspan, ss);
0826 ss << std::endl;
0827 for (auto const& det : detGroup) {
0828 detInfo(det, ss);
0829 ss << std::endl;
0830 }
0831 ss << std::endl;
0832 }
0833 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0834 }
0835 void PixelInactiveAreaFinder::printBadDetGroupSpans() {
0836 DetGroupSpanContainerPair cspans = detGroupSpans();
0837 Stream ss;
0838 for (auto const& cspan : cspans.first) {
0839 detGroupSpanInfo(cspan, ss);
0840 ss << std::endl;
0841 }
0842 for (auto const& cspan : cspans.second) {
0843 detGroupSpanInfo(cspan, ss);
0844 ss << std::endl;
0845 }
0846 edm::LogPrint("PixelInactiveAreaFinder") << ss.str();
0847 }
0848 void PixelInactiveAreaFinder::createPlottingFiles() {
0849
0850 Stream ss;
0851 std::ofstream fsDet("DETECTORS.txt");
0852 for (auto const& det : pixelDetsBarrel_) {
0853 detInfo(det, ss);
0854 ss << std::endl;
0855 }
0856 edm::LogPrint("PixelInactiveAreaFinder") << "Endcap detectors;";
0857 for (auto const& det : pixelDetsEndcap_) {
0858 detInfo(det, ss);
0859 ss << std::endl;
0860 }
0861 fsDet << ss.rdbuf();
0862 ss.str(std::string());
0863
0864 std::ofstream fsBadDet("BADDETECTORS.txt");
0865 for (auto const& det : badPixelDetsBarrel_) {
0866 detInfo(det, ss);
0867 ss << std::endl;
0868 }
0869 for (auto const& det : badPixelDetsEndcap_) {
0870 detInfo(det, ss);
0871 ss << std::endl;
0872 }
0873 fsBadDet << ss.rdbuf();
0874 ss.str(std::string());
0875
0876 std::ofstream fsSpans("DETGROUPSPANS.txt");
0877 DetGroupSpanContainerPair cspans = detGroupSpans();
0878 for (auto const& cspan : cspans.first) {
0879 detGroupSpanInfo(cspan, ss);
0880 ss << std::endl;
0881 }
0882 for (auto const& cspan : cspans.second) {
0883 detGroupSpanInfo(cspan, ss);
0884 ss << std::endl;
0885 }
0886 fsSpans << ss.rdbuf();
0887 ss.str(std::string());
0888 }
0889
0890 bool PixelInactiveAreaFinder::detWorks(det_t det) {
0891 return std::find(badPixelDetsBarrel_.begin(), badPixelDetsBarrel_.end(), det) == badPixelDetsBarrel_.end() &&
0892 std::find(badPixelDetsEndcap_.begin(), badPixelDetsEndcap_.end(), det) == badPixelDetsEndcap_.end();
0893 }
0894 PixelInactiveAreaFinder::DetGroup PixelInactiveAreaFinder::badAdjecentDetsBarrel(const det_t& det) {
0895 using std::remove_if;
0896
0897 DetGroup adj;
0898 auto const tTopo = trackerTopology_;
0899 auto const& detId = DetId(det);
0900 unsigned int layer = tTopo->pxbLayer(detId);
0901 unsigned int ladder = tTopo->pxbLadder(detId);
0902 unsigned int module = tTopo->pxbModule(detId);
0903 unsigned int nLads = nBPixLadders[layer];
0904
0905 adj.push_back(tTopo->pxbDetId(layer, ((ladder - 1) + 1) % nLads + 1, module)());
0906 adj.push_back(tTopo->pxbDetId(layer, ((ladder - 1) - 1 + nLads) % nLads + 1, module)());
0907
0908 if (module == 1) {
0909 adj.push_back(tTopo->pxbDetId(layer, ladder, module + 1)());
0910 } else if (module == nModulesPerLadder) {
0911 adj.push_back(tTopo->pxbDetId(layer, ladder, module - 1)());
0912 } else {
0913 adj.push_back(tTopo->pxbDetId(layer, ladder, module + 1)());
0914 adj.push_back(tTopo->pxbDetId(layer, ladder, module - 1)());
0915 }
0916
0917 adj.erase(remove_if(adj.begin(), adj.end(), [&](auto c) { return this->detWorks(c); }), adj.end());
0918 return adj;
0919 }
0920 PixelInactiveAreaFinder::DetGroup PixelInactiveAreaFinder::badAdjecentDetsEndcap(const det_t& det) {
0921
0922 using std::ignore;
0923 using std::tie;
0924 DetGroup adj;
0925 Span_t phiSpan, phiSpanComp;
0926 float z, zComp;
0927 unsigned int disk, diskComp;
0928 auto const& detSurf = trackerGeometry_->idToDet(DetId(det))->surface();
0929 phiSpan = detSurf.phiSpan();
0930 tie(z, ignore) = detSurf.zSpan();
0931 disk = trackerTopology_->pxfDisk(DetId(det));
0932
0933 for (auto const& detComp : badPixelDetsEndcap_) {
0934 auto const& detIdComp = DetId(detComp);
0935 auto const& detSurfComp = trackerGeometry_->idToDet(detIdComp)->surface();
0936 diskComp = trackerTopology_->pxfDisk(detIdComp);
0937 phiSpanComp = detSurfComp.phiSpan();
0938 tie(zComp, ignore) = detSurfComp.zSpan();
0939 if (det != detComp && disk == diskComp && z * zComp > 0 && phiRangesOverlap(phiSpan, phiSpanComp)) {
0940 adj.push_back(detComp);
0941 }
0942 }
0943 return adj;
0944 }
0945 PixelInactiveAreaFinder::DetGroup PixelInactiveAreaFinder::reachableDetGroup(const det_t& initDet,
0946 DetectorSet& foundDets) {
0947 DetGroup reachableDetGroup;
0948 std::queue<det_t> workQueue;
0949 det_t workDet;
0950 DetGroup badAdjDets;
0951 foundDets.insert(initDet);
0952 workQueue.push(initDet);
0953 reachableDetGroup.push_back(initDet);
0954 while (!workQueue.empty()) {
0955 workDet = workQueue.front();
0956 workQueue.pop();
0957 if (DetId(workDet).subdetId() == PixelSubdetector::PixelBarrel) {
0958 badAdjDets = this->badAdjecentDetsBarrel(workDet);
0959 } else if (DetId(workDet).subdetId() == PixelSubdetector::PixelEndcap) {
0960 badAdjDets = this->badAdjecentDetsEndcap(workDet);
0961 } else {
0962 badAdjDets = {};
0963 }
0964 for (auto const& badDet : badAdjDets) {
0965 if (foundDets.find(badDet) == foundDets.end()) {
0966 reachableDetGroup.push_back(badDet);
0967 foundDets.insert(badDet);
0968 workQueue.push(badDet);
0969 }
0970 }
0971 }
0972 return reachableDetGroup;
0973 }
0974 PixelInactiveAreaFinder::DetGroupContainer PixelInactiveAreaFinder::badDetGroupsBarrel() {
0975 DetGroupContainer detGroups;
0976 DetectorSet foundDets;
0977 for (auto const& badDet : badPixelDetsBarrel_) {
0978 if (foundDets.find(badDet) == foundDets.end()) {
0979 detGroups.push_back(this->reachableDetGroup(badDet, foundDets));
0980 }
0981 }
0982 return detGroups;
0983 }
0984 PixelInactiveAreaFinder::DetGroupContainer PixelInactiveAreaFinder::badDetGroupsEndcap() {
0985 DetGroupContainer detGroups;
0986 DetectorSet foundDets;
0987 for (auto const& badDet : badPixelDetsEndcap_) {
0988 if (foundDets.find(badDet) == foundDets.end()) {
0989 auto adjacentDets = this->reachableDetGroup(badDet, foundDets);
0990 if (ignoreSingleFPixPanelModules_ && adjacentDets.size() == 1) {
0991
0992
0993
0994 continue;
0995 }
0996 detGroups.push_back(adjacentDets);
0997 }
0998 }
0999 return detGroups;
1000 }
1001
1002 void PixelInactiveAreaFinder::getPhiSpanBarrel(const DetGroup& detGroup, DetGroupSpan& cspan) {
1003
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
1021 uint i = 0;
1022 uint currentLadder = ladv[0];
1023 uint previousLadder = ladv[(ladv.size() + i - 1) % ladv.size()];
1024
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()) {
1030 cspan.phiSpan.first = std::numeric_limits<float>::epsilon();
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 }
1042 void PixelInactiveAreaFinder::getPhiSpanEndcap(const DetGroup& detGroup, DetGroupSpan& cspan) {
1043
1044
1045
1046
1047
1048
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()) {
1063 cspan.phiSpan.first = std::numeric_limits<float>::epsilon();
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
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()) {
1087 cspan.phiSpan.first = std::numeric_limits<float>::epsilon();
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 }
1100 void PixelInactiveAreaFinder::getZSpan(const DetGroup& detGroup, DetGroupSpan& cspan) {
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 }
1110 void PixelInactiveAreaFinder::getRSpan(const DetGroup& detGroup, DetGroupSpan& cspan) {
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 }
1120 void PixelInactiveAreaFinder::getSpan(const DetGroup& detGroup, DetGroupSpan& cspan) {
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 }
1137 PixelInactiveAreaFinder::DetGroupSpanContainerPair PixelInactiveAreaFinder::detGroupSpans() {
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 }