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
|
#ifndef DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H
#define DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H
#include <string>
#include <ostream>
#include "EventFilter/SiStripRawToDigi/interface/SiStripFEDBufferComponents.h"
#include <cstdint>
namespace sistrip {
//
// Constants
//
static const uint16_t FEDCH_PER_DELAY_CHIP = 4;
static const uint16_t DELAY_CHIPS_PER_FED = FEDCH_PER_FED / FEDCH_PER_DELAY_CHIP;
static const uint16_t SPY_DELAY_CHIP_PAYLOAD_SIZE_IN_BYTES = 376 * 4; // 376 32bit words
static const uint16_t SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES =
SPY_DELAY_CHIP_PAYLOAD_SIZE_IN_BYTES + 8; // Extra 8 bytes for counters
static const uint16_t SPY_DELAYCHIP_DATA_OFFSET_IN_BITS = 44; // Offset to start of data
//static const uint16_t SPY_SAMPLES_PER_CHANNEL = ( (SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES * 8) - SPY_DELAYCHIP_DATA_OFFSET_IN_BITS ) / 10 / FEDCH_PER_DELAY_CHIP;
// TW Dirty hack to lose the 3 samples from the end that screw things up...
static const uint16_t SPY_SAMPLES_PER_CHANNEL = 298;
static const uint16_t SPY_BUFFER_SIZE_IN_BYTES = SPY_DELAY_CHIP_BUFFER_SIZE_IN_BYTES * DELAY_CHIPS_PER_FED + 40;
// Delaychip data + 8 bytes header for counters + 8 bytes for word with delay chip enable bits
// + 16 bytes for DAQ header and trailer
//
// Class definitions
//
//class representing spy channel buffers
class FEDSpyBuffer : public FEDBufferBase {
public:
/**
* constructor from a FEDRawData buffer
*
* The sistrip::preconstructCheckFEDSpyBuffer() method should be used
* to check the validity of fedBuffer before constructing a sistrip::FEDBuffer.
*
* @see sistrip::preconstructCheckFEDSpyBuffer()
*/
//construct from buffer
explicit FEDSpyBuffer(const FEDRawData& fedBuffer);
~FEDSpyBuffer() override;
void print(std::ostream& os) const override;
//get the run number from the corresponding global run
uint32_t globalRunNumber() const;
//get the L1 ID stored in the spy header
uint32_t spyHeaderL1ID() const;
//get the total frame count stored in the spy header
uint32_t spyHeaderTotalEventCount() const;
//get the L1 ID after reading a given delay chip
uint32_t delayChipL1ID(const uint8_t delayChip) const;
//get the total event count after reading a given delay chip
uint32_t delayChipTotalEventCount(const uint8_t delayChip) const;
//checks that a delay chip is complete i.e. that it all came from the same event
bool delayChipGood(const uint8_t delayChip) const;
//checks that a channel is usable (i.e. that the delay chip it is on is good)
bool channelGood(const uint8_t internalFEDannelNum) const override;
private:
//mapping of channel index to position in data
static const uint8_t channelPositionsInData_[FEDCH_PER_DELAY_CHIP];
//setup the channel objects
void findChannels();
const uint8_t* payloadPointer_;
uint16_t payloadLength_;
uint8_t versionId_;
};
class FEDSpyChannelUnpacker {
public:
explicit FEDSpyChannelUnpacker(const FEDChannel& channel);
uint16_t sampleNumber() const;
uint16_t adc() const;
bool hasData() const;
FEDSpyChannelUnpacker& operator++();
FEDSpyChannelUnpacker& operator++(int);
private:
const uint32_t* data_;
size_t currentOffset_;
uint16_t currentSample_;
uint16_t valuesLeft_;
};
//
// Inline function definitions
//
/**
* Check if a FEDRawData object satisfies the requirements for constructing a sistrip::FEDSpyBuffer
*
* These are:
* - those from sistrip::preconstructCheckFEDBufferBase() (with checkRecognizedFormat equal to true)
* - the readout mode should be equal to sistrip::READOUT_MODE_SPY
*
* In case any check fails, a value different from sistrip::FEDBufferStatusCode::SUCCESS
* is returned, and detailed information printed to LogDebug("FEDBuffer"), if relevant.
*
* @see sistrip::preconstructCheckFEDBufferBase()
*/
inline FEDBufferStatusCode preconstructCheckFEDSpyBuffer(const FEDRawData& fedBuffer) {
const auto st_base = preconstructCheckFEDBufferBase(fedBuffer, true);
if (FEDBufferStatusCode::SUCCESS != st_base)
return st_base;
const TrackerSpecialHeader hdr{fedBuffer.data() + 8};
if (READOUT_MODE_SPY != hdr.readoutMode())
return FEDBufferStatusCode::EXPECT_SPY;
return FEDBufferStatusCode::SUCCESS;
}
//FEDSpyChannelUnpacker
inline FEDSpyChannelUnpacker::FEDSpyChannelUnpacker(const FEDChannel& channel)
: data_(reinterpret_cast<const uint32_t*>(channel.data())),
currentOffset_(channel.offset()),
currentSample_(0),
valuesLeft_(channel.length()) {}
inline uint16_t FEDSpyChannelUnpacker::sampleNumber() const { return currentSample_; }
inline bool FEDSpyChannelUnpacker::hasData() const { return (valuesLeft_ != 0); }
inline FEDSpyChannelUnpacker& FEDSpyChannelUnpacker::operator++() {
currentOffset_ += FEDCH_PER_DELAY_CHIP * 10;
currentSample_++;
valuesLeft_--;
return (*this);
}
inline FEDSpyChannelUnpacker& FEDSpyChannelUnpacker::operator++(int) {
++(*this);
return *this;
}
} // namespace sistrip
#endif //ndef DQM_SiStripMonitorHardware_SiStripFEDSpyBuffer_H
|