CMS 3D CMS Logo

SiStripRawToDigiUnpacker.cc
Go to the documentation of this file.
15 #include <iostream>
16 #include <sstream>
17 #include <iomanip>
18 #include <boost/format.hpp>
19 #include <ext/algorithm>
21 
22 namespace sistrip {
23 
24  RawToDigiUnpacker::RawToDigiUnpacker( int16_t appended_bytes, int16_t fed_buffer_dump_freq, int16_t fed_event_dump_freq, int16_t trigger_fed_id,
25  bool using_fed_key, bool unpack_bad_channels, bool mark_missing_feds, const uint32_t errorThreshold ) :
26  headerBytes_( appended_bytes ),
27  fedBufferDumpFreq_( fed_buffer_dump_freq ),
28  fedEventDumpFreq_( fed_event_dump_freq ),
29  triggerFedId_( trigger_fed_id ),
30  useFedKey_( using_fed_key ),
31  unpackBadChannels_( unpack_bad_channels ),
32  markMissingFeds_( mark_missing_feds ),
33  event_(0),
34  once_(true),
35  first_(true),
36  useDaqRegister_(false),
37  quiet_(true),
38  extractCm_(false),
39  doFullCorruptBufferChecks_(false),
40  doAPVEmulatorCheck_(true),
41  errorThreshold_(errorThreshold),
42  warnings_(sistrip::mlRawToDigi_, "[sistrip::RawToDigiUnpacker::createDigis]", edm::isDebugEnabled())
43  {
44  if ( edm::isDebugEnabled() ) {
45  LogTrace("SiStripRawToDigi")
46  << "[sistrip::RawToDigiUnpacker::"<<__func__<<"]"
47  <<" Constructing object...";
48  }
49  if (unpackBadChannels_) {
50  edm::LogWarning("SiStripRawToDigi") << "Warning: Unpacking of bad channels enabled. Only enable this if you know what you are doing. " << std::endl;
51  }
52  }
53 
55  if ( edm::isDebugEnabled() ) {
56  LogTrace("SiStripRawToDigi")
57  << "[sistrip::RawToDigiUnpacker::"<<__func__<<"]"
58  << " Destructing object...";
59  }
60  }
61 
62 
63  namespace {
64 
65  edm::RunningAverage localRA(10000);
66 
67  }
68 
69  void RawToDigiUnpacker::createDigis( const SiStripFedCabling& cabling, const FEDRawDataCollection& buffers, SiStripEventSummary& summary, RawDigis& scope_mode, RawDigis& virgin_raw, RawDigis& proc_raw, Digis& zero_suppr, DetIdCollection& detids, RawDigis& cm_values ) {
70 
71  // Clear done at the end
72  assert(zs_work_digis_.empty());
73  zs_work_digis_.reserve(localRA.upper());
74  // Reserve space in bad module list
75  detids.reserve(100);
76 
77  // Check if FEDs found in cabling map and event data
78  if ( cabling.fedIds().empty() ) {
79  warnings_.add("No FEDs found in cabling map!");
80  if ( edm::isDebugEnabled() ) {
81  // Check which FED ids have non-zero size buffers
82  std::vector<uint16_t> feds;
83  for ( uint16_t ifed = FEDNumbering::MINSiStripFEDID; ifed < FEDNumbering::MAXSiStripFEDID; ifed++ ) {
84  if ( ifed != triggerFedId_ &&
85  buffers.FEDData( static_cast<int>(ifed) ).size() ) {
86  feds.push_back(ifed);
87  }
88  }
89  LogTrace("SiStripRawToDigi")
90  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
91  << " Found "
92  << feds.size()
93  << " FED buffers with non-zero size!";
94  }
95  }
96 
97  // Flag for EventSummary update using DAQ register
98  bool first_fed = true;
99 
100  // Retrieve FED ids from cabling map and iterate through
101  std::vector<uint16_t>::const_iterator ifed = cabling.fedIds().begin();
102  for ( ; ifed != cabling.fedIds().end(); ifed++ ) {
103 
104  // ignore trigger FED
105  if ( *ifed == triggerFedId_ ) { continue; }
106 
107  // Retrieve FED raw data for given FED
108  const FEDRawData& input = buffers.FEDData( static_cast<int>(*ifed) );
109 
110  // Some debug on FED buffer size
111  if ( edm::isDebugEnabled() ) {
112  if ( first_ && input.data() ) {
113  std::stringstream ss;
114  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
115  << " Found FED id "
116  << std::setw(4) << std::setfill(' ') << *ifed
117  << " in FEDRawDataCollection"
118  << " with non-zero pointer 0x"
119  << std::hex
120  << std::setw(8) << std::setfill('0')
121  << reinterpret_cast<uint32_t*>( const_cast<uint8_t*>(input.data()))
122  << std::dec
123  << " and size "
124  << std::setw(5) << std::setfill(' ') << input.size()
125  << " chars";
126  LogTrace("SiStripRawToDigi") << ss.str();
127  }
128  }
129 
130  // Dump of FEDRawData to stdout
131  if ( edm::isDebugEnabled() ) {
133  std::stringstream ss;
134  dumpRawData( *ifed, input, ss );
136  }
137  }
138 
139  // get the cabling connections for this FED
140  auto conns = cabling.fedConnections(*ifed);
141 
142  // Check on FEDRawData pointer
143  if ( !input.data() ) {
144  warnings_.add("NULL pointer to FEDRawData for FED", (boost::format("id %1%") % *ifed).str());
145  // Mark FED modules as bad
146  detids.reserve(detids.size()+conns.size());
147  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
148  for ( ; iconn != conns.end(); iconn++ ) {
149  if ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) continue;
150  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
151  }
152  continue;
153  }
154 
155  // Check on FEDRawData size
156  if ( !input.size() ) {
157  warnings_.add("FEDRawData has zero size for FED", (boost::format("id %1%") % *ifed).str());
158  // Mark FED modules as bad
159  detids.reserve(detids.size()+conns.size());
160  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
161  for ( ; iconn != conns.end(); iconn++ ) {
162  if ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) continue;
163  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
164  }
165  continue;
166  }
167 
168  // construct FEDBuffer
169  std::unique_ptr<sistrip::FEDBuffer> buffer;
170  try {
171  buffer.reset(new sistrip::FEDBuffer(input.data(),input.size()));
172  buffer->setLegacyMode(legacy_);
173  if (!buffer->doChecks(true)) {
174  if (!unpackBadChannels_ || !buffer->checkNoFEOverflows() )
175  throw cms::Exception("FEDBuffer") << "FED Buffer check fails for FED ID " << *ifed << ".";
176  }
177  if (doFullCorruptBufferChecks_ && !buffer->doCorruptBufferChecks()) {
178  throw cms::Exception("FEDBuffer") << "FED corrupt buffer check fails for FED ID " << *ifed << ".";
179  }
180  }
181  catch (const cms::Exception& e) {
182  warnings_.add("Exception caught when creating FEDBuffer object for FED", (boost::format("id %1%: %2%") % *ifed % e.what()).str());
183  // FED buffer is bad and should not be unpacked. Skip this FED and mark all modules as bad.
184  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
185  for ( ; iconn != conns.end(); iconn++ ) {
186  if ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) continue;
187  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
188  }
189  continue;
190  }
191 
192  // Check if EventSummary ("trigger FED info") needs updating
193  if ( first_fed && useDaqRegister_ ) { updateEventSummary( *buffer, summary ); first_fed = false; }
194 
195  // Check to see if EventSummary info is set
196  if ( !quiet_ && !summary.isSet() ) {
197  warnings_.add("EventSummary is not set correctly! Missing information from both \"trigger FED\" and \"DAQ registers\"!");
198  }
199 
200  // Check to see if event is to be analyzed according to EventSummary
201  if ( !summary.valid() ) {
202  if ( edm::isDebugEnabled() ) {
203  LogTrace("SiStripRawToDigi")
204  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
205  << " EventSummary is not valid: skipping...";
206  }
207  continue;
208  }
209 
211  sistrip::FEDReadoutMode mode = buffer->readoutMode();
212  sistrip::FEDLegacyReadoutMode lmode = (legacy_) ? buffer->legacyReadoutMode() : sistrip::READOUT_MODE_LEGACY_INVALID;
213 
214  // Retrive run type
215  sistrip::RunType runType_ = summary.runType();
216  if( runType_ == sistrip::APV_LATENCY || runType_ == sistrip::FINE_DELAY ) { useFedKey_ = false; }
217 
218  // Dump of FED buffer
219  if ( edm::isDebugEnabled() ) {
221  std::stringstream ss;
222  buffer->dump( ss );
224  }
225  }
226 
227  // Iterate through FED channels, extract payload and create Digis
228  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
229  for ( ; iconn != conns.end(); iconn++ ) {
230 
232  uint16_t chan = iconn->fedCh();
233 
234  // Check if fed connection is valid
235  if ( !iconn->isConnected() ) { continue; }
236 
237  // Check DetId is valid (if to be used as key)
238  if ( !useFedKey_ && ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) ) { continue; }
239 
240  // Check FED channel
241  if (!buffer->channelGood(iconn->fedCh(),doAPVEmulatorCheck_)) {
242  if (!unpackBadChannels_ || !(buffer->fePresent(iconn->fedCh()/FEDCH_PER_FEUNIT) && buffer->feEnabled(iconn->fedCh()/FEDCH_PER_FEUNIT)) ) {
243  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
244  continue;
245  }
246  }
247 
248  // Determine whether FED key is inferred from cabling or channel loop
249  uint32_t fed_key = ( summary.runType() == sistrip::FED_CABLING ) ? ( ( *ifed & sistrip::invalid_ ) << 16 ) | ( chan & sistrip::invalid_ ) : ( ( iconn->fedId() & sistrip::invalid_ ) << 16 ) | ( iconn->fedCh() & sistrip::invalid_ );
250 
251  // Determine whether DetId or FED key should be used to index digi containers
252  uint32_t key = ( useFedKey_ || (!legacy_ && mode == sistrip::READOUT_MODE_SCOPE) || (legacy_ && lmode == sistrip::READOUT_MODE_LEGACY_SCOPE) ) ? fed_key : iconn->detId();
253 
254  // Determine APV std::pair number (needed only when using DetId)
255  uint16_t ipair = ( useFedKey_ || (!legacy_ && mode == sistrip::READOUT_MODE_SCOPE) || (legacy_ && lmode == sistrip::READOUT_MODE_LEGACY_SCOPE) ) ? 0 : iconn->apvPairNumber();
256 
259 
260  Registry regItem(key, 0, zs_work_digis_.size(), 0);
261 
262  try {
265  const uint8_t packet_code = buffer->packetCode(legacy_, iconn->fedCh());
266  switch (packet_code) {
269  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc())); unpacker++;}
270  break; }
273  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc())); unpacker++;}
274  break; }
277  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc()<<2)); unpacker++;}
278  break; }
281  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc()<<1)); unpacker++;}
282  break; }
283  default: {
284  warnings_.add((boost::format("Invalid packet code %1$#x for zero-suppressed data") % uint16_t(buffer->packetCode(legacy_, iconn->fedCh()))).str(), (boost::format("FED %1% channel %2%") % *ifed % iconn->fedCh()).str());
285  if ( packet_code == 0 ) {
286  // workaround for a pre-2015 bug in the packer: assume default ZS packing
288  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc())); unpacker++;}
289  }
290  }
291  }
292  } catch (const cms::Exception& e) {
293  warnings_.add("Clusters are not ordered", (boost::format("FED %1% channel %2% : %3%") % *ifed % iconn->fedCh() % e.what()).str());
294  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
295  continue;
296  }
297 
298  regItem.length = zs_work_digis_.size() - regItem.index;
299  if (regItem.length > 0) {
300  regItem.first = zs_work_digis_[regItem.index].strip();
301  zs_work_registry_.push_back(regItem);
302  }
303 
304 
305  // Common mode values
306  if ( extractCm_ ) {
307  try {
308  Registry regItem2( key, 2*ipair, cm_work_digis_.size(), 2 );
309  cm_work_digis_.push_back( SiStripRawDigi( buffer->channel(iconn->fedCh()).cmMedian(0) ) );
310  cm_work_digis_.push_back( SiStripRawDigi( buffer->channel(iconn->fedCh()).cmMedian(1) ) );
311  cm_work_registry_.push_back( regItem2 );
312  } catch (const cms::Exception& e) {
313  warnings_.add("Problem extracting common modes", (boost::format("FED %1% channel %2%:\n %3%") % *ifed % iconn->fedCh() % e.what()).str());
314  }
315  }
316 
317  }
318 
320 
321  Registry regItem(key, 0, zs_work_digis_.size(), 0);
322 
323  try {
326 
328  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc()));unpacker++;}
329  } catch (const cms::Exception& e) {
330  warnings_.add("Clusters are not ordered", (boost::format("FED %1% channel %2%: %3%") % *ifed % iconn->fedCh() % e.what()).str());
331  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
332  continue;
333  }
334 
335  regItem.length = zs_work_digis_.size() - regItem.index;
336  if (regItem.length > 0) {
337  regItem.first = zs_work_digis_[regItem.index].strip();
338  zs_work_registry_.push_back(regItem);
339  }
340 
341 
342  }
343 
344  else if ((!legacy_ &&
349 
350  Registry regItem(key, 0, zs_work_digis_.size(), 0);
351 
352  size_t bits_shift = 0;
355 
356  try {
359 
361  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc()<<bits_shift));unpacker++;}
362  } catch (const cms::Exception& e) {
363  warnings_.add("Clusters are not ordered", (boost::format("FED %1% channel %2%: %3%") % *ifed % iconn->fedCh() % e.what()).str());
364  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
365  continue;
366  }
367 
368  regItem.length = zs_work_digis_.size() - regItem.index;
369  if (regItem.length > 0) {
370  regItem.first = zs_work_digis_[regItem.index].strip();
371  zs_work_registry_.push_back(regItem);
372  }
373 
374  }
375 
376  else if ((!legacy_ && mode == sistrip::READOUT_MODE_PREMIX_RAW)
378  ) {
379 
380  Registry regItem(key, 0, zs_work_digis_.size(), 0);
381 
382  try {
383 
386 
388  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adcPreMix()));unpacker++;}
389  } catch (const cms::Exception& e) {
390  warnings_.add("Clusters are not ordered", (boost::format("FED %1% channel %2%: %3%") % *ifed % iconn->fedCh() % e.what()).str());
391  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
392  continue;
393  }
394 
395  regItem.length = zs_work_digis_.size() - regItem.index;
396  if (regItem.length > 0) {
397  regItem.first = zs_work_digis_[regItem.index].strip();
398  zs_work_registry_.push_back(regItem);
399  }
400 
401 
402  }
403 
404  else if ((!legacy_ && mode == sistrip::READOUT_MODE_VIRGIN_RAW)
406  ) {
407 
408  std::vector<uint16_t> samples;
409 
412 
413  uint8_t packet_code = buffer->packetCode(legacy_);
414  if ( packet_code == PACKET_CODE_VIRGIN_RAW ) {
416  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
417  }
418  else {
419  if ( packet_code == PACKET_CODE_VIRGIN_RAW10 ) {
420  sistrip::FEDBSChannelUnpacker unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(iconn->fedCh()), 10);
421  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker.sampleNumber();unpacker++;}
422  }
423  else if ( packet_code == PACKET_CODE_VIRGIN_RAW8_BOTBOT ) {
424  sistrip::FEDBSChannelUnpacker unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(iconn->fedCh()), 8);
425  while (unpacker.hasData()) {samples.push_back(( unpacker.adc()<<2 ));unpacker++;}
426  }
427  else if ( packet_code == PACKET_CODE_VIRGIN_RAW8_TOPBOT ) {
428  sistrip::FEDBSChannelUnpacker unpacker = sistrip::FEDBSChannelUnpacker::virginRawModeUnpacker(buffer->channel(iconn->fedCh()), 8);
429  while (unpacker.hasData()) {samples.push_back(( unpacker.adc()<<1 ));unpacker++;}
430  }
431  }
432  if ( !samples.empty() ) {
433  Registry regItem(key, 256*ipair, virgin_work_digis_.size(), samples.size());
434  uint16_t physical;
435  uint16_t readout;
436  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
437  physical = i%128;
438  readoutOrder( physical, readout ); // convert index from physical to readout order
439  (i/128) ? readout=readout*2+1 : readout=readout*2; // un-multiplex data
440  virgin_work_digis_.push_back( SiStripRawDigi( samples[readout] ) );
441  }
442  virgin_work_registry_.push_back( regItem );
443  }
444  }
445 
446  else if ((!legacy_ && mode == sistrip::READOUT_MODE_PROC_RAW)
448  ) {
449 
450  std::vector<uint16_t> samples;
451 
454 
456  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
457 
458  if ( !samples.empty() ) {
459  Registry regItem(key, 256*ipair, proc_work_digis_.size(), samples.size());
460  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
461  proc_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
462  }
463  proc_work_registry_.push_back( regItem );
464  }
465  }
466 
467  else if ((!legacy_ && mode == sistrip::READOUT_MODE_SCOPE)
469  ) {
470 
471  std::vector<uint16_t> samples;
472 
474  sistrip::FEDRawChannelUnpacker unpacker = sistrip::FEDRawChannelUnpacker::scopeModeUnpacker(buffer->channel(iconn->fedCh()));
475 
477  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
478 
479  if ( !samples.empty() ) {
480  Registry regItem(key, 0, scope_work_digis_.size(), samples.size());
481  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
482  scope_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
483  }
484  scope_work_registry_.push_back( regItem );
485  }
486  }
487 
488  else { // Unknown readout mode! => assume scope mode
489 
490  warnings_.add((boost::format("Unknown FED readout mode (%1%)! Assuming SCOPE MODE...") % mode).str());
491 
492  std::vector<uint16_t> samples;
493 
495  sistrip::FEDRawChannelUnpacker unpacker = sistrip::FEDRawChannelUnpacker::scopeModeUnpacker(buffer->channel(iconn->fedCh()));
496 
498  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
499 
500  if ( !samples.empty() ) {
501  Registry regItem(key, 0, scope_work_digis_.size(), samples.size());
502  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
503  scope_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
504  }
505  scope_work_registry_.push_back( regItem );
506 
507  if ( edm::isDebugEnabled() ) {
508  std::stringstream ss;
509  ss << "Extracted " << samples.size()
510  << " SCOPE MODE digis (samples[0] = "
511  << samples[0]
512  << ") from FED id/ch "
513  << iconn->fedId()
514  << "/"
515  << iconn->fedCh();
516  LogTrace("SiStripRawToDigi") << ss.str();
517  }
518  } else {
519  warnings_.add("No SM digis found!");
520  }
521  }
522  } // channel loop
523  } // fed loop
524 
525  // bad channels warning
526  unsigned int detIdsSize = detids.size();
527  if ( edm::isDebugEnabled() && detIdsSize ) {
528  std::ostringstream ss;
529  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
530  << " Problems were found in data and " << detIdsSize << " channels could not be unpacked. "
531  << "See output of FED Hardware monitoring for more information. ";
533  }
534  if( (errorThreshold_ != 0) && (detIdsSize > errorThreshold_) ) {
535  edm::LogError("TooManyErrors") << "Total number of errors = " << detIdsSize;
536  }
537 
538  // update DetSetVectors
539  update(scope_mode, virgin_raw, proc_raw, zero_suppr, cm_values);
540 
541  // increment event counter
542  event_++;
543 
544  // no longer first event!
545  if ( first_ ) { first_ = false; }
546 
547  // final cleanup, just in case
549  }
550 
551  void RawToDigiUnpacker::update( RawDigis& scope_mode, RawDigis& virgin_raw, RawDigis& proc_raw, Digis& zero_suppr, RawDigis& common_mode ) {
552 
553  if ( ! zs_work_registry_.empty() ) {
554  std::sort( zs_work_registry_.begin(), zs_work_registry_.end() );
555  std::vector< edm::DetSet<SiStripDigi> > sorted_and_merged;
556  sorted_and_merged.reserve( std::min(zs_work_registry_.size(), size_t(17000)) );
557 
558  bool errorInData = false;
559  std::vector<Registry>::iterator it = zs_work_registry_.begin(), it2 = it+1, end = zs_work_registry_.end();
560  while (it < end) {
561  sorted_and_merged.push_back( edm::DetSet<SiStripDigi>(it->detid) );
562  std::vector<SiStripDigi> & digis = sorted_and_merged.back().data;
563  // first count how many digis we have
564  size_t len = it->length;
565  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) { len += it2->length; }
566  // reserve memory
567  digis.reserve(len);
568  // push them in
569  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
570  digis.insert( digis.end(), & zs_work_digis_[it2->index], & zs_work_digis_[it2->index + it2->length] );
571  }
572  it = it2;
573  }
574 
575  // check sorting
576  if (!__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() )) {
577  // this is an error in the code: i DID sort it already!
578  throw cms::Exception("Bug Found")
579  << "Container must be already sorted!\nat "
580  << __FILE__
581  << ", line "
582  << __LINE__
583  <<"\n";
584  }
585 
586  std::vector< edm::DetSet<SiStripDigi> >::iterator iii = sorted_and_merged.begin();
587  std::vector< edm::DetSet<SiStripDigi> >::iterator jjj = sorted_and_merged.end();
588  for ( ; iii != jjj; ++iii ) {
589  if ( ! __gnu_cxx::is_sorted( iii->begin(), iii->end() ) ) {
590  // this might be an error in the data, if the raws from one FED are not sorted
591  iii->clear();
592  errorInData = true;
593  }
594  }
595 
596  // output error
597  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n";
598 
599  // make output DetSetVector
600  edm::DetSetVector<SiStripDigi> zero_suppr_dsv( sorted_and_merged, true );
601  zero_suppr.swap( zero_suppr_dsv );
602  }
603 
604  // Populate final DetSetVector container with VR data
605  if ( !virgin_work_registry_.empty() ) {
606 
607  std::sort( virgin_work_registry_.begin(), virgin_work_registry_.end() );
608 
609  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
610  sorted_and_merged.reserve( std::min(virgin_work_registry_.size(), size_t(17000)) );
611 
612  bool errorInData = false;
613  std::vector<Registry>::iterator it = virgin_work_registry_.begin(), it2, end = virgin_work_registry_.end();
614  while (it < end) {
615  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
616  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
617 
618  bool isDetOk = true;
619  // first count how many digis we have
620  int maxFirstStrip = it->first;
621  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
622  // duplicated APV or data corruption. DO NOT 'break' here!
623  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
624  maxFirstStrip = it2->first;
625  }
626  if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
627 
628  // make room for 256 * (max_apv_pair + 1) Raw Digis
629  digis.resize(maxFirstStrip + 256);
630  // push them in
631  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
632  // data corruption. DO NOT 'break' here
633  if (it->length != 256) { isDetOk = false; continue; }
634  std::copy( & virgin_work_digis_[it2->index], & virgin_work_digis_[it2->index + it2->length], & digis[it2->first] );
635  }
636  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
637  it = it2;
638  }
639 
640  // output error
641  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n";
642 
643  // check sorting
644  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
645  // this is an error in the code: i DID sort it already!
646  throw cms::Exception("Bug Found")
647  << "Container must be already sorted!\nat "
648  << __FILE__
649  << ", line "
650  << __LINE__
651  <<"\n";
652  }
653 
654  // make output DetSetVector
655  edm::DetSetVector<SiStripRawDigi> virgin_raw_dsv( sorted_and_merged, true );
656  virgin_raw.swap( virgin_raw_dsv );
657  }
658 
659  // Populate final DetSetVector container with VR data
660  if ( !proc_work_registry_.empty() ) {
661  std::sort( proc_work_registry_.begin(), proc_work_registry_.end() );
662 
663  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
664  sorted_and_merged.reserve( std::min(proc_work_registry_.size(), size_t(17000)) );
665 
666  bool errorInData = false;
667  std::vector<Registry>::iterator it = proc_work_registry_.begin(), it2, end = proc_work_registry_.end();
668  while (it < end) {
669  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
670  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
671 
672  bool isDetOk = true;
673  // first count how many digis we have
674  int maxFirstStrip = it->first;
675  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
676  // duplicated APV or data corruption. DO NOT 'break' here!
677  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
678  maxFirstStrip = it2->first;
679  }
680  // skip whole det
681  if (!isDetOk) { errorInData = true; it = it2; continue; }
682 
683  // make room for 256 * (max_apv_pair + 1) Raw Digis
684  digis.resize(maxFirstStrip + 256);
685  // push them in
686  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
687  // data corruption. DO NOT 'break' here
688  if (it->length != 256) { isDetOk = false; continue; }
689  std::copy( & proc_work_digis_[it2->index], & proc_work_digis_[it2->index + it2->length], & digis[it2->first] );
690  }
691  // skip whole det
692  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; }
693  it = it2;
694  }
695 
696  // output error
697  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted proc raw data, and have been skipped in unpacking\n";
698 
699  // check sorting
700  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
701  // this is an error in the code: i DID sort it already!
702  throw cms::Exception("Bug Found")
703  << "Container must be already sorted!\nat "
704  << __FILE__
705  << ", line "
706  << __LINE__
707  <<"\n";
708  }
709 
710  // make output DetSetVector
711  edm::DetSetVector<SiStripRawDigi> proc_raw_dsv( sorted_and_merged, true );
712  proc_raw.swap( proc_raw_dsv );
713  }
714 
715  // Populate final DetSetVector container with SM data
716  if ( !scope_work_registry_.empty() ) {
717  std::sort( scope_work_registry_.begin(), scope_work_registry_.end() );
718 
719  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
720  sorted_and_merged.reserve( scope_work_registry_.size() );
721 
722  bool errorInData = false;
723  std::vector<Registry>::iterator it, end;
724  for (it = scope_work_registry_.begin(), end = scope_work_registry_.end() ; it != end; ++it) {
725  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
726  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
727  digis.insert( digis.end(), & scope_work_digis_[it->index], & scope_work_digis_[it->index + it->length] );
728 
729  if ( (it +1 != end) && (it->detid == (it+1)->detid) ) {
730  errorInData = true;
731  // let's skip *all* the detsets for that key, as we don't know which is the correct one!
732  do { ++it; } while ( ( it+1 != end) && (it->detid == (it+1)->detid) );
733  }
734  }
735 
736  // output error
737  if (errorInData) edm::LogWarning("CorruptData") << "Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n";
738 
739  // check sorting
740  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
741  // this is an error in the code: i DID sort it already!
742  throw cms::Exception("Bug Found")
743  << "Container must be already sorted!\nat "
744  << __FILE__
745  << ", line "
746  << __LINE__
747  <<"\n";
748  }
749 
750  // make output DetSetVector
751  edm::DetSetVector<SiStripRawDigi> scope_mode_dsv( sorted_and_merged, true );
752  scope_mode.swap( scope_mode_dsv );
753  }
754 
755  // Populate DetSetVector with Common Mode values
756  if ( extractCm_ ) {
757 
758  // Populate final DetSetVector container with VR data
759  if ( !cm_work_registry_.empty() ) {
760 
761  std::sort( cm_work_registry_.begin(), cm_work_registry_.end() );
762 
763  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
764  sorted_and_merged.reserve( std::min(cm_work_registry_.size(), size_t(17000)) );
765 
766  bool errorInData = false;
767  std::vector<Registry>::iterator it = cm_work_registry_.begin(), it2, end = cm_work_registry_.end();
768  while (it < end) {
769  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
770  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
771 
772  bool isDetOk = true;
773  // first count how many digis we have
774  int maxFirstStrip = it->first;
775  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
776  // duplicated APV or data corruption. DO NOT 'break' here!
777  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
778  maxFirstStrip = it2->first;
779  }
780  if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
781 
782  // make room for 2 * (max_apv_pair + 1) Common mode values
783  digis.resize(maxFirstStrip + 2);
784  // push them in
785  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
786  // data corruption. DO NOT 'break' here
787  if (it->length != 2) { isDetOk = false; continue; }
788  std::copy( & cm_work_digis_[it2->index], & cm_work_digis_[it2->index + it2->length], & digis[it2->first] );
789  }
790  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
791  it = it2;
792  }
793 
794  // output error
795  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted common mode data, and have been skipped in unpacking\n";
796 
797  // check sorting
798  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
799  // this is an error in the code: i DID sort it already!
800  throw cms::Exception("Bug Found")
801  << "Container must be already sorted!\nat "
802  << __FILE__
803  << ", line "
804  << __LINE__
805  <<"\n";
806  }
807 
808  // make output DetSetVector
809  edm::DetSetVector<SiStripRawDigi> common_mode_dsv( sorted_and_merged, true );
810  common_mode.swap( common_mode_dsv );
811  }
812 
813  }
814 
815  }
816 
818  // Clear working areas and registries
819 
820  localRA.update(zs_work_digis_.size());
821  zs_work_registry_.clear(); zs_work_digis_.clear(); zs_work_digis_.shrink_to_fit(); assert(zs_work_digis_.capacity()==0);
822  virgin_work_registry_.clear(); virgin_work_digis_.clear();
823  proc_work_registry_.clear(); proc_work_digis_.clear();
824  scope_work_registry_.clear(); scope_work_digis_.clear();
825  cm_work_registry_.clear(); cm_work_digis_.clear();
826  }
827 
829 
830  // Pointer to data (recast as 32-bit words) and number of 32-bit words
831  uint32_t* data_u32 = nullptr;
832  uint32_t size_u32 = 0;
833 
834  // Search mode
835  if ( triggerFedId_ < 0 ) {
836 
837  uint16_t ifed = 0;
838  while ( triggerFedId_ < 0 &&
839  ifed < 1 + FEDNumbering::lastFEDId() ) {
840  const FEDRawData& trigger_fed = buffers.FEDData( ifed );
841  if ( trigger_fed.data() && trigger_fed.size() ) {
842  uint8_t* temp = const_cast<uint8_t*>( trigger_fed.data() );
843  data_u32 = reinterpret_cast<uint32_t*>( temp ) + FEDHeader::length/sizeof(uint32_t) + 1;
844  size_u32 = trigger_fed.size()/sizeof(uint32_t) - FEDHeader::length/sizeof(uint32_t) - 1;
845  const FEDTrailer fedTrailer( temp + trigger_fed.size() - FEDTrailer::length );
846  if ( fedTrailer.conscheck() == 0xDEADFACE ) {
847  triggerFedId_ = ifed;
848  if ( edm::isDebugEnabled() ) {
849  std::stringstream ss;
850  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
851  << " Search mode for 'trigger FED' activated!"
852  << " Found 'trigger FED' info with id " << triggerFedId_;
853  LogTrace("SiStripRawToDigi") << ss.str();
854  }
855  }
856  }
857  ifed++;
858  }
859  if ( triggerFedId_ < 0 ) {
860  triggerFedId_ = 0;
861  if ( edm::isDebugEnabled() ) {
862  std::stringstream ss;
863  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
864  << " Search mode for 'trigger FED' activated!"
865  << " 'Trigger FED' info not found!";
867  }
868  }
869  }
870 
871  // "Trigger FED" id given in .cfg file
872  else if ( triggerFedId_ > 0 ) {
873 
874  const FEDRawData& trigger_fed = buffers.FEDData( triggerFedId_ );
875  if ( trigger_fed.data() && trigger_fed.size() ) {
876  uint8_t* temp = const_cast<uint8_t*>( trigger_fed.data() );
877  data_u32 = reinterpret_cast<uint32_t*>( temp ) + FEDHeader::length/sizeof(uint32_t) + 1;
878  size_u32 = trigger_fed.size()/sizeof(uint32_t) - FEDHeader::length/sizeof(uint32_t) - 1;
879  const FEDTrailer fedTrailer( temp + trigger_fed.size() - FEDTrailer::length );
880  if ( fedTrailer.conscheck() != 0xDEADFACE ) {
881  if ( edm::isDebugEnabled() ) {
883  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
884  << " Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
885  << " Buffer appears not to contain 'trigger FED' data!";
886  }
887  triggerFedId_ = 0;
888  }
889  }
890 
891  } else {
892  triggerFedId_ = 0;
893  data_u32 = nullptr;
894  size_u32 = 0;
895  }
896 
897  // Populate summary object with commissioning information
898  if ( triggerFedId_ > 0 ) {
899 
900  // Some checks
901  if ( !data_u32 ) {
902  if ( edm::isDebugEnabled() ) {
903  std::stringstream ss;
904  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
905  << " NULL pointer to 'trigger FED' data";
907  }
908  return;
909  }
910  if ( size_u32 < sizeof(TFHeaderDescription)/sizeof(uint32_t) ) {
911  if ( edm::isDebugEnabled() ) {
912  std::stringstream ss;
913  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
914  << " Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
916  }
917  return;
918  }
919 
920  // Write event-specific data to event
922  summary.event( static_cast<uint32_t>( header->getFedEventNumber()) );
923  summary.bx( static_cast<uint32_t>( header->getBunchCrossing()) );
924 
925  // Write commissioning information to event
926  uint32_t hsize = sizeof(TFHeaderDescription)/sizeof(uint32_t);
927  uint32_t* head = &data_u32[hsize];
928  summary.commissioningInfo( head, event );
929  summary.triggerFed( triggerFedId_ );
930 
931  }
932 
933  // Some debug
934  if ( summary.isSet() && once_ ) {
935  if ( edm::isDebugEnabled() ) {
936  std::stringstream ss;
937  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
938  << " EventSummary built from \"trigger FED\":"
939  << std::endl << summary;
940  LogTrace("SiStripRawToDigi") << ss.str();
941  }
942  once_ = false;
943  }
944  }
945 
947 
948  // Check size of input buffer
949  if ( input.size() < 24 ) {
950  output.resize( input.size() ); // Return UNadjusted buffer start position and size
951  memcpy( output.data(), input.data(), input.size() );
952  if ( edm::isDebugEnabled() ) {
953  std::stringstream ss;
954  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "] "
955  << "Input FEDRawData with FED id " << fed_id
956  << " has size " << input.size();
958  }
959  return;
960  }
961 
962  // Iterator through buffer to find DAQ header
963  bool found = false;
964  uint16_t ichar = 0;
965  while ( ichar < input.size()-16 && !found ) {
966  uint16_t offset = headerBytes_ < 0 ? ichar : headerBytes_; // Negative value means use "search mode" to find DAQ header
967  uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + offset );
968  uint32_t* fed_trailer = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + input.size() - 8 );
969 
970  // see info on FED 32-bit swapping at end-of-file
971 
972  bool old_vme_header = ( input_u32[0] & 0xF0000000 ) == 0x50000000 && ( fed_trailer[0] & 0xF0000000 ) == 0xA0000000 && ( (fed_trailer[0] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
973 
974  bool old_slink_header = ( input_u32[1] & 0xF0000000 ) == 0x50000000 && ( fed_trailer[1] & 0xF0000000 ) == 0xA0000000 && ( (fed_trailer[1] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
975 
976  bool old_slink_payload = ( input_u32[3] & 0xFF000000 ) == 0xED000000;
977 
978  bool new_buffer_format = ( input_u32[2] & 0xFF000000 ) == 0xC5000000;
979 
980  if ( old_vme_header ) {
981 
982  // Found DAQ header at byte position 'offset'
983  found = true;
984  output.resize( input.size()-offset );
985  memcpy( output.data(), // target
986  input.data()+offset, // source
987  input.size()-offset ); // nbytes
988  if ( headerBytes_ < 0 ) {
989  if ( edm::isDebugEnabled() ) {
990  std::stringstream ss;
991  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
992  << " Buffer for FED id " << fed_id
993  << " has been found at byte position " << offset
994  << " with a size of " << input.size()-offset << " bytes."
995  << " Adjust the configurable 'AppendedBytes' to " << offset;
996  LogTrace("SiStripRawToDigi") << ss.str();
997  }
998  }
999 
1000  } else if ( old_slink_header ) {
1001 
1002  if ( old_slink_payload ) {
1003 
1004  // Found DAQ header (with MSB and LSB 32-bit words swapped) at byte position 'offset'
1005  found = true;
1006  output.resize( input.size()-offset );
1007  uint32_t* output_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( output.data() ) );
1008  uint16_t iter = offset;
1009  while ( iter < output.size() / sizeof(uint32_t) ) {
1010  output_u32[iter] = input_u32[iter+1];
1011  output_u32[iter+1] = input_u32[iter];
1012  iter+=2;
1013  }
1014  if ( headerBytes_ < 0 ) {
1015  if ( edm::isDebugEnabled() ) {
1016  std::stringstream ss;
1017  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1018  << " Buffer (with MSB and LSB 32-bit words swapped) for FED id " << fed_id
1019  << " has been found at byte position " << offset
1020  << " with a size of " << output.size() << " bytes."
1021  << " Adjust the configurable 'AppendedBytes' to " << offset;
1022  LogTrace("SiStripRawToDigi") << ss.str();
1023  }
1024  }
1025 
1026  } else if ( new_buffer_format ) {
1027 
1028  // Found DAQ header at byte position 'offset'
1029  found = true;
1030  output.resize( input.size()-offset );
1031  memcpy( output.data(), // target
1032  input.data()+offset, // source
1033  input.size()-offset ); // nbytes
1034  if ( headerBytes_ < 0 ) {
1035  if ( edm::isDebugEnabled() ) {
1036  std::stringstream ss;
1037  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1038  << " Buffer for FED id " << fed_id
1039  << " has been found at byte position " << offset
1040  << " with a size of " << input.size()-offset << " bytes."
1041  << " Adjust the configurable 'AppendedBytes' to " << offset;
1042  LogTrace("SiStripRawToDigi") << ss.str();
1043  }
1044  }
1045 
1046  } else { headerBytes_ < 0 ? found = false : found = true; }
1047  } else { headerBytes_ < 0 ? found = false : found = true; }
1048  ichar++;
1049  }
1050 
1051  // Check size of output buffer
1052  if ( output.size() == 0 ) {
1053 
1054  // Did not find DAQ header after search => return buffer with null size
1055  output.resize( 0 ); //@@ NULL SIZE
1056  memcpy( output.data(), input.data(), 0 ); //@@ NULL SIZE
1057  if ( edm::isDebugEnabled() ) {
1058  std::stringstream ss;
1059  if ( headerBytes_ < 0 ) {
1060  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1061  << " DAQ header not found within buffer for FED id: " << fed_id;
1062  } else {
1063  uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) );
1064  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1065  << " DAQ header not found at expected location for FED id: " << fed_id << std::endl
1066  << " First 64-bit word of buffer is 0x"
1067  << std::hex
1068  << std::setfill('0') << std::setw(8) << input_u32[0]
1069  << std::setfill('0') << std::setw(8) << input_u32[1]
1070  << std::dec << std::endl
1071  << " Adjust 'AppendedBytes' configurable to '-1' to activate 'search mode'";
1072  }
1074  }
1075 
1076  } else if ( output.size() < 24 ) { // Found DAQ header after search, but too few words
1077 
1078  if ( edm::isDebugEnabled() ) {
1079  std::stringstream ss;
1080  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1081  << " Unexpected buffer size! FEDRawData with FED id " << fed_id
1082  << " has size " << output.size();
1084  }
1085  }
1086  }
1087 
1089 
1090  summary.event(fed.daqHeader().l1ID());
1091  summary.bx(fed.daqHeader().bxID());
1092 
1093  // Retrieve contents of DAQ registers
1094 
1095  sistrip::FEDDAQEventType readout_mode = fed.daqEventType();
1096  uint32_t daq1 = sistrip::invalid32_;
1097  uint32_t daq2 = sistrip::invalid32_;
1098 
1100  const sistrip::FEDFullDebugHeader* header = nullptr;
1101  header = dynamic_cast<const sistrip::FEDFullDebugHeader*>(fed.feHeader());
1102  daq1 = static_cast<uint32_t>( header->daqRegister() );
1103  daq2 = static_cast<uint32_t>( header->daqRegister2() );
1104  }
1105 
1106 
1107  // If FED DAQ registers contain info, update (and possibly overwrite) EventSummary
1108  if ( daq1 != 0 && daq1 != sistrip::invalid32_ ) {
1109 
1110  summary.triggerFed( triggerFedId_ );
1111  summary.fedReadoutMode( readout_mode );
1112  summary.commissioningInfo( daq1, daq2 );
1113 
1114  if ( summary.isSet() && once_ ) {
1115  if ( edm::isDebugEnabled() ) {
1116  std::stringstream ss;
1117  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1118  << " EventSummary built from FED DAQ registers:"
1119  << std::endl << summary;
1120  LogTrace("SiStripRawToDigi") << ss.str();
1121  }
1122  once_ = false;
1123  }
1124  }
1125  }
1126 
1127  void RawToDigiUnpacker::dumpRawData( uint16_t fed_id, const FEDRawData& buffer, std::stringstream& ss ) {
1128 
1129  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1130  << " Dump of buffer for FED id " << fed_id << std::endl
1131  << " Buffer contains " << buffer.size()
1132  << " bytes (NB: payload is byte-swapped)" << std::endl;
1133 
1134  if ( false ) {
1135  uint32_t* buffer_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( buffer.data() ) );
1136  unsigned int empty = 0;
1137 
1138  ss << "Byte-> 4 5 6 7 0 1 2 3\n";
1139  for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
1140  unsigned int temp0 = buffer_u32[i*2] & sistrip::invalid32_;
1141  unsigned int temp1 = buffer_u32[i*2+1] & sistrip::invalid32_;
1142  if ( !temp0 && !temp1 ) { empty++; }
1143  else {
1144  if ( empty ) {
1145  ss << " [ empty words ]" << std::endl;
1146  empty = 0;
1147  }
1148  ss << std::dec
1149  << std::setfill(' ') << std::setw(6) << i*8 << ": "
1150  << std::hex
1151  << std::setfill('0') << std::setw(8) << temp0
1152  << std::setfill('0') << std::setw(8) << temp1
1153  << std::dec
1154  << std::endl;
1155  }
1156  }
1157 
1158  } else {
1159 
1160  ss << " Byte | <---- Byte order ----< | Byte" << std::endl;
1161  ss << " cntr | 7 6 5 4 3 2 1 0 | cntr" << std::endl;
1162  for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
1163  //if ( i>=20 && ((i+4)<(buffer.size()/8)) ) { continue; }
1164  uint16_t tmp0 = buffer.data()[i*8+0] & 0xFF;
1165  uint16_t tmp1 = buffer.data()[i*8+1] & 0xFF;
1166  uint16_t tmp2 = buffer.data()[i*8+2] & 0xFF;
1167  uint16_t tmp3 = buffer.data()[i*8+3] & 0xFF;
1168  uint16_t tmp4 = buffer.data()[i*8+4] & 0xFF;
1169  uint16_t tmp5 = buffer.data()[i*8+5] & 0xFF;
1170  uint16_t tmp6 = buffer.data()[i*8+6] & 0xFF;
1171  uint16_t tmp7 = buffer.data()[i*8+7] & 0xFF;
1172 // if ( !tmp0 && !tmp1 && !tmp2 && !tmp3 &&
1173 // !tmp4 && !tmp5 && !tmp6 && !tmp7 ) { empty++; }
1174 // else {
1175 // if ( empty ) {
1176 // ss << " [.."
1177 // << std::dec << std::setfill('.') << std::setw(4) << empty
1178 // << " null words....]" << std::endl;
1179 // empty = 0;
1180 // }
1181  ss << std::dec
1182  << std::setfill(' ') << std::setw(6) << i*8+7 << " : "
1183  << std::hex
1184  << std::setfill('0') << std::setw(2) << tmp7 << " "
1185  << std::setfill('0') << std::setw(2) << tmp6 << " "
1186  << std::setfill('0') << std::setw(2) << tmp5 << " "
1187  << std::setfill('0') << std::setw(2) << tmp4 << " "
1188  << std::setfill('0') << std::setw(2) << tmp3 << " "
1189  << std::setfill('0') << std::setw(2) << tmp2 << " "
1190  << std::setfill('0') << std::setw(2) << tmp1 << " "
1191  << std::setfill('0') << std::setw(2) << tmp0
1192  << std::dec
1193  << " :" << std::setfill(' ') << std::setw(6) << i*8
1194  << std::endl;
1195 // }
1196  }
1197 
1198  }
1199  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1200  << " End of FED buffer";
1201  }
1202 
1204 
1205  method_name = "sistrip::RawToDigiUnpacker::" + method_name;
1206  try {
1207  throw; // rethrow caught exception to be dealt with below
1208  }
1209  catch ( const cms::Exception& e ) {
1210  //throw e; // rethrow cms::Exception to be caught by framework
1211  }
1212  catch ( const std::exception& e ) {
1213  if ( edm::isDebugEnabled() ) {
1214  std::stringstream ss;
1215  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1216  << " Caught std::exception!" << std::endl;
1217  if ( !extra_info.empty() ) {
1218  ss << " Information: " << extra_info << std::endl;
1219  }
1220  ss << " Caught std::exception in ["
1221  << method_name << "] with message:" << std::endl
1222  << e.what();
1224  }
1225  //throw cms::Exception(sistrip::mlRawToDigi_) << ss.str();
1226  }
1227  catch (...) {
1228  if ( edm::isDebugEnabled() ) {
1229  std::stringstream ss;
1230  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1231  << " Caught unknown exception!" << std::endl;
1232  if ( !extra_info.empty() ) {
1233  ss << " Information: " << extra_info << std::endl;
1234  }
1235  ss << "Caught unknown exception in ["
1236  << method_name << "]" << std::endl;
1238  }
1239  //throw cms::Exception(sistrip::mlRawToDigi_) << ss.str();
1240  }
1241  }
1242 
1243 }
1244 
1245 /*
1246 
1247 Some info on FED buffer 32-bit word swapping.
1248 
1249 Table below indicates if data are swapped relative to the "old"
1250 VME format (as originally expected by the Fed9UEvent class).
1251 
1252 -------------------------------------------
1253 | SWAPPED? | DATA FORMAT |
1254 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1255 | | VME | SLINK | VME | SLINK |
1256 -------------------------------------------
1257 | DAQ HEADER | N | Y | Y | Y |
1258 | TRK HEADER | N | Y | N | N |
1259 | PAYLOAD | N | Y | N | N |
1260 | DAQ TRAILER | N | Y | Y | Y |
1261 -------------------------------------------
1262 
1263 So, in code, we check in code order of bytes in DAQ header/trailer only:
1264 -> if "old_vme_header", then old format read out via vme, so do nothing.
1265 -> else if "old_slink_header", then data may be wrapped, so check additionally the TRK header:
1266 ---> if "old_slink_payload", then old format read out via slink, so swap all data;
1267 ---> else if "new_buffer_format", then new format, handled internally by Fed9UEvent, so do nothing.
1268 
1269 Pattern matching to find DAQ and tracker headers, and DAQ trailer:
1270 DAQ header, 4 bits, in field |BOE_1| with value 0x5
1271 DAQ trailer, 4 bits, in field |EOE_1| with value 0xA
1272 TRK header, 8 bits, in field |Hdr format| with value 0xED or 0xC5
1273 
1274 -------------------------------------------------------------------------------------------
1275 | SWAPPED? | DATA FORMAT |
1276 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1277 | | VME | SLINK | VME | SLINK |
1278 -------------------------------------------------------------------------------------------
1279 | DAQ HEADER | ........5....... | 5............... | 5............... | 5............... |
1280 | TRK HEADER | ........ED...... | ED.............. | ........C5...... | ........C5...... |
1281 | PAYLOAD | ..........EA.... | ..EA............ | ..EA............ | ............EA.. |
1282 | DAQ TRAILER | ........A....... | A............... | A............... | A............... |
1283 -------------------------------------------------------------------------------------------
1284 
1285 */
void triggerFed(const FEDRawDataCollection &, SiStripEventSummary &, const uint32_t &event)
trigger info
static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel &channel)
size_type size() const
Definition: EDCollection.h:97
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_BOTBOT
bool isDebugEnabled()
void update(RawDigis &scope_mode, RawDigis &virgin_raw, RawDigis &proc_raw, Digis &zero_suppr, RawDigis &common_mode)
fill DetSetVectors using registries
std::vector< Registry > proc_work_registry_
void updateEventSummary(const sistrip::FEDBuffer &, SiStripEventSummary &)
sets the SiStripEventSummary -> not yet implemented for FEDBuffer class
static FEDZSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel &channel)
std::vector< SiStripDigi > zs_work_digis_
digi collections
std::vector< Registry > scope_work_registry_
void cleanupWorkVectors()
method to clear registries and digi collections
def copy(args, dbName)
static const uint32_t length
Definition: FEDTrailer.h:61
std::vector< Registry > zs_work_registry_
registries
static FEDZSChannelUnpacker preMixRawModeUnpacker(const FEDChannel &channel)
static const uint32_t invalid32_
Definition: Constants.h:15
void locateStartOfFedBuffer(const uint16_t &fed_id, const FEDRawData &input, FEDRawData &output)
Removes any data appended prior to FED buffer and reorders 32-bit words if swapped.
static const uint32_t length
Definition: FEDHeader.h:54
static FEDRawChannelUnpacker scopeModeUnpacker(const FEDChannel &channel)
static FEDRawChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel)
static FEDBSChannelUnpacker zeroSuppressedModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
static const char mlRawToDigi_[]
void push_back(T const &t)
Definition: EDCollection.h:67
char const * what() const override
Definition: Exception.cc:103
unsigned long getBunchCrossing()
static FEDBSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
static FEDBSChannelUnpacker virginRawModeUnpacker(const FEDChannel &channel, uint16_t num_bits)
const FEDFEHeader * feHeader() const
void swap(DetSetVector &other)
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
sistrip classes
FEDDAQEventType daqEventType() const
private class to register start and end index of digis in a collection
static std::string const input
Definition: EdmProvDump.cc:48
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED8_TOPBOT
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED10
const sistrip::RunType & runType() const
unsigned long getFedEventNumber()
std::vector< SiStripRawDigi > virgin_work_digis_
static const uint8_t PACKET_CODE_VIRGIN_RAW10
const uint32_t & bx() const
void readoutOrder(uint16_t &physical_order, uint16_t &readout_order)
order of strips
~RawToDigiUnpacker()
default constructor
static const uint8_t PACKET_CODE_ZERO_SUPPRESSED
const FEDRawData & FEDData(int fedid) const
retrieve data for fed
static void dumpRawData(uint16_t fed_id, const FEDRawData &, std::stringstream &)
dumps raw data to stdout (NB: payload is byte-swapped,headers/trailer are not).
void resize(size_t newsize)
Definition: FEDRawData.cc:32
void commissioningInfo(const uint32_t *const buffer, const uint32_t &event)
const uint32_t & event() const
FedsConstIterRange fedIds() const
FEDHeaderType headerType() const
std::vector< SiStripRawDigi > scope_work_digis_
#define end
Definition: vmac.h:39
format
Some error handling for the usage.
T min(T a, T b)
Definition: MathUtil.h:58
A Digi for the silicon strip detector, containing both strip and adc information, and suitable for st...
Definition: SiStripDigi.h:12
static const uint8_t PACKET_CODE_VIRGIN_RAW8_TOPBOT
std::vector< SiStripRawDigi > proc_work_digis_
#define LogTrace(id)
void handleException(std::string method_name, std::string extra_info="")
catches all possible exceptions and rethrows them as cms::Exceptions
void add(const std::string &message, const std::string &details="")
void reserve(size_type n)
Definition: EDCollection.h:111
std::vector< SiStripRawDigi > cm_work_digis_
static const uint8_t PACKET_CODE_VIRGIN_RAW8_BOTBOT
static FEDZSChannelUnpacker zeroSuppressedLiteModeUnpacker(const FEDChannel &channel)
static const uint16_t FEDCH_PER_FEUNIT
uint16_t triggerFed() const
static const uint16_t invalid_
Definition: Constants.h:16
ConnsConstIterRange fedConnections(uint16_t fed_id) const
chan
lumi = TPaveText(lowX+0.38, lowY+0.061, lowX+0.45, lowY+0.161, "NDC") lumi.SetBorderSize( 0 ) lumi...
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
const sistrip::FedReadoutMode & fedReadoutMode() const
HLT enums.
void event_()
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
void createDigis(const SiStripFedCabling &, const FEDRawDataCollection &, SiStripEventSummary &, RawDigis &scope_mode, RawDigis &virgin_raw, RawDigis &proc_raw, Digis &zero_suppr, DetIdCollection &, RawDigis &common_mode)
creates digis
std::vector< Registry > cm_work_registry_
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
#define str(s)
static constexpr int lastFEDId()
Definition: FEDNumbering.h:22
static const uint8_t PACKET_CODE_VIRGIN_RAW
std::vector< Registry > virgin_work_registry_
Definition: event.py:1
RawToDigiUnpacker()=delete
private default constructor