From cd411cc9fd867ded5b60530566388b2fe83291a2 Mon Sep 17 00:00:00 2001
From: raffaellatramontano <41014138+Raffaella07@users.noreply.github.com>
Date: Tue, 10 May 2022 08:28:06 +0200
Subject: [PATCH] LLP GenFilter based on transverse displacement and pdgId -
backport #37669 (#37863)
* Update LLP filter with upper and/or lower cut and pdgIds
---
.../GenFilters/plugins/BuildFile.xml | 7 +
.../plugins/MCDisplacementFilter.cc | 137 ++++++++++++++++++
.../test/test_MCDisplacementFilter_cfg.py | 85 +++++++++++
3 files changed, 229 insertions(+)
create mode 100644 GeneratorInterface/GenFilters/plugins/BuildFile.xml
create mode 100644 GeneratorInterface/GenFilters/plugins/MCDisplacementFilter.cc
create mode 100644 GeneratorInterface/GenFilters/test/test_MCDisplacementFilter_cfg.py
diff --git a/GeneratorInterface/GenFilters/plugins/BuildFile.xml b/GeneratorInterface/GenFilters/plugins/BuildFile.xml
new file mode 100644
index 0000000000000..3a032fe49a025
--- /dev/null
+++ b/GeneratorInterface/GenFilters/plugins/BuildFile.xml
@@ -0,0 +1,7 @@
+
+
+
+
+
+
+
diff --git a/GeneratorInterface/GenFilters/plugins/MCDisplacementFilter.cc b/GeneratorInterface/GenFilters/plugins/MCDisplacementFilter.cc
new file mode 100644
index 0000000000000..fe478daf1c9bc
--- /dev/null
+++ b/GeneratorInterface/GenFilters/plugins/MCDisplacementFilter.cc
@@ -0,0 +1,137 @@
+
+// -*- C++ -*-
+//
+// Package: MCDisplacementFilter
+// Class: MCDisplacementFilter
+//
+
+// system include files
+//#include
+//#include
+#include
+
+// user include files
+#include "FWCore/Framework/interface/Frameworkfwd.h"
+#include "FWCore/Framework/interface/global/EDFilter.h"
+#include "FWCore/Utilities/interface/InputTag.h"
+
+#include "FWCore/Framework/interface/Event.h"
+#include "FWCore/Framework/interface/MakerMacros.h"
+
+#include "FWCore/ParameterSet/interface/ParameterSet.h"
+#include "SimDataFormats/GeneratorProducts/interface/HepMCProduct.h"
+
+using namespace edm;
+using namespace std;
+
+//Filter particles based on their minimum and/or maximum displacement on the transverse plane and optionally on their pdgIds
+//To run independently of pdgId, do not insert the particleIDs entry in filter declaration
+
+// class decleration
+//
+namespace edm {
+ class HepMCProduct;
+ class ConfigurationDescriptions;
+} // namespace edm
+
+class MCDisplacementFilter : public edm::global::EDFilter<> {
+public:
+ explicit MCDisplacementFilter(const edm::ParameterSet&);
+ ~MCDisplacementFilter() override = default;
+
+ static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
+
+ bool filter(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
+
+private:
+ // ----------member data ---------------------------
+ edm::InputTag hepMCProductTag_;
+ const edm::EDGetTokenT token_;
+ // To chose on which pdgIds the filter is applied - if ParticleIDs.at(0)==0 runs on all particles
+ std::vector particleIDs_;
+
+ const float theUpperCut_; // Maximum displacement accepted
+ const float theLowerCut_; // Minimum displacement accepted
+};
+
+//methods implementation
+//
+//Class initialization
+MCDisplacementFilter::MCDisplacementFilter(const edm::ParameterSet& iConfig)
+ : hepMCProductTag_(iConfig.getParameter("hepMCProductTag")),
+ token_(consumes(hepMCProductTag_)),
+ particleIDs_(iConfig.getParameter>("ParticleIDs")),
+ theUpperCut_(iConfig.getParameter("LengMax")),
+ theLowerCut_(iConfig.getParameter("LengMin")) {}
+
+//Filter description
+void MCDisplacementFilter::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
+ edm::ParameterSetDescription desc;
+ desc.add("hepMCProductTag", edm::InputTag("generator", "unsmeared"));
+ desc.add>("ParticleIDs", std::vector{0});
+ desc.add("LengMax", -1.);
+ desc.add("LengMin", -1.);
+ descriptions.addDefault(desc);
+}
+
+// ------------ method called to skim the data ------------
+bool MCDisplacementFilter::filter(edm::StreamID, edm::Event& iEvent, const edm::EventSetup& iSetup) const {
+ using namespace edm;
+
+ Handle evt;
+
+ iEvent.getByToken(token_, evt);
+
+ bool pass = false;
+ bool matchedID = true;
+
+ const float theUpperCut2 = theUpperCut_ * theUpperCut_;
+ const float theLowerCut2 = theLowerCut_ * theLowerCut_;
+
+ const HepMC::GenEvent* generated_event = evt->GetEvent();
+ HepMC::GenEvent::particle_const_iterator p;
+
+ for (p = generated_event->particles_begin(); p != generated_event->particles_end(); p++) {
+ //matchedID might be moved to false to true for a particle in the event, it needs to be resetted everytime
+ if (particleIDs_.at(0) != 0)
+ matchedID = false;
+
+ //if a list of pdgId is provided, loop only on particles with those pdgId
+ for (unsigned int idx = 0; idx < particleIDs_.size(); idx++) {
+ if (abs((*p)->pdg_id()) == abs(particleIDs_.at(idx))) { //compares absolute values of pdgIds
+ matchedID = true;
+ break;
+ }
+ }
+
+ if (matchedID) {
+ if (theLowerCut_ <= 0. && theUpperCut_ <= 0.) {
+ pass = true;
+ break;
+ }
+ if (((*p)->production_vertex() != nullptr) && ((*p)->end_vertex() != nullptr)) {
+ float dist2 = (((*p)->production_vertex())->position().x() - ((*p)->end_vertex())->position().x()) *
+ (((*p)->production_vertex())->position().x() - ((*p)->end_vertex())->position().x()) +
+ (((*p)->production_vertex())->position().y() - ((*p)->end_vertex())->position().y()) *
+ (((*p)->production_vertex())->position().y() - ((*p)->end_vertex())->position().y());
+ // lower/upper cuts can be also <= 0 - prompt particle needs to be accepted in that case
+ if ((theLowerCut_ <= 0. || dist2 >= theLowerCut2) && (theUpperCut_ <= 0. || dist2 < theUpperCut2)) {
+ pass = true;
+ break;
+ }
+ }
+ if (((*p)->production_vertex() == nullptr) && (((*p)->end_vertex() != nullptr))) {
+ // lower/upper cuts can be also 0 - prompt particle needs to be accepted in that case
+ float distEndVert = (*p)->end_vertex()->position().perp();
+ if ((theLowerCut_ <= 0. || distEndVert >= theLowerCut_) && (theUpperCut_ <= 0. || distEndVert < theUpperCut_)) {
+ pass = true;
+ break;
+ }
+ }
+ }
+ }
+
+ return pass;
+}
+
+DEFINE_FWK_MODULE(MCDisplacementFilter);
diff --git a/GeneratorInterface/GenFilters/test/test_MCDisplacementFilter_cfg.py b/GeneratorInterface/GenFilters/test/test_MCDisplacementFilter_cfg.py
new file mode 100644
index 0000000000000..1ed2354e51966
--- /dev/null
+++ b/GeneratorInterface/GenFilters/test/test_MCDisplacementFilter_cfg.py
@@ -0,0 +1,85 @@
+import FWCore.ParameterSet.Config as cms
+
+process = cms.Process("GEN")
+process.load("FWCore.MessageService.MessageLogger_cfi")
+
+# control point for all seeds
+#
+process.load("Configuration.StandardSequences.SimulationRandomNumberGeneratorSeeds_cff")
+
+process.load("SimGeneral.HepPDTESSource.pythiapdt_cfi")
+
+process.load("GeneratorInterface.Pythia6Interface.pythiaDefault_cff")
+
+process.load("Configuration.EventContent.EventContent_cff")
+
+process.maxEvents = cms.untracked.PSet(
+ input = cms.untracked.int32(1000)
+)
+process.options = cms.untracked.PSet(
+ wantSummary = cms.untracked.bool(True)
+)
+process.configurationMetadata = cms.untracked.PSet(
+ version = cms.untracked.string(''),
+ name = cms.untracked.string(''),
+ annotation = cms.untracked.string('generation of D*, with LongLived filter applied')
+)
+process.source = cms.Source("EmptySource")
+process.generator = cms.EDFilter("Pythia6GeneratorFilter",
+ Ptmax = cms.untracked.double(200.0),
+ pythiaPylistVerbosity = cms.untracked.int32(0),
+ ymax = cms.untracked.double(10.0),
+ ParticleID = cms.untracked.int32(413),
+ pythiaHepMCVerbosity = cms.untracked.bool(False),
+ DoubleParticle = cms.untracked.bool(False),
+ Ptmin = cms.untracked.double(200.0),
+ ymin = cms.untracked.double(-10.0),
+ maxEventsToPrint = cms.untracked.int32(0),
+ comEnergy = cms.double(10000.0),
+ PythiaParameters = cms.PSet(
+ process.pythiaDefaultBlock,
+ # User cards - name is "myParameters"
+ # Pythia's random generator initialization
+ myParameters = cms.vstring('MDCY(123,2) = 738',
+ 'MDCY(123,3) = 1',
+ 'MDCY(122,2) = 705',
+ 'MDCY(122,3) = 1'),
+ # This is a vector of ParameterSet names to be read, in this order
+ # The first two are in the include files below
+ # The last one are simply my additional parameters
+ parameterSets = cms.vstring('pythiaDefault',
+ 'myParameters')
+ )
+)
+
+process.select = cms.EDFilter("MCDisplacementFilter",
+ ParticleIDs = cms.vint32(310),
+ LengMin = cms.double(0.), ## in mm
+ LengMax = cms.double(100.), ## in mm
+
+)
+
+process.out = cms.OutputModule("PoolOutputModule",
+ process.FEVTSIMEventContent,
+ fileName = cms.untracked.string('dstardecay.root'),
+ SelectEvents = cms.untracked.PSet(
+ SelectEvents = cms.vstring('p1')
+ ),
+ dataset = cms.untracked.PSet(
+ dataTier = cms.untracked.string('GEN')
+ )
+)
+process.genParticles = cms.EDProducer("GenParticleProducer",
+ src = cms.InputTag("generator","unsmeared")
+)
+
+
+process.p1 = cms.Path(process.generator*process.select*process.genParticles)
+process.outpath = cms.EndPath(process.out)
+process.schedule = cms.Schedule(process.p1,process.outpath)
+
+process.generator.pythiaPylistVerbosity = 0
+process.generator.maxEventsToPrint = 10
+process.generator.pythiaHepMCVerbosity = True
+
+