CMS 3D CMS Logo

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