From 6364630e9d3ffe97f3fe14de3bdaa5855d9c85bc Mon Sep 17 00:00:00 2001 From: daniel <[Email> Date: Sat, 24 Aug 2019 21:20:04 +0200 Subject: [PATCH 1/2] rebasing gen filter to CMSSW_7_1_X --- .../Core/interface/EmbeddingHepMCFilter.h | 80 ++++++ .../Core/src/EmbeddingHepMCFilter.cc | 236 ++++++++++++++++++ .../Core/src/HepMCFilterDriver.cc | 6 +- .../python/EmbeddingPythia8Hadronizer_cfi.py | 45 ++++ 4 files changed, 364 insertions(+), 3 deletions(-) create mode 100644 GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h create mode 100644 GeneratorInterface/Core/src/EmbeddingHepMCFilter.cc create mode 100644 TauAnalysis/MCEmbeddingTools/python/EmbeddingPythia8Hadronizer_cfi.py diff --git a/GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h b/GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h new file mode 100644 index 0000000000000..2ce970a6e1ea1 --- /dev/null +++ b/GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h @@ -0,0 +1,80 @@ +#ifndef __EMBEDDINGHEPMCFILTER__ +#define __EMBEDDINGHEPMCFILTER__ + +#include "FWCore/MessageLogger/interface/MessageLogger.h" + +#include "GeneratorInterface/Core/interface/BaseHepMCFilter.h" +#include "DataFormats/Candidate/interface/Candidate.h" + +class EmbeddingHepMCFilter : public BaseHepMCFilter { +private: + const int tauon_neutrino_PDGID_ = 16; + const int tauonPDGID_ = 15; + const int muon_neutrino_PDGID_ = 14; + const int muonPDGID_ = 13; + const int electron_neutrino_PDGID_ = 12; + const int electronPDGID_ = 11; + int ZPDGID_ = 23; + + enum class TauDecayMode : int { Unfilled = -1, Muon = 0, Electron = 1, Hadronic = 2 }; + + std::string return_mode(TauDecayMode mode) { + if (mode == TauDecayMode::Muon) + return "Mu"; + else if (mode == TauDecayMode::Electron) + return "El"; + else if (mode == TauDecayMode::Hadronic) + return "Had"; + else + return "Undefined"; + } + + struct DecayChannel { + TauDecayMode first = TauDecayMode::Unfilled; + TauDecayMode second = TauDecayMode::Unfilled; + + void fill(TauDecayMode mode) { + if (first == TauDecayMode::Unfilled) + first = mode; + else if (second == TauDecayMode::Unfilled) + second = mode; + }; + void reset() { + first = TauDecayMode::Unfilled; + second = TauDecayMode::Unfilled; + } + void reverse() { + TauDecayMode tmp = first; + first = second; + second = tmp; + } + }; + + DecayChannel ee, mm, hh, em, eh, mh; + + struct CutsContainer { + double pt1 = -1.; + double pt2 = -1.; + double eta1 = -1.; // since we use abs eta values the -1 as default is OK + double eta2 = -1.; + DecayChannel decaychannel; + }; + + std::vector cuts_; + DecayChannel DecayChannel_; + + virtual void fill_cut(std::string cut_string, EmbeddingHepMCFilter::DecayChannel &dc, CutsContainer &cut); + virtual void fill_cuts(std::string cut_string, EmbeddingHepMCFilter::DecayChannel &dc); + + virtual void decay_and_sump4Vis(HepMC::GenParticle *particle, reco::Candidate::LorentzVector &p4Vis); + virtual void sort_by_convention(std::vector &p4VisPair); + virtual bool apply_cuts(std::vector &p4VisPair); + +public: + explicit EmbeddingHepMCFilter(const edm::ParameterSet &); + ~EmbeddingHepMCFilter() override; + + bool filter(const HepMC::GenEvent *evt) override; +}; + +#endif diff --git a/GeneratorInterface/Core/src/EmbeddingHepMCFilter.cc b/GeneratorInterface/Core/src/EmbeddingHepMCFilter.cc new file mode 100644 index 0000000000000..499ae555ac108 --- /dev/null +++ b/GeneratorInterface/Core/src/EmbeddingHepMCFilter.cc @@ -0,0 +1,236 @@ +#include "GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h" + +#include "boost/algorithm/string.hpp" +#include "boost/algorithm/string/trim_all.hpp" + +EmbeddingHepMCFilter::EmbeddingHepMCFilter(const edm::ParameterSet &iConfig) + : ZPDGID_(iConfig.getParameter("BosonPDGID")) { + // Defining standard decay channels + ee.fill(TauDecayMode::Electron); + ee.fill(TauDecayMode::Electron); + mm.fill(TauDecayMode::Muon); + mm.fill(TauDecayMode::Muon); + hh.fill(TauDecayMode::Hadronic); + hh.fill(TauDecayMode::Hadronic); + em.fill(TauDecayMode::Electron); + em.fill(TauDecayMode::Muon); + eh.fill(TauDecayMode::Electron); + eh.fill(TauDecayMode::Hadronic); + mh.fill(TauDecayMode::Muon); + mh.fill(TauDecayMode::Hadronic); + + // Filling CutContainers + + std::string cut_string_elel = iConfig.getParameter("ElElCut"); + std::string cut_string_mumu = iConfig.getParameter("MuMuCut"); + std::string cut_string_hadhad = iConfig.getParameter("HadHadCut"); + std::string cut_string_elmu = iConfig.getParameter("ElMuCut"); + std::string cut_string_elhad = iConfig.getParameter("ElHadCut"); + std::string cut_string_muhad = iConfig.getParameter("MuHadCut"); + + std::vector use_final_states = iConfig.getParameter >("Final_States"); + + for (std::vector::const_iterator final_state = use_final_states.begin(); + final_state != use_final_states.end(); + ++final_state) { + if ((*final_state) == "ElEl") + fill_cuts(cut_string_elel, ee); + else if ((*final_state) == "MuMu") + fill_cuts(cut_string_mumu, mm); + else if ((*final_state) == "HadHad") + fill_cuts(cut_string_hadhad, hh); + else if ((*final_state) == "ElMu") + fill_cuts(cut_string_elmu, em); + else if ((*final_state) == "ElHad") + fill_cuts(cut_string_elhad, eh); + else if ((*final_state) == "MuHad") + fill_cuts(cut_string_muhad, mh); + else + edm::LogWarning("EmbeddingHepMCFilter") + << (*final_state) + << " this decay channel is not supported. Please choose on of (ElEl,MuMu,HadHad,ElMu,ElHad,MuHad)"; + } +} + +EmbeddingHepMCFilter::~EmbeddingHepMCFilter() {} + +bool EmbeddingHepMCFilter::filter(const HepMC::GenEvent *evt) { + //Reset DecayChannel_ and p4VisPair_ at the beginning of each event. + DecayChannel_.reset(); + std::vector p4VisPair_; + + // Going through the particle list. Mother particles are allways before their children. + // One can stop the loop after the second tau is reached and processed. + for (HepMC::GenEvent::particle_const_iterator particle = evt->particles_begin(); particle != evt->particles_end(); + ++particle) { + int mom_id = 0; // No particle available with PDG ID 0 + if ((*particle)->production_vertex() != nullptr) { // search for the mom via the production_vertex + if ((*particle)->production_vertex()->particles_in_const_begin() != + (*particle)->production_vertex()->particles_in_const_end()) { + mom_id = (*(*particle)->production_vertex()->particles_in_const_begin())->pdg_id(); // mom was found + } + } + + if (std::abs((*particle)->pdg_id()) == tauonPDGID_ && mom_id == ZPDGID_) { + reco::Candidate::LorentzVector p4Vis; + decay_and_sump4Vis((*particle), p4Vis); // recursive access to final states. + p4VisPair_.push_back(p4Vis); + } else if (std::abs((*particle)->pdg_id()) == muonPDGID_ && + mom_id == ZPDGID_) { // Also handle the option when Z-> mumu + reco::Candidate::LorentzVector p4Vis = (reco::Candidate::LorentzVector)(*particle)->momentum(); + DecayChannel_.fill(TauDecayMode::Muon); // take the muon cuts + p4VisPair_.push_back(p4Vis); + } else if (std::abs((*particle)->pdg_id()) == electronPDGID_ && + mom_id == ZPDGID_) { // Also handle the option when Z-> ee + reco::Candidate::LorentzVector p4Vis = (reco::Candidate::LorentzVector)(*particle)->momentum(); + DecayChannel_.fill(TauDecayMode::Electron); // take the electron cuts + p4VisPair_.push_back(p4Vis); + } + } + // Putting DecayChannel_ in default convention: + // For mixed decay channels use the Electron_Muon, Electron_Hadronic, Muon_Hadronic convention. + // For symmetric decay channels (e.g. Muon_Muon) use Leading_Trailing convention with respect to Pt. + if (p4VisPair_.size() == 2) { + sort_by_convention(p4VisPair_); + edm::LogInfo("EmbeddingHepMCFilter") << "Quantities of the visible decay products:" + << "\tPt's: " + << " 1st " << p4VisPair_[0].Pt() << ", 2nd " << p4VisPair_[1].Pt() + << "\tEta's: " + << " 1st " << p4VisPair_[0].Eta() << ", 2nd " << p4VisPair_[1].Eta() + << " decay channel: " << return_mode(DecayChannel_.first) + << return_mode(DecayChannel_.second); + } else { + edm::LogError("EmbeddingHepMCFilter") << "Size less non equal two"; + } + + return apply_cuts(p4VisPair_); +} + +void EmbeddingHepMCFilter::decay_and_sump4Vis(HepMC::GenParticle *particle, reco::Candidate::LorentzVector &p4Vis) { + bool decaymode_known = false; + for (HepMC::GenVertex::particle_iterator daughter = particle->end_vertex()->particles_begin(HepMC::children); + daughter != particle->end_vertex()->particles_end(HepMC::children); + ++daughter) { + bool neutrino = (std::abs((*daughter)->pdg_id()) == tauon_neutrino_PDGID_) || + (std::abs((*daughter)->pdg_id()) == muon_neutrino_PDGID_) || + (std::abs((*daughter)->pdg_id()) == electron_neutrino_PDGID_); + + // Determining DecayMode, if particle is tau lepton. + // Asuming, that there are only the two tauons from the Z-boson. + // This is the case for the simulated Z->tautau event constructed by EmbeddingLHEProducer. + if (std::abs(particle->pdg_id()) == tauonPDGID_ && !decaymode_known) { + // use these bools to protect againt taus that aren't the last copy (which "decay" to a tau and a gamma) + bool isGamma = std::abs((*daughter)->pdg_id()) == 22; + bool isTau = std::abs((*daughter)->pdg_id()) == 15; + if (std::abs((*daughter)->pdg_id()) == muonPDGID_) { + DecayChannel_.fill(TauDecayMode::Muon); + decaymode_known = true; + } else if (std::abs((*daughter)->pdg_id()) == electronPDGID_) { + DecayChannel_.fill(TauDecayMode::Electron); + decaymode_known = true; + } else if (!neutrino && !isGamma && !isTau) { + DecayChannel_.fill(TauDecayMode::Hadronic); + decaymode_known = true; + } + } + // Adding up all visible momentum in recursive way. + if ((*daughter)->status() == 1 && !neutrino) + p4Vis += (reco::Candidate::LorentzVector)(*daughter)->momentum(); + else if (!neutrino) + decay_and_sump4Vis((*daughter), p4Vis); + } +} + +void EmbeddingHepMCFilter::sort_by_convention(std::vector &p4VisPair) { + bool mixed_false_order = + (DecayChannel_.first == TauDecayMode::Hadronic && DecayChannel_.second == TauDecayMode::Muon) || + (DecayChannel_.first == TauDecayMode::Hadronic && DecayChannel_.second == TauDecayMode::Electron) || + (DecayChannel_.first == TauDecayMode::Muon && DecayChannel_.second == TauDecayMode::Electron); + + if (DecayChannel_.first == DecayChannel_.second && p4VisPair[0].Pt() < p4VisPair[1].Pt()) { + edm::LogVerbatim("EmbeddingHepMCFilter") << "Changing symmetric channels to Leading_Trailing convention in Pt"; + edm::LogVerbatim("EmbeddingHepMCFilter") << "Pt's before: " << p4VisPair[0].Pt() << " " << p4VisPair[1].Pt(); + std::reverse(p4VisPair.begin(), p4VisPair.end()); + edm::LogVerbatim("EmbeddingHepMCFilter") << "Pt's after: " << p4VisPair[0].Pt() << " " << p4VisPair[1].Pt(); + } else if (mixed_false_order) { + edm::LogVerbatim("EmbeddingHepMCFilter") << "Swapping order of mixed channels"; + edm::LogVerbatim("EmbeddingHepMCFilter") << "Pt's before: " << p4VisPair[0].Pt() << " " << p4VisPair[1].Pt(); + DecayChannel_.reverse(); + edm::LogVerbatim("EmbeddingHepMCFilter") + << "DecayChannel: " << return_mode(DecayChannel_.first) << return_mode(DecayChannel_.second); + std::reverse(p4VisPair.begin(), p4VisPair.end()); + edm::LogVerbatim("EmbeddingHepMCFilter") << "Pt's after: " << p4VisPair[0].Pt() << " " << p4VisPair[1].Pt(); + } +} + +bool EmbeddingHepMCFilter::apply_cuts(std::vector &p4VisPair) { + for (std::vector::const_iterator cut = cuts_.begin(); cut != cuts_.end(); ++cut) { + if (DecayChannel_.first == cut->decaychannel.first && + DecayChannel_.second == cut->decaychannel.second) { // First the match to the decay channel + edm::LogInfo("EmbeddingHepMCFilter") + << "Cut pt1 = " << cut->pt1 << " pt2 = " << cut->pt2 << " abs(eta1) = " << cut->eta1 + << " abs(eta2) = " << cut->eta2 << " decay channel: " << return_mode(cut->decaychannel.first) + << return_mode(cut->decaychannel.second); + + if ((cut->pt1 == -1. || (p4VisPair[0].Pt() > cut->pt1)) && (cut->pt2 == -1. || (p4VisPair[1].Pt() > cut->pt2)) && + (cut->eta1 == -1. || (std::abs(p4VisPair[0].Eta()) < cut->eta1)) && + (cut->eta2 == -1. || (std::abs(p4VisPair[1].Eta()) < cut->eta2))) { + edm::LogInfo("EmbeddingHepMCFilter") << "This cut was passed (Stop here and take the event)"; + return true; + } + } + } + return false; +} + +void EmbeddingHepMCFilter::fill_cuts(std::string cut_string, EmbeddingHepMCFilter::DecayChannel &dc) { + edm::LogInfo("EmbeddingHepMCFilter") << return_mode(dc.first) << return_mode(dc.second) << "Cut : " << cut_string; + boost::trim_fill(cut_string, ""); + std::vector cut_paths; + boost::split(cut_paths, cut_string, boost::is_any_of("||"), boost::token_compress_on); + for (unsigned int i = 0; i < cut_paths.size(); ++i) { + // Translating the cuts of a path into a struct which is later accessed to apply them on a event. + CutsContainer cut; + fill_cut(cut_paths[i], dc, cut); + cuts_.push_back(cut); + } +} + +void EmbeddingHepMCFilter::fill_cut(std::string cut_string, + EmbeddingHepMCFilter::DecayChannel &dc, + CutsContainer &cut) { + cut.decaychannel = dc; + + boost::replace_all(cut_string, "(", ""); + boost::replace_all(cut_string, ")", ""); + std::vector single_cuts; + boost::split(single_cuts, cut_string, boost::is_any_of("&&"), boost::token_compress_on); + for (unsigned int i = 0; i < single_cuts.size(); ++i) { + std::string pt1_str, pt2_str, eta1_str, eta2_str; + if (dc.first == dc.second) { + pt1_str = return_mode(dc.first) + "1" + ".Pt" + ">"; + pt2_str = return_mode(dc.second) + "2" + ".Pt" + ">"; + eta1_str = return_mode(dc.first) + "1" + ".Eta" + "<"; + eta2_str = return_mode(dc.second) + "2" + ".Eta" + "<"; + } else { + pt1_str = return_mode(dc.first) + ".Pt" + ">"; + pt2_str = return_mode(dc.second) + ".Pt" + ">"; + eta1_str = return_mode(dc.first) + ".Eta" + "<"; + eta2_str = return_mode(dc.second) + ".Eta" + "<"; + } + + if (boost::find_first(single_cuts[i], pt1_str)) { + boost::erase_first(single_cuts[i], pt1_str); + cut.pt1 = std::stod(single_cuts[i]); + } else if (boost::find_first(single_cuts[i], pt2_str)) { + boost::erase_first(single_cuts[i], pt2_str); + cut.pt2 = std::stod(single_cuts[i]); + } else if (boost::find_first(single_cuts[i], eta1_str)) { + boost::erase_first(single_cuts[i], eta1_str); + cut.eta1 = std::stod(single_cuts[i]); + } else if (boost::find_first(single_cuts[i], eta2_str)) { + boost::erase_first(single_cuts[i], eta2_str); + cut.eta2 = std::stod(single_cuts[i]); + } + } +} diff --git a/GeneratorInterface/Core/src/HepMCFilterDriver.cc b/GeneratorInterface/Core/src/HepMCFilterDriver.cc index f58460665e89f..d576e3517a830 100644 --- a/GeneratorInterface/Core/src/HepMCFilterDriver.cc +++ b/GeneratorInterface/Core/src/HepMCFilterDriver.cc @@ -1,7 +1,7 @@ #include "GeneratorInterface/Core/interface/HepMCFilterDriver.h" #include "GeneratorInterface/Core/interface/GenericDauHepMCFilter.h" #include "GeneratorInterface/Core/interface/PartonShowerBsHepMCFilter.h" -#include "GeneratorInterface/Core/interface/PartonShowerCsHepMCFilter.h" +#include "GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -26,8 +26,8 @@ HepMCFilterDriver::HepMCFilterDriver(const edm::ParameterSet& pset) : else if (filterName=="PartonShowerBsHepMCFilter") { filter_ = new PartonShowerBsHepMCFilter(filterParameters); } - else if (filterName=="PartonShowerCsHepMCFilter") { - filter_ = new PartonShowerCsHepMCFilter(filterParameters); + else if (filterName == "EmbeddingHepMCFilter") { + filter_ = new EmbeddingHepMCFilter(filterParameters); } else { edm::LogError("HepMCFilterDriver")<< "Invalid HepMCFilter name:" << filterName; diff --git a/TauAnalysis/MCEmbeddingTools/python/EmbeddingPythia8Hadronizer_cfi.py b/TauAnalysis/MCEmbeddingTools/python/EmbeddingPythia8Hadronizer_cfi.py new file mode 100644 index 0000000000000..5c056288c8203 --- /dev/null +++ b/TauAnalysis/MCEmbeddingTools/python/EmbeddingPythia8Hadronizer_cfi.py @@ -0,0 +1,45 @@ +import FWCore.ParameterSet.Config as cms +from Configuration.Generator.Pythia8CommonSettings_cfi import * +from Configuration.Generator.Pythia8CUEP8M1Settings_cfi import * +from GeneratorInterface.ExternalDecays.TauolaSettings_cff import * + + + +generator = cms.EDFilter("Pythia8HadronizerFilter", + + maxEventsToPrint = cms.untracked.int32(1), + nAttempts = cms.uint32(1000), + HepMCFilter = cms.PSet( + filterName = cms.string('EmbeddingHepMCFilter'), + filterParameters = cms.PSet( + ElElCut = cms.string('El1.Pt > 22 && El2.Pt > 10'), + ElHadCut = cms.string('El.Pt > 28 && Had.Pt > 25'), + ElMuCut = cms.string('(El.Pt > 21 && Mu.Pt > 10) || (El.Pt > 10 && Mu.Pt > 21)'), + HadHadCut = cms.string('Had1.Pt > 35 && Had2.Pt > 30'), + MuHadCut = cms.string('Mu.Pt > 18 && Had.Pt > 25 && Mu.Eta < 2.1'), + MuMuCut = cms.string('Mu1.Pt > 17 && Mu2.Pt > 8'), + Final_States = cms.vstring('ElEl','ElHad','ElMu','HadHad','MuHad','MuMu'), + BosonPDGID = cms.int32(23) + ), + ), + pythiaPylistVerbosity = cms.untracked.int32(0), + filterEfficiency = cms.untracked.double(1.0), + pythiaHepMCVerbosity = cms.untracked.bool(False), + comEnergy = cms.double(13000.), + crossSection = cms.untracked.double(1.0), + PythiaParameters = cms.PSet( + pythia8CommonSettingsBlock, + pythia8CUEP8M1SettingsBlock, + processParameters = cms.vstring( + + 'JetMatching:merge = off', + 'Init:showChangedSettings = off', + 'Init:showChangedParticleData = off' + ), + parameterSets = cms.vstring('pythia8CommonSettings', + 'pythia8CUEP8M1Settings', + 'processParameters' + ) + ) +) + From de45778d2cce27b1f809f04d80f950409d211923 Mon Sep 17 00:00:00 2001 From: daniel <[Email> Date: Sat, 24 Aug 2019 21:30:42 +0200 Subject: [PATCH 2/2] updating HepMCFilterDriver to latest version on CMSSW_7_1_X branch --- GeneratorInterface/Core/src/HepMCFilterDriver.cc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/GeneratorInterface/Core/src/HepMCFilterDriver.cc b/GeneratorInterface/Core/src/HepMCFilterDriver.cc index d576e3517a830..e4ac57145cd40 100644 --- a/GeneratorInterface/Core/src/HepMCFilterDriver.cc +++ b/GeneratorInterface/Core/src/HepMCFilterDriver.cc @@ -1,6 +1,7 @@ #include "GeneratorInterface/Core/interface/HepMCFilterDriver.h" #include "GeneratorInterface/Core/interface/GenericDauHepMCFilter.h" #include "GeneratorInterface/Core/interface/PartonShowerBsHepMCFilter.h" +#include "GeneratorInterface/Core/interface/PartonShowerCsHepMCFilter.h" #include "GeneratorInterface/Core/interface/EmbeddingHepMCFilter.h" #include "FWCore/MessageLogger/interface/MessageLogger.h" @@ -26,6 +27,9 @@ HepMCFilterDriver::HepMCFilterDriver(const edm::ParameterSet& pset) : else if (filterName=="PartonShowerBsHepMCFilter") { filter_ = new PartonShowerBsHepMCFilter(filterParameters); } + else if (filterName=="PartonShowerCsHepMCFilter") { + filter_ = new PartonShowerCsHepMCFilter(filterParameters); + } else if (filterName == "EmbeddingHepMCFilter") { filter_ = new EmbeddingHepMCFilter(filterParameters); }