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
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
|
/** \file
*
* \author M. Zanetti - INFN Padova
* FRC 060906
*/
#include "DataFormats/FEDRawData/interface/FEDHeader.h"
#include "DataFormats/FEDRawData/interface/FEDTrailer.h"
#include "DataFormats/DTDigi/interface/DTDDUWords.h"
#include "FWCore/ServiceRegistry/interface/Service.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "EventFilter/DTRawToDigi/plugins/DTDDUUnpacker.h"
#include <iostream>
using namespace std;
using namespace edm;
DTDDUUnpacker::DTDDUUnpacker(const edm::ParameterSet& ps) : dduPSet(ps) {
// the ROS unpacker
ros25Unpacker = new DTROS25Unpacker(dduPSet.getParameter<edm::ParameterSet>("rosParameters"));
// parameters
localDAQ = dduPSet.getUntrackedParameter<bool>("localDAQ", false);
debug = dduPSet.getUntrackedParameter<bool>("debug", false);
}
DTDDUUnpacker::~DTDDUUnpacker() { delete ros25Unpacker; }
void DTDDUUnpacker::interpretRawData(const unsigned int* index32,
int datasize,
int dduID,
edm::ESHandle<DTReadOutMapping>& mapping,
std::unique_ptr<DTDigiCollection>& detectorProduct,
std::unique_ptr<DTLocalTriggerCollection>& triggerProduct,
uint16_t rosList) {
// Definitions
const int wordSize_32 = 4;
const int wordSize_64 = 8;
int numberOf32Words = datasize / wordSize_32;
const unsigned char* index8 = reinterpret_cast<const unsigned char*>(index32);
//////////////////////
/* D D U d a t a */
//////////////////////
// DDU header
FEDHeader dduHeader(index8);
if (dduHeader.check()) {
if (debug)
cout << "[DTDDUUnpacker] FED Header. BXID: " << dduHeader.bxID() << " L1ID: " << dduHeader.lvl1ID() << endl;
} else {
LogWarning("DTRawToDigi|DTDDUUnpacker")
<< "[DTDDUUnpacker] WARNING!, this is not a DDU Header, FED ID: " << dduID << endl;
}
// DDU trailer
// [BITS] stop before FED trailer := 8 bytes
FEDTrailer dduTrailer(index8 + datasize - 1 * wordSize_64);
if (dduTrailer.check()) {
if (debug)
cout << "[DTDDUUnpacker] FED Trailer. Length of the DT event: " << dduTrailer.fragmentLength() << endl;
} else {
LogWarning("DTRawToDigi|DTDDUUnpacker")
<< "[DTDDUUnpacker] WARNING!, this is not a DDU Trailer, FED ID: " << dduID << endl;
}
// Initialize control data
controlData.clean();
controlData.addDDUHeader(dduHeader);
controlData.addDDUTrailer(dduTrailer);
// check the CRC set in the FED trailer (FCRC errors)
controlData.checkCRCBit(index8 + datasize - 1 * wordSize_64);
// Check Status Words
vector<DTDDUFirstStatusWord> rosStatusWords;
// [BITS] 3 words of 8 bytes + "rosId" bytes
// In the case we are reading from DMA, the status word are swapped as the ROS data
if (localDAQ) {
// DDU channels from 1 to 4
for (int rosId = 0; rosId < 4; rosId++) {
int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + wordSize_32 + rosId;
controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
}
// DDU channels from 5 to 8
for (int rosId = 0; rosId < 4; rosId++) {
int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + rosId;
controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
}
// DDU channels from 9 to 12
for (int rosId = 0; rosId < 4; rosId++) {
int wordIndex8 = numberOf32Words * wordSize_32 - 2 * wordSize_64 + wordSize_32 + rosId;
controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
}
} else {
for (int rosId = 0; rosId < 12; rosId++) {
int wordIndex8 = numberOf32Words * wordSize_32 - 3 * wordSize_64 + rosId;
controlData.addROSStatusWord(DTDDUFirstStatusWord(index8[wordIndex8]));
}
}
int theROSList;
// [BITS] 2 words of 8 bytes + 4 bytes (half 64 bit word)
// In the case we are reading from DMA, the status word are swapped as the ROS data
if (localDAQ) {
DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2 * wordSize_64 / wordSize_32]);
controlData.addDDUStatusWord(dduStatusWord);
theROSList = dduStatusWord.rosList();
} else {
DTDDUSecondStatusWord dduStatusWord(index32[numberOf32Words - 2 * wordSize_64 / wordSize_32 + 1]);
controlData.addDDUStatusWord(dduStatusWord);
theROSList = dduStatusWord.rosList();
}
//////////////////////
/* R O S d a t a */
//////////////////////
// Set the index to start looping on ROS data
// [BITS] one 8 bytes word
index32 += (wordSize_64) / wordSize_32;
// Set the datasize to look only at ROS data
// [BITS] header, trailer, 2 status words
datasize -= 4 * wordSize_64;
// unpacking the ROS payload
ros25Unpacker->interpretRawData(index32, datasize, dduID, mapping, detectorProduct, triggerProduct, theROSList);
}
|