CMS 3D CMS Logo

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