CMS 3D CMS Logo

SiPhase2BadStripChannelBuilder.cc
Go to the documentation of this file.
1 // system include files
2 #include <vector>
3 #include <memory>
4 #include <iostream>
5 #include <fstream>
6 
7 // user include files
26 
27 #include <random>
28 
32 namespace {
33  enum badChannelAlgo { NAIVE = 1, RANDOM = 2, NONE = 99 };
34 }
35 
37 
38 class SiPhase2BadStripChannelBuilder : public ConditionDBWriter<SiStripBadStrip> {
39 public:
41  ~SiPhase2BadStripChannelBuilder() override = default;
42 
43  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
44 
45 private:
46  std::unique_ptr<SiStripBadStrip> getNewObject() override;
47 
48  void algoBeginRun(const edm::Run& run, const edm::EventSetup& es) override {
49  if (!tTopo_) {
50  tTopo_ = std::make_unique<TrackerTopology>(es.getData(topoToken_));
51  const TrackerGeometry* tkGeom_ = &es.getData(geomToken_);
52 
53  edm::LogInfo("SiPhase2BadStripChannelBuilder")
54  << " There are " << tkGeom_->detUnits().size() << " modules in this geometry.";
55 
56  for (auto const& det_u : tkGeom_->detUnits()) {
57  const DetId detid = det_u->geographicalId();
58  uint32_t rawId = detid.rawId();
59  int subid = detid.subdetId();
60  if (detid.det() == DetId::Detector::Tracker) {
61  const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u);
62  assert(pixdet);
63  LogDebug("SiPhase2BadStripChannelBuilder") << rawId << " is a " << subid << " det";
64  if (subid == StripSubdetector::TOB || subid == StripSubdetector::TID) {
65  if (tkGeom_->getDetectorType(rawId) == TrackerGeometry::ModuleType::Ph2PSS ||
66  tkGeom_->getDetectorType(rawId) == TrackerGeometry::ModuleType::Ph2SS) {
67  theOTDets.push_back(pixdet);
68  }
69  } // if it's a Strip module
70  } // if it's OT
71  } // if it's Tracker
72  } // loop of geomdets
73  };
74 
75  void algoAnalyze(const edm::Event& event, const edm::EventSetup& es) override {
76  // deterministic seed from the event number
77  // should not bias the result as the event number is already
78  // assigned randomly-enough
79  engine_.seed(event.id().event() + (event.id().luminosityBlock() << 10) + (event.id().run() << 20));
80  }
81 
82  std::map<unsigned short, unsigned short> clusterizeBadChannels(
83  const std::vector<Phase2TrackerDigi::PackedDigiType>& maskedChannels);
84 
85  // ----------member data ---------------------------
86  std::unique_ptr<TrackerTopology> tTopo_;
87  std::mt19937 engine_;
88 
91  const bool printdebug_;
92  const unsigned int popConAlgo_;
95 
96  std::vector<const Phase2TrackerGeomDetUnit*> theOTDets;
97 };
98 
99 //__________________________________________________________________________________________________
102  topoToken_(esConsumes<edm::Transition::BeginRun>()),
103  geomToken_(esConsumes<edm::Transition::BeginRun>()),
104  printdebug_(iConfig.getUntrackedParameter<bool>("printDebug", false)),
105  popConAlgo_(iConfig.getParameter<unsigned int>("popConAlgo")),
106  badComponentsFraction_(iConfig.getParameter<double>("badComponentsFraction")) {
108  throw cms::Exception("Inconsistent configuration")
109  << "[SiPhase2BadStripChannelBuilder::c'tor] the requested fraction of bad components is unphysical. \n";
110  }
111  theBCAlgo_ = static_cast<badChannelAlgo>(popConAlgo_);
112 }
113 
114 //__________________________________________________________________________________________________
115 std::unique_ptr<SiStripBadStrip> SiPhase2BadStripChannelBuilder::getNewObject() {
116  edm::LogInfo("SiPhase2BadStripChannelBuilder") << "... creating dummy SiStripBadStrip Data";
117 
118  auto obj = std::make_unique<SiStripBadStrip>();
119 
120  // early return with nullptr if fraction is ==0.
121  if (badComponentsFraction_ == 0.f) {
122  return obj;
123  }
124 
125  for (auto const& pixdet : theOTDets) {
126  uint32_t rawId = pixdet->geographicalId().rawId();
127  int subid = pixdet->geographicalId().subdetId();
128 
129  const PixelTopology& topol(pixdet->specificTopology());
130 
131  const int nrows = topol.nrows();
132  const int ncols = topol.ncolumns();
133 
134  LogDebug("SiPhase2BadStripChannelBuilder")
135  << "DetId: " << rawId << " subdet: " << subid << " nrows: " << nrows << " ncols: " << ncols;
136 
137  std::vector<unsigned int> theSiStripVector;
138 
139  switch (theBCAlgo_) {
140  case NAIVE: {
141  LogDebug("SiPhase2BadStripChannelBuilder") << "using the NAIVE algorithm";
142 
143  auto dis1 = std::uniform_int_distribution<>(0, nrows - 1); // [0, nrows]
144  auto dis2 = std::uniform_int_distribution<>(1, 10); // [1, 10]
145 
146  unsigned short firstBadStrip = std::floor(dis1(engine_));
147  unsigned short NconsecutiveBadStrips = std::floor(dis2(engine_));
148 
149  // if the interval exceeds the end of the module
150  if (firstBadStrip + NconsecutiveBadStrips > nrows) {
151  NconsecutiveBadStrips = nrows - firstBadStrip;
152  }
153 
154  unsigned int theBadStripRange;
155  theBadStripRange = obj->encodePhase2(firstBadStrip, NconsecutiveBadStrips);
156 
157  if (printdebug_)
158  edm::LogInfo("SiPhase2BadStripChannelBuilder")
159  << "detid " << rawId << " \t"
160  << " firstBadStrip " << firstBadStrip << "\t "
161  << " NconsecutiveBadStrips " << NconsecutiveBadStrips << "\t "
162  << " packed integer " << std::hex << theBadStripRange << std::dec;
163 
164  theSiStripVector.push_back(theBadStripRange);
165  break;
166  }
167  case RANDOM: {
168  LogDebug("SiPhase2BadStripChannelBuilder") << "using the RANDOM algorithm";
169 
170  // auxilliary vector to check if the channels were already used
171  std::vector<Phase2TrackerDigi::PackedDigiType> usedChannels;
172 
173  size_t nmaxBadStrips = std::floor(nrows * ncols * badComponentsFraction_);
174 
175  LogDebug("SiPhase2BadStripChannelBuilder")
176  << __FUNCTION__ << " " << __LINE__ << " will mask: " << nmaxBadStrips << " strips";
177 
178  auto disRows = std::uniform_int_distribution<>(0, nrows - 1); // [0, nrows]
179  auto disCols = std::uniform_int_distribution<>(0, ncols - 1); // [0, ncols]
180 
181  while (usedChannels.size() < nmaxBadStrips) {
182  unsigned short badStripRow = std::floor(disRows(engine_));
183  unsigned short badStripCol = std::floor(disCols(engine_));
184 
185  const auto& badChannel = Phase2TrackerDigi::pixelToChannel(badStripRow, badStripCol);
186 
187  LogDebug("SiPhase2BadStripChannelBuilder") << __FUNCTION__ << " " << __LINE__ << ": masking channel "
188  << badChannel << " (" << badStripRow << "," << badStripCol << ")";
189 
190  if (std::find(usedChannels.begin(), usedChannels.end(), badChannel) == usedChannels.end()) {
191  usedChannels.push_back(badChannel);
192  }
193  }
194 
195  const auto badChannelsGroups = this->clusterizeBadChannels(usedChannels);
196  // loop over the groups of bad strips
197  for (const auto& [first, consec] : badChannelsGroups) {
198  unsigned int theBadChannelsRange;
199  theBadChannelsRange = obj->encodePhase2(first, consec);
200 
201  if (printdebug_) {
202  edm::LogInfo("SiPhase2BadStripChannelBuilder")
203  << "detid " << rawId << " \t"
204  << " firstBadStrip " << first << "\t "
205  << " NconsecutiveBadStrips " << consec << "\t "
206  << " packed integer " << std::hex << theBadChannelsRange << std::dec;
207  }
208  theSiStripVector.push_back(theBadChannelsRange);
209  }
210  break;
211  }
212  case NONE:
213  [[fallthrough]];
214  default:
215  throw cms::Exception("Inconsistent configuration") << "Did not specifiy the right algorithm to be run";
216  }
217 
218  SiStripBadStrip::Range range(theSiStripVector.begin(), theSiStripVector.end());
219  if (!obj->put(rawId, range))
220  edm::LogError("SiPhase2BadStripChannelBuilder")
221  << "[SiPhase2BadStripChannelBuilder::getNewObject] detid already exists";
222 
223  } // loop of geomdets
224 
225  //End now write sistripbadChannel data in DB
227 
228  if (mydbservice.isAvailable()) {
229  if (mydbservice->isNewTagRequest("SiStripBadStripRcd")) {
230  mydbservice->createOneIOV<SiStripBadStrip>(*obj, mydbservice->beginOfTime(), "SiStripBadStripRcd");
231  } else {
232  mydbservice->appendOneIOV<SiStripBadStrip>(*obj, mydbservice->currentTime(), "SiStripBadStripRcd");
233  }
234  } else {
235  edm::LogError("SiPhase2BadStripChannelBuilder") << "Service is unavailable";
236  }
237 
238  return obj;
239 }
240 
241 // poor-man clusterizing algorithm
242 std::map<unsigned short, unsigned short> SiPhase2BadStripChannelBuilder::clusterizeBadChannels(
243  const std::vector<Phase2TrackerDigi::PackedDigiType>& maskedChannels) {
244  // Here we will store the result
245  std::map<unsigned short, unsigned short> result{};
246  std::map<int, std::string> printresult{};
247 
248  // Sort and remove duplicates.
249  std::set data(maskedChannels.begin(), maskedChannels.end());
250 
251  // We will start the evaluation at the beginning of our data
252  auto startOfSequence = data.begin();
253 
254  // Find all sequences
255  while (startOfSequence != data.end()) {
256  // FInd first value that is not greate than one
257  auto endOfSequence =
258  std::adjacent_find(startOfSequence, data.end(), [](const auto& v1, const auto& v2) { return v2 != v1 + 1; });
259  if (endOfSequence != data.end())
260  std::advance(endOfSequence, 1);
261 
262  auto consecutiveStrips = std::distance(startOfSequence, endOfSequence);
263  result[*startOfSequence] = consecutiveStrips;
264 
265  if (printdebug_) {
266  // Build resulting string
267  std::ostringstream oss{};
268  bool writeDash = false;
269  for (auto it = startOfSequence; it != endOfSequence; ++it) {
270  oss << (writeDash ? "-" : "") << std::to_string(*it);
271  writeDash = true;
272  }
273 
274  // Copy result to map
275  for (auto it = startOfSequence; it != endOfSequence; ++it)
276  printresult[*it] = oss.str();
277  }
278 
279  // Continue to search for the next sequence
280  startOfSequence = endOfSequence;
281  }
282 
283  if (printdebug_) {
284  // Show result on the screen. Or use the map in whichever way you want.
285  for (const auto& [value, text] : printresult)
286  edm::LogInfo("SiPhase2BadStripChannelBuilder") << std::left << std::setw(2) << value << " -> " << text << "\n";
287  }
288 
289  return result;
290 }
291 
292 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
295  desc.setComment("Module to build SiStripBadStrip Payloads for the Phase-2 Outer Tracker");
296  ConditionDBWriter::fillPSetDescription(desc); // inherited from mother class
297  desc.addUntracked<bool>("printDebug", false)->setComment("maximum amount of print-outs");
298  desc.add<unsigned int>("popConAlgo", 1)->setComment("algorithm to populate the payload: 1=NAIVE,2=RANDOM");
299  desc.add<double>("badComponentsFraction", 0.01)->setComment("fraction of bad components to populate the payload");
300  descriptions.addWithDefaultLabel(desc);
301 }
302 
305 
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
void algoBeginRun(const edm::Run &run, const edm::EventSetup &es) override
void algoAnalyze(const edm::Event &event, const edm::EventSetup &es) override
virtual int nrows() const =0
const edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > topoToken_
Log< level::Error, false > LogError
~SiPhase2BadStripChannelBuilder() override=default
std::vector< const Phase2TrackerGeomDetUnit * > theOTDets
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
assert(be >=bs)
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
static std::string to_string(const XMLCh *ch)
void createOneIOV(const T &payload, cond::Time_t firstSinceTime, const std::string &recordName)
void appendOneIOV(const T &payload, cond::Time_t sinceTime, const std::string &recordName)
static void fillPSetDescription(edm::ParameterSetDescription &desc)
std::unique_ptr< TrackerTopology > tTopo_
bool isNewTagRequest(const std::string &recordName)
static PackedDigiType pixelToChannel(unsigned int row, unsigned int col)
Transition
Definition: Transition.h:12
double f[11][100]
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
Definition: value.py:1
static constexpr auto TOB
std::unique_ptr< SiStripBadStrip > getNewObject() override
Log< level::Info, false > LogInfo
Definition: DetId.h:17
const edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > geomToken_
std::map< unsigned short, unsigned short > clusterizeBadChannels(const std::vector< Phase2TrackerDigi::PackedDigiType > &maskedChannels)
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
HLT enums.
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
std::pair< ContainerIterator, ContainerIterator > Range
bool isAvailable() const
Definition: Service.h:40
Definition: TkAlStyle.h:43
static constexpr auto TID
SiPhase2BadStripChannelBuilder(const edm::ParameterSet &)
Definition: event.py:1
Definition: Run.h:45
#define LogDebug(id)