CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
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  if (!buffer->doChecks()) {
184  if (!unpackBadChannels_ || !buffer->checkNoFEOverflows() )
185  throw cms::Exception("FEDBuffer") << "FED Buffer check fails for FED ID " << *ifed << ".";
186  }
187  if (doFullCorruptBufferChecks_ && !buffer->doCorruptBufferChecks()) {
188  throw cms::Exception("FEDBuffer") << "FED corrupt buffer check fails for FED ID " << *ifed << ".";
189  }
190  }
191  catch (const cms::Exception& e) {
192  if ( edm::isDebugEnabled() ) {
193  edm::LogWarning("sistrip::RawToDigiUnpacker") << "Exception caught when creating FEDBuffer object for FED " << *ifed << ": " << e.what();
194  }
195  // FED buffer is bad and should not be unpacked. Skip this FED and mark all modules as bad.
196  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
197  for ( ; iconn != conns.end(); iconn++ ) {
198  if ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) continue;
199  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
200  }
201  continue;
202  }
203 
204  // Check if EventSummary ("trigger FED info") needs updating
205  if ( first_fed && useDaqRegister_ ) { updateEventSummary( *buffer, summary ); first_fed = false; }
206 
207  // Check to see if EventSummary info is set
208  if ( edm::isDebugEnabled() ) {
209  if ( !quiet_ && !summary.isSet() ) {
210  std::stringstream ss;
211  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
212  << " EventSummary is not set correctly!"
213  << " Missing information from both \"trigger FED\" and \"DAQ registers\"!";
215  }
216  }
217 
218  // Check to see if event is to be analyzed according to EventSummary
219  if ( !summary.valid() ) {
220  if ( edm::isDebugEnabled() ) {
221  LogTrace("SiStripRawToDigi")
222  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
223  << " EventSummary is not valid: skipping...";
224  }
225  continue;
226  }
227 
229  sistrip::FEDReadoutMode mode = buffer->readoutMode();
230 
231  // Retrive run type
232  sistrip::RunType runType_ = summary.runType();
233  if( runType_ == sistrip::APV_LATENCY || runType_ == sistrip::FINE_DELAY ) { useFedKey_ = false; }
234 
235  // Dump of FED buffer
236  if ( edm::isDebugEnabled() ) {
238  std::stringstream ss;
239  buffer->dump( ss );
241  }
242  }
243 
244  // Iterate through FED channels, extract payload and create Digis
245  std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
246  for ( ; iconn != conns.end(); iconn++ ) {
247 
249  uint16_t chan = iconn->fedCh();
250 
251  // Check if fed connection is valid
252  if ( !iconn->isConnected() ) { continue; }
253 
254  // Check DetId is valid (if to be used as key)
255  if ( !useFedKey_ && ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) ) { continue; }
256 
257  // Check FED channel
258  if (!buffer->channelGood(iconn->fedCh(),doAPVEmulatorCheck_)) {
259  if (!unpackBadChannels_ || !(buffer->fePresent(iconn->fedCh()/FEDCH_PER_FEUNIT) && buffer->feEnabled(iconn->fedCh()/FEDCH_PER_FEUNIT)) ) {
260  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
261  continue;
262  }
263  }
264 
265  // Determine whether FED key is inferred from cabling or channel loop
266  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_ );
267 
268  // Determine whether DetId or FED key should be used to index digi containers
269  uint32_t key = ( useFedKey_ || mode == sistrip::READOUT_MODE_SCOPE ) ? fed_key : iconn->detId();
270 
271  // Determine APV std::pair number (needed only when using DetId)
272  uint16_t ipair = ( useFedKey_ || mode == sistrip::READOUT_MODE_SCOPE ) ? 0 : iconn->apvPairNumber();
273 
274 
276 
277  Registry regItem(key, 0, zs_work_digis_.size(), 0);
278 
279  try {
282 
284 
285  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc())); unpacker++;}
286  } catch (const cms::Exception& e) {
287  if ( edm::isDebugEnabled() ) {
289  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
290  << " Clusters are not ordered for FED "
291  << *ifed << " channel " << iconn->fedCh()
292  << ": " << e.what();
293  }
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  if ( edm::isDebugEnabled() ) {
315  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
316  << " Problem extracting common modes for FED id "
317  << *ifed << " and channel " << iconn->fedCh()
318  << ": " << std::endl << e.what();
319  }
320  }
321  }
322 
323  }
324 
325  else if (mode == sistrip::READOUT_MODE_ZERO_SUPPRESSED_LITE ) {
326 
327  Registry regItem(key, 0, zs_work_digis_.size(), 0);
328 
329  try {
332 
334  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adc()));unpacker++;}
335  } catch (const cms::Exception& e) {
336  if ( edm::isDebugEnabled() ) {
338  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
339  << " Clusters are not ordered for FED "
340  << *ifed << " channel " << iconn->fedCh()
341  << ": " << e.what();
342  }
343  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
344  continue;
345  }
346 
347  regItem.length = zs_work_digis_.size() - regItem.index;
348  if (regItem.length > 0) {
349  regItem.first = zs_work_digis_[regItem.index].strip();
350  zs_work_registry_.push_back(regItem);
351  }
352 
353 
354  }
355 
356  else if (mode == sistrip::READOUT_MODE_PREMIX_RAW ) {
357 
358  Registry regItem(key, 0, zs_work_digis_.size(), 0);
359 
360  try {
361 
364 
366  while (unpacker.hasData()) {zs_work_digis_.push_back(SiStripDigi(unpacker.sampleNumber()+ipair*256,unpacker.adcPreMix()));unpacker++;}
367  } catch (const cms::Exception& e) {
368  if ( edm::isDebugEnabled() ) {
370  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
371  << " Clusters are not ordered for FED "
372  << *ifed << " channel " << iconn->fedCh()
373  << ": " << e.what();
374  }
375  detids.push_back(iconn->detId()); //@@ Possible multiple entries (ok for Giovanni)
376  continue;
377  }
378 
379  regItem.length = zs_work_digis_.size() - regItem.index;
380  if (regItem.length > 0) {
381  regItem.first = zs_work_digis_[regItem.index].strip();
382  zs_work_registry_.push_back(regItem);
383  }
384 
385 
386  }
387 
388  else if ( mode == sistrip::READOUT_MODE_VIRGIN_RAW ) {
389 
390  std::vector<uint16_t> samples;
391 
394 
396  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
397 
398  if ( !samples.empty() ) {
399  Registry regItem(key, 256*ipair, virgin_work_digis_.size(), samples.size());
400  uint16_t physical;
401  uint16_t readout;
402  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
403  physical = i%128;
404  readoutOrder( physical, readout ); // convert index from physical to readout order
405  (i/128) ? readout=readout*2+1 : readout=readout*2; // un-multiplex data
406  virgin_work_digis_.push_back( SiStripRawDigi( samples[readout] ) );
407  }
408  virgin_work_registry_.push_back( regItem );
409  }
410  }
411 
412  else if ( mode == sistrip::READOUT_MODE_PROC_RAW ) {
413 
414  std::vector<uint16_t> samples;
415 
418 
420  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
421 
422  if ( !samples.empty() ) {
423  Registry regItem(key, 256*ipair, proc_work_digis_.size(), samples.size());
424  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
425  proc_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
426  }
427  proc_work_registry_.push_back( regItem );
428  }
429  }
430 
431  else if ( mode == sistrip::READOUT_MODE_SCOPE ) {
432 
433  std::vector<uint16_t> samples;
434 
436  sistrip::FEDRawChannelUnpacker unpacker = sistrip::FEDRawChannelUnpacker::scopeModeUnpacker(buffer->channel(iconn->fedCh()));
437 
439  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
440 
441  if ( !samples.empty() ) {
442  Registry regItem(key, 0, scope_work_digis_.size(), samples.size());
443  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
444  scope_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
445  }
446  scope_work_registry_.push_back( regItem );
447  }
448  }
449 
450  else { // Unknown readout mode! => assume scope mode
451 
452  if ( edm::isDebugEnabled() ) {
453  std::stringstream ss;
454  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
455  << " Unknown FED readout mode (" << mode
456  << ")! Assuming SCOPE MODE...";
458  }
459 
460  std::vector<uint16_t> samples;
461 
463  sistrip::FEDRawChannelUnpacker unpacker = sistrip::FEDRawChannelUnpacker::scopeModeUnpacker(buffer->channel(iconn->fedCh()));
464 
466  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
467 
468  if ( !samples.empty() ) {
469  Registry regItem(key, 0, scope_work_digis_.size(), samples.size());
470  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
471  scope_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
472  }
473  scope_work_registry_.push_back( regItem );
474 
475  if ( edm::isDebugEnabled() ) {
476  std::stringstream ss;
477  ss << "Extracted " << samples.size()
478  << " SCOPE MODE digis (samples[0] = "
479  << samples[0]
480  << ") from FED id/ch "
481  << iconn->fedId()
482  << "/"
483  << iconn->fedCh();
484  LogTrace("SiStripRawToDigi") << ss.str();
485  }
486  }
487  else if ( edm::isDebugEnabled() ) {
489  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
490  << " No SM digis found!";
491  }
492  }
493  } // channel loop
494  } // fed loop
495 
496  // bad channels warning
497  unsigned int detIdsSize = detids.size();
498  if ( edm::isDebugEnabled() && detIdsSize ) {
499  std::ostringstream ss;
500  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
501  << " Problems were found in data and " << detIdsSize << " channels could not be unpacked. "
502  << "See output of FED Hardware monitoring for more information. ";
504  }
505  if( (errorThreshold_ != 0) && (detIdsSize > errorThreshold_) ) {
506  edm::LogError("TooManyErrors") << "Total number of errors = " << detIdsSize;
507  }
508 
509  // update DetSetVectors
510  update(scope_mode, virgin_raw, proc_raw, zero_suppr, cm_values);
511 
512  // increment event counter
513  event_++;
514 
515  // no longer first event!
516  if ( first_ ) { first_ = false; }
517 
518  // final cleanup, just in case
520  }
521 
522  void RawToDigiUnpacker::update( RawDigis& scope_mode, RawDigis& virgin_raw, RawDigis& proc_raw, Digis& zero_suppr, RawDigis& common_mode ) {
523 
524  if ( ! zs_work_registry_.empty() ) {
526  std::vector< edm::DetSet<SiStripDigi> > sorted_and_merged;
527  sorted_and_merged.reserve( std::min(zs_work_registry_.size(), size_t(17000)) );
528 
529  bool errorInData = false;
530  std::vector<Registry>::iterator it = zs_work_registry_.begin(), it2 = it+1, end = zs_work_registry_.end();
531  while (it < end) {
532  sorted_and_merged.push_back( edm::DetSet<SiStripDigi>(it->detid) );
533  std::vector<SiStripDigi> & digis = sorted_and_merged.back().data;
534  // first count how many digis we have
535  size_t len = it->length;
536  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) { len += it2->length; }
537  // reserve memory
538  digis.reserve(len);
539  // push them in
540  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
541  digis.insert( digis.end(), & zs_work_digis_[it2->index], & zs_work_digis_[it2->index + it2->length] );
542  }
543  it = it2;
544  }
545 
546  // check sorting
547  if (!__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() )) {
548  // this is an error in the code: i DID sort it already!
549  throw cms::Exception("Bug Found")
550  << "Container must be already sorted!\nat "
551  << __FILE__
552  << ", line "
553  << __LINE__
554  <<"\n";
555  }
556 
557  std::vector< edm::DetSet<SiStripDigi> >::iterator iii = sorted_and_merged.begin();
558  std::vector< edm::DetSet<SiStripDigi> >::iterator jjj = sorted_and_merged.end();
559  for ( ; iii != jjj; ++iii ) {
560  if ( ! __gnu_cxx::is_sorted( iii->begin(), iii->end() ) ) {
561  // this might be an error in the data, if the raws from one FED are not sorted
562  iii->clear();
563  errorInData = true;
564  }
565  }
566 
567  // output error
568  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n";
569 
570  // make output DetSetVector
571  edm::DetSetVector<SiStripDigi> zero_suppr_dsv( sorted_and_merged, true );
572  zero_suppr.swap( zero_suppr_dsv );
573  }
574 
575  // Populate final DetSetVector container with VR data
576  if ( !virgin_work_registry_.empty() ) {
577 
579 
580  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
581  sorted_and_merged.reserve( std::min(virgin_work_registry_.size(), size_t(17000)) );
582 
583  bool errorInData = false;
584  std::vector<Registry>::iterator it = virgin_work_registry_.begin(), it2, end = virgin_work_registry_.end();
585  while (it < end) {
586  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
587  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
588 
589  bool isDetOk = true;
590  // first count how many digis we have
591  int maxFirstStrip = it->first;
592  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
593  // duplicated APV or data corruption. DO NOT 'break' here!
594  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
595  maxFirstStrip = it2->first;
596  }
597  if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
598 
599  // make room for 256 * (max_apv_pair + 1) Raw Digis
600  digis.resize(maxFirstStrip + 256);
601  // push them in
602  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
603  // data corruption. DO NOT 'break' here
604  if (it->length != 256) { isDetOk = false; continue; }
605  std::copy( & virgin_work_digis_[it2->index], & virgin_work_digis_[it2->index + it2->length], & digis[it2->first] );
606  }
607  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
608  it = it2;
609  }
610 
611  // output error
612  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n";
613 
614  // check sorting
615  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
616  // this is an error in the code: i DID sort it already!
617  throw cms::Exception("Bug Found")
618  << "Container must be already sorted!\nat "
619  << __FILE__
620  << ", line "
621  << __LINE__
622  <<"\n";
623  }
624 
625  // make output DetSetVector
626  edm::DetSetVector<SiStripRawDigi> virgin_raw_dsv( sorted_and_merged, true );
627  virgin_raw.swap( virgin_raw_dsv );
628  }
629 
630  // Populate final DetSetVector container with VR data
631  if ( !proc_work_registry_.empty() ) {
633 
634  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
635  sorted_and_merged.reserve( std::min(proc_work_registry_.size(), size_t(17000)) );
636 
637  bool errorInData = false;
638  std::vector<Registry>::iterator it = proc_work_registry_.begin(), it2, end = proc_work_registry_.end();
639  while (it < end) {
640  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
641  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
642 
643  bool isDetOk = true;
644  // first count how many digis we have
645  int maxFirstStrip = it->first;
646  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
647  // duplicated APV or data corruption. DO NOT 'break' here!
648  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
649  maxFirstStrip = it2->first;
650  }
651  // skip whole det
652  if (!isDetOk) { errorInData = true; it = it2; continue; }
653 
654  // make room for 256 * (max_apv_pair + 1) Raw Digis
655  digis.resize(maxFirstStrip + 256);
656  // push them in
657  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
658  // data corruption. DO NOT 'break' here
659  if (it->length != 256) { isDetOk = false; continue; }
660  std::copy( & proc_work_digis_[it2->index], & proc_work_digis_[it2->index + it2->length], & digis[it2->first] );
661  }
662  // skip whole det
663  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; }
664  it = it2;
665  }
666 
667  // output error
668  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted proc raw data, and have been skipped in unpacking\n";
669 
670  // check sorting
671  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
672  // this is an error in the code: i DID sort it already!
673  throw cms::Exception("Bug Found")
674  << "Container must be already sorted!\nat "
675  << __FILE__
676  << ", line "
677  << __LINE__
678  <<"\n";
679  }
680 
681  // make output DetSetVector
682  edm::DetSetVector<SiStripRawDigi> proc_raw_dsv( sorted_and_merged, true );
683  proc_raw.swap( proc_raw_dsv );
684  }
685 
686  // Populate final DetSetVector container with SM data
687  if ( !scope_work_registry_.empty() ) {
689 
690  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
691  sorted_and_merged.reserve( scope_work_registry_.size() );
692 
693  bool errorInData = false;
694  std::vector<Registry>::iterator it, end;
695  for (it = scope_work_registry_.begin(), end = scope_work_registry_.end() ; it != end; ++it) {
696  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
697  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
698  digis.insert( digis.end(), & scope_work_digis_[it->index], & scope_work_digis_[it->index + it->length] );
699 
700  if ( (it +1 != end) && (it->detid == (it+1)->detid) ) {
701  errorInData = true;
702  // let's skip *all* the detsets for that key, as we don't know which is the correct one!
703  do { ++it; } while ( ( it+1 != end) && (it->detid == (it+1)->detid) );
704  }
705  }
706 
707  // output error
708  if (errorInData) edm::LogWarning("CorruptData") << "Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n";
709 
710  // check sorting
711  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
712  // this is an error in the code: i DID sort it already!
713  throw cms::Exception("Bug Found")
714  << "Container must be already sorted!\nat "
715  << __FILE__
716  << ", line "
717  << __LINE__
718  <<"\n";
719  }
720 
721  // make output DetSetVector
722  edm::DetSetVector<SiStripRawDigi> scope_mode_dsv( sorted_and_merged, true );
723  scope_mode.swap( scope_mode_dsv );
724  }
725 
726  // Populate DetSetVector with Common Mode values
727  if ( extractCm_ ) {
728 
729  // Populate final DetSetVector container with VR data
730  if ( !cm_work_registry_.empty() ) {
731 
733 
734  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
735  sorted_and_merged.reserve( std::min(cm_work_registry_.size(), size_t(17000)) );
736 
737  bool errorInData = false;
738  std::vector<Registry>::iterator it = cm_work_registry_.begin(), it2, end = cm_work_registry_.end();
739  while (it < end) {
740  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
741  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
742 
743  bool isDetOk = true;
744  // first count how many digis we have
745  int maxFirstStrip = it->first;
746  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
747  // duplicated APV or data corruption. DO NOT 'break' here!
748  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
749  maxFirstStrip = it2->first;
750  }
751  if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
752 
753  // make room for 2 * (max_apv_pair + 1) Common mode values
754  digis.resize(maxFirstStrip + 2);
755  // push them in
756  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
757  // data corruption. DO NOT 'break' here
758  if (it->length != 2) { isDetOk = false; continue; }
759  std::copy( & cm_work_digis_[it2->index], & cm_work_digis_[it2->index + it2->length], & digis[it2->first] );
760  }
761  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
762  it = it2;
763  }
764 
765  // output error
766  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted common mode data, and have been skipped in unpacking\n";
767 
768  // check sorting
769  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
770  // this is an error in the code: i DID sort it already!
771  throw cms::Exception("Bug Found")
772  << "Container must be already sorted!\nat "
773  << __FILE__
774  << ", line "
775  << __LINE__
776  <<"\n";
777  }
778 
779  // make output DetSetVector
780  edm::DetSetVector<SiStripRawDigi> common_mode_dsv( sorted_and_merged, true );
781  common_mode.swap( common_mode_dsv );
782  }
783 
784  }
785 
786  }
787 
789  // Clear working areas and registries
790 
791  localRA.update(zs_work_digis_.size());
792  zs_work_registry_.clear(); zs_work_digis_.clear(); zs_work_digis_.shrink_to_fit(); assert(zs_work_digis_.capacity()==0);
793  virgin_work_registry_.clear(); virgin_work_digis_.clear();
794  proc_work_registry_.clear(); proc_work_digis_.clear();
795  scope_work_registry_.clear(); scope_work_digis_.clear();
796  cm_work_registry_.clear(); cm_work_digis_.clear();
797  }
798 
800 
801  // Pointer to data (recast as 32-bit words) and number of 32-bit words
802  uint32_t* data_u32 = 0;
803  uint32_t size_u32 = 0;
804 
805  // Search mode
806  if ( triggerFedId_ < 0 ) {
807 
808  uint16_t ifed = 0;
809  while ( triggerFedId_ < 0 &&
810  ifed < 1 + FEDNumbering::lastFEDId() ) {
811  const FEDRawData& trigger_fed = buffers.FEDData( ifed );
812  if ( trigger_fed.data() && trigger_fed.size() ) {
813  uint8_t* temp = const_cast<uint8_t*>( trigger_fed.data() );
814  data_u32 = reinterpret_cast<uint32_t*>( temp ) + sizeof(fedh_t)/sizeof(uint32_t) + 1;
815  size_u32 = trigger_fed.size()/sizeof(uint32_t) - sizeof(fedh_t)/sizeof(uint32_t) - 1;
816  fedt_t* fed_trailer = reinterpret_cast<fedt_t*>( temp + trigger_fed.size() - sizeof(fedt_t) );
817  if ( fed_trailer->conscheck == 0xDEADFACE ) {
818  triggerFedId_ = ifed;
819  if ( edm::isDebugEnabled() ) {
820  std::stringstream ss;
821  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
822  << " Search mode for 'trigger FED' activated!"
823  << " Found 'trigger FED' info with id " << triggerFedId_;
824  LogTrace("SiStripRawToDigi") << ss.str();
825  }
826  }
827  }
828  ifed++;
829  }
830  if ( triggerFedId_ < 0 ) {
831  triggerFedId_ = 0;
832  if ( edm::isDebugEnabled() ) {
833  std::stringstream ss;
834  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
835  << " Search mode for 'trigger FED' activated!"
836  << " 'Trigger FED' info not found!";
838  }
839  }
840  }
841 
842  // "Trigger FED" id given in .cfg file
843  else if ( triggerFedId_ > 0 ) {
844 
845  const FEDRawData& trigger_fed = buffers.FEDData( triggerFedId_ );
846  if ( trigger_fed.data() && trigger_fed.size() ) {
847  uint8_t* temp = const_cast<uint8_t*>( trigger_fed.data() );
848  data_u32 = reinterpret_cast<uint32_t*>( temp ) + sizeof(fedh_t)/sizeof(uint32_t) + 1;
849  size_u32 = trigger_fed.size()/sizeof(uint32_t) - sizeof(fedh_t)/sizeof(uint32_t) - 1;
850  fedt_t* fed_trailer = reinterpret_cast<fedt_t*>( temp + trigger_fed.size() - sizeof(fedt_t) );
851  if ( fed_trailer->conscheck != 0xDEADFACE ) {
852  if ( edm::isDebugEnabled() ) {
854  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
855  << " Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
856  << " Buffer appears not to contain 'trigger FED' data!";
857  }
858  triggerFedId_ = 0;
859  }
860  }
861 
862  } else {
863  triggerFedId_ = 0;
864  data_u32 = 0;
865  size_u32 = 0;
866  }
867 
868  // Populate summary object with commissioning information
869  if ( triggerFedId_ > 0 ) {
870 
871  // Some checks
872  if ( !data_u32 ) {
873  if ( edm::isDebugEnabled() ) {
874  std::stringstream ss;
875  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
876  << " NULL pointer to 'trigger FED' data";
878  }
879  return;
880  }
881  if ( size_u32 < sizeof(TFHeaderDescription)/sizeof(uint32_t) ) {
882  if ( edm::isDebugEnabled() ) {
883  std::stringstream ss;
884  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
885  << " Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
887  }
888  return;
889  }
890 
891  // Write event-specific data to event
892  TFHeaderDescription* header = (TFHeaderDescription*) data_u32;
893  summary.event( static_cast<uint32_t>( header->getFedEventNumber()) );
894  summary.bx( static_cast<uint32_t>( header->getBunchCrossing()) );
895 
896  // Write commissioning information to event
897  uint32_t hsize = sizeof(TFHeaderDescription)/sizeof(uint32_t);
898  uint32_t* head = &data_u32[hsize];
899  summary.commissioningInfo( head, event );
900  summary.triggerFed( triggerFedId_ );
901 
902  }
903 
904  // Some debug
905  if ( summary.isSet() && once_ ) {
906  if ( edm::isDebugEnabled() ) {
907  std::stringstream ss;
908  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
909  << " EventSummary built from \"trigger FED\":"
910  << std::endl << summary;
911  LogTrace("SiStripRawToDigi") << ss.str();
912  }
913  once_ = false;
914  }
915  }
916 
918 
919  // Check size of input buffer
920  if ( input.size() < 24 ) {
921  output.resize( input.size() ); // Return UNadjusted buffer start position and size
922  memcpy( output.data(), input.data(), input.size() );
923  if ( edm::isDebugEnabled() ) {
924  std::stringstream ss;
925  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "] "
926  << "Input FEDRawData with FED id " << fed_id
927  << " has size " << input.size();
929  }
930  return;
931  }
932 
933  // Iterator through buffer to find DAQ header
934  bool found = false;
935  uint16_t ichar = 0;
936  while ( ichar < input.size()-16 && !found ) {
937  uint16_t offset = headerBytes_ < 0 ? ichar : headerBytes_; // Negative value means use "search mode" to find DAQ header
938  uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + offset );
939  uint32_t* fed_trailer = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + input.size() - 8 );
940 
941  // see info on FED 32-bit swapping at end-of-file
942 
943  bool old_vme_header = ( input_u32[0] & 0xF0000000 ) == 0x50000000 && ( fed_trailer[0] & 0xF0000000 ) == 0xA0000000 && ( (fed_trailer[0] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
944 
945  bool old_slink_header = ( input_u32[1] & 0xF0000000 ) == 0x50000000 && ( fed_trailer[1] & 0xF0000000 ) == 0xA0000000 && ( (fed_trailer[1] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
946 
947  bool old_slink_payload = ( input_u32[3] & 0xFF000000 ) == 0xED000000;
948 
949  bool new_buffer_format = ( input_u32[2] & 0xFF000000 ) == 0xC5000000;
950 
951  if ( old_vme_header ) {
952 
953  // Found DAQ header at byte position 'offset'
954  found = true;
955  output.resize( input.size()-offset );
956  memcpy( output.data(), // target
957  input.data()+offset, // source
958  input.size()-offset ); // nbytes
959  if ( headerBytes_ < 0 ) {
960  if ( edm::isDebugEnabled() ) {
961  std::stringstream ss;
962  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
963  << " Buffer for FED id " << fed_id
964  << " has been found at byte position " << offset
965  << " with a size of " << input.size()-offset << " bytes."
966  << " Adjust the configurable 'AppendedBytes' to " << offset;
967  LogTrace("SiStripRawToDigi") << ss.str();
968  }
969  }
970 
971  } else if ( old_slink_header ) {
972 
973  if ( old_slink_payload ) {
974 
975  // Found DAQ header (with MSB and LSB 32-bit words swapped) at byte position 'offset'
976  found = true;
977  output.resize( input.size()-offset );
978  uint32_t* output_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( output.data() ) );
979  uint16_t iter = offset;
980  while ( iter < output.size() / sizeof(uint32_t) ) {
981  output_u32[iter] = input_u32[iter+1];
982  output_u32[iter+1] = input_u32[iter];
983  iter+=2;
984  }
985  if ( headerBytes_ < 0 ) {
986  if ( edm::isDebugEnabled() ) {
987  std::stringstream ss;
988  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
989  << " Buffer (with MSB and LSB 32-bit words swapped) for FED id " << fed_id
990  << " has been found at byte position " << offset
991  << " with a size of " << output.size() << " bytes."
992  << " Adjust the configurable 'AppendedBytes' to " << offset;
993  LogTrace("SiStripRawToDigi") << ss.str();
994  }
995  }
996 
997  } else if ( new_buffer_format ) {
998 
999  // Found DAQ header at byte position 'offset'
1000  found = true;
1001  output.resize( input.size()-offset );
1002  memcpy( output.data(), // target
1003  input.data()+offset, // source
1004  input.size()-offset ); // nbytes
1005  if ( headerBytes_ < 0 ) {
1006  if ( edm::isDebugEnabled() ) {
1007  std::stringstream ss;
1008  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1009  << " Buffer for FED id " << fed_id
1010  << " has been found at byte position " << offset
1011  << " with a size of " << input.size()-offset << " bytes."
1012  << " Adjust the configurable 'AppendedBytes' to " << offset;
1013  LogTrace("SiStripRawToDigi") << ss.str();
1014  }
1015  }
1016 
1017  } else { headerBytes_ < 0 ? found = false : found = true; }
1018  } else { headerBytes_ < 0 ? found = false : found = true; }
1019  ichar++;
1020  }
1021 
1022  // Check size of output buffer
1023  if ( output.size() == 0 ) {
1024 
1025  // Did not find DAQ header after search => return buffer with null size
1026  output.resize( 0 ); //@@ NULL SIZE
1027  memcpy( output.data(), input.data(), 0 ); //@@ NULL SIZE
1028  if ( edm::isDebugEnabled() ) {
1029  std::stringstream ss;
1030  if ( headerBytes_ < 0 ) {
1031  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1032  << " DAQ header not found within buffer for FED id: " << fed_id;
1033  } else {
1034  uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) );
1035  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1036  << " DAQ header not found at expected location for FED id: " << fed_id << std::endl
1037  << " First 64-bit word of buffer is 0x"
1038  << std::hex
1039  << std::setfill('0') << std::setw(8) << input_u32[0]
1040  << std::setfill('0') << std::setw(8) << input_u32[1]
1041  << std::dec << std::endl
1042  << " Adjust 'AppendedBytes' configurable to '-1' to activate 'search mode'";
1043  }
1045  }
1046 
1047  } else if ( output.size() < 24 ) { // Found DAQ header after search, but too few words
1048 
1049  if ( edm::isDebugEnabled() ) {
1050  std::stringstream ss;
1051  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1052  << " Unexpected buffer size! FEDRawData with FED id " << fed_id
1053  << " has size " << output.size();
1055  }
1056  }
1057  }
1058 
1060 
1061  // Retrieve contents of DAQ registers
1062 
1063  sistrip::FEDDAQEventType readout_mode = fed.daqEventType();
1064  uint32_t daq1 = sistrip::invalid32_;
1065  uint32_t daq2 = sistrip::invalid32_;
1066 
1068  const sistrip::FEDFullDebugHeader* header = 0;
1069  header = dynamic_cast<const sistrip::FEDFullDebugHeader*>(fed.feHeader());
1070  daq1 = static_cast<uint32_t>( header->daqRegister() );
1071  daq2 = static_cast<uint32_t>( header->daqRegister2() );
1072  }
1073 
1074 
1075  // If FED DAQ registers contain info, update (and possibly overwrite) EventSummary
1076  if ( daq1 != 0 && daq1 != sistrip::invalid32_ ) {
1077 
1078  summary.triggerFed( triggerFedId_ );
1079  summary.fedReadoutMode( readout_mode );
1080  summary.commissioningInfo( daq1, daq2 );
1081 
1082  if ( summary.isSet() && once_ ) {
1083  if ( edm::isDebugEnabled() ) {
1084  std::stringstream ss;
1085  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1086  << " EventSummary built from FED DAQ registers:"
1087  << std::endl << summary;
1088  LogTrace("SiStripRawToDigi") << ss.str();
1089  }
1090  once_ = false;
1091  }
1092  }
1093  }
1094 
1095  void RawToDigiUnpacker::dumpRawData( uint16_t fed_id, const FEDRawData& buffer, std::stringstream& ss ) {
1096 
1097  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1098  << " Dump of buffer for FED id " << fed_id << std::endl
1099  << " Buffer contains " << buffer.size()
1100  << " bytes (NB: payload is byte-swapped)" << std::endl;
1101  uint32_t* buffer_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( buffer.data() ) );
1102  unsigned int empty = 0;
1103 
1104  if ( 0 ) {
1105 
1106  ss << "Byte-> 4 5 6 7 0 1 2 3\n";
1107  for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
1108  unsigned int temp0 = buffer_u32[i*2] & sistrip::invalid32_;
1109  unsigned int temp1 = buffer_u32[i*2+1] & sistrip::invalid32_;
1110  if ( !temp0 && !temp1 ) { empty++; }
1111  else {
1112  if ( empty ) {
1113  ss << " [ empty words ]" << std::endl;
1114  empty = 0;
1115  }
1116  ss << std::dec
1117  << std::setfill(' ') << std::setw(6) << i*8 << ": "
1118  << std::hex
1119  << std::setfill('0') << std::setw(8) << temp0
1120  << std::setfill('0') << std::setw(8) << temp1
1121  << std::dec
1122  << std::endl;
1123  }
1124  }
1125 
1126  } else {
1127 
1128  ss << " Byte | <---- Byte order ----< | Byte" << std::endl;
1129  ss << " cntr | 7 6 5 4 3 2 1 0 | cntr" << std::endl;
1130  for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
1131  //if ( i>=20 && ((i+4)<(buffer.size()/8)) ) { continue; }
1132  uint16_t tmp0 = buffer.data()[i*8+0] & 0xFF;
1133  uint16_t tmp1 = buffer.data()[i*8+1] & 0xFF;
1134  uint16_t tmp2 = buffer.data()[i*8+2] & 0xFF;
1135  uint16_t tmp3 = buffer.data()[i*8+3] & 0xFF;
1136  uint16_t tmp4 = buffer.data()[i*8+4] & 0xFF;
1137  uint16_t tmp5 = buffer.data()[i*8+5] & 0xFF;
1138  uint16_t tmp6 = buffer.data()[i*8+6] & 0xFF;
1139  uint16_t tmp7 = buffer.data()[i*8+7] & 0xFF;
1140 // if ( !tmp0 && !tmp1 && !tmp2 && !tmp3 &&
1141 // !tmp4 && !tmp5 && !tmp6 && !tmp7 ) { empty++; }
1142 // else {
1143 // if ( empty ) {
1144 // ss << " [.."
1145 // << std::dec << std::setfill('.') << std::setw(4) << empty
1146 // << " null words....]" << std::endl;
1147 // empty = 0;
1148 // }
1149  ss << std::dec
1150  << std::setfill(' ') << std::setw(6) << i*8+7 << " : "
1151  << std::hex
1152  << std::setfill('0') << std::setw(2) << tmp7 << " "
1153  << std::setfill('0') << std::setw(2) << tmp6 << " "
1154  << std::setfill('0') << std::setw(2) << tmp5 << " "
1155  << std::setfill('0') << std::setw(2) << tmp4 << " "
1156  << std::setfill('0') << std::setw(2) << tmp3 << " "
1157  << std::setfill('0') << std::setw(2) << tmp2 << " "
1158  << std::setfill('0') << std::setw(2) << tmp1 << " "
1159  << std::setfill('0') << std::setw(2) << tmp0
1160  << std::dec
1161  << " :" << std::setfill(' ') << std::setw(6) << i*8
1162  << std::endl;
1163 // }
1164  }
1165 
1166  }
1167  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1168  << " End of FED buffer";
1169  }
1170 
1172 
1173  method_name = "sistrip::RawToDigiUnpacker::" + method_name;
1174  try {
1175  throw; // rethrow caught exception to be dealt with below
1176  }
1177  catch ( const cms::Exception& e ) {
1178  //throw e; // rethrow cms::Exception to be caught by framework
1179  }
1180  catch ( const std::exception& e ) {
1181  if ( edm::isDebugEnabled() ) {
1182  std::stringstream ss;
1183  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1184  << " Caught std::exception!" << std::endl;
1185  if ( extra_info != "" ) {
1186  ss << " Information: " << extra_info << std::endl;
1187  }
1188  ss << " Caught std::exception in ["
1189  << method_name << "] with message:" << std::endl
1190  << e.what();
1192  }
1193  //throw cms::Exception(sistrip::mlRawToDigi_) << ss.str();
1194  }
1195  catch (...) {
1196  if ( edm::isDebugEnabled() ) {
1197  std::stringstream ss;
1198  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1199  << " Caught unknown exception!" << std::endl;
1200  if ( extra_info != "" ) {
1201  ss << " Information: " << extra_info << std::endl;
1202  }
1203  ss << "Caught unknown exception in ["
1204  << method_name << "]" << std::endl;
1206  }
1207  //throw cms::Exception(sistrip::mlRawToDigi_) << ss.str();
1208  }
1209  }
1210 
1211 }
1212 
1213 /*
1214 
1215 Some info on FED buffer 32-bit word swapping.
1216 
1217 Table below indicates if data are swapped relative to the "old"
1218 VME format (as originally expected by the Fed9UEvent class).
1219 
1220 -------------------------------------------
1221 | SWAPPED? | DATA FORMAT |
1222 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1223 | | VME | SLINK | VME | SLINK |
1224 -------------------------------------------
1225 | DAQ HEADER | N | Y | Y | Y |
1226 | TRK HEADER | N | Y | N | N |
1227 | PAYLOAD | N | Y | N | N |
1228 | DAQ TRAILER | N | Y | Y | Y |
1229 -------------------------------------------
1230 
1231 So, in code, we check in code order of bytes in DAQ header/trailer only:
1232 -> if "old_vme_header", then old format read out via vme, so do nothing.
1233 -> else if "old_slink_header", then data may be wrapped, so check additionally the TRK header:
1234 ---> if "old_slink_payload", then old format read out via slink, so swap all data;
1235 ---> else if "new_buffer_format", then new format, handled internally by Fed9UEvent, so do nothing.
1236 
1237 Pattern matching to find DAQ and tracker headers, and DAQ trailer:
1238 DAQ header, 4 bits, in field |BOE_1| with value 0x5
1239 DAQ trailer, 4 bits, in field |EOE_1| with value 0xA
1240 TRK header, 8 bits, in field |Hdr format| with value 0xED or 0xC5
1241 
1242 -------------------------------------------------------------------------------------------
1243 | SWAPPED? | DATA FORMAT |
1244 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1245 | | VME | SLINK | VME | SLINK |
1246 -------------------------------------------------------------------------------------------
1247 | DAQ HEADER | ........5....... | 5............... | 5............... | 5............... |
1248 | TRK HEADER | ........ED...... | ED.............. | ........C5...... | ........C5...... |
1249 | PAYLOAD | ..........EA.... | ..EA............ | ..EA............ | ............EA.. |
1250 | DAQ TRAILER | ........A....... | A............... | A............... | A............... |
1251 -------------------------------------------------------------------------------------------
1252 
1253 */
void triggerFed(const FEDRawDataCollection &, SiStripEventSummary &, const uint32_t &event)
trigger info
static FEDRawChannelUnpacker procRawModeUnpacker(const FEDChannel &channel)
virtual char const * what() const
Definition: Exception.cc:141
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
int i
Definition: DBlmapReader.cc:9
std::vector< Registry > proc_work_registry_
void updateEventSummary(const sistrip::FEDBuffer &, SiStripEventSummary &)
sets the SiStripEventSummary -&gt; 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.
RawToDigiUnpacker()
private default constructor
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
unsigned long getBunchCrossing()
const FEDFEHeader * feHeader() const
void swap(DetSetVector &other)
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
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_
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
unsigned int offset(bool)
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
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 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
Contains cabling info at the device level, including DetId, APV pair numbers, hardware addresses...
const sistrip::FedReadoutMode & fedReadoutMode() const
list key
Definition: combine.py:13
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_
volatile std::atomic< bool > shutdown_flag false
A Digi for the silicon strip detector, containing only adc information, and suitable for storing raw ...
std::vector< Registry > virgin_work_registry_