CMS 3D CMS Logo

SiStripRawToDigiUnpacker Class Reference

Takes collection of FEDRawData as input and creates digis. More...

#include <EventFilter/SiStripRawToDigi/interface/SiStripRawToDigiUnpacker.h>

List of all members.

Public Types

typedef edm::DetSetVector
< SiStripDigi
Digis
typedef edm::DetSetVector
< SiStripRawDigi
RawDigis

Public Member Functions

void createDigis (const SiStripFedCabling &, const FEDRawDataCollection &, SiStripEventSummary &, RawDigis &scope_mode, RawDigis &virgin_raw, RawDigis &proc_raw, Digis &zero_suppr)
 Creates digis.
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.
void quiet (bool)
 SiStripRawToDigiUnpacker (int16_t appended_bytes, int16_t fed_buffer_dump_freq, int16_t fed_event_dump_freq, int16_t trigger_fed_id, bool using_fed_key)
void triggerFed (const FEDRawDataCollection &, SiStripEventSummary &, const uint32_t &event)
 ~SiStripRawToDigiUnpacker ()

Private Member Functions

void cleanupWorkVectors ()
void dumpRawData (uint16_t fed_id, const FEDRawData &, std::stringstream &)
 Dumps raw data to stdout (NB: payload is byte-swapped, headers/trailer are not).
sistrip::FedBufferFormat fedBufferFormat (const uint16_t &register_value)
sistrip::FedReadoutMode fedReadoutMode (const uint16_t &register_value)
void handleException (std::string method_name, std::string extra_info="")
 Catches all possible exceptions and rethrows them as cms::Exception's that are caught by the framework.
void physicalOrder (uint16_t &readout_order, uint16_t &physical_order)
void readoutOrder (uint16_t &physical_order, uint16_t &readout_order)
 SiStripRawToDigiUnpacker ()
 Private default constructor.
void updateEventSummary (const Fed9U::Fed9UEvent *const, SiStripEventSummary &)

Private Attributes

uint32_t event_
int16_t fedBufferDumpFreq_
Fed9U::Fed9UEvent * fedEvent_
int16_t fedEventDumpFreq_
bool first_
int16_t headerBytes_
bool once_
std::vector< SiStripRawDigiproc_work_digis_
std::vector
< DetSet_SiStripDig_registry
proc_work_registry_
bool quiet_
std::vector< SiStripRawDigiscope_work_digis_
std::vector
< DetSet_SiStripDig_registry
scope_work_registry_
int16_t triggerFedId_
bool useFedKey_
std::vector< SiStripRawDigivirgin_work_digis_
std::vector
< DetSet_SiStripDig_registry
virgin_work_registry_
std::vector< SiStripDigizs_work_digis_
std::vector
< DetSet_SiStripDig_registry
zs_work_registry_

Friends

class SiStripRawToClustersLazyUnpacker
class SiStripRawToClustersModule

Classes

struct  DetSet_SiStripDig_registry


Detailed Description

Takes collection of FEDRawData as input and creates digis.

Definition at line 29 of file SiStripRawToDigiUnpacker.h.


Member Typedef Documentation

typedef edm::DetSetVector<SiStripDigi> SiStripRawToDigiUnpacker::Digis

Definition at line 45 of file SiStripRawToDigiUnpacker.h.

typedef edm::DetSetVector<SiStripRawDigi> SiStripRawToDigiUnpacker::RawDigis

Definition at line 46 of file SiStripRawToDigiUnpacker.h.


Constructor & Destructor Documentation

SiStripRawToDigiUnpacker::SiStripRawToDigiUnpacker ( int16_t  appended_bytes,
int16_t  fed_buffer_dump_freq,
int16_t  fed_event_dump_freq,
int16_t  trigger_fed_id,
bool  using_fed_key 
)

Definition at line 28 of file SiStripRawToDigiUnpacker.cc.

References fedEvent_, edm::isDebugEnabled(), LogTrace, and sistrip::mlRawToDigi_.

00032                                                                           :
00033   headerBytes_( appended_bytes ),
00034   fedBufferDumpFreq_( fed_buffer_dump_freq ),
00035   fedEventDumpFreq_( fed_event_dump_freq ),
00036   triggerFedId_( trigger_fed_id ),
00037   useFedKey_( using_fed_key ),
00038   fedEvent_(0),
00039   event_(0),
00040   once_(true),
00041   first_(true),
00042   quiet_(true)
00043 {
00044   if ( edm::isDebugEnabled() ) {
00045     LogTrace(mlRawToDigi_)
00046       << "[SiStripRawToDigiUnpacker::"<<__func__<<"]"
00047       <<" Constructing object...";
00048   }
00049   fedEvent_ = new Fed9U::Fed9UEvent();
00050 }

SiStripRawToDigiUnpacker::~SiStripRawToDigiUnpacker (  ) 

Definition at line 54 of file SiStripRawToDigiUnpacker.cc.

References fedEvent_, edm::isDebugEnabled(), LogTrace, and sistrip::mlRawToDigi_.

00054                                                     {
00055   if ( edm::isDebugEnabled() ) {
00056     LogTrace(mlRawToDigi_)
00057       << "[SiStripRawToDigiUnpacker::"<<__func__<<"]"
00058       << " Destructing object...";
00059   }
00060   if ( fedEvent_ ) { delete fedEvent_; }
00061 }

SiStripRawToDigiUnpacker::SiStripRawToDigiUnpacker (  )  [private]

Private default constructor.


Member Function Documentation

void SiStripRawToDigiUnpacker::cleanupWorkVectors (  )  [private]

Definition at line 595 of file SiStripRawToDigiUnpacker.cc.

References proc_work_digis_, proc_work_registry_, scope_work_digis_, scope_work_registry_, virgin_work_digis_, virgin_work_registry_, zs_work_digis_, and zs_work_registry_.

Referenced by createDigis().

00595                                                   {
00596   // Clear working areas and registries
00597   zs_work_registry_.clear();      zs_work_digis_.clear();
00598   virgin_work_registry_.clear();  virgin_work_digis_.clear();
00599   proc_work_registry_.clear();    proc_work_digis_.clear();
00600   scope_work_registry_.clear();   scope_work_digis_.clear();
00601 }

void SiStripRawToDigiUnpacker::createDigis ( const SiStripFedCabling cabling,
const FEDRawDataCollection buffers,
SiStripEventSummary summary,
RawDigis scope_mode,
RawDigis virgin_raw,
RawDigis proc_raw,
Digis zero_suppr 
)

Creates digis.

Definition at line 65 of file SiStripRawToDigiUnpacker.cc.

References addr, sistrip::APV_LATENCY, cleanupWorkVectors(), SiStripFedCabling::connections(), edmNew::copy(), FEDRawData::data(), dumpRawData(), end, event_, Exception, sistrip::FED_CABLING, sistrip::FED_PROC_RAW, sistrip::FED_SCOPE_MODE, sistrip::FED_VIRGIN_RAW, sistrip::FED_ZERO_SUPPR, sistrip::FED_ZERO_SUPPR_LITE, fedBufferDumpFreq_, FEDRawDataCollection::FEDData(), fedEvent_, fedEventDumpFreq_, fedReadoutMode(), SiStripFedCabling::feds(), sistrip::FINE_DELAY, first_, FEDNumbering::getSiStripFEDIds(), handleException(), i, iggi_31X_cfg::input, sistrip::invalid32_, sistrip::invalid_, edm::isDebugEnabled(), SiStripEventSummary::isSet(), it, getDQMSummary::key, len, locateStartOfFedBuffer(), LogTrace, min, sistrip::mlRawToDigi_, mode, n, output(), proc_work_digis_, proc_work_registry_, quiet_, readoutOrder(), SiStripEventSummary::runType(), scope_work_digis_, scope_work_registry_, FEDRawData::size(), python::multivaluedict::sort(), ss, strip(), edm::DetSetVector< T >::swap(), triggerFedId_, sistrip::UNDEFINED_FED_READOUT_MODE, useFedKey_, SiStripEventSummary::valid(), virgin_work_digis_, virgin_work_registry_, width, zs_work_digis_, and zs_work_registry_.

