00001
00002
00003
00004
00005
00006
00012 #include <unistd.h>
00013 #include <stdlib.h>
00014 #include <fstream>
00015 #include <vector>
00016 #include <iostream>
00017 #include <iomanip>
00018 #include <ctime>
00019 #include <limits>
00020
00021 #define CMSSW
00022
00023 #ifdef CMSSW //compilation within CMSSW framework
00024
00025 #include "EventFilter/EcalRawToDigi/interface/MatacqRawEvent.h"
00026 #include "FWCore/Utilities/interface/Exception.h"
00027
00028 static inline void throwExcept(const std::string& s){
00029 throw cms::Exception("Matacq") << s;
00030 }
00031
00032 #else //compilation outside CMSSW framework (e.g. online)
00033
00034 #include "MatacqRawEvent.h"
00035 #include <stdexcept>
00036 static inline void throwExcept(const std::string& s){
00037 throw std::runtime_error(s.c_str());
00038 }
00039
00040 #endif //CMSSW not defined
00041
00042 using namespace std;
00043
00044
00045 const MatacqRawEvent::field32spec_t MatacqRawEvent::fov32 = {0, 0x000000F0};
00046 const MatacqRawEvent::field32spec_t MatacqRawEvent::fedId32 = {0, 0x000FFF00};
00047 const MatacqRawEvent::field32spec_t MatacqRawEvent::bxId32 = {0, 0xFFF00000};
00048 const MatacqRawEvent::field32spec_t MatacqRawEvent::lv132 = {1, 0x00FFFFFF};
00049 const MatacqRawEvent::field32spec_t MatacqRawEvent::triggerType32 = {1, 0x0F000000};
00050 const MatacqRawEvent::field32spec_t MatacqRawEvent::boeType32 = {1, 0xF0000000};
00051 const MatacqRawEvent::field32spec_t MatacqRawEvent::dccLen32 = {2, 0x00FFFFFF};
00052 const MatacqRawEvent::field32spec_t MatacqRawEvent::dccErrors32 = {2, 0xFF000000};
00053 const MatacqRawEvent::field32spec_t MatacqRawEvent::runNum32 = {3, 0x00FFFFFF};
00054 const MatacqRawEvent::field32spec_t MatacqRawEvent::h1Marker32 = {3, 0x3F000000};
00055
00056
00057 const MatacqRawEvent::field32spec_t MatacqRawEvent::formatVersion32 = {4, 0x0000FFFF};
00058 const MatacqRawEvent::field32spec_t MatacqRawEvent::freqGHz32 = {4, 0x00FF0000};
00059 const MatacqRawEvent::field32spec_t MatacqRawEvent::channelCount32 = {4, 0xFF000000};
00060 const MatacqRawEvent::field32spec_t MatacqRawEvent::timeStamp32 = {5, 0xFFFFFFFF};
00061
00062 const MatacqRawEvent::field32spec_t MatacqRawEvent::tTrigPs32 = {6, 0xFFFFFFFF};
00063
00064 const MatacqRawEvent::field32spec_t MatacqRawEvent::orbitId32 = {7, 0xFFFFFFFF};
00065 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier0_32 = {8, 0x0000FFFF};
00066 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier1_32 = {8, 0xFFFF0000};
00067 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier2_32 = {9, 0x0000FFFF};
00068 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier3_32 = {9, 0xFFFF0000};
00069 const MatacqRawEvent::field32spec_t MatacqRawEvent::timeStampMicroSec32 = {10,0xFFFFFFFF};
00070 const MatacqRawEvent::field32spec_t MatacqRawEvent::trigRec32 = {11,0xFF000000};
00071 const MatacqRawEvent::field32spec_t MatacqRawEvent::postTrig32 = {11,0x0000FFFF};
00072 const MatacqRawEvent::field32spec_t MatacqRawEvent::laserPower32 = {12,0x000000FF};
00073 const MatacqRawEvent::field32spec_t MatacqRawEvent::attenuation_dB32 = {12,0x00000F00};
00074 const MatacqRawEvent::field32spec_t MatacqRawEvent::emtcPhase32 = {12,0x0000F000};
00075 const MatacqRawEvent::field32spec_t MatacqRawEvent::emtcDelay32 = {12,0xFFFF0000};
00076 const MatacqRawEvent::field32spec_t MatacqRawEvent::delayA32 = {13,0x0000FFFF};
00077 const MatacqRawEvent::field32spec_t MatacqRawEvent::dccId32 = {13,0x003F0000};
00078 const MatacqRawEvent::field32spec_t MatacqRawEvent::color32 = {13,0x00600000};
00079 const MatacqRawEvent::field32spec_t MatacqRawEvent::trigType32 = {13,0x07000000};
00080 const MatacqRawEvent::field32spec_t MatacqRawEvent::side32 = {13,0x08000000};
00081
00082 void MatacqRawEvent::setRawData(const unsigned char* pData, size_t maxSize){
00083 error = 0;
00084 unsigned char* begin = (unsigned char*) pData;
00085 int16le_t* begin16 = (int16le_t*) pData;
00086 uint32le_t* begin32 = (uint32le_t*) pData;
00087 int16le_t* pData16 = begin16;
00088 const int daqHeaderLen = 16;
00089 if(maxSize < 6*4){
00090 error = errorLength;
00091 return;
00092 }
00093 pData16 += daqHeaderLen/sizeof(pData16[0]);
00094
00095 daqHeader = begin32;
00096 matacqDataFormatVersion = read32(begin32, formatVersion32);
00097 freqGHz = read32(begin32, freqGHz32);
00098 channelCount = read32(begin32, channelCount32);
00099 timeStamp.tv_sec = read32(begin32, timeStamp32);
00100 int headerLen = 24;
00101 if(matacqDataFormatVersion>=2){
00102 tTrigPs = read32(begin32, tTrigPs32);
00103 headerLen += 4;
00104 } else{
00105 tTrigPs = numeric_limits<int>::max();
00106 }
00107
00108 if(matacqDataFormatVersion>=3){
00109 orbitId = read32(begin32, orbitId32);
00110 vernier[0] = read32(begin32, vernier0_32);
00111 vernier[1] = read32(begin32, vernier1_32);
00112 vernier[2] = read32(begin32, vernier2_32);
00113 vernier[3] = read32(begin32, vernier3_32);
00114 timeStamp.tv_usec = read32(begin32, timeStampMicroSec32);
00115 trigRec = read32(begin32, trigRec32, true);
00116 postTrig = read32(begin32, postTrig32);
00117 delayA = read32(begin32, delayA32, true);
00118 emtcDelay = read32(begin32, emtcDelay32, true);
00119 emtcPhase = read32(begin32, emtcPhase32, true);
00120 attenuation_dB = read32(begin32, attenuation_dB32, true);
00121 laserPower = read32(begin32, laserPower32, true);
00122 headerLen = 64;
00123 } else{
00124 orbitId = 0;
00125 vernier[0] = -1;
00126 vernier[1] = -1;
00127 vernier[2] = -1;
00128 vernier[3] = -1;
00129 trigRec = -1;
00130 postTrig = -1;
00131 delayA = -1;
00132 emtcDelay = -1;
00133 emtcPhase = -1;
00134 attenuation_dB = -1;
00135 laserPower = -1;
00136 }
00137
00138 const int nCh = getChannelCount();
00139 channelData.resize(nCh);
00140
00141 pData16 = (int16le_t*) (begin+headerLen);
00142
00143 for(int iCh=0; iCh<nCh; ++iCh){
00144 if((size_t)(pData16-begin16)>maxSize){
00145 throwExcept(string("Corrupted or truncated data"));
00146 }
00147
00148 channelData[iCh].chId = *(pData16++);
00149
00150 channelData[iCh].nSamples = *(pData16++);
00151
00152 channelData[iCh].samples = pData16;
00153
00154 if(channelData[iCh].nSamples<0){
00155 throwExcept(string("Corrupted or truncated data"));
00156 }
00157 pData16 += channelData[iCh].nSamples;
00158 }
00159
00160
00161
00162 int padding = (4-(pData16-begin16))%4;
00163 if(padding<0) padding+=4;
00164 pData16 += padding;
00165 if((size_t)(pData16-begin16)>maxSize){
00166 throwExcept(string("Corrupted or truncated data"));
00167 }
00168 uint32le_t* trailer32 = (uint32le_t*)(pData16);
00169 fragLen = trailer32[1]&0xFFFFFF;
00170
00171
00172
00173
00174
00175
00176 const int nHeaders = 3;
00177 if(fragLen!=read32(begin32,dccLen32)+nHeaders
00178 && fragLen != read32(begin32,dccLen32)){
00179
00180
00181 error |= errorLengthConsistency;
00182 }
00183
00184
00185 const int trailerLen = 4;
00186 pData16 += trailerLen;
00187
00188 parsedLen = (pData16-begin16) / 4;
00189
00190 if((pData16-begin16)!=(4*fragLen)){
00191 error |= errorLength;
00192 }
00193
00194 if((size_t)(pData16-begin16)>maxSize){
00195 throwExcept(string("Corrupted or truncated data"));
00196 }
00197
00198
00199 if(getBoe()!=0x5){
00200 error |= errorWrongBoe;
00201 }
00202 }
00203
00204 int MatacqRawEvent::read32(uint32le_t* pData, field32spec_t spec32,
00205 bool ovfTrans){
00206 uint32_t result = pData[spec32.offset] & spec32.mask;
00207 uint32_t mask = spec32.mask;
00208 while((mask&0x1) == 0){
00209 mask >>= 1;
00210 result >>= 1;
00211 }
00212 if(ovfTrans){
00213
00214 mask = ((mask >>1) + 1);
00215 if(result & mask) result = (uint32_t)-1;
00216 }
00217 return result;
00218 }