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