Referenced by SiStripRawToDigiModule::produce().

00071                                                                 {
00072   // Clear working areas and registries
00073   cleanupWorkVectors();
00074   
00075   // Check if FEDs found in cabling map and event data
00076   if ( edm::isDebugEnabled() ) {
00077     if ( cabling.feds().empty() ) {
00078       edm::LogWarning(mlRawToDigi_)
00079         << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00080         << " No FEDs found in cabling map!";
00081       // Check which FED ids have non-zero size buffers
00082       std::pair<int,int> fed_range = FEDNumbering::getSiStripFEDIds();
00083       std::vector<uint16_t> feds;
00084       for ( uint16_t ifed = static_cast<uint16_t>(fed_range.first);
00085             ifed < static_cast<uint16_t>(fed_range.second); ifed++ ) {
00086         if ( ifed != triggerFedId_ && 
00087              buffers.FEDData( static_cast<int>(ifed) ).size() ) {
00088           feds.push_back(ifed);
00089         }
00090       }
00091       LogTrace(mlRawToDigi_)
00092         << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00093         << " Found " << feds.size() << " FED buffers with non-zero size!";
00094     }
00095   }
00096 
00097   // Flag for EventSummary update using DAQ register  
00098   bool first_fed = true;
00099   
00100   // Retrieve FED ids from cabling map and iterate through 
00101   std::vector<uint16_t>::const_iterator ifed = cabling.feds().begin();
00102   for ( ; ifed != cabling.feds().end(); ifed++ ) {
00103 
00104     //if ( *ifed == triggerFedId_ ) { continue; }
00105     
00106     // Retrieve FED raw data for given FED 
00107     const FEDRawData& input = buffers.FEDData( static_cast<int>(*ifed) );
00108     
00109     // Some debug on FED buffer size
00110     if ( edm::isDebugEnabled() ) {
00111       if ( first_ && input.data() ) {
00112         std::stringstream ss;
00113         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00114            << " Found FED id " 
00115            << std::setw(4) << std::setfill(' ') << *ifed 
00116            << " in FEDRawDataCollection"
00117            << " with non-zero pointer 0x" 
00118            << std::hex
00119            << std::setw(8) << std::setfill('0') 
00120            << reinterpret_cast<uint32_t*>( const_cast<uint8_t*>(input.data()))
00121            << std::dec
00122            << " and size " 
00123            << std::setw(5) << std::setfill(' ') << input.size()
00124            << " chars";
00125         LogTrace(mlRawToDigi_) << ss.str();
00126       } 
00127     }
00128     
00129     // Dump of FEDRawData to stdout
00130     if ( edm::isDebugEnabled() ) {
00131       if ( fedBufferDumpFreq_ && !(event_%fedBufferDumpFreq_) ) {
00132         std::stringstream ss;
00133         dumpRawData( *ifed, input, ss );
00134         edm::LogVerbatim(mlRawToDigi_) << ss.str();
00135       }
00136     }
00137     
00138     // Handle 32-bit swapped data (and locate start of FED buffer within raw data)
00139     FEDRawData output; 
00140     locateStartOfFedBuffer( *ifed, input, output );
00141     
00142     // Recast data to suit Fed9UEvent
00143     Fed9U::u32* data_u32 = reinterpret_cast<Fed9U::u32*>( const_cast<unsigned char*>( output.data() ) );
00144     Fed9U::u32  size_u32 = static_cast<Fed9U::u32>( output.size() / 4 ); 
00145 
00146     // Check on FEDRawData pointer
00147     if ( !data_u32 ) {
00148       if ( edm::isDebugEnabled() ) {
00149         edm::LogWarning(mlRawToDigi_)
00150           << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00151           << " NULL pointer to FEDRawData for FED id " << *ifed;
00152       }
00153       continue;
00154     }   
00155     
00156     // Check on FEDRawData size
00157     if ( !size_u32 ) {
00158       if ( edm::isDebugEnabled() ) {
00159         edm::LogWarning(mlRawToDigi_)
00160           << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00161           << " FEDRawData has zero size for FED id " << *ifed;
00162       }
00163       continue;
00164     }
00165     
00166     // Initialise Fed9UEvent using present FED buffer
00167     try {
00168       fedEvent_->Init( data_u32, 0, size_u32 ); 
00169       //fedEvent_->checkEvent();
00170     } catch(...) { 
00171       handleException( __func__, "Problem when creating Fed9UEvent" ); 
00172       continue;
00173     } 
00174    
00175     // Check if EventSummary ("trigger FED info") needs updating
00176     if ( first_fed ) {
00177       //updateEventSummary( fedEvent_, summary ); //@@ temporarily suppress statements from SiStripEventSummary!
00178       first_fed = false;
00179     }
00180     
00181     // Check to see if EventSummary info is set
00182     if ( edm::isDebugEnabled() ) {
00183       if ( !quiet_ && !summary.isSet() ) {
00184         std::stringstream ss;
00185         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00186            << " EventSummary is not set correctly!"
00187            << " Missing information from both \"trigger FED\" and \"DAQ registers\"!";
00188         edm::LogWarning(mlRawToDigi_) << ss.str();
00189       }
00190     }
00191     
00192     // Check to see if event is to be analyzed according to EventSummary
00193     if ( !summary.valid() ) { 
00194       if ( edm::isDebugEnabled() ) {
00195         LogTrace(mlRawToDigi_)
00196           << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00197           << " EventSummary is not valid: skipping...";
00198       }
00199       continue; 
00200     }
00201     
00202     // Retrive readout mode
00203     sistrip::FedReadoutMode mode = sistrip::UNDEFINED_FED_READOUT_MODE;
00204     try {
00205       mode = fedReadoutMode( static_cast<unsigned int>( fedEvent_->getSpecialTrackerEventType() ) );
00206     } catch(...) { handleException( __func__, "Problem extracting readout mode from Fed9UEvent" ); } 
00207     
00208     // Retrive run type
00209     sistrip::RunType runType_ = summary.runType();
00210     if( runType_ == sistrip::APV_LATENCY || runType_ == sistrip::FINE_DELAY ) { useFedKey_ = false; } //@@ force!
00211      
00212     // Dump of FED buffer
00213     if ( edm::isDebugEnabled() ) {
00214       if ( fedEventDumpFreq_ && !(event_%fedEventDumpFreq_) ) {
00215         std::stringstream ss;
00216         fedEvent_->dump( ss );
00217         edm::LogVerbatim(mlRawToDigi_) << ss.str();
00218       }
00219     }
00220     
00221     // Iterate through FED channels, extract payload and create Digis
00222     const std::vector<FedChannelConnection>& conns = cabling.connections(*ifed);
00223     std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
00224     for ( ; iconn != conns.end(); iconn++ ) {
00225 
00226       // Check if FedId is valid
00227       if ( !iconn->isConnected() ) { continue; }
00228       
00229       // Check DetId is valid (if to be used as key)
00230       if ( !useFedKey_ && ( !iconn->detId() || iconn->detId() == sistrip::invalid32_ ) ) { continue; }
00231 
00232       // Retrieve channel using Fed9UAddress 
00233       uint16_t channel = iconn->fedCh();
00234       uint16_t iunit = channel / 12;
00235       uint16_t ichan = channel % 12;
00236       uint16_t chan  = 12 * iunit + ichan;
00237       try {
00238         Fed9U::Fed9UAddress addr;
00239         addr.setFedChannel( static_cast<unsigned char>( channel ) );
00240         iunit = addr.getFedFeUnit();
00241         ichan = addr.getFeUnitChannel();
00242         chan  = 12*( addr.getFedFeUnit() ) + addr.getFeUnitChannel();
00243       } catch(...) { 
00244         handleException( __func__, "Problem using Fed9UAddress" ); 
00245       } 
00246       
00247       // Determine whether FED key is inferred from cabling or channel loop
00248       uint32_t fed_key = 0;
00249       if ( summary.runType() == sistrip::FED_CABLING ) {
00250         fed_key = ( ( *ifed & sistrip::invalid_ ) << 16 ) | ( chan & sistrip::invalid_ );
00251       } else { 
00252         fed_key = ( ( iconn->fedId() & sistrip::invalid_ ) << 16 ) | ( iconn->fedCh() & sistrip::invalid_ );
00253       }
00254       
00255       // Determine whether DetId or FED key should be used to index digi containers
00256       uint32_t key = ( useFedKey_ || mode == sistrip::FED_SCOPE_MODE ) ? fed_key : iconn->detId();
00257       
00258       // Determine APV std::pair number (needed only when using DetId)
00259       uint16_t ipair = ( useFedKey_ || mode == sistrip::FED_SCOPE_MODE ) ? 0 : iconn->apvPairNumber();
00260 
00261       if ( mode == sistrip::FED_SCOPE_MODE ) {
00262         
00263         std::vector<uint16_t> samples; 
00264         try { 
00265           samples = fedEvent_->feUnit( iunit ).channel( ichan ).getSamples();
00266         } catch(...) { 
00267           std::stringstream sss;
00268           sss << "Problem accessing SCOPE_MODE data for FedId/FeUnit/FeChan: " 
00269               << *ifed << "/" << iunit << "/" << ichan;
00270           handleException( __func__, sss.str() ); 
00271         } 
00272         
00273         if ( !samples.empty() ) { 
00274           DetSet_SiStripDig_registry regItem(key, 0, scope_work_digis_.size(), samples.size());
00275           for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
00276             scope_work_digis_.push_back(  SiStripRawDigi( samples[i] ) );
00277           }
00278           scope_work_registry_.push_back( regItem );
00279         }
00280         
00281       } else if ( mode == sistrip::FED_VIRGIN_RAW ) {
00282 
00283         std::vector<uint16_t> samples; 
00284         try {
00285           samples = fedEvent_->channel( iunit, ichan ).getSamples();
00286         } catch(...) { 
00287           std::stringstream sss;
00288           sss << "Problem accessing VIRGIN_RAW data for FED id/ch: " 
00289               << *ifed << "/" << ichan;
00290           handleException( __func__, sss.str() ); 
00291         } 
00292         
00293         if ( !samples.empty() ) { 
00294           DetSet_SiStripDig_registry regItem(key, 256*ipair, virgin_work_digis_.size(), samples.size());
00295           uint16_t physical;
00296           uint16_t readout; 
00297           for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
00298             physical = i%128;
00299             readoutOrder( physical, readout );                 // convert index from physical to readout order
00300             (i/128) ? readout=readout*2+1 : readout=readout*2; // un-multiplex data
00301             virgin_work_digis_.push_back(  SiStripRawDigi( samples[readout] ) );
00302           }
00303           virgin_work_registry_.push_back( regItem );
00304         }
00305 
00306       } else if ( mode == sistrip::FED_PROC_RAW ) {
00307 
00308         std::vector<uint16_t> samples; 
00309         try {
00310           samples = fedEvent_->channel( iunit, ichan ).getSamples();
00311         } catch(...) { 
00312           std::stringstream sss;
00313           sss << "Problem accessing PROC_RAW data for FED id/ch: " 
00314               << *ifed << "/" << ichan;
00315           handleException( __func__, sss.str() ); 
00316         } 
00317 
00318         if ( !samples.empty() ) { 
00319           DetSet_SiStripDig_registry regItem(key, 256*ipair, proc_work_digis_.size(), samples.size());
00320           for ( uint16_t i = 0, n = samples.size(); i < n; i++ ) {
00321             proc_work_digis_.push_back(  SiStripRawDigi( samples[i] ) );
00322           }
00323           proc_work_registry_.push_back( regItem );
00324         }
00325 
00326       } else if ( ( mode == sistrip::FED_ZERO_SUPPR ) || 
00327                   ( mode == sistrip::FED_ZERO_SUPPR_LITE ) ) { 
00328 
00329         DetSet_SiStripDig_registry regItem(key, 0, zs_work_digis_.size(), 0);
00330 
00331         int fed9uIterOffset = (mode == sistrip::FED_ZERO_SUPPR ? 7 : 2); // offset to start decoding from
00332         try{ 
00333           bool corrupt = false;
00334 #ifdef USE_PATCH_TO_CATCH_CORRUPT_FED_DATA
00335           int16_t last_strip = -1;
00336           uint16_t strips = useFedKey_ ? 256 : 256 * iconn->nApvPairs();
00337 #endif
00338           Fed9U::Fed9UEventIterator fed_iter = const_cast<Fed9U::Fed9UEventChannel&>(fedEvent_->channel( iunit, ichan )).getIterator();
00339           Fed9U::Fed9UEventIterator i = fed_iter + fed9uIterOffset; 
00340           while ( i.size() > 0 && !corrupt ) {
00341             unsigned char first_strip = *i++; // first strip of cluster
00342             unsigned char width = *i++;       // cluster width in strips 
00343             uint16_t istr = 0; 
00344             while ( istr < width && !corrupt ) {
00345               uint16_t strip = ipair*256 + first_strip + istr;
00346 #ifdef USE_PATCH_TO_CATCH_CORRUPT_FED_DATA
00347               if ( !( strip < strips && strip > last_strip ) ) { // check for corrupt FED data
00348                 //              if ( edm::isDebugEnabled() ) {
00349                 //                std::stringstream ss;
00350                 //                ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00351                 //                   << " Corrupt FED data found for FED id " << *ifed
00352                 //                   << " and channel " << iconn->fedCh()
00353                 //                   << "!  present strip: " << strip
00354                 //                   << "  last strip: " << last_strip
00355                 //                   << "  detector strips: " << strips;
00356                 //                edm::LogWarning(mlRawToDigi_) << ss.str();
00357                 //              }
00358                 corrupt = true; 
00359                 break;
00360               } 
00361               last_strip = strip;
00362 #endif
00363               zs_work_digis_.push_back( SiStripDigi( strip, static_cast<uint16_t>(*i) ) );
00364               *i++; // Iterate to next sample
00365               istr++;
00366             }
00367           }
00368         } catch(...) { 
00369           std::stringstream sss;
00370           sss << "Problem accessing ZERO_SUPPR data for FED id/ch: " 
00371               << *ifed << "/" << ichan;
00372           handleException( __func__, sss.str() ); 
00373         } 
00374 
00375         regItem.length = zs_work_digis_.size() - regItem.index;
00376         if (regItem.length > 0) {
00377             regItem.first = zs_work_digis_[regItem.index].strip();
00378             zs_work_registry_.push_back(regItem);
00379         }
00380       } else { // Unknown readout mode! => assume scope mode
00381         
00382         if ( edm::isDebugEnabled() ) {
00383           std::stringstream ss;
00384           ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00385              << " Unknown FED readout mode (" << mode
00386              << ")! Assuming SCOPE MODE..."; 
00387           edm::LogWarning(mlRawToDigi_) << ss.str();
00388         }
00389         
00390         std::vector<uint16_t> samples; 
00391         try {
00392           samples = fedEvent_->feUnit( iunit ).channel( ichan ).getSamples();
00393         } catch(...) { 
00394           std::stringstream sss;
00395           sss << "Problem accessing data (UNKNOWN FED READOUT MODE) for FED id/ch: " 
00396               << *ifed << "/" << ichan;
00397           handleException( __func__, sss.str() ); 
00398         } 
00399 
00400         if ( !samples.empty() ) { 
00401           DetSet_SiStripDig_registry regItem(key, 0, scope_work_digis_.size(), samples.size());
00402           for ( uint16_t i = 0, n= samples.size(); i < n; i++ ) {
00403             scope_work_digis_.push_back(  SiStripRawDigi( samples[i] ) );
00404           }
00405           scope_work_registry_.push_back( regItem );
00406 
00407           if ( edm::isDebugEnabled() ) {
00408             std::stringstream ss;
00409             ss << "Extracted " << samples.size() 
00410                << " SCOPE MODE digis (samples[0] = " << samples[0] 
00411                << ") from FED id/ch " 
00412                << iconn->fedId() << "/" << iconn->fedCh();
00413             //LogTrace(mlRawToDigi_) << ss.str();
00414           }
00415         } else {
00416           if ( edm::isDebugEnabled() ) {
00417             edm::LogWarning(mlRawToDigi_)
00418               << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00419               << " No SM digis found!"; 
00420           }
00421         }
00422 
00423       }
00424 
00425     } // channel loop
00426   } // fed loop
00427 
00428   if ( ! zs_work_registry_.empty() ) {
00429         std::sort( zs_work_registry_.begin(), zs_work_registry_.end() );
00430         std::vector< edm::DetSet<SiStripDigi> > sorted_and_merged;
00431         sorted_and_merged.reserve(  std::min(zs_work_registry_.size(), size_t(17000)) );
00432 
00433         bool errorInData = false;
00434         std::vector<DetSet_SiStripDig_registry>::iterator it = zs_work_registry_.begin(), it2 = it+1, end = zs_work_registry_.end();
00435         while (it < end) {
00436             sorted_and_merged.push_back( edm::DetSet<SiStripDigi>(it->detid) );
00437             std::vector<SiStripDigi> & digis = sorted_and_merged.back().data;
00438             // first count how many digis we have
00439             size_t len = it->length;
00440             for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) { len += it2->length; }
00441             // reserve memory 
00442             digis.reserve(len);
00443             // push them in
00444             for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
00445                 digis.insert( digis.end(), & zs_work_digis_[it2->index], & zs_work_digis_[it2->index + it2->length] );
00446             }
00447             it = it2;
00448         }
00449         // check sorting
00450         if (!__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end() )) {
00451             // this is an error in the code: i DID sort it already!
00452             throw cms::Exception("Bug Found") << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ <<"\n";
00453         }
00454         std::vector< edm::DetSet<SiStripDigi> >::iterator iii = sorted_and_merged.begin();
00455         std::vector< edm::DetSet<SiStripDigi> >::iterator jjj = sorted_and_merged.end(); 
00456         for ( ; iii != jjj; ++iii ) { 
00457             if ( ! __gnu_cxx::is_sorted( iii->begin(), iii->end() ) ) {
00458                 // this might be an error in the data, if the raws from one FED are not sorted
00459                 iii->clear(); errorInData = true;
00460             }
00461         }
00462         if (errorInData) { edm::LogWarning("CorruptData") << "Some modules contained corrupted ZS raw data, and have been skipped in unpacking\n"; }
00463         // make output DetSetVector
00464         edm::DetSetVector<SiStripDigi> zero_suppr_dsv( sorted_and_merged, true ); 
00465         zero_suppr.swap( zero_suppr_dsv );
00466   } 
00467 
00468   // Populate final DetSetVector container with VR data 
00469   if ( !virgin_work_registry_.empty() ) {
00470       std::sort( virgin_work_registry_.begin(), virgin_work_registry_.end() );
00471 
00472       std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
00473       sorted_and_merged.reserve( std::min(virgin_work_registry_.size(), size_t(17000)) );
00474 
00475       bool errorInData = false;
00476       std::vector<DetSet_SiStripDig_registry>::iterator it = virgin_work_registry_.begin(), it2, end = virgin_work_registry_.end();
00477       while (it < end) {
00478           sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
00479           std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
00480 
00481           bool isDetOk = true; 
00482           // first count how many digis we have
00483           int maxFirstStrip = it->first;
00484           for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) { 
00485               if (it2->first <= maxFirstStrip) { isDetOk = false; continue; } // duplicated APV or data corruption. DO NOT 'break' here!
00486               maxFirstStrip = it2->first;                           
00487           }
00488           if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
00489           // make room for 256 * (max_apv_pair + 1) Raw Digis
00490           digis.resize(maxFirstStrip + 256);
00491           // push them in
00492           for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
00493               if (it->length != 256)  { isDetOk = false; continue; } // data corruption. DO NOT 'break' here
00494               std::copy( & virgin_work_digis_[it2->index], & virgin_work_digis_[it2->index + it2->length], & digis[it2->first] );
00495           }
00496           if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
00497           it = it2;
00498       }
00499       if (errorInData) { edm::LogWarning("CorruptData") << "Some modules contained corrupted virgin raw data, and have been skipped in unpacking\n"; }
00500       // check sorting
00501       if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end()  ) ) {
00502           // this is an error in the code: i DID sort it already!
00503           throw cms::Exception("Bug Found") << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ <<"\n";
00504       }
00505       // make output DetSetVector
00506       edm::DetSetVector<SiStripRawDigi> virgin_raw_dsv( sorted_and_merged, true ); 
00507       virgin_raw.swap( virgin_raw_dsv );
00508   } 
00509   
00510   // Populate final DetSetVector container with PR data 
00511   if ( !proc_work_registry_.empty() ) {
00512       std::sort( proc_work_registry_.begin(), proc_work_registry_.end() );
00513 
00514       std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
00515       sorted_and_merged.reserve( std::min(proc_work_registry_.size(), size_t(17000)) );
00516 
00517       bool errorInData = false;
00518       std::vector<DetSet_SiStripDig_registry>::iterator it = proc_work_registry_.begin(), it2 = it+1, end = proc_work_registry_.end();
00519       while (it < end) {
00520           sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
00521           std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
00522           bool isDetOk = true; 
00523           // first count how many digis we have
00524           int maxFirstStrip = it->first;
00525           for (it2 = it+1; (it2 != end) && (it2->detid == it->detid); ++it2) { 
00526               if (it2->first <= maxFirstStrip) { isDetOk = false; continue; } // duplicated APV or data corruption. DO NOT 'break' here!
00527               maxFirstStrip = it2->first; 
00528           }
00529           if (!isDetOk) { errorInData = true; it = it2; continue; } // skip whole det
00530           // make room for 256 * (max_apv_pair + 1) Raw Digis
00531           digis.resize(maxFirstStrip + 256);
00532           // push them in
00533           for (it2 = it+0; (it2 != end) && (it2->detid == it->detid); ++it2) {
00534               if (it->length != 256)  { isDetOk = false; continue; } // data corruption. DO NOT 'break' here
00535               std::copy( & proc_work_digis_[it2->index], & proc_work_digis_[it2->index + it2->length], & digis[it->first] );
00536           }
00537           if (!isDetOk) { errorInData = true; digis.clear(); it = it2; continue; } // skip whole det
00538           it = it2;
00539       }
00540       if (errorInData) { edm::LogWarning("CorruptData") << "Some modules contained corrupted processed raw data, and have been skipped in unpacking\n"; }
00541       // check sorting
00542       if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end()  ) ) {
00543           // this is an error in the code: i DID sort it already!
00544           throw cms::Exception("Bug Found") << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ <<"\n";
00545       }
00546       // make output DetSetVector
00547       edm::DetSetVector<SiStripRawDigi> proc_raw_dsv( sorted_and_merged, true ); 
00548       proc_raw.swap( proc_raw_dsv );
00549   } 
00550   
00551   // Populate final DetSetVector container with SM data 
00552   if ( !scope_work_registry_.empty() ) {
00553       std::sort( scope_work_registry_.begin(), scope_work_registry_.end() );
00554 
00555       std::vector< edm::DetSet<SiStripRawDigi> > sorted_and_merged;
00556       sorted_and_merged.reserve( scope_work_registry_.size() );
00557 
00558       bool errorInData = false;
00559       std::vector<DetSet_SiStripDig_registry>::iterator it, end;
00560       for (it = scope_work_registry_.begin(), end = scope_work_registry_.end() ; it != end; ++it) {
00561           sorted_and_merged.push_back( edm::DetSet<SiStripRawDigi>(it->detid) );
00562           std::vector<SiStripRawDigi> & digis = sorted_and_merged.back().data;
00563           digis.insert( digis.end(), & scope_work_digis_[it->index], & scope_work_digis_[it->index + it->length] );
00564 
00565           if ( (it +1 != end) && (it->detid == (it+1)->detid) ) {
00566               errorInData = true; 
00567               // let's skip *all* the detsets for that key, as we don't know which is the correct one!
00568               do { ++it; } while ( ( it+1 != end) && (it->detid == (it+1)->detid) );
00569               //throw cms::Exception("Duplicate Key") << "Duplicate key " << it->detid << " found in scope mode.\n"; 
00570           }
00571       }
00572       if (errorInData) { edm::LogWarning("CorruptData") << "Some fed keys contained corrupted scope mode data, and have been skipped in unpacking\n"; }
00573       // check sorting
00574       if ( !__gnu_cxx::is_sorted( sorted_and_merged.begin(), sorted_and_merged.end()  ) ) {
00575           // this is an error in the code: i DID sort it already!
00576           throw cms::Exception("Bug Found") << "Container must be already sorted!\nat " << __FILE__ << ", line " << __LINE__ <<"\n";
00577       }
00578       // make output DetSetVector
00579       edm::DetSetVector<SiStripRawDigi> scope_mode_dsv( sorted_and_merged, true ); 
00580       scope_mode.swap( scope_mode_dsv );
00581 
00582   } 
00583 
00584   // Increment event counter
00585   event_++;
00586   
00587   if ( first_ ) { first_ = false; }
00588 
00589   // final cleanup, just in case
00590   cleanupWorkVectors();
00591 }

