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)
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 {
120 }
121 
122 LHEEvent::LHEEvent(const boost::shared_ptr<LHERunInfo> &runInfo,
123  const HEPEUP &hepeup,
124  const LHEEventProduct::PDF *pdf,
125  const std::vector<std::string> &comments) :
126  runInfo(runInfo), hepeup(hepeup), pdf(pdf ? new PDF(*pdf) : 0),
127  comments(comments), counted(false), readAttemptCounter(0)
128 {
129 }
130 
131 LHEEvent::LHEEvent(const boost::shared_ptr<LHERunInfo> &runInfo,
132  const LHEEventProduct &product) :
133  runInfo(runInfo), hepeup(product.hepeup()),
134  pdf(product.pdf() ? new PDF(*product.pdf()) : 0),
135  weights_(product.weights()),
136  comments(product.comments_begin(), product.comments_end()),
137  counted(false), readAttemptCounter(0)
138 {
139 }
140 
142 {
143 }
144 
145 template<typename T>
146 static inline void pop(std::vector<T> &vec, unsigned int index)
147 {
148  unsigned int size = vec.size() - 1;
149  std::memmove(&vec[index], &vec[index + 1], (size - index) * sizeof(T));
150 }
151 
153 {
154  index--;
155  if (index < 0 || index >= hepeup.NUP) {
156  edm::LogError("Generator|LHEInterface")
157  << "removeParticle: Index " << (index + 1)
158  << " out of bounds." << std::endl;
159  return;
160  }
161 
162  std::pair<int, int> mo = hepeup.MOTHUP[index];
163 
164  pop(hepeup.IDUP, index);
165  pop(hepeup.ISTUP, index);
166  pop(hepeup.MOTHUP, index);
167  pop(hepeup.ICOLUP, index);
168  pop(hepeup.PUP, index);
169  pop(hepeup.VTIMUP, index);
170  pop(hepeup.SPINUP, index);
171  hepeup.NUP--;
172  hepeup.resize();
173 
174  index++;
175  for(int i = 0; i < hepeup.NUP; i++) {
176  if (hepeup.MOTHUP[i].first == index) {
177  if (hepeup.MOTHUP[i].second > 0)
178  edm::LogError("Generator|LHEInterface")
179  << "removeParticle: Particle "
180  << (i + 2) << " has two mothers."
181  << std::endl;
182  hepeup.MOTHUP[i] = mo;
183  }
184 
185  if (hepeup.MOTHUP[i].first > index)
186  hepeup.MOTHUP[i].first--;
187  if (hepeup.MOTHUP[i].second > index)
188  hepeup.MOTHUP[i].second--;
189  }
190 }
191 
192 void LHEEvent::removeResonances(const std::vector<int> &ids)
193 {
194  for(int i = 1; i <= hepeup.NUP; i++) {
195  int id = std::abs(hepeup.IDUP[i - 1]);
196  if (hepeup.MOTHUP[i - 1].first > 0 &&
197  hepeup.MOTHUP[i - 1].second > 0 &&
198  std::find(ids.begin(), ids.end(), id) != ids.end())
199  removeParticle(hepeup, i--);
200  }
201 }
202 
204  double weight, double matchWeight)
205 {
206  if (counted)
207  edm::LogWarning("Generator|LHEInterface")
208  << "LHEEvent::count called twice on same event!"
209  << std::endl;
210 
211  runInfo->count(hepeup.IDPRUP, mode, hepeup.XWGTUP,
212  weight, matchWeight);
213 
214  counted = true;
215 }
216 
217 void LHEEvent::fillPdfInfo(HepMC::PdfInfo *info) const
218 {
219  if (pdf.get()) {
220  info->set_id1(pdf->id.first);
221  info->set_id2(pdf->id.second);
222  info->set_x1(pdf->x.first);
223  info->set_x2(pdf->x.second);
224  info->set_pdf1(pdf->xPDF.first);
225  info->set_pdf2(pdf->xPDF.second);
226  info->set_scalePDF(pdf->scalePDF);
227  } else if (hepeup.NUP >= 2) {
228  const HEPRUP *heprup = getHEPRUP();
229  info->set_id1(hepeup.IDUP[0] == 21 ? 0 : hepeup.IDUP[0]);
230  info->set_id2(hepeup.IDUP[1] == 21 ? 0 : hepeup.IDUP[1]);
231  info->set_x1(std::abs(hepeup.PUP[0][2] / heprup->EBMUP.first));
232  info->set_x2(std::abs(hepeup.PUP[1][2] / heprup->EBMUP.second));
233  info->set_pdf1(-1.0);
234  info->set_pdf2(-1.0);
235  info->set_scalePDF(hepeup.SCALUP);
236  } else {
237  info->set_x1(-1.0);
238  info->set_x2(-1.0);
239  info->set_pdf1(-1.0);
240  info->set_pdf2(-1.0);
241  info->set_scalePDF(hepeup.SCALUP);
242  }
243 }
244 
245 void LHEEvent::fillEventInfo(HepMC::GenEvent *event) const
246 {
247  event->set_signal_process_id(hepeup.IDPRUP);
248  event->set_event_scale(hepeup.SCALUP);
249  event->set_alphaQED(hepeup.AQEDUP);
250  event->set_alphaQCD(hepeup.AQCDUP);
251 }
252 
253 std::auto_ptr<HepMC::GenEvent> LHEEvent::asHepMCEvent() const
254 {
255  std::auto_ptr<HepMC::GenEvent> hepmc(new HepMC::GenEvent);
256 
257  hepmc->set_signal_process_id(hepeup.IDPRUP);
258  hepmc->set_event_scale(hepeup.SCALUP);
259  hepmc->set_alphaQED(hepeup.AQEDUP);
260  hepmc->set_alphaQCD(hepeup.AQCDUP);
261 
262  unsigned int nup = hepeup.NUP; // particles in event
263 
264  // any particles in HEPEUP block?
265  if (!nup) {
266  edm::LogWarning("Generator|LHEInterface")
267  << "Les Houches Event does not contain any partons. "
268  << "Not much to convert." ;
269  return hepmc;
270  }
271 
272  // stores (pointers to) converted particles
273  std::vector<HepMC::GenParticle*> genParticles;
274  std::vector<HepMC::GenVertex*> genVertices;
275 
276  // I. convert particles
277  for(unsigned int i = 0; i < nup; i++)
278  genParticles.push_back(makeHepMCParticle(i));
279 
280  // II. loop again to build vertices
281  for(unsigned int i = 0; i < nup; i++) {
282  unsigned int mother1 = hepeup.MOTHUP.at(i).first;
283  unsigned int mother2 = hepeup.MOTHUP.at(i).second;
284  double cTau = hepeup.VTIMUP.at(i); // decay time
285 
286  // current particle has a mother? --- Sorry, parent! We're PC.
287  if (mother1) {
288  mother1--; // FORTRAN notation!
289  if (mother2)
290  mother2--;
291  else
292  mother2 = mother1;
293 
294  HepMC::GenParticle *in_par = genParticles.at(mother1);
295  HepMC::GenVertex *current_vtx = in_par->end_vertex(); // vertex of first mother
296 
297  if (!current_vtx) {
298  current_vtx = new HepMC::GenVertex(
299  HepMC::FourVector(0, 0, 0, cTau));
300 
301  // add vertex to event
302  genVertices.push_back(current_vtx);
303  }
304 
305  for(unsigned int j = mother1; j <= mother2; j++) // set mother-daughter relations
306  if (!genParticles.at(j)->end_vertex())
307  current_vtx->add_particle_in(genParticles.at(j));
308 
309  // connect THIS outgoing particle to current vertex
310  current_vtx->add_particle_out(genParticles.at(i));
311  }
312  }
313 
314  checkHepMCTree(hepmc.get());
315 
316  // III. restore color flow
317  // ok, nobody knows how to do it so far...
318 
319  // IV. fill run information
320  const HEPRUP *heprup = getHEPRUP();
321 
322  // set beam particles
324  HepMC::FourVector(0.0, 0.0, +heprup->EBMUP.first,
325  heprup->EBMUP.first),
326  heprup->IDBMUP.first);
328  HepMC::FourVector(0.0, 0.0, -heprup->EBMUP.second,
329  heprup->EBMUP.second),
330  heprup->IDBMUP.second);
331  b1->set_status(3);
332  b2->set_status(3);
333 
334  HepMC::GenVertex *v1 = new HepMC::GenVertex();
335  HepMC::GenVertex *v2 = new HepMC::GenVertex();
336  v1->add_particle_in(b1);
337  v2->add_particle_in(b2);
338 
339  hepmc->add_vertex(v1);
340  hepmc->add_vertex(v2);
341  hepmc->set_beam_particles(b1, b2);
342 
343  // first two particles have to be the hard partons going into the interaction
344  if (genParticles.size() >= 2) {
345  if (!genParticles.at(0)->production_vertex() &&
346  !genParticles.at(1)->production_vertex()) {
347  v1->add_particle_out(genParticles.at(0));
348  v2->add_particle_out(genParticles.at(1));
349  } else
350  edm::LogWarning("Generator|LHEInterface")
351  << "Initial partons do already have a"
352  " production vertex. " << std::endl
353  << "Beam particles not connected.";
354  } else
355  edm::LogWarning("Generator|LHEInterface")
356  << "Can't find any initial partons to be"
357  " connected to the beam particles.";
358 
359  for(std::vector<HepMC::GenVertex*>::const_iterator iter = genVertices.begin();
360  iter != genVertices.end(); ++iter)
361  hepmc->add_vertex(*iter);
362 
363  // do some more consistency checks
364  for(unsigned int i = 0; i < nup; i++) {
365  if (!genParticles.at(i)->parent_event()) {
366  edm::LogWarning("Generator|LHEInterface")
367  << "Not all LHE particles could be stored"
368  " stored in the HepMC event. "
369  << std::endl
370  << "Check the mother-daughter relations"
371  " in the given LHE input file.";
372  break;
373  }
374  }
375 
376  hepmc->set_signal_process_vertex(
377  const_cast<HepMC::GenVertex*>(
378  findSignalVertex(hepmc.get(), false)));
379 
380  return hepmc;
381 }
382 
384 {
385  HepMC::GenParticle *particle = new HepMC::GenParticle(
386  HepMC::FourVector(hepeup.PUP.at(i)[0],
387  hepeup.PUP.at(i)[1],
388  hepeup.PUP.at(i)[2],
389  hepeup.PUP.at(i)[3]),
390  hepeup.IDUP.at(i));
391 
392  int status = hepeup.ISTUP.at(i);
393 
394  particle->set_generated_mass(hepeup.PUP.at(i)[4]);
395  particle->set_status(status > 0 ? (status == 2 ? 3 : status) : 3);
396 
397  return particle;
398 }
399 
400 bool LHEEvent::checkHepMCTree(const HepMC::GenEvent *event)
401 {
402  double px = 0, py = 0, pz = 0, E = 0;
403 
404  for(HepMC::GenEvent::particle_const_iterator iter = event->particles_begin();
405  iter != event->particles_end(); iter++) {
406  int status = (*iter)->status();
407  HepMC::FourVector fv = (*iter)->momentum();
408 
409  // incoming particles
410  if (status == 3 &&
411  *iter != event->beam_particles().first &&
412  *iter != event->beam_particles().second) {
413  px -= fv.px();
414  py -= fv.py();
415  pz -= fv.pz();
416  E -= fv.e();
417  }
418 
419  // outgoing particles
420  if (status == 1) {
421  px += fv.px();
422  py += fv.py();
423  pz += fv.pz();
424  E += fv.e();
425  }
426  }
427 
428  if (px*px + py*py + pz*pz + E*E > 0.1) {
429  edm::LogWarning("Generator|LHEInterface")
430  << "Energy-momentum badly conserved. "
431  << std::setprecision(3)
432  << "sum p_i = ["
433  << std::setw(7) << E << ", "
434  << std::setw(7) << px << ", "
435  << std::setw(7) << py << ", "
436  << std::setw(7) << pz << "]";
437 
438  return false;
439  }
440 
441  return true;
442 }
443 
444 const HepMC::GenVertex *LHEEvent::findSignalVertex(
445  const HepMC::GenEvent *event, bool status3)
446 {
447  double largestMass2 = -9.0e-30;
448  const HepMC::GenVertex *vertex = 0;
449  for(HepMC::GenEvent::vertex_const_iterator iter = event->vertices_begin();
450  iter != event->vertices_end(); ++iter) {
451  if ((*iter)->particles_in_size() < 2)
452  continue;
453  if ((*iter)->particles_out_size() < 1 ||
454  ((*iter)->particles_out_size() == 1 &&
455  (!(*(*iter)->particles_out_const_begin())->end_vertex() ||
456  !(*(*iter)->particles_out_const_begin())
457  ->end_vertex()->particles_out_size())))
458  continue;
459 
460  double px = 0.0, py = 0.0, pz = 0.0, E = 0.0;
461  bool hadStatus3 = false;
462  for(HepMC::GenVertex::particles_out_const_iterator iter2 =
463  (*iter)->particles_out_const_begin();
464  iter2 != (*iter)->particles_out_const_end(); ++iter2) {
465  hadStatus3 = hadStatus3 || (*iter2)->status() == 3;
466  px += (*iter2)->momentum().px();
467  py += (*iter2)->momentum().py();
468  pz += (*iter2)->momentum().pz();
469  E += (*iter2)->momentum().e();
470  }
471  if (status3 && !hadStatus3)
472  continue;
473 
474  double mass2 = E * E - (px * px + py * py + pz * pz);
475  if (mass2 > largestMass2) {
476  vertex = *iter;
477  largestMass2 = mass2;
478  }
479  }
480 
481  return vertex;
482 }
483 
484 static void fixSubTree(HepMC::GenVertex *vertex,
485  HepMC::FourVector& _time,
486  std::set<const HepMC::GenVertex*> &visited)
487 {
488  HepMC::FourVector time = _time;
489  HepMC::FourVector curTime = vertex->position();
490  bool needsFixup = curTime.t() < time.t();
491 
492  if (!visited.insert(vertex).second && !needsFixup)
493  return;
494 
495  if (needsFixup)
496  vertex->set_position(time);
497  else
498  time = curTime;
499 
500  for(HepMC::GenVertex::particles_out_const_iterator iter =
501  vertex->particles_out_const_begin();
502  iter != vertex->particles_out_const_end(); ++iter) {
503  HepMC::GenVertex *endVertex = (*iter)->end_vertex();
504  if (endVertex)
505  fixSubTree(endVertex, time, visited);
506  }
507 }
508 
510 {
511  std::set<const HepMC::GenVertex*> visited;
512  HepMC::FourVector zeroTime;
513  for(HepMC::GenEvent::vertex_iterator iter = event->vertices_begin();
514  iter != event->vertices_end(); ++iter)
515  fixSubTree(*iter, zeroTime, visited);
516 }
517 
518 } // namespace lhef
static void fixSubTree(HepMC::GenVertex *vertex, HepMC::FourVector &_time, std::set< const HepMC::GenVertex * > &visited)
Definition: LHEEvent.cc:484
int i
Definition: DBlmapReader.cc:9
HEPEUP hepeup
Definition: LHEEvent.h:81
static const TGPicture * info(bool iBackgroundIsBlack)
std::vector< std::string > comments
Definition: LHEEvent.h:84
const HEPRUP * getHEPRUP() const
Definition: LHEEvent.h:44
void fillEventInfo(HepMC::GenEvent *hepmc) const
Definition: LHEEvent.cc:245
std::pair< double, double > EBMUP
Definition: LesHouches.h:78
static void fixHepMCEventTimeOrdering(HepMC::GenEvent *event)
Definition: LHEEvent.cc:509
void removeResonances(const std::vector< int > &ids)
Definition: LHEEvent.cc:192
void count(LHERunInfo::CountMode count, double weight=1.0, double matchWeight=1.0)
Definition: LHEEvent.cc:203
std::vector< double > VTIMUP
Definition: LesHouches.h:254
static void pop(std::vector< T > &vec, unsigned int index)
Definition: LHEEvent.cc:146
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:82
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:79
HepMC::GenParticle * makeHepMCParticle(unsigned int i) const
Definition: LHEEvent.cc:383
static void removeParticle(lhef::HEPEUP &hepeup, int index)
Definition: LHEEvent.cc:152
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:217
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:444
bool counted
Definition: LHEEvent.h:85
double AQEDUP
Definition: LesHouches.h:215
static bool checkHepMCTree(const HepMC::GenEvent *event)
Definition: LHEEvent.cc:400
std::auto_ptr< HepMC::GenEvent > asHepMCEvent() const
Definition: LHEEvent.cc:253
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
int weight
Definition: histoStyle.py:50
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:87
double SCALUP
Definition: LesHouches.h:210