CMS 3D CMS Logo

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