void SiStripRawToDigiUnpacker::dumpRawData ( uint16_t  fed_id,
const FEDRawData buffer,
std::stringstream &  ss 
) [private]

Dumps raw data to stdout (NB: payload is byte-swapped, headers/trailer are not).

Definition at line 958 of file SiStripRawToDigiUnpacker.cc.

References FEDRawData::data(), empty, lat::endl(), i, sistrip::invalid32_, FEDRawData::size(), tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, and tmp7.

Referenced by createDigis().

00960                                                                   {
00961   ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00962      << " Dump of buffer for FED id " <<  fed_id << std::endl
00963      << " Buffer contains " << buffer.size()
00964      << " bytes (NB: payload is byte-swapped)" << std::endl;
00965   uint32_t* buffer_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( buffer.data() ) );
00966   unsigned int empty = 0;
00967 
00968   if ( 0 ) { 
00969 
00970     ss << "Byte->   4 5 6 7 0 1 2 3\n";
00971     for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
00972       unsigned int temp0 = buffer_u32[i*2] & sistrip::invalid32_;
00973       unsigned int temp1 = buffer_u32[i*2+1] & sistrip::invalid32_;
00974       if ( !temp0 && !temp1 ) { empty++; }
00975       else { 
00976         if ( empty ) { 
00977           ss << "        [ empty  words ]" << std::endl; 
00978           empty = 0; 
00979         }
00980         ss << std::dec
00981            << std::setfill(' ')  << std::setw(6) << i*8 << ": " 
00982            << std::hex 
00983            << std::setfill('0') << std::setw(8) << temp0 
00984            << std::setfill('0') << std::setw(8) << temp1 
00985            << std::dec
00986            << std::endl;
00987       }
00988     }
00989 
00990   } else {
00991     
00992     ss << "  Byte |  <---- Byte order ----<  | Byte" << std::endl;
00993     ss << "  cntr |  7  6  5  4  3  2  1  0  | cntr" << std::endl;
00994     for ( uint32_t i = 0; i < buffer.size()/8; i++ ) {
00995       //if ( i>=20 && ((i+4)<(buffer.size()/8)) ) { continue; }
00996       uint16_t tmp0 = buffer.data()[i*8+0] & 0xFF;
00997       uint16_t tmp1 = buffer.data()[i*8+1] & 0xFF;
00998       uint16_t tmp2 = buffer.data()[i*8+2] & 0xFF;
00999       uint16_t tmp3 = buffer.data()[i*8+3] & 0xFF;
01000       uint16_t tmp4 = buffer.data()[i*8+4] & 0xFF;
01001       uint16_t tmp5 = buffer.data()[i*8+5] & 0xFF;
01002       uint16_t tmp6 = buffer.data()[i*8+6] & 0xFF;
01003       uint16_t tmp7 = buffer.data()[i*8+7] & 0xFF;
01004       if ( !tmp0 && !tmp1 && !tmp2 && !tmp3 &&
01005            !tmp4 && !tmp5 && !tmp6 && !tmp7 ) { empty++; }
01006       else { 
01007         if ( empty ) { 
01008           ss << "         [.." 
01009              << std::dec << std::setfill('.') << std::setw(4) << empty 
01010              << " null words....]" << std::endl; 
01011           empty = 0; 
01012         }
01013         ss << std::dec
01014            << std::setfill(' ')  << std::setw(6) << i*8+7 << " : " 
01015            << std::hex 
01016            << std::setfill('0') << std::setw(2) << tmp7 << " " 
01017            << std::setfill('0') << std::setw(2) << tmp6 << " " 
01018            << std::setfill('0') << std::setw(2) << tmp5 << " " 
01019            << std::setfill('0') << std::setw(2) << tmp4 << " " 
01020            << std::setfill('0') << std::setw(2) << tmp3 << " " 
01021            << std::setfill('0') << std::setw(2) << tmp2 << " " 
01022            << std::setfill('0') << std::setw(2) << tmp1 << " " 
01023            << std::setfill('0') << std::setw(2) << tmp0 
01024            << std::dec
01025            << " :" << std::setfill(' ')  << std::setw(6) << i*8 
01026            << std::endl;
01027       }
01028     }
01029 
01030   }
01031   ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
01032      << " End of FED buffer";
01033 }

