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