File indexing completed on 2024-04-06 12:25:46
0001
0002 #ifndef HBHE_PULSESHAPE_FLAG_H_IKAJHGEWRHIGKHAWFIKGHAWIKGH
0003 #define HBHE_PULSESHAPE_FLAG_H_IKAJHGEWRHIGKHAWFIKGHAWIKGH
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #include <string>
0015 #include <vector>
0016 #include <map>
0017 #include <cmath>
0018
0019 #include "DataFormats/HcalDigi/interface/HBHEDataFrame.h"
0020 #include "DataFormats/HcalRecHit/interface/HcalRecHitCollections.h"
0021 #include "DataFormats/HcalRecHit/interface/HBHERecHit.h"
0022 #include "DataFormats/METReco/interface/HcalCaloFlagLabels.h"
0023 #include "CalibFormats/HcalObjects/interface/HcalCalibrations.h"
0024 #include "CalibFormats/HcalObjects/interface/HcalCoderDb.h"
0025 #include "CalibFormats/CaloObjects/interface/CaloSamples.h"
0026
0027 class HBHEPulseShapeFlagSetter;
0028 struct TriangleFitResult;
0029
0030 class HBHEPulseShapeFlagSetter {
0031 public:
0032 HBHEPulseShapeFlagSetter(double MinimumChargeThreshold,
0033 double TS4TS5ChargeThreshold,
0034 double TS3TS4ChargeThreshold,
0035 double TS3TS4UpperChargeThreshold,
0036 double TS5TS6ChargeThreshold,
0037 double TS5TS6UpperChargeThreshold,
0038 double R45PlusOneRange,
0039 double R45MinusOneRange,
0040 unsigned int TrianglePeakTS,
0041 const std::vector<double>& LinearThreshold,
0042 const std::vector<double>& LinearCut,
0043 const std::vector<double>& RMS8MaxThreshold,
0044 const std::vector<double>& RMS8MaxCut,
0045 const std::vector<double>& LeftSlopeThreshold,
0046 const std::vector<double>& LeftSlopeCut,
0047 const std::vector<double>& RightSlopeThreshold,
0048 const std::vector<double>& RightSlopeCut,
0049 const std::vector<double>& RightSlopeSmallThreshold,
0050 const std::vector<double>& RightSlopeSmallCut,
0051 const std::vector<double>& TS4TS5UpperThreshold,
0052 const std::vector<double>& TS4TS5UpperCut,
0053 const std::vector<double>& TS4TS5LowerThreshold,
0054 const std::vector<double>& TS4TS5LowerCut,
0055 bool UseDualFit,
0056 bool TriangleIgnoreSlow,
0057 bool setLegacyFlags = true);
0058
0059 ~HBHEPulseShapeFlagSetter();
0060
0061 void Clear();
0062 void Initialize();
0063
0064 template <class Dataframe>
0065 void SetPulseShapeFlags(HBHERecHit& hbhe,
0066 const Dataframe& digi,
0067 const HcalCoder& coder,
0068 const HcalCalibrations& calib);
0069
0070 private:
0071 double mMinimumChargeThreshold;
0072 double mTS4TS5ChargeThreshold;
0073 double mTS3TS4UpperChargeThreshold;
0074 double mTS5TS6UpperChargeThreshold;
0075 double mTS3TS4ChargeThreshold;
0076 double mTS5TS6ChargeThreshold;
0077 double mR45PlusOneRange;
0078 double mR45MinusOneRange;
0079 int mTrianglePeakTS;
0080 std::vector<double> mCharge;
0081
0082 std::vector<std::pair<double, double> > mLambdaLinearCut;
0083 std::vector<std::pair<double, double> > mLambdaRMS8MaxCut;
0084 std::vector<std::pair<double, double> > mLeftSlopeCut;
0085 std::vector<std::pair<double, double> > mRightSlopeCut;
0086 std::vector<std::pair<double, double> > mRightSlopeSmallCut;
0087 std::vector<std::pair<double, double> > mTS4TS5UpperCut;
0088 std::vector<std::pair<double, double> > mTS4TS5LowerCut;
0089 bool mUseDualFit;
0090 bool mTriangleIgnoreSlow;
0091 bool mSetLegacyFlags;
0092 std::vector<double> CumulativeIdealPulse;
0093
0094 private:
0095 TriangleFitResult PerformTriangleFit(const std::vector<double>& Charge);
0096 double PerformNominalFit(const std::vector<double>& Charge);
0097 double PerformDualNominalFit(const std::vector<double>& Charge);
0098 double DualNominalFitSingleTry(const std::vector<double>& Charge, int Offset, int Distance, bool newCharges = true);
0099 double CalculateRMS8Max(const std::vector<double>& Charge);
0100 double PerformLinearFit(const std::vector<double>& Charge);
0101
0102 private:
0103 bool CheckPassFilter(double Charge, double Discriminant, std::vector<std::pair<double, double> >& Cuts, int Side);
0104 std::vector<double> f1_;
0105 std::vector<double> f2_;
0106 std::vector<double> errors_;
0107 };
0108
0109 struct TriangleFitResult {
0110 double Chi2;
0111 double LeftSlope;
0112 double RightSlope;
0113 };
0114
0115
0116 template <class Dataframe>
0117 void HBHEPulseShapeFlagSetter::SetPulseShapeFlags(HBHERecHit& hbhe,
0118 const Dataframe& digi,
0119 const HcalCoder& coder,
0120 const HcalCalibrations& calib) {
0121
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131 int abseta = hbhe.id().ietaAbs();
0132 if (abseta == 28 || abseta == 29)
0133 return;
0134
0135 CaloSamples Tool;
0136 coder.adc2fC(digi, Tool);
0137
0138
0139 const unsigned nRead = digi.size();
0140 mCharge.resize(nRead);
0141
0142 double TotalCharge = 0.0;
0143 for (unsigned i = 0; i < nRead; ++i) {
0144 mCharge[i] = Tool[i] - calib.pedestal(digi[i].capid());
0145 TotalCharge += mCharge[i];
0146 }
0147
0148
0149 if (TotalCharge < mMinimumChargeThreshold)
0150 return;
0151
0152 if (mSetLegacyFlags) {
0153 double NominalChi2 = 0;
0154 if (mUseDualFit == true)
0155 NominalChi2 = PerformDualNominalFit(mCharge);
0156 else
0157 NominalChi2 = PerformNominalFit(mCharge);
0158
0159 double LinearChi2 = PerformLinearFit(mCharge);
0160
0161 double RMS8Max = CalculateRMS8Max(mCharge);
0162
0163
0164 if (CheckPassFilter(TotalCharge, log(LinearChi2) - log(NominalChi2), mLambdaLinearCut, -1) == false)
0165 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHEFlatNoise);
0166 if (CheckPassFilter(TotalCharge, log(RMS8Max) * 2 - log(NominalChi2), mLambdaRMS8MaxCut, -1) == false)
0167 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHESpikeNoise);
0168
0169
0170 if ((int)mCharge.size() >=
0171 mTrianglePeakTS)
0172 {
0173 TriangleFitResult TriangleResult = PerformTriangleFit(mCharge);
0174
0175
0176 double TS4Left = 1000;
0177 double TS4Right = 1000;
0178
0179
0180 if (TriangleResult.LeftSlope > 1e-5)
0181 TS4Left = mCharge[mTrianglePeakTS] / TriangleResult.LeftSlope;
0182 if (TriangleResult.RightSlope < -1e-5)
0183 TS4Right = mCharge[mTrianglePeakTS] / -TriangleResult.RightSlope;
0184
0185 if (TS4Left > 1000 || TS4Left < -1000)
0186 TS4Left = 1000;
0187 if (TS4Right > 1000 || TS4Right < -1000)
0188 TS4Right = 1000;
0189
0190 if (mTriangleIgnoreSlow == false)
0191 {
0192 if (CheckPassFilter(mCharge[mTrianglePeakTS], TS4Left, mLeftSlopeCut, 1) == false)
0193 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHETriangleNoise);
0194 else if (CheckPassFilter(mCharge[mTrianglePeakTS], TS4Right, mRightSlopeCut, 1) == false)
0195 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHETriangleNoise);
0196 }
0197
0198
0199 if (CheckPassFilter(mCharge[mTrianglePeakTS], TS4Right, mRightSlopeSmallCut, -1) == false)
0200 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHETriangleNoise);
0201 }
0202 }
0203
0204 int soi = digi.presamples();
0205
0206 if (mCharge[soi] + mCharge[soi + 1] > mTS4TS5ChargeThreshold &&
0207 mTS4TS5ChargeThreshold > 0)
0208 {
0209 double TS4TS5 = (mCharge[soi] - mCharge[soi + 1]) / (mCharge[soi] + mCharge[soi + 1]);
0210 if (CheckPassFilter(mCharge[soi] + mCharge[soi + 1], TS4TS5, mTS4TS5UpperCut, 1) == false)
0211 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHETS4TS5Noise);
0212 if (CheckPassFilter(mCharge[soi] + mCharge[soi + 1], TS4TS5, mTS4TS5LowerCut, -1) == false)
0213 hbhe.setFlagField(1, HcalCaloFlagLabels::HBHETS4TS5Noise);
0214
0215 if (CheckPassFilter(mCharge[soi] + mCharge[soi + 1], TS4TS5, mTS4TS5UpperCut, 1) ==
0216 false &&
0217 mCharge[soi - 1] + mCharge[soi] > mTS3TS4ChargeThreshold &&
0218 mTS3TS4ChargeThreshold > 0 &&
0219 mCharge[soi + 1] + mCharge[soi + 2] < mTS5TS6UpperChargeThreshold &&
0220 mTS5TS6UpperChargeThreshold > 0 &&
0221 fabs((mCharge[soi] - mCharge[soi + 1]) / (mCharge[soi] + mCharge[soi + 1]) - 1.0) <
0222 mR45PlusOneRange)
0223 {
0224 double TS3TS4 = (mCharge[soi - 1] - mCharge[soi]) / (mCharge[soi - 1] + mCharge[soi]);
0225 if (CheckPassFilter(mCharge[soi - 1] + mCharge[soi], TS3TS4, mTS4TS5UpperCut, 1) ==
0226 true &&
0227 CheckPassFilter(mCharge[soi - 1] + mCharge[soi], TS3TS4, mTS4TS5LowerCut, -1) ==
0228 true &&
0229 TS3TS4 > (mR45MinusOneRange - 1))
0230 hbhe.setFlagField(
0231 1, HcalCaloFlagLabels::HBHEOOTPU);
0232 }
0233
0234 if (CheckPassFilter(mCharge[soi] + mCharge[soi + 1], TS4TS5, mTS4TS5LowerCut, -1) ==
0235 false &&
0236 mCharge[soi - 1] + mCharge[soi] < mTS3TS4UpperChargeThreshold &&
0237 mTS3TS4UpperChargeThreshold > 0 &&
0238 mCharge[soi + 1] + mCharge[soi + 2] > mTS5TS6ChargeThreshold &&
0239 mTS5TS6ChargeThreshold > 0 &&
0240 fabs((mCharge[soi] - mCharge[soi + 1]) / (mCharge[soi] + mCharge[soi + 1]) + 1.0) <
0241 mR45MinusOneRange)
0242 {
0243 double TS5TS6 = (mCharge[soi + 1] - mCharge[soi + 2]) / (mCharge[soi + 1] + mCharge[soi + 2]);
0244 if (CheckPassFilter(mCharge[soi + 1] + mCharge[soi + 2], TS5TS6, mTS4TS5UpperCut, 1) ==
0245 true &&
0246 CheckPassFilter(mCharge[soi + 1] + mCharge[soi + 2], TS5TS6, mTS4TS5LowerCut, -1) ==
0247 true &&
0248 TS5TS6 < (1 - mR45PlusOneRange))
0249 hbhe.setFlagField(
0250 1, HcalCaloFlagLabels::HBHEOOTPU);
0251 }
0252 }
0253 }
0254
0255 #endif