sistrip::FedBufferFormat SiStripRawToDigiUnpacker::fedBufferFormat ( const uint16_t &  register_value  )  [inline, private]

Definition at line 143 of file SiStripRawToDigiUnpacker.h.

References sistrip::APV_ERROR_FORMAT, sistrip::FULL_DEBUG_FORMAT, sistrip::UNDEFINED_FED_BUFFER_FORMAT, and sistrip::UNKNOWN_FED_BUFFER_FORMAT.

00143                                                                                                  {
00144   if      ( (register_value&0xF) == 0x1 ) { return sistrip::FULL_DEBUG_FORMAT; }
00145   else if ( (register_value&0xF) == 0x2 ) { return sistrip::APV_ERROR_FORMAT; }
00146   else if ( (register_value&0xF) == 0x0 ) { return sistrip::UNDEFINED_FED_BUFFER_FORMAT; }
00147   else                                    { return sistrip::UNKNOWN_FED_BUFFER_FORMAT; }
00148 }

sistrip::FedReadoutMode SiStripRawToDigiUnpacker::fedReadoutMode ( const uint16_t &  register_value  )  [inline, private]

Definition at line 150 of file SiStripRawToDigiUnpacker.h.

References sistrip::FED_PROC_RAW, sistrip::FED_SCOPE_MODE, sistrip::FED_VIRGIN_RAW, sistrip::FED_ZERO_SUPPR, sistrip::FED_ZERO_SUPPR_LITE, and sistrip::UNKNOWN_FED_READOUT_MODE.

