CMS 3D CMS Logo

ClustersFromRawProducer.cc
Go to the documentation of this file.
1 /*
2  */
5 
8 
9 
12 
16 
18 
19 
26 
27 
29 #include <sstream>
30 #include <memory>
31 #include <atomic>
32 #include <mutex>
33 
35 
36 
37 // #define VIDEBUG
38 #ifdef VIDEBUG
39 #include<iostream>
40 #define COUT std::cout << "VI "
41 #else
42 #define COUT LogDebug("")
43 #endif
44 
45 
46 namespace {
47  std::unique_ptr<sistrip::FEDBuffer> fillBuffer(int fedId, const FEDRawDataCollection& rawColl) {
48  std::unique_ptr<sistrip::FEDBuffer> buffer;
49 
50  // Retrieve FED raw data for given FED
51  const FEDRawData& rawData = rawColl.FEDData(fedId);
52 
53  // Check on FEDRawData pointer
54  if UNLIKELY( !rawData.data() ) {
55  if (edm::isDebugEnabled()) {
57  << "[ClustersFromRawProducer::"
58  << __func__
59  << "]"
60  << " NULL pointer to FEDRawData for FED id "
61  << fedId;
62  }
63  return buffer;
64  }
65 
66  // Check on FEDRawData size
67  if UNLIKELY( !rawData.size() ) {
68  if (edm::isDebugEnabled()) {
70  << "[ClustersFromRawProducer::"
71  << __func__ << "]"
72  << " FEDRawData has zero size for FED id "
73  << fedId;
74  }
75  return buffer;
76  }
77 
78  // construct FEDBuffer
79  try {
80  buffer.reset(new sistrip::FEDBuffer(rawData.data(),rawData.size()));
81  if UNLIKELY(!buffer->doChecks(false)) throw cms::Exception("FEDBuffer") << "FED Buffer check fails for FED ID" << fedId << ".";
82  }
83  catch (const cms::Exception& e) {
84  if (edm::isDebugEnabled()) {
86  << "Exception caught when creating FEDBuffer object for FED " << fedId << ": " << e.what();
87  }
88  return std::unique_ptr<sistrip::FEDBuffer>();
89  }
90 
91  /*
92  // dump of FEDRawData to stdout
93  if ( dump_ ) {
94  std::stringstream ss;
95  RawToDigiUnpacker::dumpRawData( fedId, rawData, ss );
96  LogTrace(mlRawToDigi_)
97  << ss.str();
98  }
99  */
100 
101  return buffer;
102 
103  }
104 
105 
106  class ClusterFiller final : public StripClusterizerAlgorithm::output_t::Getter {
107  public:
108  ClusterFiller(const FEDRawDataCollection& irawColl,
109  StripClusterizerAlgorithm & iclusterizer,
110  SiStripRawProcessingAlgorithms & irawAlgos,
111  bool idoAPVEmulatorCheck,
112  bool hybridZeroSuppressed):
113  rawColl(irawColl),
114  clusterizer(iclusterizer),
115  rawAlgos(irawAlgos),
116  doAPVEmulatorCheck(idoAPVEmulatorCheck),
117  hybridZeroSuppressed_(hybridZeroSuppressed){
118  incTot(clusterizer.allDetIds().size());
119  for (auto & d : done) d=nullptr;
120  }
121 
122 
123  ~ClusterFiller() override { printStat();}
124 
126 
127  private:
128 
129 
130  std::unique_ptr<sistrip::FEDBuffer> buffers[1024];
131  std::atomic<sistrip::FEDBuffer*> done[1024];
132 
133 
134  const FEDRawDataCollection& rawColl;
135 
138 
139 
140  // March 2012: add flag for disabling APVe check in configuration
141  bool doAPVEmulatorCheck;
142 
143  bool hybridZeroSuppressed_;
144 
145 
146 #ifdef VIDEBUG
147  struct Stat {
148  Stat() : totDet(0), detReady(0),detSet(0),detAct(0),detNoZ(0),detAbrt(0),totClus(0){}
149  std::atomic<int> totDet; // all dets
150  std::atomic<int> detReady; // dets "updated"
151  std::atomic<int> detSet; // det actually set not empty
152  std::atomic<int> detAct; // det actually set with content
153  std::atomic<int> detNoZ; // det actually set with content
154  std::atomic<int> detAbrt; // det aborted
155  std::atomic<int> totClus; // total number of clusters
156  };
157 
158  mutable Stat stat;
159  // void zeroStat() const { stat = std::move(Stat()); }
160  void incTot(int n) const { stat.totDet=n;}
161  void incReady() const { stat.detReady++;}
162  void incSet() const { stat.detSet++;}
163  void incAct() const { stat.detAct++;}
164  void incNoZ() const { stat.detNoZ++;}
165  void incAbrt() const { stat.detAbrt++;}
166  void incClus(int n) const { stat.totClus+=n;}
167  void printStat() const {
168  COUT << "VI clusters " << stat.totDet <<','<< stat.detReady <<','<< stat.detSet <<','<< stat.detAct<<','<< stat.detNoZ <<','<<stat.detAbrt <<','<<stat.totClus << std::endl;
169  }
170 
171 #else
172  static void zeroStat(){}
173  static void incTot(int){}
174  static void incReady() {}
175  static void incSet() {}
176  static void incAct() {}
177  static void incNoZ() {}
178  static void incAbrt(){}
179  static void incClus(int){}
180  static void printStat(){}
181 #endif
182 
183  };
184 
185 
186 } // namespace
187 
188 
189 
191 
192  public:
193 
195  onDemand(conf.getParameter<bool>("onDemand")),
196  cabling_(nullptr),
197  clusterizer_(StripClusterizerAlgorithmFactory::create(conf.getParameter<edm::ParameterSet>("Clusterizer"))),
198  rawAlgos_(SiStripRawProcessingFactory::create(conf.getParameter<edm::ParameterSet>("Algorithms"))),
199  doAPVEmulatorCheck_(conf.existsAs<bool>("DoAPVEmulatorCheck") ? conf.getParameter<bool>("DoAPVEmulatorCheck") : true),
200  hybridZeroSuppressed_(conf.getParameter<bool>("HybridZeroSuppressed"))
201  {
202  productToken_ = consumes<FEDRawDataCollection>(conf.getParameter<edm::InputTag>("ProductLabel"));
203  produces< edmNew::DetSetVector<SiStripCluster> > ();
204  assert(clusterizer_.get());
205  assert(rawAlgos_.get());
206  }
207 
208 
209  void beginRun( const edm::Run&, const edm::EventSetup& es) override {
210  initialize(es);
211  }
212 
213 
214  void produce(edm::Event& ev, const edm::EventSetup& es) override {
215 
216  initialize(es);
217 
218  // get raw data
220  ev.getByToken( productToken_, rawData);
221 
222 
223  std::unique_ptr< edmNew::DetSetVector<SiStripCluster> > output(
224  onDemand ?
227  std::make_shared<ClusterFiller>(*rawData, *clusterizer_, *rawAlgos_,
228  doAPVEmulatorCheck_, hybridZeroSuppressed_)),
229  clusterizer_->allDetIds())
231  );
232 
233  if(onDemand) assert(output->onDemand());
234 
235  output->reserve(15000,24*10000);
236 
237 
238  if (!onDemand) {
239  run(*rawData, *output);
240  output->shrink_to_fit();
241  COUT << output->dataSize() << " clusters from "
242  << output->size() << " modules"
243  << std::endl;
244  }
245 
246  ev.put(std::move(output));
247 
248  }
249 
250 private:
251 
252  void initialize(const edm::EventSetup& es);
253 
255 
256 
257  private:
258 
259  bool onDemand;
260 
262 
264 
265  std::unique_ptr<StripClusterizerAlgorithm> clusterizer_;
266  std::unique_ptr<SiStripRawProcessingAlgorithms> rawAlgos_;
267 
268 
269  // March 2012: add flag for disabling APVe check in configuration
271 
273 };
274 
277 
278 
279 
280 
282 
283  (*clusterizer_).initialize(es);
284  cabling_ = (*clusterizer_).cabling();
285  (*rawAlgos_).initialize(es);
286 
287 }
288 
291 
292  ClusterFiller filler(rawColl, *clusterizer_, *rawAlgos_, doAPVEmulatorCheck_, hybridZeroSuppressed_);
293 
294  // loop over good det in cabling
295  for ( auto idet : clusterizer_->allDetIds()) {
296 
298 
299  filler.fill(record);
300 
301  if(record.empty()) record.abort();
302 
303  } // end loop over dets
304 }
305 
306 namespace {
307  template<typename OUT>
308  OUT unpackZS(const sistrip::FEDChannel& chan, sistrip::FEDReadoutMode mode, uint16_t stripOffset, OUT out)
309  {
310  using namespace sistrip;
311  switch ( mode ) {
314  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan);
315  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
316  } break;
319  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan, 10);
320  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
321  } break;
324  {
325  switch ( chan.packetCode() ) {
327  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedModeUnpacker(chan);
328  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
329  } break;
331  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedModeUnpacker(chan, 10);
332  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
333  } break;
335  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedModeUnpacker(chan, 8);
336  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<2); unpacker++; }
337  } break;
339  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedModeUnpacker(chan, 8);
340  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<1); unpacker++; }
341  } break;
342  default:
343  edm::LogWarning(mlRawToCluster_) << "[ClustersFromRawProducer::" << __func__ << "]"
344  << " invalid packet code " << chan.packetCode() << " for zero-suppressed.";
345  }
346  } break;
349  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan);
350  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<1); unpacker++; }
351  } break;
354  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan);
355  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<2); unpacker++; }
356  } break;
357  default:;
358  }
359  return out;
360  }
361 
362  class StripByStripAdder {
363  public:
364  typedef std::output_iterator_tag iterator_category;
365  typedef void value_type;
366  typedef void difference_type;
367  typedef void pointer;
368  typedef void reference;
369 
370  StripByStripAdder(StripClusterizerAlgorithm& clusterizer,
373  : clusterizer_(clusterizer), state_(state), record_(record) {}
374 
375  StripByStripAdder& operator= ( SiStripDigi digi )
376  {
377  clusterizer_.stripByStripAdd(state_, digi.strip(), digi.adc(), record_);
378  return *this;
379  }
380 
381  StripByStripAdder& operator* () { return *this; }
382  StripByStripAdder& operator++ () { return *this; }
383  StripByStripAdder& operator++ (int) { return *this; }
384  private:
385  StripClusterizerAlgorithm& clusterizer_;
388  };
389 }
390 
392 try { // edmNew::CapacityExaustedException
393  incReady();
394 
395  auto idet= record.id();
396 
397  COUT << "filling " << idet << std::endl;
398 
399  auto const & det = clusterizer.stripByStripBegin(idet);
400  if (!det.valid()) return;
402 
403  incSet();
404 
405  // Loop over apv-pairs of det
406  for (auto const conn : clusterizer.currentConnection(det)) {
407  if UNLIKELY(!conn) continue;
408 
409  const uint16_t fedId = conn->fedId();
410 
411  // If fed id is null or connection is invalid continue
412  if UNLIKELY( !fedId || !conn->isConnected() ) { continue; }
413 
414 
415  // If Fed hasnt already been initialised, extract data and initialise
416  sistrip::FEDBuffer * buffer = done[fedId];
417  if (!buffer) {
418  buffer = fillBuffer(fedId, rawColl).release();
419  if (!buffer) { continue;}
420  sistrip::FEDBuffer * exp = nullptr;
421  if (done[fedId].compare_exchange_strong(exp, buffer)) buffers[fedId].reset(buffer);
422  else { delete buffer; buffer = done[fedId]; }
423  }
424  assert(buffer);
425 
426  // check channel
427  const uint8_t fedCh = conn->fedCh();
428 
429  if UNLIKELY(!buffer->channelGood(fedCh,doAPVEmulatorCheck)) {
430  if (edm::isDebugEnabled()) {
431  std::ostringstream ss;
432  ss << "Problem unpacking channel " << fedCh << " on FED " << fedId;
434  }
435  continue;
436  }
437 
438  // Determine APV std::pair number
439  uint16_t ipair = conn->apvPairNumber();
440 
441 
442  const sistrip::FEDReadoutMode mode = buffer->readoutMode();
443 
445  // ZS modes
446  try {
447  auto perStripAdder = StripByStripAdder(clusterizer, state, record);
448  if LIKELY( ! hybridZeroSuppressed_ ) {
449  unpackZS(buffer->channel(fedCh), mode, ipair*256, perStripAdder);
450  } else {
451  const uint32_t id = conn->detId();
452  edm::DetSet<SiStripDigi> unpDigis{id}; unpDigis.reserve(256);
453  unpackZS(buffer->channel(fedCh), mode, ipair*256, std::back_inserter(unpDigis));
455  rawAlgos.convertHybridDigiToRawDigiVector(unpDigis, workRawDigis);
456  edm::DetSet<SiStripDigi> suppDigis{id};
457  rawAlgos.suppressHybridData(id, ipair*2, workRawDigis, suppDigis);
458  std::copy(std::begin(suppDigis), std::end(suppDigis), perStripAdder);
459  }
461  throw;
462  } catch (const cms::Exception& e) {
463  if (edm::isDebugEnabled()) {
464  edm::LogWarning(sistrip::mlRawToCluster_) << "Unordered clusters for channel " << fedCh << " on FED " << fedId << ": " << e.what();
465  }
466  continue;
467  }
468 
469  } else if ( mode == sistrip::READOUT_MODE_VIRGIN_RAW ) {
470 
471  std::vector<int16_t> digis;
472  switch ( buffer->channel(fedCh).packetCode() ) {
474  { auto unpacker = sistrip::FEDRawChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh));
475  while (unpacker.hasData()) { digis.push_back(unpacker.adc()); unpacker++; }
476  } break;
478  { auto unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh), 10);
479  while (unpacker.hasData()) { digis.push_back(unpacker.adc()); unpacker++; }
480  } break;
482  { auto unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh), 8);
483  while (unpacker.hasData()) { digis.push_back(unpacker.adc()<<2); unpacker++; }
484  } break;
486  { auto unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh), 8);
487  while (unpacker.hasData()) { digis.push_back(unpacker.adc()<<1); unpacker++; }
488  } break;
489  default:
490  edm::LogWarning(sistrip::mlRawToCluster_) << "[ClustersFromRawProducer::" << __func__ << "]"
491  << " invalid packet code " << buffer->channel(fedCh).packetCode() << " for virgin raw.";
492  }
493  //process raw
494  uint32_t id = conn->detId();
495  edm::DetSet<SiStripDigi> zsdigis(id);
496  //rawAlgos_->subtractorPed->subtract( id, ipair*256, digis);
497  //rawAlgos_->subtractorCMN->subtract( id, digis);
498  //rawAlgos_->suppressor->suppress( digis, zsdigis);
499  uint16_t firstAPV = ipair*2;
500  rawAlgos.suppressVirginRawData(id, firstAPV,digis, zsdigis);
501  for ( const auto digi : zsdigis ) {
502  clusterizer.stripByStripAdd(state, digi.strip(), digi.adc(), record);
503  }
504 
505  } else if ( mode == sistrip::READOUT_MODE_PROC_RAW ) {
506 
507  // create unpacker
509 
510  // unpack
511  std::vector<int16_t> digis;
512  while (unpacker.hasData()) {
513  digis.push_back(unpacker.adc());
514  unpacker++;
515  }
516 
517  //process raw
518  uint32_t id = conn->detId();
519  edm::DetSet<SiStripDigi> zsdigis(id);
520  //rawAlgos_->subtractorCMN->subtract( id, digis);
521  //rawAlgos_->suppressor->suppress( digis, zsdigis);
522  uint16_t firstAPV = ipair*2;
523  rawAlgos.suppressProcessedRawData(id, firstAPV,digis, zsdigis);
524  for( edm::DetSet<SiStripDigi>::const_iterator it = zsdigis.begin(); it!=zsdigis.end(); it++) {
525  clusterizer.stripByStripAdd(state, it->strip(), it->adc(), record);
526  }
527  } else {
529  << "[ClustersFromRawProducer::" << __func__ << "]"
530  << " FEDRawData readout mode " << mode << " from FED id " << fedId << " not supported.";
531  continue;
532  }
533  } // end loop over conn
534 
535  clusterizer.stripByStripEnd(state,record);
536 
537  incAct();
538 
539  if (record.full()) {
540  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand for " << record.id() << ' ' << record.size();
541  record.abort();
542  incAbrt();
543  }
544 
545  if(!record.empty()) incNoZ();
546 
547  COUT << "filled " << record.size() << std::endl;
548  for ( auto const & cl : record ) COUT << cl.firstStrip() << ','<< cl.amplitudes().size() << std::endl;
549  incClus(record.size());
551  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand";
552 }
553 
554 }
555 
556 
iterator end()
Definition: DetSet.h:60
static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel &channel)
T getParameter(std::string const &) const
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
static AlgebraicMatrix initialize()
bool isDebugEnabled()
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
void beginRun(const edm::Run &, const edm::EventSetup &es) override
void run(const FEDRawDataCollection &rawColl, edmNew::DetSetVector< SiStripCluster > &output)
def copy(args, dbName)
static const char mlRawToCluster_[]
JetCorrectorParameters::Record record
Definition: classes.h:7
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
SiStripAPVRestorer::digivector_t digivector_t
static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel)
FEDReadoutMode readoutMode() const
bool ev
char const * what() const override
Definition: Exception.cc:141
void initialize(const edm::EventSetup &es)
static FEDBSChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
#define nullptr
virtual bool channelGood(const uint8_t internalFEDannelNum, const bool doAPVeCheck=true) const
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
sistrip classes
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED10
static const uint8_t PACKET_CODE_VIRGIN_RAW10
void reserve(size_t s)
Definition: DetSet.h:67
void produce(edm::Event &ev, const edm::EventSetup &es) override
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
static std::auto_ptr< StripClusterizerAlgorithm > create(const edm::ParameterSet &)
const uint16_t & strip() const
Definition: SiStripDigi.h:40
#define end
Definition: vmac.h:39
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
const FEDChannel & channel(const uint8_t internalFEDChannelNum) const
static const uint8_t PACKET_CODE_VIRGIN_RAW8_TOPBOT
iterator begin()
Definition: DetSet.h:59
static const uint8_t PACKET_CODE_VIRGIN_RAW8_BOTBOT
SiStripDetCabling const * cabling_
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
SiStripClusterizerFromRaw(const edm::ParameterSet &conf)
#define begin
Definition: vmac.h:32
HLT enums.
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
#define LIKELY(x)
#define COUT
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
collection_type::const_iterator const_iterator
Definition: DetSet.h:33
const uint16_t & adc() const
Definition: SiStripDigi.h:41
std::unique_ptr< SiStripRawProcessingAlgorithms > rawAlgos_
edm::EDGetTokenT< FEDRawDataCollection > productToken_
def move(src, dest)
Definition: eostools.py:510
static const uint8_t PACKET_CODE_VIRGIN_RAW
Definition: Run.h:44
#define UNLIKELY(x)