CMS 3D CMS Logo

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