CMS 3D CMS Logo

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