CMS 3D CMS Logo

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