eic-smear  1.0.3
A collection of ROOT classes for Monte Carlo events and a fast-smearing code simulating detector effects for the Electron-Ion Collider task force
File.cxx
Go to the documentation of this file.
1 
10 #include "eicsmear/erhic/File.h"
11 
12 #include <fstream>
13 #include <sstream>
14 #include <string>
15 
16 #include <TSystem.h>
17 
23 
24 namespace erhic {
25 
27 
29 
30 bool LogReaderPythia::Extract(const std::string& file) {
31  // First we get the cross section from the log file.
32  std::ifstream ifs(file.c_str(), std::ios::in);
33 
34  if (!ifs.is_open()) return false;
35 
36  std::string line;
37  const std::string searchPattern("Pythia total cross section normalisation:");
38  std::string normalisation;
39  std::string nEvents;
40 
41  while (ifs.good()) {
42  std::getline(ifs, line);
43  size_t position = line.find(searchPattern);
44  if (position != std::string::npos) {
45  // We found the line.
46  // Erase the text preceding the cross section.
47  std::stringstream ss;
48  line.erase(0, position + searchPattern.length());
49  ss.str("");
50  ss.clear();
51  ss << line;
52  ss >> normalisation;
53  } // if
54  const std::string searchPattern2("Total Number of generated events");
55  position = line.find(searchPattern2);
56  if (position != std::string::npos) {
57  // We found the line.
58  // Erase the text preceding the cross section.
59  std::stringstream ss;
60  line.erase(0, position + searchPattern2.length());
61  ss.str("");
62  ss.clear();
63  ss << line;
64  ss >> nEvents;
65  } // if
66  } // while
67  crossSection_.SetString(normalisation.c_str());
68  std::cout << crossSection_.GetString().Atof() << std::endl;
69  nEvents_.SetString(nEvents.c_str());
70  std::cout << nEvents_.GetString().Atoi() << std::endl;
71  std::cout << "Extracted information from " << file << std::endl;
72  return true;
73 }
74 
75 Int_t LogReaderPythia::Save() const {
76  return
77  crossSection_.Write("crossSection") +
78  nEvents_.Write("nEvents");
79  nEvents_.Write("nTrials");
80 }
81 
82 //
83 // class LogReaderPepsi
84 //
85 
87 
89 
90 bool LogReaderPepsi::Extract(const std::string& file) {
91  // First we get the cross section from the log file.
92  std::ifstream ifs(file.c_str(), std::ios::in);
93  if (!ifs.is_open()) return false;
94  std::string line;
95  const std::string searchPattern(
96  "total cross section in pb from MC simulation");
97  std::string normalisation;
98  std::string nEvents;
99  while (ifs.good()) {
100  std::getline(ifs, line);
101  size_t position = line.find(searchPattern);
102  if (position != std::string::npos) {
103  // We found the line.
104  // Erase the text preceding the cross section.
105  std::stringstream ss;
106  line.erase(0, position + searchPattern.length());
107  ss.str("");
108  ss.clear();
109  ss << line;
110  double value;
111  // Divide by 1,000,000 to go from pb to microbarn
112  ss >> value;
113  value /= 1.e6;
114  ss.str("");
115  ss.clear();
116  ss << value;
117  ss >> normalisation;
118  } // if
119  const std::string searchPattern2("Total Number of trials");
120  position = line.find(searchPattern2);
121  if (position != std::string::npos) {
122  // We found the line.
123  // Erase the text preceding the cross section.
124  std::stringstream ss;
125  line.erase(0, position + searchPattern2.length());
126  ss.str("");
127  ss.clear();
128  ss << line;
129  ss >> nEvents;
130  } // if
131  } // while
132  crossSection_.SetString(normalisation.c_str());
133  std::cout << crossSection_.GetString().Atof() << std::endl;
134  nEvents_.SetString(nEvents.c_str());
135  std::cout << nEvents_.GetString().Atoi() << std::endl;
136  std::cout << "Extracted information from " << file << std::endl;
137  return true;
138 }
139 
140 Int_t LogReaderPepsi::Save() const {
141  return
142  crossSection_.Write("crossSection") +
143  nEvents_.Write("nEvents");
144 }
145 
146 //
147 // class LogReaderDjangoh
148 //
149 
151 
153 
154 bool LogReaderDjangoh::Extract(const std::string& file) {
155  // First we get the cross section from the log file.
156  std::ifstream ifs(file.c_str(), std::ios::in);
157 
158  if (!ifs.is_open()) return false;
159 
160  std::string line;
161  // There are two places we need to look for cross sections.
162  // As standard, look for the line starting with
163  // Cross-section from HERACLES
164  // Sometimes there will be an additional line starting
165  // Total cross section is now SIGTOT =
166  // *If* this line is present we take the cross section from there,
167  // otherwise use the 'HERACLES' line, which is always present.
168  // Both lines give cross section in pb.
169  const std::string xsecPattern("Cross-section from HERACLES =");
170  const std::string xsecAltPattern("Total cross section is now SIGTOT =");
171  std::string normalisation;
172  std::string nEvents;
173 
174  while (ifs.good()) {
175  std::getline(ifs, line);
176  // Look for normal cross section line, unless the cross section
177  // was already set (via the alternative line, see below).
178  size_t position = line.find(xsecPattern);
179  if (position != std::string::npos && normalisation.empty()) {
180  // We found the line.
181  // Erase the text preceding the cross section.
182  std::stringstream ss;
183  line.erase(0, position + xsecPattern.length());
184  ss << line;
185  double value;
186  // Divide by 1,000,000 to go from pb to microbarn
187  ss >> value;
188  value /= 1.e6;
189  ss.str("");
190  ss.clear();
191  ss << value;
192  ss >> normalisation;
193  } // if
194  position = line.find(xsecAltPattern);
195  // Look for alternative cross section.
196  if (position != std::string::npos) {
197  // We found the line.
198  // Erase the text preceding the cross section.
199  std::stringstream ss;
200  line.erase(0, position + xsecAltPattern.length());
201  ss << line;
202  double value;
203  // Divide by 1,000,000 to go from pb to microbarn
204  ss >> value;
205  value /= 1.e6;
206  ss.str("");
207  ss.clear();
208  ss << value;
209  ss >> normalisation;
210  } // if
211  const std::string searchPattern2("TOTAL EVENT NUMBER");
212  position = line.find(searchPattern2);
213  if (position != std::string::npos) {
214  // We found the line.
215  // Erase the text preceding the cross section.
216  std::stringstream ss;
217  line.erase(0, position + searchPattern2.length());
218  ss.str("");
219  ss.clear();
220  ss << line;
221  ss >> nEvents;
222  } // if
223  } // while
224 
225  crossSection_.SetString(normalisation.c_str());
226  std::cout << crossSection_.GetString().Atof() << std::endl;
227  nEvents_.SetString(nEvents.c_str());
228  std::cout << nEvents_.GetString().Atoi() << std::endl;
229 
230  std::cout << "Extracted information from " << file << std::endl;
231  return true;
232 }
233 
234 Int_t LogReaderDjangoh::Save() const {
235  return
236  crossSection_.Write("crossSection") +
237  nEvents_.Write("nEvents");
238 }
239 
240 
241 bool LogReaderMilou::Extract(const std::string& file) {
242  // First we get the cross section from the log file.
243  std::ifstream ifs(file.c_str(), std::ios::in);
244 
245  if (!ifs.is_open()) return false;
246 
247  std::string line;
248 
249  const std::string nEventPattern("Number of generated events =");
250  const std::string xsecPattern("Total cross-section (nb) :");
251  const std::string errorPattern("Error :");
252 
253  std::string tmp("");
254 
255  std::stringstream ss;
256 
257  while (ifs.good()) {
258  std::getline(ifs, line);
259  ss.str("");
260  ss.clear();
261  // Look for one of the search patterns.
262  if (line.find(nEventPattern) != std::string::npos) {
263  line.erase(0,
264  line.find(nEventPattern) + nEventPattern.length());
265  ss << line;
266  ss >> tmp;
267  nEvents_.SetString(tmp.c_str());
268  } else if (line.find(xsecPattern) != std::string::npos) {
269  line.erase(0,
270  line.find(xsecPattern) + xsecPattern.length());
271  ss << line;
272  ss >> tmp;
273  crossSection_.SetString(tmp.c_str());
274  } else if (line.find(errorPattern) != std::string::npos) {
275  line.erase(0,
276  line.find(errorPattern) + errorPattern.length());
277  ss << line;
278  ss >> tmp;
279  crossSectionError_.SetString(tmp.c_str());
280  } // if
281  } // while
282  // Return true if all the strings are filled, or false if any
283  // of them are empty.
284  return !(nEvents_.GetString().IsNull() ||
285  crossSection_.GetString().IsNull() ||
286  crossSectionError_.GetString().IsNull());
287 }
288 
289 Int_t LogReaderMilou::Save() const {
290  Int_t bytes(0);
291  bytes += nEvents_.Write("nEvents");
292  bytes += crossSection_.Write("crossSection");
293  bytes += crossSectionError_.Write("crossSectionError");
294  return bytes;
295 }
296 
298 : mNEvents("")
299 , mCrossSection("") {
300 }
301 
303 }
304 
306  return new LogReaderGmcTrans;
307 }
308 
309 bool LogReaderGmcTrans::Extract(const std::string& filename) {
310  // Open the file, check for errors.
311  std::ifstream file(filename.c_str(), std::ios::in);
312  if (!file.is_open()) {
313  return false;
314  } // if
315  // The line with the number of generated events ends with this:
316  const std::string eventPattern("generated events (IEVGEN)");
317  // Thw line with the total cross section ends with this:
318  const std::string xsecPattern("total xsec in microbarns after selector");
319  // Read the file line-by-line, looking for the patterns.
320  std::stringstream sstream; // For splitting the string
321  std::string line;
322  while (file.good()) {
323  std::getline(file, line);
324  // Check for number-of-events pattern.
325  if (line.find(eventPattern) != std::string::npos) {
326  // Found it, the number of events is the first word in the line.
327  std::string tmp;
328  sstream.str("");
329  sstream.clear();
330  sstream << line;
331  sstream >> tmp;
332  mNEvents.SetString(tmp.c_str());
333  } // if
334  // Check for total cross section pattern.
335  if (line.find(xsecPattern) != std::string::npos) {
336  std::string tmp;
337  sstream.str("");
338  sstream.clear();
339  sstream << line;
340  sstream >> tmp;
341  mCrossSection.SetString(tmp.c_str());
342  } // if
343  } // while
344  return !(mNEvents.GetString().IsNull() ||
345  mCrossSection.GetString().IsNull());
346 }
347 
348 Int_t LogReaderGmcTrans::Save() const {
349  return mNEvents.Write("nEvents") + mCrossSection.Write("crossSection");
350 }
351 
353  return mNEvents.GetString().Atoi();
354 }
355 
357  return mCrossSection.GetString().Atof();
358 }
359 
361  static LogReaderFactory theInstance;
362  return theInstance;
363 }
364 
372  // The event name will be "EventX" where "X" is the Monte Carlo
373  // generator name.
374  TString name = event.ClassName();
375  name.ReplaceAll("erhic::", "");
376  name.ReplaceAll("Event", "");
377  name.ToLower();
378  return CreateReader(name.Data());
379 }
380 
387 LogReader* LogReaderFactory::CreateReader(const std::string& name) const {
388  // Use TString::ToLower() to convert the input name to all
389  // lower case.
390  TString str(name);
391  str.ToLower();
392  LogReader* reader(NULL);
393  if (prototypes_.find(str.Data()) != prototypes_.end()) {
394  reader = prototypes_.find(str.Data())->second->Create();
395  } // if
396  return reader;
397 }
398 
405 LogReader* LogReaderFactory::CreateReader(std::istream& is) const {
406  std::string line;
407  std::getline(is, line);
408  // Use TString::ToLower() to convert the input name to all
409  // lower case.
410  TString str(line);
411  str.ToLower();
412  LogReader* reader(NULL);
413  if (str.Contains("pythia")) {
414  reader = CreateReader("pythia");
415  } else if (str.Contains("pepsi") || str.Contains("lepto")) {
416  reader = CreateReader("pepsi");
417  } else if (str.Contains("rapgap")) {
418  reader = CreateReader("rapgap");
419  } else if (str.Contains("djangoh")) {
420  reader = CreateReader("djangoh");
421  } else if (str.Contains("milou")) {
422  reader = CreateReader("milou");
423  } // if
424  return reader;
425 }
426 
427 std::string LogReaderFactory::Locate(const std::string& mcFile) const {
428  TString inFileName(mcFile);
429  TString logFileName;
430  std::string extension;
431  if (mcFile.find_last_of('.') != std::string::npos) {
432  extension = mcFile.substr(mcFile.find_last_of('.'));
433  } // if
434  // If the input file is in the current directory, expand the full path:
435  if (std::string(".") == gSystem->DirName(inFileName)) {
436  inFileName.Prepend("/").Prepend(gSystem->pwd());
437  } // if
438 
439  // The standard data directory structure is to have a directory called
440  // TXTFILES containing the Monte Carlo output, and a directory called
441  // LOGFILES containing the corresponding log files. The sub-directory
442  // structure of LOGFILES should match that of TXTFILES.
443  // So, first we'll check if the input path contains TXTFILES, in which
444  // case we just substitute LOGFILES:
445  if (inFileName.Contains("TXTFILES")) {
446  logFileName = inFileName;
447  logFileName.ReplaceAll("TXTFILES", "LOGFILES");
448  logFileName.ReplaceAll(extension.c_str(), ".log");
449  } // if...
450  // Check if the file whose name we have constructed exists.
451  // If not clear the string contents.
452  if (gSystem->AccessPathName(logFileName, kFileExists)) {
453  logFileName.Clear();
454  } // if
455  // OK, that didn't work, so let's just look in the current directory
456  if (logFileName.IsNull()) {
457  logFileName = inFileName;
458  if (extension.empty()) {
459  logFileName.Append(".log");
460  } else {
461  logFileName.ReplaceAll(extension.c_str(), ".log");
462  } // if
463  } // if
464  // Check if the file whose name we have constructed exists.
465  // If not clear the string contents.
466  if (gSystem->AccessPathName(logFileName, kFileExists)) {
467  logFileName.Clear();
468  } // if
469  return logFileName.Data();
470 }
471 
473  prototypes_.insert(std::make_pair("pythia",
474  new LogReaderPythia));
475  prototypes_.insert(std::make_pair("milou",
476  new LogReaderMilou));
477  prototypes_.insert(std::make_pair("pepsi",
478  new LogReaderPepsi));
479  prototypes_.insert(std::make_pair("djangoh",
480  new LogReaderDjangoh));
481  prototypes_.insert(std::make_pair("gmctrans", new LogReaderGmcTrans));
482 }
483 
485  Map::iterator i = prototypes_.begin();
486  for (; i != prototypes_.end(); ++i) {
487  delete i->second;
488  } // for
489 }
490 
491 template<typename T>
492 File<T>::File() : t_(new T) { }
493 
494 template<typename T>
496  if (t_) {
497  delete t_;
498  t_ = NULL;
499  } // if
500 }
501 
502 template<typename T>
503 std::string File<T>::GetGeneratorName() const {
504  // The event class name is "EventX" where "X" is the generator
505  // name.
506  TString name = t_->ClassName();
507  name.ReplaceAll("erhic::", "");
508  name.ReplaceAll("Event", "");
509  name.ToLower();
510  return name.Data();
511 }
512 
513 template<typename T>
516 }
517 
519  static FileFactory theInstance;
520  return theInstance;
521 }
522 
523 const FileType* FileFactory::GetFile(const std::string& name) const {
524  const FileType* file(NULL);
525  if (prototypes_.find(name) != prototypes_.end()) {
526  file = prototypes_.find(name)->second->Create();
527  } // if
528  return file;
529 }
530 
531 const FileType* FileFactory::GetFile(std::istream& is) const {
532  std::string line;
533  std::getline(is, line);
534  // Use TString::ToLower() to convert the input name to all
535  // lower case.
536  TString str(line);
537  str.ToLower();
538  const FileType* file(NULL);
539  if (str.Contains("pythia")) {
540  file = GetFile("pythia");
541  } else if (str.Contains("pepsi") || str.Contains("lepto")) {
542  file = GetFile("pepsi");
543  } else if (str.Contains("rapgap")) {
544  file = GetFile("rapgap");
545  } else if (str.Contains("djangoh")) {
546  file = GetFile("djangoh");
547  } else if (str.Contains("milou")) {
548  file = GetFile("milou");
549  } else if (str.Contains("gmctrans")) {
550  file = GetFile("gmctrans");
551  } // if
552  return file;
553 }
554 
556  prototypes_.insert(std::make_pair("djangoh",
557  new File<EventDjangoh>()));
558  prototypes_.insert(std::make_pair("dpmjet",
559  new File<EventDpmjet>()));
560  prototypes_.insert(std::make_pair("milou",
561  new File<EventMilou>()));
562  prototypes_.insert(std::make_pair("pepsi",
563  new File<EventPepsi>()));
564  prototypes_.insert(std::make_pair("pythia",
565  new File<EventPythia>()));
566  prototypes_.insert(std::make_pair("rapgap",
567  new File<EventRapgap>()));
568  prototypes_.insert(std::make_pair("gmctrans",
569  new File<EventGmcTrans>()));
570 }
571 
573  Map::iterator i = prototypes_.begin();
574  for (; i != prototypes_.end(); ++i) {
575  if (i->second) delete i->second;
576  } // for
577 }
578 
579 } // namespace erhic
std::string Locate(const std::string &mcFile) const
Definition: File.cxx:427
bool Extract(const std::string &file)
Definition: File.cxx:241
Int_t Save() const
Definition: File.cxx:348
virtual ~LogReaderGmcTrans()
Definition: File.cxx:302
TObjString nEvents_
Cross section error in nb
Definition: File.h:271
bool Extract(const std::string &file)
Definition: File.cxx:90
TObjString mCrossSection
Total cross section in microbarns.
Definition: File.h:348
LogReaderGmcTrans * Create() const
Definition: File.cxx:305
TObjString nEvents_
Total cross section in microbarns
Definition: File.h:108
virtual ~File()
Definition: File.cxx:495
static FileFactory & GetInstance()
Definition: File.cxx:518
Int_t Save() const
Definition: File.cxx:140
virtual ~LogReaderPythia()
Definition: File.cxx:28
bool Extract(const std::string &file)
Definition: File.cxx:30
bool Extract(const std::string &file)
Definition: File.cxx:154
static LogReaderFactory & GetInstance()
Definition: File.cxx:360
Int_t GetNEvents() const
Definition: File.cxx:352
TObjString crossSectionError_
Total cross section in nb
Definition: File.h:270
virtual ~LogReaderDjangoh()
Definition: File.cxx:152
const FileType * GetFile(const std::string &generatorName) const
Definition: File.cxx:523
Int_t Save() const
Definition: File.cxx:234
bool Extract(const std::string &filename)
Definition: File.cxx:309
const FileType * GetFile(std::istream &) const
Definition: File.cxx:531
Int_t Save() const
Definition: File.cxx:75
TObjString mNEvents
Number of generated events.
Definition: File.h:347
LogReader * CreateReader(const EventBase &event) const
Definition: File.cxx:371
virtual ~LogReaderPepsi()
Definition: File.cxx:88
virtual LogReader * CreateLogReader() const
Definition: File.cxx:514
TObjString nEvents_
Total cross section in microbarns
Definition: File.h:156
virtual std::string GetGeneratorName() const
Definition: File.cxx:503
Int_t Save() const
Definition: File.cxx:289
TObjString nEvents_
Total cross section in microbarns
Definition: File.h:204
virtual ~FileFactory()
Definition: File.cxx:572
Double_t GetCrossSection() const
Definition: File.cxx:356