CMS 3D CMS Logo

SiStripDigiToRaw.cc

Go to the documentation of this file.
00001 // Last commit: $Id: SiStripDigiToRaw.cc,v 1.27.2.3 2009/03/04 13:28:33 bainbrid Exp $
00002 
00003 #include "EventFilter/SiStripRawToDigi/interface/SiStripDigiToRaw.h"
00004 #include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
00005 #include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
00006 #include "DataFormats/FEDRawData/interface/FEDHeader.h"
00007 #include "DataFormats/FEDRawData/interface/FEDTrailer.h"
00008 #include "DataFormats/SiStripDigi/interface/SiStripDigi.h"
00009 #include "DataFormats/SiStripCommon/interface/SiStripConstants.h"
00010 #include "FWCore/Utilities/interface/CRC16.h"
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 #include "Fed9UUtils.hh"
00013 #include <iostream>
00014 #include <sstream>
00015 #include <vector>
00016 
00017 using namespace std;
00018 
00019 // -----------------------------------------------------------------------------
00021 SiStripDigiToRaw::SiStripDigiToRaw( std::string mode, 
00022                                     int16_t nbytes,
00023                                     bool use_fed_key ) : 
00024   readoutMode_(mode),
00025   nAppendedBytes_(nbytes),
00026   useFedKey_(use_fed_key)
00027 {
00028   if ( edm::isDebugEnabled() ) {
00029     LogDebug("DigiToRaw")
00030       << "[SiStripDigiToRaw::SiStripDigiToRaw]"
00031       << " Constructing object...";
00032   }
00033 }
00034 
00035 // -----------------------------------------------------------------------------
00037 SiStripDigiToRaw::~SiStripDigiToRaw() {
00038   if ( edm::isDebugEnabled() ) {
00039     LogDebug("DigiToRaw")
00040       << "[SiStripDigiToRaw::~SiStripDigiToRaw]"
00041       << " Destructing object...";
00042   }
00043 }
00044 
00045 // -----------------------------------------------------------------------------
00054 void SiStripDigiToRaw::createFedBuffers( edm::Event& event,
00055                                          edm::ESHandle<SiStripFedCabling>& cabling,
00056                                          edm::Handle< edm::DetSetVector<SiStripDigi> >& collection,
00057                                          auto_ptr<FEDRawDataCollection>& buffers ) {
00058 
00059   try {
00060     
00061     const uint16_t strips_per_fed = 96 * 256; 
00062     vector<uint16_t> raw_data; 
00063     raw_data.reserve(strips_per_fed);
00064     
00065     const vector<uint16_t>& fed_ids = cabling->feds();
00066     vector<uint16_t>::const_iterator ifed;
00067 
00068     for ( ifed = fed_ids.begin(); ifed != fed_ids.end(); ifed++ ) {
00069     
00070       raw_data.clear(); raw_data.resize( strips_per_fed, 0 );
00071       
00072       const std::vector<FedChannelConnection>& conns = cabling->connections(*ifed);
00073       std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
00074       for ( ; iconn != conns.end(); iconn++ ) {
00075 
00076         // Determine FED key from cabling
00077         uint32_t fed_key = ( ( iconn->fedId() & sistrip::invalid_ ) << 16 ) | ( iconn->fedCh() & sistrip::invalid_ );
00078         
00079         // Determine whether DetId or FED key should be used to index digi containers
00080         uint32_t key = ( useFedKey_ || readoutMode_ == "SCOPE_MODE" ) ? fed_key : iconn->detId();
00081 
00082         // Determine APV pair number (needed only when using DetId)
00083         uint16_t ipair = ( useFedKey_ || readoutMode_ == "SCOPE_MODE" ) ? 0 : iconn->apvPairNumber();
00084         
00085         // Check key is non-zero and valid
00086         if ( !key || ( key == sistrip::invalid32_ ) ) { continue; }
00087 
00088         // Find digis for DetID in collection
00089         vector< edm::DetSet<SiStripDigi> >::const_iterator digis = collection->find( key );
00090         if (digis == collection->end()) { continue; } 
00091 
00092         edm::DetSet<SiStripDigi>::const_iterator idigi;
00093         for ( idigi = digis->data.begin(); idigi != digis->data.end(); idigi++ ) {
00094           if ( (*idigi).strip() < ipair*256 ||
00095                (*idigi).strip() > ipair*256+255 ) { continue; }
00096           unsigned short strip = iconn->fedCh()*256 + (*idigi).strip() % 256;
00097 
00098           if ( strip >= strips_per_fed ) {
00099             if ( edm::isDebugEnabled() ) {
00100               std::stringstream ss;
00101               ss << "[SiStripDigiToRaw::createFedBuffers]"
00102                  << " strip >= strips_per_fed";
00103               edm::LogWarning("DigiToRaw") << ss.str();
00104             }
00105             continue;
00106           }
00107           
00108           // check if value already exists
00109           if ( edm::isDebugEnabled() ) {
00110             if ( raw_data[strip] && raw_data[strip] != (*idigi).adc() ) {
00111               std::stringstream ss; 
00112               ss << "[SiStripDigiToRaw::createFedBuffers]" 
00113                  << " Incompatible ADC values in buffer!"
00114                  << "  FedId/FedCh: " << *ifed << "/" << iconn->fedCh()
00115                  << "  DetStrip: " << (*idigi).strip() 
00116                  << "  FedStrip: " << strip
00117                  << "  AdcValue: " << (*idigi).adc()
00118                << "  RawData[" << strip << "]: " << raw_data[strip];
00119               edm::LogWarning("DigiToRaw") << ss.str();
00120             }
00121           }
00122 
00123           // Add digi to buffer
00124           raw_data[strip] = (*idigi).adc();
00125 
00126         }
00127         // if ((*idigi).strip() >= (ipair+1)*256) break;
00128       }
00129 
00130       // instantiate appropriate buffer creator object depending on readout mode
00131       Fed9U::Fed9UBufferCreator* creator = 0;
00132       if ( readoutMode_ == "SCOPE_MODE" ) {
00133         if ( edm::isDebugEnabled() ) {
00134           edm::LogWarning("DigiToRaw")
00135             << "[SiStripDigiToRaw::createFedBuffers]" 
00136             << " Fed9UBufferCreatorScopeMode not implemented yet!";
00137         }
00138       } else if ( readoutMode_ == "VIRGIN_RAW" ) {
00139         creator = new Fed9U::Fed9UBufferCreatorRaw();
00140       } else if ( readoutMode_ == "PROCESSED_RAW" ) {
00141         creator = new Fed9U::Fed9UBufferCreatorProcRaw();
00142       } else if ( readoutMode_ == "ZERO_SUPPRESSED" ) {
00143         creator = new Fed9U::Fed9UBufferCreatorZS();
00144       } else {
00145         if ( edm::isDebugEnabled() ) {
00146           edm::LogWarning("DigiToRaw")
00147             << "[SiStripDigiToRaw::createFedBuffers]" 
00148             << " UNKNOWN readout mode";
00149         }
00150       }
00151   
00152       if ( !creator ) { 
00153         if ( edm::isDebugEnabled() ) {
00154           edm::LogWarning("DigiToRaw")
00155             << "[SiStripDigiToRaw::createFedBuffers]" 
00156             << " NULL pointer to Fed9UBufferCreator";
00157         }
00158         return; 
00159       }
00160 
00161       // generate FED buffer and pass to Daq
00162       Fed9U::Fed9UBufferGenerator generator( creator );
00163       generator.generateFed9UBuffer( raw_data );
00164       //generator.setSlink64();
00165       FEDRawData& fedrawdata = buffers->FEDData( *ifed ); 
00166       // calculate size of FED buffer in units of bytes (unsigned char)
00167       int nbytes = generator.getBufferSize() * 4;
00168       // resize (public) "data_" member of struct FEDRawData
00169       fedrawdata.resize( nbytes );
00170       // copy FED buffer to struct FEDRawData using Fed9UBufferGenerator
00171       unsigned char* chars = const_cast<unsigned char*>( fedrawdata.data() );
00172       unsigned int* ints = reinterpret_cast<unsigned int*>( chars );
00173       generator.getBuffer( ints );
00174       if ( creator ) { delete creator; }
00175 
00176       //@@ THIS IS TEMPORARY FIX SO THAT DAQ WORKS. CONCERNS 32-BIT WORD SWAPPING
00177       FEDRawData temp( fedrawdata );
00178       uint32_t* temp_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( temp.data() ) );
00179       uint32_t* fedrawdata_u32 = reinterpret_cast<uint32_t*>( const_cast<unsigned char*>( fedrawdata.data() ) );
00180       uint16_t iter = 0; 
00181       while ( iter < fedrawdata.size() / sizeof(uint32_t) ) {
00182         fedrawdata_u32[iter] = temp_u32[iter+1];
00183         fedrawdata_u32[iter+1] = temp_u32[iter];
00184         iter+=2;
00185       }
00186       
00187       //@@ OVERWRITE HEADER AND TRAILER FOR DAQ
00188       FEDHeader header( fedrawdata.data() );
00189       header.set( fedrawdata.data(), 0, ( 0xFFFFFF && event.id().event() ), 0, *ifed ); //@@ LIMIT EV# to 24 BITS!!!
00190       
00191       FEDTrailer trailer( fedrawdata.data() + ( fedrawdata.size() - 8 )  );
00192       trailer.set( fedrawdata.data() + ( fedrawdata.size() - 8 ), 
00193                    fedrawdata.size() / 8,
00194                    evf::compute_crc( fedrawdata.data(), fedrawdata.size() ), 0, 0 );
00195       
00196     }
00197     
00198   }
00199   catch ( std::string err ) {
00200     if ( edm::isDebugEnabled() ) {
00201       edm::LogWarning("DigiToRaw") 
00202         << "SiStripDigiToRaw::createFedBuffers] " 
00203         << "Exception caught : " << err;
00204     }
00205   }
00206   
00207 }
00208 
00209 

Generated on Tue Jun 9 17:34:51 2009 for CMSSW by  doxygen 1.5.4