File indexing completed on 2024-09-11 04:32:02
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <memory>
0016
0017
0018 #include "CondFormats/DataRecord/interface/SiPhase2OuterTrackerCondDataRecords.h"
0019 #include "CondFormats/SiStripObjects/interface/SiStripBadStrip.h"
0020 #include "DataFormats/Phase2TrackerDigi/interface/Phase2TrackerDigi.h"
0021 #include "DataFormats/SiStripDetId/interface/SiStripDetId.h"
0022 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
0023 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
0024 #include "FWCore/Framework/interface/ESProducer.h"
0025 #include "FWCore/Framework/interface/EventSetupRecordIntervalFinder.h"
0026 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0027 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0028 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0029 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0030 #include "FWCore/ServiceRegistry/interface/Service.h"
0031 #include "FWCore/Utilities/interface/Exception.h"
0032 #include "FWCore/Utilities/interface/RandomNumberGenerator.h"
0033 #include "Geometry/CommonDetUnit/interface/PixelGeomDetUnit.h"
0034 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
0035 #include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
0036 #include "Geometry/Records/interface/TrackerTopologyRcd.h"
0037 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
0038
0039
0040 #include "CLHEP/Random/RandFlat.h"
0041 #include "CLHEP/Random/JamesRandom.h"
0042
0043 class SiPhase2BadStripConfigurableFakeESSource : public edm::ESProducer, public edm::EventSetupRecordIntervalFinder {
0044 public:
0045 SiPhase2BadStripConfigurableFakeESSource(const edm::ParameterSet&);
0046 ~SiPhase2BadStripConfigurableFakeESSource() override = default;
0047
0048 void setIntervalFor(const edm::eventsetup::EventSetupRecordKey&,
0049 const edm::IOVSyncValue& iov,
0050 edm::ValidityInterval& iValidity) override;
0051
0052 typedef std::unique_ptr<SiStripBadStrip> ReturnType;
0053 ReturnType produce(const SiPhase2OuterTrackerBadStripRcd&);
0054
0055 static void fillDescriptions(edm::ConfigurationDescriptions&);
0056
0057 private:
0058 std::map<unsigned short, unsigned short> clusterizeBadChannels(
0059 const std::vector<Phase2TrackerDigi::PackedDigiType>& maskedChannels);
0060
0061
0062 bool printDebug_;
0063 float badComponentsFraction_;
0064
0065
0066 std::unique_ptr<CLHEP::HepRandomEngine> engine_;
0067
0068
0069 edm::ESGetToken<TrackerTopology, TrackerTopologyRcd> trackTopoToken_;
0070 edm::ESGetToken<TrackerGeometry, TrackerDigiGeometryRecord> geomToken_;
0071 };
0072
0073 SiPhase2BadStripConfigurableFakeESSource::SiPhase2BadStripConfigurableFakeESSource(const edm::ParameterSet& iConfig)
0074 : engine_(new CLHEP::HepJamesRandom(iConfig.getParameter<unsigned int>("seed"))) {
0075 auto cc = setWhatProduced(this);
0076 trackTopoToken_ = cc.consumes();
0077 geomToken_ = cc.consumes();
0078
0079 printDebug_ = iConfig.getUntrackedParameter<bool>("printDebug", false);
0080 badComponentsFraction_ = iConfig.getParameter<double>("badComponentsFraction");
0081
0082 if (badComponentsFraction_ > 1. || badComponentsFraction_ < 0.) {
0083 throw cms::Exception("Inconsistent configuration")
0084 << "[SiPhase2BadStripChannelBuilder::c'tor] the requested fraction of bad components is unphysical. \n";
0085 }
0086
0087 findingRecord<SiPhase2OuterTrackerBadStripRcd>();
0088 }
0089
0090 void SiPhase2BadStripConfigurableFakeESSource::setIntervalFor(const edm::eventsetup::EventSetupRecordKey&,
0091 const edm::IOVSyncValue& iov,
0092 edm::ValidityInterval& iValidity) {
0093 iValidity = edm::ValidityInterval{iov.beginOfTime(), iov.endOfTime()};
0094 }
0095
0096
0097 SiPhase2BadStripConfigurableFakeESSource::ReturnType SiPhase2BadStripConfigurableFakeESSource::produce(
0098 const SiPhase2OuterTrackerBadStripRcd& iRecord) {
0099 using namespace edm::es;
0100 using Phase2TrackerGeomDetUnit = PixelGeomDetUnit;
0101
0102
0103 TrackerGeometry const& tGeom = iRecord.get(geomToken_);
0104
0105 auto badStrips = std::make_unique<SiStripBadStrip>();
0106
0107
0108 if (badComponentsFraction_ == 0.f) {
0109 return badStrips;
0110 }
0111
0112 LogDebug("SiPhase2BadStripConfigurableFakeESSource")
0113 << " There are " << tGeom.detUnits().size() << " modules in this geometry.";
0114
0115 int counter{0};
0116 for (auto const& det_u : tGeom.detUnits()) {
0117 const DetId detid = det_u->geographicalId();
0118 uint32_t rawId = detid.rawId();
0119 int subid = detid.subdetId();
0120 if (detid.det() == DetId::Detector::Tracker) {
0121 const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u);
0122 assert(pixdet);
0123 if (subid == StripSubdetector::TOB || subid == StripSubdetector::TID) {
0124 if (tGeom.getDetectorType(rawId) == TrackerGeometry::ModuleType::Ph2PSS ||
0125 tGeom.getDetectorType(rawId) == TrackerGeometry::ModuleType::Ph2SS) {
0126 const PixelTopology& topol(pixdet->specificTopology());
0127
0128 const int nrows = topol.nrows();
0129 const int ncols = topol.ncolumns();
0130
0131 LogDebug("SiPhase2BadStripConfigurableFakeESSource")
0132 << "DetId: " << rawId << " subdet: " << subid << " nrows: " << nrows << " ncols: " << ncols;
0133
0134
0135 std::vector<Phase2TrackerDigi::PackedDigiType> usedChannels;
0136
0137 size_t nmaxBadStrips = std::floor(nrows * ncols * badComponentsFraction_);
0138
0139 while (usedChannels.size() < nmaxBadStrips) {
0140 unsigned short badStripRow = std::floor(CLHEP::RandFlat::shoot(engine_.get(), 0, nrows));
0141 unsigned short badStripCol = std::floor(CLHEP::RandFlat::shoot(engine_.get(), 0, ncols));
0142 const auto& badChannel = Phase2TrackerDigi::pixelToChannel(badStripRow, badStripCol);
0143 if (std::find(usedChannels.begin(), usedChannels.end(), badChannel) == usedChannels.end()) {
0144 usedChannels.push_back(badChannel);
0145 }
0146 }
0147
0148
0149
0150 const auto badChannelsGroups = this->clusterizeBadChannels(usedChannels);
0151
0152 LogDebug("SiPhase2BadStripConfigurableFakeESSource")
0153 << rawId << " (" << counter << ") "
0154 << " masking " << nmaxBadStrips << " strips, used channels size: " << usedChannels.size()
0155 << ", clusters size: " << badChannelsGroups.size();
0156
0157 std::vector<unsigned int> theSiStripVector;
0158
0159
0160 for (const auto& [first, consec] : badChannelsGroups) {
0161 unsigned int theBadChannelsRange;
0162 theBadChannelsRange = badStrips->encodePhase2(first, consec);
0163
0164 if (printDebug_) {
0165 edm::LogInfo("SiPhase2BadStripConfigurableFakeESSource")
0166 << "detid " << rawId << " \t"
0167 << " firstBadStrip " << first << "\t "
0168 << " NconsecutiveBadStrips " << consec << "\t "
0169 << " packed integer " << std::hex << theBadChannelsRange << std::dec;
0170 }
0171 theSiStripVector.push_back(theBadChannelsRange);
0172 }
0173
0174 SiStripBadStrip::Range range(theSiStripVector.begin(), theSiStripVector.end());
0175 if (!badStrips->put(rawId, range))
0176 edm::LogError("SiPhase2BadStripConfigurableFakeESSource")
0177 << "[SiPhase2BadStripConfigurableFakeESSource::produce] detid already exists";
0178
0179 counter++;
0180
0181 }
0182 }
0183 }
0184 }
0185
0186 LogDebug("SiPhase2BadStripConfigurableFakeESSource") << "end of the detId loops";
0187
0188 return badStrips;
0189 }
0190
0191
0192 std::map<unsigned short, unsigned short> SiPhase2BadStripConfigurableFakeESSource::clusterizeBadChannels(
0193 const std::vector<Phase2TrackerDigi::PackedDigiType>& maskedChannels) {
0194
0195 std::map<unsigned short, unsigned short> result{};
0196 std::map<int, std::string> printresult{};
0197
0198
0199 std::set data(maskedChannels.begin(), maskedChannels.end());
0200
0201
0202 auto startOfSequence = data.begin();
0203
0204
0205 while (startOfSequence != data.end()) {
0206
0207 auto endOfSequence =
0208 std::adjacent_find(startOfSequence, data.end(), [](const auto& v1, const auto& v2) { return v2 != v1 + 1; });
0209 if (endOfSequence != data.end())
0210 std::advance(endOfSequence, 1);
0211
0212 auto consecutiveStrips = std::distance(startOfSequence, endOfSequence);
0213 result[*startOfSequence] = consecutiveStrips;
0214
0215 if (printDebug_) {
0216
0217 std::ostringstream oss{};
0218 bool writeDash = false;
0219 for (auto it = startOfSequence; it != endOfSequence; ++it) {
0220 oss << (writeDash ? "-" : "") << std::to_string(*it);
0221 writeDash = true;
0222 }
0223
0224
0225 for (auto it = startOfSequence; it != endOfSequence; ++it)
0226 printresult[*it] = oss.str();
0227 }
0228
0229
0230 startOfSequence = endOfSequence;
0231 }
0232
0233 if (printDebug_) {
0234
0235 for (const auto& [value, text] : printresult)
0236 LogDebug("SiPhase2BadStripConfigurableFakeESSource")
0237 << std::left << std::setw(2) << value << " -> " << text << "\n";
0238 }
0239 return result;
0240 }
0241
0242 void SiPhase2BadStripConfigurableFakeESSource::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0243 edm::ParameterSetDescription desc;
0244 desc.setComment("Configurable Fake Phase-2 Outer Tracker Bad Strip ESSource");
0245 desc.add<unsigned int>("seed", 1)->setComment("random seed");
0246 desc.addUntracked<bool>("printDebug", false)->setComment("maximum amount of print-outs");
0247 desc.add<double>("badComponentsFraction", 0.01)->setComment("fraction of bad components to populate the ES");
0248 descriptions.addWithDefaultLabel(desc);
0249 }
0250
0251
0252 #include "FWCore/Framework/interface/SourceFactory.h"
0253 DEFINE_FWK_EVENTSETUP_SOURCE(SiPhase2BadStripConfigurableFakeESSource);