CMS 3D CMS Logo

MatacqRawEvent.cc
Go to the documentation of this file.
1 // -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 8; -*-
2 /*
3  * Original author: Ph. Gras CEA/Saclay
4  */
5 
11 #include <unistd.h>
12 #include <cstdlib>
13 #include <fstream>
14 #include <vector>
15 #include <iostream>
16 #include <iomanip>
17 #include <ctime>
18 #include <limits>
19 
20 #define CMSSW
21 
22 #ifdef CMSSW //compilation within CMSSW framework
23 
26 
27 static inline void throwExcept(const std::string &s) { throw cms::Exception("Matacq") << s; }
28 
29 #else //compilation outside CMSSW framework (e.g. online)
30 
31 #include "MatacqRawEvent.h"
32 #include <stdexcept>
33 static inline void throwExcept(const std::string &s) { throw std::runtime_error(s.c_str()); }
34 
35 #endif //CMSSW not defined
36 
37 using namespace std;
38 
39 //DAQ header fields:
50 
51 //Matacq header fields:
56 // for data format version >=2:
58 // for data format version >=3:
76 
77 void MatacqRawEvent::setRawData(const unsigned char *pData, size_t maxSize) {
78  error = 0;
79  const int16le_t *begin16 = (const int16le_t *)pData;
80  const uint32le_t *begin32 = (const uint32le_t *)pData;
81  if (maxSize < 6 * 4) {
82  error = errorLength;
83  return;
84  }
85 
86  daqHeader = begin32;
87  matacqDataFormatVersion = read32(begin32, formatVersion32);
88  freqGHz = read32(begin32, freqGHz32);
89  channelCount = read32(begin32, channelCount32);
90  timeStamp.tv_sec = read32(begin32, timeStamp32);
91  int headerLen = 24; //in bytes
92  if (matacqDataFormatVersion >= 2) {
93  tTrigPs = read32(begin32, tTrigPs32);
94  headerLen += 4;
95  } else {
96  tTrigPs = numeric_limits<int>::max();
97  }
98 
99  if (matacqDataFormatVersion >= 3) {
100  orbitId = read32(begin32, orbitId32);
101  vernier[0] = read32(begin32, vernier0_32);
102  vernier[1] = read32(begin32, vernier1_32);
103  vernier[2] = read32(begin32, vernier2_32);
104  vernier[3] = read32(begin32, vernier3_32);
105  timeStamp.tv_usec = read32(begin32, timeStampMicroSec32);
106  trigRec = read32(begin32, trigRec32, true);
107  postTrig = read32(begin32, postTrig32);
108  delayA = read32(begin32, delayA32, true);
109  emtcDelay = read32(begin32, emtcDelay32, true);
110  emtcPhase = read32(begin32, emtcPhase32, true);
111  attenuation_dB = read32(begin32, attenuation_dB32, true);
112  laserPower = read32(begin32, laserPower32, true);
113  headerLen = 64;
114  } else {
115  orbitId = 0;
116  vernier[0] = -1;
117  vernier[1] = -1;
118  vernier[2] = -1;
119  vernier[3] = -1;
120  trigRec = -1;
121  postTrig = -1;
122  delayA = -1;
123  emtcDelay = -1;
124  emtcPhase = -1;
125  attenuation_dB = -1;
126  laserPower = -1;
127  }
128 
129  const int nCh = getChannelCount();
130  channelData.resize(nCh);
131 
132  const int16le_t *pData16 = (const int16le_t *)(pData + headerLen);
133 
134  for (int iCh = 0; iCh < nCh; ++iCh) {
135  if ((size_t)(pData16 - begin16) > maxSize) {
136  throwExcept(string("Corrupted or truncated data"));
137  }
138  //channel id:
139  channelData[iCh].chId = *(pData16++);
140  //number of time samples for this channel:
141  channelData[iCh].nSamples = *(pData16++);
142  //pointer to time sample data of this channel:
143  channelData[iCh].samples = pData16;
144  //moves to next channel data block:
145  if (channelData[iCh].nSamples < 0) {
146  throwExcept(string("Corrupted or truncated data"));
147  }
148  pData16 += channelData[iCh].nSamples;
149  }
150 
151  //data trailer chekes:
152  //FED header is aligned on 64-bit=>padding to skip
153  int padding = (4 - (pData16 - begin16)) % 4;
154  if (padding < 0)
155  padding += 4;
156  pData16 += padding;
157  if ((size_t)(pData16 - begin16) > maxSize) {
158  throwExcept(string("Corrupted or truncated data"));
159  }
160  const uint32le_t *trailer32 = (const uint32le_t *)(pData16);
161  fragLen = trailer32[1] & 0xFFFFFF;
162 
163  //cout << "Event fragment length including headers: " << fragLen
164  // << " 64-bit words\n";
165 
166  //FIXME: I am expecting the event length specifies in the header to
167  //include the header, while it is not the case in current TB 2006 data
168  const int nHeaders = 3;
169  if (fragLen != read32(begin32, dccLen32) + nHeaders && fragLen != read32(begin32, dccLen32)) {
170  //cout << "Error: fragment length is not consistent with DCC "
171  // "length\n";
172  error |= errorLengthConsistency;
173  }
174 
175  //skip trailers
176  const int trailerLen = 4;
177  pData16 += trailerLen;
178 
179  parsedLen = (pData16 - begin16) / 4;
180 
181  if ((pData16 - begin16) != (4 * fragLen)) {
182  error |= errorLength;
183  }
184 
185  if ((size_t)(pData16 - begin16) > maxSize) {
186  throwExcept(string("Corrupted or truncated data"));
187  }
188 
189  //some checks
190  if (getBoe() != 0x5) {
191  error |= errorWrongBoe;
192  }
193 }
194 
195 int MatacqRawEvent::read32(const uint32le_t *pData, field32spec_t spec32, bool ovfTrans) {
196  uint32_t result = pData[spec32.offset] & spec32.mask;
197  uint32_t mask = spec32.mask;
198  while ((mask & 0x1) == 0) {
199  mask >>= 1;
200  result >>= 1;
201  }
202  if (ovfTrans) {
203  //overflow bit (MSB) mask:
204  mask = ((mask >> 1) + 1);
205  if (result & mask)
206  result = (uint32_t)-1;
207  }
208  return result;
209 }
static const field32spec_t vernier1_32
static const field32spec_t fedId32
static const field32spec_t boeType32
static int read32(const uint32le_t *pData, field32spec_t spec, bool ovfTrans=false)
static const field32spec_t runNum32
static const field32spec_t timeStamp32
static const field32spec_t trigType32
static const field32spec_t tTrigPs32
static const field32spec_t channelCount32
static const field32spec_t emtcPhase32
void setRawData(const unsigned char *buffer, size_t bufferSize)
static const field32spec_t dccLen32
static const field32spec_t fov32
static const field32spec_t attenuation_dB32
static const field32spec_t lv132
static const field32spec_t vernier0_32
static const field32spec_t vernier3_32
static const field32spec_t postTrig32
static const field32spec_t timeStampMicroSec32
static const field32spec_t trigRec32
static const field32spec_t vernier2_32
static const field32spec_t emtcDelay32
static const field32spec_t side32
static const field32spec_t dccId32
static const field32spec_t triggerType32
static const field32spec_t color32
static const field32spec_t delayA32
static const field32spec_t orbitId32
static const field32spec_t formatVersion32
static const field32spec_t dccErrors32
static const field32spec_t h1Marker32
static const field32spec_t freqGHz32
static const field32spec_t laserPower32
static void throwExcept(const std::string &s)
static const field32spec_t bxId32