Referenced by createDigis(), and SiStripRawToClustersLazyUnpacker::fill().

00150                                                                                                {
00151   if      ( ((register_value>>1)&0x7) == 0x0 ) { return sistrip::FED_SCOPE_MODE; }
00152   else if ( ((register_value>>1)&0x7) == 0x1 ) { return sistrip::FED_VIRGIN_RAW; }
00153   else if ( ((register_value>>1)&0x7) == 0x3 ) { return sistrip::FED_PROC_RAW; }
00154   else if ( ((register_value>>1)&0x7) == 0x5 ) { return sistrip::FED_ZERO_SUPPR; }
00155   else if ( ((register_value>>1)&0x7) == 0x6 ) { return sistrip::FED_ZERO_SUPPR_LITE; }
00156   else                                         { return sistrip::UNKNOWN_FED_READOUT_MODE; }
00157 }

void SiStripRawToDigiUnpacker::handleException ( std::string  method_name,
std::string  extra_info = "" 
) [private]

Catches all possible exceptions and rethrows them as cms::Exception's that are caught by the framework.

Definition at line 1037 of file SiStripRawToDigiUnpacker.cc.

References e, lat::endl(), exception, edm::isDebugEnabled(), sistrip::mlRawToDigi_, and ss.

Referenced by createDigis(), and SiStripRawToClustersLazyUnpacker::fill().

