CMS 3D CMS Logo

MahiFit.cc
Go to the documentation of this file.
1 #define EIGEN_NO_DEBUG // kill throws in eigen code
4 
6 
7 void MahiFit::setParameters(bool iDynamicPed,
8  double iTS4Thresh,
9  double chiSqSwitch,
10  bool iApplyTimeSlew,
11  HcalTimeSlew::BiasSetting slewFlavor,
12  bool iCalculateArrivalTime,
13  double iMeanTime,
14  double iTimeSigmaHPD,
15  double iTimeSigmaSiPM,
16  const std::vector<int>& iActiveBXs,
17  int iNMaxItersMin,
18  int iNMaxItersNNLS,
19  double iDeltaChiSqThresh,
20  double iNnlsThresh) {
21  dynamicPed_ = iDynamicPed;
22 
23  ts4Thresh_ = iTS4Thresh;
25 
26  applyTimeSlew_ = iApplyTimeSlew;
27  slewFlavor_ = slewFlavor;
28 
29  calculateArrivalTime_ = iCalculateArrivalTime;
30  meanTime_ = iMeanTime;
31  timeSigmaHPD_ = iTimeSigmaHPD;
32  timeSigmaSiPM_ = iTimeSigmaSiPM;
33 
34  activeBXs_ = iActiveBXs;
35 
36  nMaxItersMin_ = iNMaxItersMin;
37  nMaxItersNNLS_ = iNMaxItersNNLS;
38 
39  deltaChiSqThresh_ = iDeltaChiSqThresh;
40  nnlsThresh_ = iNnlsThresh;
41 
42  bxOffsetConf_ = -(*std::min_element(activeBXs_.begin(), activeBXs_.end()));
43  bxSizeConf_ = activeBXs_.size();
44 }
45 
46 void MahiFit::phase1Apply(const HBHEChannelInfo& channelData,
47  float& reconstructedEnergy,
48  float& reconstructedTime,
49  bool& useTriple,
50  float& chi2) const {
51  assert(channelData.nSamples() == 8 || channelData.nSamples() == 10);
52 
54 
55  nnlsWork_.tsOffset = channelData.soi();
56 
57  std::array<float, 3> reconstructedVals{{0.0f, -9999.f, -9999.f}};
58 
59  double tsTOT = 0, tstrig = 0; // in GeV
60  for (unsigned int iTS = 0; iTS < nnlsWork_.tsSize; ++iTS) {
61  auto const amplitude = channelData.tsRawCharge(iTS) - channelData.tsPedestal(iTS);
62 
63  nnlsWork_.amplitudes.coeffRef(iTS) = amplitude;
64 
65  //ADC granularity
66  auto const noiseADC = norm_ * channelData.tsDFcPerADC(iTS);
67 
68  //Electronic pedestal
69  auto const pedWidth = channelData.tsPedestalWidth(iTS);
70 
71  //Photostatistics
72  auto const noisePhoto = (amplitude > pedWidth) ? std::sqrt(amplitude * channelData.fcByPE()) : 0.f;
73 
74  //Total uncertainty from all sources
75  nnlsWork_.noiseTerms.coeffRef(iTS) = noiseADC * noiseADC + noisePhoto * noisePhoto + pedWidth * pedWidth;
76 
77  tsTOT += amplitude;
78  if (iTS == nnlsWork_.tsOffset)
79  tstrig += amplitude;
80  }
81 
82  tsTOT *= channelData.tsGain(0);
83  tstrig *= channelData.tsGain(0);
84 
85  useTriple = false;
86  if (tstrig >= ts4Thresh_ && tsTOT > 0) {
87  //Average pedestal width (for covariance matrix constraint)
88  nnlsWork_.pedVal = 0.25f * (channelData.tsPedestalWidth(0) * channelData.tsPedestalWidth(0) +
89  channelData.tsPedestalWidth(1) * channelData.tsPedestalWidth(1) +
90  channelData.tsPedestalWidth(2) * channelData.tsPedestalWidth(2) +
91  channelData.tsPedestalWidth(3) * channelData.tsPedestalWidth(3));
92 
93  // only do pre-fit with 1 pulse if chiSq threshold is positive
94  if (chiSqSwitch_ > 0) {
95  doFit(reconstructedVals, 1);
96  if (reconstructedVals[2] > chiSqSwitch_) {
97  doFit(reconstructedVals, 0); //nbx=0 means use configured BXs
98  useTriple = true;
99  }
100  } else {
101  doFit(reconstructedVals, 0);
102  useTriple = true;
103  }
104  } else {
105  reconstructedVals.at(0) = 0.f; //energy
106  reconstructedVals.at(1) = -9999.f; //time
107  reconstructedVals.at(2) = -9999.f; //chi2
108  }
109 
110  reconstructedEnergy = reconstructedVals[0] * channelData.tsGain(0);
111  reconstructedTime = reconstructedVals[1];
112  chi2 = reconstructedVals[2];
113 }
114 
115 void MahiFit::doFit(std::array<float, 3>& correctedOutput, int nbx) const {
116  unsigned int bxSize = 1;
117 
118  if (nbx == 1) {
119  nnlsWork_.bxOffset = 0;
120  } else {
121  bxSize = bxSizeConf_;
123  }
124 
125  nnlsWork_.nPulseTot = bxSize;
126 
127  if (dynamicPed_)
129  nnlsWork_.bxs.setZero(nnlsWork_.nPulseTot);
130 
131  if (nbx == 1) {
132  nnlsWork_.bxs.coeffRef(0) = 0;
133  } else {
134  for (unsigned int iBX = 0; iBX < bxSize; ++iBX) {
135  nnlsWork_.bxs.coeffRef(iBX) =
136  activeBXs_[iBX] -
137  ((static_cast<int>(nnlsWork_.tsOffset) + activeBXs_[0]) >= 0 ? 0 : (nnlsWork_.tsOffset + activeBXs_[0]));
138  }
139  }
140 
141  nnlsWork_.maxoffset = nnlsWork_.bxs.coeff(bxSize - 1);
142  if (dynamicPed_)
144 
147 
148  FullSampleVector pulseShapeArray;
149  FullSampleVector pulseDerivArray;
150  FullSampleMatrix pulseCov;
151 
152  int offset = 0;
153  for (unsigned int iBX = 0; iBX < nnlsWork_.nPulseTot; ++iBX) {
154  offset = nnlsWork_.bxs.coeff(iBX);
155 
156  if (offset == pedestalBX_) {
157  nnlsWork_.pulseMat.col(iBX) = SampleVector::Ones(nnlsWork_.tsSize);
158  nnlsWork_.pulseDerivMat.col(iBX) = SampleVector::Zero(nnlsWork_.tsSize);
159  } else {
160  pulseShapeArray.setZero(nnlsWork_.tsSize + nnlsWork_.maxoffset + nnlsWork_.bxOffset);
162  pulseDerivArray.setZero(nnlsWork_.tsSize + nnlsWork_.maxoffset + nnlsWork_.bxOffset);
163  pulseCov.setZero(nnlsWork_.tsSize + nnlsWork_.maxoffset + nnlsWork_.bxOffset,
166 
168  nnlsWork_.amplitudes.coeff(nnlsWork_.tsOffset + offset), pulseShapeArray, pulseDerivArray, pulseCov);
169 
170  nnlsWork_.pulseMat.col(iBX) = pulseShapeArray.segment(nnlsWork_.maxoffset - offset, nnlsWork_.tsSize);
172  nnlsWork_.pulseDerivMat.col(iBX) = pulseDerivArray.segment(nnlsWork_.maxoffset - offset, nnlsWork_.tsSize);
173  nnlsWork_.pulseCovArray[iBX] = pulseCov.block(
175  }
176  }
177 
178  const float chiSq = minimize();
179 
180  bool foundintime = false;
181  unsigned int ipulseintime = 0;
182 
183  for (unsigned int iBX = 0; iBX < nnlsWork_.nPulseTot; ++iBX) {
184  if (nnlsWork_.bxs.coeff(iBX) == 0) {
185  ipulseintime = iBX;
186  foundintime = true;
187  break;
188  }
189  }
190 
191  if (foundintime) {
192  correctedOutput.at(0) = nnlsWork_.ampVec.coeff(ipulseintime); //charge
193  if (correctedOutput.at(0) != 0) {
194  // fixME store the timeslew
195  float arrivalTime = 0.f;
197  arrivalTime = calculateArrivalTime(ipulseintime);
198  correctedOutput.at(1) = arrivalTime; //time
199  } else
200  correctedOutput.at(1) = -9999.f; //time
201 
202  correctedOutput.at(2) = chiSq; //chi2
203  }
204 }
205 
206 const float MahiFit::minimize() const {
209 
210  SampleMatrix invCovMat;
211  invCovMat.setConstant(nnlsWork_.tsSize, nnlsWork_.tsSize, nnlsWork_.pedVal);
212  invCovMat += nnlsWork_.noiseTerms.asDiagonal();
213 
214  float oldChiSq = 9999;
215  float chiSq = oldChiSq;
216 
217  for (int iter = 1; iter < nMaxItersMin_; ++iter) {
218  updateCov(invCovMat);
219 
220  if (nnlsWork_.nPulseTot > 1) {
221  nnls();
222  } else {
224  }
225 
226  const float newChiSq = calculateChiSq();
227  const float deltaChiSq = newChiSq - chiSq;
228 
229  if (newChiSq == oldChiSq && newChiSq < chiSq) {
230  break;
231  }
232  oldChiSq = chiSq;
233  chiSq = newChiSq;
234 
235  if (std::abs(deltaChiSq) < deltaChiSqThresh_)
236  break;
237  }
238 
239  return chiSq;
240 }
241 
242 void MahiFit::updatePulseShape(const float itQ,
243  FullSampleVector& pulseShape,
244  FullSampleVector& pulseDeriv,
245  FullSampleMatrix& pulseCov) const {
246  float t0 = meanTime_;
247 
248  if (applyTimeSlew_) {
249  if (itQ <= 1.f)
250  t0 += tsDelay1GeV_;
251  else
252  t0 += hcalTimeSlewDelay_->delay(float(itQ), slewFlavor_);
253  }
254 
255  std::array<double, HcalConst::maxSamples> pulseN;
256  std::array<double, HcalConst::maxSamples> pulseM;
257  std::array<double, HcalConst::maxSamples> pulseP;
258 
259  const float xx = t0;
260  const float xxm = -nnlsWork_.dt + t0;
261  const float xxp = nnlsWork_.dt + t0;
262 
263  psfPtr_->singlePulseShapeFuncMahi(&xx);
264  psfPtr_->getPulseShape(pulseN);
265 
266  psfPtr_->singlePulseShapeFuncMahi(&xxm);
267  psfPtr_->getPulseShape(pulseM);
268 
269  psfPtr_->singlePulseShapeFuncMahi(&xxp);
270  psfPtr_->getPulseShape(pulseP);
271 
272  //in the 2018+ case where the sample of interest (SOI) is in TS3, add an extra offset to align
273  //with previous SOI=TS4 case assumed by psfPtr_->getPulseShape()
274  int delta = 4 - nnlsWork_.tsOffset;
275 
276  auto invDt = 0.5 / nnlsWork_.dt;
277 
278  for (unsigned int iTS = 0; iTS < nnlsWork_.tsSize; ++iTS) {
279  pulseShape(iTS + nnlsWork_.maxoffset) = pulseN[iTS + delta];
281  pulseDeriv(iTS + nnlsWork_.maxoffset) = (pulseM[iTS + delta] - pulseP[iTS + delta]) * invDt;
282 
283  pulseM[iTS + delta] -= pulseN[iTS + delta];
284  pulseP[iTS + delta] -= pulseN[iTS + delta];
285  }
286 
287  for (unsigned int iTS = 0; iTS < nnlsWork_.tsSize; ++iTS) {
288  for (unsigned int jTS = 0; jTS < iTS + 1; ++jTS) {
289  auto const tmp = 0.5 * (pulseP[iTS + delta] * pulseP[jTS + delta] + pulseM[iTS + delta] * pulseM[jTS + delta]);
290 
291  pulseCov(jTS + nnlsWork_.maxoffset, iTS + nnlsWork_.maxoffset) = tmp;
292  if (iTS != jTS)
293  pulseCov(iTS + nnlsWork_.maxoffset, jTS + nnlsWork_.maxoffset) = tmp;
294  }
295  }
296 }
297 
298 void MahiFit::updateCov(const SampleMatrix& samplecov) const {
299  SampleMatrix invCovMat = samplecov;
300 
301  for (unsigned int iBX = 0; iBX < nnlsWork_.nPulseTot; ++iBX) {
302  auto const amp = nnlsWork_.ampVec.coeff(iBX);
303  if (amp == 0)
304  continue;
305 
306  int offset = nnlsWork_.bxs.coeff(iBX);
307 
308  if (offset == pedestalBX_)
309  continue;
310  else {
311  auto const ampsq = amp * amp;
312  invCovMat += ampsq * nnlsWork_.pulseCovArray[offset + nnlsWork_.bxOffset];
313  }
314  }
315 
316  nnlsWork_.covDecomp.compute(invCovMat);
317 }
318 
319 float MahiFit::calculateArrivalTime(unsigned int itIndex) const {
320  if (nnlsWork_.nPulseTot > 1) {
321  SamplePulseMatrix pulseDerivMatTMP = nnlsWork_.pulseDerivMat;
322  for (unsigned int iBX = 0; iBX < nnlsWork_.nPulseTot; ++iBX) {
323  nnlsWork_.pulseDerivMat.col(iBX) = pulseDerivMatTMP.col(nnlsWork_.bxs.coeff(iBX) + nnlsWork_.bxOffset);
324  }
325  }
326 
327  for (unsigned int iBX = 0; iBX < nnlsWork_.nPulseTot; ++iBX) {
328  nnlsWork_.pulseDerivMat.col(iBX) *= nnlsWork_.ampVec.coeff(iBX);
329  }
330 
331  //FIXME: avoid solve full equation for one element
333  PulseVector solution = nnlsWork_.pulseDerivMat.colPivHouseholderQr().solve(residuals);
334  float t = std::clamp((float)solution.coeff(itIndex), -timeLimit_, timeLimit_);
335 
336  return t;
337 }
338 
339 void MahiFit::nnls() const {
340  const unsigned int npulse = nnlsWork_.nPulseTot;
341  const unsigned int nsamples = nnlsWork_.tsSize;
342 
343  PulseVector updateWork;
344 
347  nnlsWork_.aTbVec = nnlsWork_.invcovp.transpose() * (nnlsWork_.covDecomp.matrixL().solve(nnlsWork_.amplitudes));
348 
349  int iter = 0;
350  Index idxwmax = 0;
351  float wmax = 0.0f;
352  float threshold = nnlsThresh_;
353 
354  while (true) {
355  if (iter > 0 || nnlsWork_.nP == 0) {
356  if (nnlsWork_.nP == std::min(npulse, nsamples))
357  break;
358 
359  const unsigned int nActive = npulse - nnlsWork_.nP;
360  // exit if there are no more pulses to constrain
361  if (nActive == 0)
362  break;
363 
364  updateWork = nnlsWork_.aTbVec - nnlsWork_.aTaMat * nnlsWork_.ampVec;
365 
366  Index idxwmaxprev = idxwmax;
367  float wmaxprev = wmax;
368  wmax = updateWork.tail(nActive).maxCoeff(&idxwmax);
369 
370  if (wmax < threshold || (idxwmax == idxwmaxprev && wmax == wmaxprev)) {
371  break;
372  }
373 
374  if (iter >= nMaxItersNNLS_) {
375  break;
376  }
377 
378  //unconstrain parameter
379  idxwmax += nnlsWork_.nP;
380  nnlsUnconstrainParameter(idxwmax);
381  }
382 
383  while (true) {
384  if (nnlsWork_.nP == 0)
385  break;
386 
387  PulseVector ampvecpermtest = nnlsWork_.ampVec.head(nnlsWork_.nP);
388 
390 
391  //check solution
392  if (ampvecpermtest.head(nnlsWork_.nP).minCoeff() > 0.f) {
393  nnlsWork_.ampVec.head(nnlsWork_.nP) = ampvecpermtest.head(nnlsWork_.nP);
394  break;
395  }
396 
397  //update parameter vector
398  Index minratioidx = 0;
399 
400  // no realizable optimization here (because it autovectorizes!)
401  float minratio = std::numeric_limits<float>::max();
402  for (unsigned int ipulse = 0; ipulse < nnlsWork_.nP; ++ipulse) {
403  if (ampvecpermtest.coeff(ipulse) <= 0.f) {
404  const float c_ampvec = nnlsWork_.ampVec.coeff(ipulse);
405  const float ratio = c_ampvec / (c_ampvec - ampvecpermtest.coeff(ipulse));
406  if (ratio < minratio) {
407  minratio = ratio;
408  minratioidx = ipulse;
409  }
410  }
411  }
412  nnlsWork_.ampVec.head(nnlsWork_.nP) +=
413  minratio * (ampvecpermtest.head(nnlsWork_.nP) - nnlsWork_.ampVec.head(nnlsWork_.nP));
414 
415  //avoid numerical problems with later ==0. check
416  nnlsWork_.ampVec.coeffRef(minratioidx) = 0.f;
417 
418  nnlsConstrainParameter(minratioidx);
419  }
420 
421  ++iter;
422 
423  //adaptive convergence threshold to avoid infinite loops but still
424  //ensure best value is used
425  if (iter % 10 == 0) {
426  threshold *= 10.;
427  }
428  }
429 }
430 
433 
434  float aTaCoeff = (nnlsWork_.invcovp.transpose() * nnlsWork_.invcovp).coeff(0);
435  float aTbCoeff =
436  (nnlsWork_.invcovp.transpose() * (nnlsWork_.covDecomp.matrixL().solve(nnlsWork_.amplitudes))).coeff(0);
437 
438  nnlsWork_.ampVec.coeffRef(0) = std::max(0.f, aTbCoeff / aTaCoeff);
439 }
440 
441 float MahiFit::calculateChiSq() const {
443  .squaredNorm();
444 }
445 
447  bool hasTimeInfo,
448  const HcalTimeSlew* hcalTimeSlewDelay,
449  unsigned int nSamples) {
450  if (!(&ps == currentPulseShape_)) {
451  hcalTimeSlewDelay_ = hcalTimeSlewDelay;
452  tsDelay1GeV_ = hcalTimeSlewDelay->delay(1.0, slewFlavor_);
453 
454  resetPulseShapeTemplate(ps, hasTimeInfo, nSamples);
455  currentPulseShape_ = &ps;
456  }
457 }
458 
459 void MahiFit::resetPulseShapeTemplate(const HcalPulseShapes::Shape& ps, bool hasTimeInfo, unsigned int nSamples) {
461 
462  // only the pulse shape itself from PulseShapeFunctor is used for Mahi
463  // the uncertainty terms calculated inside PulseShapeFunctor are used for Method 2 only
464  psfPtr_.reset(new FitterFuncs::PulseShapeFunctor(ps, false, false, false, 1, 0, 0, HcalConst::maxSamples));
465 
466  // 1 sigma time constraint
467  nnlsWork_.dt = hasTimeInfo ? timeSigmaSiPM_ : timeSigmaHPD_;
468 
472 }
473 
475  if (idxp != nnlsWork_.nP) {
476  nnlsWork_.aTaMat.col(nnlsWork_.nP).swap(nnlsWork_.aTaMat.col(idxp));
477  nnlsWork_.aTaMat.row(nnlsWork_.nP).swap(nnlsWork_.aTaMat.row(idxp));
478  nnlsWork_.pulseMat.col(nnlsWork_.nP).swap(nnlsWork_.pulseMat.col(idxp));
479  Eigen::numext::swap(nnlsWork_.aTbVec.coeffRef(nnlsWork_.nP), nnlsWork_.aTbVec.coeffRef(idxp));
480  Eigen::numext::swap(nnlsWork_.ampVec.coeffRef(nnlsWork_.nP), nnlsWork_.ampVec.coeffRef(idxp));
481  Eigen::numext::swap(nnlsWork_.bxs.coeffRef(nnlsWork_.nP), nnlsWork_.bxs.coeffRef(idxp));
482  }
483  ++nnlsWork_.nP;
484 }
485 
486 void MahiFit::nnlsConstrainParameter(Index minratioidx) const {
487  if (minratioidx != (nnlsWork_.nP - 1)) {
488  nnlsWork_.aTaMat.col(nnlsWork_.nP - 1).swap(nnlsWork_.aTaMat.col(minratioidx));
489  nnlsWork_.aTaMat.row(nnlsWork_.nP - 1).swap(nnlsWork_.aTaMat.row(minratioidx));
490  nnlsWork_.pulseMat.col(nnlsWork_.nP - 1).swap(nnlsWork_.pulseMat.col(minratioidx));
491  Eigen::numext::swap(nnlsWork_.aTbVec.coeffRef(nnlsWork_.nP - 1), nnlsWork_.aTbVec.coeffRef(minratioidx));
492  Eigen::numext::swap(nnlsWork_.ampVec.coeffRef(nnlsWork_.nP - 1), nnlsWork_.ampVec.coeffRef(minratioidx));
493  Eigen::numext::swap(nnlsWork_.bxs.coeffRef(nnlsWork_.nP - 1), nnlsWork_.bxs.coeffRef(minratioidx));
494  }
495  --nnlsWork_.nP;
496 }
497 
498 void MahiFit::phase1Debug(const HBHEChannelInfo& channelData, MahiDebugInfo& mdi) const {
499  float recoEnergy, recoTime, chi2;
500  bool use3;
501  phase1Apply(channelData, recoEnergy, recoTime, use3, chi2);
502 
503  mdi.nSamples = channelData.nSamples();
504  mdi.soi = channelData.soi();
505 
506  mdi.use3 = use3;
507 
508  mdi.inTimeConst = nnlsWork_.dt;
509  mdi.inPedAvg = 0.25 * (channelData.tsPedestalWidth(0) * channelData.tsPedestalWidth(0) +
510  channelData.tsPedestalWidth(1) * channelData.tsPedestalWidth(1) +
511  channelData.tsPedestalWidth(2) * channelData.tsPedestalWidth(2) +
512  channelData.tsPedestalWidth(3) * channelData.tsPedestalWidth(3));
513  mdi.inGain = channelData.tsGain(0);
514 
515  for (unsigned int iTS = 0; iTS < channelData.nSamples(); ++iTS) {
516  double charge = channelData.tsRawCharge(iTS);
517  double ped = channelData.tsPedestal(iTS);
518 
519  mdi.inNoiseADC[iTS] = norm_ * channelData.tsDFcPerADC(iTS);
520 
521  if ((charge - ped) > channelData.tsPedestalWidth(iTS)) {
522  mdi.inNoisePhoto[iTS] = sqrt((charge - ped) * channelData.fcByPE());
523  } else {
524  mdi.inNoisePhoto[iTS] = 0;
525  }
526 
527  mdi.inPedestal[iTS] = channelData.tsPedestalWidth(iTS);
528  mdi.totalUCNoise[iTS] = nnlsWork_.noiseTerms.coeffRef(iTS);
529 
530  if (channelData.hasTimeInfo()) {
531  mdi.inputTDC[iTS] = channelData.tsRiseTime(iTS);
532  } else {
533  mdi.inputTDC[iTS] = -1;
534  }
535  }
536 
537  mdi.arrivalTime = recoTime;
538  mdi.chiSq = chi2;
539 
540  for (unsigned int iBX = 0; iBX < nnlsWork_.nPulseTot; ++iBX) {
541  if (nnlsWork_.bxs.coeff(iBX) == 0) {
542  mdi.mahiEnergy = nnlsWork_.ampVec.coeff(iBX);
543  for (unsigned int iTS = 0; iTS < nnlsWork_.tsSize; ++iTS) {
544  mdi.count[iTS] = iTS;
545  mdi.inputTS[iTS] = nnlsWork_.amplitudes.coeff(iTS);
546  mdi.itPulse[iTS] = nnlsWork_.pulseMat.col(iBX).coeff(iTS);
547  }
548  } else if (nnlsWork_.bxs.coeff(iBX) == pedestalBX_) {
549  mdi.pedEnergy = nnlsWork_.ampVec.coeff(iBX);
550  } else if (nnlsWork_.bxs.coeff(iBX) >= -3 && nnlsWork_.bxs.coeff(iBX) <= 4) {
551  int ootIndex = nnlsWork_.bxs.coeff(iBX);
552  if (ootIndex > 0)
553  ootIndex += 2;
554  else
555  ootIndex += 3;
556  mdi.ootEnergy[ootIndex] = nnlsWork_.ampVec.coeff(iBX);
557  for (unsigned int iTS = 0; iTS < nnlsWork_.tsSize; ++iTS) {
558  mdi.ootPulse[ootIndex][iTS] = nnlsWork_.pulseMat.col(iBX).coeff(iTS);
559  }
560  }
561  }
562 }
563 
564 void MahiFit::solveSubmatrix(PulseMatrix& mat, PulseVector& invec, PulseVector& outvec, unsigned nP) const {
565  using namespace Eigen;
566  switch (nP) { // pulse matrix is always square.
567  case 10: {
568  Matrix<float, 10, 10> temp = mat;
569  outvec.head<10>() = temp.ldlt().solve(invec.head<10>());
570  } break;
571  case 9: {
572  Matrix<float, 9, 9> temp = mat.topLeftCorner<9, 9>();
573  outvec.head<9>() = temp.ldlt().solve(invec.head<9>());
574  } break;
575  case 8: {
576  Matrix<float, 8, 8> temp = mat.topLeftCorner<8, 8>();
577  outvec.head<8>() = temp.ldlt().solve(invec.head<8>());
578  } break;
579  case 7: {
580  Matrix<float, 7, 7> temp = mat.topLeftCorner<7, 7>();
581  outvec.head<7>() = temp.ldlt().solve(invec.head<7>());
582  } break;
583  case 6: {
584  Matrix<float, 6, 6> temp = mat.topLeftCorner<6, 6>();
585  outvec.head<6>() = temp.ldlt().solve(invec.head<6>());
586  } break;
587  case 5: {
588  Matrix<float, 5, 5> temp = mat.topLeftCorner<5, 5>();
589  outvec.head<5>() = temp.ldlt().solve(invec.head<5>());
590  } break;
591  case 4: {
592  Matrix<float, 4, 4> temp = mat.topLeftCorner<4, 4>();
593  outvec.head<4>() = temp.ldlt().solve(invec.head<4>());
594  } break;
595  case 3: {
596  Matrix<float, 3, 3> temp = mat.topLeftCorner<3, 3>();
597  outvec.head<3>() = temp.ldlt().solve(invec.head<3>());
598  } break;
599  case 2: {
600  Matrix<float, 2, 2> temp = mat.topLeftCorner<2, 2>();
601  outvec.head<2>() = temp.ldlt().solve(invec.head<2>());
602  } break;
603  case 1: {
604  Matrix<float, 1, 1> temp = mat.topLeftCorner<1, 1>();
605  outvec.head<1>() = temp.ldlt().solve(invec.head<1>());
606  } break;
607  default:
608  throw cms::Exception("HcalMahiWeirdState")
609  << "Weird number of pulses encountered in Mahi, module is configured incorrectly!";
610  }
611 }
612 
614  nnlsWork_.nPulseTot = 0;
615  nnlsWork_.tsOffset = 0;
616  nnlsWork_.bxOffset = 0;
617  nnlsWork_.maxoffset = 0;
618  nnlsWork_.nP = 0;
619 
620  // NOT SURE THIS IS NEEDED
621  nnlsWork_.amplitudes.setZero();
622  nnlsWork_.noiseTerms.setZero();
623 }
HBHEChannelInfo::tsDFcPerADC
constexpr float tsDFcPerADC(const unsigned ts) const
Definition: HBHEChannelInfo.h:167
MahiFit::updatePulseShape
void updatePulseShape(const float itQ, FullSampleVector &pulseShape, FullSampleVector &pulseDeriv, FullSampleMatrix &pulseCov) const
Definition: MahiFit.cc:242
MahiFit::nnlsWork_
MahiNnlsWorkspace nnlsWork_
Definition: MahiFit.h:148
MahiDebugInfo::ootEnergy
float ootEnergy[7]
Definition: MahiFit.h:80
HBHEChannelInfo::hasTimeInfo
constexpr bool hasTimeInfo() const
Definition: HBHEChannelInfo.h:134
HLT_2018_cff.chiSqSwitch
chiSqSwitch
Definition: HLT_2018_cff.py:7102
CustomPhysics_cfi.amplitude
amplitude
Definition: CustomPhysics_cfi.py:12
MahiNnlsWorkspace::maxoffset
int maxoffset
Definition: MahiFit.h:22
HBHEChannelInfo::tsRiseTime
constexpr float tsRiseTime(const unsigned ts) const
Definition: HBHEChannelInfo.h:168
HBHEChannelInfo::nSamples
constexpr unsigned nSamples() const
Definition: HBHEChannelInfo.h:131
MessageLogger.h
MahiDebugInfo::itPulse
float itPulse[MaxSVSize]
Definition: MahiFit.h:85
MahiFit::timeSigmaSiPM_
float timeSigmaSiPM_
Definition: MahiFit.h:170
MahiFit::applyTimeSlew_
bool applyTimeSlew_
Definition: MahiFit.h:162
MahiDebugInfo::totalUCNoise
float totalUCNoise[MaxSVSize]
Definition: MahiFit.h:74
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
MahiDebugInfo
Definition: MahiFit.h:58
MahiFit::setPulseShapeTemplate
void setPulseShapeTemplate(const HcalPulseShapes::Shape &ps, bool hasTimeInfo, const HcalTimeSlew *hcalTimeSlewDelay, unsigned int nSamples)
Definition: MahiFit.cc:446
MahiDebugInfo::mahiEnergy
float mahiEnergy
Definition: MahiFit.h:76
HcalConst::maxSamples
constexpr int maxSamples
Definition: PulseShapeFunctor.h:8
min
T min(T a, T b)
Definition: MathUtil.h:58
FullSampleMatrix
Eigen::Matrix< double, FullSampleVectorSize, FullSampleVectorSize > FullSampleMatrix
Definition: EigenMatrixTypes.h:18
SampleMatrix
Eigen::Matrix< double, SampleVectorSize, SampleVectorSize > SampleMatrix
Definition: EigenMatrixTypes.h:17
HBHEChannelInfo::tsPedestalWidth
constexpr double tsPedestalWidth(const unsigned ts) const
Definition: HBHEChannelInfo.h:161
MahiNnlsWorkspace::aTaMat
PulseMatrix aTaMat
Definition: MahiFit.h:52
FitterFuncs::PulseShapeFunctor
Definition: PulseShapeFunctor.h:19
edm::swap
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:117
MahiDebugInfo::count
float count[MaxSVSize]
Definition: MahiFit.h:82
HBHEChannelInfo::tsGain
constexpr double tsGain(const unsigned ts) const
Definition: HBHEChannelInfo.h:162
cms::cuda::assert
assert(be >=bs)
MahiFit::bxSizeConf_
unsigned int bxSizeConf_
Definition: MahiFit.h:180
MahiFit.h
MahiFit::phase1Apply
void phase1Apply(const HBHEChannelInfo &channelData, float &reconstructedEnergy, float &reconstructedTime, bool &useTriple, float &chi2) const
Definition: MahiFit.cc:46
MahiFit::resetWorkspace
void resetWorkspace() const
Definition: MahiFit.cc:613
MahiNnlsWorkspace::ampVec
PulseVector ampVec
Definition: MahiFit.h:49
hltPixelTracks_cff.chi2
chi2
Definition: hltPixelTracks_cff.py:25
MahiFit::nnlsConstrainParameter
void nnlsConstrainParameter(Index minratioidx) const
Definition: MahiFit.cc:486
MahiNnlsWorkspace::bxs
BXVector bxs
Definition: MahiFit.h:26
createJobs.tmp
tmp
align.sh
Definition: createJobs.py:716
groupFilesInBlocks.temp
list temp
Definition: groupFilesInBlocks.py:142
MahiDebugInfo::pedEnergy
float pedEnergy
Definition: MahiFit.h:79
PresampleTask_cfi.nSamples
nSamples
Definition: PresampleTask_cfi.py:7
HcalTimeSlew::BiasSetting
BiasSetting
Definition: HcalTimeSlew.h:71
HcalTimeSlew
Definition: HcalTimeSlew.h:19
HcalTimeSlew::delay
float delay(float fC, BiasSetting bias=Medium) const
Returns the amount (ns) by which a pulse of the given number of fC will be delayed by the timeslew ef...
Definition: HcalTimeSlew.cc:20
MahiFit::calculateChiSq
float calculateChiSq() const
Definition: MahiFit.cc:441
MahiDebugInfo::inPedAvg
float inPedAvg
Definition: MahiFit.h:66
MahiFit::bxOffsetConf_
int bxOffsetConf_
Definition: MahiFit.h:181
MahiFit::nnlsThresh_
float nnlsThresh_
Definition: MahiFit.h:178
MahiNnlsWorkspace::tsOffset
unsigned int tsOffset
Definition: MahiFit.h:20
MahiNnlsWorkspace::aTbVec
PulseVector aTbVec
Definition: MahiFit.h:53
MahiFit::psfPtr_
std::unique_ptr< FitterFuncs::PulseShapeFunctor > psfPtr_
Definition: MahiFit.h:185
PulseVector
Eigen::Matrix< double, Eigen::Dynamic, 1, 0, PulseVectorSize, 1 > PulseVector
Definition: EigenMatrixTypes.h:14
MahiFit::timeLimit_
static constexpr float timeLimit_
Definition: MahiFit.h:155
HBHEChannelInfo::fcByPE
constexpr double fcByPE() const
Definition: HBHEChannelInfo.h:137
FrontierCondition_GT_autoExpress_cfi.t0
t0
Definition: FrontierCondition_GT_autoExpress_cfi.py:148
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
MahiFit::setParameters
void setParameters(bool iDynamicPed, double iTS4Thresh, double chiSqSwitch, bool iApplyTimeSlew, HcalTimeSlew::BiasSetting slewFlavor, bool iCalculateArrivalTime, double iMeanTime, double iTimeSigmaHPD, double iTimeSigmaSiPM, const std::vector< int > &iActiveBXs, int iNMaxItersMin, int iNMaxItersNNLS, double iDeltaChiSqThresh, double iNnlsThresh)
Definition: MahiFit.cc:7
MahiNnlsWorkspace::noiseTerms
SampleVector noiseTerms
Definition: MahiFit.h:32
MahiDebugInfo::inNoisePhoto
float inNoisePhoto[MaxSVSize]
Definition: MahiFit.h:71
MahiDebugInfo::use3
bool use3
Definition: MahiFit.h:62
MahiDebugInfo::nSamples
int nSamples
Definition: MahiFit.h:59
MahiDebugInfo::arrivalTime
float arrivalTime
Definition: MahiFit.h:78
HBHEChannelInfo::tsPedestal
constexpr double tsPedestal(const unsigned ts) const
Definition: HBHEChannelInfo.h:160
OrderedSet.t
t
Definition: OrderedSet.py:90
MahiFit::calculateArrivalTime_
bool calculateArrivalTime_
Definition: MahiFit.h:167
MahiDebugInfo::ootPulse
float ootPulse[7][MaxSVSize]
Definition: MahiFit.h:86
MahiNnlsWorkspace::invcovp
SamplePulseMatrix invcovp
Definition: MahiFit.h:51
particleFlowDisplacedVertex_cfi.ratio
ratio
Definition: particleFlowDisplacedVertex_cfi.py:93
ALCARECOTkAlJpsiMuMu_cff.charge
charge
Definition: ALCARECOTkAlJpsiMuMu_cff.py:47
MahiNnlsWorkspace::pedVal
float pedVal
Definition: MahiFit.h:35
MahiDebugInfo::soi
int soi
Definition: MahiFit.h:60
MahiFit::MahiFit
MahiFit()
Definition: MahiFit.cc:5
MahiFit::pedestalBX_
static constexpr int pedestalBX_
Definition: MahiFit.h:151
MahiNnlsWorkspace::dt
float dt
Definition: MahiFit.h:23
MahiFit::cntsetPulseShape_
int cntsetPulseShape_
Definition: MahiFit.h:184
MahiFit::solveSubmatrix
void solveSubmatrix(PulseMatrix &mat, PulseVector &invec, PulseVector &outvec, unsigned nP) const
Definition: MahiFit.cc:564
MahiNnlsWorkspace::tsSize
unsigned int tsSize
Definition: MahiFit.h:19
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
MahiFit::timeSigmaHPD_
float timeSigmaHPD_
Definition: MahiFit.h:169
MahiFit::minimize
const float minimize() const
Definition: MahiFit.cc:206
MahiNnlsWorkspace::amplitudes
SampleVector amplitudes
Definition: MahiFit.h:29
cms::cuda::wmax
V V wmax
Definition: HistoContainer.h:136
MahiFit::phase1Debug
void phase1Debug(const HBHEChannelInfo &channelData, MahiDebugInfo &mdi) const
Definition: MahiFit.cc:498
dumpMFGeometry_cfg.delta
delta
Definition: dumpMFGeometry_cfg.py:25
MahiFit::chiSqSwitch_
float chiSqSwitch_
Definition: MahiFit.h:160
MahiFit::tsDelay1GeV_
float tsDelay1GeV_
Definition: MahiFit.h:164
MahiNnlsWorkspace::pulseCovArray
std::array< SampleMatrix, MaxPVSize > pulseCovArray
Definition: MahiFit.h:39
MahiFit::nMaxItersNNLS_
int nMaxItersNNLS_
Definition: MahiFit.h:175
MahiDebugInfo::inputTDC
int inputTDC[MaxSVSize]
Definition: MahiFit.h:84
MahiFit::updateCov
void updateCov(const SampleMatrix &invCovMat) const
Definition: MahiFit.cc:298
SamplePulseMatrix
Eigen::Matrix< double, SampleVectorSize, Eigen::Dynamic, 0, SampleVectorSize, PulseVectorSize > SamplePulseMatrix
Definition: EigenMatrixTypes.h:20
MahiFit::ts4Thresh_
float ts4Thresh_
Definition: MahiFit.h:159
MahiNnlsWorkspace::pulseMat
SamplePulseMatrix pulseMat
Definition: MahiFit.h:42
MahiFit::onePulseMinimize
void onePulseMinimize() const
Definition: MahiFit.cc:431
SampleVector
Eigen::Matrix< double, SampleVectorSize, 1 > SampleVector
Definition: EigenMatrixTypes.h:12
MahiNnlsWorkspace::nP
unsigned int nP
Definition: MahiFit.h:48
HcalPulseShape
Definition: HcalPulseShape.h:6
FullSampleVector
Eigen::Matrix< double, FullSampleVectorSize, 1 > FullSampleVector
Definition: EigenMatrixTypes.h:13
MahiDebugInfo::inTimeConst
float inTimeConst
Definition: MahiFit.h:64
MahiFit::nnls
void nnls() const
Definition: MahiFit.cc:339
MahiNnlsWorkspace::bxOffset
int bxOffset
Definition: MahiFit.h:21
MahiFit::hcalTimeSlewDelay_
const HcalTimeSlew * hcalTimeSlewDelay_
Definition: MahiFit.h:127
MahiFit::norm_
float norm_
Definition: MahiFit.h:165
MahiFit::meanTime_
float meanTime_
Definition: MahiFit.h:168
MahiDebugInfo::inGain
float inGain
Definition: MahiFit.h:67
MahiFit::resetPulseShapeTemplate
void resetPulseShapeTemplate(const HcalPulseShapes::Shape &ps, bool hasTimeInfo, unsigned int nSamples)
Definition: MahiFit.cc:459
MahiFit::deltaChiSqThresh_
float deltaChiSqThresh_
Definition: MahiFit.h:177
PulseMatrix
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic, 0, PulseVectorSize, PulseVectorSize > PulseMatrix
Definition: EigenMatrixTypes.h:19
MahiFit::currentPulseShape_
const HcalPulseShapes::Shape * currentPulseShape_
Definition: MahiFit.h:126
Exception
Definition: hltDiff.cc:246
MahiNnlsWorkspace::covDecomp
SampleDecompLLT covDecomp
Definition: MahiFit.h:55
MahiFit::slewFlavor_
HcalTimeSlew::BiasSetting slewFlavor_
Definition: MahiFit.h:163
HBHEChannelInfo::tsRawCharge
constexpr double tsRawCharge(const unsigned ts) const
Definition: HBHEChannelInfo.h:159
MahiDebugInfo::inputTS
float inputTS[MaxSVSize]
Definition: MahiFit.h:83
MahiDebugInfo::inNoiseADC
float inNoiseADC[MaxSVSize]
Definition: MahiFit.h:69
MahiFit::dynamicPed_
bool dynamicPed_
Definition: MahiFit.h:158
MahiFit::doFit
void doFit(std::array< float, 3 > &correctedOutput, const int nbx) const
Definition: MahiFit.cc:115
MahiFit::Index
BXVector::Index Index
Definition: MahiFit.h:125
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
HBHEChannelInfo::soi
constexpr unsigned soi() const
Definition: HBHEChannelInfo.h:132
MahiDebugInfo::chiSq
float chiSq
Definition: MahiFit.h:77
remoteMonitoring_LED_IterMethod_cfg.threshold
threshold
Definition: remoteMonitoring_LED_IterMethod_cfg.py:426
hltrates_dqm_sourceclient-live_cfg.offset
offset
Definition: hltrates_dqm_sourceclient-live_cfg.py:82
MahiFit::activeBXs_
std::vector< int > activeBXs_
Definition: MahiFit.h:172
MahiDebugInfo::inPedestal
float inPedestal[MaxSVSize]
Definition: MahiFit.h:72
MahiNnlsWorkspace::nPulseTot
unsigned int nPulseTot
Definition: MahiFit.h:18
MahiFit::calculateArrivalTime
float calculateArrivalTime(unsigned int iBX) const
Definition: MahiFit.cc:319
geometryCSVtoXML.xx
xx
Definition: geometryCSVtoXML.py:19
MahiFit::nMaxItersMin_
int nMaxItersMin_
Definition: MahiFit.h:174
MahiNnlsWorkspace::pulseDerivMat
SamplePulseMatrix pulseDerivMat
Definition: MahiFit.h:45
HBHEChannelInfo
Definition: HBHEChannelInfo.h:15
MahiFit::nnlsUnconstrainParameter
void nnlsUnconstrainParameter(Index idxp) const
Definition: MahiFit.cc:474