diff --git a/Configuration/ProcessModifiers/python/fastSimFixLongLivedBug_cff.py b/Configuration/ProcessModifiers/python/fastSimFixLongLivedBug_cff.py new file mode 100644 index 0000000000000..18c84cd767e6d --- /dev/null +++ b/Configuration/ProcessModifiers/python/fastSimFixLongLivedBug_cff.py @@ -0,0 +1,4 @@ +import FWCore.ParameterSet.Config as cms + +# Desiged to disable the bug in Run II samples that duplicates hits for long lived particles +fastSimFixLongLivedBug = cms.Modifier() diff --git a/FastSimulation/SimplifiedGeometryPropagator/interface/Decayer.h b/FastSimulation/SimplifiedGeometryPropagator/interface/Decayer.h index 09b297ee1bcd6..ea51155940824 100644 --- a/FastSimulation/SimplifiedGeometryPropagator/interface/Decayer.h +++ b/FastSimulation/SimplifiedGeometryPropagator/interface/Decayer.h @@ -50,10 +50,11 @@ namespace fastsim \param engine The Random Engine. */ void decay(const Particle & particle, std::vector > & secondaries, CLHEP::HepRandomEngine & engine) const; - + void setfixLongLivedBug(bool disable){ fixLongLivedBug_ = disable; }; private: std::unique_ptr pythia_; //!< Instance of pythia std::unique_ptr pythiaRandomEngine_; //!< Instance of pythia Random Engine + bool fixLongLivedBug_; }; } #endif diff --git a/FastSimulation/SimplifiedGeometryPropagator/interface/ParticleManager.h b/FastSimulation/SimplifiedGeometryPropagator/interface/ParticleManager.h index 47eee9af958ae..2b40bfe85ef3f 100644 --- a/FastSimulation/SimplifiedGeometryPropagator/interface/ParticleManager.h +++ b/FastSimulation/SimplifiedGeometryPropagator/interface/ParticleManager.h @@ -56,7 +56,8 @@ namespace fastsim { double deltaRchargedMother, const ParticleFilter & particleFilter, std::vector & simTracks, - std::vector & simVertices); + std::vector & simVertices, + bool fixLongLivedBug); //! Default destructor. ~ParticleManager(); @@ -142,15 +143,18 @@ namespace fastsim { double lengthUnitConversionFactor2_; //!< Convert pythia unis to cm^2 (FastSim standard) double timeUnitConversionFactor_; //!< Convert pythia unis to ns (FastSim standard) std::vector > particleBuffer_; //!< The vector of all secondaries that are not yet propagated in the event. + bool fixLongLivedBug_; }; } -inline bool isExotic(int pdgid_) { +inline bool isExotic(bool fixLongLivedBug, int pdgid_) { unsigned int pdgid = std::abs(pdgid_); return ((pdgid >= 1000000 && pdgid < 4000000 && pdgid != 3000022) || // SUSY, R-hadron, and technicolor particles pdgid == 17 || // 4th generation lepton pdgid == 34 || // W-prime - pdgid == 37); // charged Higgs + pdgid == 37 || // charged Higgs + (pdgid == 39 && fixLongLivedBug)); // bulk graviton + } #endif diff --git a/FastSimulation/SimplifiedGeometryPropagator/plugins/FastSimProducer.cc b/FastSimulation/SimplifiedGeometryPropagator/plugins/FastSimProducer.cc index 02d6eed087aaf..ac0059ae43af6 100644 --- a/FastSimulation/SimplifiedGeometryPropagator/plugins/FastSimProducer.cc +++ b/FastSimulation/SimplifiedGeometryPropagator/plugins/FastSimProducer.cc @@ -93,6 +93,8 @@ class FastSimProducer : public edm::stream::EDProducer<> { std::vector > interactionModels_; //!< All defined interaction models std::map interactionModelMap_; //!< Each interaction model has a unique name static const std::string MESSAGECATEGORY; //!< Category of debugging messages ("FastSimulation") + + bool fixLongLivedBug_; }; const std::string FastSimProducer::MESSAGECATEGORY = "FastSimulation"; @@ -107,8 +109,10 @@ FastSimProducer::FastSimProducer(const edm::ParameterSet& iConfig) , _randomEngine(nullptr) , simulateCalorimetry(iConfig.getParameter("simulateCalorimetry")) , simulateMuons(iConfig.getParameter("simulateMuons")) + , fixLongLivedBug_(iConfig.getParameter("fixLongLivedBug")) { - + // Fix the decayer for the long lived stuff + decayer_.setfixLongLivedBug(fixLongLivedBug_); //---------------- // define interaction models //--------------- @@ -195,7 +199,8 @@ FastSimProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) ,deltaRchargedMother_ ,particleFilter_ ,*simTracks_ - ,*simVertices_); + ,*simVertices_ + ,fixLongLivedBug_); // Initialize the calorimeter geometry if(simulateCalorimetry) diff --git a/FastSimulation/SimplifiedGeometryPropagator/python/fastSimProducer_cff.py b/FastSimulation/SimplifiedGeometryPropagator/python/fastSimProducer_cff.py index e6e4482c4699c..4b5c2fd9e1fac 100644 --- a/FastSimulation/SimplifiedGeometryPropagator/python/fastSimProducer_cff.py +++ b/FastSimulation/SimplifiedGeometryPropagator/python/fastSimProducer_cff.py @@ -77,4 +77,9 @@ MaterialEffectsForMuonsInECAL = MaterialEffectsForMuonsInECALBlock.MaterialEffectsForMuonsInECAL, MaterialEffectsForMuonsInHCAL = MaterialEffectsForMuonsInHCALBlock.MaterialEffectsForMuonsInHCAL, GFlash = FamosCalorimetryBlock.GFlash, + fixLongLivedBug = cms.bool(False), ) + +from Configuration.ProcessModifiers.fastSimFixLongLivedBug_cff import fastSimFixLongLivedBug + +fastSimFixLongLivedBug.toModify(fastSimProducer, fixLongLivedBug = cms.bool(True)) diff --git a/FastSimulation/SimplifiedGeometryPropagator/src/Decayer.cc b/FastSimulation/SimplifiedGeometryPropagator/src/Decayer.cc index cb9eb36ebc2ca..eebf15cd6bd7d 100644 --- a/FastSimulation/SimplifiedGeometryPropagator/src/Decayer.cc +++ b/FastSimulation/SimplifiedGeometryPropagator/src/Decayer.cc @@ -18,7 +18,7 @@ fastsim::Decayer::Decayer() pythia_->settings.flag("PartonLevel:FSRinResonances",false); pythia_->settings.flag("ProcessLevel:resonanceDecays",false); pythia_->init(); - + fixLongLivedBug_ = false; // forbid all decays // (decays are allowed selectively in the decay function) Pythia8::ParticleData & pdt = pythia_->particleData; @@ -39,9 +39,8 @@ fastsim::Decayer::decay(const Particle & particle,std::vector & simTracks, - std::vector & simVertices) + std::vector & simVertices, + bool fixLongLivedBug) : genEvent_(&genEvent) , genParticleIterator_(genEvent_->particles_begin()) , genParticleEnd_(genEvent_->particles_end()) @@ -44,7 +45,7 @@ fastsim::ParticleManager::ParticleManager( , lengthUnitConversionFactor_(conversion_factor(genEvent_->length_unit(),HepMC::Units::LengthUnit::CM)) , lengthUnitConversionFactor2_(lengthUnitConversionFactor_*lengthUnitConversionFactor_) , timeUnitConversionFactor_(lengthUnitConversionFactor_/fastsim::Constants::speedOfLight) - + , fixLongLivedBug_(fixLongLivedBug) { // add the main vertex from the signal event to the simvertex collection @@ -240,7 +241,6 @@ std::unique_ptr fastsim::ParticleManager::nextGenParticle() const HepMC::GenParticle & particle = **genParticleIterator_; const HepMC::GenVertex * productionVertex = particle.production_vertex(); const HepMC::GenVertex * endVertex = particle.end_vertex(); - // skip incoming particles if(!productionVertex){ continue; @@ -251,22 +251,27 @@ std::unique_ptr fastsim::ParticleManager::nextGenParticle() // particles which do not descend from exotics must be produced within the beampipe int exoticRelativeId = 0; - if (productionVertex->position().perp2() * lengthUnitConversionFactor2_ > beamPipeRadius2_) // + const bool producedWithinBeamPipe = productionVertex->position().perp2() * lengthUnitConversionFactor2_ < beamPipeRadius2_; + if (!producedWithinBeamPipe) // { exoticRelativesChecker(productionVertex, exoticRelativeId, 0); - if (!isExotic(exoticRelativeId)) { + if (!isExotic(fixLongLivedBug_, exoticRelativeId)) { continue; } - } - - - // particle must not decay before it reaches the beam pipe - if(endVertex && endVertex->position().perp2()*lengthUnitConversionFactor2_ < beamPipeRadius2_) + } + const bool decayedWithinBeamPipe = endVertex && endVertex->position().perp2() * lengthUnitConversionFactor2_ < beamPipeRadius2_; + if(decayedWithinBeamPipe) { continue; } - + // SM particles that descend from exotics and cross the beam pipe radius should make hits but not be decayed, + // by default it will duplicate FastSim hits for long lived particles + // and so anything produced without activating fixLongLivedBug_ is physically wrong + if (fixLongLivedBug_ && producedWithinBeamPipe && !decayedWithinBeamPipe){ + exoticRelativesChecker(productionVertex, exoticRelativeId, 0); + } + // make the particle std::unique_ptr newParticle( new Particle(particle.pdg_id(), @@ -279,7 +284,7 @@ std::unique_ptr fastsim::ParticleManager::nextGenParticle() particle.momentum().z()*momentumUnitConversionFactor_, particle.momentum().e()*momentumUnitConversionFactor_))); newParticle->setGenParticleIndex(genParticleIndex_); - if (isExotic(exoticRelativeId)) { + if (isExotic(fixLongLivedBug_, exoticRelativeId)) { newParticle->setMotherPdgId(exoticRelativeId); } // try to get the life time of the particle from the genEvent @@ -313,14 +318,14 @@ std::unique_ptr fastsim::ParticleManager::nextGenParticle() void fastsim::ParticleManager::exoticRelativesChecker(const HepMC::GenVertex* originVertex, int& exoticRelativeId_, int ngendepth = 0) { - if (ngendepth > 99 || exoticRelativeId_ == -1 || isExotic(std::abs(exoticRelativeId_))) + if (ngendepth > 99 || exoticRelativeId_ == -1 || isExotic(fixLongLivedBug_, std::abs(exoticRelativeId_))) return; ngendepth += 1; std::vector::const_iterator relativesIterator_ = originVertex->particles_in_const_begin(); std::vector::const_iterator relativesIteratorEnd_ = originVertex->particles_in_const_end(); for (; relativesIterator_ != relativesIteratorEnd_; ++relativesIterator_) { const HepMC::GenParticle& genRelative = **relativesIterator_; - if (isExotic(std::abs(genRelative.pdg_id()))) { + if (isExotic(fixLongLivedBug_, std::abs(genRelative.pdg_id()))) { exoticRelativeId_ = genRelative.pdg_id(); if (ngendepth == 100) exoticRelativeId_ = -1;