CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RawDataUnpacker.cc
Go to the documentation of this file.
1 /****************************************************************************
2 *
3 * This is a part of TOTEM offline software.
4 * Authors:
5 * Jan Kašpar (jan.kaspar@gmail.com)
6 *
7 ****************************************************************************/
8 
10 
12 
13 //----------------------------------------------------------------------------------------------------
14 
15 using namespace std;
16 using namespace edm;
17 
18 //----------------------------------------------------------------------------------------------------
19 
21 {
22 }
23 
24 //----------------------------------------------------------------------------------------------------
25 
26 int RawDataUnpacker::Run(int fedId, const FEDRawData &data, vector<TotemFEDInfo> &fedInfoColl, SimpleVFATFrameCollection &coll) const
27 {
28  unsigned int size_in_words = data.size() / 8; // bytes -> words
29  if (size_in_words < 2)
30  {
31  LogProblem("Totem") << "Error in RawDataUnpacker::Run > " <<
32  "Data in FED " << fedId << " too short (size = " << size_in_words << " words).";
33  return 1;
34  }
35 
36  fedInfoColl.push_back(TotemFEDInfo(fedId));
37 
38  return ProcessOptoRxFrame((const word *) data.data(), size_in_words, fedInfoColl.back(), &coll);
39 }
40 
41 //----------------------------------------------------------------------------------------------------
42 
43 int RawDataUnpacker::ProcessOptoRxFrame(const word *buf, unsigned int frameSize, TotemFEDInfo &fedInfo, SimpleVFATFrameCollection *fc) const
44 {
45  // get OptoRx metadata
46  unsigned long long head = buf[0];
47  unsigned long long foot = buf[frameSize-1];
48 
49  fedInfo.setHeader(head);
50  fedInfo.setFooter(foot);
51 
52  unsigned int BOE = (head >> 60) & 0xF;
53  unsigned int H0 = (head >> 0) & 0xF;
54 
55  //unsigned long LV1 = (head >> 32) & 0xFFFFFF;
56  //unsigned long BX = (head >> 20) & 0xFFF;
57  unsigned int OptoRxId = (head >> 8) & 0xFFF;
58  unsigned int FOV = (head >> 4) & 0xF;
59 
60  unsigned int EOE = (foot >> 60) & 0xF;
61  unsigned int F0 = (foot >> 0) & 0xF;
62  unsigned int FSize = (foot >> 32) & 0x3FF;
63 
64  // check header and footer structure
65  if (BOE != 5 || H0 != 0 || EOE != 10 || F0 != 0 || FSize != frameSize)
66  {
67  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessOptoRxFrame > " << "Wrong structure of OptoRx header/footer: "
68  << "BOE=" << BOE << ", H0=" << H0 << ", EOE=" << EOE << ", F0=" << F0
69  << ", size (OptoRx)=" << FSize << ", size (DATE)=" << frameSize
70  << ". OptoRxID=" << OptoRxId << ". Skipping frame." << endl;
71  return 0;
72  }
73 
74  #ifdef DEBUG
75  printf(">> RawDataUnpacker::ProcessOptoRxFrame > OptoRxId = %u, BX = %lu, LV1 = %lu, frameSize = %u, subFrames = %u)\n",
76  OptoRxId, BX, LV1, frameSize, subFrames);
77  #endif
78 
79  // parallel or serial transmission?
80  if (FOV == 1)
81  return ProcessOptoRxFrameSerial(buf, frameSize, fc);
82 
83  if (FOV == 2)
84  return ProcessOptoRxFrameParallel(buf, frameSize, fedInfo, fc);
85 
86  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessOptoRxFrame > " << "Unknown FOV = " << FOV << endl;
87 
88  return 0;
89 }
90 
91 //----------------------------------------------------------------------------------------------------
92 
93 int RawDataUnpacker::ProcessOptoRxFrameSerial(const word *buf, unsigned int frameSize, SimpleVFATFrameCollection *fc) const
94 {
95  // get OptoRx metadata
96  unsigned int OptoRxId = (buf[0] >> 8) & 0xFFF;
97 
98  // get number of subframes
99  unsigned int subFrames = (frameSize - 2) / 194;
100 
101  // process all sub-frames
102  unsigned int errorCounter = 0;
103  for (unsigned int r = 0; r < subFrames; ++r)
104  {
105  for (unsigned int c = 0; c < 4; ++c)
106  {
107  unsigned int head = (buf[1 + 194 * r] >> (16 * c)) & 0xFFFF;
108  unsigned int foot = (buf[194 + 194 * r] >> (16 * c)) & 0xFFFF;
109 
110  #ifdef DEBUG
111  printf(">>>> r = %i, c = %i: S = %i, BOF = %i, EOF = %i, ID = %i, ID' = %i\n", r, c, head & 0x1, head >> 12, foot >> 12, (head >> 8) & 0xF, (foot >> 8) & 0xF);
112  #endif
113 
114  // stop if this GOH is NOT active
115  if ((head & 0x1) == 0)
116  continue;
117 
118  #ifdef DEBUG
119  printf("\tHeader active (%04x -> %x).\n", head, head & 0x1);
120  #endif
121 
122  // check structure
123  if (head >> 12 != 0x4 || foot >> 12 != 0xB || ((head >> 8) & 0xF) != ((foot >> 8) & 0xF))
124  {
125  char ss[500];
126  if (head >> 12 != 0x4)
127  sprintf(ss, "\n\tHeader is not 0x4 as expected (%x).", head);
128  if (foot >> 12 != 0xB)
129  sprintf(ss, "\n\tFooter is not 0xB as expected (%x).", foot);
130  if (((head >> 8) & 0xF) != ((foot >> 8) & 0xF))
131  sprintf(ss, "\n\tIncompatible GOH IDs in header (%x) and footer (%x).", ((head >> 8) & 0xF),
132  ((foot >> 8) & 0xF));
133 
134  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessOptoRxFrame > " << "Wrong payload structure (in GOH block row " << r <<
135  " and column " << c << ") in OptoRx frame ID " << OptoRxId << ". GOH block omitted." << ss << endl;
136 
137  errorCounter++;
138  continue;
139  }
140 
141  // allocate memory for VFAT frames
142  unsigned int goh = (head >> 8) & 0xF;
143  vector<VFATFrame::word*> dataPtrs;
144  for (unsigned int fi = 0; fi < 16; fi++)
145  {
146  TotemFramePosition fp(0, 0, OptoRxId, goh, fi);
147  dataPtrs.push_back( fc->InsertEmptyFrame(fp)->getData() );
148  }
149 
150  #ifdef DEBUG
151  printf(">>>> transposing GOH block at prefix: %i, dataPtrs = %p\n", OptoRxId*192 + goh*16, dataPtrs);
152  #endif
153 
154  // deserialization
155  for (int i = 0; i < 192; i++)
156  {
157  int iword = 11 - i / 16; // number of current word (11...0)
158  int ibit = 15 - i % 16; // number of current bit (15...0)
159  unsigned int w = (buf[i + 2 + 194 * r] >> (16 * c)) & 0xFFFF;
160 
161  // Fill the current bit of the current word of all VFAT frames
162  for (int idx = 0; idx < 16; idx++)
163  {
164  if (w & (1 << idx))
165  dataPtrs[idx][iword] |= (1 << ibit);
166  }
167  }
168  }
169  }
170 
171  return errorCounter;
172 }
173 
174 //----------------------------------------------------------------------------------------------------
175 
176 int RawDataUnpacker::ProcessOptoRxFrameParallel(const word *buf, unsigned int frameSize, TotemFEDInfo &fedInfo, SimpleVFATFrameCollection *fc) const
177 {
178  // get OptoRx metadata
179  unsigned long long head = buf[0];
180  unsigned int OptoRxId = (head >> 8) & 0xFFF;
181 
182  // recast data as buffer or 16bit words, skip header
183  const uint16_t *payload = (const uint16_t *) (buf + 1);
184 
185  // read in OrbitCounter block
186  const uint32_t *ocPtr = (const uint32_t *) payload;
187  fedInfo.setOrbitCounter(*ocPtr);
188  payload += 2;
189 
190  // size in 16bit words, without header, footer and orbit counter block
191  unsigned int nWords = (frameSize-2) * 4 - 2;
192 
193  // process all VFAT data
194  for (unsigned int offset = 0; offset < nWords;)
195  {
196  unsigned int wordsProcessed = ProcessVFATDataParallel(payload + offset, OptoRxId, fc);
197  offset += wordsProcessed;
198  }
199 
200  return 0;
201 }
202 
203 //----------------------------------------------------------------------------------------------------
204 
205 int RawDataUnpacker::ProcessVFATDataParallel(const uint16_t *buf, unsigned int OptoRxId, SimpleVFATFrameCollection *fc) const
206 {
207  // start counting processed words
208  unsigned int wordsProcessed = 1;
209 
210  // padding word? skip it
211  if (buf[0] == 0xFFFF)
212  return wordsProcessed;
213 
214  // check header flag
215  unsigned int hFlag = (buf[0] >> 8) & 0xFF;
216  if (hFlag != vmCluster && hFlag != vmRaw)
217  {
218  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessVFATDataParallel > "
219  << "Unknown header flag " << hFlag << ". Skipping this word." << endl;
220  return wordsProcessed;
221  }
222 
223  // compile frame position
224  // NOTE: DAQ group uses terms GOH and fiber in the other way
225  unsigned int gohIdx = (buf[0] >> 4) & 0xF;
226  unsigned int fiberIdx = (buf[0] >> 0) & 0xF;
227  TotemFramePosition fp(0, 0, OptoRxId, gohIdx, fiberIdx);
228 
229  // prepare temporary VFAT frame
230  VFATFrame f;
231  VFATFrame::word *fd = f.getData();
232 
233  // copy footprint, BC, EC, Flags, ID, if they exist
234  uint8_t presenceFlags = 0;
235 
236  if (((buf[wordsProcessed] >> 12) & 0xF) == 0xA) // BC
237  {
238  presenceFlags |= 0x1;
239  fd[11] = buf[wordsProcessed];
240  wordsProcessed++;
241  }
242 
243  if (((buf[wordsProcessed] >> 12) & 0xF) == 0xC) // EC, flags
244  {
245  presenceFlags |= 0x2;
246  fd[10] = buf[wordsProcessed];
247  wordsProcessed++;
248  }
249 
250  if (((buf[wordsProcessed] >> 12) & 0xF) == 0xE) // ID
251  {
252  presenceFlags |= 0x4;
253  fd[9] = buf[wordsProcessed];
254  wordsProcessed++;
255  }
256 
257  // save offset where channel data start
258  unsigned int dataOffset = wordsProcessed;
259 
260  // find trailer
261  if (hFlag == vmCluster)
262  {
263  unsigned int nCl = 0;
264  while ( (buf[wordsProcessed + nCl] >> 12) != 0xF )
265  nCl++;
266 
267  wordsProcessed += nCl;
268  }
269 
270  if (hFlag == vmRaw)
271  wordsProcessed += 9;
272 
273  // process trailer
274  unsigned int tSig = buf[wordsProcessed] >> 12;
275  unsigned int tErrFlags = (buf[wordsProcessed] >> 8) & 0xF;
276  unsigned int tSize = buf[wordsProcessed] & 0xFF;
277 
278  f.setDAQErrorFlags(tErrFlags);
279 
280  bool skipFrame = false;
281  bool suppressChannelErrors = false;
282 
283  if (tSig != 0xF)
284  {
285  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessVFATDataParallel > "
286  << "Wrong trailer signature (" << tSig << ") at "
287  << fp << ". This frame will be skipped." << endl;
288  skipFrame = true;
289  }
290 
291  if (tErrFlags != 0)
292  {
293  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessVFATDataParallel > "
294  << "Error flags not zero (" << tErrFlags << ") at "
295  << fp << ". Channel errors will be suppressed." << endl;
296  suppressChannelErrors = true;
297  }
298 
299  wordsProcessed++;
300 
301  if (tSize != wordsProcessed)
302  {
303  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessVFATDataParallel > "
304  << "Trailer size (" << tSize << ") does not match with words processed ("
305  << wordsProcessed << ") at " << fp << ". This frame will be skipped." << endl;
306  skipFrame = true;
307  }
308 
309  if (skipFrame)
310  return wordsProcessed;
311 
312  // get channel data - cluster mode
313  if (hFlag == vmCluster)
314  {
315  for (unsigned int nCl = 0; (buf[dataOffset + nCl] >> 12) != 0xF; ++nCl)
316  {
317  const uint16_t &w = buf[dataOffset + nCl];
318  unsigned int upperBlock = w >> 8;
319  unsigned int clSize = upperBlock & 0x7F;
320  unsigned int clPos = (w >> 0) & 0xFF;
321 
322  // special case: upperBlock=0xD0 => numberOfClusters
323  if (upperBlock == 0xD0)
324  {
325  presenceFlags |= 0x10;
326  f.setNumberOfClusters(clPos);
327  continue;
328  }
329 
330  // special case: size=0 means chip full
331  if (clSize == 0)
332  clSize = 128;
333 
334  // activate channels
335  // convention - range <pos, pos-size+1>
336  signed int chMax = clPos;
337  signed int chMin = clPos - clSize + 1;
338  if (chMax < 0 || chMax > 127 || chMin < 0 || chMin > 127 || chMin > chMax)
339  {
340  if (!suppressChannelErrors)
341  LogProblem("Totem") << "Error in RawDataUnpacker::ProcessVFATDataParallel > "
342  << "Invalid cluster (pos=" << clPos
343  << ", size=" << clSize << ", min=" << chMin << ", max=" << chMax << ") at " << fp
344  <<". Skipping this cluster." << endl;
345 
346  continue;
347  }
348 
349  for (signed int ch = chMin; ch <= chMax; ch++)
350  {
351  unsigned int wi = ch / 16;
352  unsigned int bi = ch % 16;
353  fd[wi + 1] |= (1 << bi);
354  }
355  }
356  }
357 
358  // get channel data and CRC - raw mode
359  if (hFlag == vmRaw)
360  {
361  for (unsigned int i = 0; i < 8; i++)
362  fd[8 - i] = buf[dataOffset + i];
363 
364  // copy CRC
365  presenceFlags |= 0x8;
366  fd[0] = buf[dataOffset + 8];
367  }
368 
369  // save frame to output
370  f.setPresenceFlags(presenceFlags);
371  fc->Insert(fp, f);
372 
373  return wordsProcessed;
374 }
int ProcessOptoRxFrame(const word *buf, unsigned int frameSize, TotemFEDInfo &fedInfo, SimpleVFATFrameCollection *fc) const
Process one Opto-Rx (or LoneG) frame.
OptoRx headers and footers.
Definition: TotemFEDInfo.h:15
int i
Definition: DBlmapReader.cc:9
VFATFrame::word * getData()
Definition: VFATFrame.h:40
int ProcessOptoRxFrameSerial(const word *buffer, unsigned int frameSize, SimpleVFATFrameCollection *fc) const
Process one Opto-Rx frame in serial (old) format.
const double w
Definition: UKUtility.cc:23
uint16_t word
Definition: VFATFrame.h:22
size_t size() const
Lenght of the data buffer in bytes.
Definition: FEDRawData.h:47
void setOrbitCounter(uint32_t _oc)
Definition: TotemFEDInfo.h:33
void setFooter(uint64_t _f)
Definition: TotemFEDInfo.h:36
tuple fd
Definition: ztee.py:136
double f[11][100]
int ProcessOptoRxFrameParallel(const word *buffer, unsigned int frameSize, TotemFEDInfo &fedInfo, SimpleVFATFrameCollection *fc) const
Process one Opto-Rx frame in parallel (new) format.
VFATFrame * InsertEmptyFrame(TotemFramePosition index)
inserts an empty (default) frame to the given position and returns pointer to the frame ...
JetCorrectorParametersCollection coll
Definition: classes.h:10
void setPresenceFlags(uint8_t v)
Sets presence flags.
Definition: VFATFrame.h:76
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
void setDAQErrorFlags(uint8_t v)
Sets DAQ error flags.
Definition: VFATFrame.h:112
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:82
int ProcessVFATDataParallel(const uint16_t *buf, unsigned int OptoRxId, SimpleVFATFrameCollection *fc) const
Process data from one VFAT in parallel (new) format.
const unsigned char * data() const
Return a const pointer to the beginning of the data buffer.
Definition: FEDRawData.cc:28
void setHeader(uint64_t _h)
Definition: TotemFEDInfo.h:25
int Run(int fedId, const FEDRawData &data, std::vector< TotemFEDInfo > &fedInfoColl, SimpleVFATFrameCollection &coll) const
Unpack data from FED with fedId into `coll&#39; collection.
void Insert(const TotemFramePosition &index, const VFATFrame &frame)
void setNumberOfClusters(uint8_t v)
Definition: VFATFrame.h:117