01038                                                                        { // throw (cms::Exception) {
01039   method_name = "SiStripRawToDigiUnpacker::" + method_name;
01040   try {
01041     throw; // rethrow caught exception to be dealt with below
01042   } 
01043   catch ( const cms::Exception& e ) { 
01044     //throw e; // rethrow cms::Exception to be caught by framework
01045   }
01046   catch ( const ICUtils::ICException& e ) {
01047     if ( edm::isDebugEnabled() ) {
01048       std::stringstream ss;
01049       ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
01050          << " Caught ICUtils::ICException exception!" << std::endl;
01051       if ( extra_info != "" ) { 
01052         ss << " Information: " << extra_info << std::endl;
01053       }
01054       ss << " Caught ICUtils::ICException in ["
01055          << method_name << "] with message:" << std::endl 
01056          << e.what();
01057       edm::LogWarning(mlRawToDigi_) << ss.str();
01058     }
01059     //throw cms::Exception(mlRawToDigi_) << ss.str();
01060   }
01061   catch ( const std::exception& e ) {
01062     if ( edm::isDebugEnabled() ) {
01063       std::stringstream ss;
01064       ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
01065          << " Caught std::exception!" << std::endl;
01066       if ( extra_info != "" ) { 
01067         ss << " Information: " << extra_info << std::endl;
01068       }
01069       ss << " Caught std::exception in ["
01070          << method_name << "] with message:" << std::endl 
01071          << e.what();
01072       edm::LogWarning(mlRawToDigi_) << ss.str();
01073     }
01074     //throw cms::Exception(mlRawToDigi_) << ss.str();
01075   }
01076   catch (...) {
01077     if ( edm::isDebugEnabled() ) {
01078       std::stringstream ss;
01079       ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
01080          << " Caught unknown exception!" << std::endl;
01081       if ( extra_info != "" ) { 
01082         ss << " Information: " << extra_info << std::endl;
01083       }
01084       ss << "Caught unknown exception in ["
01085          << method_name << "]" << std::endl;
01086       edm::LogWarning(mlRawToDigi_) << ss.str();
01087     }
01088     //throw cms::Exception(mlRawToDigi_) << ss.str();
01089   }
01090 }

void SiStripRawToDigiUnpacker::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.

Pattern matches to find DAQ header: DAQ header, 4 MSB, BEO1, with value 0x5 DAQ header, 4 LSB, Hx$$, with value 0x8 (or 0x0) DAQ trailer, 4 MSB, EOE, with value 0xA

Definition at line 731 of file SiStripRawToDigiUnpacker.cc.

References FEDRawData::data(), lat::endl(), headerBytes_, edm::isDebugEnabled(), iter, LogTrace, sistrip::mlRawToDigi_, offset, FEDRawData::resize(), FEDRawData::size(), and ss.

Referenced by SiStripFEDRawDataCheck::analyze(), createDigis(), and SiStripRawToClustersLazyUnpacker::fill().

00733                                                                             {
00734   
00735   // Check size of input buffer
00736   if ( input.size() < 24 ) { 
00737     output.resize( input.size() ); // Return UNadjusted buffer start position and size
00738     memcpy( output.data(), input.data(), input.size() );
00739     if ( edm::isDebugEnabled() ) {
00740       std::stringstream ss; 
00741       ss << "[SiStripRawToDigiUnpacker::" << __func__ << "] "
00742          << "Input FEDRawData with FED id " << fed_id 
00743          << " has size " << input.size();
00744       edm::LogWarning(mlRawToDigi_) << ss.str();
00745     }
00746     return;
00747   } 
00748   
00749   // Iterator through buffer to find DAQ header 
00750   bool found = false;
00751   uint16_t ichar = 0;
00752   while ( ichar < input.size()-16 && !found ) {
00753     uint16_t offset = headerBytes_ < 0 ? ichar : headerBytes_; // Negative value means use "search mode" to find DAQ header
00754     uint32_t* input_u32   = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + offset );
00755     uint32_t* fed_trailer = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) + input.size() - 8 );
00756 
00757     /*
00758 
00759       Some info on FED buffer 32-bit word swapping. Table below
00760       indicates if data are swapped relative to "old" VME format (as
00761       orignally expected by Fed9UEvent)
00762 
00763       | SWAPPED?    |         DATA FORMAT       |
00764       | (wrt "OLD") | OLD (0xED)  | NEW (0xC5)  |
00765       |             | VME | SLINK | VME | SLINK |
00766       -------------------------------------------
00767       | DAQ HEADER  |  N  |   Y   |  Y  |   Y   |
00768       | TRK HEADER  |  N  |   Y   |  N  |   N   |
00769       | PAYLOAD     |  N  |   Y   |  N  |   N   |
00770       | DAQ TRAILER |  N  |   Y   |  Y  |   Y   |
00771 
00772       So, in code, we check in code order of bytes in DAQ header/trailer only:
00773       -> if "old_vme_header",           then old format read out via vme, so do nothing.
00774       -> else if "old_slink_header",    then data mapy be wwapped, so check additionally the TRK header:
00775       --> if "old_slink_payload",       then old format read out via slink, so swap all data;
00776       --> else if "new_buffer_format",  then new format, handled internally by Fed9UEvent, so do nothing.
00777 
00778      */
00779     
00780     bool old_vme_header = 
00781       ( input_u32[0]    & 0xF0000000 ) == 0x50000000 &&
00782       ( fed_trailer[0]  & 0xF0000000 ) == 0xA0000000 && 
00783       ( (fed_trailer[0] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
00784     
00785     bool old_slink_header = 
00786       ( input_u32[1]    & 0xF0000000 ) == 0x50000000 &&
00787       ( fed_trailer[1]  & 0xF0000000 ) == 0xA0000000 &&
00788       ( (fed_trailer[1] & 0x00FFFFFF)*0x8 ) == (input.size() - offset);
00789 
00790     bool old_slink_payload = ( input_u32[3] & 0xFF000000 ) == 0xED000000;
00791     
00792     bool new_buffer_format = ( input_u32[2] & 0xFF000000 ) == 0xC5000000;
00793     
00794     if ( old_vme_header )  {
00795       
00796       // Found DAQ header at byte position 'offset'
00797       found = true;
00798       output.resize( input.size()-offset );
00799       memcpy( output.data(),         // target
00800               input.data()+offset,   // source
00801               input.size()-offset ); // nbytes
00802       if ( headerBytes_ < 0 ) {
00803         if ( edm::isDebugEnabled() ) {
00804           std::stringstream ss;
00805           ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]" 
00806              << " Buffer for FED id " << fed_id 
00807              << " has been found at byte position " << offset
00808              << " with a size of " << input.size()-offset << " bytes."
00809              << " Adjust the configurable 'AppendedBytes' to " << offset;
00810           LogTrace(mlRawToDigi_) << ss.str();
00811         }
00812       }
00813       
00814     } else if ( old_slink_header ) {
00815       
00816       if ( old_slink_payload ) {
00817       
00818         // Found DAQ header (with MSB and LSB 32-bit words swapped) at byte position 'offset' 
00819         found = true;
00820         output.resize( input.size()-offset );
00821         uint32_t* output_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( output.data() ) );
00822         uint16_t iter = offset; 
00823         while ( iter < output.size() / sizeof(uint32_t) ) {
00824           output_u32[iter] = input_u32[iter+1];
00825           output_u32[iter+1] = input_u32[iter];
00826           iter+=2;
00827         }
00828         if ( headerBytes_ < 0 ) {
00829           if ( edm::isDebugEnabled() ) {
00830             std::stringstream ss;
00831             ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]" 
00832                << " Buffer (with MSB and LSB 32-bit words swapped) for FED id " << fed_id 
00833                << " has been found at byte position " << offset
00834                << " with a size of " << output.size() << " bytes."
00835                << " Adjust the configurable 'AppendedBytes' to " << offset;
00836             LogTrace(mlRawToDigi_) << ss.str();
00837           }
00838         }
00839 
00840       } else if ( new_buffer_format ) {
00841         
00842         // Found DAQ header at byte position 'offset'
00843         found = true;
00844         output.resize( input.size()-offset );
00845         memcpy( output.data(),         // target
00846                 input.data()+offset,   // source
00847                 input.size()-offset ); // nbytes
00848         if ( headerBytes_ < 0 ) {
00849           if ( edm::isDebugEnabled() ) {
00850             std::stringstream ss;
00851             ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]" 
00852                << " Buffer for FED id " << fed_id 
00853                << " has been found at byte position " << offset
00854                << " with a size of " << input.size()-offset << " bytes."
00855                << " Adjust the configurable 'AppendedBytes' to " << offset;
00856             LogTrace(mlRawToDigi_) << ss.str();
00857           }
00858         }
00859         
00860       } else { headerBytes_ < 0 ? found = false : found = true; }
00861     } else { headerBytes_ < 0 ? found = false : found = true; }
00862     ichar++;
00863   }      
00864   
00865   // Check size of output buffer
00866   if ( output.size() == 0 ) { 
00867     
00868     // Did not find DAQ header after search => return buffer with NULL size
00869     output.resize( 0 ); //@@ NULL SIZE!
00870     memcpy( output.data(), input.data(), 0 ); //@@ NULL SIZE!
00871     if ( edm::isDebugEnabled() ) {
00872       std::stringstream ss;
00873       if ( headerBytes_ < 0 ) {
00874         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00875            << " DAQ header not found within buffer for FED id: " << fed_id;
00876       } else {
00877         uint32_t* input_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( input.data() ) );
00878         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00879            << " DAQ header not found at expected location for FED id: " << fed_id << std::endl
00880            << " First 64-bit word of buffer is 0x"
00881            << std::hex 
00882            << std::setfill('0') << std::setw(8) << input_u32[0] 
00883            << std::setfill('0') << std::setw(8) << input_u32[1] 
00884            << std::dec << std::endl
00885            << " Adjust 'AppendedBytes' configurable to '-1' to activate 'search mode'";
00886       }
00887       edm::LogWarning(mlRawToDigi_) << ss.str();
00888     }
00889     
00890   } else if ( output.size() < 24 ) { // Found DAQ header after search, but too few words
00891     
00892     if ( edm::isDebugEnabled() ) {
00893       std::stringstream ss; 
00894       ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00895          << " Unexpected buffer size! FEDRawData with FED id " << fed_id 
00896          << " has size " << output.size();
00897       edm::LogWarning(mlRawToDigi_) << ss.str();
00898     }
00899 
00900   } 
00901   
00902 }

