StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
LHEF3.cc
1 // LHEF3.cc is a part of the PYTHIA event generator.
2 // Copyright (C) 2018 Torbjorn Sjostrand.
3 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
4 // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 
6 // This file is written by Stefan Prestel.
7 // It contains the main class for LHEF 3.0 functionalities.
8 // Function definitions.
9 
10 #include "Pythia8/LHEF3.h"
11 
12 namespace Pythia8 {
13 
14 //==========================================================================
15 
16 // The XMLTag struct is used to represent all information within an XML tag.
17 // It contains the attributes as a map, any sub-tags as a vector of pointers
18 // to other XMLTag objects, and any other information as a single string.
19 
20 //--------------------------------------------------------------------------
21 
22 // Constants.
23 const XMLTag::pos_t XMLTag::end = string::npos;
24 
25 //==========================================================================
26 
27 // The LHAweights struct.
28 
29 //--------------------------------------------------------------------------
30 
31 // Construct from XML tag.
32 
33 LHAweights::LHAweights(const XMLTag & tag) {
34  for ( map<string,string>::const_iterator it = tag.attr.begin();
35  it != tag.attr.end(); ++it ) {
36  string v = it->second.c_str();
37  attributes[it->first] = v;
38  }
39 
40  contents = tag.contents;
41 
42  istringstream iss(tag.contents);
43  double w;
44  while ( iss >> w ) weights.push_back(w);
45 }
46 
47 //--------------------------------------------------------------------------
48 
49 // Print out.
50 
51 void LHAweights::list(ostream & file) const {
52  file << "<weights";
53  for ( map<string,string>::const_iterator it = attributes.begin();
54  it != attributes.end(); ++it )
55  file << " " << it->first << "=\"" << it->second << "\"";
56  file << ">";
57  for ( int j = 0, M = weights.size(); j < M; ++j ) file << " " << weights[j];
58  file << "</weights>" << endl;
59 }
60 
61 //==========================================================================
62 
63 // The LHAscales struct: Collect different scales relevant for an event.
64 
65 //--------------------------------------------------------------------------
66 
67 // Construct from an XML-tag.
68 
69 LHAscales::LHAscales(const XMLTag & tag, double defscale)
70  : muf(defscale), mur(defscale), mups(defscale), SCALUP(defscale) {
71  for ( map<string,string>::const_iterator it = tag.attr.begin();
72  it != tag.attr.end(); ++it ) {
73  double v = atof(it->second.c_str());
74  if ( it->first == "muf" ) muf = v;
75  else if ( it->first == "mur" ) mur = v;
76  else if ( it->first == "mups" ) mups = v;
77  else attributes.insert(make_pair(it->first, v));
78  }
79  contents = tag.contents;
80 }
81 
82 //--------------------------------------------------------------------------
83 
84 // Print out the corresponding XML-tag.
85 
86 void LHAscales::list(ostream & file) const {
87  file << "<scales";
88  file << " muf=\"" << muf << "\"";
89  file << " mur=\"" << mur << "\"";
90  file << " mups=\"" << mups << "\"";
91  for ( map<string,double>::const_iterator it = attributes.begin();
92  it != attributes.end(); ++it )
93  file << " " << it->first << "=\"" << it->second << "\"";
94  file << ">" << contents;
95  file << "</scales>" << endl;
96 }
97 
98 //==========================================================================
99 
100 // The LHAgenerator struct: Collect generator information for an event file.
101 
102 //--------------------------------------------------------------------------
103 
104 // Construct from an XML-tag
105 
106 LHAgenerator::LHAgenerator(const XMLTag & tag, string defname)
107  : name(defname), version(defname), contents(defname) {
108  for ( map<string,string>::const_iterator it = tag.attr.begin();
109  it != tag.attr.end(); ++it ) {
110  if ( it->first == "name" ) name = it->second;
111  else if ( it->first == "version" ) version = it->second;
112  else attributes.insert(make_pair(it->first, it->second));
113  }
114  contents = tag.contents;
115 }
116 
117 //--------------------------------------------------------------------------
118 
119 // Print out the corresponding XML-tag.
120 
121 void LHAgenerator::list(ostream & file) const {
122  file << "<generator";
123  if ( name != "" ) file << " name=\"" << name << "\"";
124  if ( version != "" ) file << " version=\"" << version << "\"";
125  for ( map<string,string>::const_iterator it = attributes.begin();
126  it != attributes.end(); ++it )
127  file << " " << it->first << "=\"" << it->second << "\"";
128  file << " >";
129  file << contents;
130  file << "</generator>" << endl;
131 }
132 
133 //==========================================================================
134 
135 // The LHAwgt struct: Collect the wgt information.
136 
137 //--------------------------------------------------------------------------
138 
139 // Construct from an XML-tag
140 
141 LHAwgt::LHAwgt(const XMLTag & tag, double defwgt)
142  : id(""), contents(defwgt) {
143  for ( map<string,string>::const_iterator it = tag.attr.begin();
144  it != tag.attr.end(); ++it ) {
145  if ( it->first == "id" ) id = it->second;
146  else attributes.insert(make_pair(it->first, it->second));
147  }
148  contents = atof(tag.contents.c_str());
149 }
150 
151 //--------------------------------------------------------------------------
152 
153 // Print out the corresponding XML-tag.
154 
155 void LHAwgt::list(ostream & file) const {
156  file << "<wgt";
157  if ( id != "" ) file << " id=\"" << id << "\"";
158  for ( map<string,string>::const_iterator it = attributes.begin();
159  it != attributes.end(); ++it )
160  file << " " << it->first << "=\"" << it->second << "\"";
161  file << " >";
162  file << contents;
163  file << "</wgt>" << endl;
164 }
165 
166 //==========================================================================
167 
168 // The LHAweight struct: Collect the weight information.
169 
170 //--------------------------------------------------------------------------
171 
172 // Construct from an XML-tag.
173 
174 LHAweight::LHAweight(const XMLTag & tag, string defname)
175  : id(defname), contents(defname) {
176  for ( map<string,string>::const_iterator it = tag.attr.begin();
177  it != tag.attr.end(); ++it ) {
178  if ( it->first == "id" ) id = it->second;
179  else attributes.insert(make_pair(it->first, it->second));
180  }
181  contents = tag.contents;
182 }
183 
184 //--------------------------------------------------------------------------
185 
186 // Print out the corresponding XML-tag.
187 
188 void LHAweight::list(ostream & file) const {
189  file << "<weight";
190  if ( id != "" ) file << " id=\"" << id << "\"";
191  for ( map<string,string>::const_iterator it = attributes.begin();
192  it != attributes.end(); ++it )
193  file << " " << it->first << "=\"" << it->second << "\"";
194  file << " >";
195  file << contents;
196  file << "</weight>" << endl;
197 }
198 
199 //==========================================================================
200 
201 // The LHAweightgroup struct: The LHAweightgroup assigns a group-name to a set
202 // of LHAweight objects.
203 
204 //--------------------------------------------------------------------------
205 
206 // Construct a group of LHAweight objects from an XML tag and
207 // insert them in the given vector.
208 
209 LHAweightgroup::LHAweightgroup(const XMLTag & tag) {
210 
211  for ( map<string,string>::const_iterator it = tag.attr.begin();
212  it != tag.attr.end(); ++it ) {
213  if ( it->first == "name" ) name = it->second;
214  else attributes.insert(make_pair(it->first,it->second));
215  }
216  if ( name=="" ) {
217  string key("type");
218  if( attributes.find(key) != attributes.end() ) {
219  name = attributes[key];
220  }
221  }
222 
223  contents = tag.contents;
224 
225  // Now add the weight's step by step.
226  string s;
227  vector<XMLTag*> tags = XMLTag::findXMLTags(tag.contents, &s);
228  for ( int i = 0, N = tags.size(); i < N; ++i ) {
229  const XMLTag & tagnow = *tags[i];
230  LHAweight wt(tagnow);
231  weights.insert(make_pair(wt.id, wt));
232  weightsKeys.push_back(wt.id);
233  }
234  for ( int i = 0, N = tag.tags.size(); i < N; ++i ) {
235  const XMLTag & tagnow = *tag.tags[i];
236  const LHAweight & wt(tagnow);
237  weights.insert(make_pair(wt.id, wt));
238  weightsKeys.push_back(wt.id);
239  }
240 
241  for ( int i = 0, N = tags.size(); i < N; ++i ) if (tags[i]) delete tags[i];
242 
243 }
244 
245 //--------------------------------------------------------------------------
246 
247 // Print out the corresponding XML-tag.
248 
249 void LHAweightgroup::list(ostream & file) const {
250  file << "<weightgroup";
251  if ( name != "" ) file << " name=\"" << name << "\"";
252  for ( map<string,string>::const_iterator it = attributes.begin();
253  it != attributes.end(); ++it )
254  file << " " << it->first << "=\"" << it->second << "\"";
255  file << " >\n";
256  for ( map<string,LHAweight>::const_iterator it = weights.begin();
257  it != weights.end(); ++it ) it->second.list(file);
258  file << "</weightgroup>" << endl;
259 }
260 
261 //==========================================================================
262 
263 // The LHArwgt struct: Assigns a group-name to a set of LHAwgt objects.
264 
265 //--------------------------------------------------------------------------
266 
267 // Construct a group of LHAwgt objects from an XML tag and
268 // insert them in the given vector.
269 
270 LHArwgt::LHArwgt(const XMLTag & tag) {
271 
272  for ( map<string,string>::const_iterator it = tag.attr.begin();
273  it != tag.attr.end(); ++it ) {
274  string v = it->second.c_str();
275  attributes[it->first] = v;
276  }
277  contents = tag.contents;
278 
279  // Now add the wgt's step by step.
280  string s;
281  vector<XMLTag*> tags = XMLTag::findXMLTags(tag.contents, &s);
282  for ( int i = 0, N = tags.size(); i < N; ++i ) {
283  const XMLTag & tagnow = *tags[i];
284  LHAwgt wt(tagnow);
285  wgts.insert(make_pair(wt.id, wt));
286  wgtsKeys.push_back(wt.id);
287  }
288  for ( int i = 0, N = tag.tags.size(); i < N; ++i ) {
289  const XMLTag & tagnow = *tag.tags[i];
290  LHAwgt wt(tagnow);
291  wgts.insert(make_pair(wt.id, wt));
292  wgtsKeys.push_back(wt.id);
293  }
294 
295  for ( int i = 0, N = tags.size(); i < N; ++i ) if (tags[i]) delete tags[i];
296 
297 }
298 
299 //--------------------------------------------------------------------------
300 
301 // Print out the corresponding XML-tag.
302 
303 void LHArwgt::list(ostream & file) const {
304  file << "<rwgt";
305  for ( map<string,string>::const_iterator it = attributes.begin();
306  it != attributes.end(); ++it )
307  file << " " << it->first << "=\"" << it->second << "\"";
308  file << " >\n";
309  for ( map<string,LHAwgt>::const_iterator it = wgts.begin();
310  it != wgts.end(); ++it ) it->second.list(file);
311  file << "</rwgt>" << endl;
312 }
313 
314 //==========================================================================
315 
316 // The LHAinitrwgt assigns a group-name to a set of LHAweightgroup objects.
317 
318 //--------------------------------------------------------------------------
319 
320 // Construct a group of LHAweightgroup objects from an XML tag and
321 // insert them in the given vector.
322 
323 LHAinitrwgt::LHAinitrwgt(const XMLTag & tag) {
324  for ( map<string,string>::const_iterator it = tag.attr.begin();
325  it != tag.attr.end(); ++it ) {
326  string v = it->second.c_str();
327  attributes[it->first] = v;
328  }
329  contents = tag.contents;
330 
331  // Now add the wgt's step by step.
332  string s;
333  vector<XMLTag*> tags = XMLTag::findXMLTags(tag.contents, &s);
334  for ( int i = 0, N = tags.size(); i < N; ++i ) {
335  const XMLTag & tagnow = *tags[i];
336  if ( tagnow.name == "weightgroup" ) {
337  LHAweightgroup wgroup(tagnow);
338  string wgname = wgroup.name;
339  // if still no name, use integer as a key
340  if (wgname=="") {
341  stringstream iss;
342  iss << i;
343  wgname=iss.str();
344  }
345  weightgroups.insert(make_pair(wgname, wgroup));
346  weightgroupsKeys.push_back(wgname);
347  string ss;
348  vector<XMLTag*> tags2 = XMLTag::findXMLTags(tagnow.contents, &ss);
349  for ( int k = 0, M = tags2.size(); k < M; ++k ) {
350  const XMLTag & tagnow2 = *tags2[k];
351  if ( tagnow2.name == "weight" ) {
352  LHAweight wt(tagnow2);
353  string wtname = wt.id;
354  weights.insert(make_pair(wtname, wt));
355  weightsKeys.push_back(wtname);
356  }
357  }
358  for ( int j = 0, M = tags2.size(); j < M; ++j )
359  if (tags2[j]) delete tags2[j];
360  } else if ( tagnow.name == "weight" ) {
361  LHAweight wt(tagnow);
362  string wtname = wt.id;
363  weights.insert(make_pair(wtname, wt));
364  weightsKeys.push_back(wtname);
365  }
366  }
367 
368  // Now add the wgt's step by step.
369  for ( int i = 0, N = tag.tags.size(); i < N; ++i ) {
370  const XMLTag & tagnow = *tag.tags[i];
371  if ( tagnow.name == "weightgroup" ) {
372  LHAweightgroup wgroup(tagnow);
373  string wgname = wgroup.name;
374  weightgroups.insert(make_pair(wgname, wgroup));
375  weightgroupsKeys.push_back(wgname);
376  string ss;
377  vector<XMLTag*> tags2 = XMLTag::findXMLTags(tagnow.contents, &ss);
378  for ( int k = 0, M = tags2.size(); k < M; ++k ) {
379  const XMLTag & tagnow2 = *tags2[k];
380  if ( tagnow2.name == "weight" ) {
381  LHAweight wt(tagnow2);
382  string wtname = wt.id;
383  weights.insert(make_pair(wtname, wt));
384  weightsKeys.push_back(wtname);
385  }
386  }
387  for ( int k = 0, M = tagnow.tags.size(); k < M; ++k ) {
388  const XMLTag & tagnow2 = *tagnow.tags[k];
389  if ( tagnow2.name == "weight" ) {
390  LHAweight wt(tagnow2);
391  string wtname = wt.id;
392  weights.insert(make_pair(wtname, wt));
393  weightsKeys.push_back(wtname);
394  }
395  }
396  for ( int j = 0, M = tags2.size(); j < M; ++j )
397  if (tags2[j]) delete tags2[j];
398  } else if ( tagnow.name == "weight" ) {
399  LHAweight wt(tagnow);
400  string wtname = wt.id;
401  weights.insert(make_pair(wtname, wt));
402  weightsKeys.push_back(wtname);
403  }
404  }
405 
406  for ( int i = 0, N = tags.size(); i < N; ++i ) if (tags[i]) delete tags[i];
407 
408 }
409 
410 //--------------------------------------------------------------------------
411 
412 // Print out the corresponding XML-tag.
413 
414 void LHAinitrwgt::list(ostream & file) const {
415  file << "<initrwgt";
416  for ( map<string,string>::const_iterator it = attributes.begin();
417  it != attributes.end(); ++it )
418  file << " " << it->first << "=\"" << it->second << "\"";
419  file << " >\n";
420  for ( map<string,LHAweightgroup>::const_iterator it = weightgroups.begin();
421  it != weightgroups.end(); ++it ) it->second.list(file);
422  for ( map<string,LHAweight>::const_iterator it = weights.begin();
423  it != weights.end(); ++it ) it->second.list(file);
424  file << "</initrwgt>" << endl;
425 }
426 
427 //==========================================================================
428 
429 // The HEPRUP class is a simple container for the Les Houches file init block.
430 
431 void HEPRUP::clear() {
432  IDBMUP = make_pair(0,0);
433  EBMUP = make_pair(0,0);
434  PDFGUP = make_pair(0,0);
435  PDFSUP = make_pair(0,0);
436  IDWTUP = -1;
437  NPRUP = 0;
438  XSECUP.resize(0);
439  XERRUP.resize(0);
440  XMAXUP.resize(0);
441  LPRUP.resize(0);
442  initrwgt.clear();
443  generators.resize(0);
444  weightgroups.clear();
445  weights.clear();
446 
447 }
448 
449 //==========================================================================
450 
451 // The HEPEUP class is a simple container corresponding to the Les Houches
452 // accord (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
453 // common block with the same name. The members are named in the same
454 // way as in the common block. However, fortran arrays are represented
455 // by vectors, except for the arrays of length two which are
456 // represented by pair objects.
457 
458 //--------------------------------------------------------------------------
459 
460 // Copy information from the given HEPEUP.
461 
462 HEPEUP & HEPEUP::setEvent(const HEPEUP & x) {
463 
464  NUP = x.NUP;
465  IDPRUP = x.IDPRUP;
466  XWGTUP = x.XWGTUP;
467  XPDWUP = x.XPDWUP;
468  SCALUP = x.SCALUP;
469  AQEDUP = x.AQEDUP;
470  AQCDUP = x.AQCDUP;
471  IDUP = x.IDUP;
472  ISTUP = x.ISTUP;
473  MOTHUP = x.MOTHUP;
474  ICOLUP = x.ICOLUP;
475  PUP = x.PUP;
476  VTIMUP = x.VTIMUP;
477  SPINUP = x.SPINUP;
478  heprup = x.heprup;
479  scalesSave = x.scalesSave;
480  weightsSave = x.weightsSave;
481  weights_detailed = x.weights_detailed;
482  weights_compressed = x.weights_compressed;
483  rwgtSave = x.rwgtSave;
484  attributes = x.attributes;
485  return *this;
486 
487 }
488 
489 //--------------------------------------------------------------------------
490 
491 // Reset the HEPEUP object.
492 
493 void HEPEUP::reset() {
494  NUP = 0;
495  weights_detailed.clear();
496  weights_compressed.clear();
497  weightsSave.clear();
498  rwgtSave.clear();
499  scalesSave.clear();
500  attributes.clear();
501 }
502 
503 //--------------------------------------------------------------------------
504 
505 // Assuming the NUP variable, corresponding to the number of
506 // particles in the current event, is correctly set, resize the
507 // relevant vectors accordingly.
508 
509 void HEPEUP::resize() {
510  IDUP.resize(NUP);
511  ISTUP.resize(NUP);
512  MOTHUP.resize(NUP);
513  ICOLUP.resize(NUP);
514  PUP.resize(NUP, vector<double>(5));
515  VTIMUP.resize(NUP);
516  SPINUP.resize(NUP);
517 }
518 
519 //==========================================================================
520 
521 // The Reader class is initialized with a stream from which to read a
522 // version 1/2 Les Houches Accord event file. In the constructor of
523 // the Reader object the optional header information is read and then
524 // the mandatory init is read. After this the whole header block
525 // including the enclosing lines with tags are available in the public
526 // headerBlock member variable. Also the information from the init
527 // block is available in the heprup member variable and any additional
528 // comment lines are available in initComments. After each successful
529 // call to the readEvent() function the standard Les Houches Accord
530 // information about the event is available in the hepeup member
531 // variable and any additional comments in the eventComments
532 // variable. A typical reading sequence would look as follows:
533 
534 //--------------------------------------------------------------------------
535 
536 // Used internally in the constructors to read header and init blocks.
537 bool Reader::init() {
538 
539  bool readingHeader = false;
540  bool readingInit = false;
541 
542  // Make sure we are reading a LHEF file:
543  getLine();
544 
545  if ( currentLine.find("<LesHouchesEvents" ) == string::npos )
546  return false;
547  version = 0;
548  if ( currentLine.find("version=\"1" ) != string::npos )
549  version = 1;
550  else if ( currentLine.find("version=\"2" ) != string::npos )
551  version = 2;
552  else if ( currentLine.find("version=\"3" ) != string::npos )
553  version = 3;
554  else
555  return false;
556 
557  // Clear all members.
558  outsideBlock="";
559  headerBlock="";
560  headerComments="";
561  heprup.clear();
562  initComments="";
563  hepeup.clear();
564  eventComments="";
565 
566  // Loop over all lines until we hit the </init> tag.
567  while ( getLine() && currentLine.find("</init>") == string::npos ) {
568  if ( currentLine.find("<header") != string::npos ) {
569  // We have hit the header block, so we should dump this and
570  // all following lines to headerBlock until we hit the end of
571  // it.
572  readingHeader = true;
573  headerBlock = currentLine + "\n";
574  }
575  else if ( currentLine.find("<init>") != string::npos
576  || currentLine.find("<init ") != string::npos ) {
577  // We have hit the init block, so we should expect to find the
578  // standard information in the following.
579  readingInit = true;
580 
581  // The first line tells us how many lines to read next.
582  getLine();
583  istringstream iss(currentLine);
584  if ( !( iss >> heprup.IDBMUP.first >> heprup.IDBMUP.second
585  >> heprup.EBMUP.first >> heprup.EBMUP.second
586  >> heprup.PDFGUP.first >> heprup.PDFGUP.second
587  >> heprup.PDFSUP.first >> heprup.PDFSUP.second
588  >> heprup.IDWTUP >> heprup.NPRUP ) ) {
589  heprup.NPRUP = -42;
590  return false;
591  }
592  heprup.resize();
593 
594  for ( int i = 0; i < heprup.NPRUP; ++i ) {
595  getLine();
596  istringstream isss(currentLine);
597  if ( !( isss >> heprup.XSECUP[i] >> heprup.XERRUP[i]
598  >> heprup.XMAXUP[i] >> heprup.LPRUP[i] ) ) {
599  heprup.NPRUP = -42;
600  return false;
601  }
602  }
603  }
604  else if ( currentLine.find("</header>") != string::npos ) {
605  // The end of the header block. Dump this line as well to the
606  // headerBlock and we're done.
607  readingHeader = false;
608  headerBlock += currentLine + "\n";
609  }
610  else if ( readingHeader ) {
611  // We are in the process of reading the header block. Dump the
612  // line to headerBlock.
613  headerBlock += currentLine + "\n";
614  headerComments += currentLine + "\n";
615  }
616  else if ( readingInit ) {
617  // Here we found a comment line. Dump it to initComments.
618  initComments += currentLine + "\n";
619  }
620  else {
621  // We found some other stuff outside the standard tags.
622  outsideBlock += currentLine + "\n";
623  }
624  }
625 
626  if ( file == NULL ) heprup.NPRUP = -42;
627 
628  // Scan the header block for XML tags
629  string leftovers;
630  vector<XMLTag*> tags1 = XMLTag::findXMLTags(headerComments, &leftovers);
631  if ( leftovers.find_first_not_of(" \t\n") == string::npos )
632  leftovers="";
633 
634  for ( int i = 0, N = tags1.size(); i < N; ++i ) {
635  const XMLTag & tag = *tags1[i];
636 
637  if ( tag.name == "initrwgt" ) {
638  LHAinitrwgt irwgt(tag);
639  heprup.initrwgt = irwgt;
640  for ( int j = 0, M = tag.tags.size(); j < M; ++j ) {
641  XMLTag & ctag = *tag.tags[j];
642  if ( ctag.name == "weightgroup" ) {
643  LHAweightgroup wgroup(ctag);
644  string wgname = wgroup.name;
645  heprup.weightgroups.insert(make_pair(wgname, wgroup));
646 
647  string ss;
648  vector<XMLTag*> tags2 = XMLTag::findXMLTags(ctag.contents, &ss);
649  for ( int k = 0, O = tags2.size(); k < O; ++k ) {
650  const XMLTag & tagnow2 = *tags2[k];
651  if ( tagnow2.name == "weight" ) {
652  LHAweight wt(tagnow2);
653  string wtname = wt.id;
654  heprup.weights.insert(make_pair(wtname, wt));
655  }
656  }
657  for ( int k = 0, O = ctag.tags.size(); k < O; ++k ) {
658  const XMLTag & tagnow2 = *ctag.tags[k];
659  if ( tagnow2.name == "weight" ) {
660  LHAweight wt(tagnow2);
661  string wtname = wt.id;
662  heprup.weights.insert(make_pair(wtname, wt));
663  }
664  }
665  } else if ( ctag.name == "weight" ) {
666  string tname = ctag.attr["id"];
667  heprup.weights.insert(make_pair(tname, LHAweight(ctag)));
668  }
669  }
670  }
671  }
672 
673  heprup.generators.clear();
674  // Scan the init block for XML tags
675  leftovers="";
676  vector<XMLTag*> tags2 = XMLTag::findXMLTags(initComments, &leftovers);
677  if ( leftovers.find_first_not_of(" \t\n") == string::npos )
678  leftovers="";
679 
680  for ( int i = 0, N = tags2.size(); i < N; ++i ) {
681  const XMLTag & tag = *tags2[i];
682  if ( tag.name == "generator" ) {
683  heprup.generators.push_back(LHAgenerator(tag));
684  }
685  }
686 
687  for ( int i = 0, N = tags1.size(); i < N; ++i )
688  if (tags1[i]) delete tags1[i];
689  for ( int i = 0, N = tags2.size(); i < N; ++i )
690  if (tags2[i]) delete tags2[i];
691 
692  // Done
693  return true;
694 
695 }
696 
697 //--------------------------------------------------------------------------
698 
699 // Read an event from the file and store it in the hepeup
700 // object. Optional comment lines are stored in the eventComments
701 // member variable. return true if the read was successful.
702 
703 bool Reader::readEvent(HEPEUP * peup) {
704 
705  HEPEUP & eup = (peup? *peup: hepeup);
706  eup.clear();
707  eup.heprup = &heprup;
708  weights_detailed_vec.clear();
709 
710  // Check if the initialization was successful. Otherwise we will
711  // not read any events.
712  if ( heprup.NPRUP < 0 ) return false;
713  eventComments = "";
714  outsideBlock = "";
715  eup.NUP = 0;
716 
717  // Keep reading lines until we hit the next event or the end of
718  // the event block. Save any inbetween lines. Exit if we didn't
719  // find an event.
720  while ( getLine() && currentLine.find("<event") == string::npos )
721  outsideBlock += currentLine + "\n";
722 
723  // Get event attributes.
724  if (currentLine != "") {
725  string eventLine(currentLine);
726  eventLine += "</event>";
727  vector<XMLTag*> evtags = XMLTag::findXMLTags(eventLine);
728  XMLTag & evtag = *evtags[0];
729  for ( map<string,string>::const_iterator it = evtag.attr.begin();
730  it != evtag.attr.end(); ++it ) {
731  eup.attributes.insert(make_pair(it->first,it->second));
732  }
733  for ( int i = 0, N = evtags.size(); i < N; ++i )
734  if (evtags[i]) delete evtags[i];
735  }
736 
737  if ( !getLine() ) return false;
738 
739  // We found an event. The first line determines how many
740  // subsequent particle lines we have.
741  istringstream iss(currentLine);
742  if ( !( iss >> eup.NUP >> eup.IDPRUP >> eup.XWGTUP
743  >> eup.SCALUP >> eup.AQEDUP >> eup.AQCDUP ) )
744  return false;
745  eup.resize();
746 
747  // Read all particle lines.
748  for ( int i = 0; i < eup.NUP; ++i ) {
749  if ( !getLine() ) return false;
750  istringstream isss(currentLine);
751  if ( !( isss >> eup.IDUP[i] >> eup.ISTUP[i]
752  >> eup.MOTHUP[i].first >> eup.MOTHUP[i].second
753  >> eup.ICOLUP[i].first >> eup.ICOLUP[i].second
754  >> eup.PUP[i][0] >> eup.PUP[i][1] >> eup.PUP[i][2]
755  >> eup.PUP[i][3] >> eup.PUP[i][4]
756  >> eup.VTIMUP[i] >> eup.SPINUP[i] ) )
757  return false;
758  }
759 
760  // Now read any additional comments.
761  while ( getLine() && currentLine.find("</event>") == string::npos )
762  eventComments += currentLine + "\n";
763 
764  if ( file == NULL ) return false;
765 
766  eup.scalesSave = LHAscales(eup.SCALUP);
767 
768  // Scan the init block for XML tags
769  string leftovers;
770  vector<XMLTag*> tags = XMLTag::findXMLTags(eventComments, &leftovers);
771  if ( leftovers.find_first_not_of(" \t\n") == string::npos )
772  leftovers="";
773 
774  eventComments = "";
775  istringstream f(leftovers);
776  string l;
777  while (getline(f, l)) {
778  size_t p = l.find_first_not_of(" \t");
779  l.erase(0, p);
780  p = l.find_last_not_of(" \t");
781  if (string::npos != p) l.erase(p+1);
782  if (l.find_last_not_of("\n") != string::npos)
783  eventComments += l + "\n";
784  }
785 
786  for ( int i = 0, N = tags.size(); i < N; ++i ) {
787  XMLTag & tag = *tags[i];
788 
789  if ( tag.name == "weights" ) {
790  LHAweights wts(tag);
791  eup.weightsSave = wts;
792 
793  for ( int k = 0, M = int(wts.weights.size()); k < M; ++k ) {
794  eup.weights_compressed.push_back(wts.weights[k]);
795  }
796 
797  }
798  else if ( tag.name == "scales" ) {
799  eup.scalesSave = LHAscales(tag, eup.SCALUP);
800  }
801  else if ( tag.name == "rwgt" ) {
802  LHArwgt rwgt0(tag);
803  eup.rwgtSave = rwgt0;
804  string s;
805  vector<XMLTag*> tags2 = XMLTag::findXMLTags(rwgt0.contents, &s);
806  for ( int k = 0, M = tags2.size(); k < M; ++k ) {
807  const XMLTag & tagnow = *tags2[k];
808  if ( tagnow.name == "wgt" ) {
809  LHAwgt wt(tagnow);
810  eup.weights_detailed.insert(make_pair(wt.id, wt.contents));
811  weights_detailed_vec.push_back(wt.contents);
812  }
813  }
814  for ( int k = 0, M = tag.tags.size(); k < M; ++k ) {
815  const XMLTag & tagnow = *tag.tags[k];
816  if ( tagnow.name == "wgt" ) {
817  LHAwgt wt(tagnow);
818  eup.weights_detailed.insert(make_pair(wt.id, wt.contents));
819  weights_detailed_vec.push_back(wt.contents);
820  }
821  }
822  }
823  }
824 
825  for ( int i = 0, N = tags.size(); i < N; ++i ) if (tags[i]) delete tags[i];
826 
827  return true;
828 
829 }
830 
831 //==========================================================================
832 
833 // The Writer class is initialized with a stream to which to write a
834 // version 3.0 Les Houches Accord event file.
835 
836 //--------------------------------------------------------------------------
837 
838 // Write out an optional header block followed by the standard init
839 // block information together with any comment lines.
840 
841 void Writer::init() {
842 
843  // Write out the standard XML tag for the event file.
844  if ( version == 1 )
845  file << "<LesHouchesEvents version=\"1.0\">" << endl;
846  else
847  file << "<LesHouchesEvents version=\"3.0\">" << endl;
848 
849  file << setprecision(8);
850 
851  // Print headercomments and header init information.
852  file << "<header>" << endl;
853  file << hashline(headerStream.str(),true) << std::flush;
854  if ( version != 1 ) heprup.initrwgt.list(file);
855  file << "</header>" << endl;
856 
857  file << "<init>"<< endl
858  << " " << setw(8) << heprup.IDBMUP.first
859  << " " << setw(8) << heprup.IDBMUP.second
860  << " " << setw(14) << heprup.EBMUP.first
861  << " " << setw(14) << heprup.EBMUP.second
862  << " " << setw(4) << heprup.PDFGUP.first
863  << " " << setw(4) << heprup.PDFGUP.second
864  << " " << setw(4) << heprup.PDFSUP.first
865  << " " << setw(4) << heprup.PDFSUP.second
866  << " " << setw(4) << heprup.IDWTUP
867  << " " << setw(4) << heprup.NPRUP << endl;
868  heprup.resize();
869  for ( int i = 0; i < heprup.NPRUP; ++i )
870  file << " " << setw(14) << heprup.XSECUP[i]
871  << " " << setw(14) << heprup.XERRUP[i]
872  << " " << setw(14) << heprup.XMAXUP[i]
873  << " " << setw(6) << heprup.LPRUP[i] << endl;
874 
875  if ( version == 1 ) {
876  file << hashline(initStream.str(),true) << std::flush
877  << "</init>" << endl;
878  initStream.str("");
879  return;
880  }
881 
882  for ( int i = 0, N = heprup.generators.size(); i < N; ++i ) {
883  heprup.generators[i].list(file);
884  }
885 
886  file << hashline(initStream.str(),true) << std::flush
887  << "</init>" << endl;
888  initStream.str("");
889 }
890 
891 //--------------------------------------------------------------------------
892 
893 // Write out the event stored in hepeup, followed by optional
894 // comment lines.
895 
896 bool Writer::writeEvent(HEPEUP * peup, int pDigits) {
897 
898  HEPEUP & eup = (peup? *peup: hepeup);
899 
900  file << "<event";
901  for ( map<string,string>::const_iterator it = eup.attributes.begin();
902  it != eup.attributes.end(); ++it )
903  file << " " << it->first << "=\"" << it->second << "\"";
904  file << ">" << std::flush << endl;
905  file << " " << setw(4) << eup.NUP
906  << " " << setw(6) << eup.IDPRUP
907  << " " << setw(14) << eup.XWGTUP
908  << " " << setw(14) << eup.SCALUP
909  << " " << setw(14) << eup.AQEDUP
910  << " " << setw(14) << eup.AQCDUP << endl;
911  eup.resize();
912 
913  for ( int i = 0; i < eup.NUP; ++i )
914  file << " " << setw(8) << eup.IDUP[i]
915  << " " << setw(2) << eup.ISTUP[i]
916  << " " << setw(4) << eup.MOTHUP[i].first
917  << " " << setw(4) << eup.MOTHUP[i].second
918  << " " << setw(4) << eup.ICOLUP[i].first
919  << " " << setw(4) << eup.ICOLUP[i].second
920  << " " << setw(pDigits) << eup.PUP[i][0]
921  << " " << setw(pDigits) << eup.PUP[i][1]
922  << " " << setw(pDigits) << eup.PUP[i][2]
923  << " " << setw(pDigits) << eup.PUP[i][3]
924  << " " << setw(pDigits) << eup.PUP[i][4]
925  << " " << setw(1) << eup.VTIMUP[i]
926  << " " << setw(1) << eup.SPINUP[i] << endl;
927 
928  // Write event comments.
929  file << hashline(eventStream.str()) << std::flush;
930  eventStream.str("");
931 
932  if ( version != 1 ) {
933  eup.rwgtSave.list(file);
934  eup.weightsSave.list(file);
935  eup.scalesSave.list(file);
936  }
937 
938  file << "</event>" << endl;
939 
940  if ( !file ) return false;
941 
942  return true;
943 
944 }
945 
946 //--------------------------------------------------------------------------
947 
948 // Write out an event as a string.
949 
950 string Writer::getEventString(HEPEUP * peup) {
951 
952  HEPEUP & eup = (peup? *peup: hepeup);
953 
954  stringstream helper;
955 
956  helper << "<event";
957  for ( map<string,string>::const_iterator it = eup.attributes.begin();
958  it != eup.attributes.end(); ++it )
959  helper << " " << it->first << "=\"" << it->second << "\"";
960  helper << ">" << std::flush << endl;
961  helper << " " << setw(4) << eup.NUP
962  << " " << setw(6) << eup.IDPRUP
963  << " " << setw(14) << eup.XWGTUP
964  << " " << setw(14) << eup.SCALUP
965  << " " << setw(14) << eup.AQEDUP
966  << " " << setw(14) << eup.AQCDUP << endl;
967  eup.resize();
968 
969  for ( int i = 0; i < eup.NUP; ++i ) {
970  helper << " " << setw(8) << eup.IDUP[i]
971  << " " << setw(2) << eup.ISTUP[i]
972  << " " << setw(4) << eup.MOTHUP[i].first
973  << " " << setw(4) << eup.MOTHUP[i].second
974  << " " << setw(6) << eup.ICOLUP[i].first
975  << " " << setw(6) << eup.ICOLUP[i].second
976  << fixed
977  << setprecision(15)
978  << " " << setw(22) << eup.PUP[i][0]
979  << " " << setw(22) << eup.PUP[i][1]
980  << " " << setw(22) << eup.PUP[i][2]
981  << " " << setw(22) << eup.PUP[i][3]
982  << " " << setw(22) << eup.PUP[i][4]
983  << " " << setw(6) << eup.VTIMUP[i]
984  << " " << setw(6) << eup.SPINUP[i] << endl;
985  }
986 
987  // Write event comments.
988  helper << hashline(eventStream.str()) << std::flush;
989  eventStream.str("");
990 
991  if ( version != 1 ) {
992  eup.rwgtSave.list(helper);
993  eup.weightsSave.list(helper);
994  eup.scalesSave.list(helper);
995  }
996 
997  helper << "</event>" << endl;
998 
999  string helperString = helper.str();
1000  //event = helperString.c_str();
1001 
1002  return helperString;
1003 
1004 }
1005 
1006 //--------------------------------------------------------------------------
1007 
1008 // Make sure that each line in the string s starts with a
1009 // #-character and that the string ends with a new-line.
1010 
1011 string Writer::hashline(string s, bool comment) {
1012  string ret;
1013  istringstream is(s);
1014  string ss;
1015  while ( getline(is, ss) ) {
1016  if ( comment )
1017  ss = "# " + ss;
1018  ret += ss + '\n';
1019  }
1020  return ret;
1021 }
1022 
1023 //==========================================================================
1024 
1025 }
void version(std::ostream &os=std::cout)
print HepMC version
Definition: Version.h:27