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