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