CMS 3D CMS Logo

SiPhase2BadStripConfigurableFakeESSource.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: CalibTracker/SiPhase2TrackerESProducers
4 // Class: SiPhase2BadStripConfigurableFakeESSource
5 //
14 // system include files
15 #include <memory>
16 
17 // user include files
38 
39 // neede for the random number generation
40 #include "CLHEP/Random/RandFlat.h"
41 #include "CLHEP/Random/JamesRandom.h"
42 
44 public:
46  ~SiPhase2BadStripConfigurableFakeESSource() override = default;
47 
49  const edm::IOVSyncValue& iov,
50  edm::ValidityInterval& iValidity) override;
51 
52  typedef std::unique_ptr<SiStripBadStrip> ReturnType;
54 
56 
57 private:
58  std::map<unsigned short, unsigned short> clusterizeBadChannels(
59  const std::vector<Phase2TrackerDigi::PackedDigiType>& maskedChannels);
60 
61  // configurables
64 
65  // random engine
66  std::unique_ptr<CLHEP::HepRandomEngine> engine_;
67 
68  // es tokens
71 };
72 
74  : engine_(new CLHEP::HepJamesRandom(iConfig.getParameter<unsigned int>("seed"))) {
75  auto cc = setWhatProduced(this);
76  trackTopoToken_ = cc.consumes();
77  geomToken_ = cc.consumes();
78 
79  printDebug_ = iConfig.getUntrackedParameter<bool>("printDebug", false);
80  badComponentsFraction_ = iConfig.getParameter<double>("badComponentsFraction");
81 
83  throw cms::Exception("Inconsistent configuration")
84  << "[SiPhase2BadStripChannelBuilder::c'tor] the requested fraction of bad components is unphysical. \n";
85  }
86 
87  findingRecord<SiPhase2OuterTrackerBadStripRcd>();
88 }
89 
91  const edm::IOVSyncValue& iov,
92  edm::ValidityInterval& iValidity) {
93  iValidity = edm::ValidityInterval{iov.beginOfTime(), iov.endOfTime()};
94 }
95 
96 // ------------ method called to produce the data ------------
98  const SiPhase2OuterTrackerBadStripRcd& iRecord) {
99  using namespace edm::es;
101 
102  //TrackerTopology const& tTopo = iRecord.get(trackTopoToken_);
103  TrackerGeometry const& tGeom = iRecord.get(geomToken_);
104 
105  auto badStrips = std::make_unique<SiStripBadStrip>();
106 
107  // early return with nullptr if fraction is == 0.f
108  if (badComponentsFraction_ == 0.f) {
109  return badStrips;
110  }
111 
112  LogDebug("SiPhase2BadStripConfigurableFakeESSource")
113  << " There are " << tGeom.detUnits().size() << " modules in this geometry.";
114 
115  int counter{0};
116  for (auto const& det_u : tGeom.detUnits()) {
117  const DetId detid = det_u->geographicalId();
118  uint32_t rawId = detid.rawId();
119  int subid = detid.subdetId();
120  if (detid.det() == DetId::Detector::Tracker) {
121  const Phase2TrackerGeomDetUnit* pixdet = dynamic_cast<const Phase2TrackerGeomDetUnit*>(det_u);
122  assert(pixdet);
123  if (subid == StripSubdetector::TOB || subid == StripSubdetector::TID) {
126  const PixelTopology& topol(pixdet->specificTopology());
127 
128  const int nrows = topol.nrows();
129  const int ncols = topol.ncolumns();
130 
131  LogDebug("SiPhase2BadStripConfigurableFakeESSource")
132  << "DetId: " << rawId << " subdet: " << subid << " nrows: " << nrows << " ncols: " << ncols;
133 
134  // auxilliary vector to check if the channels were already used
135  std::vector<Phase2TrackerDigi::PackedDigiType> usedChannels;
136 
137  size_t nmaxBadStrips = std::floor(nrows * ncols * badComponentsFraction_);
138 
139  while (usedChannels.size() < nmaxBadStrips) {
140  unsigned short badStripRow = std::floor(CLHEP::RandFlat::shoot(engine_.get(), 0, nrows));
141  unsigned short badStripCol = std::floor(CLHEP::RandFlat::shoot(engine_.get(), 0, ncols));
142  const auto& badChannel = Phase2TrackerDigi::pixelToChannel(badStripRow, badStripCol);
143  if (std::find(usedChannels.begin(), usedChannels.end(), badChannel) == usedChannels.end()) {
144  usedChannels.push_back(badChannel);
145  }
146  }
147 
148  //usedChannels.push_back(Phase2TrackerDigi::pixelToChannel(0,1)); // useful for testing
149 
150  const auto badChannelsGroups = this->clusterizeBadChannels(usedChannels);
151 
152  LogDebug("SiPhase2BadStripConfigurableFakeESSource")
153  << rawId << " (" << counter << ") "
154  << " masking " << nmaxBadStrips << " strips, used channels size: " << usedChannels.size()
155  << ", clusters size: " << badChannelsGroups.size();
156 
157  std::vector<unsigned int> theSiStripVector;
158 
159  // loop over the groups of bad strips
160  for (const auto& [first, consec] : badChannelsGroups) {
161  unsigned int theBadChannelsRange;
162  theBadChannelsRange = badStrips->encodePhase2(first, consec);
163 
164  if (printDebug_) {
165  edm::LogInfo("SiPhase2BadStripConfigurableFakeESSource")
166  << "detid " << rawId << " \t"
167  << " firstBadStrip " << first << "\t "
168  << " NconsecutiveBadStrips " << consec << "\t "
169  << " packed integer " << std::hex << theBadChannelsRange << std::dec;
170  }
171  theSiStripVector.push_back(theBadChannelsRange);
172  }
173 
174  SiStripBadStrip::Range range(theSiStripVector.begin(), theSiStripVector.end());
175  if (!badStrips->put(rawId, range))
176  edm::LogError("SiPhase2BadStripConfigurableFakeESSource")
177  << "[SiPhase2BadStripConfigurableFakeESSource::produce] detid already exists";
178 
179  counter++;
180 
181  } // if it's a strip module
182  } // if it's OT
183  } // if it's Tracker
184  } // loop on DetIds
185 
186  LogDebug("SiPhase2BadStripConfigurableFakeESSource") << "end of the detId loops";
187 
188  return badStrips;
189 }
190 
191 // poor-man clusterizing algorithm
193  const std::vector<Phase2TrackerDigi::PackedDigiType>& maskedChannels) {
194  // Here we will store the result
195  std::map<unsigned short, unsigned short> result{};
196  std::map<int, std::string> printresult{};
197 
198  // Sort and remove duplicates.
199  std::set data(maskedChannels.begin(), maskedChannels.end());
200 
201  // We will start the evaluation at the beginning of our data
202  auto startOfSequence = data.begin();
203 
204  // Find all sequences
205  while (startOfSequence != data.end()) {
206  // Find first value that is not greater than one
207  auto endOfSequence =
208  std::adjacent_find(startOfSequence, data.end(), [](const auto& v1, const auto& v2) { return v2 != v1 + 1; });
209  if (endOfSequence != data.end())
210  std::advance(endOfSequence, 1);
211 
212  auto consecutiveStrips = std::distance(startOfSequence, endOfSequence);
213  result[*startOfSequence] = consecutiveStrips;
214 
215  if (printDebug_) {
216  // Build resulting string
217  std::ostringstream oss{};
218  bool writeDash = false;
219  for (auto it = startOfSequence; it != endOfSequence; ++it) {
220  oss << (writeDash ? "-" : "") << std::to_string(*it);
221  writeDash = true;
222  }
223 
224  // Copy result to map
225  for (auto it = startOfSequence; it != endOfSequence; ++it)
226  printresult[*it] = oss.str();
227  }
228 
229  // Continue to search for the next sequence
230  startOfSequence = endOfSequence;
231  }
232 
233  if (printDebug_) {
234  // Show result on the screen. Or use the map in whichever way you want.
235  for (const auto& [value, text] : printresult)
236  LogDebug("SiPhase2BadStripConfigurableFakeESSource")
237  << std::left << std::setw(2) << value << " -> " << text << "\n";
238  }
239  return result;
240 }
241 
244  desc.setComment("Configurable Fake Phase-2 Outer Tracker Bad Strip ESSource");
245  desc.add<unsigned int>("seed", 1)->setComment("random seed");
246  desc.addUntracked<bool>("printDebug", false)->setComment("maximum amount of print-outs");
247  desc.add<double>("badComponentsFraction", 0.01)->setComment("fraction of bad components to populate the ES");
248  descriptions.addWithDefaultLabel(desc);
249 }
250 
251 //define this as a plug-in
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > geomToken_
auto setWhatProduced(T *iThis, const es::Label &iLabel={})
Definition: ESProducer.h:163
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
static const IOVSyncValue & endOfTime()
Definition: IOVSyncValue.cc:82
virtual int nrows() const =0
std::string to_string(const V &value)
Definition: OMSAccess.h:71
const DetContainer & detUnits() const override
Returm a vector of all GeomDet.
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:46
T getUntrackedParameter(std::string const &, T const &) const
std::map< unsigned short, unsigned short > clusterizeBadChannels(const std::vector< Phase2TrackerDigi::PackedDigiType > &maskedChannels)
static const IOVSyncValue & beginOfTime()
Definition: IOVSyncValue.cc:88
ModuleType getDetectorType(DetId) const
static PackedDigiType pixelToChannel(unsigned int row, unsigned int col)
double f[11][100]
~SiPhase2BadStripConfigurableFakeESSource() override=default
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
Log< level::Info, false > LogInfo
#define DEFINE_FWK_EVENTSETUP_SOURCE(type)
Definition: SourceFactory.h:91
Definition: DetId.h:17
void setIntervalFor(const edm::eventsetup::EventSetupRecordKey &, const edm::IOVSyncValue &iov, edm::ValidityInterval &iValidity) override
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
ReturnType produce(const SiPhase2OuterTrackerBadStripRcd &)
static void fillDescriptions(edm::ConfigurationDescriptions &)
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > trackTopoToken_
std::pair< ContainerIterator, ContainerIterator > Range
ProductT const & get(ESGetToken< ProductT, DepRecordT > const &iToken) const
static constexpr auto TID
#define LogDebug(id)