File indexing completed on 2024-04-06 12:01:08
0001 #include "CommonTools/PileupAlgos/interface/PuppiAlgo.h"
0002 #include "FWCore/Utilities/interface/Exception.h"
0003 #include "Math/QuantFuncMathCore.h"
0004 #include "Math/SpecFuncMathCore.h"
0005 #include "Math/ProbFunc.h"
0006 #include "TMath.h"
0007
0008 PuppiAlgo::PuppiAlgo(edm::ParameterSet &iConfig) {
0009 fEtaMin = iConfig.getParameter<std::vector<double>>("etaMin");
0010 fEtaMax = iConfig.getParameter<std::vector<double>>("etaMax");
0011 fPtMin = iConfig.getParameter<std::vector<double>>("ptMin");
0012 fNeutralPtMin = iConfig.getParameter<std::vector<double>>("MinNeutralPt");
0013 fNeutralPtSlope = iConfig.getParameter<std::vector<double>>("MinNeutralPtSlope");
0014 fRMSEtaSF = iConfig.getParameter<std::vector<double>>("RMSEtaSF");
0015 fMedEtaSF = iConfig.getParameter<std::vector<double>>("MedEtaSF");
0016 fEtaMaxExtrap = iConfig.getParameter<double>("EtaMaxExtrap");
0017
0018 std::vector<edm::ParameterSet> lAlgos = iConfig.getParameter<std::vector<edm::ParameterSet>>("puppiAlgos");
0019 fNAlgos = lAlgos.size();
0020
0021 std::vector<double> tmprms;
0022 std::vector<double> tmpmed;
0023
0024 for (unsigned int i0 = 0; i0 < lAlgos.size(); i0++) {
0025 int pAlgoId = lAlgos[i0].getParameter<int>("algoId");
0026 bool pCharged = lAlgos[i0].getParameter<bool>("useCharged");
0027 bool pWeight0 = lAlgos[i0].getParameter<bool>("applyLowPUCorr");
0028 int pComb = lAlgos[i0].getParameter<int>("combOpt");
0029 double pConeSize = lAlgos[i0].getParameter<double>("cone");
0030 double pRMSPtMin = lAlgos[i0].getParameter<double>("rmsPtMin");
0031 double pRMSSF = lAlgos[i0].getParameter<double>("rmsScaleFactor");
0032 fAlgoId.push_back(pAlgoId);
0033 fCharged.push_back(pCharged);
0034 fAdjust.push_back(pWeight0);
0035 fCombId.push_back(pComb);
0036 fConeSize.push_back(pConeSize);
0037 fRMSPtMin.push_back(pRMSPtMin);
0038 fRMSScaleFactor.push_back(pRMSSF);
0039 double pRMS = 0;
0040 double pMed = 0;
0041 double pMean = 0;
0042 int pNCount = 0;
0043 fRMS.push_back(pRMS);
0044 fMedian.push_back(pMed);
0045 fMean.push_back(pMean);
0046 fNCount.push_back(pNCount);
0047
0048 tmprms.clear();
0049 tmpmed.clear();
0050 for (unsigned int j0 = 0; j0 < fEtaMin.size(); j0++) {
0051 tmprms.push_back(pRMS);
0052 tmpmed.push_back(pMed);
0053 }
0054 fRMS_perEta.push_back(tmprms);
0055 fMedian_perEta.push_back(tmpmed);
0056 }
0057
0058 cur_PtMin = -99.;
0059 cur_NeutralPtMin = -99.;
0060 cur_NeutralPtSlope = -99.;
0061 cur_RMS = -99.;
0062 cur_Med = -99.;
0063 }
0064 PuppiAlgo::~PuppiAlgo() {
0065 fPups.clear();
0066 fPupsPV.clear();
0067 }
0068 void PuppiAlgo::reset() {
0069 fPups.clear();
0070 fPupsPV.clear();
0071 for (unsigned int i0 = 0; i0 < fNAlgos; i0++) {
0072 fMedian[i0] = 0;
0073 fRMS[i0] = 0;
0074 fMean[i0] = 0;
0075 fNCount[i0] = 0;
0076 }
0077 }
0078
0079 void PuppiAlgo::fixAlgoEtaBin(int i_eta) {
0080 cur_PtMin = fPtMin[i_eta];
0081 cur_NeutralPtMin = fNeutralPtMin[i_eta];
0082 cur_NeutralPtSlope = fNeutralPtSlope[i_eta];
0083 cur_RMS = fRMS_perEta[0][i_eta];
0084 cur_Med = fMedian_perEta[0][i_eta];
0085 }
0086
0087 void PuppiAlgo::add(const PuppiCandidate &iParticle, const double &iVal, const unsigned int iAlgo) {
0088 if (iParticle.pt < fRMSPtMin[iAlgo])
0089 return;
0090
0091
0092
0093
0094 int puppi_id = iParticle.id;
0095 if (puppi_id == std::numeric_limits<int>::lowest()) {
0096 throw cms::Exception("PuppiRegisterNotSet") << "The puppi register is not set. This must be set before use.\n";
0097 }
0098
0099
0100 if ((std::abs(iParticle.eta) < fEtaMaxExtrap) && (puppi_id == 2)) {
0101 fPups.push_back(iVal);
0102 fNCount[iAlgo]++;
0103 }
0104
0105 if (std::abs(iParticle.eta) < fEtaMaxExtrap && (puppi_id == 1))
0106 fPupsPV.push_back(iVal);
0107 }
0108
0109
0110
0111
0112 void PuppiAlgo::computeMedRMS(const unsigned int &iAlgo) {
0113
0114 if (iAlgo >= fNAlgos)
0115 return;
0116 if (fNCount[iAlgo] == 0)
0117 return;
0118
0119
0120 int lNBefore = 0;
0121 for (unsigned int i0 = 0; i0 < iAlgo; i0++)
0122 lNBefore += fNCount[i0];
0123 std::sort(fPups.begin() + lNBefore, fPups.begin() + lNBefore + fNCount[iAlgo]);
0124
0125
0126 int lNum0 = 0;
0127 for (int i0 = lNBefore; i0 < lNBefore + fNCount[iAlgo]; i0++) {
0128 if (fPups[i0] == 0)
0129 lNum0 = i0 - lNBefore;
0130 }
0131
0132
0133 int lNHalfway = lNBefore + lNum0 + int(double(fNCount[iAlgo] - lNum0) * 0.50);
0134 fMedian[iAlgo] = fPups[lNHalfway];
0135 double lMed = fMedian[iAlgo];
0136
0137 int lNRMS = 0;
0138 for (int i0 = lNBefore; i0 < lNBefore + fNCount[iAlgo]; i0++) {
0139 fMean[iAlgo] += fPups[i0];
0140 if (fPups[i0] == 0)
0141 continue;
0142
0143 if (fAdjust[iAlgo] && fPups[i0] > lMed)
0144 continue;
0145 lNRMS++;
0146 fRMS[iAlgo] += (fPups[i0] - lMed) * (fPups[i0] - lMed);
0147 }
0148 fMean[iAlgo] /= fNCount[iAlgo];
0149 if (lNRMS > 0)
0150 fRMS[iAlgo] /= lNRMS;
0151 if (fRMS[iAlgo] == 0)
0152 fRMS[iAlgo] = 1e-5;
0153
0154 fRMS[iAlgo] = sqrt(fRMS[iAlgo]);
0155
0156
0157 fRMS[iAlgo] *= fRMSScaleFactor[iAlgo];
0158
0159 if (fAdjust[iAlgo]) {
0160
0161 int lNPV = 0;
0162 for (unsigned int i0 = 0; i0 < fPupsPV.size(); i0++)
0163 if (fPupsPV[i0] <= lMed)
0164 lNPV++;
0165 double lAdjust = double(lNPV) / double(lNPV + 0.5 * fNCount[iAlgo]);
0166 if (lAdjust > 0) {
0167 fMedian[iAlgo] -= sqrt(ROOT::Math::chisquared_quantile(lAdjust, 1.) * fRMS[iAlgo]);
0168 fRMS[iAlgo] -= sqrt(ROOT::Math::chisquared_quantile(lAdjust, 1.) * fRMS[iAlgo]);
0169 }
0170 }
0171
0172
0173
0174
0175 for (unsigned int j0 = 0; j0 < fEtaMin.size(); j0++) {
0176 fRMS_perEta[iAlgo][j0] = fRMS[iAlgo] * fRMSEtaSF[j0];
0177 fMedian_perEta[iAlgo][j0] = fMedian[iAlgo] * fMedEtaSF[j0];
0178 }
0179 }
0180
0181
0182
0183 double PuppiAlgo::compute(std::vector<double> const &iVals, double iChi2) const {
0184 if (fAlgoId[0] == -1)
0185 return 1;
0186 double lVal = 0.;
0187 double lPVal = 1.;
0188 int lNDOF = 0;
0189 for (unsigned int i0 = 0; i0 < fNAlgos; i0++) {
0190 if (fNCount[i0] == 0)
0191 return 1.;
0192 if (fCombId[i0] == 1 && i0 > 0) {
0193 double pPVal = ROOT::Math::chisquared_cdf(lVal, lNDOF);
0194 lPVal *= pPVal;
0195 lNDOF = 0;
0196 lVal = 0;
0197 }
0198 double pVal = iVals[i0];
0199
0200 if (fAlgoId[i0] == 0 && iVals[i0] == 0)
0201 pVal = cur_Med;
0202 if (fAlgoId[i0] == 3 && iVals[i0] == 0)
0203 pVal = cur_Med;
0204 if (fAlgoId[i0] == 5 && iVals[i0] == 0)
0205 pVal = cur_Med;
0206 lVal += (pVal - cur_Med) * (fabs(pVal - cur_Med)) / cur_RMS / cur_RMS;
0207 lNDOF++;
0208 if (i0 == 0 && iChi2 != 0)
0209 lNDOF++;
0210 if (i0 == 0 && iChi2 != 0)
0211 lVal += iChi2;
0212 }
0213
0214 lPVal *= ROOT::Math::chisquared_cdf(lVal, lNDOF);
0215 return lPVal;
0216 }
0217
0218 void PuppiAlgo::fillDescriptionsPuppiAlgo(edm::ParameterSetDescription &desc) {
0219 edm::ParameterSetDescription puppialgos;
0220 puppialgos.add<int>("algoId", 5);
0221 puppialgos.add<bool>("useCharged", false);
0222 puppialgos.add<bool>("applyLowPUCorr", false);
0223 puppialgos.add<int>("combOpt", 5);
0224 puppialgos.add<double>("cone", .4);
0225 puppialgos.add<double>("rmsPtMin", .1);
0226 puppialgos.add<double>("rmsScaleFactor", 1.0);
0227 std::vector<edm::ParameterSet> VPSetPuppiAlgos;
0228 edm::ParameterSet puppiset;
0229 puppiset.addParameter<int>("algoId", 5);
0230 puppiset.addParameter<bool>("useCharged", false);
0231 puppiset.addParameter<bool>("applyLowPUCorr", false);
0232 puppiset.addParameter<int>("combOpt", 5);
0233 puppiset.addParameter<double>("cone", .4);
0234 puppiset.addParameter<double>("rmsPtMin", .1);
0235 puppiset.addParameter<double>("rmsScaleFactor", 1.0);
0236 VPSetPuppiAlgos.push_back(puppiset);
0237
0238 edm::ParameterSetDescription algos;
0239 algos.addVPSet("puppiAlgos", puppialgos, VPSetPuppiAlgos);
0240 std::vector<edm::ParameterSet> VPSetAlgos;
0241 edm::ParameterSet algosset;
0242 algos.add<std::vector<double>>("etaMin", {0.});
0243 algos.add<std::vector<double>>("etaMax", {2.5});
0244 algos.add<std::vector<double>>("ptMin", {0.});
0245 algos.add<std::vector<double>>("MinNeutralPt", {0.2});
0246 algos.add<std::vector<double>>("MinNeutralPtSlope", {0.015});
0247 algos.add<std::vector<double>>("RMSEtaSF", {1.0});
0248 algos.add<std::vector<double>>("MedEtaSF", {1.0});
0249 algos.add<double>("EtaMaxExtrap", 2.0);
0250 algosset.addParameter<std::vector<double>>("etaMin", {0.});
0251 algosset.addParameter<std::vector<double>>("etaMax", {2.5});
0252 algosset.addParameter<std::vector<double>>("ptMin", {0.});
0253 algosset.addParameter<std::vector<double>>("MinNeutralPt", {0.2});
0254 algosset.addParameter<std::vector<double>>("MinNeutralPtSlope", {0.015});
0255 algosset.addParameter<std::vector<double>>("RMSEtaSF", {1.0});
0256 algosset.addParameter<std::vector<double>>("MedEtaSF", {1.0});
0257 algosset.addParameter<double>("EtaMaxExtrap", 2.0);
0258 algosset.addParameter<std::vector<edm::ParameterSet>>("puppiAlgos", VPSetPuppiAlgos);
0259 VPSetAlgos.push_back(algosset);
0260 desc.addVPSet("algos", algos, VPSetAlgos);
0261 }