CMS 3D CMS Logo

SiPixelGainCalibScaler.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: Tools/SiPixelGainCalibScaler
4 // Class: SiPixelGainCalibScaler
5 //
13 //
14 // Original Author: Marco Musich
15 // Created: Thu, 16 Jul 2020 10:36:21 GMT
16 //
17 //
18 
19 // system include files
20 #include <memory>
21 
22 // user include files
49 
50 //
51 // class declaration
52 //
53 
54 // If the analyzer does not use TFileService, please remove
55 // the template argument to the base class so the class inherits
56 // from edm::one::EDAnalyzer<>
57 // This will improve performance in multithreaded jobs.
58 
59 namespace gainScale {
60  struct VCalInfo {
61  private:
64  double m_offset;
65  double m_offsetL1;
66 
67  public:
68  // default constructor
70 
71  // initialize
72  void init(double conversionFactor, double conversionFactorL1, double offset, double offsetL1) {
73  m_conversionFactor = conversionFactor;
74  m_conversionFactorL1 = conversionFactorL1;
75  m_offset = offset;
76  m_offsetL1 = offsetL1;
77  }
78 
79  void printAllInfo() {
80  edm::LogVerbatim("SiPixelGainCalibScaler") << " conversion factor : " << m_conversionFactor << "\n"
81  << " conversion factor (L1) : " << m_conversionFactorL1 << "\n"
82  << " offset : " << m_offset << "\n"
83  << " offset (L1) : " << m_offsetL1 << "\n";
84  }
85 
88  double getOffset() { return m_offset; }
89  double getOffsetL1() { return m_offsetL1; }
90  virtual ~VCalInfo() {}
91  };
92 } // namespace gainScale
93 
94 class SiPixelGainCalibScaler : public edm::one::EDAnalyzer<edm::one::SharedResources> {
95 public:
97  ~SiPixelGainCalibScaler() override;
98 
99  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
100 
101 private:
102  void beginJob() override;
103  void analyze(const edm::Event&, const edm::EventSetup&) override;
104  void endJob() override;
105  template <class tokenType, class PayloadType>
106  void computeAndStorePalyoads(const edm::EventSetup& iSetup, const tokenType& token);
107 
108  // ----------member data ---------------------------
110  const bool isForHLT_;
111  const bool verbose_;
112  const std::vector<edm::ParameterSet> m_parameters;
113 
116 
121 
124 };
125 
126 //
127 // constructors and destructor
128 //
130  : recordName_(iConfig.getParameter<std::string>("record")),
131  isForHLT_(iConfig.getParameter<bool>("isForHLT")),
132  verbose_(iConfig.getUntrackedParameter<bool>("verbose", false)),
133  m_parameters(iConfig.getParameter<std::vector<edm::ParameterSet> >("parameters")) {
138 
139  for (auto& thePSet : m_parameters) {
140  const unsigned int phase(thePSet.getParameter<unsigned int>("phase"));
141  switch (phase) {
142  case 0: {
143  phase0VCal.init(thePSet.getParameter<double>("conversionFactor"),
144  thePSet.getParameter<double>("conversionFactorL1"),
145  thePSet.getParameter<double>("offset"),
146  thePSet.getParameter<double>("offsetL1"));
147  break;
148  }
149  case 1: {
150  phase1VCal.init(thePSet.getParameter<double>("conversionFactor"),
151  thePSet.getParameter<double>("conversionFactorL1"),
152  thePSet.getParameter<double>("offset"),
153  thePSet.getParameter<double>("offsetL1"));
154  break;
155  }
156  default:
157  throw cms::Exception("LogicError") << "Unrecongnized phase: " << phase << ". Exiting!";
158  }
159  }
160 }
161 
163 
164 //
165 // member functions
166 //
167 
168 // ------------ method called for each event ------------
170  using namespace edm;
171 
172  int run = iEvent.id().run();
173  bool hasPixelHLTGainIOV = pixelHLTGainWatcher_.check(iSetup);
174  bool hasPixelOfflineGainIOV = pixelOfflineGainWatcher_.check(iSetup);
175 
176  if ((hasPixelHLTGainIOV && isForHLT_) || (hasPixelOfflineGainIOV && !isForHLT_)) {
177  edm::LogPrint("SiPixelGainCalibScaler") << " Pixel Gains have a new IOV for run: " << run << std::endl;
178 
179  if (isForHLT_) {
180  computeAndStorePalyoads<edm::ESGetToken<SiPixelGainCalibrationForHLT, SiPixelGainCalibrationForHLTRcd>,
182  } else {
183  computeAndStorePalyoads<edm::ESGetToken<SiPixelGainCalibrationOffline, SiPixelGainCalibrationOfflineRcd>,
185  }
186  } // if new IOV
187 }
188 
189 // ------------ template method to construct the payloads ------------
190 template <class tokenType, class PayloadType>
192  gainScale::VCalInfo myVCalInfo;
193 
194  //=======================================================
195  // Retrieve geometry information
196  //=======================================================
197  const TrackerGeometry* pDD = &iSetup.getData(tkGeomToken_);
198  edm::LogInfo("SiPixelGainCalibScaler") << "There are: " << pDD->dets().size() << " detectors";
199 
200  // switch on the phase1
202  myVCalInfo = phase1VCal;
203  edm::LogInfo("SiPixelGainCalibScaler") << " ==> This is a phase1 IOV";
204  } else {
205  myVCalInfo = phase0VCal;
206  edm::LogInfo("SiPixelGainCalibScaler") << " ==> This is a phase0 IOV";
207  }
208 
209  myVCalInfo.printAllInfo();
210 
211  // if need the ESHandle to check if the SetupData was there or not
212  auto payload = &iSetup.getData(token);
213  std::vector<uint32_t> detids;
214  payload->getDetIds(detids);
215 
216  float mingain = payload->getGainLow();
217  float maxgain = (payload->getGainHigh()) * myVCalInfo.getConversionFactorL1();
218  float minped = payload->getPedLow();
219  float maxped = payload->getPedHigh() * 1.10;
220 
221  PayloadType SiPixelGainCalibration_(minped, maxped, mingain, maxgain);
222 
223  //Retrieve tracker topology from geometry
224  const TrackerTopology* tTopo = &iSetup.getData(tkTopoToken_);
225 
226  // possible to load it not from EventSetup
227  //const char* path_toTopologyXML = "Geometry/TrackerCommonData/data/PhaseI/trackerParameters.xml";
228  //TrackerTopology tTopo = StandaloneTrackerTopology::fromTrackerParametersXMLFile(edm::FileInPath(path_toTopologyXML).fullPath());
229 
230  for (const auto& d : detids) {
231  bool isLayer1 = false;
232  int subid = DetId(d).subdetId();
233  if (subid == PixelSubdetector::PixelBarrel) {
234  auto layer = tTopo->pxbLayer(DetId(d));
235  if (layer == 1) {
236  isLayer1 = true;
237  }
238  }
239 
240  std::vector<char> theSiPixelGainCalibration;
241 
242  auto range = payload->getRange(d);
243  int numberOfRowsToAverageOver = payload->getNumberOfRowsToAverageOver();
244  int ncols = payload->getNCols(d);
245  int nRocsInRow = (range.second - range.first) / ncols / numberOfRowsToAverageOver;
246  unsigned int nRowsForHLT = 1;
247  int nrows = std::max((payload->getNumberOfRowsToAverageOver() * nRocsInRow),
248  nRowsForHLT); // dirty trick to make it work for the HLT payload
249 
250  auto rangeAndCol = payload->getRangeAndNCols(d);
251  bool isDeadColumn;
252  bool isNoisyColumn;
253 
254  if (verbose_) {
255  edm::LogVerbatim("SiPixelGainCalibScaler")
256  << "NCOLS: " << payload->getNCols(d) << " " << rangeAndCol.second << " NROWS:" << nrows
257  << ", RANGES: " << rangeAndCol.first.second - rangeAndCol.first.first
258  << ", Ratio: " << float(rangeAndCol.first.second - rangeAndCol.first.first) / rangeAndCol.second << std::endl;
259  }
260 
261  for (int col = 0; col < ncols; col++) {
262  for (int row = 0; row < nrows; row++) {
263  float gain = payload->getGain(col, row, rangeAndCol.first, rangeAndCol.second, isDeadColumn, isNoisyColumn);
264  float ped = payload->getPed(col, row, rangeAndCol.first, rangeAndCol.second, isDeadColumn, isNoisyColumn);
265 
266  if (verbose_)
267  edm::LogInfo("SiPixelGainCalibScaler") << "pre-change gain: " << gain << " pede:" << ped << std::endl;
268 
269  //
270  // From here https://github.com/cms-sw/cmssw/blob/master/CalibTracker/SiPixelESProducers/src/SiPixelGainCalibrationForHLTService.cc#L20-L47
271  //
272  // vcal = ADC * DBgain - DBped * DBgain
273  // electrons = vcal * conversionFactor + offset
274  //
275  // follows:
276  // electrons = (ADC*DBgain – DBped*DBgain)*conversionFactor + offset
277  // electrons = ADC*conversionFactor*DBgain - conversionFactor*DBped*DBgain + offset
278  //
279  // this should equal the new equation:
280  //
281  // electrons = ADC*DBgain' - DBPed' * DBgain'
282  //
283  // So equating piece by piece:
284  //
285  // DBgain' = conversionFactor*DBgain
286  // DBped' = (conversionFactor*DBped*Dbgain – offset)/(conversionFactor*DBgain)
287  // = DBped - offset/DBgain'
288  //
289 
290  if (isLayer1) {
291  gain = gain * myVCalInfo.getConversionFactorL1();
292  ped = ped - myVCalInfo.getOffsetL1() / gain;
293  } else {
294  gain = gain * myVCalInfo.getConversionFactor();
295  ped = ped - myVCalInfo.getOffset() / gain;
296  }
297 
298  if (verbose_)
299  edm::LogInfo("SiPixelGainCalibScaler") << "post-change gain: " << gain << " pede:" << ped << std::endl;
300 
301  if constexpr (std::is_same_v<PayloadType, SiPixelGainCalibrationForHLT>) {
302  SiPixelGainCalibration_.setData(ped, gain, theSiPixelGainCalibration, false, false);
303  } else {
304  SiPixelGainCalibration_.setDataPedestal(ped, theSiPixelGainCalibration);
305  if ((row + 1) % numberOfRowsToAverageOver == 0) { // fill the column average after every ROC!
306  SiPixelGainCalibration_.setDataGain(gain, numberOfRowsToAverageOver, theSiPixelGainCalibration);
307  }
308  }
309  } // loop on rows
310  } // loop on columns
311 
312  typename PayloadType::Range outrange(theSiPixelGainCalibration.begin(), theSiPixelGainCalibration.end());
313  if (!SiPixelGainCalibration_.put(d, outrange, ncols))
314  edm::LogError("SiPixelGainCalibScaler") << "[SiPixelGainCalibScaler::analyze] detid already exists" << std::endl;
315  } // loop on DetIds
316 
317  // Write into DB
318  edm::LogInfo(" --- writing to DB!");
320  if (!mydbservice.isAvailable()) {
321  edm::LogError("db service unavailable");
322  return;
323  } else {
324  edm::LogInfo("DB service OK");
325  }
326 
327  try {
328  if (mydbservice->isNewTagRequest(recordName_)) {
329  mydbservice->createOneIOV<PayloadType>(SiPixelGainCalibration_, mydbservice->beginOfTime(), recordName_);
330  } else {
331  mydbservice->appendOneIOV<PayloadType>(SiPixelGainCalibration_, mydbservice->currentTime(), recordName_);
332  }
333  edm::LogInfo(" --- all OK");
334  } catch (const cond::Exception& er) {
335  edm::LogError("SiPixelGainCalibScaler") << er.what() << std::endl;
336  } catch (const std::exception& er) {
337  edm::LogError("SiPixelGainCalibScaler") << "caught std::exception " << er.what() << std::endl;
338  } catch (...) {
339  edm::LogError("SiPixelGainCalibScaler") << "Funny error" << std::endl;
340  }
341 }
342 
343 // ------------ method called once each job just before starting event loop ------------
345 
346 // ------------ method called once each job just after ending the event loop ------------
348 
349 // ------------ method fills 'descriptions' with the allowed parameters for the module ------------
352  desc.add<std::string>("record", "SiPixelGainCalibrationForHLTRcd");
353  desc.add<bool>("isForHLT", true);
354 
356  vcalInfos.add<unsigned int>("phase");
357  vcalInfos.add<double>("conversionFactor");
358  vcalInfos.add<double>("conversionFactorL1");
359  vcalInfos.add<double>("offset");
360  vcalInfos.add<double>("offsetL1");
361 
362  std::vector<edm::ParameterSet> tmp;
363  tmp.reserve(2);
364  {
366  phase0VCal.addParameter<unsigned int>("phase", 0);
367  phase0VCal.addParameter<double>("conversionFactor", 65.);
368  phase0VCal.addParameter<double>("conversionFactorL1", 65.);
369  phase0VCal.addParameter<double>("offset", -414.);
370  phase0VCal.addParameter<double>("offsetL1", -414.);
371  tmp.push_back(phase0VCal);
372  }
373  {
375  phase1VCal.addParameter<unsigned int>("phase", 1);
376  phase1VCal.addParameter<double>("conversionFactor", 47.);
377  phase1VCal.addParameter<double>("conversionFactorL1", 50.);
378  phase1VCal.addParameter<double>("offset", -60.);
379  phase1VCal.addParameter<double>("offsetL1", -670.);
380  tmp.push_back(phase1VCal);
381  }
382  desc.addVPSet("parameters", vcalInfos, tmp);
383 
384  desc.addUntracked<bool>("verbose", false);
385 
386  descriptions.add("siPixelGainCalibScaler", desc);
387 }
388 
389 //define this as a plug-in
Log< level::Info, true > LogVerbatim
unsigned int pxbLayer(const DetId &id) const
Base exception class for the object to relational access.
Definition: Exception.h:11
void analyze(const edm::Event &, const edm::EventSetup &) override
PixelRecoRange< float > Range
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
const DetContainer & dets() const override
Returm a vector of all GeomDet (including all GeomDetUnits)
void computeAndStorePalyoads(const edm::EventSetup &iSetup, const tokenType &token)
const std::vector< edm::ParameterSet > m_parameters
Log< level::Error, false > LogError
void createOneIOV(const T &payload, cond::Time_t firstSinceTime, const std::string &recordName)
constexpr std::array< uint8_t, layerIndexSize > layer
edm::ESWatcher< SiPixelGainCalibrationOfflineRcd > pixelOfflineGainWatcher_
void appendOneIOV(const T &payload, cond::Time_t sinceTime, const std::string &recordName)
int iEvent
Definition: GenABIO.cc:224
bool isNewTagRequest(const std::string &recordName)
bool isThere(GeomDetEnumerators::SubDetector subdet) const
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
bool getData(T &iHolder) const
Definition: EventSetup.h:122
ParameterDescriptionBase * add(U const &iLabel, T const &value)
Log< level::Warning, true > LogPrint
d
Definition: ztail.py:151
edm::ESGetToken< TrackerGeometry, TrackerDigiGeometryRecord > tkGeomToken_
Log< level::Info, false > LogInfo
gainScale::VCalInfo phase0VCal
Definition: DetId.h:17
edm::ESGetToken< SiPixelGainCalibrationOffline, SiPixelGainCalibrationOfflineRcd > gainOfflineCalibToken_
gainScale::VCalInfo phase1VCal
edm::ESWatcher< SiPixelGainCalibrationForHLTRcd > pixelHLTGainWatcher_
edm::ESGetToken< TrackerTopology, TrackerTopologyRcd > tkTopoToken_
edm::ESGetToken< SiPixelGainCalibrationForHLT, SiPixelGainCalibrationForHLTRcd > gainHLTCalibToken_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
bool check(const edm::EventSetup &iSetup)
Definition: ESWatcher.h:57
void init(double conversionFactor, double conversionFactorL1, double offset, double offsetL1)
HLT enums.
col
Definition: cuy.py:1009
bool isAvailable() const
Definition: Service.h:40
SiPixelGainCalibScaler(const edm::ParameterSet &)
char const * what() const noexcept override
Definition: Exception.cc:103
tmp
align.sh
Definition: createJobs.py:716
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)