StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
LesHouches.cc
1 // LesHouches.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 // Function definitions (not found in the header) for the LHAup and
7 // LHAupLHEF classes.
8 
9 #include "Pythia8/LesHouches.h"
10 
11 // Access time information.
12 #include <ctime>
13 
14 namespace Pythia8 {
15 
16 //==========================================================================
17 
18 // LHAup class.
19 
20 //--------------------------------------------------------------------------
21 
22 // Constants: could be changed here if desired, but normally should not.
23 // These are of technical nature, as described for each.
24 
25 // LHA convention with cross section in pb may require conversion from mb.
26 const double LHAup::CONVERTMB2PB = 1e9;
27 
28 //--------------------------------------------------------------------------
29 
30 // Print the initialization info; to check it worked.
31 
32 void LHAup::listInit() {
33 
34  // Header.
35  cout << "\n -------- LHA initialization information ------------ \n";
36 
37  // Beam info.
38  cout << fixed << setprecision(3)
39  << "\n beam kind energy pdfgrp pdfset \n"
40  << " A " << setw(6) << idBeamASave
41  << setw(12) << eBeamASave
42  << setw(8) << pdfGroupBeamASave
43  << setw(8) << pdfSetBeamASave << "\n"
44  << " B " << setw(6) << idBeamBSave
45  << setw(12) << eBeamBSave
46  << setw(8) << pdfGroupBeamBSave
47  << setw(8) << pdfSetBeamBSave << "\n";
48 
49  // Event weighting strategy.
50  cout << "\n Event weighting strategy = " << setw(2)
51  << strategySave << "\n" ;
52 
53  // Process list.
54  cout << scientific << setprecision(4)
55  << "\n Processes, with strategy-dependent cross section info \n"
56  << " number xsec (pb) xerr (pb) xmax (pb) \n" ;
57  for (int ip = 0; ip < int(processes.size()); ++ip) {
58  cout << setw(8) << processes[ip].idProc
59  << setw(15) << processes[ip].xSecProc
60  << setw(15) << processes[ip].xErrProc
61  << setw(15) << processes[ip].xMaxProc << "\n";
62  }
63 
64  // Finished.
65  cout << "\n -------- End LHA initialization information -------- \n";
66 
67 }
68 
69 //--------------------------------------------------------------------------
70 
71 // Print the event info; to check it worked.
72 
73 void LHAup::listEvent() {
74 
75  // Header.
76  cout << "\n -------- LHA event information and listing -------------"
77  << "--------------------------------------------------------- \n";
78 
79  // Basic event info.
80  cout << scientific << setprecision(4)
81  << "\n process = " << setw(8) << idProc
82  << " weight = " << setw(12) << weightProc
83  << " scale = " << setw(12) << scaleProc << " (GeV) \n"
84  << " "
85  << " alpha_em = " << setw(12) << alphaQEDProc
86  << " alpha_strong = " << setw(12) << alphaQCDProc << "\n";
87 
88  // Particle list
89  cout << fixed << setprecision(3)
90  << "\n Participating Particles \n"
91  << " no id stat mothers colours p_x "
92  << "p_y p_z e m tau spin \n" ;
93  for (int ip = 1; ip < int(particles.size()); ++ip) {
94  cout << setw(6) << ip
95  << setw(10) << particles[ip].idPart
96  << setw(5) << particles[ip].statusPart
97  << setw(6) << particles[ip].mother1Part
98  << setw(6) << particles[ip].mother2Part
99  << setw(6) << particles[ip].col1Part
100  << setw(6) << particles[ip].col2Part
101  << setw(11) << particles[ip].pxPart
102  << setw(11) << particles[ip].pyPart
103  << setw(11) << particles[ip].pzPart
104  << setw(11) << particles[ip].ePart
105  << setw(11) << particles[ip].mPart
106  << setw(8) << particles[ip].tauPart
107  << setw(8) << particles[ip].spinPart << "\n";
108  }
109 
110  // PDF info - optional.
111  if (pdfIsSetSave) cout << "\n pdf: id1 =" << setw(5) << id1pdfSave
112  << " id2 =" << setw(5) << id2pdfSave
113  << " x1 =" << scientific << setw(10) << x1pdfSave
114  << " x2 =" << setw(10) << x2pdfSave
115  << " scalePDF =" << setw(10) << scalePDFSave
116  << " pdf1 =" << setw(10) << pdf1Save
117  << " pdf2 =" << setw(10) << pdf2Save << "\n";
118 
119  // Finished.
120  cout << "\n -------- End LHA event information and listing ---------"
121  << "--------------------------------------------------------- \n";
122 
123 }
124 
125 //--------------------------------------------------------------------------
126 
127 // Open and write header to a Les Houches Event File.
128 
129 bool LHAup::openLHEF(string fileNameIn) {
130 
131  // Open file for writing. Reset it to be empty.
132  fileName = fileNameIn;
133  const char* cstring = fileName.c_str();
134  osLHEF.open(cstring, ios::out | ios::trunc);
135  if (!osLHEF) {
136  infoPtr->errorMsg("Error in LHAup::openLHEF:"
137  " could not open file", fileName);
138  return false;
139  }
140 
141  // Read out current date and time.
142  time_t t = time(0);
143  strftime(dateNow,12,"%d %b %Y",localtime(&t));
144  strftime(timeNow,9,"%H:%M:%S",localtime(&t));
145 
146  // Write header.
147  osLHEF << "<LesHouchesEvents version=\"1.0\">\n"
148  << "<!--\n"
149  << " File written by Pythia8::LHAup on "
150  << dateNow << " at " << timeNow << "\n"
151  << "-->" << endl;
152 
153  // Done.
154  return true;
155 
156 }
157 
158 //--------------------------------------------------------------------------
159 
160 // Write initialization information to a Les Houches Event File.
161 
162 bool LHAup::initLHEF() {
163 
164  // Write information on beams.
165  osLHEF << "<init>\n" << scientific << setprecision(6)
166  << " " << idBeamASave << " " << idBeamBSave
167  << " " << eBeamASave << " " << eBeamBSave
168  << " " << pdfGroupBeamASave << " " << pdfGroupBeamBSave
169  << " " << pdfSetBeamASave << " " << pdfSetBeamBSave
170  << " " << strategySave << " " << processes.size() << "\n";
171 
172  // Write information on all the subprocesses.
173  for (int ip = 0; ip < int(processes.size()); ++ip)
174  osLHEF << " " << setw(13) << processes[ip].xSecProc
175  << " " << setw(13) << processes[ip].xErrProc
176  << " " << setw(13) << processes[ip].xMaxProc
177  << " " << setw(6) << processes[ip].idProc << "\n";
178 
179  // Done.
180  osLHEF << "</init>" << endl;
181  return true;
182 
183 }
184 
185 //--------------------------------------------------------------------------
186 
187 // Write event information to a Les Houches Event File.
188 // Normal mode is to line up event info in columns, but the non-verbose
189 // altnernative saves space at the expense of human readability.
190 
191 bool LHAup::eventLHEF(bool verbose) {
192 
193  // Default verbose option.
194  if (verbose) {
195 
196  // Write information on process as such.
197  osLHEF << "<event>\n" << scientific << setprecision(6)
198  << " " << setw(5) << particles.size() - 1
199  << " " << setw(5) << idProc
200  << " " << setw(13) << weightProc
201  << " " << setw(13) << scaleProc
202  << " " << setw(13) << alphaQEDProc
203  << " " << setw(13) << alphaQCDProc << "\n";
204 
205  // Write information on the particles, excluding zeroth.
206  for (int ip = 1; ip < int(particles.size()); ++ip) {
207  LHAParticle& ptNow = particles[ip];
208  osLHEF << " " << setw(8) << ptNow.idPart
209  << " " << setw(5) << ptNow.statusPart
210  << " " << setw(5) << ptNow.mother1Part
211  << " " << setw(5) << ptNow.mother2Part
212  << " " << setw(5) << ptNow.col1Part
213  << " " << setw(5) << ptNow.col2Part << setprecision(10)
214  << " " << setw(17) << ptNow.pxPart
215  << " " << setw(17) << ptNow.pyPart
216  << " " << setw(17) << ptNow.pzPart
217  << " " << setw(17) << ptNow.ePart
218  << " " << setw(17) << ptNow.mPart << setprecision(6);
219  if (ptNow.tauPart == 0.) osLHEF << " 0.";
220  else osLHEF << " " << setw(13) << ptNow.tauPart;
221  if (ptNow.spinPart == 9.) osLHEF << " 9.";
222  else osLHEF << " " << setw(13) << ptNow.spinPart;
223  osLHEF << "\n";
224  }
225 
226  // Optionally write information on PDF values at hard interaction.
227  if (pdfIsSetSave) osLHEF << "#pdf"
228  << " " << setw(4) << id1pdfSave
229  << " " << setw(4) << id2pdfSave
230  << " " << setw(13) << x1pdfSave
231  << " " << setw(13) << x2pdfSave
232  << " " << setw(13) << scalePDFSave
233  << " " << setw(13) << pdf1Save
234  << " " << setw(13) << pdf2Save << "\n";
235 
236  // Alternative non-verbose option.
237  } else {
238 
239  // Write information on process as such.
240  osLHEF << "<event>\n" << scientific << setprecision(6)
241  << particles.size() - 1 << " " << idProc << " "
242  << weightProc << " " << scaleProc << " "
243  << alphaQEDProc << " " << alphaQCDProc << "\n";
244 
245  // Write information on the particles, excluding zeroth.
246  for (int ip = 1; ip < int(particles.size()); ++ip) {
247  LHAParticle& ptNow = particles[ip];
248  osLHEF << ptNow.idPart << " " << ptNow.statusPart
249  << " " << ptNow.mother1Part << " " << ptNow.mother2Part
250  << " " << ptNow.col1Part << " " << ptNow.col2Part
251  << setprecision(10) << " " << ptNow.pxPart
252  << " " << ptNow.pyPart << " " << ptNow.pzPart
253  << " " << ptNow.ePart << " " << ptNow.mPart
254  << setprecision(6);
255  if (ptNow.tauPart == 0.) osLHEF << " 0.";
256  else osLHEF << " " << setw(13) << ptNow.tauPart;
257  if (ptNow.spinPart == 9.) osLHEF << " 9.";
258  else osLHEF << " " << setw(13) << ptNow.spinPart;
259  osLHEF << "\n";
260  }
261 
262  // Optionally write information on PDF values at hard interaction.
263  if (pdfIsSetSave) osLHEF << "#pdf" << " " << id1pdfSave
264  << " " << id2pdfSave << " " << x1pdfSave << " " << x2pdfSave
265  << " " << scalePDFSave << " " << pdf1Save << " " << pdf2Save
266  << "\n";
267  }
268 
269  // Done.
270  osLHEF << "</event>" << endl;
271  return true;
272 
273 }
274 
275 //--------------------------------------------------------------------------
276 
277 // Write end of a Les Houches Event File and close it.
278 
279 bool LHAup::closeLHEF(bool updateInit) {
280 
281  // Write an end to the file.
282  osLHEF << "</LesHouchesEvents>" << endl;
283  osLHEF.close();
284 
285  // Optionally update the cross section information.
286  if (updateInit) {
287  const char* cstring = fileName.c_str();
288  osLHEF.open(cstring, ios::in | ios::out);
289 
290  // Rewrite header; identically with what openLHEF did.
291  osLHEF << "<LesHouchesEvents version=\"1.0\">\n"
292  << "<!--\n"
293  << " File written by Pythia8::LHAup on "
294  << dateNow << " at " << timeNow << "\n"
295  << "-->" << endl;
296 
297  // Redo initialization information.
298  initLHEF();
299  osLHEF.close();
300  }
301 
302  // Done.
303  return true;
304 
305 }
306 
307 //--------------------------------------------------------------------------
308 
309 // Read in initialization information from a Les Houches Event File.
310 
311 bool LHAup::setInitLHEF(istream& is, bool readHeaders) {
312 
313  // Check that first line is consistent with proper LHEF file.
314  string line;
315  if (!getline(is, line)) return false;
316  if (line.find("<LesHouchesEvents") == string::npos) return false;
317  if (line.find("version=\"1.0\"" ) == string::npos ) return false;
318 
319  // What to search for if reading headers; if not reading
320  // headers then return to default behaviour
321  string headerTag = (readHeaders) ? "<header>" : "<init";
322 
323  // Loop over lines until an <init (or optionally <header>) tag
324  // is found first on a line.
325  string tag = " ";
326  do {
327  if (!getline(is, line)) return false;
328  if (line.find_first_not_of(" \n\t\v\b\r\f\a") != string::npos) {
329  istringstream getfirst(line);
330  getfirst >> tag;
331  if (!getfirst) return false;
332  }
333  } while (tag != "<init>" && tag != "<init" && tag != headerTag);
334 
335  // If header tag found, process if required
336  if (readHeaders == true && tag == headerTag) {
337  // Temporary local storage
338  map < string, string > headerMap;
339 
340  // Loop over lines until an <init> tag is found.
341  bool read = true, newKey = false;
342  string key = "base";
343  vector < string > keyVec;
344 
345  while (true) {
346  if (!getline(is, line)) return false;
347 
348  // Break lines containing multiple tags into two segments.
349  // (Could be generalized to multiple segments but this is
350  // sufficient to handle at least <tag>info</tag> on same line.
351  size_t firstTagEnd = line.find_first_of(">");
352  size_t secondTagBegin = line.find_first_of("<",firstTagEnd);
353  vector<string> lineVec;
354  if (firstTagEnd != string::npos && secondTagBegin != string::npos) {
355  lineVec.push_back(line.substr(0,secondTagBegin));
356  lineVec.push_back(line.substr(secondTagBegin,
357  line.size()-secondTagBegin));
358  }
359  else {
360  lineVec.push_back(line);
361  }
362 
363  // Loop over segments of current line
364  for (int iVec=0; iVec<int(lineVec.size()); ++iVec) {
365  line = lineVec[iVec];
366 
367  // Clean line to contain only valid characters
368  size_t posBeg = line.find_first_not_of(" \n\t\v\b\r\f\a");
369  size_t posEnd = line.find_last_not_of(" \n\t\v\b\r\f\a");
370  string lineClean = " ";
371  if (posBeg != string::npos && posEnd != string::npos && posBeg
372  < posEnd) {
373  lineClean = line.substr(posBeg, posEnd - posBeg + 1);
374  posBeg = 0;
375  posEnd = lineClean.size();
376  }
377 
378  // Check for empty line
379  if (lineClean == " " || posBeg >= posEnd) continue;
380 
381  // PZS Jan 2015: Allow multiple open/close tags on a single line.
382  size_t tagBeg = lineClean.find_first_of("<");
383  size_t tagEnd = lineClean.find_first_of(">");
384 
385  while (tagBeg != string::npos && tagBeg < tagEnd) {
386 
387  // Update remainder (non-tag) part of line, for later storage
388  posBeg = tagEnd+1;
389 
390  // Only take the first word of the tag,
391  tag = lineClean.substr(tagBeg + 1, tagEnd - tagBeg - 1);
392  istringstream getfirst(tag);
393  getfirst >> tag;
394 
395  // Prepare for next while iteration:
396  // Look for next tag on line and update posBeg and posEnd.
397  tagBeg = lineClean.find_first_of("<",tagEnd);
398  tagEnd = lineClean.find_first_of(">",tagBeg+1);
399 
400  // Tag present, so handle here
401  if (getfirst) {
402 
403  // Exit condition
404  if (tag == "init") break;
405 
406  // End of header block; keep reading until <init> tag,
407  // but do not store any further information
408  else if (tag == "/header") {
409  read = false;
410  continue;
411 
412  // Opening tag
413  } else if (tag[0] != '/') {
414  keyVec.push_back(tag);
415  newKey = true;
416  continue;
417 
418  // Closing tag that matches current key
419  } else if (tag == "/" + keyVec.back()) {
420  keyVec.pop_back();
421  newKey = true;
422  continue;
423 
424  // Also check for forgotten close tag: next-to-last element
425  } else if (keyVec.size() >= 2
426  && tag == "/" + keyVec[keyVec.size()-2]) {
427  infoPtr->errorMsg("Warning in LHAup::setInitLHEF:"
428  " corrupt LHEF end tag",keyVec.back());
429  keyVec.pop_back();
430  keyVec.pop_back();
431  newKey = true;
432  continue;
433  }
434 
435  } // if (getfirst)
436 
437  } // Loop over tags
438 
439  // Exit condition
440  if (tag == "init") break;
441 
442  // At this point the (rest of) the line is not a tag;
443  // If no longer reading anything, skip.
444  if (!read) continue;
445 
446  // Check for key change
447  if (newKey) {
448  if (keyVec.empty()) key = "base";
449  else key = keyVec[0];
450  for (size_t i = 1; i < keyVec.size(); i++)
451  key += "." + keyVec[i];
452  newKey = false;
453  }
454 
455  // Check if anything remains to store of this line
456  posBeg = line.find_first_not_of(" \n\t\v\b\r\f\a",posBeg);
457  if (posBeg == string::npos || posBeg > posEnd) continue;
458 
459  // Append information to local storage
460  headerMap[key] += line.substr(posBeg,posEnd - posBeg + 1) + "\n";
461 
462  } // Loop over line segments
463 
464  // Exit condition
465  if (tag == "init") break;
466 
467  } // while (true)
468 
469  // Copy information to info using LHAup::setInfoHeader
470  for (map < string, string >::iterator it = headerMap.begin();
471  it != headerMap.end(); it++)
472  setInfoHeader(it->first, it->second);
473 
474  } // if (readHeaders == true && tag == headerTag)
475 
476  // Read in first info line; done if empty.
477  if (!getline(is, line)) return false;
478  if (line.find("</init") != string::npos) return true;
479 
480  // Read in beam and strategy info, and store it.
481  int idbmupA, idbmupB;
482  double ebmupA, ebmupB;
483  int pdfgupA, pdfgupB, pdfsupA, pdfsupB, idwtup, nprup;
484  istringstream getbms(line);
485  getbms >> idbmupA >> idbmupB >> ebmupA >> ebmupB >> pdfgupA
486  >> pdfgupB >> pdfsupA >> pdfsupB >> idwtup >> nprup;
487  if (!getbms) return false;
488  setBeamA(idbmupA, ebmupA, pdfgupA, pdfsupA);
489  setBeamB(idbmupB, ebmupB, pdfgupB, pdfsupB);
490  setStrategy(idwtup);
491 
492  // Read in process info, one process at a time, and store it.
493  double xsecup, xerrup, xmaxup;
494  xSecSumSave = 0.;
495  xErrSumSave = 0.;
496  int lprup;
497  for (int ip = 0; ip < nprup; ++ip) {
498  if (!getline(is, line)) return false;
499  istringstream getpro(line);
500  getpro >> xsecup >> xerrup >> xmaxup >> lprup ;
501  if (!getpro) return false;
502  addProcess(lprup, xsecup, xerrup, xmaxup);
503  xSecSumSave += xsecup;
504  xErrSumSave += pow2(xerrup);
505  }
506  xErrSumSave = sqrt(xErrSumSave);
507 
508  // Reading worked.
509  return true;
510 
511 }
512 
513 //--------------------------------------------------------------------------
514 
515 // Read in event information from a Les Houches Event File,
516 // into a staging area where it can be reused by setOldEventLHEF.
517 
518 bool LHAup::setNewEventLHEF(istream& is) {
519 
520  // Loop over lines until an <event tag is found first on a line.
521  string line, tag;
522  do {
523  if (!getline(is, line)) return false;
524  if (line.find_first_not_of(" \n\t\v\b\r\f\a") != string::npos) {
525  istringstream getfirst(line);
526  getfirst >> tag;
527  if (!getfirst) return false;
528  }
529  } while (tag != "<event>" && tag != "<event");
530 
531  // Read in process info and store it.
532  if (!getline(is, line)) return false;
533  istringstream getpro(line);
534  getpro >> nupSave >> idprupSave >> xwgtupSave >> scalupSave
535  >> aqedupSave >> aqcdupSave;
536  if (!getpro) return false;
537 
538  // Reset particlesSave vector, add slot-0 empty particle.
539  particlesSave.clear();
540  particlesSave.push_back( LHAParticle() );
541 
542  // Read in particle info one by one, and store it.
543  // Note unusual C++ loop range, to better reflect LHA/Fortran standard.
544  // (Recall that process(...) above added empty particle at index 0.)
545  int idup, istup, mothup1, mothup2, icolup1, icolup2;
546  double pup1, pup2, pup3, pup4, pup5, vtimup, spinup;
547  for (int ip = 1; ip <= nupSave; ++ip) {
548  if (!getline(is, line)) return false;
549  istringstream getall(line);
550  getall >> idup >> istup >> mothup1 >> mothup2 >> icolup1 >> icolup2
551  >> pup1 >> pup2 >> pup3 >> pup4 >> pup5 >> vtimup >> spinup;
552  if (!getall) return false;
553  particlesSave.push_back( LHAParticle( idup, istup, mothup1, mothup2,
554  icolup1, icolup2, pup1, pup2, pup3, pup4, pup5, vtimup, spinup, -1.) );
555  }
556 
557  // Flavour and x values of hard-process initiators.
558  id1InSave = particlesSave[1].idPart;
559  id2InSave = particlesSave[2].idPart;
560  x1InSave = (eBeamASave > 0.) ? particlesSave[1].ePart / eBeamASave : 0.;
561  x2InSave = (eBeamBSave > 0.) ? particlesSave[2].ePart / eBeamBSave : 0.;
562 
563  // Continue parsing till </event>. Look for optional info on the way.
564  getPDFSave = false;
565  getScale = false;
566  do {
567  if (!getline(is, line)) return false;
568  istringstream getinfo(line);
569  getinfo >> tag;
570  if (!getinfo) return false;
571 
572  // Extract PDF info if present.
573  if (tag == "#pdf" && !getPDFSave) {
574  getinfo >> id1pdfInSave >> id2pdfInSave >> x1pdfInSave >> x2pdfInSave
575  >> scalePDFInSave >> pdf1InSave >> pdf2InSave;
576  if (!getinfo) return false;
577  getPDFSave = true;
578 
579  // Extract scale info if present.
580  } else if (tag == "#" && !getScale) {
581  double scaleIn = 0;
582  for (int i = 3; i < int(particlesSave.size()); ++i)
583  if (particlesSave[i].statusPart == 1) {
584  if ( !(getinfo >> scaleIn) ) return false;
585  particlesSave[i].scalePart = scaleIn;
586  }
587  if (!getinfo) return false;
588  getScale = true;
589  }
590  } while (tag != "</event>" && tag != "</event");
591 
592  // Need id and x values even when no PDF info. Rest empty.
593  if (!getPDFSave) {
594  id1pdfInSave = id1InSave;
595  id2pdfInSave = id2InSave;
596  x1pdfInSave = x1InSave;
597  x2pdfInSave = x2InSave;
598  scalePDFInSave = 0.;
599  pdf1InSave = 0.;
600  pdf2InSave = 0.;
601  }
602 
603  // Reading worked.
604  return true;
605 
606 }
607 
608 //--------------------------------------------------------------------------
609 
610 // Make current event information read in by setNewEventLHEF.
611 
612 bool LHAup::setOldEventLHEF() {
613 
614  // Store saved event, optionally also parton density information.
615  setProcess( idprupSave, xwgtupSave, scalupSave, aqedupSave, aqcdupSave);
616  for (int ip = 1; ip <= nupSave; ++ip) addParticle( particlesSave[ip] );
617  setIdX( id1InSave, id2InSave, x1InSave, x2InSave);
618  setPdf( id1pdfInSave, id2pdfInSave, x1pdfInSave, x2pdfInSave,
619  scalePDFInSave, pdf1InSave, pdf2InSave, getPDFSave);
620 
621  // Done;
622  return true;
623 
624 }
625 
626 //--------------------------------------------------------------------------
627 
628 // Open a file using provided ifstream and return a pointer to an istream
629 // that can be used to process the file.
630 
631 istream* LHAup::openFile(const char *fn, ifstream &ifs) {
632  // Open the file
633  ifs.open(fn);
634  return (istream *) &ifs;
635 }
636 
637 //--------------------------------------------------------------------------
638 
639 // Companion method to 'openFile', above.
640 // Correctly deallocates memory if required before closing the file.
641 
642 void LHAup::closeFile(istream *&is, ifstream &ifs) {
643  // If the istream pointer is not NULL and is not the
644  // same as the ifstream, then delete pointer.
645  if (is && is != &ifs) delete is;
646  is = NULL;
647 
648  // Close the file
649  if (ifs.is_open()) ifs.close();
650 }
651 
652 //==========================================================================
653 
654 // LHAupLHEF class.
655 
656 //--------------------------------------------------------------------------
657 
658 // Routine for doing the job of reading and setting initialization info.
659 
660 bool LHAupLHEF::setInitLHEF( istream & isIn, bool readHead ) {
661 
662  // Done if there was a problem with initialising the reader
663  if (!reader.isGood) return false;
664 
665  // Construct header information (stored in comments strings or optional
666  // header file), so that reading of headers is possible.
667  string comments;
668  comments+="<LesHouchesEvents version =\"3.0\">\n";
669  comments+="<header>\n";
670  comments+=reader.headerComments;
671  comments+="</header>\n";
672  comments+="<init>\n";
673  comments+=reader.initComments;
674  comments+="</init>\n";
675  istringstream is1(comments);
676  bool useComments = (headerfile == NULL);
677  istream & iss((useComments ? is1 : isIn));
678 
679  // Check that first line is consistent with proper LHEF file.
680  string line;
681  if ( useComments && !getline(iss,line)) return false;
682  if (!useComments && !getLine(line)) return false;
683 
684  // What to search for if reading headers; if not reading
685  // headers then return to default behaviour
686  string headerTag = (readHead) ? "<header>" : "<init";
687 
688  // Loop over lines until an <init (or optionally <header>) tag
689  // is found first on a line.
690  string tag = " ";
691  do {
692  if ( useComments && !getline(iss,line)) return false;
693  if (!useComments && !getLine(line)) return false;
694  if (line.find_first_not_of(" \n\t\v\b\r\f\a") != string::npos) {
695  istringstream getfirst(line);
696  getfirst >> tag;
697  if (!getfirst) return false;
698  }
699  } while (tag != "<init>" && tag != "<init" && tag != headerTag);
700 
701  // If header tag found, process if required
702  if (readHead == true && tag == headerTag) {
703  // Temporary local storage
704  map < string, string > headerMap;
705 
706  // Loop over lines until an <init> tag is found.
707  bool read = true, newKey = false;
708  int commentDepth = 0;
709  string key = "base";
710  vector < string > keyVec;
711  while (true) {
712  if ( useComments && !getline(iss,line)) return false;
713  if (!useComments && !getLine(line)) return false;
714 
715  // Tell XML parser to ignore comment and CDATA blocks
716  // If we are currently inside a comment block, check for block end
717  if (commentDepth >= 1 && line.find("-->") != string::npos) {
718  commentDepth--;
719  size_t comBeg = line.find("-->")+2;
720  size_t comEnd = line.find_last_not_of("\n\t\v\b\r\f\a ");
721  if( comEnd == comBeg ) continue;
722  line = line.substr(comBeg,comEnd-comBeg+1);
723  }
724  if (commentDepth >= 1 && line.find("]]>") != string::npos)
725  commentDepth--;
726  // If the comment block did not end on this line, skip to next line
727  if (commentDepth >= 1) continue;
728  // Check for beginning of comment blocks (parse until comment begins)
729  if (line.find("<!--") != string::npos) {
730  if (line.find("-->") == string::npos) commentDepth++;
731  int comBeg = line.find("<!--");
732  line = line.substr(0,comBeg);
733  }
734  // Check for beginning of CDATA statement (parse until CDATA begins)
735  if (line.find("<![cdata[") != string::npos
736  || line.find("<![CDATA[") != string::npos) {
737  if (line.find("]]>") == string::npos) commentDepth++;
738  int comBeg = line.find("<![");
739  line = line.substr(0,comBeg);
740  }
741 
742  // Break lines containing multiple tags into two segments.
743  // (Could be generalized to multiple segments but this is
744  // sufficient to handle at least <tag>info</tag> on same line.
745  size_t firstTagEnd = line.find_first_of(">");
746  size_t secondTagBegin = line.find_first_of("<",firstTagEnd);
747  vector<string> lineVec;
748  if (firstTagEnd != string::npos && secondTagBegin != string::npos) {
749  lineVec.push_back(line.substr(0,secondTagBegin));
750  lineVec.push_back(line.substr(secondTagBegin,
751  line.size()-secondTagBegin));
752  }
753  else {
754  lineVec.push_back(line);
755  }
756 
757  // Loop over segments of current line
758  for (int iVec=0; iVec<int(lineVec.size()); ++iVec) {
759  line = lineVec[iVec];
760 
761  // Clean line to contain only valid characters
762  size_t posBeg = line.find_first_not_of(" \n\t\v\b\r\f\a");
763  size_t posEnd = line.find_last_not_of(" \n\t\v\b\r\f\a");
764  string lineClean = " ";
765  if (posBeg != string::npos && posEnd != string::npos && posBeg
766  < posEnd) {
767  lineClean = line.substr(posBeg, posEnd - posBeg + 1);
768  posBeg = 0;
769  posEnd = lineClean.size();
770  line = lineClean;
771  }
772 
773  // Check for empty line
774  if (lineClean == " " || posBeg >= posEnd) continue;
775 
776  // PZS Jan 2015: Allow multiple open/close tags on a single line.
777  size_t tagBeg = lineClean.find_first_of("<");
778  size_t tagEnd = lineClean.find_first_of(">");
779 
780  while (tagBeg != string::npos && tagBeg < tagEnd) {
781 
782  // Update remainder (non-tag) part of line, for later storage
783  posBeg = tagEnd+1;
784 
785  // Only take the first word of the tag,
786  tag = lineClean.substr(tagBeg + 1, tagEnd - tagBeg - 1);
787  istringstream getfirst(tag);
788  getfirst >> tag;
789 
790  // Prepare for next while iteration:
791  // Look for next tag on line and update posBeg and posEnd.
792  tagBeg = lineClean.find_first_of("<",tagEnd);
793  tagEnd = lineClean.find_first_of(">",tagBeg+1);
794 
795  // Tag present, so handle here
796  if (getfirst) {
797 
798  // Exit condition
799  if (tag == "init") break;
800 
801  // End of header block; keep reading until <init> tag,
802  // but do not store any further information
803  else if (tag == "/header") {
804  read = false;
805  continue;
806 
807  // Opening tag
808  } else if (tag[0] != '/') {
809  keyVec.push_back(tag);
810  newKey = true;
811  continue;
812 
813  // Closing tag that matches current key
814  } else if (tag == "/" + keyVec.back()) {
815  keyVec.pop_back();
816  newKey = true;
817  continue;
818 
819  // Also check for forgotten close tag: next-to-last element
820  } else if (keyVec.size() >= 2
821  && tag == "/" + keyVec[keyVec.size()-2]) {
822  infoPtr->errorMsg("Warning in LHAupLHEF::setInitLHEF:"
823  " corrupt LHEF end tag",keyVec.back());
824  keyVec.pop_back();
825  keyVec.pop_back();
826  newKey = true;
827  continue;
828  }
829 
830  } // if (getfirst)
831 
832  } // Loop over tags
833 
834  // Exit condition
835  if (tag == "init") break;
836 
837  // At this point the (rest of) the line is not a tag;
838  // If no longer reading anything, skip.
839  if (!read) continue;
840 
841  // Check for key change
842  if (newKey) {
843  if (keyVec.empty()) key = "base";
844  else key = keyVec[0];
845  for (size_t i = 1; i < keyVec.size(); i++)
846  key += "." + keyVec[i];
847  newKey = false;
848  }
849 
850  // Check if anything remains to store of this line
851  posBeg = line.find_first_not_of(" \n\t\v\b\r\f\a",posBeg);
852  if (posBeg == string::npos || posBeg > posEnd) continue;
853 
854  // Append information to local storage
855  headerMap[key] += line.substr(posBeg,posEnd - posBeg + 1) + "\n";
856 
857  } // Loop over line segments
858 
859  // Exit condition
860  if (tag == "init") break;
861 
862  } // while (true)
863 
864  // Copy information to info using LHAup::setInfoHeader
865  for (map < string, string >::iterator it = headerMap.begin();
866  it != headerMap.end(); it++)
867  setInfoHeader(it->first, it->second);
868 
869  } // if (readHead == true && tag == headerTag)
870 
871  // Extract beam and strategy info, and store it.
872  int idbmupA, idbmupB;
873  double ebmupA, ebmupB;
874  int pdfgupA, pdfgupB, pdfsupA, pdfsupB, idwtup, nprup;
875 
876  idbmupA = reader.heprup.IDBMUP.first;
877  idbmupB = reader.heprup.IDBMUP.second;
878  ebmupA = reader.heprup.EBMUP.first;
879  ebmupB = reader.heprup.EBMUP.second;
880  pdfgupA = reader.heprup.PDFGUP.first;
881  pdfgupB = reader.heprup.PDFGUP.first;
882  pdfsupA = reader.heprup.PDFSUP.first;
883  pdfsupB = reader.heprup.PDFSUP.second;
884  idwtup = reader.heprup.IDWTUP;
885  nprup = reader.heprup.NPRUP;
886 
887  setBeamA(idbmupA, ebmupA, pdfgupA, pdfsupA);
888  setBeamB(idbmupB, ebmupB, pdfgupB, pdfsupB);
889  setStrategy(idwtup);
890 
891  // Read in process info, one process at a time, and store it.
892  double xsecup, xerrup, xmaxup;
893  xSecSumSave = 0.;
894  xErrSumSave = 0.;
895  int lprup;
896  infoPtr->sigmaLHEFSave.resize(0);
897  for (int ip = 0; ip < nprup; ++ip) {
898  xsecup = reader.heprup.XSECUP[ip];
899  xerrup = reader.heprup.XERRUP[ip];
900  xmaxup = reader.heprup.XMAXUP[ip];
901  lprup = reader.heprup.LPRUP[ip];
902  addProcess(lprup, xsecup, xerrup, xmaxup);
903  xSecSumSave += xsecup;
904  xErrSumSave += pow(xerrup,2);
905  infoPtr->sigmaLHEFSave.push_back(xsecup);
906  }
907  xErrSumSave = sqrt(xErrSumSave);
908 
909  // Now extract LHEF 2.0/3.0 novelties.
910  infoPtr->setLHEF3InitInfo();
911  if (reader.version > 1) {
912  infoPtr->setLHEF3InitInfo( reader.version,
913  &reader.heprup.initrwgt, &(reader.heprup.generators),
914  &(reader.heprup.weightgroups), &(reader.heprup.weights),
915  reader.headerBlock);
916  }
917 
918  // Reading worked.
919  return true;
920 }
921 
922 //--------------------------------------------------------------------------
923 
924 // Routine for doing the job of reading and setting info on next event.
925 
926 bool LHAupLHEF::setNewEventLHEF() {
927 
928  // Done if the reader finished preemptively.
929  if(!reader.readEvent()) return false;
930 
931  // Extract process info and store it.
932  nupSave = reader.hepeup.NUP;
933  idprupSave = reader.hepeup.IDPRUP;
934  xwgtupSave = reader.hepeup.XWGTUP;
935  scalupSave = reader.hepeup.SCALUP;
936  aqedupSave = reader.hepeup.AQEDUP;
937  aqcdupSave = reader.hepeup.AQCDUP;
938 
939  // Reset particlesSave vector, add slot-0 empty particle.
940  particlesSave.clear();
941  particlesSave.push_back( Pythia8::LHAParticle() );
942 
943  // Read in particle info one by one, and store it.
944  // Note unusual C++ loop range, to better reflect LHA/Fortran standard.
945  // (Recall that process(...) above added empty particle at index 0.)
946  int idup, istup, mothup1, mothup2, icolup1, icolup2;
947  double pup1, pup2, pup3, pup4, pup5, vtimup, spinup;
948  for ( int i = 0; i < reader.hepeup.NUP; ++i ) {
949  // Extract information stored in reader.
950  idup = reader.hepeup.IDUP[i];
951  istup = reader.hepeup.ISTUP[i];
952  mothup1 = reader.hepeup.MOTHUP[i].first;
953  mothup2 = reader.hepeup.MOTHUP[i].second;
954  icolup1 = reader.hepeup.ICOLUP[i].first;
955  icolup2 = reader.hepeup.ICOLUP[i].second;
956  pup1 = reader.hepeup.PUP[i][0];
957  pup2 = reader.hepeup.PUP[i][1];
958  pup3 = reader.hepeup.PUP[i][2];
959  pup4 = reader.hepeup.PUP[i][3];
960  pup5 = reader.hepeup.PUP[i][4];
961  vtimup = reader.hepeup.VTIMUP[i];
962  spinup = reader.hepeup.SPINUP[i];
963  particlesSave.push_back( Pythia8::LHAParticle( idup,istup,mothup1,mothup2,
964  icolup1, icolup2, pup1, pup2, pup3, pup4, pup5, vtimup, spinup, -1.) );
965  }
966 
967  // Flavour and x values of hard-process initiators.
968  id1InSave = particlesSave[1].idPart;
969  id2InSave = particlesSave[2].idPart;
970  x1InSave = (eBeamA() > 0.) ? particlesSave[1].ePart / eBeamA() : 0.;
971  x2InSave = (eBeamB() > 0.) ? particlesSave[2].ePart / eBeamB() : 0.;
972 
973  // Parse event comments and look for optional info on the way.
974  std::string line, tag;
975  std::stringstream ss(reader.eventComments);
976  getPDFSave = false;
977  getScale = false;
978  getScale = (setScalesFromLHEF && reader.version == 1) ? false : true;
979  while (getline(ss, line)) {
980  istringstream getinfo(line);
981  getinfo >> tag;
982  if (!getinfo) break;
983  // Extract PDF info if present.
984  if (tag == "#pdf" && !getPDFSave) {
985  getinfo >> id1pdfInSave >> id2pdfInSave >> x1pdfInSave >> x2pdfInSave
986  >> scalePDFInSave >> pdf1InSave >> pdf2InSave;
987  if (!getinfo) return false;
988  getPDFSave = true;
989  // Extract scale info if present.
990  } else if (tag == "#" && !getScale) {
991  double scaleIn = 0;
992  for (int i = 3; i < int(particlesSave.size()); ++i)
993  if (particlesSave[i].statusPart == 1) {
994  if ( !(getinfo >> scaleIn) ) return false;
995  particlesSave[i].scalePart = scaleIn;
996  }
997  if (!getinfo) return false;
998  getScale = true;
999  }
1000  }
1001 
1002  // Set production scales from <scales> tag.
1003  if ( setScalesFromLHEF && reader.version > 1 ){
1004  for ( map<string,double>::const_iterator
1005  it = reader.hepeup.scalesSave.attributes.begin();
1006  it != reader.hepeup.scalesSave.attributes.end(); ++it ) {
1007  if ( it->first.find_last_of("_") != string::npos) {
1008  unsigned iFound = it->first.find_last_of("_") + 1;
1009  int iPos = atoi(it->first.substr(iFound).c_str());
1010  // Only set production scales of final particles.
1011  if ( iPos < int(particlesSave.size())
1012  && particlesSave[iPos].statusPart == 1)
1013  particlesSave[iPos].scalePart = it->second;
1014  }
1015  }
1016  }
1017 
1018  // Need id and x values even when no PDF info. Rest empty.
1019  if (!getPDFSave) {
1020  id1pdfInSave = id1InSave;
1021  id2pdfInSave = id2InSave;
1022  x1pdfInSave = x1InSave;
1023  x2pdfInSave = x2InSave;
1024  scalePDFInSave = 0.;
1025  pdf1InSave = 0.;
1026  pdf2InSave = 0.;
1027  }
1028 
1029  // Now extract LHEF 2.0/3.0 novelties.
1030  infoPtr->setLHEF3EventInfo();
1031  // Set everything for 2.0 and 3.0
1032  if (reader.version > 1) {
1033  infoPtr->setLHEF3EventInfo( &reader.hepeup.attributes,
1034  &reader.hepeup.weights_detailed, &reader.hepeup.weights_compressed,
1035  &reader.hepeup.scalesSave, &reader.hepeup.weightsSave,
1036  &reader.hepeup.rwgtSave, reader.weights_detailed_vector(),
1037  reader.eventComments, reader.hepeup.XWGTUP);
1038  // Try to at least set the event attributes for 1.0
1039  } else {
1040  infoPtr->setLHEF3EventInfo( &reader.hepeup.attributes, 0, 0, 0, 0, 0,
1041  vector<double>(), "", 1.0);
1042  }
1043 
1044  // Reading worked.
1045  return true;
1046 
1047 }
1048 
1049 //==========================================================================
1050 
1051 // LHAupFromPYTHIA8 class.
1052 
1053 //--------------------------------------------------------------------------
1054 
1055 // Read in initialization information from PYTHIA 8.
1056 
1057 bool LHAupFromPYTHIA8::setInit() {
1058 
1059  // Read in beam from Info class. Parton density left empty.
1060  int idbmupA = infoPtr->idA();
1061  int idbmupB = infoPtr->idB();
1062  double ebmupA = infoPtr->eA();
1063  double ebmupB = infoPtr->eB();
1064  int pdfgupA = 0;
1065  int pdfgupB = 0;
1066  int pdfsupA = 0;
1067  int pdfsupB = 0;
1068  setBeamA(idbmupA, ebmupA, pdfgupA, pdfsupA);
1069  setBeamB(idbmupB, ebmupB, pdfgupB, pdfsupB);
1070 
1071  // Currently only one allowed strategy.
1072  int idwtup = 3;
1073  setStrategy(idwtup);
1074 
1075  // Only one process with dummy information. (Can overwrite at the end.)
1076  int lprup = 9999;
1077  double xsecup = 1.;
1078  double xerrup = 0.;
1079  double xmaxup = 1.;
1080  addProcess(lprup, xsecup, xerrup, xmaxup);
1081 
1082  // Done.
1083  return true;
1084 
1085 }
1086 
1087 //--------------------------------------------------------------------------
1088 
1089 // Read in event information from PYTHIA 8.
1090 
1091 bool LHAupFromPYTHIA8::setEvent( int) {
1092 
1093  // Read process information from Info class, and store it.
1094  // Note: renormalization scale here, factorization further down.
1095  // For now always convert to process 9999, instead of infoPtr->code().
1096  int idprup = 9999;
1097  double xwgtup = infoPtr->weight();
1098  double scalup = infoPtr->QRen();
1099  double aqedup = infoPtr->alphaEM();
1100  double aqcdup = infoPtr->alphaS();
1101  setProcess(idprup, xwgtup, scalup, aqedup, aqcdup);
1102 
1103  // Read in particle info one by one, excluding zero and beams, and store it.
1104  // Note unusual C++ loop range, to better reflect LHA/Fortran standard.
1105  int nup = processPtr->size() - 3;
1106  int idup, statusup, istup, mothup1, mothup2, icolup1, icolup2;
1107  double pup1, pup2, pup3, pup4, pup5, vtimup, spinup;
1108  for (int ip = 1; ip <= nup; ++ip) {
1109  Particle& particle = (*processPtr)[ip + 2];
1110  idup = particle.id();
1111  // Convert from PYTHIA8 to LHA status codes.
1112  statusup = particle.status();
1113  if (ip < 3) istup = -1;
1114  else if (statusup < 0) istup = 2;
1115  else istup = 1;
1116  mothup1 = max(0, particle.mother1() - 2);
1117  mothup2 = max(0, particle.mother2() - 2);
1118  icolup1 = particle.col();
1119  icolup2 = particle.acol();
1120  pup1 = particle.px();
1121  pup2 = particle.py();
1122  pup3 = particle.pz();
1123  pup4 = particle.e();
1124  pup5 = particle.m();
1125  vtimup = particle.tau();
1126  spinup = particle.pol();
1127  addParticle(idup, istup, mothup1, mothup2, icolup1, icolup2,
1128  pup1, pup2, pup3, pup4, pup5, vtimup, spinup, -1.) ;
1129  }
1130 
1131  // Extract hard-process initiator information from Info class, and store it.
1132  int id1up = infoPtr->id1();
1133  int id2up = infoPtr->id2();
1134  double x1up = infoPtr->x1();
1135  double x2up = infoPtr->x2();
1136  setIdX( id1up, id2up, x1up, x2up);
1137 
1138  // Also extract pdf information from Info class, and store it.
1139  int id1pdfup = infoPtr->id1pdf();
1140  int id2pdfup = infoPtr->id2pdf();
1141  double x1pdfup = infoPtr->x1pdf();
1142  double x2pdfup = infoPtr->x2pdf();
1143  double scalePDFup = infoPtr->QFac();
1144  double pdf1up = infoPtr->pdf1();
1145  double pdf2up = infoPtr->pdf2();
1146  setPdf(id1pdfup, id2pdfup, x1pdfup, x2pdfup, scalePDFup, pdf1up,
1147  pdf2up, true);
1148 
1149  // Done.
1150  return true;
1151 
1152 }
1153 
1154 //--------------------------------------------------------------------------
1155 
1156 // Update cross-section information at the end of the run.
1157 
1158 bool LHAupFromPYTHIA8::updateSigma() {
1159 
1160  // Read out information from PYTHIA 8 and send it in to LHA.
1161  double sigGen = CONVERTMB2PB * infoPtr->sigmaGen();
1162  double sigErr = CONVERTMB2PB * infoPtr->sigmaErr();
1163  setXSec(0, sigGen);
1164  setXErr(0, sigErr);
1165 
1166  // Done.
1167  return true;
1168 
1169 }
1170 
1171 //==========================================================================
1172 
1173 // LHEF3FromPythia8 class.
1174 
1175 //--------------------------------------------------------------------------
1176 
1177 // Function to open the output file stream.
1178 
1179 bool LHEF3FromPythia8::openLHEF(string fileNameIn) {
1180 
1181  // Open file for writing. Reset it to be empty.
1182  fileName = fileNameIn;
1183  const char* cstring = fileName.c_str();
1184  osLHEF.open(cstring, ios::out | ios::trunc);
1185  if (!osLHEF) {
1186  infoPtr->errorMsg("Error in LHAup::openLHEF:"
1187  " could not open file", fileName);
1188  return false;
1189  }
1190 
1191  // Done.
1192  return true;
1193 }
1194 
1195 //--------------------------------------------------------------------------
1196 
1197 // Routine for reading, setting and printing the initialisation info.
1198 
1199 bool LHEF3FromPythia8::setInit() {
1200 
1201  // Start with clean writer.
1202  writer.headerStream.str("");
1203  writer.initStream.str("");
1204  writer.headerStream.clear();
1205  writer.initStream.clear();
1206 
1207  // PDG id's of beam particles. (first/second is in +/-z direction).
1208  heprup.IDBMUP = make_pair(infoPtr->idA(), infoPtr->idB());
1209 
1210  // Energy of beam particles given in GeV.
1211  heprup.EBMUP = make_pair(infoPtr->eA(),infoPtr->eB());
1212 
1213  // The author group for the PDF used for the beams according to the
1214  // PDFLib specification.
1215  heprup.PDFGUP = make_pair(0,0);
1216 
1217  // The id number the PDF used for the beams according to the
1218  // PDFLib specification.
1219  heprup.PDFSUP = make_pair(0,0);
1220 
1221  // Master switch indicating how the ME generator envisages the
1222  // events weights should be interpreted according to the Les Houches
1223  // accord.
1224  heprup.IDWTUP = -4;
1225 
1226  // The number of different subprocesses in this file.
1227  heprup.NPRUP = 1;
1228 
1229  // The cross sections for the different subprocesses in pb.
1230  vector<double> XSECUP;
1231  for ( int i=0; i < heprup.NPRUP; ++i)
1232  XSECUP.push_back(CONVERTMB2PB * infoPtr->sigmaGen());
1233  heprup.XSECUP = XSECUP;
1234 
1235  // The statistical error in the cross sections for the different
1236  // subprocesses in pb.
1237  vector<double> XERRUP;
1238  for ( int i=0; i < heprup.NPRUP; ++i)
1239  XERRUP.push_back(CONVERTMB2PB * infoPtr->sigmaErr());
1240  heprup.XERRUP = XERRUP;
1241 
1242  // The maximum event weights (in HEPEUP::XWGTUP) for different
1243  vector<double> XMAXUP;
1244  for ( int i=0; i < heprup.NPRUP; ++i) XMAXUP.push_back(0.0);
1245  heprup.XMAXUP = XMAXUP;
1246 
1247  // The subprocess code for the different subprocesses.
1248  vector<int> LPRUP;
1249  for ( int i=0; i < heprup.NPRUP; ++i) LPRUP.push_back(9999+i);
1250  heprup.LPRUP = LPRUP;
1251 
1252  // Contents of the LHAinitrwgt tag
1253  if (infoPtr->initrwgt) heprup.initrwgt = *(infoPtr->initrwgt);
1254 
1255  // Contents of the LHAgenerator tags.
1256  if (infoPtr->generators) heprup.generators = *(infoPtr->generators);
1257 
1258  // A map of the LHAweightgroup tags, indexed by name.
1259  if (infoPtr->weightgroups) heprup.weightgroups = *(infoPtr->weightgroups);
1260 
1261  // A map of the LHAweight tags, indexed by name.
1262  if (infoPtr->init_weights) heprup.weights = *(infoPtr->init_weights);
1263 
1264  // Get init information.
1265  writer.version = 3;
1266 
1267  string line, tag;
1268 
1269  // Not implemented yet:
1270  // Write header block of input LHEF
1271  // Write header comments of input LHEF
1272 
1273  // Print Pythia settings
1274  stringstream setout;
1275  settingsPtr->writeFile(setout, true);
1276  while ( getline(setout,line) )
1277  writer.headerBlock() << line << "\n";
1278 
1279  // Not implemented yet:
1280  // Write init comments of input LHEF.
1281 
1282  writer.heprup = heprup;
1283  writer.init();
1284 
1285  // Done
1286  return true;
1287 }
1288 
1289 //--------------------------------------------------------------------------
1290 
1291 // Routine for reading, setting and printing the next event.
1292 
1293 bool LHEF3FromPythia8::setEvent(int) {
1294 
1295  Event event = *eventPtr;
1296 
1297  // Begin filling Les Houches blocks.
1298  hepeup.clear();
1299  hepeup.resize(0);
1300 
1301  // The number of particle entries in the current event.
1302  hepeup.NUP = 2;
1303  for ( int i = 0; i < int(event.size()); ++i) {
1304  if ( event[i].status() == -22) ++hepeup.NUP;
1305  if ( event[i].isFinal()) ++hepeup.NUP;
1306  }
1307 
1308  // The subprocess code for this event (as given in LPRUP).
1309  hepeup.IDPRUP = 9999;
1310 
1311  // The weight for this event.
1312  hepeup.XWGTUP = infoPtr->weight();
1313 
1314  // The PDF weights for the two incoming partons. Note that this
1315  // variable is not present in the current LesHouches accord
1316  // (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>),
1317  // hopefully it will be present in a future accord.
1318  hepeup.XPDWUP = make_pair(0,0);
1319 
1320  // The scale in GeV used in the calculation of the PDF's in this
1321  // event.
1322  hepeup.SCALUP = eventPtr->scale();
1323 
1324  // The value of the QED coupling used in this event.
1325  hepeup.AQEDUP = infoPtr->alphaEM();
1326 
1327  // The value of the QCD coupling used in this event.
1328  hepeup.AQCDUP = infoPtr->alphaS();
1329 
1330  // Find incoming particles.
1331  int in1, in2;
1332  in1 = in2 = 0;
1333  for ( int i = 0; i < int( event.size()); ++i) {
1334  if ( event[i].mother1() == 1 && in1 == 0) in1 = i;
1335  if ( event[i].mother1() == 2 && in2 == 0) in2 = i;
1336  }
1337 
1338  // Find resonances in hard process.
1339  vector<int> hardResonances;
1340  for ( int i = 0; i < int(event.size()); ++i) {
1341  if ( event[i].status() != -22) continue;
1342  if ( event[i].mother1() != 3) continue;
1343  if ( event[i].mother2() != 4) continue;
1344  hardResonances.push_back(i);
1345  }
1346 
1347  // Find resonances and decay products after showering.
1348  vector<int> evolvedResonances;
1349  vector<pair<int,int> > evolvedDecayProducts;
1350  for ( int j = 0; j < int(hardResonances.size()); ++j) {
1351  for ( int i = int(event.size())-1; i > 0; --i) {
1352  if ( i == hardResonances[j]
1353  || (event[i].mother1() == event[i].mother2()
1354  && event[i].isAncestor(hardResonances[j])) ) {
1355  evolvedResonances.push_back(i);
1356  evolvedDecayProducts.push_back(
1357  make_pair(event[i].daughter1(), event[i].daughter2()) );
1358  break;
1359  }
1360  }
1361  }
1362 
1363  // Event for bookkeeping of resonances.
1364  Event now = Event();
1365  now.init("(dummy event)", particleDataPtr);
1366  now.reset();
1367 
1368  // The PDG id's for the particle entries in this event.
1369  // The status codes for the particle entries in this event.
1370  // Indices for the first and last mother for the particle entries in
1371  // this event.
1372  // The colour-line indices (first(second) is (anti)colour) for the
1373  // particle entries in this event.
1374  // Lab frame momentum (Px, Py, Pz, E and M in GeV) for the particle
1375  // entries in this event.
1376  // Invariant lifetime (c*tau, distance from production to decay in
1377  // mm) for the particle entries in this event.
1378  // Spin info for the particle entries in this event given as the
1379  // cosine of the angle between the spin vector of a particle and the
1380  // 3-momentum of the decaying particle, specified in the lab frame.
1381  hepeup.IDUP.push_back(event[in1].id());
1382  hepeup.IDUP.push_back(event[in2].id());
1383  hepeup.ISTUP.push_back(-1);
1384  hepeup.ISTUP.push_back(-1);
1385  hepeup.MOTHUP.push_back(make_pair(0,0));
1386  hepeup.MOTHUP.push_back(make_pair(0,0));
1387  hepeup.ICOLUP.push_back(make_pair(event[in1].col(),event[in1].acol()));
1388  hepeup.ICOLUP.push_back(make_pair(event[in2].col(),event[in2].acol()));
1389  vector <double> p;
1390  p.push_back(0.0);
1391  p.push_back(0.0);
1392  p.push_back(event[in1].pz());
1393  p.push_back(event[in1].e());
1394  p.push_back(event[in1].m());
1395  hepeup.PUP.push_back(p);
1396  p.resize(0);
1397  p.push_back(0.0);
1398  p.push_back(0.0);
1399  p.push_back(event[in2].pz());
1400  p.push_back(event[in2].e());
1401  p.push_back(event[in2].m());
1402  hepeup.PUP.push_back(p);
1403  p.resize(0);
1404  hepeup.VTIMUP.push_back(event[in1].tau());
1405  hepeup.VTIMUP.push_back(event[in2].tau());
1406  hepeup.SPINUP.push_back(event[in1].pol());
1407  hepeup.SPINUP.push_back(event[in2].pol());
1408 
1409  now.append(event[in1]);
1410  now.append(event[in2]);
1411 
1412  // Attach resonances
1413  for ( int j = 0; j < int(evolvedResonances.size()); ++j) {
1414  int i = evolvedResonances[j];
1415  hepeup.IDUP.push_back(event[i].id());
1416  hepeup.ISTUP.push_back(2);
1417  hepeup.MOTHUP.push_back(make_pair(1,2));
1418  hepeup.ICOLUP.push_back(make_pair(event[i].col(),event[i].acol()));
1419  p.push_back(event[i].px());
1420  p.push_back(event[i].py());
1421  p.push_back(event[i].pz());
1422  p.push_back(event[i].e());
1423  p.push_back(event[i].m());
1424  hepeup.PUP.push_back(p);
1425  p.resize(0);
1426  hepeup.VTIMUP.push_back(event[i].tau());
1427  hepeup.SPINUP.push_back(event[i].pol());
1428  now.append(event[i]);
1429  now.back().statusPos();
1430  }
1431 
1432  // Loop through event and attach remaining decays
1433  vector<int> iSkip;
1434  int iDec = 0;
1435  do {
1436 
1437  if ( now[iDec].isFinal() && now[iDec].canDecay()
1438  && now[iDec].mayDecay() && now[iDec].isResonance() ) {
1439 
1440  int iD1 = now[iDec].daughter1();
1441  int iD2 = now[iDec].daughter2();
1442 
1443  // Done if no daughters exist.
1444  if ( iD1 == 0 || iD2 == 0 ) continue;
1445 
1446  // Attach daughters.
1447  for ( int k = iD1; k <= iD2; ++k ) {
1448  Particle partNow = event[k];
1449  hepeup.IDUP.push_back(partNow.id());
1450  hepeup.MOTHUP.push_back(make_pair(iDec,iDec));
1451  hepeup.ICOLUP.push_back(make_pair(partNow.col(),partNow.acol()));
1452  p.push_back(partNow.px());
1453  p.push_back(partNow.py());
1454  p.push_back(partNow.pz());
1455  p.push_back(partNow.e());
1456  p.push_back(partNow.m());
1457  hepeup.PUP.push_back(p);
1458  p.resize(0);
1459  hepeup.VTIMUP.push_back(partNow.tau());
1460  hepeup.SPINUP.push_back(partNow.pol());
1461  now.append(partNow);
1462  if ( partNow.canDecay() && partNow.mayDecay() && partNow.isResonance()){
1463  now.back().statusPos();
1464  hepeup.ISTUP.push_back(2);
1465  } else
1466  hepeup.ISTUP.push_back(1);
1467 
1468  iSkip.push_back(k);
1469  }
1470 
1471  // End of loop over all entries.
1472  }
1473  } while (++iDec < now.size());
1474 
1475  // Attach final state particles
1476  for ( int i = 0; i < int(event.size()); ++i) {
1477  if (!event[i].isFinal()) continue;
1478  // Skip resonance decay products.
1479  bool skip = false;
1480  for ( int j = 0; j < int(evolvedDecayProducts.size()); ++j) {
1481  skip = ( i >= evolvedDecayProducts[j].first
1482  && i <= evolvedDecayProducts[j].second);
1483  }
1484  if (skip) continue;
1485  for ( int j = 0; j < int(iSkip.size()); ++j) {
1486  skip = ( i == iSkip[j] );
1487  }
1488  if (skip) continue;
1489 
1490  hepeup.IDUP.push_back(event[i].id());
1491  hepeup.ISTUP.push_back(1);
1492  hepeup.MOTHUP.push_back(make_pair(1,2));
1493  hepeup.ICOLUP.push_back(make_pair(event[i].col(),event[i].acol()));
1494  p.push_back(event[i].px());
1495  p.push_back(event[i].py());
1496  p.push_back(event[i].pz());
1497  p.push_back(event[i].e());
1498  p.push_back(event[i].m());
1499  hepeup.PUP.push_back(p);
1500  p.resize(0);
1501  hepeup.VTIMUP.push_back(event[i].tau());
1502  hepeup.SPINUP.push_back(event[i].pol());
1503  now.append(event[i]);
1504  }
1505 
1506  // A pointer to the current HEPRUP object.
1507  hepeup.heprup = &heprup;
1508 
1509  // The weights associated with this event, as given by the LHAwgt tags.
1510  if (infoPtr->weights_detailed)
1511  hepeup.weights_detailed = *(infoPtr->weights_detailed);
1512 
1513  // The weights associated with this event, as given by the LHAweights tags.
1514  if (infoPtr->weights_compressed)
1515  hepeup.weights_compressed = *(infoPtr->weights_compressed);
1516 
1517  // Contents of the LHAscales tag
1518  if (infoPtr->scales) hepeup.scalesSave = *(infoPtr->scales);
1519 
1520  // Contents of the LHAweights tag (compressed format)
1521  if (infoPtr->weights) hepeup.weightsSave = *(infoPtr->weights);
1522 
1523  // Contents of the LHArwgt tag (detailed format)
1524  if (infoPtr->rwgt) hepeup.rwgtSave = *(infoPtr->rwgt);
1525 
1526  // Any other attributes.
1527  if (infoPtr->eventAttributes)
1528  hepeup.attributes = *(infoPtr->eventAttributes);
1529 
1530  // Not implemented yet:
1531  // Write event comments of input LHEF.
1532 
1533  writer.hepeup = hepeup;
1534  if (writeToFile) writer.writeEvent(&hepeup,pDigits);
1535 
1536  return true;
1537 
1538 }
1539 
1540 //--------------------------------------------------------------------------
1541 
1542 // Write end of a Les Houches Event File and close it.
1543 
1544 bool LHEF3FromPythia8::closeLHEF(bool updateInit) {
1545 
1546  // Write an end to the file.
1547  osLHEF << "</LesHouchesEvents>" << endl;
1548  osLHEF.close();
1549 
1550  // Optionally update the cross section information.
1551  if (updateInit) {
1552  const char* cstring = fileName.c_str();
1553  osLHEF.open(cstring, ios::in | ios::out);
1554 
1555  setInit();
1556  osLHEF.close();
1557  }
1558 
1559  // Done.
1560  return true;
1561 
1562 }
1563 
1564 //==========================================================================
1565 
1566 } // end namespace Pythia8
Definition: AgUStep.h:26