CMS 3D CMS Logo

ClustersFromRawProducer.cc
Go to the documentation of this file.
1 /*
2  */
5 
8 
11 
15 
17 
27 
29 #include <sstream>
30 #include <memory>
31 #include <atomic>
32 #include <mutex>
33 
34 // #define VIDEBUG
35 #ifdef VIDEBUG
36 #include <iostream>
37 #define COUT std::cout << "VI "
38 #else
39 #define COUT LogDebug("")
40 #endif
41 
42 namespace {
43  std::unique_ptr<sistrip::FEDBuffer> fillBuffer(int fedId, const FEDRawDataCollection& rawColl) {
44  std::unique_ptr<sistrip::FEDBuffer> buffer;
45 
46  // Retrieve FED raw data for given FED
47  const FEDRawData& rawData = rawColl.FEDData(fedId);
48 
49  // Check on FEDRawData pointer
50  const auto st_buffer = sistrip::preconstructCheckFEDBuffer(rawData);
52  if (edm::isDebugEnabled()) {
54  << "[ClustersFromRawProducer::" << __func__ << "]" << st_buffer << " for FED ID " << fedId;
55  }
56  return buffer;
57  }
58  buffer = std::make_unique<sistrip::FEDBuffer>(rawData);
59  const auto st_chan = buffer->findChannels();
61  if (edm::isDebugEnabled()) {
63  << "Exception caught when creating FEDBuffer object for FED " << fedId << ": " << st_chan;
64  }
65  buffer.reset();
66  return buffer;
67  }
68  if UNLIKELY (!buffer->doChecks(false)) {
69  if (edm::isDebugEnabled()) {
71  << "Exception caught when creating FEDBuffer object for FED " << fedId << ": FED Buffer check fails";
72  }
73  buffer.reset();
74  return buffer;
75  }
76 
77  /*
78  // dump of FEDRawData to stdout
79  if ( dump_ ) {
80  std::stringstream ss;
81  RawToDigiUnpacker::dumpRawData( fedId, rawData, ss );
82  LogTrace(mlRawToDigi_)
83  << ss.str();
84  }
85  */
86 
87  return buffer;
88  }
89 
90  class ClusterFiller final : public StripClusterizerAlgorithm::output_t::Getter {
91  public:
92  ClusterFiller(const FEDRawDataCollection& irawColl,
93  StripClusterizerAlgorithm& iclusterizer,
95  bool idoAPVEmulatorCheck,
96  bool legacy,
97  bool hybridZeroSuppressed)
98  : rawColl(irawColl),
99  clusterizer(iclusterizer),
100  conditions(iclusterizer.conditions()),
101  rawAlgos(irawAlgos),
102  doAPVEmulatorCheck(idoAPVEmulatorCheck),
103  legacy_(legacy),
104  hybridZeroSuppressed_(hybridZeroSuppressed) {
105  incTot(clusterizer.conditions().allDetIds().size());
106  for (auto& d : done)
107  d = nullptr;
108  }
109 
110  ~ClusterFiller() override { printStat(); }
111 
113 
114  private:
115  std::unique_ptr<sistrip::FEDBuffer> buffers[1024];
116  std::atomic<sistrip::FEDBuffer*> done[1024];
117 
118  const FEDRawDataCollection& rawColl;
119 
123 
124  // March 2012: add flag for disabling APVe check in configuration
125  bool doAPVEmulatorCheck;
126 
127  bool legacy_;
128  bool hybridZeroSuppressed_;
129 
130 #ifdef VIDEBUG
131  struct Stat {
132  Stat() : totDet(0), detReady(0), detSet(0), detAct(0), detNoZ(0), detAbrt(0), totClus(0) {}
133  std::atomic<int> totDet; // all dets
134  std::atomic<int> detReady; // dets "updated"
135  std::atomic<int> detSet; // det actually set not empty
136  std::atomic<int> detAct; // det actually set with content
137  std::atomic<int> detNoZ; // det actually set with content
138  std::atomic<int> detAbrt; // det aborted
139  std::atomic<int> totClus; // total number of clusters
140  };
141 
142  mutable Stat stat;
143  // void zeroStat() const { stat = std::move(Stat()); }
144  void incTot(int n) const { stat.totDet = n; }
145  void incReady() const { stat.detReady++; }
146  void incSet() const { stat.detSet++; }
147  void incAct() const { stat.detAct++; }
148  void incNoZ() const { stat.detNoZ++; }
149  void incAbrt() const { stat.detAbrt++; }
150  void incClus(int n) const { stat.totClus += n; }
151  void printStat() const {
152  COUT << "VI clusters " << stat.totDet << ',' << stat.detReady << ',' << stat.detSet << ',' << stat.detAct << ','
153  << stat.detNoZ << ',' << stat.detAbrt << ',' << stat.totClus << std::endl;
154  }
155 
156 #else
157  static void zeroStat() {}
158  static void incTot(int) {}
159  static void incReady() {}
160  static void incSet() {}
161  static void incAct() {}
162  static void incNoZ() {}
163  static void incAbrt() {}
164  static void incClus(int) {}
165  static void printStat() {}
166 #endif
167  };
168 } // namespace
169 
171 public:
173  : onDemand(conf.getParameter<bool>("onDemand")),
175  conf.getParameter<edm::ParameterSet>("Clusterizer"))),
176  rawAlgos_(SiStripRawProcessingFactory::create(conf.getParameter<edm::ParameterSet>("Algorithms"),
177  consumesCollector())),
178  doAPVEmulatorCheck_(conf.getParameter<bool>("DoAPVEmulatorCheck")),
179  legacy_(conf.getParameter<bool>("LegacyUnpacker")),
180  hybridZeroSuppressed_(conf.getParameter<bool>("HybridZeroSuppressed")) {
181  productToken_ = consumes<FEDRawDataCollection>(conf.getParameter<edm::InputTag>("ProductLabel"));
182  produces<edmNew::DetSetVector<SiStripCluster> >();
183  assert(clusterizer_.get());
184  assert(rawAlgos_.get());
185  }
186 
187  void produce(edm::Event& ev, const edm::EventSetup& es) override {
188  initialize(es);
189 
190  // get raw data
192  ev.getByToken(productToken_, rawData);
193 
194  std::unique_ptr<edmNew::DetSetVector<SiStripCluster> > output(
196  std::shared_ptr<edmNew::DetSetVector<SiStripCluster>::Getter>(std::make_shared<ClusterFiller>(
198  clusterizer_->conditions().allDetIds())
200 
201  if (onDemand)
202  assert(output->onDemand());
203 
204  output->reserve(15000, 24 * 10000);
205 
206  if (!onDemand) {
207  run(*rawData, *output);
208  output->shrink_to_fit();
209  COUT << output->dataSize() << " clusters from " << output->size() << " modules" << std::endl;
210  }
211 
212  ev.put(std::move(output));
213  }
214 
215  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
216 
217 private:
218  void initialize(const edm::EventSetup& es);
219 
221 
222 private:
223  bool onDemand;
224 
226 
227  std::unique_ptr<StripClusterizerAlgorithm> clusterizer_;
228  std::unique_ptr<SiStripRawProcessingAlgorithms> rawAlgos_;
229 
230  // March 2012: add flag for disabling APVe check in configuration
232 
233  bool legacy_;
235 };
236 
239 
240  desc.add("ProductLabel", edm::InputTag("rawDataCollector"));
241  desc.add<std::string>("ConditionsLabel", "");
242  desc.add("onDemand", true);
243  desc.add("DoAPVEmulatorCheck", true);
244  desc.add("LegacyUnpacker", false);
245  desc.add("HybridZeroSuppressed", false);
246 
249  desc.add("Clusterizer", clusterizer);
250 
253  desc.add("Algorithms", algorithms);
254 
255  descriptions.addWithDefaultLabel(desc);
256 }
257 
260 
262  (*clusterizer_).initialize(es);
263  (*rawAlgos_).initialize(es);
264 }
265 
268 
269  // loop over good det in cabling
270  for (auto idet : clusterizer_->conditions().allDetIds()) {
272 
273  filler.fill(record);
274 
275  if (record.empty())
276  record.abort();
277  } // end loop over dets
278 }
279 
280 namespace {
281  class StripByStripAdder {
282  public:
283  typedef std::output_iterator_tag iterator_category;
284  typedef void value_type;
285  typedef void difference_type;
286  typedef void pointer;
287  typedef void reference;
288 
289  StripByStripAdder(StripClusterizerAlgorithm& clusterizer,
292  : clusterizer_(clusterizer), state_(state), record_(record) {}
293 
294  StripByStripAdder& operator=(SiStripDigi digi) {
295  clusterizer_.stripByStripAdd(state_, digi.strip(), digi.adc(), record_);
296  return *this;
297  }
298 
299  StripByStripAdder& operator*() { return *this; }
300  StripByStripAdder& operator++() { return *this; }
301  StripByStripAdder& operator++(int) { return *this; }
302 
303  private:
304  StripClusterizerAlgorithm& clusterizer_;
307  };
308 
309  template <typename Container>
310  class ADC_back_inserter {
311  public:
312  ADC_back_inserter(Container& c) : c_(c) {}
313 
314  ADC_back_inserter& operator=(SiStripRawDigi digi) {
315  c_.push_back(digi.adc());
316  return *this;
317  }
318  ADC_back_inserter& operator*() { return *this; }
319  ADC_back_inserter& operator++() { return *this; }
320  ADC_back_inserter& operator++(int) { return *this; }
321 
322  private:
323  Container& c_;
324  };
325 } // namespace
326 
328  try { // edmNew::CapacityExaustedException
329  incReady();
330 
331  auto idet = record.id();
332 
333  COUT << "filling " << idet << std::endl;
334 
335  auto const& det = clusterizer.stripByStripBegin(idet);
336  if (!det.valid())
337  return;
339 
340  incSet();
341  record.reserve(16);
342  // Loop over apv-pairs of det
343  for (auto const conn : conditions.currentConnection(det)) {
344  if UNLIKELY (!conn)
345  continue;
346 
347  const uint16_t fedId = conn->fedId();
348 
349  // If fed id is null or connection is invalid continue
350  if UNLIKELY (!fedId || !conn->isConnected()) {
351  continue;
352  }
353 
354  // If Fed hasnt already been initialised, extract data and initialise
356  if (!buffer) {
357  buffer = fillBuffer(fedId, rawColl).release();
358  if (!buffer) {
359  continue;
360  }
361  sistrip::FEDBuffer* exp = nullptr;
362  if (done[fedId].compare_exchange_strong(exp, buffer))
363  buffers[fedId].reset(buffer);
364  else {
365  delete buffer;
366  buffer = done[fedId];
367  }
368  }
369  assert(buffer);
370 
371  buffer->setLegacyMode(legacy_);
372 
373  // check channel
374  const uint8_t fedCh = conn->fedCh();
375 
376  if UNLIKELY (!buffer->channelGood(fedCh, doAPVEmulatorCheck)) {
377  if (edm::isDebugEnabled()) {
378  std::ostringstream ss;
379  ss << "Problem unpacking channel " << fedCh << " on FED " << fedId;
381  }
382  continue;
383  }
384 
385  // Determine APV std::pair number
386  uint16_t ipair = conn->apvPairNumber();
387 
388  const sistrip::FEDReadoutMode mode = buffer->readoutMode();
389  const sistrip::FEDLegacyReadoutMode lmode =
390  legacy_ ? buffer->legacyReadoutMode() : sistrip::READOUT_MODE_LEGACY_INVALID;
391 
392  using namespace sistrip;
393  if LIKELY (fedchannelunpacker::isZeroSuppressed(mode, legacy_, lmode)) {
394  auto perStripAdder = StripByStripAdder(clusterizer, state, record);
395  const auto isNonLite = fedchannelunpacker::isNonLiteZS(mode, legacy_, lmode);
396  const uint8_t pCode = (isNonLite ? buffer->packetCode(legacy_, fedCh) : 0);
398  if LIKELY (!hybridZeroSuppressed_) {
400  buffer->channel(fedCh), perStripAdder, ipair * 256, isNonLite, mode, legacy_, lmode, pCode);
401  } else {
402  const uint32_t id = conn->detId();
403  edm::DetSet<SiStripDigi> unpDigis{id};
404  unpDigis.reserve(256);
406  buffer->channel(fedCh), std::back_inserter(unpDigis), ipair * 256, isNonLite, mode, legacy_, lmode, pCode);
408  edm::DetSet<SiStripDigi> suppDigis{id};
409  rawAlgos.suppressHybridData(unpDigis, suppDigis, ipair * 2);
410  std::copy(std::begin(suppDigis), std::end(suppDigis), perStripAdder);
411  }
412  }
415  << "Unordered clusters for channel " << fedCh << " on FED " << fedId << ": " << toString(st_ch);
416  continue;
417  }
418  } else {
420  if (fedchannelunpacker::isVirginRaw(mode, legacy_, lmode)) {
421  std::vector<int16_t> digis;
423  buffer->channel(fedCh), ADC_back_inserter(digis), buffer->channel(fedCh).packetCode());
425  //process raw
426  uint32_t id = conn->detId();
427  edm::DetSet<SiStripDigi> zsdigis(id);
428  //rawAlgos_->subtractorPed->subtract( id, ipair*256, digis);
429  //rawAlgos_->subtractorCMN->subtract( id, digis);
430  //rawAlgos_->suppressor->suppress( digis, zsdigis);
431  uint16_t firstAPV = ipair * 2;
432  rawAlgos.suppressVirginRawData(id, firstAPV, digis, zsdigis);
433  for (const auto digi : zsdigis) {
434  clusterizer.stripByStripAdd(state, digi.strip(), digi.adc(), record);
435  }
436  }
437  } else if (fedchannelunpacker::isProcessedRaw(mode, legacy_, lmode)) {
438  std::vector<int16_t> digis;
439  st_ch = fedchannelunpacker::unpackProcessedRaw(buffer->channel(fedCh), ADC_back_inserter(digis));
441  //process raw
442  uint32_t id = conn->detId();
443  edm::DetSet<SiStripDigi> zsdigis(id);
444  //rawAlgos_->subtractorCMN->subtract( id, digis);
445  //rawAlgos_->suppressor->suppress( digis, zsdigis);
446  uint16_t firstAPV = ipair * 2;
447  rawAlgos.suppressProcessedRawData(id, firstAPV, digis, zsdigis);
448  for (edm::DetSet<SiStripDigi>::const_iterator it = zsdigis.begin(); it != zsdigis.end(); it++) {
449  clusterizer.stripByStripAdd(state, it->strip(), it->adc(), record);
450  }
451  }
452  } else {
454  << "[ClustersFromRawProducer::" << __func__ << "]"
455  << " FEDRawData readout mode " << mode << " from FED id " << fedId << " not supported.";
456  }
459  << "[ClustersFromRawProducer::" << __func__ << "]" << toString(st_ch) << " from FED id " << fedId
460  << " channel " << fedCh;
461  }
462  }
463  } // end loop over conn
464 
465  clusterizer.stripByStripEnd(state, record);
466 
467  incAct();
468 
469  if (record.full()) {
470  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand for "
471  << record.id() << ' ' << record.size();
472  record.abort();
473  incAbrt();
474  }
475 
476  if (!record.empty())
477  incNoZ();
478 
479  COUT << "filled " << record.size() << std::endl;
480  for (auto const& cl : record)
481  COUT << cl.firstStrip() << ',' << cl.amplitudes().size() << std::endl;
482  incClus(record.size());
483  } catch (edmNew::CapacityExaustedException const&) {
484  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand";
485  }
486 }
bool isDebugEnabled()
void addWithDefaultLabel(ParameterSetDescription const &psetDescription)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
StatusCode unpackZeroSuppressed(const FEDChannel &channel, OUT &&out, uint16_t stripStart, bool isNonLite, FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID, uint8_t packetCode=0)
void run(const FEDRawDataCollection &rawColl, edmNew::DetSetVector< SiStripCluster > &output)
def create(alignables, pedeDump, additionalData, outputFile, config)
static const char mlRawToCluster_[]
constexpr Process operator++(Process p)
Definition: DataFormats.h:68
#define LIKELY(x)
Definition: Likely.h:20
void initialize(const edm::EventSetup &es)
static void fillDescriptions(edm::ParameterSetDescription &algorithms)
Log< level::Error, false > LogError
uint16_t adc() const
assert(be >=bs)
std::string toString(fedchannelunpacker::StatusCode status)
sistrip classes
const SiStripClusterizerConditions & conditions() const
const uint16_t & strip() const
Definition: SiStripDigi.h:33
const uint16_t & adc() const
Definition: SiStripDigi.h:34
bool isProcessedRaw(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
void reserve(size_t s)
Definition: DetSet.h:65
void produce(edm::Event &ev, const edm::EventSetup &es) override
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool isVirginRaw(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
StatusCode unpackVirginRaw(const FEDChannel &channel, OUT &&out, uint8_t packetCode)
std::unique_ptr< StripClusterizerAlgorithm > clusterizer_
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
Definition: SiStripDigi.h:12
virtual void fill(typename DetSetVector< T >::TSFastFiller &)=0
d
Definition: ztail.py:151
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
bool isZeroSuppressed(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
SiStripClusterizerFromRaw(const edm::ParameterSet &conf)
bool isNonLiteZS(FEDReadoutMode mode, bool legacy=false, FEDLegacyReadoutMode lmode=READOUT_MODE_LEGACY_INVALID)
HLT enums.
conn
Definition: getInfo.py:9
FEDBufferStatusCode preconstructCheckFEDBuffer(const FEDRawData &fedBuffer, bool allowBadBuffer=false)
#define COUT
static void fillDescriptions(edm::ParameterSetDescription &clusterizer)
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
#define UNLIKELY(x)
Definition: Likely.h:21
Log< level::Warning, false > LogWarning
collection_type::const_iterator const_iterator
Definition: DetSet.h:31
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
std::unique_ptr< SiStripRawProcessingAlgorithms > rawAlgos_
edm::AssociationVector< reco::JetRefBaseProd, Values > Container
edm::EDGetTokenT< FEDRawDataCollection > productToken_
def move(src, dest)
Definition: eostools.py:511
StatusCode unpackProcessedRaw(const FEDChannel &channel, OUT &&out)