33 mMinimumChargeThreshold = 99999999;
37 unsigned int TrianglePeakTS,
38 vector<double> LinearThreshold,
39 vector<double> LinearCut,
40 vector<double> RMS8MaxThreshold,
41 vector<double> RMS8MaxCut,
42 vector<double> LeftSlopeThreshold,
43 vector<double> LeftSlopeCut,
44 vector<double> RightSlopeThreshold,
45 vector<double> RightSlopeCut,
46 vector<double> RightSlopeSmallThreshold,
47 vector<double> RightSlopeSmallCut,
49 bool TriangleIgnoreSlow)
58 mMinimumChargeThreshold = MinimumChargeThreshold;
59 mTrianglePeakTS = TrianglePeakTS;
60 mTriangleIgnoreSlow = TriangleIgnoreSlow;
62 for(
int i = 0;
i < (int)LinearThreshold.size() &&
i < (int)LinearCut.size();
i++)
63 mLambdaLinearCut.push_back(pair<double, double>(LinearThreshold[
i], LinearCut[i]));
64 sort(mLambdaLinearCut.begin(), mLambdaLinearCut.end());
66 for(
int i = 0; i < (int)RMS8MaxThreshold.size() && i < (int)RMS8MaxCut.size(); i++)
67 mLambdaRMS8MaxCut.push_back(pair<double, double>(RMS8MaxThreshold[i], RMS8MaxCut[i]));
68 sort(mLambdaRMS8MaxCut.begin(), mLambdaRMS8MaxCut.end());
70 for(
int i = 0; i < (int)LeftSlopeThreshold.size() && i < (int)LeftSlopeCut.size(); i++)
71 mLeftSlopeCut.push_back(pair<double, double>(LeftSlopeThreshold[i], LeftSlopeCut[i]));
72 sort(mLeftSlopeCut.begin(), mLeftSlopeCut.end());
74 for(
int i = 0; i < (int)RightSlopeThreshold.size() && i < (int)RightSlopeCut.size(); i++)
75 mRightSlopeCut.push_back(pair<double, double>(RightSlopeThreshold[i], RightSlopeCut[i]));
76 sort(mRightSlopeCut.begin(), mRightSlopeCut.end());
78 for(
int i = 0; i < (int)RightSlopeSmallThreshold.size() && i < (int)RightSlopeSmallCut.size(); i++)
79 mRightSlopeSmallCut.push_back(pair<double, double>(RightSlopeSmallThreshold[i], RightSlopeSmallCut[i]));
80 sort(mRightSlopeSmallCut.begin(), mRightSlopeSmallCut.end());
82 mUseDualFit = UseDualFit;
115 mCharge.resize(digi.
size());
117 double TotalCharge = 0;
119 for(
int i = 0;
i < (int)digi.
size(); ++
i)
122 TotalCharge += mCharge[
i];
126 if(TotalCharge < mMinimumChargeThreshold)
129 double NominalChi2 = 0;
130 if (mUseDualFit ==
true)
131 NominalChi2=PerformDualNominalFit(mCharge);
133 NominalChi2=PerformNominalFit(mCharge);
135 double LinearChi2 = PerformLinearFit(mCharge);
137 double RMS8Max = CalculateRMS8Max(mCharge);
141 if(CheckPassFilter(TotalCharge,
log(LinearChi2) -
log(NominalChi2), mLambdaLinearCut, -1) ==
false)
143 if(CheckPassFilter(TotalCharge,
log(RMS8Max) * 2 -
log(NominalChi2), mLambdaRMS8MaxCut, -1) ==
false)
147 if ((
int)mCharge.size() >= mTrianglePeakTS)
150 double TS4Left = 1000;
151 double TS4Right = 1000;
155 TS4Left = mCharge[mTrianglePeakTS] / TriangleResult.
LeftSlope;
157 TS4Right = mCharge[mTrianglePeakTS] / -TriangleResult.
RightSlope;
159 if(TS4Left > 1000 || TS4Left < -1000)
161 if(TS4Right > 1000 || TS4Right < -1000)
164 if(mTriangleIgnoreSlow ==
false)
166 if(CheckPassFilter(mCharge[mTrianglePeakTS], TS4Left, mLeftSlopeCut, 1) ==
false)
168 else if(CheckPassFilter(mCharge[mTrianglePeakTS], TS4Right, mRightSlopeCut, 1) ==
false)
173 if(CheckPassFilter(mCharge[mTrianglePeakTS], TS4Right, mRightSlopeSmallCut, -1) ==
false)
194 vector<double> PulseShape;
199 PulseShape.reserve(350);
200 for(
int i = 0;
i < 200;
i++)
201 PulseShape.push_back(HPDShape.
at(
i));
202 PulseShape.insert(PulseShape.begin(), 150, 0);
204 CumulativeIdealPulse.reserve(350);
205 CumulativeIdealPulse.clear();
206 CumulativeIdealPulse.push_back(0);
207 for(
unsigned int i = 1;
i < PulseShape.size();
i++)
208 CumulativeIdealPulse.push_back(CumulativeIdealPulse[
i-1] + PulseShape[
i]);
227 int DigiSize = Charge.size();
230 double MinimumRightChi2 = 1000000;
231 double Numerator = 0;
232 double Denominator = 0;
234 for(
int iTS = mTrianglePeakTS + 2; iTS <= DigiSize; iTS++)
240 for(
int i = mTrianglePeakTS + 1;
i < iTS;
i++)
242 Numerator += (
i - mTrianglePeakTS) * (Charge[
i] - Charge[mTrianglePeakTS]);
243 Denominator += (
i - mTrianglePeakTS) * (
i - mTrianglePeakTS);
246 double BestSlope = 0;
247 if (Denominator!=0) BestSlope = Numerator / Denominator;
255 if(BestSlope > -1 * Charge[mTrianglePeakTS] / (iTS - mTrianglePeakTS))
256 BestSlope = -1 * Charge[mTrianglePeakTS] / (iTS - mTrianglePeakTS);
257 if(BestSlope < -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS))
258 BestSlope = -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS);
263 if(BestSlope < -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS))
264 BestSlope = -1 * Charge[mTrianglePeakTS] / (iTS - 1 - mTrianglePeakTS);
273 for(
int i = mTrianglePeakTS + 1;
i < iTS;
i++)
274 Chi2 += (Charge[mTrianglePeakTS] - Charge[
i] + (
i - mTrianglePeakTS) * BestSlope)
275 * (Charge[mTrianglePeakTS] - Charge[
i] + (
i - mTrianglePeakTS) * BestSlope);
276 for(
int i = iTS;
i < DigiSize;
i++)
277 Chi2 += Charge[
i] * Charge[
i];
279 if(Chi2 < MinimumRightChi2)
281 MinimumRightChi2 = Chi2;
287 double MinimumLeftChi2 = 1000000;
289 for(
int iTS = 0; iTS < (int)mTrianglePeakTS; iTS++)
294 for(
int i = iTS;
i < (int)mTrianglePeakTS;
i++)
296 Numerator = Numerator + (
i - mTrianglePeakTS) * (Charge[
i] - Charge[mTrianglePeakTS]);
297 Denominator = Denominator + (
i - mTrianglePeakTS) * (
i - mTrianglePeakTS);
300 double BestSlope = 0;
301 if (Denominator!=0) BestSlope = Numerator / Denominator;
309 if(BestSlope > Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS))
310 BestSlope = Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS);
311 if(BestSlope < Charge[mTrianglePeakTS] / (mTrianglePeakTS + 1 - iTS))
312 BestSlope = Charge[mTrianglePeakTS] / (mTrianglePeakTS + 1 - iTS);
316 if(BestSlope > Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS))
317 BestSlope = Charge[mTrianglePeakTS] / (mTrianglePeakTS - iTS);
322 for(
int i = 0;
i < iTS;
i++)
323 Chi2 += Charge[
i] * Charge[
i];
324 for(
int i = iTS;
i < (int)mTrianglePeakTS;
i++)
325 Chi2 += (Charge[mTrianglePeakTS] - Charge[
i] + (
i - mTrianglePeakTS) * BestSlope)
326 * (Charge[mTrianglePeakTS] - Charge[
i] + (
i - mTrianglePeakTS) * BestSlope);
328 if(MinimumLeftChi2 > Chi2)
330 MinimumLeftChi2 = Chi2;
335 result.
Chi2 = MinimumLeftChi2 + MinimumRightChi2;
349 int DigiSize = Charge.size();
351 double MinimumChi2 = 100000;
359 for(
int i = 0;
i + 250 < (int)CumulativeIdealPulse.size();
i++)
361 if(CumulativeIdealPulse[
i+250] - CumulativeIdealPulse[
i] < 1
e-5)
369 for(
int j = 0;
j < DigiSize;
j++)
372 F = CumulativeIdealPulse[
i+
j*25+25] - CumulativeIdealPulse[
i+
j*25];
378 SumF2 += F * F / ErrorTemp;
379 SumTF += F * Charge[
j] / ErrorTemp;
380 SumT2 += fabs(Charge[
j]);
394 double Chi2 = SumT2 - SumTF * SumTF / SumF2;
396 if(Chi2 < MinimumChi2)
401 if(MinimumChi2 < 1
e-5)
417 double OverallMinimumChi2 = 1000000;
419 int AvailableDistance[] = {-100, -75, -50, 50, 75, 100};
422 for(
int k = 0;
k < 6;
k++)
424 double SingleMinimumChi2 = 1000000;
428 for(
int i = 0;
i + 250 < (int)CumulativeIdealPulse.size();
i += 10)
430 double Chi2 = DualNominalFitSingleTry(Charge,
i, AvailableDistance[
k]);
432 if(Chi2 < SingleMinimumChi2)
434 SingleMinimumChi2 = Chi2;
440 for(
int i = MinOffset - 15;
i + 250 < (int)CumulativeIdealPulse.size() &&
i < MinOffset + 15;
i++)
442 double Chi2 = DualNominalFitSingleTry(Charge,
i, AvailableDistance[
k]);
443 if(Chi2 < SingleMinimumChi2)
444 SingleMinimumChi2 = Chi2;
448 if(SingleMinimumChi2 < OverallMinimumChi2)
449 OverallMinimumChi2 = SingleMinimumChi2;
452 return OverallMinimumChi2;
467 int DigiSize = Charge.size();
469 if(Offset < 0 || Offset + 250 >= (
int)CumulativeIdealPulse.size())
471 if(CumulativeIdealPulse[Offset+250] - CumulativeIdealPulse[Offset] < 1
e-5)
474 static vector<double> F1;
475 static vector<double> F2;
488 for(
int j = 0;
j < DigiSize;
j++)
491 F1[
j] = CumulativeIdealPulse[Offset+
j*25+25] - CumulativeIdealPulse[Offset+
j*25];
496 int OffsetTemp = Offset +
j * 25 + Distance;
501 if(OffsetTemp + 25 < (
int)CumulativeIdealPulse.size() && OffsetTemp + 25 >= 0)
502 C1 = CumulativeIdealPulse[OffsetTemp+25];
503 if(OffsetTemp + 25 >= (
int)CumulativeIdealPulse.size())
504 C1 = CumulativeIdealPulse[CumulativeIdealPulse.size()-1];
505 if(OffsetTemp < (
int)CumulativeIdealPulse.size() && OffsetTemp >= 0)
506 C2 = CumulativeIdealPulse[OffsetTemp];
507 if(OffsetTemp >= (
int)CumulativeIdealPulse.size())
508 C2 = CumulativeIdealPulse[CumulativeIdealPulse.size()-1];
515 SumF1F1 += F1[
j] * F1[
j] / Error;
516 SumF1F2 += F1[
j] * F2[
j] / Error;
517 SumF2F2 += F2[
j] * F2[
j] / Error;
518 SumTF1 += F1[
j] * Charge[
j] / Error;
519 SumTF2 += F2[
j] * Charge[
j] / Error;
524 if (fabs(SumF1F2*SumF1F2-SumF1F1*SumF2F2)>1
e-5)
526 Height = (SumF1F2 * SumTF2 - SumF2F2 * SumTF1) / (SumF1F2 * SumF1F2 - SumF1F1 * SumF2F2);
527 Height2 = (SumF1F2 * SumTF1 - SumF1F1 * SumTF2) / (SumF1F2 * SumF1F2 - SumF1F1 * SumF2F2);
531 for(
int j = 0;
j < DigiSize;
j++)
533 double Error = Charge[
j];
537 double Residual = Height * F1[
j] + Height2 * F2[
j] - Charge[
j];
538 Chi2 += Residual * Residual / Error;
559 int DigiSize = Charge.size();
561 if (DigiSize<=2)
return 1
e-5;
563 vector<double> TempCharge = Charge;
566 sort(TempCharge.begin(), TempCharge.end());
570 for(
int i = 0;
i < DigiSize - 2;
i++)
572 Total = Total + TempCharge[
i];
573 Total2 = Total2 + TempCharge[
i] * TempCharge[
i];
582 double RMS =
sqrt(Total2 - Total * Total / (DigiSize - 2));
584 double RMS8Max = RMS / TempCharge[DigiSize-1];
588 return RMS / TempCharge[DigiSize-1];
601 int DigiSize = Charge.size();
603 double SumTS2OverTi = 0;
604 double SumTSOverTi = 0;
605 double SumOverTi = 0;
610 for(
int i = 0;
i < DigiSize;
i++)
616 SumTS2OverTi += 1.*
i *
i / Error2;
617 SumTSOverTi += 1.*
i / Error2;
618 SumOverTi += 1. / Error2;
619 SumTiTS += Charge[
i] *
i / Error2;
620 SumTi += Charge[
i] / Error2;
623 double CM1 = SumTS2OverTi;
624 double CM2 = SumTSOverTi;
625 double CD1 = SumTSOverTi;
626 double CD2 = SumOverTi;
631 double Slope = (C1 * CD2 - C2 * CD1) / (CM1 * CD2 - CM2 * CD1);
632 double Intercept = (C1 * CM2 - C2 * CM1) / (CD1 * CM2 - CD2 * CM1);
636 for(
int i = 0;
i < DigiSize;
i++)
638 double Deviation = Slope *
i + Intercept - Charge[
i];
639 double Error2 = Charge[
i];
642 Chi2 += Deviation * Deviation / Error2;
654 vector<pair<double, double> > &Cuts,
669 if(Charge <= Cuts[0].
first)
672 int IndexLargerThanCharge = -1;
673 for(
int i = 1;
i < (int)Cuts.size();
i++)
675 if(Cuts[
i].first > Charge)
677 IndexLargerThanCharge =
i;
682 double limit = 1000000;
684 if(IndexLargerThanCharge == -1)
685 limit = Cuts[Cuts.size()-1].second;
688 double C1 = Cuts[IndexLargerThanCharge].first;
689 double C2 = Cuts[IndexLargerThanCharge-1].first;
690 double L1 = Cuts[IndexLargerThanCharge].second;
691 double L2 = Cuts[IndexLargerThanCharge-1].second;
693 limit = (Charge - C1) / (C2 - C1) * (L2 - L1) + L1;
696 if(Side > 0 && Discriminant > limit)
698 if(Side < 0 && Discriminant < limit)
int size() const
total number of samples in the digi
void setFlagField(uint32_t value, int base, int width=1)
double pedestal(int fCapId) const
get pedestal for capid=0..3
double CalculateRMS8Max(const std::vector< double > &Charge)
double PerformNominalFit(const std::vector< double > &Charge)
double PerformDualNominalFit(const std::vector< double > &Charge)
~HBHEPulseShapeFlagSetter()
double PerformLinearFit(const std::vector< double > &Charge)
TriangleFitResult PerformTriangleFit(const std::vector< double > &Charge)
MVATrainerComputer * calib
HBHEPulseShapeFlagSetter()
bool CheckPassFilter(double Charge, double Discriminant, std::vector< std::pair< double, double > > &Cuts, int Side)
Log< T >::type log(const T &t)
int capid() const
get the Capacitor id
const HcalQIESample & sample(int i) const
access a sample
double DualNominalFitSingleTry(const std::vector< double > &Charge, int Offset, int Distance)
float at(double time) const
const Shape & hbShape() const
virtual void adc2fC(const HBHEDataFrame &df, CaloSamples &lf) const =0
void SetPulseShapeFlags(HBHERecHit &hbhe, const HBHEDataFrame &digi, const HcalCoder &coder, const HcalCalibrations &calib)