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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
|
#include "EventFilter/Phase2TrackerRawToDigi/interface/Phase2TrackerFEDHeader.h"
#include "EventFilter/Phase2TrackerRawToDigi/interface/utils.h"
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
namespace Phase2Tracker {
Phase2TrackerFEDHeader::Phase2TrackerFEDHeader(const uint8_t* headerPointer) : trackerHeader_(headerPointer) {
header_first_word_ = read64(0, trackerHeader_);
header_second_word_ = read64(8, trackerHeader_);
// decode the Tracker Header and store info
init();
}
void Phase2TrackerFEDHeader::init() {
dataFormatVersion_ = dataFormatVersion();
debugMode_ = debugMode();
// WARNING: eventType must be called before
// readoutMode, conditionData and dataType
// as this info is stored in eventType
eventType_ = eventType();
readoutMode_ = readoutMode();
conditionData_ = conditionData();
dataType_ = dataType();
glibStatusCode_ = glibStatusCode();
// numberOfCBC must be called before pointerToData
numberOfCBC_ = numberOfCBC();
pointerToData_ = pointerToData();
LogTrace("Phase2TrackerFEDBuffer") << "[Phase2Tracker::Phase2TrackerFEDHeader::" << __func__ << "]: \n"
<< " Tracker Header contents:\n"
<< " -- Data Format Version : " << uint32_t(dataFormatVersion_) << "\n"
<< " -- Debug Level : " << debugMode_ << "\n"
<< " -- Operating Mode : " << readoutMode_ << "\n"
<< " -- Condition Data : " << (conditionData_ ? "Present" : "Absent")
<< "\n"
<< " -- Data Type : " << (dataType_ ? "Real" : "Fake") << "\n"
<< " -- Glib Stat registers : " << std::hex << std::setw(16) << glibStatusCode_
<< "\n"
<< " -- connected CBC : " << std::dec << numberOfCBC_ << "\n";
}
uint8_t Phase2TrackerFEDHeader::dataFormatVersion() const {
uint8_t Version = static_cast<uint8_t>(extract64(VERSION_M, VERSION_S, header_first_word_));
if (Version != 1) {
std::ostringstream ss;
ss << "[Phase2Tracker::Phase2TrackerFEDHeader::" << __func__ << "] ";
ss << "Invalid Data Format Version in Traker Header : ";
printHex(&header_first_word_, 1, ss);
throw cms::Exception("Phase2TrackerFEDBuffer") << ss.str();
}
return Version;
}
READ_MODE Phase2TrackerFEDHeader::debugMode() const {
// Read debugMode in Tracker Header
uint8_t mode = static_cast<uint8_t>(extract64(HEADER_FORMAT_M, HEADER_FORMAT_S, header_first_word_));
switch (mode) { // check if it is one of correct modes
case SUMMARY:
return READ_MODE(SUMMARY);
case FULL_DEBUG:
return READ_MODE(FULL_DEBUG);
case CBC_ERROR:
return READ_MODE(CBC_ERROR);
default: // else create Exception
std::ostringstream ss;
ss << "[Phase2Tracker::Phase2TrackerFEDHeader::" << __func__ << "] ";
ss << "Invalid Header Format in Traker Header : ";
printHex(&header_first_word_, 1, ss);
throw cms::Exception("Phase2TrackerFEDBuffer") << ss.str();
}
return READ_MODE(READ_MODE_INVALID);
}
uint8_t Phase2TrackerFEDHeader::eventType() const {
return static_cast<uint8_t>(extract64(EVENT_TYPE_M, EVENT_TYPE_S, header_first_word_));
}
// decode eventType_. Read: readoutMode, conditionData and dataType
FEDReadoutMode Phase2TrackerFEDHeader::readoutMode() const {
// readout mode is first bit of event type
uint8_t mode = static_cast<uint8_t>(eventType_ >> 2) & 0x3;
switch (mode) { // check if it is one of correct modes
case 2:
return FEDReadoutMode(READOUT_MODE_PROC_RAW);
case 1:
return FEDReadoutMode(READOUT_MODE_ZERO_SUPPRESSED);
default: // else create Exception
std::ostringstream ss;
ss << "[Phase2Tracker::Phase2TrackerFEDHeader::" << __func__ << "] ";
ss << "Invalid Readout Mode in Traker Header : ";
printHex(&header_first_word_, 1, ss);
throw cms::Exception("Phase2TrackerFEDBuffer") << ss.str();
}
}
uint8_t Phase2TrackerFEDHeader::conditionData() const { return static_cast<uint8_t>(eventType_ >> 1) & 0x1; }
uint8_t Phase2TrackerFEDHeader::dataType() const { return static_cast<uint8_t>(eventType_) & 0x1; }
uint64_t Phase2TrackerFEDHeader::glibStatusCode() const {
return extract64(GLIB_STATUS_M, GLIB_STATUS_S, header_first_word_);
}
std::vector<bool> Phase2TrackerFEDHeader::frontendStatus() const {
uint16_t FE_status = static_cast<uint16_t>(extract64(FRONTEND_STAT_M, FRONTEND_STAT_S, header_first_word_));
std::vector<bool> status(16, false);
for (int i = 0; i < 16; i++) {
status[i] = (FE_status >> i) & 0x1;
}
return status;
}
uint16_t Phase2TrackerFEDHeader::numberOfCBC() const {
if (debugMode_ != SUMMARY) {
return static_cast<uint16_t>(extract64(CBC_NUMBER_M, CBC_NUMBER_S, header_second_word_));
} else {
return 0;
}
}
// pending too
std::vector<uint8_t> Phase2TrackerFEDHeader::CBCStatus() const {
// set offset and data to begining of second header 64 bit word
int offset = 8;
uint64_t data64 = header_second_word_;
// number of CBC:
uint16_t cbc_num = numberOfCBC();
// size of data per CBC (in bits)
int status_size = 0;
if (debugMode_ == FULL_DEBUG) {
status_size = 8;
} else if (debugMode_ == CBC_ERROR) {
status_size = 1;
}
// starting byte for CBC status bits
std::vector<uint8_t> cbc_status;
if (status_size == 8) {
int num_bytes = cbc_num;
int current_byte = 5;
while (num_bytes > 0) {
cbc_status.push_back(static_cast<uint8_t>((data64 >> current_byte * 8) & 0xFF));
if (current_byte == 0) {
current_byte = 8;
offset += 8;
data64 = read64(offset, trackerHeader_);
}
current_byte--;
num_bytes--;
}
} else if (status_size == 1) {
int current_bit = 47;
int num_bits = cbc_num;
while (num_bits > 0) {
cbc_status.push_back(static_cast<uint8_t>((data64 >> current_bit) & 0x1));
if (current_bit == 0) {
current_bit = 64;
offset += 8;
data64 = read64(offset, trackerHeader_);
}
current_bit--;
num_bits--;
}
}
return cbc_status;
}
const uint8_t* Phase2TrackerFEDHeader::pointerToData() {
int status_size = 0;
int cbc_num = numberOfCBC();
// CAUTION: we express all sizes in bits here
if (debugMode_ == FULL_DEBUG) {
status_size = 8;
} else if (debugMode_ == CBC_ERROR) {
status_size = 1;
}
// compute number of additional 64 bit words before payload
int num_add_words64 = (cbc_num * status_size - 48 + 64 - 1) / 64;
// back to bytes
trackerHeaderSize_ = (2 + num_add_words64) * 8;
return &trackerHeader_[trackerHeaderSize_];
}
} // namespace Phase2Tracker
|