00001
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
00077 uint32_t fed_key = ( ( iconn->fedId() & sistrip::invalid_ ) << 16 ) | ( iconn->fedCh() & sistrip::invalid_ );
00078
00079
00080 uint32_t key = ( useFedKey_ || readoutMode_ == "SCOPE_MODE" ) ? fed_key : iconn->detId();
00081
00082
00083 uint16_t ipair = ( useFedKey_ || readoutMode_ == "SCOPE_MODE" ) ? 0 : iconn->apvPairNumber();
00084
00085
00086 if ( !key || ( key == sistrip::invalid32_ ) ) { continue; }
00087
00088
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
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
00124 raw_data[strip] = (*idigi).adc();
00125
00126 }
00127
00128 }
00129
00130
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
00162 Fed9U::Fed9UBufferGenerator generator( creator );
00163 generator.generateFed9UBuffer( raw_data );
00164
00165 FEDRawData& fedrawdata = buffers->FEDData( *ifed );
00166
00167 int nbytes = generator.getBufferSize() * 4;
00168
00169 fedrawdata.resize( nbytes );
00170
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
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
00188 FEDHeader header( fedrawdata.data() );
00189 header.set( fedrawdata.data(), 0, ( 0xFFFFFF && event.id().event() ), 0, *ifed );
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