CMS 3D CMS Logo

LHEEvent.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <iomanip>
3 #include <iostream>
4 #include <memory>
5 
6 #include <cmath>
7 #include <cstring>
8 #include <memory>
9 #include <sstream>
10 #include <string>
11 #include <vector>
12 
13 #include "HepMC/GenEvent.h"
14 #include "HepMC/GenVertex.h"
15 #include "HepMC/GenParticle.h"
16 #include "HepMC/SimpleVector.h"
17 
19 
21 
24 
25 static int skipWhitespace(std::istream &in) {
26  int ch;
27  do {
28  ch = in.get();
29  } while (std::isspace(ch));
30  if (ch != std::istream::traits_type::eof())
31  in.putback(ch);
32  return ch;
33 }
34 
35 namespace lhef {
36 
37  LHEEvent::LHEEvent(const std::shared_ptr<LHERunInfo> &runInfo, std::istream &in)
38  : runInfo(runInfo),
39  weights_(0),
40  counted(false),
41  readAttemptCounter(0),
42  npLO_(-99),
43  npNLO_(-99)
44 
45  {
46  hepeup.NUP = 0;
47  hepeup.XPDWUP.first = hepeup.XPDWUP.second = 0.0;
48 
50  if (!in.good())
51  throw cms::Exception("InvalidFormat") << "Les Houches file contained invalid"
52  " event header."
53  << std::endl;
54 
55  // store the original value of XWGTUP for the user
57 
58  int idwtup = runInfo->getHEPRUP()->IDWTUP;
59  if (idwtup >= 0 && hepeup.XWGTUP < 0) {
60  edm::LogWarning("Generator|LHEInterface") << "Non-allowed negative event weight encountered." << std::endl;
62  }
63 
64  if (std::abs(idwtup) == 3 && std::abs(hepeup.XWGTUP) != 1.) {
65  edm::LogInfo("Generator|LHEInterface") << "Event weight not set to one for abs(IDWTUP) == 3" << std::endl;
66  hepeup.XWGTUP = hepeup.XWGTUP > 0. ? 1.0 : -1.0;
67  }
68 
69  hepeup.resize();
70 
71  for (int i = 0; i < hepeup.NUP; i++) {
72  in >> hepeup.IDUP[i] >> hepeup.ISTUP[i] >> hepeup.MOTHUP[i].first >> hepeup.MOTHUP[i].second >>
73  hepeup.ICOLUP[i].first >> hepeup.ICOLUP[i].second >> hepeup.PUP[i][0] >> hepeup.PUP[i][1] >>
74  hepeup.PUP[i][2] >> hepeup.PUP[i][3] >> hepeup.PUP[i][4] >> hepeup.VTIMUP[i] >> hepeup.SPINUP[i];
75  if (!in.good())
76  throw cms::Exception("InvalidFormat") << "Les Houches file contained invalid event"
77  " in particle line "
78  << (i + 1) << "." << std::endl;
79  }
80 
81  while (skipWhitespace(in) == '#') {
83  std::getline(in, line);
84  std::istringstream ss(line);
86  ss >> tag;
87  if (tag == "#pdf") {
88  pdf = std::make_unique<PDF>();
89  ss >> pdf->id.first >> pdf->id.second >> pdf->x.first >> pdf->x.second >> pdf->scalePDF >> pdf->xPDF.first >>
90  pdf->xPDF.second;
91  if (ss.bad()) {
92  edm::LogWarning("Generator|LHEInterface") << "Les Houches event contained"
93  " unparseable PDF information."
94  << std::endl;
95  pdf.reset();
96  } else
97  continue;
98  }
99  comments.push_back(line + "\n");
100  }
101 
102  if (!in.eof())
103  edm::LogWarning("Generator|LHEInterface") << "Les Houches file contained spurious"
104  " content after event data."
105  << std::endl;
106  }
107 
108  LHEEvent::LHEEvent(const std::shared_ptr<LHERunInfo> &runInfo, const HEPEUP &hepeup)
109  : runInfo(runInfo), hepeup(hepeup), counted(false), readAttemptCounter(0), npLO_(-99), npNLO_(-99) {}
110 
111  LHEEvent::LHEEvent(const std::shared_ptr<LHERunInfo> &runInfo,
112  const HEPEUP &hepeup,
113  const LHEEventProduct::PDF *pdf,
114  const std::vector<std::string> &comments)
115  : runInfo(runInfo),
116  hepeup(hepeup),
117  pdf(pdf ? new PDF(*pdf) : nullptr),
118  comments(comments),
119  counted(false),
120  readAttemptCounter(0),
121  npLO_(-99),
122  npNLO_(-99) {}
123 
124  LHEEvent::LHEEvent(const std::shared_ptr<LHERunInfo> &runInfo, const LHEEventProduct &product)
125  : runInfo(runInfo),
126  hepeup(product.hepeup()),
127  pdf(product.pdf() ? new PDF(*product.pdf()) : nullptr),
128  weights_(product.weights()),
129  comments(product.comments_begin(), product.comments_end()),
130  counted(false),
131  readAttemptCounter(0),
132  originalXWGTUP_(product.originalXWGTUP()),
133  scales_(product.scales()),
134  npLO_(product.npLO()),
135  npNLO_(product.npNLO()) {}
136 
138 
139  void LHEEvent::removeParticle(HEPEUP &hepeup, int index) {
140  index--;
141  if (index < 0 || index >= hepeup.NUP) {
142  edm::LogError("Generator|LHEInterface")
143  << "removeParticle: Index " << (index + 1) << " out of bounds." << std::endl;
144  return;
145  }
146 
147  std::pair<int, int> mo = hepeup.MOTHUP[index];
148 
149  hepeup.IDUP.erase(hepeup.IDUP.begin() + index);
150  hepeup.ISTUP.erase(hepeup.ISTUP.begin() + index);
151  hepeup.MOTHUP.erase(hepeup.MOTHUP.begin() + index);
152  hepeup.ICOLUP.erase(hepeup.ICOLUP.begin() + index);
153  hepeup.PUP.erase(hepeup.PUP.begin() + index);
154  hepeup.VTIMUP.erase(hepeup.VTIMUP.begin() + index);
155  hepeup.SPINUP.erase(hepeup.SPINUP.begin() + index);
156 
157  hepeup.NUP--;
158 
159  index++;
160  for (int i = 0; i < hepeup.NUP; i++) {
161  if (hepeup.MOTHUP[i].first == index) {
162  if (hepeup.MOTHUP[i].second > 0)
163  edm::LogError("Generator|LHEInterface")
164  << "removeParticle: Particle " << (i + 2) << " has two mothers." << std::endl;
165  hepeup.MOTHUP[i] = mo;
166  }
167 
168  if (hepeup.MOTHUP[i].first > index)
169  hepeup.MOTHUP[i].first--;
170  if (hepeup.MOTHUP[i].second > index)
171  hepeup.MOTHUP[i].second--;
172  }
173  }
174 
175  void LHEEvent::removeResonances(const std::vector<int> &ids) {
176  for (int i = 1; i <= hepeup.NUP; i++) {
177  int id = std::abs(hepeup.IDUP[i - 1]);
178  if (hepeup.MOTHUP[i - 1].first > 0 && hepeup.MOTHUP[i - 1].second > 0 &&
179  std::find(ids.begin(), ids.end(), id) != ids.end())
180  removeParticle(hepeup, i--);
181  }
182  }
183 
184  void LHEEvent::count(LHERunInfo::CountMode mode, double weight, double matchWeight) {
185  if (counted)
186  edm::LogWarning("Generator|LHEInterface") << "LHEEvent::count called twice on same event!" << std::endl;
187 
188  runInfo->count(hepeup.IDPRUP, mode, hepeup.XWGTUP, weight, matchWeight);
189 
190  counted = true;
191  }
192 
193  void LHEEvent::fillPdfInfo(HepMC::PdfInfo *info) const {
194  if (pdf.get()) {
195  info->set_id1(pdf->id.first);
196  info->set_id2(pdf->id.second);
197  info->set_x1(pdf->x.first);
198  info->set_x2(pdf->x.second);
199  info->set_pdf1(pdf->xPDF.first);
200  info->set_pdf2(pdf->xPDF.second);
201  info->set_scalePDF(pdf->scalePDF);
202  } else if (hepeup.NUP >= 2) {
203  const HEPRUP *heprup = getHEPRUP();
204  info->set_id1(hepeup.IDUP[0] == 21 ? 0 : hepeup.IDUP[0]);
205  info->set_id2(hepeup.IDUP[1] == 21 ? 0 : hepeup.IDUP[1]);
206  info->set_x1(std::abs(hepeup.PUP[0][2] / heprup->EBMUP.first));
207  info->set_x2(std::abs(hepeup.PUP[1][2] / heprup->EBMUP.second));
208  info->set_pdf1(-1.0);
209  info->set_pdf2(-1.0);
210  info->set_scalePDF(hepeup.SCALUP);
211  } else {
212  info->set_x1(-1.0);
213  info->set_x2(-1.0);
214  info->set_pdf1(-1.0);
215  info->set_pdf2(-1.0);
216  info->set_scalePDF(hepeup.SCALUP);
217  }
218  }
219 
221  event->set_signal_process_id(hepeup.IDPRUP);
222  event->set_event_scale(hepeup.SCALUP);
223  event->set_alphaQED(hepeup.AQEDUP);
224  event->set_alphaQCD(hepeup.AQCDUP);
225  }
226 
227  std::unique_ptr<HepMC::GenEvent> LHEEvent::asHepMCEvent() const {
228  std::unique_ptr<HepMC::GenEvent> hepmc(new HepMC::GenEvent);
229 
230  hepmc->set_signal_process_id(hepeup.IDPRUP);
231  hepmc->set_event_scale(hepeup.SCALUP);
232  hepmc->set_alphaQED(hepeup.AQEDUP);
233  hepmc->set_alphaQCD(hepeup.AQCDUP);
234 
235  unsigned int nup = hepeup.NUP; // particles in event
236 
237  // any particles in HEPEUP block?
238  if (!nup) {
239  edm::LogWarning("Generator|LHEInterface") << "Les Houches Event does not contain any partons. "
240  << "Not much to convert.";
241  return hepmc;
242  }
243 
244  // stores (pointers to) converted particles
245  std::vector<HepMC::GenParticle *> genParticles;
246  std::vector<HepMC::GenVertex *> genVertices;
247 
248  // I. convert particles
249  for (unsigned int i = 0; i < nup; i++)
250  genParticles.push_back(makeHepMCParticle(i));
251 
252  // II. loop again to build vertices
253  for (unsigned int i = 0; i < nup; i++) {
254  unsigned int mother1 = hepeup.MOTHUP.at(i).first;
255  unsigned int mother2 = hepeup.MOTHUP.at(i).second;
256  double cTau = hepeup.VTIMUP.at(i); // decay time
257 
258  // current particle has a mother? --- Sorry, parent! We're PC.
259  if (mother1) {
260  mother1--; // FORTRAN notation!
261  if (mother2)
262  mother2--;
263  else
264  mother2 = mother1;
265 
266  HepMC::GenParticle *in_par = genParticles.at(mother1);
267  HepMC::GenVertex *current_vtx = in_par->end_vertex(); // vertex of first mother
268 
269  if (!current_vtx) {
270  current_vtx = new HepMC::GenVertex(HepMC::FourVector(0, 0, 0, cTau));
271 
272  // add vertex to event
273  genVertices.push_back(current_vtx);
274  }
275 
276  for (unsigned int j = mother1; j <= mother2; j++) // set mother-daughter relations
277  if (!genParticles.at(j)->end_vertex())
278  current_vtx->add_particle_in(genParticles.at(j));
279 
280  // connect THIS outgoing particle to current vertex
281  current_vtx->add_particle_out(genParticles.at(i));
282  }
283  }
284 
285  checkHepMCTree(hepmc.get());
286 
287  // III. restore color flow
288  // ok, nobody knows how to do it so far...
289 
290  // IV. fill run information
291  const HEPRUP *heprup = getHEPRUP();
292 
293  // set beam particles
295  HepMC::FourVector(0.0, 0.0, +heprup->EBMUP.first, heprup->EBMUP.first), heprup->IDBMUP.first);
297  HepMC::FourVector(0.0, 0.0, -heprup->EBMUP.second, heprup->EBMUP.second), heprup->IDBMUP.second);
298  b1->set_status(3);
299  b2->set_status(3);
300 
301  HepMC::GenVertex *v1 = new HepMC::GenVertex();
302  HepMC::GenVertex *v2 = new HepMC::GenVertex();
303  v1->add_particle_in(b1);
304  v2->add_particle_in(b2);
305 
306  hepmc->add_vertex(v1);
307  hepmc->add_vertex(v2);
308  hepmc->set_beam_particles(b1, b2);
309 
310  // first two particles have to be the hard partons going into the interaction
311  if (genParticles.size() >= 2) {
312  if (!genParticles.at(0)->production_vertex() && !genParticles.at(1)->production_vertex()) {
313  v1->add_particle_out(genParticles.at(0));
314  v2->add_particle_out(genParticles.at(1));
315  } else
316  edm::LogWarning("Generator|LHEInterface") << "Initial partons do already have a"
317  " production vertex. "
318  << std::endl
319  << "Beam particles not connected.";
320  } else
321  edm::LogWarning("Generator|LHEInterface") << "Can't find any initial partons to be"
322  " connected to the beam particles.";
323 
324  for (std::vector<HepMC::GenVertex *>::const_iterator iter = genVertices.begin(); iter != genVertices.end(); ++iter)
325  hepmc->add_vertex(*iter);
326 
327  // do some more consistency checks
328  for (unsigned int i = 0; i < nup; i++) {
329  if (!genParticles.at(i)->parent_event()) {
330  edm::LogWarning("Generator|LHEInterface") << "Not all LHE particles could be stored"
331  " stored in the HepMC event. "
332  << std::endl
333  << "Check the mother-daughter relations"
334  " in the given LHE input file.";
335  break;
336  }
337  }
338 
339  hepmc->set_signal_process_vertex(const_cast<HepMC::GenVertex *>(findSignalVertex(hepmc.get(), false)));
340 
341  return hepmc;
342  }
343 
345  HepMC::GenParticle *particle = new HepMC::GenParticle(
346  HepMC::FourVector(hepeup.PUP.at(i)[0], hepeup.PUP.at(i)[1], hepeup.PUP.at(i)[2], hepeup.PUP.at(i)[3]),
347  hepeup.IDUP.at(i));
348 
349  int status = hepeup.ISTUP.at(i);
350 
351  particle->set_generated_mass(hepeup.PUP.at(i)[4]);
352  particle->set_status(status > 0 ? (status == 2 ? 3 : status) : 3);
353 
354  return particle;
355  }
356 
358  double px = 0, py = 0, pz = 0, E = 0;
359 
360  for (HepMC::GenEvent::particle_const_iterator iter = event->particles_begin(); iter != event->particles_end();
361  iter++) {
362  int status = (*iter)->status();
363  HepMC::FourVector fv = (*iter)->momentum();
364 
365  // incoming particles
366  if (status == 3 && *iter != event->beam_particles().first && *iter != event->beam_particles().second) {
367  px -= fv.px();
368  py -= fv.py();
369  pz -= fv.pz();
370  E -= fv.e();
371  }
372 
373  // outgoing particles
374  if (status == 1) {
375  px += fv.px();
376  py += fv.py();
377  pz += fv.pz();
378  E += fv.e();
379  }
380  }
381 
382  if (px * px + py * py + pz * pz + E * E > 0.1) {
383  edm::LogWarning("Generator|LHEInterface")
384  << "Energy-momentum badly conserved. " << std::setprecision(3) << "sum p_i = [" << std::setw(7) << E << ", "
385  << std::setw(7) << px << ", " << std::setw(7) << py << ", " << std::setw(7) << pz << "]";
386 
387  return false;
388  }
389 
390  return true;
391  }
392 
393  const HepMC::GenVertex *LHEEvent::findSignalVertex(const HepMC::GenEvent *event, bool status3) {
394  double largestMass2 = -9.0e-30;
395  const HepMC::GenVertex *vertex = nullptr;
396  for (HepMC::GenEvent::vertex_const_iterator iter = event->vertices_begin(); iter != event->vertices_end(); ++iter) {
397  if ((*iter)->particles_in_size() < 2)
398  continue;
399  if ((*iter)->particles_out_size() < 1 ||
400  ((*iter)->particles_out_size() == 1 &&
401  (!(*(*iter)->particles_out_const_begin())->end_vertex() ||
402  !(*(*iter)->particles_out_const_begin())->end_vertex()->particles_out_size())))
403  continue;
404 
405  double px = 0.0, py = 0.0, pz = 0.0, E = 0.0;
406  bool hadStatus3 = false;
407  for (HepMC::GenVertex::particles_out_const_iterator iter2 = (*iter)->particles_out_const_begin();
408  iter2 != (*iter)->particles_out_const_end();
409  ++iter2) {
410  hadStatus3 = hadStatus3 || (*iter2)->status() == 3;
411  px += (*iter2)->momentum().px();
412  py += (*iter2)->momentum().py();
413  pz += (*iter2)->momentum().pz();
414  E += (*iter2)->momentum().e();
415  }
416  if (status3 && !hadStatus3)
417  continue;
418 
419  double mass2 = E * E - (px * px + py * py + pz * pz);
420  if (mass2 > largestMass2) {
421  vertex = *iter;
422  largestMass2 = mass2;
423  }
424  }
425 
426  return vertex;
427  }
428 
429  static void fixSubTree(HepMC::GenVertex *vertex,
430  HepMC::FourVector &_time,
431  std::set<const HepMC::GenVertex *> &visited) {
432  HepMC::FourVector time = _time;
433  HepMC::FourVector curTime = vertex->position();
434  bool needsFixup = curTime.t() < time.t();
435 
436  if (!visited.insert(vertex).second && !needsFixup)
437  return;
438 
439  if (needsFixup)
440  vertex->set_position(time);
441  else
442  time = curTime;
443 
444  for (HepMC::GenVertex::particles_out_const_iterator iter = vertex->particles_out_const_begin();
445  iter != vertex->particles_out_const_end();
446  ++iter) {
447  HepMC::GenVertex *endVertex = (*iter)->end_vertex();
448  if (endVertex)
449  fixSubTree(endVertex, time, visited);
450  }
451  }
452 
454  std::set<const HepMC::GenVertex *> visited;
455  HepMC::FourVector zeroTime;
456  for (HepMC::GenEvent::vertex_iterator iter = event->vertices_begin(); iter != event->vertices_end(); ++iter)
457  fixSubTree(*iter, zeroTime, visited);
458  }
459 
460 } // namespace lhef
HEPEUP hepeup
Definition: LHEEvent.h:86
static const TGPicture * info(bool iBackgroundIsBlack)
double cTau(int pdgID, const HepPDT::ParticleDataTable *pdt)
LHEEvent(const std::shared_ptr< LHERunInfo > &runInfo, std::istream &in)
Definition: LHEEvent.cc:37
std::vector< std::string > comments
Definition: LHEEvent.h:89
std::vector< std::pair< int, int > > ICOLUP
Definition: LesHouches.h:240
std::pair< double, double > EBMUP
Definition: LesHouches.h:82
const std::shared_ptr< LHERunInfo > runInfo
Definition: LHEEvent.h:84
static void fixHepMCEventTimeOrdering(HepMC::GenEvent *event)
Definition: LHEEvent.cc:453
void removeResonances(const std::vector< int > &ids)
Definition: LHEEvent.cc:175
Definition: weight.py:1
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
Definition: LHEEvent.cc:184
std::vector< double > VTIMUP
Definition: LesHouches.h:252
Log< level::Error, false > LogError
std::pair< double, double > XPDWUP
Definition: LesHouches.h:202
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
std::unique_ptr< HepMC::GenEvent > asHepMCEvent() const
Definition: LHEEvent.cc:227
void fillEventInfo(HepMC::GenEvent *hepmc) const
Definition: LHEEvent.cc:220
void resize(int nup)
Definition: LesHouches.h:161
static void removeParticle(lhef::HEPEUP &hepeup, int index)
Definition: LHEEvent.cc:139
std::vector< FiveVector > PUP
Definition: LesHouches.h:246
std::vector< double > SPINUP
Definition: LesHouches.h:259
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< int > ISTUP
Definition: LesHouches.h:228
const HEPRUP * getHEPRUP() const
Definition: LHEEvent.h:39
std::vector< std::pair< int, int > > MOTHUP
Definition: LesHouches.h:234
std::vector< int > IDUP
Definition: LesHouches.h:223
Log< level::Info, false > LogInfo
double AQCDUP
Definition: LesHouches.h:218
void fillPdfInfo(HepMC::PdfInfo *info) const
Definition: LHEEvent.cc:193
static void fixSubTree(HepMC::GenVertex *vertex, HepMC::FourVector &_time, std::set< const HepMC::GenVertex *> &visited)
Definition: LHEEvent.cc:429
HepMC::GenParticle * makeHepMCParticle(unsigned int i) const
Definition: LHEEvent.cc:344
static const HepMC::GenVertex * findSignalVertex(const HepMC::GenEvent *event, bool status3=true)
Definition: LHEEvent.cc:393
std::unique_ptr< PDF > pdf
Definition: LHEEvent.h:87
bool counted
Definition: LHEEvent.h:90
double AQEDUP
Definition: LesHouches.h:213
static bool checkHepMCTree(const HepMC::GenEvent *event)
Definition: LHEEvent.cc:357
VertexRefVector::iterator vertex_iterator
iterator over a vector of references to Vertex objects in the same collection
Definition: VertexFwd.h:19
Log< level::Warning, false > LogWarning
static constexpr float b2
static int skipWhitespace(std::istream &in)
Definition: LHEEvent.cc:25
double XWGTUP
Definition: LesHouches.h:194
static constexpr float b1
Definition: event.py:1
double originalXWGTUP_
Definition: LHEEvent.h:92
double SCALUP
Definition: LesHouches.h:208