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