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