1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
// -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: t; tab-width: 8; -*-
/*
* Original author: Ph. Gras CEA/Saclay
*/
/**
* \file
* Implementation of the MatacqTBRawEvent class
*/
#include <unistd.h>
#include <cstdlib>
#include <fstream>
#include <vector>
#include <iostream>
#include <iomanip>
#include <ctime>
#include <limits>
#include <stdexcept>
#include "EventFilter/EcalTBRawToDigi/src/MatacqRawEvent.h"
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::fov32 = {0, 0x000000F0};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::fedId32 = {0, 0x000FFF00};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::bxId32 = {0, 0xFFF00000};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::lv132 = {1, 0x00FFFFFF};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::triggerType32 = {1, 0x0F000000};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::boeType32 = {1, 0xF0000000};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::dccLen32 = {2, 0x00FFFFFF};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::dccErrors32 = {2, 0xFF000000};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::runNum32 = {3, 0x00FFFFFF};
const MatacqTBRawEvent::field32spec_t MatacqTBRawEvent::h1Marker32 = {3, 0xF0000000};
void MatacqTBRawEvent::setRawData(const unsigned char* pData, size_t maxSize) {
error = 0;
const int16le_t* begin16 = (const int16le_t*)pData;
const int16le_t* pData16 = begin16;
daqHeader = (const uint32le_t*)pData16;
const int daqHeaderLen = 16; //in bytes
pData16 += daqHeaderLen / sizeof(pData16[0]);
matacqHeader = (const matacqHeader_t*)pData16;
pData16 += sizeof(matacqHeader_t) / sizeof(pData16[0]);
if (getMatacqDataFormatVersion() >= 2) { //trigger position present
tTrigPs = *((const int32_t*)pData16);
pData16 += 2;
} else {
tTrigPs = std::numeric_limits<int>::max();
}
const int nCh = getChannelCount();
channelData.resize(nCh);
for (int iCh = 0; iCh < nCh; ++iCh) {
//channel id:
channelData[iCh].chId = *(pData16++);
//number of time samples for this channel:
channelData[iCh].nSamples = *(pData16++);
//pointer to time sample data of this channel:
channelData[iCh].samples = pData16;
//moves to next channel data block:
pData16 += channelData[iCh].nSamples;
}
//data trailer chekes:
//FED header is aligned on 64-bit=>padding to skip
int padding = (4 - (pData16 - begin16)) % 4;
if (padding < 0)
padding += 4;
pData16 += padding;
const uint32le_t* trailer32 = (const uint32le_t*)(pData16);
fragLen = trailer32[1] & 0xFFFFFF;
//std::cout << "Event fragment length including headers: " << fragLen
// << " 64-bit words\n";
//FIXME: I am expecting the event length specifies in the header to
//include the header, while it is not the case in current TB 2006 data
const int nHeaders = 3;
if (fragLen != read32(daqHeader, dccLen32) + nHeaders && fragLen != read32(daqHeader, dccLen32)) {
//std::cout << "Error: fragment length is not consistent with DCC "
// "length\n";
error |= errorLengthConsistency;
}
//skip trailers
const int trailerLen = 4;
pData16 += trailerLen;
parsedLen = (pData16 - begin16) / 4;
if ((pData16 - begin16) != (4 * fragLen)) {
error |= errorLength;
}
if ((size_t)(pData16 - begin16) > maxSize) {
throw std::runtime_error(std::string("Corrupted or truncated data"));
}
//some checks
if (getBoe() != 0x5) {
error |= errorWrongBoe;
}
}
int MatacqTBRawEvent::read32(const uint32le_t* pData, field32spec_t spec32) const {
int result = pData[spec32.offset] & spec32.mask;
int mask = spec32.mask;
while ((mask & 0x1) == 0) {
mask >>= 1;
result >>= 1;
}
return result;
}
|