File indexing completed on 2024-04-06 12:13:27
0001 #include "GeneratorInterface/Core/interface/PythiaHepMCFilterGammaGamma.h"
0002 #include "DataFormats/Math/interface/LorentzVector.h"
0003 #include "Math/GenVector/VectorUtil.h"
0004
0005 #include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
0006
0007 #include "TLorentzVector.h"
0008
0009 #include <iostream>
0010
0011 using namespace edm;
0012 using namespace std;
0013 using namespace HepMC;
0014
0015 PythiaHepMCFilterGammaGamma::PythiaHepMCFilterGammaGamma(const edm::ParameterSet& iConfig)
0016 : ptSeedThr(iConfig.getParameter<double>("PtSeedThr")),
0017 etaSeedThr(iConfig.getParameter<double>("EtaSeedThr")),
0018 ptGammaThr(iConfig.getParameter<double>("PtGammaThr")),
0019 etaGammaThr(iConfig.getParameter<double>("EtaGammaThr")),
0020 ptTkThr(iConfig.getParameter<double>("PtTkThr")),
0021 etaTkThr(iConfig.getParameter<double>("EtaTkThr")),
0022 ptElThr(iConfig.getParameter<double>("PtElThr")),
0023 etaElThr(iConfig.getParameter<double>("EtaElThr")),
0024 dRTkMax(iConfig.getParameter<double>("dRTkMax")),
0025 dRSeedMax(iConfig.getParameter<double>("dRSeedMax")),
0026 dPhiSeedMax(iConfig.getParameter<double>("dPhiSeedMax")),
0027 dEtaSeedMax(iConfig.getParameter<double>("dEtaSeedMax")),
0028 dRNarrowCone(iConfig.getParameter<double>("dRNarrowCone")),
0029 pTMinCandidate1(iConfig.getParameter<double>("PtMinCandidate1")),
0030 pTMinCandidate2(iConfig.getParameter<double>("PtMinCandidate2")),
0031 etaMaxCandidate(iConfig.getParameter<double>("EtaMaxCandidate")),
0032 invMassMin(iConfig.getParameter<double>("InvMassMin")),
0033 invMassMax(iConfig.getParameter<double>("InvMassMax")),
0034 energyCut(iConfig.getParameter<double>("EnergyCut")),
0035 nTkConeMax(iConfig.getParameter<int>("NTkConeMax")),
0036 nTkConeSum(iConfig.getParameter<int>("NTkConeSum")),
0037 acceptPrompts(iConfig.getParameter<bool>("AcceptPrompts")),
0038 promptPtThreshold(iConfig.getParameter<double>("PromptPtThreshold")) {}
0039
0040 PythiaHepMCFilterGammaGamma::~PythiaHepMCFilterGammaGamma() {}
0041
0042 bool PythiaHepMCFilterGammaGamma::filter(const HepMC::GenEvent* myGenEvent) {
0043 bool accepted = false;
0044
0045
0046 std::vector<const GenParticle*> seeds;
0047
0048
0049
0050 std::vector<const GenParticle*> egamma;
0051
0052
0053
0054 std::vector<const GenParticle*> stable;
0055
0056
0057
0058
0059 for (HepMC::GenEvent::particle_const_iterator p = myGenEvent->particles_begin(); p != myGenEvent->particles_end();
0060 ++p) {
0061 if (((*p)->status() == 1 && (*p)->pdg_id() == 22) ||
0062 ((*p)->status() == 1 && abs((*p)->pdg_id()) == 11))
0063
0064 {
0065
0066 if ((*p)->momentum().perp() > ptSeedThr && fabs((*p)->momentum().eta()) < etaSeedThr) {
0067 seeds.push_back(*p);
0068 }
0069 }
0070
0071 if ((*p)->status() == 1) {
0072
0073 if (abs((*p)->pdg_id()) == 211 ||
0074 abs((*p)->pdg_id()) == 321 ||
0075 abs((*p)->pdg_id()) == 11 ||
0076 abs((*p)->pdg_id()) == 13 ||
0077 abs((*p)->pdg_id()) == 15) {
0078
0079 if ((*p)->momentum().perp() > ptTkThr && fabs((*p)->momentum().eta()) < etaTkThr) {
0080 stable.push_back(*p);
0081 }
0082 }
0083
0084
0085 if ((*p)->pdg_id() == 22 && (*p)->momentum().perp() > ptGammaThr && fabs((*p)->momentum().eta()) < etaGammaThr) {
0086 egamma.push_back(*p);
0087 }
0088 if (abs((*p)->pdg_id()) == 11 && (*p)->momentum().perp() > ptElThr && fabs((*p)->momentum().eta()) < etaElThr) {
0089 egamma.push_back(*p);
0090 }
0091 }
0092 }
0093
0094 if (seeds.size() < 2)
0095 return accepted;
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106 std::vector<int> nTracks;
0107
0108
0109
0110 std::vector<TLorentzVector> candidate;
0111
0112
0113 std::vector<TLorentzVector> candidateNarrow, candidateSeed;
0114
0115 std::vector<const GenParticle*>::iterator itSeed;
0116
0117 const GenParticle* mom;
0118 int this_id;
0119 int first_different_id;
0120
0121 for (itSeed = seeds.begin(); itSeed != seeds.end(); ++itSeed) {
0122 TLorentzVector energy, narrowCone, temp1, temp2, tempseed;
0123
0124 tempseed.SetXYZM((*itSeed)->momentum().px(), (*itSeed)->momentum().py(), (*itSeed)->momentum().pz(), 0);
0125 for (auto itEn = egamma.begin(); itEn != egamma.end(); ++itEn) {
0126 temp1.SetXYZM((*itEn)->momentum().px(), (*itEn)->momentum().py(), (*itEn)->momentum().pz(), 0);
0127
0128 double DR = temp1.DeltaR(tempseed);
0129 double DPhi = temp1.DeltaPhi(tempseed);
0130 double DEta = (*itEn)->momentum().eta() - (*itSeed)->momentum().eta();
0131 if (DPhi < 0)
0132 DPhi = -DPhi;
0133 if (DEta < 0)
0134 DEta = -DEta;
0135
0136
0137 if (DR < dRSeedMax || (DPhi < dPhiSeedMax && DEta < dEtaSeedMax)) {
0138 energy += temp1;
0139 }
0140 if (DR < dRNarrowCone) {
0141 narrowCone += temp1;
0142 }
0143 }
0144
0145
0146
0147 int counter = 0;
0148
0149 if (energy.Et() != 0.) {
0150 if (fabs(energy.Eta()) < etaMaxCandidate) {
0151 temp2.SetXYZM(energy.Px(), energy.Py(), energy.Pz(), 0);
0152
0153
0154 for (auto itStable = stable.begin(); itStable != stable.end(); ++itStable) {
0155 temp1.SetXYZM((*itStable)->momentum().px(), (*itStable)->momentum().py(), (*itStable)->momentum().pz(), 0);
0156 double DR = temp1.DeltaR(temp2);
0157 if (DR < dRTkMax)
0158 counter++;
0159 }
0160
0161 if (acceptPrompts) {
0162 if ((*itSeed)->momentum().perp() > promptPtThreshold) {
0163
0164
0165 bool isPrompt = true;
0166 this_id = (*itSeed)->pdg_id();
0167 mom = (*itSeed);
0168 while (mom->pdg_id() == this_id) {
0169 const GenParticle* mother =
0170 mom->production_vertex() ? *(mom->production_vertex()->particles_in_const_begin()) : nullptr;
0171
0172 mom = mother;
0173 if (mom == nullptr) {
0174 break;
0175 }
0176 }
0177
0178 first_different_id = mom->pdg_id();
0179
0180 if (mom->status() == 2 && std::abs(first_different_id) > 100)
0181 isPrompt = false;
0182
0183
0184 if (isPrompt)
0185 counter = 0;
0186 }
0187 }
0188 }
0189 }
0190
0191 candidate.push_back(energy);
0192 candidateSeed.push_back(tempseed);
0193 candidateNarrow.push_back(narrowCone);
0194 nTracks.push_back(counter);
0195 }
0196
0197 if (candidate.size() < 2)
0198 return accepted;
0199
0200 TLorentzVector minvMin, minvMax;
0201
0202
0203
0204
0205
0206
0207
0208 int i1, i2;
0209 for (unsigned int i = 0; i < candidate.size() - 1; ++i) {
0210 if (candidate[i].Energy() < energyCut)
0211 continue;
0212 if (nTracks[i] > nTkConeMax)
0213 continue;
0214 if (fabs(candidate[i].Eta()) > etaMaxCandidate)
0215 continue;
0216
0217 for (unsigned int j = i + 1; j < candidate.size(); ++j) {
0218
0219 if (candidate[j].Energy() < energyCut)
0220 continue;
0221 if (nTracks[j] > nTkConeMax)
0222 continue;
0223 if (fabs(candidate[j].Eta()) > etaMaxCandidate)
0224 continue;
0225
0226
0227 if (nTracks[i] + nTracks[j] > nTkConeSum)
0228 continue;
0229
0230
0231 if (candidate[i].Pt() > candidate[j].Pt()) {
0232 i1 = i;
0233 i2 = j;
0234 } else {
0235 i1 = j;
0236 i2 = i;
0237 }
0238
0239
0240 if (candidate[i1].Pt() < pTMinCandidate1 || candidate[i2].Pt() < pTMinCandidate2)
0241 continue;
0242
0243
0244 minvMin = candidate[i] + candidate[j];
0245 if (minvMin.M() < invMassMin)
0246 continue;
0247
0248 minvMax = candidate[i] + candidate[j];
0249 if (minvMax.M() > invMassMax)
0250 continue;
0251
0252 accepted = true;
0253 }
0254 }
0255
0256 return accepted;
0257 }