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_VIRGIN_RAW ) {
357 
358  std::vector<uint16_t> samples;
359 
362 
364  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
365 
366  if ( !samples.empty() ) {
367  Registry regItem(key, 256*ipair, virgin_work_digis_.size(), samples.size());
368  uint16_t physical;
369  uint16_t readout;
370  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
371  physical = i%128;
372  readoutOrder( physical, readout ); // convert index from physical to readout order
373  (i/128) ? readout=readout*2+1 : readout=readout*2; // un-multiplex data
374  virgin_work_digis_.push_back( SiStripRawDigi( samples[readout] ) );
375  }
376  virgin_work_registry_.push_back( regItem );
377  }
378  }
379 
380  else if ( mode == sistrip::READOUT_MODE_PROC_RAW ) {
381 
382  std::vector<uint16_t> samples;
383 
386 
388  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
389 
390  if ( !samples.empty() ) {
391  Registry regItem(key, 256*ipair, proc_work_digis_.size(), samples.size());
392  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
393  proc_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
394  }
395  proc_work_registry_.push_back( regItem );
396  }
397  }
398 
399  else if ( mode == sistrip::READOUT_MODE_SCOPE ) {
400 
401  std::vector<uint16_t> samples;
402 
404  sistrip::FEDRawChannelUnpacker unpacker = sistrip::FEDRawChannelUnpacker::scopeModeUnpacker(buffer->channel(iconn->fedCh()));
405 
407  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
408 
409  if ( !samples.empty() ) {
410  Registry regItem(key, 0, scope_work_digis_.size(), samples.size());
411  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
412  scope_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
413  }
414  scope_work_registry_.push_back( regItem );
415  }
416  }
417 
418  else { // Unknown readout mode! => assume scope mode
419 
420  if ( edm::isDebugEnabled() ) {
421  std::stringstream ss;
422  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
423  << " Unknown FED readout mode (" << mode
424  << ")! Assuming SCOPE MODE...";
426  }
427 
428  std::vector<uint16_t> samples;
429 
431  sistrip::FEDRawChannelUnpacker unpacker = sistrip::FEDRawChannelUnpacker::scopeModeUnpacker(buffer->channel(iconn->fedCh()));
432 
434  while (unpacker.hasData()) {samples.push_back(unpacker.adc());unpacker++;}
435 
436  if ( !samples.empty() ) {
437  Registry regItem(key, 0, scope_work_digis_.size(), samples.size());
438  for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
439  scope_work_digis_.push_back( SiStripRawDigi( samples[i] ) );
440  }
441  scope_work_registry_.push_back( regItem );
442 
443  if ( edm::isDebugEnabled() ) {
444  std::stringstream ss;
445  ss << "Extracted " << samples.size()
446  << " SCOPE MODE digis (samples[0] = "
447  << samples[0]
448  << ") from FED id/ch "
449  << iconn->fedId()
450  << "/"
451  << iconn->fedCh();
452  LogTrace("SiStripRawToDigi") << ss.str();
453  }
454  }
455  else if ( edm::isDebugEnabled() ) {
457  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
458  << " No SM digis found!";
459  }
460  }
461  } // channel loop
462  } // fed loop
463 
464  // bad channels warning
465  unsigned int detIdsSize = detids.size();
466  if ( edm::isDebugEnabled() && detIdsSize ) {
467  std::ostringstream ss;
468  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
469  << " Problems were found in data and " << detIdsSize << " channels could not be unpacked. "
470  << "See output of FED Hardware monitoring for more information. ";
472  }
473  if( (errorThreshold_ != 0) && (detIdsSize > errorThreshold_) ) {
474  edm::LogError("TooManyErrors") << "Total number of errors = " << detIdsSize;
475  }
476 
477  // update DetSetVectors
478  update(scope_mode, virgin_raw, proc_raw, zero_suppr, cm_values);
479 
480  // increment event counter
481  event_++;
482 
483  // no longer first event!
484  if ( first_ ) { first_ = false; }
485 
486  // final cleanup, just in case
488  }
489 
490  void RawToDigiUnpacker::update( RawDigis& scope_mode, RawDigis& virgin_raw, RawDigis& proc_raw, Digis& zero_suppr, RawDigis& common_mode ) {
491 
492  if ( ! zs_work_registry_.empty() ) {
494  std::vector< edm::DetSet<SiStripDigi> > sorted_and_merged;
495  sorted_and_merged.reserve( std::min(zs_work_registry_.size(), size_t(17000)) );
496 
497  bool errorInData = false;
498  std::vector<Registry>::iterator it = zs_work_registry_.begin(), it2 = it+1, end = zs_work_registry_.end();
499  while (it < end) {
500  sorted_and_merged.push_back( edm::DetSet<SiStripDigi>(it->detid) );
501  std::vector<SiStripDigi> & digis = sorted_and_merged.back().data;
502  // first count how many digis we have
503  size_t len = it->length;
504  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) { len += it2->length; }
505  // reserve memory
506  digis.reserve(len);
507  // push them in
508  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
509  digis.insert( digis.end(), & zs_work_digis_[it2->index], & zs_work_digis_[it2->index + it2->length] );
510  }
511  it = it2;
512  }
513 
514  // check sorting
515  if (!__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() )) {
516  // this is an error in the code: i DID sort it already!
517  throw cms::Exception("Bug Found")
518  << "Container must be already sorted!\nat "
519  << __FILE__
520  << ", line "
521  << __LINE__
522  <<"\n";
523  }
524 
525  std::vector< edm::DetSet<SiStripDigi> >::iterator iii = sorted_and_merged.begin();
526  std::vector< edm::DetSet<SiStripDigi> >::iterator jjj = sorted_and_merged.end();
527  for ( ; iii != jjj; ++iii ) {
528  if ( ! __gnu_cxx::is_sorted( iii->begin(), iii->end() ) ) {
529  // this might be an error in the data, if the raws from one FED are not sorted
530  iii->clear();
531  errorInData = true;
532  }
533  }
534 
535  // output error
536  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n";
537 
538  // make output DetSetVector
539  edm::DetSetVector<SiStripDigi> zero_suppr_dsv( sorted_and_merged, true );
540  zero_suppr.swap( zero_suppr_dsv );
541  }
542 
543  // Populate final DetSetVector container with VR data
544  if ( !virgin_work_registry_.empty() ) {
545 
547 
548  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
549  sorted_and_merged.reserve( std::min(virgin_work_registry_.size(), size_t(17000)) );
550 
551  bool errorInData = false;
552  std::vector<Registry>::iterator it = virgin_work_registry_.begin(), it2, end = virgin_work_registry_.end();
553  while (it < end) {
554  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
555  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
556 
557  bool isDetOk = true;
558  // first count how many digis we have
559  int maxFirstStrip = it->first;
560  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
561  // duplicated APV or data corruption. DO NOT 'break' here!
562  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
563  maxFirstStrip = it2->first;
564  }
565  if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
566 
567  // make room for 256 * (max_apv_pair + 1) Raw Digis
568  digis.resize(maxFirstStrip + 256);
569  // push them in
570  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
571  // data corruption. DO NOT 'break' here
572  if (it->length != 256) { isDetOk = false; continue; }
573  std::copy( & virgin_work_digis_[it2->index], & virgin_work_digis_[it2->index + it2->length], & digis[it2->first] );
574  }
575  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
576  it = it2;
577  }
578 
579  // output error
580  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n";
581 
582  // check sorting
583  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
584  // this is an error in the code: i DID sort it already!
585  throw cms::Exception("Bug Found")
586  << "Container must be already sorted!\nat "
587  << __FILE__
588  << ", line "
589  << __LINE__
590  <<"\n";
591  }
592 
593  // make output DetSetVector
594  edm::DetSetVector<SiStripRawDigi> virgin_raw_dsv( sorted_and_merged, true );
595  virgin_raw.swap( virgin_raw_dsv );
596  }
597 
598  // Populate final DetSetVector container with VR data
599  if ( !proc_work_registry_.empty() ) {
601 
602  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
603  sorted_and_merged.reserve( std::min(proc_work_registry_.size(), size_t(17000)) );
604 
605  bool errorInData = false;
606  std::vector<Registry>::iterator it = proc_work_registry_.begin(), it2, end = proc_work_registry_.end();
607  while (it < end) {
608  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
609  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
610 
611  bool isDetOk = true;
612  // first count how many digis we have
613  int maxFirstStrip = it->first;
614  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
615  // duplicated APV or data corruption. DO NOT 'break' here!
616  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
617  maxFirstStrip = it2->first;
618  }
619  // skip whole det
620  if (!isDetOk) { errorInData = true; it = it2; continue; }
621 
622  // make room for 256 * (max_apv_pair + 1) Raw Digis
623  digis.resize(maxFirstStrip + 256);
624  // push them in
625  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
626  // data corruption. DO NOT 'break' here
627  if (it->length != 256) { isDetOk = false; continue; }
628  std::copy( & proc_work_digis_[it2->index], & proc_work_digis_[it2->index + it2->length], & digis[it2->first] );
629  }
630  // skip whole det
631  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; }
632  it = it2;
633  }
634 
635  // output error
636  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted proc raw data, and have been skipped in unpacking\n";
637 
638  // check sorting
639  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
640  // this is an error in the code: i DID sort it already!
641  throw cms::Exception("Bug Found")
642  << "Container must be already sorted!\nat "
643  << __FILE__
644  << ", line "
645  << __LINE__
646  <<"\n";
647  }
648 
649  // make output DetSetVector
650  edm::DetSetVector<SiStripRawDigi> proc_raw_dsv( sorted_and_merged, true );
651  proc_raw.swap( proc_raw_dsv );
652  }
653 
654  // Populate final DetSetVector container with SM data
655  if ( !scope_work_registry_.empty() ) {
657 
658  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
659  sorted_and_merged.reserve( scope_work_registry_.size() );
660 
661  bool errorInData = false;
662  std::vector<Registry>::iterator it, end;
663  for (it = scope_work_registry_.begin(), end = scope_work_registry_.end() ; it != end; ++it) {
664  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
665  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
666  digis.insert( digis.end(), & scope_work_digis_[it->index], & scope_work_digis_[it->index + it->length] );
667 
668  if ( (it +1 != end) && (it->detid == (it+1)->detid) ) {
669  errorInData = true;
670  // let's skip *all* the detsets for that key, as we don't know which is the correct one!
671  do { ++it; } while ( ( it+1 != end) && (it->detid == (it+1)->detid) );
672  }
673  }
674 
675  // output error
676  if (errorInData) edm::LogWarning("CorruptData") << "Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n";
677 
678  // check sorting
679  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
680  // this is an error in the code: i DID sort it already!
681  throw cms::Exception("Bug Found")
682  << "Container must be already sorted!\nat "
683  << __FILE__
684  << ", line "
685  << __LINE__
686  <<"\n";
687  }
688 
689  // make output DetSetVector
690  edm::DetSetVector<SiStripRawDigi> scope_mode_dsv( sorted_and_merged, true );
691  scope_mode.swap( scope_mode_dsv );
692  }
693 
694  // Populate DetSetVector with Common Mode values
695  if ( extractCm_ ) {
696 
697  // Populate final DetSetVector container with VR data
698  if ( !cm_work_registry_.empty() ) {
699 
701 
702  std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
703  sorted_and_merged.reserve( std::min(cm_work_registry_.size(), size_t(17000)) );
704 
705  bool errorInData = false;
706  std::vector<Registry>::iterator it = cm_work_registry_.begin(), it2, end = cm_work_registry_.end();
707  while (it < end) {
708  sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
709  std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
710 
711  bool isDetOk = true;
712  // first count how many digis we have
713  int maxFirstStrip = it->first;
714  for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) {
715  // duplicated APV or data corruption. DO NOT 'break' here!
716  if (it2->first <= maxFirstStrip) { isDetOk = false; continue; }
717  maxFirstStrip = it2->first;
718  }
719  if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
720 
721  // make room for 2 * (max_apv_pair + 1) Common mode values
722  digis.resize(maxFirstStrip + 2);
723  // push them in
724  for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
725  // data corruption. DO NOT 'break' here
726  if (it->length != 2) { isDetOk = false; continue; }
727  std::copy( & cm_work_digis_[it2->index], & cm_work_digis_[it2->index + it2->length], & digis[it2->first] );
728  }
729  if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
730  it = it2;
731  }
732 
733  // output error
734  if (errorInData) edm::LogWarning("CorruptData") << "Some modules contained corrupted common mode data, and have been skipped in unpacking\n";
735 
736  // check sorting
737  if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() ) ) {
738  // this is an error in the code: i DID sort it already!
739  throw cms::Exception("Bug Found")
740  << "Container must be already sorted!\nat "
741  << __FILE__
742  << ", line "
743  << __LINE__
744  <<"\n";
745  }
746 
747  // make output DetSetVector
748  edm::DetSetVector<SiStripRawDigi> common_mode_dsv( sorted_and_merged, true );
749  common_mode.swap( common_mode_dsv );
750  }
751 
752  }
753 
754  }
755 
757  // Clear working areas and registries
758 
759  localRA.update(zs_work_digis_.size());
760  zs_work_registry_.clear(); zs_work_digis_.clear(); zs_work_digis_.shrink_to_fit(); assert(zs_work_digis_.capacity()==0);
761  virgin_work_registry_.clear(); virgin_work_digis_.clear();
762  proc_work_registry_.clear(); proc_work_digis_.clear();
763  scope_work_registry_.clear(); scope_work_digis_.clear();
764  cm_work_registry_.clear(); cm_work_digis_.clear();
765  }
766 
768 
769  // Pointer to data (recast as 32-bit words) and number of 32-bit words
770  uint32_t* data_u32 = 0;
771  uint32_t size_u32 = 0;
772 
773  // Search mode
774  if ( triggerFedId_ < 0 ) {
775 
776  uint16_t ifed = 0;
777  while ( triggerFedId_ < 0 &&
778  ifed < 1 + FEDNumbering::lastFEDId() ) {
779  const FEDRawData& trigger_fed = buffers.FEDData( ifed );
780  if ( trigger_fed.data() && trigger_fed.size() ) {
781  uint8_t* temp = const_cast<uint8_t*>( trigger_fed.data() );
782  data_u32 = reinterpret_cast<uint32_t*>( temp ) + sizeof(fedh_t)/sizeof(uint32_t) + 1;
783  size_u32 = trigger_fed.size()/sizeof(uint32_t) - sizeof(fedh_t)/sizeof(uint32_t) - 1;
784  fedt_t* fed_trailer = reinterpret_cast<fedt_t*>( temp + trigger_fed.size() - sizeof(fedt_t) );
785  if ( fed_trailer->conscheck == 0xDEADFACE ) {
786  triggerFedId_ = ifed;
787  if ( edm::isDebugEnabled() ) {
788  std::stringstream ss;
789  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
790  << " Search mode for 'trigger FED' activated!"
791  << " Found 'trigger FED' info with id " << triggerFedId_;
792  LogTrace("SiStripRawToDigi") << ss.str();
793  }
794  }
795  }
796  ifed++;
797  }
798  if ( triggerFedId_ < 0 ) {
799  triggerFedId_ = 0;
800  if ( edm::isDebugEnabled() ) {
801  std::stringstream ss;
802  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
803  << " Search mode for 'trigger FED' activated!"
804  << " 'Trigger FED' info not found!";
806  }
807  }
808  }
809 
810  // "Trigger FED" id given in .cfg file
811  else if ( triggerFedId_ > 0 ) {
812 
813  const FEDRawData& trigger_fed = buffers.FEDData( triggerFedId_ );
814  if ( trigger_fed.data() && trigger_fed.size() ) {
815  uint8_t* temp = const_cast<uint8_t*>( trigger_fed.data() );
816  data_u32 = reinterpret_cast<uint32_t*>( temp ) + sizeof(fedh_t)/sizeof(uint32_t) + 1;
817  size_u32 = trigger_fed.size()/sizeof(uint32_t) - sizeof(fedh_t)/sizeof(uint32_t) - 1;
818  fedt_t* fed_trailer = reinterpret_cast<fedt_t*>( temp + trigger_fed.size() - sizeof(fedt_t) );
819  if ( fed_trailer->conscheck != 0xDEADFACE ) {
820  if ( edm::isDebugEnabled() ) {
822  << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
823  << " Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
824  << " Buffer appears not to contain 'trigger FED' data!";
825  }
826  triggerFedId_ = 0;
827  }
828  }
829 
830  } else {
831  triggerFedId_ = 0;
832  data_u32 = 0;
833  size_u32 = 0;
834  }
835 
836  // Populate summary object with commissioning information
837  if ( triggerFedId_ > 0 ) {
838 
839  // Some checks
840  if ( !data_u32 ) {
841  if ( edm::isDebugEnabled() ) {
842  std::stringstream ss;
843  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
844  << " NULL pointer to 'trigger FED' data";
846  }
847  return;
848  }
849  if ( size_u32 < sizeof(TFHeaderDescription)/sizeof(uint32_t) ) {
850  if ( edm::isDebugEnabled() ) {
851  std::stringstream ss;
852  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
853  << " Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
855  }
856  return;
857  }
858 
859  // Write event-specific data to event
860  TFHeaderDescription* header = (TFHeaderDescription*) data_u32;
861  summary.event( static_cast<uint32_t>( header->getFedEventNumber()) );
862  summary.bx( static_cast<uint32_t>( header->getBunchCrossing()) );
863 
864  // Write commissioning information to event
865  uint32_t hsize = sizeof(TFHeaderDescription)/sizeof(uint32_t);
866  uint32_t* head = &data_u32[hsize];
867  summary.commissioningInfo( head, event );
868  summary.triggerFed( triggerFedId_ );
869 
870  }
871 
872  // Some debug
873  if ( summary.isSet() && once_ ) {
874  if ( edm::isDebugEnabled() ) {
875  std::stringstream ss;
876  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
877  << " EventSummary built from \"trigger FED\":"
878  << std::endl << summary;
879  LogTrace("SiStripRawToDigi") << ss.str();
880  }
881  once_ = false;
882  }
883  }
884 
886 
887  // Check size of input buffer
888  if ( input.size() < 24 ) {
889  output.resize( input.size() ); // Return UNadjusted buffer start position and size
890  memcpy( output.data(), input.data(), input.size() );
891  if ( edm::isDebugEnabled() ) {
892  std::stringstream ss;
893  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "] "
894  << "Input FEDRawData with FED id " << fed_id
895  << " has size " << input.size();
897  }
898  return;
899  }
900 
901  // Iterator through buffer to find DAQ header
902  bool found = false;
903  uint16_t ichar = 0;
904  while ( ichar < input.size()-16 && !found ) {
905  uint16_t offset = headerBytes_ < 0 ? ichar : headerBytes_; // Negative value means use "search mode" to find DAQ header
906  uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + offset );
907  uint32_t* fed_trailer = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + input.size() - 8 );
908 
909  // see info on FED 32-bit swapping at end-of-file
910 
911  bool old_vme_header = ( input_u32[0] & 0xF0000000 ) == 0x50000000 && ( fed_trailer[0] & 0xF0000000 ) == 0xA0000000 && ( (fed_trailer[0] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
912 
913  bool old_slink_header = ( input_u32[1] & 0xF0000000 ) == 0x50000000 && ( fed_trailer[1] & 0xF0000000 ) == 0xA0000000 && ( (fed_trailer[1] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
914 
915  bool old_slink_payload = ( input_u32[3] & 0xFF000000 ) == 0xED000000;
916 
917  bool new_buffer_format = ( input_u32[2] & 0xFF000000 ) == 0xC5000000;
918 
919  if ( old_vme_header ) {
920 
921  // Found DAQ header at byte position 'offset'
922  found = true;
923  output.resize( input.size()-offset );
924  memcpy( output.data(), // target
925  input.data()+offset, // source
926  input.size()-offset ); // nbytes
927  if ( headerBytes_ < 0 ) {
928  if ( edm::isDebugEnabled() ) {
929  std::stringstream ss;
930  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
931  << " Buffer for FED id " << fed_id
932  << " has been found at byte position " << offset
933  << " with a size of " << input.size()-offset << " bytes."
934  << " Adjust the configurable 'AppendedBytes' to " << offset;
935  LogTrace("SiStripRawToDigi") << ss.str();
936  }
937  }
938 
939  } else if ( old_slink_header ) {
940 
941  if ( old_slink_payload ) {
942 
943  // Found DAQ header (with MSB and LSB 32-bit words swapped) at byte position 'offset'
944  found = true;
945  output.resize( input.size()-offset );
946  uint32_t* output_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( output.data() ) );
947  uint16_t iter = offset;
948  while ( iter < output.size() / sizeof(uint32_t) ) {
949  output_u32[iter] = input_u32[iter+1];
950  output_u32[iter+1] = input_u32[iter];
951  iter+=2;
952  }
953  if ( headerBytes_ < 0 ) {
954  if ( edm::isDebugEnabled() ) {
955  std::stringstream ss;
956  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
957  << " Buffer (with MSB and LSB 32-bit words swapped) for FED id " << fed_id
958  << " has been found at byte position " << offset
959  << " with a size of " << output.size() << " bytes."
960  << " Adjust the configurable 'AppendedBytes' to " << offset;
961  LogTrace("SiStripRawToDigi") << ss.str();
962  }
963  }
964 
965  } else if ( new_buffer_format ) {
966 
967  // Found DAQ header at byte position 'offset'
968  found = true;
969  output.resize( input.size()-offset );
970  memcpy( output.data(), // target
971  input.data()+offset, // source
972  input.size()-offset ); // nbytes
973  if ( headerBytes_ < 0 ) {
974  if ( edm::isDebugEnabled() ) {
975  std::stringstream ss;
976  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
977  << " Buffer for FED id " << fed_id
978  << " has been found at byte position " << offset
979  << " with a size of " << input.size()-offset << " bytes."
980  << " Adjust the configurable 'AppendedBytes' to " << offset;
981  LogTrace("SiStripRawToDigi") << ss.str();
982  }
983  }
984 
985  } else { headerBytes_ < 0 ? found = false : found = true; }
986  } else { headerBytes_ < 0 ? found = false : found = true; }
987  ichar++;
988  }
989 
990  // Check size of output buffer
991  if ( output.size() == 0 ) {
992 
993  // Did not find DAQ header after search => return buffer with null size
994  output.resize( 0 ); //@@ NULL SIZE
995  memcpy( output.data(), input.data(), 0 ); //@@ NULL SIZE
996  if ( edm::isDebugEnabled() ) {
997  std::stringstream ss;
998  if ( headerBytes_ < 0 ) {
999  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1000  << " DAQ header not found within buffer for FED id: " << fed_id;
1001  } else {
1002  uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) );
1003  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1004  << " DAQ header not found at expected location for FED id: " << fed_id << std::endl
1005  << " First 64-bit word of buffer is 0x"
1006  << std::hex
1007  << std::setfill('0') << std::setw(8) << input_u32[0]
1008  << std::setfill('0') << std::setw(8) << input_u32[1]
1009  << std::dec << std::endl
1010  << " Adjust 'AppendedBytes' configurable to '-1' to activate 'search mode'";
1011  }
1013  }
1014 
1015  } else if ( output.size() < 24 ) { // Found DAQ header after search, but too few words
1016 
1017  if ( edm::isDebugEnabled() ) {
1018  std::stringstream ss;
1019  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1020  << " Unexpected buffer size! FEDRawData with FED id " << fed_id
1021  << " has size " << output.size();
1023  }
1024  }
1025  }
1026 
1028 
1029  // Retrieve contents of DAQ registers
1030 
1031  sistrip::FEDDAQEventType readout_mode = fed.daqEventType();
1032  uint32_t daq1 = sistrip::invalid32_;
1033  uint32_t daq2 = sistrip::invalid32_;
1034 
1036  const sistrip::FEDFullDebugHeader* header = 0;
1037  header = dynamic_cast<const sistrip::FEDFullDebugHeader*>(fed.feHeader());
1038  daq1 = static_cast<uint32_t>( header->daqRegister() );
1039  daq2 = static_cast<uint32_t>( header->daqRegister2() );
1040  }
1041 
1042 
1043  // If FED DAQ registers contain info, update (and possibly overwrite) EventSummary
1044  if ( daq1 != 0 && daq1 != sistrip::invalid32_ ) {
1045 
1046  summary.triggerFed( triggerFedId_ );
1047  summary.fedReadoutMode( readout_mode );
1048  summary.commissioningInfo( daq1, daq2 );
1049 
1050  if ( summary.isSet() && once_ ) {
1051  if ( edm::isDebugEnabled() ) {
1052  std::stringstream ss;
1053  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1054  << " EventSummary built from FED DAQ registers:"
1055  << std::endl << summary;
1056  LogTrace("SiStripRawToDigi") << ss.str();
1057  }
1058  once_ = false;
1059  }
1060  }
1061  }
1062 
1063  void RawToDigiUnpacker::dumpRawData( uint16_t fed_id, const FEDRawData& buffer, std::stringstream& ss ) {
1064 
1065  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1066  << " Dump of buffer for FED id " << fed_id << std::endl
1067  << " Buffer contains " << buffer.size()
1068  << " bytes (NB: payload is byte-swapped)" << std::endl;
1069  uint32_t* buffer_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( buffer.data() ) );
1070  unsigned int empty = 0;
1071 
1072  if ( 0 ) {
1073 
1074  ss << "Byte-> 4 5 6 7 0 1 2 3\n";
1075  for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
1076  unsigned int temp0 = buffer_u32[i*2] & sistrip::invalid32_;
1077  unsigned int temp1 = buffer_u32[i*2+1] & sistrip::invalid32_;
1078  if ( !temp0 && !temp1 ) { empty++; }
1079  else {
1080  if ( empty ) {
1081  ss << " [ empty words ]" << std::endl;
1082  empty = 0;
1083  }
1084  ss << std::dec
1085  << std::setfill(' ') << std::setw(6) << i*8 << ": "
1086  << std::hex
1087  << std::setfill('0') << std::setw(8) << temp0
1088  << std::setfill('0') << std::setw(8) << temp1
1089  << std::dec
1090  << std::endl;
1091  }
1092  }
1093 
1094  } else {
1095 
1096  ss << " Byte | <---- Byte order ----< | Byte" << std::endl;
1097  ss << " cntr | 7 6 5 4 3 2 1 0 | cntr" << std::endl;
1098  for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
1099  //if ( i>=20 && ((i+4)<(buffer.size()/8)) ) { continue; }
1100  uint16_t tmp0 = buffer.data()[i*8+0] & 0xFF;
1101  uint16_t tmp1 = buffer.data()[i*8+1] & 0xFF;
1102  uint16_t tmp2 = buffer.data()[i*8+2] & 0xFF;
1103  uint16_t tmp3 = buffer.data()[i*8+3] & 0xFF;
1104  uint16_t tmp4 = buffer.data()[i*8+4] & 0xFF;
1105  uint16_t tmp5 = buffer.data()[i*8+5] & 0xFF;
1106  uint16_t tmp6 = buffer.data()[i*8+6] & 0xFF;
1107  uint16_t tmp7 = buffer.data()[i*8+7] & 0xFF;
1108 // if ( !tmp0 && !tmp1 && !tmp2 && !tmp3 &&
1109 // !tmp4 && !tmp5 && !tmp6 && !tmp7 ) { empty++; }
1110 // else {
1111 // if ( empty ) {
1112 // ss << " [.."
1113 // << std::dec << std::setfill('.') << std::setw(4) << empty
1114 // << " null words....]" << std::endl;
1115 // empty = 0;
1116 // }
1117  ss << std::dec
1118  << std::setfill(' ') << std::setw(6) << i*8+7 << " : "
1119  << std::hex
1120  << std::setfill('0') << std::setw(2) << tmp7 << " "
1121  << std::setfill('0') << std::setw(2) << tmp6 << " "
1122  << std::setfill('0') << std::setw(2) << tmp5 << " "
1123  << std::setfill('0') << std::setw(2) << tmp4 << " "
1124  << std::setfill('0') << std::setw(2) << tmp3 << " "
1125  << std::setfill('0') << std::setw(2) << tmp2 << " "
1126  << std::setfill('0') << std::setw(2) << tmp1 << " "
1127  << std::setfill('0') << std::setw(2) << tmp0
1128  << std::dec
1129  << " :" << std::setfill(' ') << std::setw(6) << i*8
1130  << std::endl;
1131 // }
1132  }
1133 
1134  }
1135  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1136  << " End of FED buffer";
1137  }
1138 
1140 
1141  method_name = "sistrip::RawToDigiUnpacker::" + method_name;
1142  try {
1143  throw; // rethrow caught exception to be dealt with below
1144  }
1145  catch ( const cms::Exception& e ) {
1146  //throw e; // rethrow cms::Exception to be caught by framework
1147  }
1148  catch ( const std::exception& e ) {
1149  if ( edm::isDebugEnabled() ) {
1150  std::stringstream ss;
1151  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1152  << " Caught std::exception!" << std::endl;
1153  if ( extra_info != "" ) {
1154  ss << " Information: " << extra_info << std::endl;
1155  }
1156  ss << " Caught std::exception in ["
1157  << method_name << "] with message:" << std::endl
1158  << e.what();
1160  }
1161  //throw cms::Exception(sistrip::mlRawToDigi_) << ss.str();
1162  }
1163  catch (...) {
1164  if ( edm::isDebugEnabled() ) {
1165  std::stringstream ss;
1166  ss << "[sistrip::RawToDigiUnpacker::" << __func__ << "]"
1167  << " Caught unknown exception!" << std::endl;
1168  if ( extra_info != "" ) {
1169  ss << " Information: " << extra_info << std::endl;
1170  }
1171  ss << "Caught unknown exception in ["
1172  << method_name << "]" << std::endl;
1174  }
1175  //throw cms::Exception(sistrip::mlRawToDigi_) << ss.str();
1176  }
1177  }
1178 
1179 }
1180 
1181 /*
1182 
1183 Some info on FED buffer 32-bit word swapping.
1184 
1185 Table below indicates if data are swapped relative to the "old"
1186 VME format (as originally expected by the Fed9UEvent class).
1187 
1188 -------------------------------------------
1189 | SWAPPED? | DATA FORMAT |
1190 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1191 | | VME | SLINK | VME | SLINK |
1192 -------------------------------------------
1193 | DAQ HEADER | N | Y | Y | Y |
1194 | TRK HEADER | N | Y | N | N |
1195 | PAYLOAD | N | Y | N | N |
1196 | DAQ TRAILER | N | Y | Y | Y |
1197 -------------------------------------------
1198 
1199 So, in code, we check in code order of bytes in DAQ header/trailer only:
1200 -> if "old_vme_header", then old format read out via vme, so do nothing.
1201 -> else if "old_slink_header", then data may be wrapped, so check additionally the TRK header:
1202 ---> if "old_slink_payload", then old format read out via slink, so swap all data;
1203 ---> else if "new_buffer_format", then new format, handled internally by Fed9UEvent, so do nothing.
1204 
1205 Pattern matching to find DAQ and tracker headers, and DAQ trailer:
1206 DAQ header, 4 bits, in field |BOE_1| with value 0x5
1207 DAQ trailer, 4 bits, in field |EOE_1| with value 0xA
1208 TRK header, 8 bits, in field |Hdr format| with value 0xED or 0xC5
1209 
1210 -------------------------------------------------------------------------------------------
1211 | SWAPPED? | DATA FORMAT |
1212 | (wrt "OLD") | OLD (0xED) | NEW (0xC5) |
1213 | | VME | SLINK | VME | SLINK |
1214 -------------------------------------------------------------------------------------------
1215 | DAQ HEADER | ........5....... | 5............... | 5............... | 5............... |
1216 | TRK HEADER | ........ED...... | ED.............. | ........C5...... | ........C5...... |
1217 | PAYLOAD | ..........EA.... | ..EA............ | ..EA............ | ............EA.. |
1218 | DAQ TRAILER | ........A....... | A............... | A............... | A............... |
1219 -------------------------------------------------------------------------------------------
1220 
1221 */
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_