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
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
|
// -*- C++ -*-
//
// Package: SiPixelCalibDigiProducer
// Class: SiPixelCalibDigiProducer
//
/**\class SiPixelCalibDigiProducer SiPixelCalibDigiProducer.cc CalibTracker/SiPixelCalibDigiProducer/src/SiPixelCalibDigiProducer.cc
Description: <one line class summary>
Implementation:
<Notes on implementation>
*/
//
// Original Author: Freya Blekman
// Created: Wed Oct 31 15:28:52 CET 2007
//
//
// system include files
// user include files
#include "FWCore/Framework/interface/EventSetup.h"
#include "Geometry/Records/interface/TrackerDigiGeometryRecord.h"
#include "DataFormats/SiPixelDigi/interface/SiPixelCalibDigiError.h"
#include "CondFormats/SiPixelObjects/interface/SiPixelFrameConverter.h"
#include "CondFormats/SiPixelObjects/interface/SiPixelFedCablingMap.h"
#include "CondFormats/SiPixelObjects/interface/ElectronicIndex.h"
#include "CondFormats/SiPixelObjects/interface/DetectorIndex.h"
#include "CondFormats/SiPixelObjects/interface/LocalPixel.h"
#include "SiPixelCalibDigiProducer.h"
#include <sstream>
//
// constants, enums and typedefs
//
//
// static data member definitions
//
//
// constructors and destructor
//
SiPixelCalibDigiProducer::SiPixelCalibDigiProducer(const edm::ParameterSet& iConfig)
: src_(iConfig.getParameter<edm::InputTag>("src")),
iEventCounter_(0),
ignore_non_pattern_(iConfig.getParameter<bool>("ignoreNonPattern")),
control_pattern_size_(iConfig.getParameter<bool>("checkPatternEachEvent")),
includeErrors_(iConfig.getUntrackedParameter<bool>("includeErrors", false)),
errorType(iConfig.getUntrackedParameter<int>("errorTypeNumber", 1)),
conf_(iConfig),
number_of_pixels_per_pattern_(0),
use_realeventnumber_(iConfig.getParameter<bool>("useRealEventNumber"))
{
tPixelDigi = consumes<edm::DetSetVector<PixelDigi>>(src_);
//register your products
produces<edm::DetSetVector<SiPixelCalibDigi>>();
if (includeErrors_)
produces<edm::DetSetVector<SiPixelCalibDigiError>>();
calibToken_ = esConsumes<SiPixelCalibConfiguration, SiPixelCalibConfigurationRcd>();
trackerGeomToken_ = esConsumes<TrackerGeometry, TrackerDigiGeometryRecord>();
cablingMapToken_ = esConsumes<SiPixelFedCablingMap, SiPixelFedCablingMapRcd>();
}
SiPixelCalibDigiProducer::~SiPixelCalibDigiProducer() {
// do anything here that needs to be done at desctruction time
// (e.g. close files, deallocate resources etc.)
}
//
// member functions
//
/////////////////////////////////////////////
// function description:
// this function checks where/when the pattern changes so that one can fill the data from the temporary container into the event
bool SiPixelCalibDigiProducer::store() {
// std::cout << "in store() " << std::endl;
if (iEventCounter_ % pattern_repeat_ == 0) {
// std::cout << "now at event " << iEventCounter_ <<" where we save the calibration information into the CMSSW digi";
return true;
} else if (iEventCounter_ == calib_->expectedTotalEvents())
return true;
else
return false;
return true;
}
////////////////////////////////////////////////////////////////////
// function description:
// fill function, uses maps to keep track of which pixel is where in the local storage container. Called every event to fill and compress the digi data into calibdig format
void SiPixelCalibDigiProducer::fill(edm::Event& iEvent, const edm::EventSetup& iSetup) {
// figure out which calibration point we're on now..
short icalibpoint = calib_->vcalIndexForEvent(iEventCounter_);
edm::Handle<edm::DetSetVector<PixelDigi>> pixelDigis;
iEvent.getByToken(tPixelDigi, pixelDigis);
edm::LogInfo("SiPixelCalibProducer") << "in fill(), calibpoint " << icalibpoint << " ndigis " << pixelDigis->size()
<< std::endl;
// loop over the data and store things
edm::DetSetVector<PixelDigi>::const_iterator digiIter;
for (digiIter = pixelDigis->begin(); digiIter != pixelDigis->end(); ++digiIter) { // ITERATOR OVER DET IDs
uint32_t detid = digiIter->id;
edm::DetSet<PixelDigi>::const_iterator ipix; // ITERATOR OVER DIGI DATA
for (ipix = digiIter->data.begin(); ipix != digiIter->end(); ++ipix) {
// fill in the appropriate location of the temporary data container
fillPixel(detid, ipix->row(), ipix->column(), icalibpoint, ipix->adc());
}
}
}
////////////////////////////////////////////////////
// function description:
// this is the function where we check the cabling map and see if we can assign a fed id to the det ID.
// returns false if no fed <-> detid association was found
bool SiPixelCalibDigiProducer::checkFED(uint32_t detid) {
// edm::LogInfo("SiPixelCalibProducer") << "in checkFED" << std::endl;
if (detid_to_fedid_[detid])
return true;
for (int fedid = 0; fedid <= 40; ++fedid) {
// edm::LogInfo("SiPixelCalibProducer") << " looking at fedid " << fedid << std::endl;
SiPixelFrameConverter converter(theCablingMap_.product(), fedid);
if (converter.hasDetUnit(detid)) {
detid_to_fedid_[detid] = fedid;
edm::LogInfo("SiPixelCalibDigiProducer")
<< "matched detid " << detid << " to fed " << detid_to_fedid_[detid] << std::endl;
return true;
}
}
return false;
}
////////////////////////////////////////////////////
// function description:
// this is the function where we look in the maps to find the correct calibration digi container, after which the data is filled.
void SiPixelCalibDigiProducer::fillPixel(uint32_t detid, short row, short col, short ipoint, short adc) {
// edm::LogInfo("SiPixelCalibProducer") << " in fillpixel()" << std::endl;
// edm::LogInfo("SiPixelCalibProducer") << "in fillPixel " << detid << " " << row << " " << col << " " << ipoint << " " << adc << std::endl;
if (!checkFED(detid)) {
edm::LogError("SiPixelCalibDigiProducer") << " was unable to match detid " << detid << " to a FED!" << std::endl;
return;
}
if (!checkPixel(detid, row, col)) {
return;
}
// now the check if the pixel exists and fill
//
pixelstruct temppixelworker;
temppixelworker.first = detid;
temppixelworker.second.first = row;
temppixelworker.second.second = col;
std::map<pixelstruct, SiPixelCalibDigi>::const_iterator ipix = intermediate_data_.find(temppixelworker);
if (ipix == intermediate_data_.end()) {
SiPixelCalibDigi tempdigi(calib_->nVCal());
tempdigi.setrowcol(row, col);
intermediate_data_[temppixelworker] = tempdigi;
}
intermediate_data_[temppixelworker].fill(ipoint, adc);
return;
}
//////////////////////////////////////////////////////////////
// function description:
// this function cleans up after everything in the pattern is filled. This involves setting the content of the intermediate_data_ containers to zero and completely emptying the map
void SiPixelCalibDigiProducer::clear() {
// edm::LogInfo("SiPixelCalibProducer") << "in clear() " << std::endl;
// this is where we empty the containers so they can be re-filled
// the idea: the detPixelMap_ container shrinks/expands as a function
// of the number of pixels looked at at one particular time...
// unlike the intermediate_data_ container which only expands when
// detPixelMap_ becomes bigger than intermedate_data_
// shrink the detPixelMap_
uint32_t tempsize = intermediate_data_.size();
if (tempsize > number_of_pixels_per_pattern_) {
edm::LogError("SiPixelCalibDigiProducer") << "Number of pixels in pattern is now: " << tempsize << ", size is was "
<< number_of_pixels_per_pattern_ << std::endl;
number_of_pixels_per_pattern_ = tempsize;
}
intermediate_data_.erase(intermediate_data_.begin(), intermediate_data_.end());
intermediate_data_.clear();
// and erase the error bits
error_data_.erase(error_data_.begin(), error_data_.end());
error_data_.clear();
}
////////////////////////////////////////////////////
// function description:
// This method gets the pattern from the calib_ (SiPixelCalibConfiguration) object and fills a vector of pairs that is easier to check
void SiPixelCalibDigiProducer::setPattern() {
// edm::LogInfo("SiPixelCalibProducer") << "in setPattern()" << std::endl;
uint32_t patternnumber = (iEventCounter_ - 1) / pattern_repeat_;
uint32_t rowpatternnumber = patternnumber / calib_->nColumnPatterns();
uint32_t colpatternnumber = patternnumber % calib_->nColumnPatterns();
edm::LogInfo("SiPixelCalibDigiProducer")
<< " rowpatternnumbers = " << rowpatternnumber << " " << colpatternnumber << " " << patternnumber << std::endl;
// update currentpattern_
std::vector<short> calibcols = calib_->getColumnPattern();
std::vector<short> calibrows = calib_->getRowPattern();
std::vector<short> temprowvals(0);
std::vector<short> tempcolvals(0);
uint32_t nminuscol = 0;
uint32_t nminusrow = 0;
uint32_t npatterns = 0;
for (uint32_t icol = 0; icol < calibcols.size(); icol++) {
if (calibcols[icol] == -1) {
nminuscol++;
} else if (nminuscol == colpatternnumber) {
//edm::LogInfo("SiPixelCalibProducer") << "col " << calibcols[icol] << std::endl;
short val = calibcols[icol];
tempcolvals.push_back(val);
} else if (nminuscol > colpatternnumber)
break;
}
for (uint32_t irow = 0; irow < calibrows.size(); irow++) {
// edm::LogInfo("SiPixelCalibProducer") << "row " << irow <<" "<< nminusrow<<" " << calibrows[irow] << std::endl;
if (calibrows[irow] == -1)
nminusrow++;
else if (nminusrow == rowpatternnumber) {
short val = calibrows[irow];
temprowvals.push_back(val);
} else if (nminusrow > rowpatternnumber)
break;
}
//now clean up the currentpattern_;
while (currentpattern_.size() > temprowvals.size() * tempcolvals.size()) {
currentpattern_.erase(currentpattern_.end());
}
for (uint32_t irow = 0; irow < temprowvals.size(); irow++) {
for (uint32_t icol = 0; icol < tempcolvals.size(); icol++) {
std::pair<short, short> pattern(temprowvals[irow], tempcolvals[icol]);
npatterns++;
if (npatterns > currentpattern_.size())
currentpattern_.push_back(pattern);
else
currentpattern_[npatterns - 1] = pattern;
}
}
}
////////////////////////////////////////////
// function description:
// produce method. This is the main loop method
void SiPixelCalibDigiProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
// edm::LogInfo("SiPixelCalibDigiProducer") <<"in produce() " << std::endl;
using namespace edm;
calib_ = iSetup.getHandle(calibToken_);
theGeometry_ = iSetup.getHandle(trackerGeomToken_);
theCablingMap_ = iSetup.getHandle(cablingMapToken_);
pattern_repeat_ = calib_->getNTriggers() * calib_->nVCal();
if (use_realeventnumber_) {
iEventCounter_ = iEvent.id().event() - 1;
} else
iEventCounter_++;
if (iEventCounter_ % pattern_repeat_ == 1)
setPattern();
// edm::LogInfo("SiPixelCalibDigiProducer") << "now starting fill..." << std::endl;
fill(iEvent, iSetup); // fill method where the actual looping over the digis is done.
// edm::LogInfo("SiPixelCalibDigiProducer") << "done filling..." << std::endl;
auto pOut = std::make_unique<edm::DetSetVector<SiPixelCalibDigi>>();
auto pErr = std::make_unique<edm::DetSetVector<SiPixelCalibDigiError>>();
// copy things over into pOut if necessary (this is only once per pattern)
if (store()) {
// edm::LogInfo("SiPixelCalibDigiProducer") << "in loop" << std::endl;
for (std::map<pixelstruct, SiPixelCalibDigi>::const_iterator idet = intermediate_data_.begin();
idet != intermediate_data_.end();
++idet) {
uint32_t detid = idet->first.first;
if (!control_pattern_size_) {
if (!checkPixel(idet->first.first, idet->first.second.first, idet->first.second.second))
continue;
}
SiPixelCalibDigi tempdigi = idet->second;
edm::DetSet<SiPixelCalibDigi>& detSet = pOut->find_or_insert(detid);
detSet.data.push_back(tempdigi);
}
if (includeErrors_) {
for (std::map<pixelstruct, SiPixelCalibDigiError>::const_iterator ierr = error_data_.begin();
ierr != error_data_.end();
++ierr) {
uint32_t detid = ierr->first.first;
SiPixelCalibDigiError temperror = ierr->second;
edm::DetSet<SiPixelCalibDigiError>& errSet = pErr->find_or_insert(detid);
errSet.data.push_back(temperror);
}
}
edm::LogInfo("INFO") << "now filling event " << iEventCounter_ << " as pixel pattern changes every "
<< pattern_repeat_ << " events..." << std::endl;
clear();
}
iEvent.put(std::move(pOut));
if (includeErrors_)
iEvent.put(std::move(pErr));
}
//-----------------------------------------------
// method to check that the pixels are actually valid...
bool SiPixelCalibDigiProducer::checkPixel(uint32_t detid, short row, short col) {
if (!control_pattern_size_ && !store())
return true;
if (!ignore_non_pattern_)
return true;
edm::LogInfo("SiPixelCalibDigiProducer") << "Event" << iEventCounter_ << ",now in checkpixel() " << std::endl;
if (currentpattern_.empty())
setPattern();
// uint32_t iroc;
uint32_t fedid = detid_to_fedid_[detid];
SiPixelFrameConverter formatter(theCablingMap_.product(), fedid);
sipixelobjects::DetectorIndex detector = {detid, row, col};
sipixelobjects::ElectronicIndex cabling;
formatter.toCabling(cabling, detector);
// cabling should now contain cabling.roc and cabling.dcol and cabling.pxid
// however, the coordinates now need to be converted from dcl, pxid to the row,col coordinates used in the calibration info
sipixelobjects::LocalPixel::DcolPxid loc;
loc.dcol = cabling.dcol;
loc.pxid = cabling.pxid;
sipixelobjects::LocalPixel locpixel(loc);
currentpair_.first = locpixel.rocRow();
currentpair_.second = locpixel.rocCol();
for (uint32_t i = 0; i < currentpattern_.size(); ++i) {
// edm::LogInfo("SiPixelCalibDigiProducer") << "found pair " << currentpair_.first << "," << currentpair_.second << " calib " << currentpattern_[i].first << ","<< currentpattern_[i].second << " input " << row << "," << col << std::endl;
if (currentpair_ == currentpattern_[i]) {
return true;
}
}
std::ostringstream errorlog;
errorlog << "DETID " << detid << ", row, col (offline)=" << row << "," << col
<< " row, col (ROC) =" << currentpair_.first << "," << currentpair_.second
<< " found no match in list of patterns: ";
for (uint32_t i = 0; i < currentpattern_.size(); ++i) {
if (i != 0 && i != currentpattern_.size() - 1)
errorlog << " ";
errorlog << "(";
errorlog << currentpattern_[i].first;
errorlog << ",";
errorlog << currentpattern_[i].second;
errorlog << ")";
}
edm::LogError("ERROR") << errorlog.str() << std::endl;
if (includeErrors_) { // book the error
pixelstruct temppixelworker;
temppixelworker.first = detid;
temppixelworker.second.first = row;
temppixelworker.second.second = col;
std::map<pixelstruct, SiPixelCalibDigiError>::const_iterator ierr = error_data_.find(temppixelworker);
if (ierr == error_data_.end()) {
SiPixelCalibDigiError temperr(row, col, 1);
error_data_[temppixelworker] = temperr;
}
}
return false;
}
DEFINE_FWK_MODULE(SiPixelCalibDigiProducer);
|