Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2023-03-17 10:59:42

0001 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 8; -*-
0002 /*
0003  * Original author: Ph. Gras CEA/Saclay 
0004  */
0005 
0006 /**
0007  * \file
0008  * Implementation of the MaacqRawEvent class
0009  */
0010 
0011 #include <unistd.h>
0012 #include <cstdlib>
0013 #include <fstream>
0014 #include <vector>
0015 #include <iostream>
0016 #include <iomanip>
0017 #include <ctime>
0018 #include <limits>
0019 
0020 #define CMSSW
0021 
0022 #ifdef CMSSW  //compilation within CMSSW framework
0023 
0024 #include "EventFilter/EcalRawToDigi/interface/MatacqRawEvent.h"
0025 #include "FWCore/Utilities/interface/Exception.h"
0026 
0027 static inline void throwExcept(const std::string &s) { throw cms::Exception("Matacq") << s; }
0028 
0029 #else  //compilation outside CMSSW framework (e.g. online)
0030 
0031 #include "MatacqRawEvent.h"
0032 #include <stdexcept>
0033 static inline void throwExcept(const std::string &s) { throw std::runtime_error(s.c_str()); }
0034 
0035 #endif  //CMSSW not defined
0036 
0037 using namespace std;
0038 
0039 //DAQ header fields:
0040 const MatacqRawEvent::field32spec_t MatacqRawEvent::fov32 = {0, 0x000000F0};
0041 const MatacqRawEvent::field32spec_t MatacqRawEvent::fedId32 = {0, 0x000FFF00};
0042 const MatacqRawEvent::field32spec_t MatacqRawEvent::bxId32 = {0, 0xFFF00000};
0043 const MatacqRawEvent::field32spec_t MatacqRawEvent::lv132 = {1, 0x00FFFFFF};
0044 const MatacqRawEvent::field32spec_t MatacqRawEvent::triggerType32 = {1, 0x0F000000};
0045 const MatacqRawEvent::field32spec_t MatacqRawEvent::boeType32 = {1, 0xF0000000};
0046 const MatacqRawEvent::field32spec_t MatacqRawEvent::dccLen32 = {2, 0x00FFFFFF};
0047 const MatacqRawEvent::field32spec_t MatacqRawEvent::dccErrors32 = {2, 0xFF000000};
0048 const MatacqRawEvent::field32spec_t MatacqRawEvent::runNum32 = {3, 0x00FFFFFF};
0049 const MatacqRawEvent::field32spec_t MatacqRawEvent::h1Marker32 = {3, 0x3F000000};
0050 
0051 //Matacq header fields:
0052 const MatacqRawEvent::field32spec_t MatacqRawEvent::formatVersion32 = {4, 0x0000FFFF};
0053 const MatacqRawEvent::field32spec_t MatacqRawEvent::freqGHz32 = {4, 0x00FF0000};
0054 const MatacqRawEvent::field32spec_t MatacqRawEvent::channelCount32 = {4, 0xFF000000};
0055 const MatacqRawEvent::field32spec_t MatacqRawEvent::timeStamp32 = {5, 0xFFFFFFFF};
0056 //  for data format version >=2:
0057 const MatacqRawEvent::field32spec_t MatacqRawEvent::tTrigPs32 = {6, 0xFFFFFFFF};
0058 //  for data format version >=3:
0059 const MatacqRawEvent::field32spec_t MatacqRawEvent::orbitId32 = {7, 0xFFFFFFFF};
0060 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier0_32 = {8, 0x0000FFFF};
0061 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier1_32 = {8, 0xFFFF0000};
0062 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier2_32 = {9, 0x0000FFFF};
0063 const MatacqRawEvent::field32spec_t MatacqRawEvent::vernier3_32 = {9, 0xFFFF0000};
0064 const MatacqRawEvent::field32spec_t MatacqRawEvent::timeStampMicroSec32 = {10, 0xFFFFFFFF};
0065 const MatacqRawEvent::field32spec_t MatacqRawEvent::trigRec32 = {11, 0xFF000000};
0066 const MatacqRawEvent::field32spec_t MatacqRawEvent::postTrig32 = {11, 0x0000FFFF};
0067 const MatacqRawEvent::field32spec_t MatacqRawEvent::laserPower32 = {12, 0x000000FF};
0068 const MatacqRawEvent::field32spec_t MatacqRawEvent::attenuation_dB32 = {12, 0x00000F00};
0069 const MatacqRawEvent::field32spec_t MatacqRawEvent::emtcPhase32 = {12, 0x0000F000};
0070 const MatacqRawEvent::field32spec_t MatacqRawEvent::emtcDelay32 = {12, 0xFFFF0000};
0071 const MatacqRawEvent::field32spec_t MatacqRawEvent::delayA32 = {13, 0x0000FFFF};
0072 const MatacqRawEvent::field32spec_t MatacqRawEvent::dccId32 = {13, 0x003F0000};
0073 const MatacqRawEvent::field32spec_t MatacqRawEvent::color32 = {13, 0x00600000};
0074 const MatacqRawEvent::field32spec_t MatacqRawEvent::trigType32 = {13, 0x07000000};
0075 const MatacqRawEvent::field32spec_t MatacqRawEvent::side32 = {13, 0x08000000};
0076 
0077 void MatacqRawEvent::setRawData(const unsigned char *pData, size_t maxSize) {
0078   error = 0;
0079   const int16le_t *begin16 = (const int16le_t *)pData;
0080   const uint32le_t *begin32 = (const uint32le_t *)pData;
0081   if (maxSize < 6 * 4) {
0082     error = errorLength;
0083     return;
0084   }
0085 
0086   daqHeader = begin32;
0087   matacqDataFormatVersion = read32(begin32, formatVersion32);
0088   freqGHz = read32(begin32, freqGHz32);
0089   channelCount = read32(begin32, channelCount32);
0090   timeStamp.tv_sec = read32(begin32, timeStamp32);
0091   int headerLen = 24;  //in bytes
0092   if (matacqDataFormatVersion >= 2) {
0093     tTrigPs = read32(begin32, tTrigPs32);
0094     headerLen += 4;
0095   } else {
0096     tTrigPs = numeric_limits<int>::max();
0097   }
0098 
0099   if (matacqDataFormatVersion >= 3) {
0100     orbitId = read32(begin32, orbitId32);
0101     vernier[0] = read32(begin32, vernier0_32);
0102     vernier[1] = read32(begin32, vernier1_32);
0103     vernier[2] = read32(begin32, vernier2_32);
0104     vernier[3] = read32(begin32, vernier3_32);
0105     timeStamp.tv_usec = read32(begin32, timeStampMicroSec32);
0106     trigRec = read32(begin32, trigRec32, true);
0107     postTrig = read32(begin32, postTrig32);
0108     delayA = read32(begin32, delayA32, true);
0109     emtcDelay = read32(begin32, emtcDelay32, true);
0110     emtcPhase = read32(begin32, emtcPhase32, true);
0111     attenuation_dB = read32(begin32, attenuation_dB32, true);
0112     laserPower = read32(begin32, laserPower32, true);
0113     headerLen = 64;
0114   } else {
0115     orbitId = 0;
0116     vernier[0] = -1;
0117     vernier[1] = -1;
0118     vernier[2] = -1;
0119     vernier[3] = -1;
0120     trigRec = -1;
0121     postTrig = -1;
0122     delayA = -1;
0123     emtcDelay = -1;
0124     emtcPhase = -1;
0125     attenuation_dB = -1;
0126     laserPower = -1;
0127   }
0128 
0129   const int nCh = getChannelCount();
0130   channelData.resize(nCh);
0131 
0132   const int16le_t *pData16 = (const int16le_t *)(pData + headerLen);
0133 
0134   for (int iCh = 0; iCh < nCh; ++iCh) {
0135     if ((size_t)(pData16 - begin16) > maxSize) {
0136       throwExcept(string("Corrupted or truncated data"));
0137     }
0138     //channel id:
0139     channelData[iCh].chId = *(pData16++);
0140     //number of time samples for this channel:
0141     channelData[iCh].nSamples = *(pData16++);
0142     //pointer to time sample data of this channel:
0143     channelData[iCh].samples = pData16;
0144     //moves to next channel data block:
0145     if (channelData[iCh].nSamples < 0) {
0146       throwExcept(string("Corrupted or truncated data"));
0147     }
0148     pData16 += channelData[iCh].nSamples;
0149   }
0150 
0151   //data trailer chekes:
0152   //FED header is aligned on 64-bit=>padding to skip
0153   int padding = (4 - (pData16 - begin16)) % 4;
0154   if (padding < 0)
0155     padding += 4;
0156   pData16 += padding;
0157   if ((size_t)(pData16 - begin16) > maxSize) {
0158     throwExcept(string("Corrupted or truncated data"));
0159   }
0160   const uint32le_t *trailer32 = (const uint32le_t *)(pData16);
0161   fragLen = trailer32[1] & 0xFFFFFF;
0162 
0163   //cout << "Event fragment length including headers: " << fragLen
0164   //     << " 64-bit words\n";
0165 
0166   //FIXME: I am expecting the event length specifies in the header to
0167   //include the header, while it is not the case in current TB 2006 data
0168   const int nHeaders = 3;
0169   if (fragLen != read32(begin32, dccLen32) + nHeaders && fragLen != read32(begin32, dccLen32)) {
0170     //cout << "Error: fragment length is not consistent with DCC "
0171     //  "length\n";
0172     error |= errorLengthConsistency;
0173   }
0174 
0175   //skip trailers
0176   const int trailerLen = 4;
0177   pData16 += trailerLen;
0178 
0179   parsedLen = (pData16 - begin16) / 4;
0180 
0181   if ((pData16 - begin16) != (4 * fragLen)) {
0182     error |= errorLength;
0183   }
0184 
0185   if ((size_t)(pData16 - begin16) > maxSize) {
0186     throwExcept(string("Corrupted or truncated data"));
0187   }
0188 
0189   //some checks
0190   if (getBoe() != 0x5) {
0191     error |= errorWrongBoe;
0192   }
0193 }
0194 
0195 int MatacqRawEvent::read32(const uint32le_t *pData, field32spec_t spec32, bool ovfTrans) {
0196   uint32_t result = pData[spec32.offset] & spec32.mask;
0197   uint32_t mask = spec32.mask;
0198   while ((mask & 0x1) == 0) {
0199     mask >>= 1;
0200     result >>= 1;
0201   }
0202   if (ovfTrans) {
0203     //overflow bit (MSB) mask:
0204     mask = ((mask >> 1) + 1);
0205     if (result & mask)
0206       result = (uint32_t)-1;
0207   }
0208   return result;
0209 }