CMS 3D CMS Logo

EcalEBPhase2TPParamProducer.cc
Go to the documentation of this file.
6 //
20 
21 #include <iostream>
22 #include <string>
23 #include <sstream>
24 #include <vector>
25 #include <ctime>
26 #include <fstream>
27 #include <iomanip>
28 #include <TGraph.h>
29 #include <TFile.h>
30 #include <TMatrix.h>
31 #include <zlib.h>
39 public:
40  explicit EcalEBPhase2TPParamProducer(edm::ParameterSet const& pSet);
42  void analyze(const edm::Event& evt, const edm::EventSetup& evtSetup) override;
43  void beginJob() override;
45 
46 private:
47  std::vector<int> computeWeights(int type);
48 
49  void getNumericalDeriv(TGraph graph, TGraph& deriv);
50  void fillFMat(std::vector<unsigned int> clockSampleSet,
51  bool useThirdPulse,
52  std::vector<float> sampleSet,
53  std::vector<float> sampleDotSet,
54  TMatrix& FMat,
55  unsigned int binOfMaximum);
56  void getGMatrix(TMatrix FMat, float scaleMatrixBy, TMatrix& GMat);
57  void getPulseSampleSet(TGraph pulseGraph, float phaseShift, std::vector<float>& sampleSet);
58  bool computeLinearizerParam(double theta, double gainRatio, double calibCoeff, int& shift, int& mult);
59 
63  const int nSamplesToUse_;
64  const bool useBXPlusOne_;
65  const double phaseShift_;
66  const unsigned int nWeightGroups_;
68 
69  gzFile out_file_;
70  TGraph* thePulse_;
71  TGraph* pulseDot_;
72 
73  const UInt_t NPoints_ = 1599; //With the CMSSW pulse
74 
75  static constexpr float norm_ = 1 / 503.109; // with the CMSSW pulse shape
76  static constexpr float offset_ = 0.; // with the CMSSW pulse shape
77  int multToInt_ = 0x1000;
78 
79  int i2cSub_[2] = {0, 0};
80 
81  const double et_sat_;
82  const double xtal_LSB_;
83  const unsigned int binOfMaximum_;
84  static const int linTopRange_;
85 };
86 
88  : theBarrelGeometryToken_(esConsumes(edm::ESInputTag("", "EcalBarrel"))),
89  inFile_(pSet.getParameter<edm::FileInPath>("inputFile")),
90  outFile_(pSet.getUntrackedParameter<std::string>("outputFile")),
91  nSamplesToUse_(pSet.getParameter<unsigned int>("nSamplesToUse")),
92  useBXPlusOne_(pSet.getParameter<bool>("useBXPlusOne")),
93  phaseShift_(pSet.getParameter<double>("phaseShift")),
94  nWeightGroups_(pSet.getParameter<unsigned int>("nWeightGroups")),
95  theEcalTPGPedestals_Token_(esConsumes(edm::ESInputTag("EcalLiteDTUPedestals", ""))),
96  et_sat_(pSet.getParameter<double>("Et_sat")),
97  xtal_LSB_(pSet.getParameter<double>("xtal_LSB")),
98  binOfMaximum_(pSet.getParameter<unsigned int>("binOfMaximum"))
99 
100 {
101  out_file_ = gzopen(outFile_.c_str(), "wb");
102 
104  TFile* inFile = new TFile(filename.c_str(), "READ");
105 
106  inFile->GetObject("average-pulse", thePulse_);
107  delete inFile;
108 
109  if (binOfMaximum_ != 6 && binOfMaximum_ != 8)
110  edm::LogError("EcalEBPhase2TPParamProducer")
111  << " Value for binOfMaximum " << binOfMaximum_ << " is wrong, The default binOfMaximum=6 will be used";
112 
113  if (nSamplesToUse_ != 6 && nSamplesToUse_ != 8 && nSamplesToUse_ != 12)
114  edm::LogError("EcalEBPhase2TPParamProducer")
115  << " Value for nSamplesToUse " << nSamplesToUse_ << " is wrong, The default nSamplesToUse=8 will be used";
116 }
117 
119 
121 
124  desc.add<edm::FileInPath>("inputFile");
125  desc.addUntracked<std::string>("outputFile");
126  desc.add<unsigned int>("nSamplesToUse", 8);
127  desc.add<bool>("useBXPlusOne", false);
128  desc.add<double>("phaseShift", 2.581);
129  desc.add<unsigned int>("nWeightGroups", 61200);
130  desc.add<double>("Et_sat", 1998.36);
131  desc.add<double>("xtal_LSB", 0.0488);
132  desc.add<unsigned int>("binOfMaximum", 6);
133  descriptions.add("ecalEBPhase2TPParamProducerDefault", desc);
134 }
135 
137  using namespace edm;
138  using namespace std;
139 
140  const EcalLiteDTUPedestals* peds = nullptr;
141  const auto* theBarrelGeometry = &evtSetup.getData(theBarrelGeometryToken_);
142  const auto* theEcalTPPedestals = &evtSetup.getData(theEcalTPGPedestals_Token_);
143 
144  std::string tmpStringConv;
145  const char* tmpStringOut;
146 
147  // Compute weights //
148  std::vector<int> ampWeights[nWeightGroups_];
149  std::vector<int> timeWeights[nWeightGroups_];
150 
151  for (unsigned int iGr = 0; iGr < nWeightGroups_; iGr++) {
152  ampWeights[iGr] = computeWeights(1);
153  timeWeights[iGr] = computeWeights(2);
154  }
155 
156  /* write to compressed file */
157  std::stringstream toCompressStream("");
158  for (unsigned int iGr = 0; iGr < nWeightGroups_; iGr++) {
159  toCompressStream << " WEIGHTAMP " << dec << iGr << std::endl;
160  for (long unsigned int i = 0; i < ampWeights[iGr].size(); i++) {
161  if (ampWeights[iGr][i] < 0)
162  toCompressStream << "-0x" << std::hex << abs(ampWeights[iGr][i]) << " ";
163  else
164  toCompressStream << "0x" << std::hex << ampWeights[iGr][i] << " ";
165  }
166  toCompressStream << "\n";
167  }
168  toCompressStream << "\n";
169  tmpStringConv = toCompressStream.str();
170  tmpStringOut = tmpStringConv.c_str();
171  gzwrite(out_file_, tmpStringOut, std::strlen(tmpStringOut));
172  toCompressStream.str(std::string());
173 
174  for (unsigned int iGr = 0; iGr < nWeightGroups_; iGr++) {
175  toCompressStream << "WEIGHTTIME " << dec << iGr << std::endl;
176  for (long unsigned int i = 0; i < timeWeights[iGr].size(); i++) {
177  if (timeWeights[iGr][i] < 0)
178  toCompressStream << "-0x" << std::hex << abs(timeWeights[iGr][i]) << " ";
179  else
180  toCompressStream << "0x" << std::hex << timeWeights[iGr][i] << " ";
181  }
182  toCompressStream << "\n";
183  }
184 
185  toCompressStream << "\n";
186  tmpStringConv = toCompressStream.str();
187  tmpStringOut = tmpStringConv.c_str();
188  gzwrite(out_file_, tmpStringOut, std::strlen(tmpStringOut));
189  toCompressStream.str(std::string());
190 
191  // fill map between xTals and groups. If each xTal is a group there is a one-to-one map
192  const std::vector<DetId>& ebCells = theBarrelGeometry->getValidDetIds(DetId::Ecal, EcalBarrel);
193  std::map<int, int> mapXtalToGroup;
194 
195  int iGroup = 0;
196  for (const auto& it : ebCells) {
197  EBDetId id(it);
198  std::pair<int, int> xTalToGroup(id.rawId(), iGroup);
199  mapXtalToGroup.insert(xTalToGroup);
200  iGroup++;
201  }
202 
203  //write to file
204 
205  for (std::map<int, int>::const_iterator it = mapXtalToGroup.begin(); it != mapXtalToGroup.end(); it++) {
206  toCompressStream << "CRYSTAL " << dec << it->first << std::endl;
207  toCompressStream << it->second << std::endl;
208  }
209  tmpStringConv = toCompressStream.str();
210  tmpStringOut = tmpStringConv.c_str();
211  gzwrite(out_file_, tmpStringOut, std::strlen(tmpStringOut));
212  toCompressStream.str(std::string());
213 
215 
216  for (const auto& it : ebCells) {
217  EBDetId id(it);
218  toCompressStream << "LINCONST " << dec << id.rawId() << std::endl;
219  double theta = theBarrelGeometry->getGeometry(id)->getPosition().theta();
220  EcalLiteDTUPedestalsMap::const_iterator itped = theEcalTPPedestals->getMap().find(id);
221 
222  if (itped != theEcalTPPedestals->end()) {
223  peds = &(*itped);
224 
225  } else {
226  edm::LogError("EcalEBPhase2TPParamProducer") << " could not find EcalLiteDTUPedestal entry for " << id;
227  throw cms::Exception("could not find pedestals");
228  }
229 
230  int shift, mult;
231  double calibCoeff = 1.;
232  bool ok;
233  for (unsigned int i = 0; i < ecalPh2::NGAINS; ++i) {
235  if (!ok) {
236  edm::LogError("EcalEBPhase2TPParamProducer")
237  << "unable to compute the parameters for SM=" << id.ism() << " xt=" << id.ic() << " " << id.rawId();
238  throw cms::Exception("unable to compute the parameters");
239 
240  } else {
241  int tmpPedByGain = (int)(peds->mean(i) + 0.5);
242  toCompressStream << std::hex << " 0x" << tmpPedByGain << " 0x" << mult << " 0x" << shift << " " << i2cSub_[i]
243  << std::endl;
244  }
245  }
246  }
247  tmpStringConv = toCompressStream.str();
248  tmpStringOut = tmpStringConv.c_str();
249  gzwrite(out_file_, tmpStringOut, std::strlen(tmpStringOut));
250  toCompressStream.str(std::string());
251 }
252 
254  std::vector<float> sampleSet;
255  std::vector<float> sampleDotSet;
256  std::vector<unsigned int> clockSampleSet;
257  double scaleMatrixBy = 1.;
258  int lbinOfMaximum = binOfMaximum_;
259 
260  switch (binOfMaximum_) {
261  case 6:
262  break;
263  case 8:
264  break;
265  default:
266  lbinOfMaximum = 6;
267  break;
268  }
269 
270  switch (nSamplesToUse_) {
271  case 12:
272  clockSampleSet = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
273  break;
274  case 8:
275  switch (lbinOfMaximum) {
276  case 8:
277  clockSampleSet = {2, 3, 4, 5, 6, 7, 8, 9};
278  break;
279  case 6:
280  clockSampleSet = {0, 1, 2, 3, 4, 5, 6, 7};
281  break;
282  }
283  break;
284 
285  case 6:
286  switch (lbinOfMaximum) {
287  case 8:
288  clockSampleSet = {3, 4, 6, 7, 8, 9};
289  break;
290  case 6:
291  clockSampleSet = {1, 2, 4, 5, 6, 7};
292  break;
293  }
294  break;
295 
296  default:
297  clockSampleSet = {0, 1, 2, 3, 4, 5, 6, 7};
298  break;
299  }
300 
302  pulseDot_ = new TGraph();
304  getPulseSampleSet(*pulseDot_, phaseShift_, sampleDotSet);
305 
306  unsigned int fMatColumns = useBXPlusOne_ ? 6 : 4;
307 
308  TMatrix fMat(clockSampleSet.size(), fMatColumns);
309  fillFMat(clockSampleSet, useBXPlusOne_, sampleSet, sampleDotSet, fMat, lbinOfMaximum);
310  TMatrix gMat(fMatColumns, clockSampleSet.size());
311 
312  getGMatrix(fMat, scaleMatrixBy, gMat);
313 
314  std::vector<int> tmpWeightVec;
315  std::vector<int> tmpTimeWeightVec;
316  unsigned int iClock = 0;
317  for (unsigned int iSample = 0; iSample < 12; iSample++) {
318  bool inSampleSet = false;
319  for (unsigned int clockSample = 0; clockSample < clockSampleSet.size(); clockSample++) {
320  if (iSample == clockSampleSet[clockSample]) {
321  inSampleSet = true;
322  iClock = clockSample;
323  break;
324  }
325  }
326  if (inSampleSet) {
327  if (type == 1)
328  tmpWeightVec.push_back(round(gMat(2, iClock) * multToInt_)); // amp weights
329  if (type == 2)
330  tmpWeightVec.push_back(round(gMat(3, iClock) * multToInt_)); // time weights
331  } else {
332  if (type == 1)
333  tmpWeightVec.push_back(0); // amp weights
334  if (type == 2)
335  tmpWeightVec.push_back(0); // time weights
336  }
337  }
338 
339  return tmpWeightVec;
340 }
341 
342 void EcalEBPhase2TPParamProducer::getNumericalDeriv(TGraph graph, TGraph& deriv) {
343  UInt_t numPoints = graph.GetN();
344  if (numPoints != NPoints_) {
345  edm::LogWarning("EcalEBPhase2TPParamProducer") << "Error! Wrong amount of points in pulse graph! ";
346  }
347  Double_t xval;
348  Double_t yval;
349  Double_t xvalPOne;
350  Double_t yvalPOne;
351 
352  for (UInt_t p = 0; p < NPoints_ - 1; p++) {
353  graph.GetPoint(p, xval, yval);
354  graph.GetPoint(p + 1, xvalPOne, yvalPOne);
355  float midpoint = (xvalPOne + xval) / 2;
356  float rise = yvalPOne - yval;
357  float run = xvalPOne - xval;
358  deriv.SetPoint(deriv.GetN(), midpoint, rise / run);
359  }
360  deriv.SetName("pulse_prime");
361 }
362 
363 void EcalEBPhase2TPParamProducer::fillFMat(std::vector<UInt_t> clockSampleSet,
364  bool useThirdPulse,
365  std::vector<float> sampleSet,
366  std::vector<float> sampleDotSet,
367  TMatrix& fMat,
368  uint binOfMaximum) {
369  Int_t iShift = 8 - binOfMaximum;
370  for (UInt_t i = 0; i < clockSampleSet.size(); i++) {
371  Int_t tmpClockToSample = clockSampleSet[i] + iShift;
372  fMat(i, 0) = sampleSet[tmpClockToSample];
373  fMat(i, 1) = sampleDotSet[tmpClockToSample];
374  if (tmpClockToSample > 4) {
375  fMat(i, 2) = sampleSet[tmpClockToSample - 4];
376  fMat(i, 3) = sampleDotSet[tmpClockToSample - 4];
377  }
378  if (clockSampleSet[i] > 8 && useThirdPulse) {
379  fMat(i, 4) = sampleSet[tmpClockToSample - 8];
380  fMat(i, 5) = sampleDotSet[tmpClockToSample - 8];
381  }
382  }
383 }
384 
385 void EcalEBPhase2TPParamProducer::getGMatrix(TMatrix fMat, float scaleMatrixBy, TMatrix& gMat) {
386  TMatrix FT = fMat;
387  FT.T();
388  TMatrix tmpFT = FT;
389  TMatrix FTDotF = TMatrix(tmpFT, TMatrix::kMult, fMat);
390  TMatrix InvFTDotF = FTDotF;
391 
392  //Possible for this bit to fail depending on the sample set and phase shift
393  InvFTDotF.Invert();
394 
395  TMatrix tmpMat(InvFTDotF, TMatrix::kMult, FT);
396  gMat = tmpMat;
397  gMat *= scaleMatrixBy;
398 }
399 
401  float phaseShift,
402  std::vector<float>& sampleSet) {
403  for (UInt_t i = 0; i < ecalPh2::sampleSize; i++) {
404  float t = (ecalPh2::Samp_Period * i) + phaseShift;
405  float y = pulseGraph.Eval(t + offset_) * norm_;
406  sampleSet.push_back(y);
407  }
408 }
409 
411  double theta, double gainRatio, double calibCoeff, int& shift, int& mult) {
412  bool result = false;
413 
414  static constexpr double linTopRange_ = 16383.;
415  // linTopRange_ 16383 = (2**14)-1 is setting the top of the range for the linearizer output
416  double factor = (linTopRange_ * (xtal_LSB_ * gainRatio * calibCoeff * sin(theta))) / et_sat_;
417  //first with shift_ = 0
418  //add 0.5 (for rounding) and set to int
419  //Here we are getting mult with a max bit length of 8
420  //and shift_ with a max bit length of 4
421  mult = (int)(factor + 0.5);
422  for (shift = 0; shift < 15; shift++) {
423  if (mult >= 128 && mult < 256) {
424  result = true;
425  break;
426  }
427  factor *= 2;
428  mult = (int)(factor + 0.5);
429  }
430 
431  return result;
432 }
433 
434 // DEfine this module as a plug-in
ESGetTokenH3DDVariant esConsumes(std::string const &Record, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
static constexpr unsigned int NGAINS
Definition: EcalConstants.h:32
T const & getData(const ESGetToken< T, R > &iToken) const noexcept(false)
Definition: EventSetup.h:119
const edm::ESGetToken< EcalLiteDTUPedestalsMap, EcalLiteDTUPedestalsRcd > theEcalTPGPedestals_Token_
std::string fullPath() const
Definition: FileInPath.cc:161
void getNumericalDeriv(TGraph graph, TGraph &deriv)
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
Log< level::Error, false > LogError
float mean(unsigned int i) const
std::vector< int > computeWeights(int type)
void getGMatrix(TMatrix FMat, float scaleMatrixBy, TMatrix &GMat)
void fillFMat(std::vector< unsigned int > clockSampleSet, bool useThirdPulse, std::vector< float > sampleSet, std::vector< float > sampleDotSet, TMatrix &FMat, unsigned int binOfMaximum)
static constexpr unsigned int sampleSize
Definition: EcalConstants.h:36
static constexpr double Samp_Period
Definition: EcalConstants.h:31
const edm::ESGetToken< CaloSubdetectorGeometry, EcalBarrelGeometryRecord > theBarrelGeometryToken_
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
bool computeLinearizerParam(double theta, double gainRatio, double calibCoeff, int &shift, int &mult)
constexpr float gains[NGAINS]
Definition: EcalConstants.h:20
EcalEBPhase2TPParamProducer(edm::ParameterSet const &pSet)
std::vector< Item >::const_iterator const_iterator
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void getPulseSampleSet(TGraph pulseGraph, float phaseShift, std::vector< float > &sampleSet)
void analyze(const edm::Event &evt, const edm::EventSetup &evtSetup) override
HLT enums.
static unsigned int const shift
Log< level::Warning, false > LogWarning
Geom::Theta< T > theta() const
static void fillDescriptions(edm::ConfigurationDescriptions &)
TPG Param Builder for Phase2