CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/src/EventFilter/EcalRawToDigi/src/MatacqRawEvent.cc

Go to the documentation of this file.
00001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 8; -*-
00002 /*
00003  * $Id: MatacqRawEvent.cc,v 1.1 2009/02/25 14:44:25 pgras Exp $
00004  * Original author: Ph. Gras CEA/Saclay 
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 //DAQ header fields:
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 //Matacq header fields:
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 //  for data format version >=2:
00062 const MatacqRawEvent::field32spec_t MatacqRawEvent::tTrigPs32           = {6, 0xFFFFFFFF};
00063 //  for data format version >=3:
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; //in bytes
00089   if(maxSize < 6*4){
00090     error = errorLength;
00091     return;
00092   }
00093   pData16 += daqHeaderLen/sizeof(pData16[0]);
00094   //  matacqHeader = (matacqHeader_t*) pData16;
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; //in bytes
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     //channel id:
00148     channelData[iCh].chId = *(pData16++);
00149     //number of time samples for this channel:
00150     channelData[iCh].nSamples = *(pData16++);
00151     //pointer to time sample data of this channel:
00152     channelData[iCh].samples = pData16;
00153     //moves to next channel data block:
00154     if(channelData[iCh].nSamples<0){
00155       throwExcept(string("Corrupted or truncated data"));
00156     }
00157     pData16 += channelData[iCh].nSamples;
00158   }
00159   
00160   //data trailer chekes:
00161   //FED header is aligned on 64-bit=>padding to skip
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   //cout << "Event fragment length including headers: " << fragLen
00172   //     << " 64-bit words\n";
00173   
00174   //FIXME: I am expecting the event length specifies in the header to
00175   //include the header, while it is not the case in current TB 2006 data
00176   const int nHeaders = 3;
00177   if(fragLen!=read32(begin32,dccLen32)+nHeaders
00178      && fragLen != read32(begin32,dccLen32)){
00179     //cout << "Error: fragment length is not consistent with DCC "
00180     //  "length\n";
00181     error |= errorLengthConsistency;
00182   }
00183   
00184   //skip trailers
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   //some checks
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     //overflow bit (MSB) mask:
00214     mask = ((mask >>1) + 1);
00215     if(result & mask)  result = (uint32_t)-1;
00216   }
00217   return result;
00218 }