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