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 legacy,
113  bool hybridZeroSuppressed):
114  rawColl(irawColl),
115  clusterizer(iclusterizer),
116  rawAlgos(irawAlgos),
117  doAPVEmulatorCheck(idoAPVEmulatorCheck),
118  legacy_(legacy),
119  hybridZeroSuppressed_(hybridZeroSuppressed){
120  incTot(clusterizer.allDetIds().size());
121  for (auto & d : done) d=nullptr;
122  }
123 
124 
125  ~ClusterFiller() override { printStat();}
126 
128 
129  private:
130 
131 
132  std::unique_ptr<sistrip::FEDBuffer> buffers[1024];
133  std::atomic<sistrip::FEDBuffer*> done[1024];
134 
135 
136  const FEDRawDataCollection& rawColl;
137 
140 
141 
142  // March 2012: add flag for disabling APVe check in configuration
143  bool doAPVEmulatorCheck;
144 
145  bool legacy_;
146  bool hybridZeroSuppressed_;
147 
148 
149 #ifdef VIDEBUG
150  struct Stat {
151  Stat() : totDet(0), detReady(0),detSet(0),detAct(0),detNoZ(0),detAbrt(0),totClus(0){}
152  std::atomic<int> totDet; // all dets
153  std::atomic<int> detReady; // dets "updated"
154  std::atomic<int> detSet; // det actually set not empty
155  std::atomic<int> detAct; // det actually set with content
156  std::atomic<int> detNoZ; // det actually set with content
157  std::atomic<int> detAbrt; // det aborted
158  std::atomic<int> totClus; // total number of clusters
159  };
160 
161  mutable Stat stat;
162  // void zeroStat() const { stat = std::move(Stat()); }
163  void incTot(int n) const { stat.totDet=n;}
164  void incReady() const { stat.detReady++;}
165  void incSet() const { stat.detSet++;}
166  void incAct() const { stat.detAct++;}
167  void incNoZ() const { stat.detNoZ++;}
168  void incAbrt() const { stat.detAbrt++;}
169  void incClus(int n) const { stat.totClus+=n;}
170  void printStat() const {
171  COUT << "VI clusters " << stat.totDet <<','<< stat.detReady <<','<< stat.detSet <<','<< stat.detAct<<','<< stat.detNoZ <<','<<stat.detAbrt <<','<<stat.totClus << std::endl;
172  }
173 
174 #else
175  static void zeroStat(){}
176  static void incTot(int){}
177  static void incReady() {}
178  static void incSet() {}
179  static void incAct() {}
180  static void incNoZ() {}
181  static void incAbrt(){}
182  static void incClus(int){}
183  static void printStat(){}
184 #endif
185 
186  };
187 } // namespace
188 
189 
190 
192 
193  public:
194 
196  onDemand(conf.getParameter<bool>("onDemand")),
197  cabling_(nullptr),
198  clusterizer_(StripClusterizerAlgorithmFactory::create(conf.getParameter<edm::ParameterSet>("Clusterizer"))),
199  rawAlgos_(SiStripRawProcessingFactory::create(conf.getParameter<edm::ParameterSet>("Algorithms"))),
200  doAPVEmulatorCheck_(conf.existsAs<bool>("DoAPVEmulatorCheck") ? conf.getParameter<bool>("DoAPVEmulatorCheck") : true),
201  legacy_(conf.existsAs<bool>("LegacyUnpacker") ? conf.getParameter<bool>("LegacyUnpacker") : false),
202  hybridZeroSuppressed_(conf.getParameter<bool>("HybridZeroSuppressed"))
203  {
204  productToken_ = consumes<FEDRawDataCollection>(conf.getParameter<edm::InputTag>("ProductLabel"));
205  produces< edmNew::DetSetVector<SiStripCluster> > ();
206  assert(clusterizer_.get());
207  assert(rawAlgos_.get());
208  }
209 
210 
211  void beginRun( const edm::Run&, const edm::EventSetup& es) override {
212  initialize(es);
213  }
214 
215 
216  void produce(edm::Event& ev, const edm::EventSetup& es) override {
217 
218  initialize(es);
219 
220  // get raw data
222  ev.getByToken( productToken_, rawData);
223 
224 
225  std::unique_ptr< edmNew::DetSetVector<SiStripCluster> > output(
226  onDemand ?
229  std::make_shared<ClusterFiller>(*rawData, *clusterizer_, *rawAlgos_,
230  doAPVEmulatorCheck_, legacy_, hybridZeroSuppressed_)),
231  clusterizer_->allDetIds())
233  );
234 
235  if(onDemand) assert(output->onDemand());
236 
237  output->reserve(15000,24*10000);
238 
239 
240  if (!onDemand) {
241  run(*rawData, *output);
242  output->shrink_to_fit();
243  COUT << output->dataSize() << " clusters from "
244  << output->size() << " modules"
245  << std::endl;
246  }
247 
248  ev.put(std::move(output));
249 
250  }
251 
252 private:
253 
254  void initialize(const edm::EventSetup& es);
255 
257 
258 
259  private:
260 
261  bool onDemand;
262 
264 
266 
267  std::unique_ptr<StripClusterizerAlgorithm> clusterizer_;
268  std::unique_ptr<SiStripRawProcessingAlgorithms> rawAlgos_;
269 
270 
271  // March 2012: add flag for disabling APVe check in configuration
273 
274  bool legacy_;
276 };
277 
280 
281 
282 
283 
285 
286  (*clusterizer_).initialize(es);
287  cabling_ = (*clusterizer_).cabling();
288  (*rawAlgos_).initialize(es);
289 
290 }
291 
294 
295  ClusterFiller filler(rawColl, *clusterizer_, *rawAlgos_, doAPVEmulatorCheck_, legacy_, hybridZeroSuppressed_);
296 
297  // loop over good det in cabling
298  for ( auto idet : clusterizer_->allDetIds()) {
299 
301 
302  filler.fill(record);
303 
304  if(record.empty()) record.abort();
305 
306  } // end loop over dets
307 }
308 
309 namespace {
310  template<typename OUT>
311  OUT unpackZS(const sistrip::FEDChannel& chan, sistrip::FEDReadoutMode mode, uint16_t stripOffset, OUT out)
312  {
313  using namespace sistrip;
314  switch ( mode ) {
317  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan);
318  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
319  } break;
322  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan, 10);
323  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
324  } break;
327  {
328  switch ( chan.packetCode() ) {
330  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedModeUnpacker(chan);
331  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
332  } break;
334  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedModeUnpacker(chan, 10);
335  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()); unpacker++; }
336  } break;
338  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedModeUnpacker(chan, 8);
339  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<2); unpacker++; }
340  } break;
342  { auto unpacker = FEDBSChannelUnpacker::zeroSuppressedModeUnpacker(chan, 8);
343  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<1); unpacker++; }
344  } break;
345  default:
346  edm::LogWarning(mlRawToCluster_) << "[ClustersFromRawProducer::" << __func__ << "]"
347  << " invalid packet code " << chan.packetCode() << " for zero-suppressed.";
348  }
349  } break;
352  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan);
353  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<1); unpacker++; }
354  } break;
357  { auto unpacker = FEDZSChannelUnpacker::zeroSuppressedLiteModeUnpacker(chan);
358  while (unpacker.hasData()) { *out++ = SiStripDigi(stripOffset+unpacker.sampleNumber(), unpacker.adc()<<2); unpacker++; }
359  } break;
360  default:;
361  }
362  return out;
363  }
364 
365  class StripByStripAdder {
366  public:
367  typedef std::output_iterator_tag iterator_category;
368  typedef void value_type;
369  typedef void difference_type;
370  typedef void pointer;
371  typedef void reference;
372 
373  StripByStripAdder(StripClusterizerAlgorithm& clusterizer,
376  : clusterizer_(clusterizer), state_(state), record_(record) {}
377 
378  StripByStripAdder& operator= ( SiStripDigi digi )
379  {
380  clusterizer_.stripByStripAdd(state_, digi.strip(), digi.adc(), record_);
381  return *this;
382  }
383 
384  StripByStripAdder& operator* () { return *this; }
385  StripByStripAdder& operator++ () { return *this; }
386  StripByStripAdder& operator++ (int) { return *this; }
387  private:
388  StripClusterizerAlgorithm& clusterizer_;
391  };
392 }
393 
395 try { // edmNew::CapacityExaustedException
396  incReady();
397 
398  auto idet= record.id();
399 
400  COUT << "filling " << idet << std::endl;
401 
402  auto const & det = clusterizer.stripByStripBegin(idet);
403  if (!det.valid()) return;
405 
406  incSet();
407 
408  // Loop over apv-pairs of det
409  for (auto const conn : clusterizer.currentConnection(det)) {
410  if UNLIKELY(!conn) continue;
411 
412  const uint16_t fedId = conn->fedId();
413 
414  // If fed id is null or connection is invalid continue
415  if UNLIKELY( !fedId || !conn->isConnected() ) { continue; }
416 
417 
418  // If Fed hasnt already been initialised, extract data and initialise
419  sistrip::FEDBuffer * buffer = done[fedId];
420  if (!buffer) {
421  buffer = fillBuffer(fedId, rawColl).release();
422  if (!buffer) { continue;}
423  sistrip::FEDBuffer * exp = nullptr;
424  if (done[fedId].compare_exchange_strong(exp, buffer)) buffers[fedId].reset(buffer);
425  else { delete buffer; buffer = done[fedId]; }
426  }
427  assert(buffer);
428 
429  buffer->setLegacyMode(legacy_);
430 
431  // check channel
432  const uint8_t fedCh = conn->fedCh();
433 
434  if UNLIKELY(!buffer->channelGood(fedCh,doAPVEmulatorCheck)) {
435  if (edm::isDebugEnabled()) {
436  std::ostringstream ss;
437  ss << "Problem unpacking channel " << fedCh << " on FED " << fedId;
439  }
440  continue;
441  }
442 
443  // Determine APV std::pair number
444  uint16_t ipair = conn->apvPairNumber();
445 
446 
447  const sistrip::FEDReadoutMode mode = buffer->readoutMode();
449 
450  if LIKELY( (!legacy_) && ( mode > sistrip::READOUT_MODE_VIRGIN_RAW ) && ( mode < sistrip::READOUT_MODE_SPY ) && ( mode != sistrip::READOUT_MODE_PROC_RAW ) ) {
451  // ZS modes
452  try {
453  auto perStripAdder = StripByStripAdder(clusterizer, state, record);
454  if LIKELY( ! hybridZeroSuppressed_ ) {
455  unpackZS(buffer->channel(fedCh), mode, ipair*256, perStripAdder);
456  } else {
457  const uint32_t id = conn->detId();
458  edm::DetSet<SiStripDigi> unpDigis{id}; unpDigis.reserve(256);
459  unpackZS(buffer->channel(fedCh), mode, ipair*256, std::back_inserter(unpDigis));
461  rawAlgos.convertHybridDigiToRawDigiVector(unpDigis, workRawDigis);
462  edm::DetSet<SiStripDigi> suppDigis{id};
463  rawAlgos.suppressHybridData(id, ipair*2, workRawDigis, suppDigis);
464  std::copy(std::begin(suppDigis), std::end(suppDigis), perStripAdder);
465  }
466  } catch (edmNew::CapacityExaustedException const&) {
467  throw;
468  } catch (const cms::Exception& e) {
469  if (edm::isDebugEnabled()) {
470  edm::LogWarning(sistrip::mlRawToCluster_) << "Unordered clusters for channel " << fedCh << " on FED " << fedId << ": " << e.what();
471  }
472  continue;
473  }
476  clusterizer.addFed(state, unpacker, ipair, record);
479  while (unpacker.hasData()) {
480  clusterizer.stripByStripAdd(state, ipair*256+unpacker.sampleNumber(), unpacker.adc(), record);
481  unpacker++;
482  }
484 
485  std::vector<int16_t> samples;
486  switch ( buffer->channel(fedCh).packetCode() ) {
488  { auto unpacker = sistrip::FEDRawChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh));
489  while (unpacker.hasData()) { samples.push_back(unpacker.adc()); unpacker++; }
490  } break;
492  { auto unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh), 10);
493  while (unpacker.hasData()) { samples.push_back(unpacker.adc()); unpacker++; }
494  } break;
496  { auto unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh), 8);
497  while (unpacker.hasData()) { samples.push_back(unpacker.adc()<<2); unpacker++; }
498  } break;
500  { auto unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(fedCh), 8);
501  while (unpacker.hasData()) { samples.push_back(unpacker.adc()<<1); unpacker++; }
502  } break;
503  default:
504  edm::LogWarning(sistrip::mlRawToCluster_) << "[ClustersFromRawProducer::" << __func__ << "]"
505  << " invalid packet code " << buffer->channel(fedCh).packetCode() << " for virgin raw.";
506  }
507  // un-multiplex the digis (from readout to physical order)
508  std::vector<int16_t> digis;
509  for ( uint16_t i = 0; i != samples.size(); ++i ) {
510  // move bits around: 2-0->7-5 , 4-3->4-3 , 6-5->2-1 , 7->0
511  const auto readout = ((i&0x7)<<5) + (i&(0x3<<3)) + ((i&(0x3<<5))>>4) + ((i&(0x1<<7))>>7);
512  digis.push_back(samples[readout]);
513  }
514  //process raw
515  uint32_t id = conn->detId();
516  edm::DetSet<SiStripDigi> zsdigis(id);
517  //rawAlgos_->subtractorPed->subtract( id, ipair*256, digis);
518  //rawAlgos_->subtractorCMN->subtract( id, digis);
519  //rawAlgos_->suppressor->suppress( digis, zsdigis);
520  uint16_t firstAPV = ipair*2;
521  rawAlgos.suppressVirginRawData(id, firstAPV,digis, zsdigis);
522  for ( const auto digi : zsdigis ) {
523  clusterizer.stripByStripAdd(state, digi.strip(), digi.adc(), record);
524  }
525 
527 
528  // create unpacker
530 
531  // unpack
532  std::vector<int16_t> digis;
533  while (unpacker.hasData()) {
534  digis.push_back(unpacker.adc());
535  unpacker++;
536  }
537 
538  //process raw
539  uint32_t id = conn->detId();
540  edm::DetSet<SiStripDigi> zsdigis(id);
541  //rawAlgos_->subtractorCMN->subtract( id, digis);
542  //rawAlgos_->suppressor->suppress( digis, zsdigis);
543  uint16_t firstAPV = ipair*2;
544  rawAlgos.suppressProcessedRawData(id, firstAPV,digis, zsdigis);
545  for( edm::DetSet<SiStripDigi>::const_iterator it = zsdigis.begin(); it!=zsdigis.end(); it++) {
546  clusterizer.stripByStripAdd(state, it->strip(), it->adc(), record);
547  }
548  } else {
550  << "[ClustersFromRawProducer::" << __func__ << "]"
551  << " FEDRawData readout mode " << mode << " from FED id " << fedId << " not supported.";
552  continue;
553  }
554  } // end loop over conn
555 
556  clusterizer.stripByStripEnd(state,record);
557 
558  incAct();
559 
560  if (record.full()) {
561  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand for " << record.id() << ' ' << record.size();
562  record.abort();
563  incAbrt();
564  }
565 
566  if(!record.empty()) incNoZ();
567 
568  COUT << "filled " << record.size() << std::endl;
569  for ( auto const & cl : record ) COUT << cl.firstStrip() << ','<< cl.amplitudes().size() << std::endl;
570  incClus(record.size());
571 } catch (edmNew::CapacityExaustedException const&) {
572  edm::LogError(sistrip::mlRawToCluster_) << "too many Sistrip Clusters to fit space allocated for OnDemand";
573 }
574 
575 }
576 
577 
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()
static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel &channel)
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:125
static std::unique_ptr< StripClusterizerAlgorithm > create(const edm::ParameterSet &)
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:517
SiStripAPVRestorer::digivector_t digivector_t
static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel)
FEDReadoutMode readoutMode() const
#define nullptr
#define LIKELY(x)
Definition: Likely.h:20
bool ev
char const * what() const override
Definition: Exception.cc:103
void initialize(const edm::EventSetup &es)
static FEDBSChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
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
void setLegacyMode(bool legacy)
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
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
const uint16_t & strip() const
Definition: SiStripDigi.h:33
FEDLegacyReadoutMode legacyReadoutMode() const
#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
static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel)
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 COUT
MatrixMeschach operator*(const MatrixMeschach &mat1, const MatrixMeschach &mat2)
#define UNLIKELY(x)
Definition: Likely.h:21
collection_type::const_iterator const_iterator
Definition: DetSet.h:33
const uint16_t & adc() const
Definition: SiStripDigi.h:34
std::unique_ptr< SiStripRawProcessingAlgorithms > rawAlgos_
edm::EDGetTokenT< FEDRawDataCollection > productToken_
def move(src, dest)
Definition: eostools.py:511
static const uint8_t PACKET_CODE_VIRGIN_RAW
Definition: Run.h:45