[07b7064] | 1 | #include "PuppiAlgo.hh"
|
---|
| 2 | #include "Math/QuantFuncMathCore.h"
|
---|
| 3 | #include "Math/SpecFuncMathCore.h"
|
---|
| 4 | #include "Math/ProbFunc.h"
|
---|
| 5 | #include "TMath.h"
|
---|
| 6 |
|
---|
| 7 | PuppiAlgo::PuppiAlgo(AlgoObj &iAlgo) {
|
---|
| 8 | fEtaMin = iAlgo.etaMin;
|
---|
| 9 | fEtaMax = iAlgo.etaMax;
|
---|
| 10 | fPtMin = iAlgo.ptMin;
|
---|
| 11 | fNeutralPtMin = iAlgo.minNeutralPt;
|
---|
| 12 | fNeutralPtSlope = iAlgo.minNeutralPtSlope;
|
---|
| 13 | fRMSEtaSF = iAlgo.rmsEtaSF;
|
---|
| 14 | fMedEtaSF = iAlgo.medEtaSF;
|
---|
| 15 | fEtaMaxExtrap = iAlgo.etaMaxExtrap;
|
---|
| 16 | std::vector<AlgoSubObj> lAlgos = iAlgo.subAlgos;
|
---|
| 17 | fNAlgos = lAlgos.size();
|
---|
[239e1d0] | 18 | //std::cout << "==> " << fEtaMin << " - " << fEtaMax << " - " << fPtMin << " - " << fNeutralPtMin << " - " << fNeutralPtSlope << " - " << fRMSEtaSF << " - " << std::endl;
|
---|
[07b7064] | 19 | for(unsigned int i0 = 0; i0 < lAlgos.size(); i0++) {
|
---|
| 20 | int pAlgoId = lAlgos[i0].metricId;
|
---|
| 21 | bool pCharged = lAlgos[i0].useCharged;
|
---|
| 22 | bool pWeight0 = lAlgos[i0].applyLowPUCorr;
|
---|
| 23 | int pComb = lAlgos[i0].combId;
|
---|
| 24 | double pConeSize = lAlgos[i0].coneSize;
|
---|
| 25 | double pRMSPtMin = lAlgos[i0].rmsPtMin;
|
---|
| 26 | double pRMSSF = lAlgos[i0].rmsScaleFactor;
|
---|
[239e1d0] | 27 | //std::cout << "Algo==> " << i0 << " - " << pAlgoId << " - " << pCharged << " - " << pWeight0 << " - " << pComb << " - " << pConeSize << " - " << pRMSPtMin << " - " << std::endl;
|
---|
[07b7064] | 28 | fAlgoId .push_back(pAlgoId);
|
---|
| 29 | fCharged .push_back(pCharged);
|
---|
| 30 | fAdjust .push_back(pWeight0);
|
---|
| 31 | fCombId .push_back(pComb);
|
---|
| 32 | fConeSize .push_back(pConeSize);
|
---|
| 33 | fRMSPtMin .push_back(pRMSPtMin);
|
---|
| 34 | fRMSScaleFactor.push_back(pRMSSF);
|
---|
| 35 | double pRMS = 0;
|
---|
| 36 | double pMed = 0;
|
---|
| 37 | double pMean = 0;
|
---|
| 38 | int pNCount = 0;
|
---|
| 39 | fRMS .push_back(pRMS);
|
---|
| 40 | fMedian.push_back(pMed);
|
---|
| 41 | fMean .push_back(pMean);
|
---|
| 42 | fNCount.push_back(pNCount);
|
---|
| 43 | /*
|
---|
| 44 | tmprms .clear();
|
---|
| 45 | tmpmed .clear();
|
---|
| 46 | for (unsigned int j0 = 0; j0 < fEtaMin.size(); j0++){
|
---|
| 47 | tmprms.push_back(pRMS);
|
---|
| 48 | tmpmed.push_back(pMed);
|
---|
| 49 | }
|
---|
| 50 | fRMS_perEta.push_back(tmprms);
|
---|
| 51 | fMedian_perEta.push_back(tmpmed);
|
---|
| 52 | */
|
---|
| 53 | }
|
---|
| 54 | }
|
---|
| 55 | PuppiAlgo::~PuppiAlgo() {
|
---|
| 56 | fPups .clear();
|
---|
| 57 | fPupsPV.clear();
|
---|
| 58 | }
|
---|
| 59 | void PuppiAlgo::reset() {
|
---|
| 60 | fPups .clear();
|
---|
| 61 | fPupsPV.clear();
|
---|
| 62 | for(unsigned int i0 = 0; i0 < fNAlgos; i0++) {
|
---|
| 63 | fMedian[i0] = 0;
|
---|
| 64 | fRMS [i0] = 0;
|
---|
| 65 | fMean [i0] = 0;
|
---|
| 66 | fNCount[i0] = 0;
|
---|
| 67 | }
|
---|
| 68 | }
|
---|
| 69 | void PuppiAlgo::add(const fastjet::PseudoJet &iParticle,const double &iVal,const unsigned int iAlgo) {
|
---|
| 70 | if(iParticle.pt() < fRMSPtMin[iAlgo]) return;
|
---|
| 71 | if(fCharged[iAlgo] && fabs(iParticle.user_index()) < 1) return;
|
---|
| 72 | if(fCharged[iAlgo] && (fabs(iParticle.user_index()) >=1 && fabs(iParticle.user_index()) <=2)) fPupsPV.push_back(iVal);
|
---|
| 73 | if(fCharged[iAlgo] && fabs(iParticle.user_index()) < 3) return;
|
---|
| 74 | fPups.push_back(iVal);
|
---|
| 75 | fNCount[iAlgo]++;
|
---|
| 76 | /* eta extrap (cmssw version)
|
---|
| 77 | if ((std::abs(iParticle.eta()) < fEtaMaxExtrap) && (std::abs(puppi_register) >= 3)){
|
---|
| 78 | fPups.push_back(iVal);
|
---|
| 79 | // fPupsPV.push_back(iVal);
|
---|
| 80 | fNCount[iAlgo]++;
|
---|
| 81 | }
|
---|
| 82 | // for the low PU case, correction. for checking that the PU-only median will be below the PV particles
|
---|
| 83 | if(std::abs(iParticle.eta()) < fEtaMaxExtrap && (std::abs(puppi_register) >=1 && std::abs(puppi_register) <=2)) fPupsPV.push_back(iVal);
|
---|
| 84 | */
|
---|
| 85 | }
|
---|
| 86 | void PuppiAlgo::computeMedRMS(const unsigned int &iAlgo,const double &iPVFrac) {
|
---|
| 87 | if(iAlgo >= fNAlgos ) return;
|
---|
| 88 | if(fNCount[iAlgo] == 0) return;
|
---|
| 89 | int lNBefore = 0;
|
---|
| 90 | for(unsigned int i0 = 0; i0 < iAlgo; i0++) lNBefore += fNCount[i0];
|
---|
| 91 | std::sort(fPups.begin()+lNBefore,fPups.begin()+lNBefore+fNCount[iAlgo]);
|
---|
| 92 | int lNum0 = 0;
|
---|
| 93 | for(int i0 = lNBefore; i0 < lNBefore+fNCount[iAlgo]; i0++) {
|
---|
| 94 | if(fPups[i0] == 0) lNum0 = i0-lNBefore;
|
---|
| 95 | }
|
---|
| 96 | //lNum0 = 0;
|
---|
| 97 | int lNHalfway = lNBefore + lNum0 + int( double( fNCount[iAlgo]-lNum0 )*0.50);
|
---|
| 98 | fMedian[iAlgo] = fPups[lNHalfway];
|
---|
| 99 | double lMed = fMedian[iAlgo]; //Just to make the readability easier
|
---|
| 100 |
|
---|
| 101 | int lNRMS = 0;
|
---|
| 102 | for(int i0 = lNBefore; i0 < lNBefore+fNCount[iAlgo]; i0++) {
|
---|
| 103 | fMean[iAlgo] += fPups[i0];
|
---|
| 104 | if(fPups[i0] == 0) continue;
|
---|
| 105 | if(fAdjust[iAlgo] && fPups[i0] > lMed) continue;
|
---|
| 106 | lNRMS++;
|
---|
| 107 | fRMS [iAlgo] += (fPups[i0]-lMed)*(fPups[i0]-lMed);
|
---|
| 108 | }
|
---|
| 109 | fMean[iAlgo]/=fNCount[iAlgo];
|
---|
| 110 | if(lNRMS > 0) fRMS [iAlgo]/=lNRMS;
|
---|
| 111 | if(fRMS[iAlgo] == 0) fRMS[iAlgo] = 1e-5;
|
---|
| 112 |
|
---|
| 113 | fRMS [iAlgo] = sqrt(fRMS[iAlgo]);
|
---|
| 114 | fRMS [iAlgo] *= fRMSScaleFactor[iAlgo];
|
---|
| 115 | if(fAdjust[iAlgo]){
|
---|
| 116 | //Adjust the p-value to correspond to the median
|
---|
| 117 | std::sort(fPupsPV.begin(),fPupsPV.end());
|
---|
| 118 | int lNPV = 0;
|
---|
| 119 | for(unsigned int i0 = 0; i0 < fPupsPV.size(); i0++) if(fPupsPV[i0] <= lMed ) lNPV++;
|
---|
| 120 | double lAdjust = double(lNPV)/double(lNPV+0.5*fNCount[iAlgo]);
|
---|
| 121 | if(lAdjust > 0) {
|
---|
| 122 | fMedian[iAlgo] -= sqrt(ROOT::Math::chisquared_quantile(lAdjust,1.)*fRMS[iAlgo]);
|
---|
| 123 | fRMS[iAlgo] -= sqrt(ROOT::Math::chisquared_quantile(lAdjust,1.)*fRMS[iAlgo]);
|
---|
| 124 | }
|
---|
| 125 | }
|
---|
| 126 | /* eta extrapolated version
|
---|
| 127 | for (unsigned int j0 = 0; j0 < fEtaMin.size(); j0++){
|
---|
| 128 | fRMS_perEta[iAlgo][j0] = fRMS[iAlgo]*fRMSEtaSF[j0];
|
---|
| 129 | fMedian_perEta[iAlgo][j0] = fMedian[iAlgo]*fMedEtaSF[j0];
|
---|
| 130 | }
|
---|
| 131 | */
|
---|
| 132 | }
|
---|
| 133 | //This code is probably a bit confusing
|
---|
| 134 | double PuppiAlgo::compute(std::vector<double> &iVals,double iChi2) {
|
---|
| 135 | if(fAlgoId[0] == -1) return 1;
|
---|
| 136 | double lVal = 0.;
|
---|
| 137 | double lPVal = 1.;
|
---|
| 138 | int lNDOF = 0;
|
---|
| 139 | for(unsigned int i0 = 0; i0 < fNAlgos; i0++) {
|
---|
| 140 | if(fNCount[i0] == 0) return 1.; //in the NoPU case return 1.
|
---|
| 141 | if(fCombId[i0] == 1 && i0 > 0) { //Compute the previous p-value so that p-values can be multiplieed
|
---|
| 142 | double pPVal = ROOT::Math::chisquared_cdf(lVal,lNDOF);
|
---|
| 143 | lPVal *= pPVal;
|
---|
| 144 | lNDOF = 0;
|
---|
| 145 | lVal = 0;
|
---|
| 146 | }
|
---|
| 147 | double pVal = iVals[i0];
|
---|
| 148 | //Special Check for any algo with log(0)
|
---|
| 149 | if(fAlgoId[i0] == 0 && iVals[i0] == 0) pVal = fMedian[i0];
|
---|
| 150 | if(fAlgoId[i0] == 3 && iVals[i0] == 0) pVal = fMedian[i0];
|
---|
| 151 | if(fAlgoId[i0] == 5 && iVals[i0] == 0) pVal = fMedian[i0];
|
---|
| 152 | lVal += (pVal-fMedian[i0])*(fabs(pVal-fMedian[i0]))/fRMS[i0]/fRMS[i0];
|
---|
| 153 | lNDOF++;
|
---|
| 154 | if(i0 == 0 && iChi2 != 0) lNDOF++; //Add external Chi2 to first element
|
---|
| 155 | if(i0 == 0 && iChi2 != 0) lVal+=iChi2; //Add external Chi2 to first element
|
---|
| 156 | }
|
---|
| 157 | //Top it off with the last calc
|
---|
| 158 | lPVal *= ROOT::Math::chisquared_cdf(lVal,lNDOF);
|
---|
| 159 | return lPVal;
|
---|
| 160 | }
|
---|
| 161 | double PuppiAlgo::neutralPt(int iNPV) {
|
---|
| 162 | return fNeutralPtMin + iNPV * fNeutralPtSlope;
|
---|
| 163 | }
|
---|
| 164 | int PuppiAlgo::numAlgos() {
|
---|
| 165 | return fNAlgos;
|
---|
| 166 | }
|
---|
| 167 | double PuppiAlgo::ptMin() {
|
---|
| 168 | return fPtMin;
|
---|
| 169 | }
|
---|
| 170 | double PuppiAlgo::etaMin() {
|
---|
| 171 | return fEtaMin;
|
---|
| 172 | }
|
---|
| 173 | double PuppiAlgo::etaMax() {
|
---|
| 174 | return fEtaMax;
|
---|
| 175 | }
|
---|
| 176 | int PuppiAlgo::algoId(const unsigned int &iAlgo) {
|
---|
| 177 | assert(iAlgo < fNAlgos);
|
---|
| 178 | return fAlgoId[iAlgo];
|
---|
| 179 | }
|
---|
| 180 | bool PuppiAlgo::isCharged(const unsigned int &iAlgo) {
|
---|
| 181 | assert(iAlgo < fNAlgos);
|
---|
| 182 | return fCharged[iAlgo];
|
---|
| 183 | }
|
---|
| 184 | double PuppiAlgo::coneSize(const unsigned int &iAlgo) {
|
---|
| 185 | assert(iAlgo < fNAlgos);
|
---|
| 186 | return fConeSize[iAlgo];
|
---|
| 187 | }
|
---|