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
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
|
/* \file SiStripSpyUnpacker.cc
* \brief Source code for the SpyChannel unpacking factory.
*/
#include "FWCore/Utilities/interface/Exception.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "DataFormats/Common/interface/DetSetVector.h"
#include "DataFormats/Common/interface/DetSet.h"
#include "CondFormats/SiStripObjects/interface/SiStripFedCabling.h"
#include "DataFormats/SiStripCommon/interface/SiStripFedKey.h"
#include "DataFormats/FEDRawData/interface/FEDNumbering.h"
#include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
#include "DataFormats/SiStripDigi/interface/SiStripRawDigi.h"
#include "EventFilter/SiStripRawToDigi/interface/SiStripDetSetVectorFiller.h"
#include "DQM/SiStripMonitorHardware/interface/SiStripFEDSpyBuffer.h"
#include "DQM/SiStripMonitorHardware/interface/SiStripSpyUnpacker.h"
#include <algorithm>
#include <vector>
#include <ext/algorithm>
using namespace std;
namespace sistrip {
SpyUnpacker::SpyUnpacker(const bool allowIncompleteEvents) : allowIncompleteEvents_(allowIncompleteEvents) {
if (edm::isDebugEnabled()) {
LogTrace("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
<< " Constructing object...";
}
} // end of SpyUnpacker constructor.
SpyUnpacker::~SpyUnpacker() {
if (edm::isDebugEnabled()) {
LogTrace("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
<< " Destructing object...";
}
} // end of SpyUnpacker destructor.
void SpyUnpacker::createDigis(const SiStripFedCabling& cabling,
const FEDRawDataCollection& buffers,
RawDigis* pDigis,
const std::vector<uint32_t>& ids,
Counters* pTotalEventCounts,
Counters* pL1ACounts,
uint32_t* aRunRef) const {
//create DSV filler to fill output
//As of Feb 2010, bug in DataFormats/SiStripCommon/interface/ConstantsForHardwareSystems.h:
//number of feds=max-min+1 (440...). Corrected in head of DataFormats/SiStripCommon package.
uint16_t nFeds = static_cast<uint16_t>(FED_ID_MAX - FED_ID_MIN + 1);
RawDigiDetSetVectorFiller dsvFiller(nFeds * FEDCH_PER_FED, nFeds * FEDCH_PER_FED * SPY_SAMPLES_PER_CHANNEL);
//check if FEDs found in cabling map and event data
if (edm::isDebugEnabled()) {
if (cabling.fedIds().empty()) {
edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
<< " No FEDs found in cabling map!";
}
}
//retrieve FED ids from cabling map and iterate through
std::vector<uint32_t>::const_iterator ifed = ids.begin();
std::vector<uint32_t>::const_iterator endfed = ids.end();
//reference value for run number
//encoded per fed but should be the same for all feds
uint32_t lRef = 0;
//initialise counter vectors to FED_ID_MAX+1
pTotalEventCounts->resize(FED_ID_MAX + 1, 0);
pL1ACounts->resize(FED_ID_MAX + 1, 0);
for (; ifed != endfed; ++ifed) {
uint32_t lFedId = (*ifed);
//check the fedid is valid:
if (lFedId < FED_ID_MIN || lFedId > FED_ID_MAX) {
if (edm::isDebugEnabled()) {
edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
<< " Invalid FED id provided: " << lFedId;
}
continue;
}
//retrieve FED raw data for given FED
const FEDRawData& input = buffers.FEDData(static_cast<int>(lFedId));
//check on FEDRawData pointer
if (!input.data()) {
if (edm::isDebugEnabled()) {
edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
<< " NULL pointer to FEDRawData for FED id " << lFedId;
}
continue;
}
//check on FEDRawData size
if (!input.size()) {
if (edm::isDebugEnabled()) {
edm::LogWarning("SiStripSpyUnpacker") << "[sistrip::SpyUnpacker::" << __func__ << "]"
<< " FEDRawData has zero size for FED id " << lFedId;
}
continue;
}
//get the cabling connections for this FED
auto conns = cabling.fedConnections(lFedId);
//construct FEDBuffer
const auto st_buffer = preconstructCheckFEDSpyBuffer(input);
if (sistrip::FEDBufferStatusCode::SUCCESS != st_buffer) {
edm::LogWarning("SiStripSpyUnpacker")
<< "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": "
<< "An exception of category 'FEDBuffer' occurred.\n"
<< st_buffer;
continue;
}
const sistrip::FEDSpyBuffer buffer{input};
if (!buffer.doChecks() && !allowIncompleteEvents_) {
edm::LogWarning("SiStripSpyUnpacker")
<< "Exception caught when creating FEDSpyBuffer object for FED " << lFedId << ": "
<< "An exception of category 'FEDSpyBuffer' occurred.\n"
<< "FED Buffer check fails for FED ID " << lFedId << ".";
continue;
}
// end of buffer reset try.
// Get the event counter values
uint32_t totalEvCount = buffer.spyHeaderTotalEventCount();
uint32_t l1ID = buffer.spyHeaderL1ID();
uint32_t lGRun = buffer.globalRunNumber();
//for the first fed, put it as reference value for others
if (lRef == 0)
lRef = lGRun;
if (lGRun != lRef) {
edm::LogError("SiStripSpyUnpacker") << " -- Global run encoded in buffer for FED " << lFedId << ": " << lGRun
<< " is different from reference value " << lRef << std::endl;
}
// Add event counters
(*pL1ACounts)[lFedId] = l1ID;
(*pTotalEventCounts)[lFedId] = totalEvCount;
//iterate through FED channels, extract payload and create Digis
std::vector<FedChannelConnection>::const_iterator iconn = conns.begin();
std::vector<FedChannelConnection>::const_iterator endconn = conns.end();
for (; iconn != endconn; ++iconn) {
//check if fed connection is valid
if (!iconn->isConnected()) {
continue;
}
//FED channel
uint16_t chan = iconn->fedCh();
//check values are valid:
if (chan > FEDCH_PER_FED || iconn->fedId() != lFedId) {
if (edm::isDebugEnabled()) {
std::ostringstream ss;
ss << "Channel connection values invalid: iconn->fedId() = " << iconn->fedId() << " for FED " << lFedId
<< ", iconn->fedCh() = " << chan << std::endl;
edm::LogWarning("SiStripSpyUnpacker") << ss.str();
}
continue;
}
//check FED channel
if (!buffer.channelGood(chan)) {
if (edm::isDebugEnabled()) {
std::ostringstream ss;
ss << "Channel check failed for FED " << lFedId << " channel " << chan << std::endl;
edm::LogWarning("SiStripSpyUnpacker") << ss.str();
}
continue;
}
//determine key from cabling
const uint32_t key = ((lFedId & sistrip::invalid_) << 16) | (chan & sistrip::invalid_);
// Start a new channel in the filler
dsvFiller.newChannel(key);
// Create the unpacker object
sistrip::FEDSpyChannelUnpacker unpacker = sistrip::FEDSpyChannelUnpacker(buffer.channel(chan));
// Unpack the data into dsv filler
while (unpacker.hasData()) {
dsvFiller.addItem(SiStripRawDigi{unpacker.adc()});
unpacker++;
}
} // end of channel loop
} //fed loop
//set the run number
*aRunRef = lRef;
//create DSV to return
std::unique_ptr<RawDigis> pResult = dsvFiller.createDetSetVector();
pDigis->swap(*pResult);
} // end of SpyUnpacker::createDigis method.
} // namespace sistrip
|