CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
GenMuonRadiationAlgorithm.cc
Go to the documentation of this file.
2 
4 
6 
9 
11 
13 #include "TauAnalysis/MCEmbeddingTools/interface/extraPythia.h" // needed for call_pyexec
14 
17 
19 
21 
22 #include "HepMC/IO_HEPEVT.h"
23 #include <HepMC/HEPEVT_Wrapper.h>
24 #include "HepPID/ParticleIDTranslations.hh"
25 
26 #include <Math/VectorUtil.h>
27 
28 const double protonMass = 0.938272;
29 
32 
34 {
35  public:
37  : gen::Pythia6Service(cfg),
38  beamEnergy_(cfg.getParameter<double>("beamEnergy")),
39  genEvt_(0),
40  verbosity_(cfg.getParameter<int>("verbosity"))
41  {}
43 
44  void setEvent(const HepMC::GenEvent* genEvt)
45  {
46  genEvt_ = genEvt;
47  }
48 
49  private:
50  void upInit()
51  {
52  // initialize LEs Houches accord common block (see hep-ph/0109068)
53  // needed to run PYTHIA in parton shower mode
54  if ( verbosity_ ) std::cout << "<upInit:" << std::endl;
55  lhef::HEPRUP heprup;
56  heprup.IDBMUP.first = 2212;
57  heprup.IDBMUP.second = 2212;
58  heprup.EBMUP.first = beamEnergy_;
59  heprup.EBMUP.second = beamEnergy_;
60  heprup.PDFGUP.first = -9; // CV: LHE input event contains proton remnants
61  heprup.PDFGUP.second = -9;
62  heprup.PDFSUP.first = 10042;
63  heprup.PDFSUP.second = 10042;
64  heprup.IDWTUP = 3;
65  heprup.NPRUP = 1;
66  heprup.XSECUP.push_back(1.e+3);
67  heprup.XERRUP.push_back(0.);
68  heprup.XMAXUP.push_back(1.);
69  heprup.LPRUP.push_back(1);
71  }
72  void upEvnt()
73  {
74  if ( verbosity_ ) std::cout << "<upEvnt>:" << std::endl;
75  int numParticles = 0;
76  for ( HepMC::GenEvent::particle_const_iterator genParticle = genEvt_->particles_begin();
77  genParticle != genEvt_->particles_end(); ++genParticle ) {
78  ++numParticles;
79  }
80  lhef::HEPEUP hepeup;
81  hepeup.NUP = numParticles;
82  if ( verbosity_ ) std::cout << " numParticles = " << numParticles << std::endl;
83  hepeup.IDPRUP = 1;
84  hepeup.XWGTUP = 1.;
85  hepeup.XPDWUP.first = 0.;
86  hepeup.XPDWUP.second = 0.;
87  hepeup.SCALUP = -1.;
88  hepeup.AQEDUP = -1.;
89  hepeup.AQCDUP = -1.;
90  hepeup.resize();
91  std::map<int, int> barcodeToIdxMap;
92  int genParticleIdx = 0;
93  for ( HepMC::GenEvent::particle_const_iterator genParticle = genEvt_->particles_begin();
94  genParticle != genEvt_->particles_end(); ++genParticle ) {
95  barcodeToIdxMap[(*genParticle)->barcode()] = genParticleIdx + 1; // CV: conversion between C++ and Fortran array index conventions
96  int pdgId = (*genParticle)->pdg_id();
97  hepeup.IDUP[genParticleIdx] = pdgId;
98  if ( pdgId == 2212 && !(*genParticle)->production_vertex() ) {
99  hepeup.ISTUP[genParticleIdx] = -1;
100  } else {
101  hepeup.ISTUP[genParticleIdx] = (*genParticle)->status();
102  }
103  if ( (*genParticle)->production_vertex() ) {
104  int firstMother = 0;
105  bool firstMother_initialized = false;
106  int lastMother = 0;
107  bool lastMother_initialized = false;
108  for ( HepMC::GenVertex::particles_in_const_iterator genMother = (*genParticle)->production_vertex()->particles_in_const_begin();
109  genMother != (*genParticle)->production_vertex()->particles_in_const_end(); ++genMother ) {
110  int genMotherBarcode = (*genMother)->barcode();
111  assert(barcodeToIdxMap.find(genMotherBarcode) != barcodeToIdxMap.end());
112  int genMotherIdx = barcodeToIdxMap[genMotherBarcode];
113  if ( genMotherIdx < firstMother || !firstMother_initialized ) {
114  firstMother = genMotherIdx;
115  firstMother_initialized = true;
116  }
117  if ( genMotherIdx > lastMother || !lastMother_initialized ) {
118  lastMother = genMotherIdx;
119  lastMother_initialized = true;
120  }
121  }
122  hepeup.MOTHUP[genParticleIdx].first = firstMother;
123  hepeup.MOTHUP[genParticleIdx].second = ( lastMother > firstMother ) ? lastMother : 0;
124  } else {
125  hepeup.MOTHUP[genParticleIdx].first = 0;
126  hepeup.MOTHUP[genParticleIdx].second = 0;
127  }
128  hepeup.ICOLUP[genParticleIdx].first = 0;
129  hepeup.ICOLUP[genParticleIdx].second = 0;
130  hepeup.PUP[genParticleIdx][0] = (*genParticle)->momentum().px();
131  hepeup.PUP[genParticleIdx][1] = (*genParticle)->momentum().py();
132  hepeup.PUP[genParticleIdx][2] = (*genParticle)->momentum().pz();
133  hepeup.PUP[genParticleIdx][3] = (*genParticle)->momentum().e();
134  hepeup.PUP[genParticleIdx][4] = (*genParticle)->momentum().m();
135  if ( (*genParticle)->status() == 1 ) hepeup.VTIMUP[genParticleIdx] = 1.e+6;
136  else hepeup.VTIMUP[genParticleIdx] = 0.;
137  hepeup.SPINUP[genParticleIdx] = 9;
138  if ( verbosity_ ) {
139  std::cout << "adding genParticle #" << (genParticleIdx + 1)
140  << " (pdgId = " << hepeup.IDUP[genParticleIdx] << ", status = " << hepeup.ISTUP[genParticleIdx] << "):"
141  << " En = " << hepeup.PUP[genParticleIdx][3] << ","
142  << " Px = " << hepeup.PUP[genParticleIdx][0] << ","
143  << " Py = " << hepeup.PUP[genParticleIdx][1] << ","
144  << " Pz = " << hepeup.PUP[genParticleIdx][2] << " (mass = " << hepeup.PUP[genParticleIdx][4] << ")" << std::endl;
145  std::cout << "(mothers = " << hepeup.MOTHUP[genParticleIdx].first << ":" << hepeup.MOTHUP[genParticleIdx].second << ")" << std::endl;
146  }
147  ++genParticleIdx;
148  }
150  }
151  bool upVeto()
152  {
153  if ( verbosity_ ) std::cout << "<upVeto>:" << std::endl;
154  return false; // keep current event
155  }
156 
157  double beamEnergy_;
158 
159  const HepMC::GenEvent* genEvt_;
160 
162 };
163 
165  : beamEnergy_(cfg.getParameter<double>("beamEnergy")),
166  photos_(0),
167  pythia_(0)
168 {
170  if ( !rng.isAvailable() )
171  throw cms::Exception("Configuration")
172  << "The RandomNumberProducer module requires the RandomNumberGeneratorService\n"
173  << "which appears to be absent. Please add that service to your configuration\n"
174  << "or remove the modules that require it.\n";
175 
176  // this is a global variable defined in GeneratorInterface/ExternalDecays/src/ExternalDecayDriver.cc
177  decayRandomEngine = &rng->getEngine();
178 
179  std::string mode_string = cfg.getParameter<std::string>("mode");
180  if ( mode_string == "pythia" ) mode_ = kPYTHIA;
181  else if ( mode_string == "photos" ) mode_ = kPHOTOS;
182  else throw cms::Exception("Configuration")
183  << " Invalid Configuration Parameter 'mode' = " << mode_string << " !!\n";
184 
185  if ( mode_ == kPYTHIA ) pythia_ = new myPythia6ServiceWithCallback(cfg);
186  if ( mode_ == kPHOTOS ) photos_ = new gen::PhotosInterface(cfg.getParameter<edm::ParameterSet>("PhotosOptions"));
187 
188  verbosity_ = ( cfg.exists("verbosity") ) ?
189  cfg.getParameter<int>("verbosity") : 0;
190 }
191 
193 {
194  delete photos_;
195  call_pystat(1);
196  delete pythia_;
197 }
198 
199 namespace
200 {
201  double square(double x)
202  {
203  return x*x;
204  }
205 
206  reco::Candidate::LorentzVector getP4_limited(const reco::Candidate::LorentzVector& p4, double mass)
207  {
208  // CV: restrict reconstructed momenta to 1 TeV maximum
209  // (higher values are almost for sure due to reconstruction errors)
210  reco::Candidate::LorentzVector p4_limited = p4;
211  if ( p4.energy() > 1.e+3 ) {
212  double scaleFactor = 1.e+3/p4.energy();
213  double px_limited = scaleFactor*p4.px();
214  double py_limited = scaleFactor*p4.py();
215  double pz_limited = scaleFactor*p4.pz();
216  double en_limited = sqrt(square(px_limited) + square(py_limited) + square(pz_limited) + square(mass));
217  p4_limited.SetPxPyPzE(
218  px_limited,
219  py_limited,
220  pz_limited,
221  en_limited);
222  }
223  return p4_limited;
224  }
225 
227  const reco::Candidate::LorentzVector& p4ToBoost)
228  {
229  reco::Candidate::Vector boost = rfSystem.BoostToCM();
230  return ROOT::Math::VectorUtil::boost(p4ToBoost, -boost);
231  }
232 }
233 
235  const reco::Candidate::LorentzVector& otherP4, int& errorFlag)
236 {
237  if ( verbosity_ ) {
238  std::cout << "<GenMuonRadiationAlgorithm::compMuonFSR>:" << std::endl;
239  std::cout << " muon: En = " << muonP4.E() << ", Pt = " << muonP4.pt() << ", eta = " << muonP4.eta() << ", phi = " << muonP4.phi() << ", charge = " << muonCharge << std::endl;
240  std::cout << " other: En = " << otherP4.E() << ", Pt = " << otherP4.pt() << ", eta = " << otherP4.eta() << ", phi = " << otherP4.phi() << std::endl;
241  }
242 
243  reco::Candidate::LorentzVector muonP4_limited = getP4_limited(muonP4, muonP4.mass());
244  int muonPdgId = -13*muonCharge;
245  reco::Candidate::LorentzVector otherP4_limited = getP4_limited(otherP4, otherP4.mass());
246  int otherPdgId = +13*muonCharge;
247  reco::Candidate::LorentzVector zP4 = muonP4_limited + otherP4_limited;
248  int zPdgId = 23;
249  if ( verbosity_ ) {
250  std::cout << "muon(limited): En = " << muonP4_limited.E() << ", Pt = " << muonP4_limited.pt() << ", eta = " << muonP4_limited.eta() << ", phi = " << muonP4_limited.phi() << std::endl;
251  std::cout << "other: En = " << otherP4_limited.E() << ", Pt = " << otherP4_limited.pt() << ", eta = " << otherP4_limited.eta() << ", phi = " << otherP4_limited.phi() << std::endl;
252  std::cout << "Z: En = " << zP4.E() << ", Pt = " << zP4.pt() << ", eta = " << zP4.eta() << ", phi = " << zP4.phi() << std::endl;
253  }
254 
255  HepMC::GenEvent* genEvt_beforeFSR = new HepMC::GenEvent();
256  HepMC::GenVertex* genVtx_in = new HepMC::GenVertex(HepMC::FourVector(0.,0.,0.,0.));
257  double protonEn = beamEnergy_;
258  double protonPz = sqrt(square(protonEn) - square(protonMass));
259  genVtx_in->add_particle_in(new HepMC::GenParticle(HepMC::FourVector(0., 0., +protonPz, protonEn), 2212, 3));
260  genVtx_in->add_particle_in(new HepMC::GenParticle(HepMC::FourVector(0., 0., -protonPz, protonEn), 2212, 3));
261  genEvt_beforeFSR->add_vertex(genVtx_in);
262  reco::Candidate::LorentzVector ppP4_scattered(-zP4.px(), -zP4.py(), -zP4.pz(), 2.*beamEnergy_ - zP4.E());
263  double protonEn_rf = 0.5*ppP4_scattered.mass();
264  double protonP_rf = sqrt(square(protonEn_rf) - square(protonMass));
265  reco::Candidate::LorentzVector proton1P4_scattered_rf(0., 0., +protonP_rf, protonEn_rf);
266  reco::Candidate::LorentzVector proton2P4_scattered_rf(0., 0., -protonP_rf, protonEn_rf);
267  reco::Candidate::LorentzVector proton1P4_scattered = boostToLab(ppP4_scattered, proton1P4_scattered_rf);
268  reco::Candidate::LorentzVector proton2P4_scattered = boostToLab(ppP4_scattered, proton2P4_scattered_rf);
269  genVtx_in->add_particle_out(new HepMC::GenParticle(HepMC::FourVector(proton1P4_scattered.px(), proton1P4_scattered.py(), proton1P4_scattered.pz(), proton1P4_scattered.E()), 2212, 1));
270  genVtx_in->add_particle_out(new HepMC::GenParticle(HepMC::FourVector(proton2P4_scattered.px(), proton2P4_scattered.py(), proton2P4_scattered.pz(), proton2P4_scattered.E()), 2212, 1));
271  HepMC::GenVertex* genVtx_out = new HepMC::GenVertex(HepMC::FourVector(0.,0.,0.,0.));
272  HepMC::GenParticle* genZ = new HepMC::GenParticle((HepMC::FourVector)zP4, zPdgId, 2, HepMC::Flow(), HepMC::Polarization(0,0));
273  genVtx_in->add_particle_out(genZ);
274  genVtx_out->add_particle_in(genZ);
275  HepMC::GenParticle* genMuon = new HepMC::GenParticle((HepMC::FourVector)muonP4_limited, muonPdgId, 1, HepMC::Flow(), HepMC::Polarization(0,0));
276  genVtx_out->add_particle_out(genMuon);
277  HepMC::GenParticle* genOther = new HepMC::GenParticle((HepMC::FourVector)otherP4_limited, otherPdgId, 1, HepMC::Flow(), HepMC::Polarization(0,0));
278  genVtx_out->add_particle_out(genOther);
279  genEvt_beforeFSR->add_vertex(genVtx_out);
280  if ( verbosity_ ) {
281  std::cout << "genEvt (beforeFSR):" << std::endl;
282  genEvt_beforeFSR->print(std::cout);
283  }
284 
285  repairBarcodes(genEvt_beforeFSR);
286 
287  HepMC::GenEvent* genEvt_afterFSR = 0;
288 
289  if ( mode_ == kPYTHIA ) {
290  gen::Pythia6Service::InstanceWrapper pythia6InstanceGuard(pythia_);
291 
292  if ( !pythia_isInitialized_ ) {
294  //pythia_->setCSAParams();
295  //pythia_->setSLHAParams();
296  gen::call_pygive("MSTU(12) = 12345");
297  call_pyinit("USER", "", "", 0.);
298  pythia_isInitialized_ = true;
299  }
300 
301  pythia_->setEvent(genEvt_beforeFSR);
302  if ( verbosity_ ) {
303  std::cout << "HEPEUP (beforeFSR):" << std::endl;
304  call_pylist(7);
305  std::cout.flush();
306  }
307  call_pyevnt();
308  call_pyedit(0); // CV: remove comment lines (confuses conversion to HepMC::Event)
309  if ( verbosity_ ) {
310  std::cout << "PYJETS (afterFSR):" << std::endl;
311  call_pylist(1);
312  std::cout.flush();
313  }
314  call_pyhepc(1);
315  if ( verbosity_ ) {
316  std::cout << "HepMC (afterFSR):" << std::endl;
317  call_pylist(5);
318  std::cout.flush();
319  }
320 
321  HepMC::IO_HEPEVT conv;
322  conv.set_print_inconsistency_errors(false);
323  genEvt_afterFSR = conv.read_next_event();
324  } else if ( mode_ == kPHOTOS ) {
325 
326  if ( !photos_isInitialized_ ) {
327  photos_->init();
328  photos_isInitialized_ = true;
329  }
330 
331  HepMC::IO_HEPEVT conv;
332  conv.write_event(genEvt_beforeFSR);
333  genEvt_afterFSR = photos_->apply(genEvt_beforeFSR);
334  } else assert(0);
335 
336  if ( verbosity_ ) {
337  std::cout << "genEvt (afterFSR):" << std::endl;
338  genEvt_afterFSR->print(std::cout);
339  }
340 
341  // find lowest energy muon
342  // (= muon after FSR)
343  reco::Candidate::LorentzVector muonP4afterFSR = muonP4;
344  for ( HepMC::GenEvent::particle_iterator genParticle = genEvt_afterFSR->particles_begin();
345  genParticle != genEvt_afterFSR->particles_end(); ++genParticle ) {
346  if ( (*genParticle)->pdg_id() == muonPdgId && (*genParticle)->momentum().e() < muonP4afterFSR.E() ) {
347  muonP4afterFSR.SetPxPyPzE(
348  (*genParticle)->momentum().px(),
349  (*genParticle)->momentum().py(),
350  (*genParticle)->momentum().pz(),
351  (*genParticle)->momentum().e());
352  }
353  }
354  reco::Candidate::LorentzVector sumPhotonP4 = muonP4 - muonP4afterFSR;
355  if ( verbosity_ ) {
356  std::cout << "sumPhotons: En = " << sumPhotonP4.E() << ", Pt = " << sumPhotonP4.pt() << ", eta = " << sumPhotonP4.eta() << ", phi = " << sumPhotonP4.phi() << std::endl;
357  }
358 
359  delete genEvt_beforeFSR;
360  if ( genEvt_afterFSR != genEvt_beforeFSR ) delete genEvt_afterFSR;
361 
362  return sumPhotonP4;
363 }
T getParameter(std::string const &) const
math::XYZVector Vector
point in the space
Definition: Candidate.h:47
static HepMC::IO_HEPEVT conv
std::pair< double, double > EBMUP
Definition: LesHouches.h:78
const double protonMass
Definition: V0Fitter.cc:40
GenMuonRadiationAlgorithm(const edm::ParameterSet &)
bool call_pygive(const std::string &line)
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::vector< double > VTIMUP
Definition: LesHouches.h:254
std::pair< int, int > IDBMUP
Definition: LesHouches.h:73
std::pair< double, double > XPDWUP
Definition: LesHouches.h:204
myPythia6ServiceWithCallback(const edm::ParameterSet &cfg)
void photos_(int &)
std::pair< int, int > PDFGUP
Definition: LesHouches.h:84
std::vector< std::pair< int, int > > MOTHUP
Definition: LesHouches.h:236
void call_pylist(int mode)
void resize(int nup)
Definition: LesHouches.h:161
T sqrt(T t)
Definition: SSEVec.h:48
double p4[4]
Definition: TauolaWrapper.h:92
std::vector< FiveVector > PUP
Definition: LesHouches.h:248
static void fillHEPEUP(const HEPEUP *hepeup)
std::vector< double > SPINUP
Definition: LesHouches.h:261
bool isAvailable() const
Definition: Service.h:46
std::vector< int > ISTUP
Definition: LesHouches.h:230
virtual CLHEP::HepRandomEngine & getEngine() const =0
Use this to get the random number engine, this is the only function most users should call...
void call_pyedit(int mode)
std::vector< int > IDUP
Definition: LesHouches.h:225
std::vector< double > XERRUP
Definition: LesHouches.h:114
std::vector< double > XMAXUP
Definition: LesHouches.h:119
double AQCDUP
Definition: LesHouches.h:220
reco::Candidate::LorentzVector compFSR(const reco::Candidate::LorentzVector &, int, const reco::Candidate::LorentzVector &, int &)
std::pair< int, int > PDFSUP
Definition: LesHouches.h:90
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:41
void repairBarcodes(HepMC::GenEvent *)
myPythia6ServiceWithCallback * pythia_
if(dp >Float(M_PI)) dp-
double square(const double a)
void setEvent(const HepMC::GenEvent *genEvt)
tuple cout
Definition: gather_cfg.py:121
double AQEDUP
Definition: LesHouches.h:215
Definition: DDAxes.h:10
CLHEP::HepRandomEngine * decayRandomEngine
std::vector< double > XSECUP
Definition: LesHouches.h:108
double XWGTUP
Definition: LesHouches.h:196
std::vector< std::pair< int, int > > ICOLUP
Definition: LesHouches.h:242
static void fillHEPRUP(const HEPRUP *heprup)
HepMC::GenEvent * apply(HepMC::GenEvent *)
std::vector< int > LPRUP
Definition: LesHouches.h:124
double SCALUP
Definition: LesHouches.h:210