CMS 3D CMS Logo

GenPUProtonProducer.cc
Go to the documentation of this file.
1 /* \class GenPUProtonProducer
2  *
3  * Modification of GenParticleProducer.
4  * Saves final state protons from HepMC events in Crossing Frame, in the generator-particle format.
5  *
6  * Note: Use the option USER_CXXFLAGS=-DEDM_ML_DEBUG with SCRAM in order to enable debug messages.
7  *
8  * March 9, 2017 : Initial version.
9  * March 14, 2017 : Updated debug messages.
10  * July 27, 2017 : Removed extra loop initially inherited from GenParticleProducer.
11  * August 17, 2017 : Replaced std::auto_ptr with std::unique_ptr.
12  * September 6, 2017 : Updated module to edm::global::EDProducer with ConvertParticle as RunCache following GenParticleProducer.
13  *
14  */
15 
20 
21 #include <vector>
22 #include <string>
23 #include <unordered_map>
24 
25 namespace {
26 
27  class ConvertParticle {
28  public:
29  static constexpr int PDGCacheMax = 32768;
30  static constexpr double mmToCm = 0.1;
31 
32  ConvertParticle() :
33  abortOnUnknownPDGCode_( true ),
34  initialized_( false ),
35  chargeP_( PDGCacheMax, 0 ), chargeM_( PDGCacheMax, 0 ) {};
36 
37  ConvertParticle(bool abortOnUnknownPDGCode) :
38  abortOnUnknownPDGCode_( abortOnUnknownPDGCode ),
39  initialized_( false ),
40  chargeP_( PDGCacheMax, 0 ), chargeM_( PDGCacheMax, 0 ) {};
41 
42  ~ConvertParticle() {};
43 
44  bool initialized() const { return initialized_; }
45 
46  void init(HepPDT::ParticleDataTable const& pdt) {
47  if( !initialized_ ) {
48  for( HepPDT::ParticleDataTable::const_iterator p = pdt.begin(); p != pdt.end(); ++p ) {
49  HepPDT::ParticleID const& id = p->first;
50  int pdgId = id.pid(), apdgId = std::abs( pdgId );
51  int q3 = id.threeCharge();
52  if ( apdgId < PDGCacheMax && pdgId > 0 ) {
53  chargeP_[ apdgId ] = q3;
54  chargeM_[ apdgId ] = -q3;
55  } else if ( apdgId < PDGCacheMax ) {
56  chargeP_[ apdgId ] = -q3;
57  chargeM_[ apdgId ] = q3;
58  } else {
59  chargeMap_.emplace( pdgId, q3);
60  chargeMap_.emplace( -pdgId, -q3);
61  }
62  }
63  initialized_ = true;
64  }
65  }
66 
67  bool operator() (reco::GenParticle& cand, HepMC::GenParticle const* part) const {
68  reco::Candidate::LorentzVector p4( part->momentum() );
69  int pdgId = part->pdg_id();
70  cand.setThreeCharge( chargeTimesThree( pdgId ) );
71  cand.setPdgId( pdgId );
72  cand.setStatus( part->status() );
73  cand.setP4( p4 );
74  cand.setCollisionId(0);
75  HepMC::GenVertex const* v = part->production_vertex();
76  if ( v != nullptr ) {
77  HepMC::ThreeVector vtx = v->point3d();
78  reco::Candidate::Point vertex( vtx.x() * mmToCm, vtx.y() * mmToCm, vtx.z() * mmToCm );
79  cand.setVertex( vertex );
80  } else {
81  cand.setVertex( reco::Candidate::Point( 0, 0, 0 ) );
82  }
83  return true;
84  }
85 
86  private:
87  bool abortOnUnknownPDGCode_;
88  bool initialized_;
89  std::vector<int> chargeP_, chargeM_;
90  std::unordered_map<int, int> chargeMap_;
91 
92  int chargeTimesThree( int id ) const {
93  if( std::abs( id ) < PDGCacheMax )
94  return id > 0 ? chargeP_[ id ] : chargeM_[ - id ];
95 
96  auto f = chargeMap_.find( id );
97  if ( f == chargeMap_.end() ) {
98  if ( abortOnUnknownPDGCode_ )
99  throw edm::Exception( edm::errors::LogicError ) << "invalid PDG id: " << id << std::endl;
100  else
101  return HepPDT::ParticleID(id).threeCharge();
102  }
103  return f->second;
104  }
105 
106  };
107 
108  class SelectProton {
109  public:
110  bool operator() ( HepMC::GenParticle const* part, double minPz ) const {
111  bool selection = ( ( !part->end_vertex() && part->status() == 1 ) &&
112  ( part->pdg_id() == 2212 ) && ( TMath::Abs( part->momentum().pz() ) >= minPz ) );
113  return selection;
114  }
115  };
116 
117 } // Anonymous namespace
118 
123 
129 
130 namespace edm { class ParameterSet; }
131 
132 class GenPUProtonProducer : public edm::global::EDProducer<edm::RunCache<ConvertParticle> > {
133  public:
135  ~GenPUProtonProducer() override;
136 
137  void produce( edm::StreamID, edm::Event& e, const edm::EventSetup&) const override;
138  std::shared_ptr<ConvertParticle> globalBeginRun(const edm::Run&, const edm::EventSetup&) const override;
139  void globalEndRun(edm::Run const&, edm::EventSetup const&) const override {};
140 
141  private:
143 
145  std::vector<int> bunchList_;
146  double minPz_;
147  SelectProton select_;
148 
149 };
150 
158 
162 
163 #include <algorithm>
164 
165 using namespace edm;
166 using namespace reco;
167 using namespace std;
168 using namespace HepMC;
169 
171  abortOnUnknownPDGCode_( cfg.getUntrackedParameter<bool>( "abortOnUnknownPDGCode", true ) ),
172  bunchList_( cfg.getParameter<vector<int> >( "bunchCrossingList" ) ),
173  minPz_( cfg.getParameter<double>( "minPz" ) )
174 {
175  produces<GenParticleCollection>();
176  mixToken_ = consumes<CrossingFrame<HepMCProduct> >( InputTag(cfg.getParameter<std::string>( "mix" ),"generatorSmeared") );
177 }
178 
180 
181 std::shared_ptr<ConvertParticle> GenPUProtonProducer::globalBeginRun(const Run&, const EventSetup& es) const {
183  es.getData( pdt );
184  auto convert_ptr = std::make_shared<ConvertParticle>( abortOnUnknownPDGCode_ );
185  if( !convert_ptr->initialized() ) convert_ptr->init( *pdt );
186 
187  return convert_ptr;
188 }
189 
190 void GenPUProtonProducer::produce( StreamID, Event& evt, const EventSetup& es ) const {
191 
192  size_t totalSize = 0;
193  size_t npiles = 1;
194 
196  evt.getByToken(mixToken_,cf);
197  std::unique_ptr<MixCollection<HepMCProduct> > cfhepmcprod( new MixCollection<HepMCProduct>( cf.product() ) );
198  npiles = cfhepmcprod->size();
199 
200  LogDebug("GenPUProtonProducer") << " Number of pile-up events : " << npiles << endl;
201 
202  for(size_t icf = 0; icf < npiles; ++icf){
203  LogDebug("GenPUProtonProducer") << "CF " << icf << " size : " << cfhepmcprod->getObject(icf).GetEvent()->particles_size() << endl;
204  totalSize += cfhepmcprod->getObject(icf).GetEvent()->particles_size();
205  }
206  LogDebug("GenPUProtonProducer") << "Total size : " << totalSize << endl;
207 
208  // Initialise containers
209  auto candsPtr = std::make_unique<GenParticleCollection>();
210  GenParticleCollection& cands = *candsPtr;
211 
212  // Loop over pile-up events
213  ConvertParticle const& convertParticle_ = *runCache( evt.getRun().index() );
214 
216  unsigned int total_number_of_protons = 0;
217  size_t idx_mix = 0;
218  // Fill collection
219  for( mixHepMC_itr = cfhepmcprod->begin() ; mixHepMC_itr != cfhepmcprod->end() ; ++mixHepMC_itr, ++idx_mix ){
220  int bunch = mixHepMC_itr.bunch();
221 
222  if( find( bunchList_.begin(), bunchList_.end(), bunch ) != bunchList_.end() ){
223 
224  auto event = (*mixHepMC_itr).GetEvent();
225 
226  size_t num_particles = event->particles_size();
227 
228  // Fill output collection
229  unsigned int number_of_protons = 0;
230  for( auto p = event->particles_begin() ; p != event->particles_end() ; ++p ) {
231  HepMC::GenParticle const* part = *p;
232  if( select_(part, minPz_) ) {
233  reco::GenParticle cand;
234  convertParticle_( cand, part );
235  ++number_of_protons;
236  cands.push_back( cand );
237  }
238  }
239  LogDebug("GenPUProtonProducer") << "Idx : " << idx_mix << " Bunch : " << bunch
240  << " Number of particles : " << num_particles
241  << " Number of protons : " << number_of_protons << endl;
242 
243  total_number_of_protons += number_of_protons;
244  }
245  }
246  LogDebug("GenPUProtonProducer") << "Total number of protons : " << total_number_of_protons << endl;
247  LogDebug("GenPUProtonProducer") << "Output collection size : " << cands.size() << endl;
248 
249  evt.put( std::move(candsPtr) );
250 }
251 
253 
255 
#define LogDebug(id)
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
std::shared_ptr< ConvertParticle > globalBeginRun(const edm::Run &, const edm::EventSetup &) const override
std::vector< int > bunchList_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:136
edm::EDGetTokenT< CrossingFrame< edm::HepMCProduct > > mixToken_
void setCollisionId(int s)
Definition: GenParticle.h:38
HepPDT::ParticleDataTable ParticleDataTable
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:519
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
void produce(edm::StreamID, edm::Event &e, const edm::EventSetup &) const override
int init
Definition: HydjetWrapper.h:67
selection
main part
Definition: corrVsCorr.py:98
Run const & getRun() const
Definition: Event.cc:114
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:20
#define constexpr
void getData(T &iHolder) const
Definition: EventSetup.h:81
void setVertex(const Point &vertex) override
set vertex
double p4[4]
Definition: TauolaWrapper.h:92
T Abs(T a)
Definition: MathUtil.h:49
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
GenPUProtonProducer(const edm::ParameterSet &)
RunIndex index() const
Definition: Run.cc:24
double f[11][100]
static int PDGCacheMax
T const * product() const
Definition: Handle.h:81
void setThreeCharge(Charge qx3) final
set electric charge
Definition: LeafCandidate.h:97
static const double mmToCm
part
Definition: HCALResponse.h:20
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:37
fixed size matrix
HLT enums.
math::XYZPoint Point
point in the space
Definition: Candidate.h:41
void setStatus(int status) final
set status word
void setPdgId(int pdgId) final
void setP4(const LorentzVector &p4) final
set 4-momentum
def move(src, dest)
Definition: eostools.py:510
Definition: event.py:1
Definition: Run.h:43