void SiStripRawToDigiUnpacker::physicalOrder ( uint16_t &  readout_order,
uint16_t &  physical_order 
) [inline, private]

Definition at line 136 of file SiStripRawToDigiUnpacker.h.

00137                                                                          {
00138   physical_order = ( (32 * (readout_order%4)) +
00139                      (8 * static_cast<uint16_t>(static_cast<float>(readout_order)/4.0)) -
00140                      (31 * static_cast<uint16_t>(static_cast<float>(readout_order)/16.0)) );
00141 }

void SiStripRawToDigiUnpacker::quiet ( bool  quiet  )  [inline]

Definition at line 159 of file SiStripRawToDigiUnpacker.h.

References quiet_.

00159 { quiet_ = quiet; }

void SiStripRawToDigiUnpacker::readoutOrder ( uint16_t &  physical_order,
uint16_t &  readout_order 
) [inline, private]

Definition at line 129 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis().

00130                                                                        {
00131   readout_order = ( 4*((static_cast<uint16_t>((static_cast<float>(physical_order)/8.0)))%4) +
00132                     static_cast<uint16_t>(static_cast<float>(physical_order)/32.0) +
00133                     16*(physical_order%8) );
00134 }

void SiStripRawToDigiUnpacker::triggerFed ( const FEDRawDataCollection buffers,
SiStripEventSummary summary,
const uint32_t &  event 
)

Definition at line 605 of file SiStripRawToDigiUnpacker.cc.

References SiStripEventSummary::bx(), SiStripEventSummary::commissioningInfo(), fedt_struct::conscheck, FEDRawData::data(), lat::endl(), SiStripEventSummary::event(), FEDRawDataCollection::FEDData(), TFHeaderDescription::getBunchCrossing(), TFHeaderDescription::getFedEventNumber(), header, edm::isDebugEnabled(), SiStripEventSummary::isSet(), FEDNumbering::lastFEDId(), LogTrace, sistrip::mlRawToDigi_, once_, FEDRawData::size(), ss, pyDBSRunClass::temp, SiStripEventSummary::triggerFed(), and triggerFedId_.

Referenced by SiStripRawToDigiModule::produce().

00607                                                                    {
00608   
00609   // Pointer to data (recast as 32-bit words) and number of 32-bit words
00610   uint32_t* data_u32 = 0;
00611   uint32_t  size_u32 = 0;
00612   
00613   if ( triggerFedId_ < 0 ) { // Search mode
00614     
00615     uint16_t ifed = 0;
00616     while ( triggerFedId_ < 0 && 
00617             ifed < 1 + FEDNumbering::lastFEDId() ) {
00618       const FEDRawData& trigger_fed = buffers.FEDData( ifed );
00619       if ( trigger_fed.data() && trigger_fed.size() ) {
00620         uint8_t*  temp = const_cast<uint8_t*>( trigger_fed.data() );
00621         data_u32 = reinterpret_cast<uint32_t*>( temp ) + sizeof(fedh_t)/sizeof(uint32_t) + 1;
00622         size_u32 = trigger_fed.size()/sizeof(uint32_t) - sizeof(fedh_t)/sizeof(uint32_t) - 1;
00623         fedt_t* fed_trailer = reinterpret_cast<fedt_t*>( temp + trigger_fed.size() - sizeof(fedt_t) );
00624         if ( fed_trailer->conscheck == 0xDEADFACE ) { 
00625           triggerFedId_ = ifed; 
00626           if ( edm::isDebugEnabled() ) {
00627             std::stringstream ss;
00628             ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00629                << " Search mode for 'trigger FED' activated!"
00630                << " Found 'trigger FED' info with id " << triggerFedId_;
00631             LogTrace(mlRawToDigi_) << ss.str();
00632           }
00633         }
00634       }
00635       ifed++;
00636     }
00637     if ( triggerFedId_ < 0 ) {
00638       triggerFedId_ = 0;
00639       if ( edm::isDebugEnabled() ) {
00640         std::stringstream ss;
00641         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00642            << " Search mode for 'trigger FED' activated!"
00643            << " 'Trigger FED' info not found!";
00644         edm::LogWarning(mlRawToDigi_) << ss.str();
00645       }
00646     }
00647     
00648   } else if ( triggerFedId_ > 0 ) { // "Trigger FED" id given in .cfg file
00649     
00650     const FEDRawData& trigger_fed = buffers.FEDData( triggerFedId_ );
00651     if ( trigger_fed.data() && trigger_fed.size() ) {
00652       uint8_t*  temp = const_cast<uint8_t*>( trigger_fed.data() );
00653       data_u32 = reinterpret_cast<uint32_t*>( temp ) + sizeof(fedh_t)/sizeof(uint32_t) + 1;
00654       size_u32 = trigger_fed.size()/sizeof(uint32_t) - sizeof(fedh_t)/sizeof(uint32_t) - 1;
00655       fedt_t* fed_trailer = reinterpret_cast<fedt_t*>( temp + trigger_fed.size() - sizeof(fedt_t) );
00656       if ( fed_trailer->conscheck != 0xDEADFACE ) { 
00657         if ( edm::isDebugEnabled() ) {
00658           edm::LogWarning(mlRawToDigi_) 
00659             << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00660             << " Unexpected stamp found in DAQ trailer (ie, not 0xDEADFACE)!"
00661             << " Buffer appears not to contain 'trigger FED' data!";
00662         }
00663         triggerFedId_ = 0; 
00664       }
00665     }
00666       
00667   } else { 
00668     triggerFedId_ = 0; 
00669     data_u32 = 0;
00670     size_u32 = 0;
00671   }
00672   
00673   // Populate summary object with commissioning information
00674   if ( triggerFedId_ > 0 ) { 
00675 
00676     // Some checks
00677     if ( !data_u32 ) {
00678       if ( edm::isDebugEnabled() ) {
00679         std::stringstream ss;
00680         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00681            << " NULL pointer to 'trigger FED' data";
00682         edm::LogWarning(mlRawToDigi_) << ss.str();
00683       }
00684       return;
00685     } 
00686     if ( size_u32 < sizeof(TFHeaderDescription)/sizeof(uint32_t) ) {
00687       if ( edm::isDebugEnabled() ) {
00688         std::stringstream ss;
00689         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00690            << " Unexpected 'Trigger FED' data size [32-bit words]: " << size_u32;
00691         edm::LogWarning(mlRawToDigi_) << ss.str();
00692       }
00693       return;
00694     }
00695     
00696     // Write event-specific data to event
00697     TFHeaderDescription* header = (TFHeaderDescription*) data_u32;
00698     summary.event( static_cast<uint32_t>( header->getFedEventNumber()) );
00699     summary.bx( static_cast<uint32_t>( header->getBunchCrossing()) );
00700     
00701     // Write commissioning information to event 
00702     uint32_t hsize = sizeof(TFHeaderDescription)/sizeof(uint32_t);
00703     uint32_t* head = &data_u32[hsize];
00704     summary.commissioningInfo( head, event );
00705     summary.triggerFed( triggerFedId_ );
00706     
00707   }
00708 
00709   // Some debug
00710   if ( summary.isSet() && once_ ) {
00711     if ( edm::isDebugEnabled() ) {
00712       std::stringstream ss;
00713       ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00714          << " EventSummary built from \"trigger FED\":" 
00715          << std::endl << summary;
00716       LogTrace(mlRawToDigi_) << ss.str();
00717     }
00718     once_ = false;
00719   }
00720   
00721 }

