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