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
|
#include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
namespace sistrip {
const uint8_t FEDSpyBuffer::channelPositionsInData_[FEDCH_PER_DELAY_CHIP] = {0, 3, 2, 1};
FEDSpyBuffer::FEDSpyBuffer(const FEDRawData& fedBuffer)
: FEDBufferBase(fedBuffer),
payloadPointer_(getPointerToDataAfterTrackerSpecialHeader() + 16),
payloadLength_(getPointerToByteAfterEndOfPayload() - payloadPointer_),
versionId_(*(getPointerToDataAfterTrackerSpecialHeader() + 3)) {
//Check the buffer format version ID and take action for any exceptions
if (versionId_ == 0x00) {
payloadPointer_ = payloadPointer_ - 8;
}
//find the channel start positions
findChannels();
}
FEDSpyBuffer::~FEDSpyBuffer() {}
void FEDSpyBuffer::findChannels() {
size_t delayChipStartByteIndex = 0;
//Loop over delay chips checking their data fits into buffer and setting up channel objects with correct offset
for (uint8_t iDelayChip = 0; iDelayChip < DELAY_CHIPS_PER_FED; ++iDelayChip) {
if (delayChipStartByteIndex + SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES > payloadLength_) {
throw cms::Exception("FEDSpyBuffer") << "Delay chip " << uint16_t(iDelayChip) << " does not fit into buffer. "
<< "Buffer size is " << bufferSize() << " delay chip data starts at "
<< delayChipStartByteIndex + 8 + 8 + 8 + 8 << ". ";
}
for (uint8_t i = 0; i < FEDCH_PER_DELAY_CHIP; i++) {
const uint8_t chanelIndexInDataOrder = channelPositionsInData_[i];
const uint8_t fedCh = iDelayChip * FEDCH_PER_DELAY_CHIP + i;
const size_t channelOffsetInBits = SPY_DELAYCHIP_DATA_OFFSET_IN_BITS + 10 * chanelIndexInDataOrder;
channels_[fedCh] =
FEDChannel(payloadPointer_ + delayChipStartByteIndex, channelOffsetInBits, SPY_SAMPLES_PER_CHANNEL);
}
delayChipStartByteIndex += SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES;
}
}
uint32_t FEDSpyBuffer::globalRunNumber() const {
if (versionId_ < 0x02) {
return 0;
}
const uint8_t* runNumberPointer = getPointerToDataAfterTrackerSpecialHeader() + 4;
uint32_t result = 0;
result |= runNumberPointer[0];
result |= (uint32_t(runNumberPointer[1]) << 8);
result |= (uint32_t(runNumberPointer[2]) << 16);
result |= (uint32_t(runNumberPointer[3]) << 24);
return result;
}
uint32_t FEDSpyBuffer::spyHeaderL1ID() const {
if (versionId_ == 0x00) {
return delayChipL1ID(0);
}
uint32_t result = 0;
const uint8_t* spyCounters = payloadPointer_ - 8;
result |= spyCounters[4];
result |= (uint32_t(spyCounters[5]) << 8);
result |= (uint32_t(spyCounters[6]) << 16);
result |= (uint32_t(spyCounters[7]) << 24);
return result;
}
uint32_t FEDSpyBuffer::spyHeaderTotalEventCount() const {
if (versionId_ == 0x00) {
return delayChipTotalEventCount(0);
}
uint32_t result = 0;
const uint8_t* spyCounters = payloadPointer_ - 8;
result |= spyCounters[0];
result |= (uint32_t(spyCounters[1]) << 8);
result |= (uint32_t(spyCounters[2]) << 16);
result |= (uint32_t(spyCounters[3]) << 24);
return result;
}
uint32_t FEDSpyBuffer::delayChipL1ID(const uint8_t delayChip) const {
const uint8_t* delayChipCounters = payloadPointer_ + ((SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES) * (delayChip + 1) - 8);
uint32_t result = 0;
result |= delayChipCounters[4];
result |= (uint32_t(delayChipCounters[5]) << 8);
result |= (uint32_t(delayChipCounters[6]) << 16);
result |= (uint32_t(delayChipCounters[7]) << 24);
return result;
}
uint32_t FEDSpyBuffer::delayChipTotalEventCount(const uint8_t delayChip) const {
const uint8_t* delayChipCounters = payloadPointer_ + ((SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES) * (delayChip + 1) - 8);
uint32_t result = 0;
result |= delayChipCounters[0];
result |= (uint32_t(delayChipCounters[1]) << 8);
result |= (uint32_t(delayChipCounters[2]) << 16);
result |= (uint32_t(delayChipCounters[3]) << 24);
return result;
}
void FEDSpyBuffer::print(std::ostream& os) const {
FEDBufferBase::print(os);
//TODO
}
bool FEDSpyBuffer::delayChipGood(const uint8_t delayChip) const {
if (versionId_ == 0x00) {
if (delayChip == 0)
return true;
}
uint32_t l1CountBefore = 0;
uint32_t totalEventCountBefore = 0;
if (delayChip == 0) {
l1CountBefore = spyHeaderL1ID();
totalEventCountBefore = spyHeaderTotalEventCount();
} else {
l1CountBefore = delayChipL1ID(delayChip - 1);
totalEventCountBefore = delayChipTotalEventCount(delayChip - 1);
}
const uint32_t l1CountAfter = delayChipL1ID(delayChip);
const uint32_t totalEventCountAfter = delayChipTotalEventCount(delayChip);
const bool eventMatches = ((l1CountBefore == l1CountAfter) && (totalEventCountBefore == totalEventCountAfter));
if (!eventMatches) {
std::ostringstream ss;
ss << "Delay chip data was overwritten on chip " << uint16_t(delayChip) << " L1A before: " << l1CountBefore
<< " after: " << l1CountAfter << " Total event count before: " << totalEventCountBefore
<< " after: " << totalEventCountAfter << std::endl;
dump(ss);
edm::LogInfo("FEDSpyBuffer") << ss.str();
}
return eventMatches;
}
bool FEDSpyBuffer::channelGood(const uint8_t internalFEDChannelNum) const {
return delayChipGood(internalFEDChannelNum / FEDCH_PER_DELAY_CHIP);
}
uint16_t FEDSpyChannelUnpacker::adc() const {
const size_t offsetWords = currentOffset_ / 32;
const uint8_t offsetBits = currentOffset_ % 32;
if (offsetBits < 23) {
return ((data_[offsetWords] >> (32 - 10 - offsetBits)) & 0x3FF);
} else {
return (((data_[offsetWords] << (10 - 32 + offsetBits)) & 0x3FF) |
((data_[offsetWords + 1] & (0xFFC00000 << (32 - offsetBits))) >> (64 - 10 - offsetBits)));
}
}
} // namespace sistrip
|