void SiStripRawToDigiUnpacker::updateEventSummary ( const Fed9U::Fed9UEvent * const  fed,
SiStripEventSummary summary 
) [private]

Definition at line 906 of file SiStripRawToDigiUnpacker.cc.

References SiStripEventSummary::commissioningInfo(), lat::endl(), SiStripEventSummary::fedReadoutMode(), sistrip::invalid32_, sistrip::invalid_, edm::isDebugEnabled(), SiStripEventSummary::isSet(), LogTrace, sistrip::mlRawToDigi_, once_, ss, SiStripEventSummary::triggerFed(), and triggerFedId_.

00907                                                                                   {
00908   
00909   // Retrieve contents of DAQ registers
00910   //@@ uint16_t trigger_type = sistrip::invalid_;
00911   uint16_t readout_mode = sistrip::invalid_;
00912   uint32_t daq1 = sistrip::invalid32_;
00913   uint32_t daq2 = sistrip::invalid32_;
00914   
00915   if ( fed ) {
00916     //@@ trigger_type = static_cast<uint16_t>( fed->?????() ); 
00917     readout_mode = static_cast<uint16_t>( fed->getEventType() ); 
00918     daq1 = static_cast<uint32_t>( fed->getDaqRegister() ); 
00919     daq2 = static_cast<uint32_t>( fed->getDaqRegisterTwo() ); 
00920   }
00921   
00922   // If FED DAQ registers contain info, update (and possibly overwrite) EventSummary 
00923   if ( daq1 != 0 && daq1 != sistrip::invalid32_ ) {
00924     
00925     summary.triggerFed( triggerFedId_ );
00926     summary.fedReadoutMode( readout_mode );
00927     summary.commissioningInfo( daq1, daq2 );
00928     
00929     if ( summary.isSet() && once_ ) {
00930       if ( edm::isDebugEnabled() ) {
00931         std::stringstream ss;
00932         ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00933            << " EventSummary built from FED DAQ registers:"
00934            << std::endl << summary;
00935         LogTrace(mlRawToDigi_) << ss.str();
00936       }
00937       once_ = false;
00938     }
00939   }
00940   //@@ below needed to set run type in PHYSICS 
00941 //   } else if ( trigger_type == ??? ) { 
00942 //     summary.runType( sistrip::PHYSICS );
00943 //     std::stringstream ss;
00944 //     ss << "[SiStripRawToDigiUnpacker::" << __func__ << "]"
00945 //        << " EventSummary built from 'Event Type' field in DAQ header:"
00946 //        << std::endl << summary;
00947 //     LogTrace(mlRawToDigi_) << ss.str();
00948 //     once_ = false;
00949 //   }
00950   
00951 }


Friends And Related Function Documentation

friend class SiStripRawToClustersLazyUnpacker [friend]

Definition at line 32 of file SiStripRawToDigiUnpacker.h.

friend class SiStripRawToClustersModule [friend]

Definition at line 31 of file SiStripRawToDigiUnpacker.h.


Member Data Documentation

uint32_t SiStripRawToDigiUnpacker::event_ [private]

Definition at line 98 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis().

int16_t SiStripRawToDigiUnpacker::fedBufferDumpFreq_ [private]

Definition at line 91 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis().

Fed9U::Fed9UEvent* SiStripRawToDigiUnpacker::fedEvent_ [private]

Definition at line 96 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis(), SiStripRawToDigiUnpacker(), and ~SiStripRawToDigiUnpacker().

int16_t SiStripRawToDigiUnpacker::fedEventDumpFreq_ [private]

Definition at line 92 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis().

bool SiStripRawToDigiUnpacker::first_ [private]

Definition at line 102 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis().

int16_t SiStripRawToDigiUnpacker::headerBytes_ [private]

Definition at line 90 of file SiStripRawToDigiUnpacker.h.

Referenced by locateStartOfFedBuffer().

bool SiStripRawToDigiUnpacker::once_ [private]

Definition at line 100 of file SiStripRawToDigiUnpacker.h.

Referenced by triggerFed(), and updateEventSummary().

std::vector<SiStripRawDigi> SiStripRawToDigiUnpacker::proc_work_digis_ [private]

Definition at line 123 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

std::vector<DetSet_SiStripDig_registry> SiStripRawToDigiUnpacker::proc_work_registry_ [private]

Definition at line 121 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

bool SiStripRawToDigiUnpacker::quiet_ [private]

Definition at line 104 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis(), and quiet().

std::vector<SiStripRawDigi> SiStripRawToDigiUnpacker::scope_work_digis_ [private]

Definition at line 123 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

std::vector<DetSet_SiStripDig_registry> SiStripRawToDigiUnpacker::scope_work_registry_ [private]

Definition at line 120 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

int16_t SiStripRawToDigiUnpacker::triggerFedId_ [private]

Definition at line 93 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis(), triggerFed(), and updateEventSummary().

bool SiStripRawToDigiUnpacker::useFedKey_ [private]

Definition at line 94 of file SiStripRawToDigiUnpacker.h.

Referenced by createDigis().

std::vector<SiStripRawDigi> SiStripRawToDigiUnpacker::virgin_work_digis_ [private]

Definition at line 123 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

std::vector<DetSet_SiStripDig_registry> SiStripRawToDigiUnpacker::virgin_work_registry_ [private]

Definition at line 119 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

std::vector<SiStripDigi> SiStripRawToDigiUnpacker::zs_work_digis_ [private]

Definition at line 122 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().

std::vector<DetSet_SiStripDig_registry> SiStripRawToDigiUnpacker::zs_work_registry_ [private]

Definition at line 118 of file SiStripRawToDigiUnpacker.h.

Referenced by cleanupWorkVectors(), and createDigis().


The documentation for this class was generated from the following files:
Generated on Tue Jun 9 18:32:32 2009 for CMSSW by  doxygen 1.5.4