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
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
|
// Skip FED40 pilot-blade
// Include parameter driven interface to SiPixelQuality for study purposes
// exclude ROC(raw) based on bad ROC list in SiPixelQuality
// enabled by: process.siPixelDigis.useQualityInfo = True (BY DEFAULT NOT USED)
// 20-10-2010 Andrew York (Tennessee)
// Jan 2016 Tamas Almos Vami (Tav) (Wigner RCP) -- Cabling Map label option
// Jul 2017 Viktor Veszpremi -- added PixelFEDChannel
#include <memory>
#include "DataFormats/Common/interface/Handle.h"
#include "FWCore/Framework/interface/ESHandle.h"
#include "FWCore/Framework/interface/ESTransientHandle.h"
#include "FWCore/Framework/interface/ESWatcher.h"
#include "FWCore/Framework/interface/stream/EDProducer.h"
#include "FWCore/Framework/interface/EventSetup.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/ConsumesCollector.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"
#include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
#include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
#include "FWCore/Utilities/interface/ESGetToken.h"
#include "FWCore/MessageLogger/interface/MessageLogger.h"
#include "CondFormats/DataRecord/interface/SiPixelFedCablingMapRcd.h"
#include "CondFormats/DataRecord/interface/SiPixelQualityRcd.h"
#include "CondFormats/SiPixelObjects/interface/SiPixelQuality.h"
#include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingMap.h"
#include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingTree.h"
#include "DataFormats/Common/interface/DetSetVector.h"
#include "DataFormats/Common/interface/DetSetVectorNew.h"
#include "DataFormats/DetId/interface/DetIdCollection.h"
#include "DataFormats/FEDRawData/interface/FEDRawData.h"
#include "DataFormats/FEDRawData/interface/FEDRawDataCollection.h"
#include "DataFormats/SiPixelDigi/interface/PixelDigi.h"
#include "DataFormats/SiPixelDetId/interface/PixelFEDChannel.h"
#include "DataFormats/SiPixelRawData/interface/SiPixelRawDataError.h"
#include "DataFormats/SiPixelDigi/interface/SiPixelDigiConstants.h"
#include "EventFilter/SiPixelRawToDigi/interface/PixelDataFormatter.h"
#include "EventFilter/SiPixelRawToDigi/interface/PixelUnpackingRegions.h"
using namespace sipixelconstants;
/** \class SiPixelRawToDigi
* Plug-in module that performs Raw data to digi conversion
* for pixel subdetector
*/
class SiPixelRawToDigi : public edm::stream::EDProducer<> {
public:
/// ctor
explicit SiPixelRawToDigi(const edm::ParameterSet&);
/// dtor
~SiPixelRawToDigi() override;
static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
/// get data, convert to digis attach againe to Event
void produce(edm::Event&, const edm::EventSetup&) override;
private:
edm::ParameterSet config_;
std::unique_ptr<SiPixelFedCablingTree> cabling_;
const SiPixelQuality* badPixelInfo_;
PixelUnpackingRegions* regions_;
const std::vector<int> tkerrorlist_;
const std::vector<int> usererrorlist_;
std::vector<unsigned int> fedIds_;
edm::ESWatcher<SiPixelFedCablingMapRcd> recordWatcher_;
edm::ESWatcher<SiPixelQualityRcd> qualityWatcher_;
// always consumed
const edm::EDGetTokenT<FEDRawDataCollection> fedRawDataCollectionToken_;
const edm::ESGetToken<SiPixelFedCablingMap, SiPixelFedCablingMapRcd> cablingMapToken_;
// consume only if pixel quality is used -> useQuality_
edm::ESGetToken<SiPixelQuality, SiPixelQualityRcd> siPixelQualityToken_;
// always produced
const edm::EDPutTokenT<edm::DetSetVector<PixelDigi>> siPixelDigiCollectionToken_;
// produce only if error collections are included -> includeErrors_
edm::EDPutTokenT<edm::DetSetVector<SiPixelRawDataError>> errorPutToken_;
edm::EDPutTokenT<DetIdCollection> tkErrorPutToken_;
edm::EDPutTokenT<DetIdCollection> userErrorPutToken_;
edm::EDPutTokenT<edmNew::DetSetVector<PixelFEDChannel>> disabledChannelPutToken_;
const bool includeErrors_;
const bool useQuality_;
const bool usePilotBlade_;
const bool usePhase1_;
};
// -----------------------------------------------------------------------------
SiPixelRawToDigi::SiPixelRawToDigi(const edm::ParameterSet& conf)
: config_(conf),
badPixelInfo_(nullptr),
regions_(nullptr),
tkerrorlist_(config_.getParameter<std::vector<int>>("ErrorList")),
usererrorlist_(config_.getParameter<std::vector<int>>("UserErrorList")),
fedRawDataCollectionToken_{consumes<FEDRawDataCollection>(config_.getParameter<edm::InputTag>("InputLabel"))},
cablingMapToken_{esConsumes<SiPixelFedCablingMap, SiPixelFedCablingMapRcd>(
edm::ESInputTag("", config_.getParameter<std::string>("CablingMapLabel")))},
siPixelDigiCollectionToken_{produces<edm::DetSetVector<PixelDigi>>()},
includeErrors_(config_.getParameter<bool>("IncludeErrors")),
useQuality_(config_.getParameter<bool>("UseQualityInfo")),
usePilotBlade_(config_.getParameter<bool>("UsePilotBlade")),
usePhase1_(config_.getParameter<bool>("UsePhase1"))
{
if (useQuality_) {
siPixelQualityToken_ = esConsumes<SiPixelQuality, SiPixelQualityRcd>(
edm::ESInputTag("", config_.getParameter<std::string>("SiPixelQualityLabel")));
}
// Products
if (includeErrors_) {
errorPutToken_ = produces<edm::DetSetVector<SiPixelRawDataError>>();
tkErrorPutToken_ = produces<DetIdCollection>();
userErrorPutToken_ = produces<DetIdCollection>("UserErrorModules");
disabledChannelPutToken_ = produces<edmNew::DetSetVector<PixelFEDChannel>>();
}
// regions
if (!config_.getParameter<edm::ParameterSet>("Regions").getParameterNames().empty()) {
regions_ = new PixelUnpackingRegions(config_, consumesCollector());
}
// Control the usage of pilot-blade data, FED=40
if (usePilotBlade_)
edm::LogInfo("SiPixelRawToDigi") << " Use pilot blade data (FED 40)";
// Control the usage of phase1
if (usePhase1_)
edm::LogInfo("SiPixelRawToDigi") << " Using phase1";
}
// -----------------------------------------------------------------------------
SiPixelRawToDigi::~SiPixelRawToDigi() {
edm::LogInfo("SiPixelRawToDigi") << " HERE ** SiPixelRawToDigi destructor!";
if (regions_)
delete regions_;
}
void SiPixelRawToDigi::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
edm::ParameterSetDescription desc;
desc.add<bool>("IncludeErrors", true);
desc.add<bool>("UseQualityInfo", false);
{
desc.add<std::vector<int>>("ErrorList", std::vector<int>{29})
->setComment("## ErrorList: list of error codes used by tracking to invalidate modules");
}
{
desc.add<std::vector<int>>("UserErrorList", std::vector<int>{40})
->setComment("## UserErrorList: list of error codes used by Pixel experts for investigation");
}
desc.add<edm::InputTag>("InputLabel", edm::InputTag("siPixelRawData"));
{
edm::ParameterSetDescription psd0;
psd0.addOptional<std::vector<edm::InputTag>>("inputs");
psd0.addOptional<std::vector<double>>("deltaPhi");
psd0.addOptional<std::vector<double>>("maxZ");
psd0.addOptional<edm::InputTag>("beamSpot");
desc.add<edm::ParameterSetDescription>("Regions", psd0)
->setComment("## Empty Regions PSet means complete unpacking");
}
desc.add<bool>("UsePilotBlade", false)->setComment("## Use pilot blades");
desc.add<bool>("UsePhase1", false)->setComment("## Use phase1");
desc.add<std::string>("CablingMapLabel", "")->setComment("CablingMap label"); //Tav
desc.add<std::string>("SiPixelQualityLabel", "")->setComment("SiPixelQuality label");
descriptions.add("siPixelRawToDigi", desc);
}
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
void SiPixelRawToDigi::produce(edm::Event& ev, const edm::EventSetup& es) {
const uint32_t dummydetid = 0xffffffff;
// initialize cabling map or update if necessary
if (recordWatcher_.check(es)) {
// cabling map, which maps online address (fed->link->ROC->local pixel) to offline (DetId->global pixel)
edm::ESHandle<SiPixelFedCablingMap> cablingMap = es.getHandle(cablingMapToken_);
fedIds_ = cablingMap->fedIds();
cabling_ = cablingMap->cablingTree();
LogDebug("map version:") << cabling_->version();
}
// initialize quality record or update if necessary
if (qualityWatcher_.check(es) && useQuality_) {
// quality info for dead pixel modules or ROCs
edm::ESHandle<SiPixelQuality> qualityInfo = es.getHandle(siPixelQualityToken_);
badPixelInfo_ = qualityInfo.product();
if (!badPixelInfo_) {
edm::LogError("SiPixelQualityNotPresent") << "Configured to use SiPixelQuality, but SiPixelQuality not present";
}
}
edm::Handle<FEDRawDataCollection> buffers;
ev.getByToken(fedRawDataCollectionToken_, buffers);
// create product (digis & errors)
auto collection = edm::DetSetVector<PixelDigi>();
// collection->reserve(8*1024);
auto errorcollection = edm::DetSetVector<SiPixelRawDataError>{};
auto tkerror_detidcollection = DetIdCollection{};
auto usererror_detidcollection = DetIdCollection{};
auto disabled_channelcollection = edmNew::DetSetVector<PixelFEDChannel>{};
PixelDataFormatter formatter(cabling_.get(), usePhase1_); // for phase 1 & 0
formatter.setErrorStatus(includeErrors_);
if (useQuality_)
formatter.setQualityStatus(useQuality_, badPixelInfo_);
bool errorsInEvent = false;
PixelDataFormatter::DetErrors nodeterrors;
if (regions_) {
regions_->run(ev, es);
formatter.setModulesToUnpack(regions_->modulesToUnpack());
LogDebug("SiPixelRawToDigi") << "region2unpack #feds: " << regions_->nFEDs();
LogDebug("SiPixelRawToDigi") << "region2unpack #modules (BPIX,EPIX,total): " << regions_->nBarrelModules() << " "
<< regions_->nForwardModules() << " " << regions_->nModules();
}
for (auto aFed = fedIds_.begin(); aFed != fedIds_.end(); ++aFed) {
int fedId = *aFed;
if (!usePilotBlade_ && (fedId == 40))
continue; // skip pilot blade data
if (regions_ && !regions_->mayUnpackFED(fedId))
continue;
LogDebug("SiPixelRawToDigi") << "PRODUCE DIGI FOR FED:" << fedId;
PixelDataFormatter::Errors errors;
//get event data for this fed
const FEDRawData& fedRawData = buffers->FEDData(fedId);
//convert data to digi and strip off errors
formatter.interpretRawData(errorsInEvent, fedId, fedRawData, collection, errors);
//pack errors into collection
if (includeErrors_) {
formatter.unpackFEDErrors(errors,
tkerrorlist_,
usererrorlist_,
errorcollection,
tkerror_detidcollection,
usererror_detidcollection,
disabled_channelcollection,
nodeterrors);
} // if errors to be included in the event
} // loop on FED data to be unpacked
if (includeErrors_) {
edm::DetSet<SiPixelRawDataError>& errorDetSet = errorcollection.find_or_insert(dummydetid);
errorDetSet.data = nodeterrors;
}
if (errorsInEvent)
LogDebug("SiPixelRawToDigi") << "Error words were stored in this event";
ev.emplace(siPixelDigiCollectionToken_, std::move(collection));
if (includeErrors_) {
ev.emplace(errorPutToken_, std::move(errorcollection));
ev.emplace(tkErrorPutToken_, std::move(tkerror_detidcollection));
ev.emplace(userErrorPutToken_, std::move(usererror_detidcollection));
ev.emplace(disabledChannelPutToken_, std::move(disabled_channelcollection));
}
}
// declare this as a framework plugin
#include "FWCore/Framework/interface/MakerMacros.h"
DEFINE_FWK_MODULE(SiPixelRawToDigi);
|