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