Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2024-06-29 07:05:51

0001 /**
0002  \file
0003  Implementations of file information and log-reading classes.
0004 
0005  \author    Thomas Burton
0006  \date      2011-07-29
0007  \copyright 2011 Brookhaven National Lab
0008  */
0009 
0010 #include "eicsmear/erhic/File.h"
0011 
0012 #include <fstream>
0013 #include <sstream>
0014 #include <string>
0015 
0016 #include <TSystem.h>
0017 
0018 #include "eicsmear/gzstream.h"
0019 #include "eicsmear/erhic/EventPepsi.h"
0020 #include "eicsmear/erhic/EventDjangoh.h"
0021 #include "eicsmear/erhic/EventDpmjet.h"
0022 #include "eicsmear/erhic/EventRapgap.h"
0023 #include "eicsmear/erhic/EventGmcTrans.h"
0024 #include "eicsmear/erhic/EventHepMC.h"
0025 #include "eicsmear/erhic/EventSimple.h"
0026 #include "eicsmear/erhic/EventDEMP.h"
0027 #include "eicsmear/erhic/EventSartre.h"
0028 
0029 #include <HepMC3/Version.h>
0030 
0031 using std::cout;
0032 using std::cerr;
0033 using std::endl;
0034 
0035 
0036 static void LogLineParse(std::string line, const std::string searchPattern, std::string& toupdate, const double rescale=1 ){
0037   size_t position = line.find(searchPattern);
0038   if (position != std::string::npos) {
0039     // We found the line.
0040     // This should be the first and only occurence. Check.
0041     if ( toupdate!="") throw std::runtime_error( "LogLineParse: Found two instances of the search pattern");
0042     // Erase the text preceding the value.
0043     std::stringstream ss;
0044     line.erase(0, position + searchPattern.length());
0045     ss.str("");
0046     ss.clear();
0047     ss << line;
0048     // Sometimes this needs rescaling (pb to mb)
0049     if ( rescale!=1 ){
0050       double v;
0051       ss >> v;
0052       v /= 1.e6;
0053       ss.clear();  ss << v;
0054     }
0055     ss >> toupdate;
0056   }  // if
0057   return;
0058 }
0059 
0060 namespace erhic {
0061 
0062 LogReaderPythia::LogReaderPythia() { }
0063 
0064 LogReaderPythia::~LogReaderPythia() { }
0065 
0066 bool LogReaderPythia::Extract(const std::string& file) {
0067   // First we get the cross section from the log file.
0068   std::ifstream ifs(file.c_str(), std::ios::in);
0069 
0070   if (!ifs.is_open()) return false;
0071 
0072   std::string line;
0073   std::string normalisation;
0074   std::string nEvents;
0075   std::string nTrials;
0076 
0077   while (ifs.good()) {
0078     std::getline(ifs, line);
0079     LogLineParse( line, "Pythia total cross section normalisation:", normalisation );
0080     LogLineParse( line, "Total Number of generated events", nEvents );
0081     LogLineParse( line, "Total Number of trials", nTrials );
0082   }  // while
0083 
0084   crossSection_.SetString(normalisation.c_str());
0085   nEvents_.SetString(nEvents.c_str());
0086   nTrials_.SetString(nTrials.c_str());
0087   std::cout << "Extracted information from " << file << std::endl;
0088   return true;
0089 }
0090 
0091 Int_t LogReaderPythia::Save() const {
0092   Int_t byteswritten = 0;
0093   byteswritten += crossSection_.Write("crossSection");
0094   byteswritten += nEvents_.Write("nEvents");
0095   byteswritten += nTrials_.Write("nTrials");
0096   return byteswritten;
0097 }
0098 
0099 //
0100 // class LogReaderPepsi
0101 //
0102 
0103 LogReaderPepsi::LogReaderPepsi() { }
0104 
0105 LogReaderPepsi::~LogReaderPepsi() { }
0106 
0107 bool LogReaderPepsi::Extract(const std::string& file) {
0108   // First we get the cross section from the log file.
0109   std::ifstream ifs(file.c_str(), std::ios::in);
0110   if (!ifs.is_open()) return false;
0111   std::string line;
0112   std::string normalisation;
0113   std::string nEvents;
0114   std::string nTrials;
0115 
0116   while (ifs.good()) {
0117     std::getline(ifs, line);
0118     // Divide by 1,000,000 to go from pb to microbarn
0119     LogLineParse( line, "total cross section in pb from MC simulation", normalisation, 1e-6 );
0120     LogLineParse( line, "Total Number of generated events", nEvents );
0121     LogLineParse( line, "Total Number of trials", nTrials );
0122   }  // while
0123 
0124   crossSection_.SetString(normalisation.c_str());
0125   nEvents_.SetString(nEvents.c_str());
0126   nTrials_.SetString(nTrials.c_str());
0127   std::cout << "Extracted information from " << file << std::endl;
0128   return true;
0129 }
0130 
0131 Int_t LogReaderPepsi::Save() const {
0132   Int_t byteswritten = 0;
0133   byteswritten += crossSection_.Write("crossSection");
0134   byteswritten += nEvents_.Write("nEvents");
0135   byteswritten += nTrials_.Write("nTrials");
0136   return byteswritten;
0137 }
0138 
0139 //
0140 // class LogReaderDjangoh
0141 //
0142 
0143 LogReaderDjangoh::LogReaderDjangoh() { }
0144 
0145 LogReaderDjangoh::~LogReaderDjangoh() { }
0146 
0147 bool LogReaderDjangoh::Extract(const std::string& file) {
0148   // First we get the cross section from the log file.
0149   std::ifstream ifs(file.c_str(), std::ios::in);
0150 
0151   if (!ifs.is_open()) return false;
0152 
0153   std::string line;
0154   // There are two places we need to look for cross sections.
0155   // As standard, look for the line starting with
0156   //   Cross-section from HERACLES
0157   // Sometimes there will be an additional line starting
0158   //   Total cross section is now    SIGTOT =
0159   // *If* this line is present we take the cross section from there,
0160   // otherwise use the 'HERACLES' line, which is always present.
0161   // Both lines give cross section in pb.
0162   const std::string xsecPattern("Cross-section from HERACLES =");
0163   const std::string xsecAltPattern("Total cross section is now    SIGTOT =");
0164   std::string normalisation;
0165   std::string nEvents;
0166 
0167   while (ifs.good()) {
0168     std::getline(ifs, line);
0169     // Look for normal cross section line, unless the cross section
0170     // was already set (via the alternative line, see below).
0171     size_t position = line.find(xsecPattern);
0172     if (position != std::string::npos && normalisation.empty()) {
0173       // We found the line.
0174       // Erase the text preceding the cross section.
0175       std::stringstream ss;
0176       line.erase(0, position + xsecPattern.length());
0177       ss << line;
0178       double value;
0179       // Divide by 1,000,000 to go from pb to microbarn
0180       ss >> value;
0181       value /= 1.e6;
0182       ss.str("");
0183       ss.clear();
0184       ss << value;
0185       ss >> normalisation;
0186     }  // if
0187     position = line.find(xsecAltPattern);
0188     // Look for alternative cross section.
0189     if (position != std::string::npos) {
0190       // We found the line.
0191       // Erase the text preceding the cross section.
0192       std::stringstream ss;
0193       line.erase(0, position + xsecAltPattern.length());
0194       ss << line;
0195       double value;
0196       // Divide by 1,000,000 to go from pb to microbarn
0197       ss >> value;
0198       value /= 1.e6;
0199       ss.str("");
0200       ss.clear();
0201       ss << value;
0202       ss >> normalisation;
0203     }  // if
0204     const std::string searchPattern2("TOTAL EVENT NUMBER");
0205     position = line.find(searchPattern2);
0206     if (position != std::string::npos) {
0207       // We found the line.
0208       // Erase the text preceding the cross section.
0209       std::stringstream ss;
0210       line.erase(0, position + searchPattern2.length());
0211       ss.str("");
0212       ss.clear();
0213       ss << line;
0214       ss >> nEvents;
0215     }  // if
0216   }  // while
0217 
0218   crossSection_.SetString(normalisation.c_str());
0219   std::cout << crossSection_.GetString().Atof() << std::endl;
0220   nEvents_.SetString(nEvents.c_str());
0221   std::cout << nEvents_.GetString().Atoi() << std::endl;
0222 
0223   std::cout << "Extracted information from " << file << std::endl;
0224   return true;
0225 }
0226 
0227 Int_t LogReaderDjangoh::Save() const {
0228   return
0229   crossSection_.Write("crossSection") +
0230   nEvents_.Write("nEvents");
0231 }
0232 
0233 
0234 bool LogReaderMilou::Extract(const std::string& file) {
0235   // First we get the cross section from the log file.
0236   std::ifstream ifs(file.c_str(), std::ios::in);
0237 
0238   if (!ifs.is_open()) return false;
0239 
0240   std::string line;
0241 
0242   const std::string nEventPattern("Number of generated events    =");
0243   const std::string xsecPattern("Total cross-section (nb) :");
0244   const std::string errorPattern("Error                    :");
0245 
0246   std::string tmp("");
0247 
0248   std::stringstream ss;
0249 
0250   while (ifs.good()) {
0251     std::getline(ifs, line);
0252     ss.str("");
0253     ss.clear();
0254     // Look for one of the search patterns.
0255     if (line.find(nEventPattern) != std::string::npos) {
0256       line.erase(0,
0257                  line.find(nEventPattern) + nEventPattern.length());
0258       ss << line;
0259       ss >> tmp;
0260       nEvents_.SetString(tmp.c_str());
0261     } else if (line.find(xsecPattern) != std::string::npos) {
0262       line.erase(0,
0263                  line.find(xsecPattern) + xsecPattern.length());
0264       ss << line;
0265       ss >> tmp;
0266       crossSection_.SetString(tmp.c_str());
0267     } else if (line.find(errorPattern) != std::string::npos) {
0268       line.erase(0,
0269                  line.find(errorPattern) + errorPattern.length());
0270       ss << line;
0271       ss >> tmp;
0272       crossSectionError_.SetString(tmp.c_str());
0273     }  // if
0274   }  // while
0275   // Return true if all the strings are filled, or false if any
0276   // of them are empty.
0277   return !(nEvents_.GetString().IsNull() ||
0278               crossSection_.GetString().IsNull() ||
0279               crossSectionError_.GetString().IsNull());
0280 }
0281 
0282 Int_t LogReaderMilou::Save() const {
0283   Int_t bytes(0);
0284   bytes += nEvents_.Write("nEvents");
0285   bytes += crossSection_.Write("crossSection");
0286   bytes += crossSectionError_.Write("crossSectionError");
0287   return bytes;
0288 }
0289 
0290 LogReaderGmcTrans::LogReaderGmcTrans()
0291 : mNEvents("")
0292 , mCrossSection("") {
0293 }
0294 
0295 LogReaderGmcTrans::~LogReaderGmcTrans() {
0296 }
0297 
0298 LogReaderGmcTrans* LogReaderGmcTrans::Create() const {
0299   return new LogReaderGmcTrans;
0300 }
0301 
0302 bool LogReaderGmcTrans::Extract(const std::string& filename) {
0303   // Open the file, check for errors.
0304   std::ifstream file(filename.c_str(), std::ios::in);
0305   if (!file.is_open()) {
0306     return false;
0307   }  // if
0308   // The line with the number of generated events ends with this:
0309   const std::string eventPattern("generated events (IEVGEN)");
0310   // Thw line with the total cross section ends with this:
0311   const std::string xsecPattern("total xsec in microbarns after selector");
0312   // Read the file line-by-line, looking for the patterns.
0313   std::stringstream sstream;  // For splitting the string
0314   std::string line;
0315   while (file.good()) {
0316     std::getline(file, line);
0317     // Check for number-of-events pattern.
0318     if (line.find(eventPattern) != std::string::npos) {
0319       // Found it, the number of events is the first word in the line.
0320       std::string tmp;
0321       sstream.str("");
0322       sstream.clear();
0323       sstream << line;
0324       sstream >> tmp;
0325       mNEvents.SetString(tmp.c_str());
0326     }  // if
0327     // Check for total cross section pattern.
0328     if (line.find(xsecPattern) != std::string::npos) {
0329       std::string tmp;
0330       sstream.str("");
0331       sstream.clear();
0332       sstream << line;
0333       sstream >> tmp;
0334       mCrossSection.SetString(tmp.c_str());
0335     }  // if
0336   }  // while
0337   return !(mNEvents.GetString().IsNull() ||
0338            mCrossSection.GetString().IsNull());
0339 }
0340 
0341 Int_t LogReaderGmcTrans::Save() const {
0342   return mNEvents.Write("nEvents") + mCrossSection.Write("crossSection");
0343 }
0344 
0345 Int_t LogReaderGmcTrans::GetNEvents() const {
0346   return mNEvents.GetString().Atoi();
0347 }
0348 
0349 Double_t LogReaderGmcTrans::GetCrossSection() const {
0350   return mCrossSection.GetString().Atof();
0351 }
0352 
0353 LogReaderFactory& LogReaderFactory::GetInstance() {
0354   static LogReaderFactory theInstance;
0355   return theInstance;
0356 }
0357 
0358 /**
0359  Returns a LogReader instance of the type for reading log files
0360  from the Monte Carlo generator event type 'event'.
0361  Returns NULL in the case of an unsupported generator.
0362  The LogReader must be deleted by the user.
0363  */
0364 LogReader* LogReaderFactory::CreateReader(const EventBase& event) const {
0365   // The event name will be "EventX" where "X" is the Monte Carlo
0366   // generator name.
0367   TString name = event.ClassName();
0368   name.ReplaceAll("erhic::", "");
0369   name.ReplaceAll("Event", "");
0370   name.ToLower();
0371   return CreateReader(name.Data());
0372 }
0373 
0374 /**
0375  Returns a LogReader instance of the type for reading log files
0376  from the Monte Carlo generator named 'name'.
0377  Returns NULL in the case of an unsupported generator.
0378  The LogReader must be deleted by the user.
0379  */
0380 LogReader* LogReaderFactory::CreateReader(const std::string& name) const {
0381   // Use TString::ToLower() to convert the input name to all
0382   // lower case.
0383   TString str(name);
0384   str.ToLower();
0385   LogReader* reader(NULL);
0386   if (prototypes_.find(str.Data()) != prototypes_.end()) {
0387     reader = prototypes_.find(str.Data())->second->Create();
0388   }  // if
0389   return reader;
0390 }
0391 
0392 /**
0393  Returns a LogReader instance of the type for reading log files
0394  from the Monte Carlo generator named 'name'.
0395  Returns NULL in the case of an unsupported generator.
0396  The LogReader must be deleted by the user.
0397  */
0398 LogReader* LogReaderFactory::CreateReader(std::istream& is) const {
0399   std::string line;
0400   std::getline(is, line);
0401   // Use TString::ToLower() to convert the input name to all
0402   // lower case.
0403   TString str(line);
0404   str.ToLower();
0405   LogReader* reader(NULL);
0406   if (str.Contains("pythia")) {
0407     reader = CreateReader("pythia");
0408   } else if (str.Contains("pepsi") || str.Contains("lepto")) {
0409     reader = CreateReader("pepsi");
0410   } else if (str.Contains("rapgap")) {
0411     reader = CreateReader("rapgap");
0412   } else if (str.Contains("djangoh")) {
0413     reader = CreateReader("djangoh");
0414     //} else if (str.Contains("beagle")) {
0415     //reader = CreateReader("beagle");
0416   } else if (str.Contains("milou")) {
0417     reader = CreateReader("milou");
0418   } else if (str.Contains("simple")) {
0419     reader = CreateReader("simple");
0420    } else if (str.Contains("demp")) {
0421     reader = CreateReader("demp");
0422   } else if (str.Contains("sartre")) {
0423     reader = CreateReader("sartre");
0424   }  // if
0425   return reader;
0426 }
0427 
0428 std::string LogReaderFactory::Locate(const std::string& mcFile) const {
0429   TString inFileName(mcFile);
0430   TString logFileName;
0431   std::string extension;
0432   if (mcFile.find_last_of('.') != std::string::npos) {
0433     extension = mcFile.substr(mcFile.find_last_of('.'));
0434   }  // if
0435   // If the input file is in the current directory, expand the full path:
0436   if (std::string(".") == gSystem->DirName(inFileName)) {
0437     inFileName.Prepend("/").Prepend(gSystem->pwd());
0438   }  // if
0439 
0440   // The standard data directory structure is to have a directory called
0441   // TXTFILES containing the Monte Carlo output, and a directory called
0442   // LOGFILES containing the corresponding log files. The sub-directory
0443   // structure of LOGFILES should match that of TXTFILES.
0444   // So, first we'll check if the input path contains TXTFILES, in which
0445   // case we just substitute LOGFILES:
0446   if (inFileName.Contains("TXTFILES")) {
0447     logFileName = inFileName;
0448     logFileName.ReplaceAll("TXTFILES", "LOGFILES");
0449     logFileName.ReplaceAll(extension.c_str(), ".log");
0450   }  // if...
0451   // Check if the file whose name we have constructed exists.
0452   // If not clear the string contents.
0453   if (gSystem->AccessPathName(logFileName, kFileExists)) {
0454     logFileName.Clear();
0455   }  // if
0456   // OK, that didn't work, so let's just look in the current directory
0457   if (logFileName.IsNull()) {
0458     logFileName = inFileName;
0459     if (extension.empty()) {
0460       logFileName.Append(".log");
0461     } else {
0462       logFileName.ReplaceAll(extension.c_str(), ".log");
0463     } // if
0464   }  // if
0465   // Check if the file whose name we have constructed exists.
0466   // If not clear the string contents.
0467   if (gSystem->AccessPathName(logFileName, kFileExists)) {
0468     logFileName.Clear();
0469   }  // if
0470   return logFileName.Data();
0471 }
0472 
0473 LogReaderFactory::LogReaderFactory() {
0474   prototypes_.insert(std::make_pair("pythia",
0475                                     new LogReaderPythia));
0476   prototypes_.insert(std::make_pair("milou",
0477                                     new LogReaderMilou));
0478   prototypes_.insert(std::make_pair("pepsi",
0479                                     new LogReaderPepsi));
0480   prototypes_.insert(std::make_pair("djangoh",
0481                                     new LogReaderDjangoh));
0482   prototypes_.insert(std::make_pair("gmctrans", new LogReaderGmcTrans));
0483 }
0484 
0485 LogReaderFactory::~LogReaderFactory() {
0486   Map::iterator i = prototypes_.begin();
0487   for (; i != prototypes_.end(); ++i) {
0488     delete i->second;
0489   }  // for
0490 }
0491 
0492 template<typename T>
0493 File<T>::File() : t_(new T) {
0494   TString name = t_->ClassName();
0495   name.ReplaceAll("erhic::", "");
0496   name.ReplaceAll("Event", "");
0497   name.ToLower();
0498   generatorname = name.Data();
0499 }
0500 
0501 template<typename T>
0502 File<T>::~File() {
0503   if (t_) {
0504     delete t_;
0505     t_ = NULL;
0506   }  // if
0507 }
0508 
0509 template class File<EventDjangoh>;
0510 template class File<EventDpmjet>;
0511 template class File<EventMilou>;
0512 template class File<EventPepsi>;
0513 template class File<EventPythia>;
0514 template class File<EventBeagle>;
0515 template class File<EventRapgap>;
0516 template class File<EventGmcTrans>;
0517 template class File<EventSimple>;
0518 template class File<EventDEMP>;
0519 template class File<EventSartre>;
0520 // File<EventHepMC> is specialized in the File.h
0521 
0522 std::string FileType::GetGeneratorName() const {
0523     return generatorname;
0524 }
0525   
0526 
0527 void FileType::SetGeneratorName(const std::string newname){
0528   generatorname = newname;
0529   for (auto & c: generatorname) c = tolower(static_cast<unsigned char>(c));
0530 }
0531 
0532 template<typename T>
0533 LogReader* File<T>::CreateLogReader() const {
0534   return LogReaderFactory::GetInstance().CreateReader(*t_);
0535 }
0536 
0537 FileFactory& FileFactory::GetInstance() {
0538   static FileFactory theInstance;
0539   return theInstance;
0540 }
0541 
0542 const FileType* FileFactory::GetFile(const std::string& name) const {
0543   FileType* file(NULL);
0544   if (prototypes_.find(name) != prototypes_.end()) {
0545     file = prototypes_.find(name)->second->Create();
0546     if ( TString(name).Contains("hepmc") )file->SetGeneratorName( "hepmc");
0547   }  // if
0548 
0549   return file;
0550 }
0551 
0552 const FileType* FileFactory::GetFile(std::shared_ptr<std::istream>& isp, const std::string fileName) const {
0553   std::string line;
0554 
0555   // Note: This "uses up" the first line, subsequent readers
0556   // cannot use it anymore.
0557   // This leaves a conundrum. The only information passed to
0558   // the event factory comes from
0559   //   EventFromAsciiFactory<erhic::EventHepMC>* CreateEventFactory(std::istream& is) const {
0560   // return new EventFromAsciiFactory<erhic::EventHepMC>(is);}
0561   // So the class only knows the stream
0562   // and the Filetype.
0563   // We could
0564   // - reset the stream. Seekg, tellg don't work for gzstream, and close/open need the name of the file
0565   //   which already this class doesnt know
0566   // - use globals - no thanks
0567   // - Enrich the virtual eventfactory. That seems the most unintrusive way as long as it's a generic
0568   //   field meant for additional information. That's what we'll use
0569 
0570 
0571   // skip empty lines (thanks, hepmc2...)
0572   do {
0573     std::getline(*isp, line);
0574   } while (line.empty());
0575 
0576   // Use TString::ToLower() to convert the input name to all
0577   // lower case.
0578   TString str(line);
0579   str.ToLower();
0580   const FileType* file(NULL);
0581   if (str.Contains("pythia")) {
0582     file = GetFile("pythia");
0583   } else if (str.Contains("pepsi") || str.Contains("lepto")) {
0584     file = GetFile("pepsi");
0585   } else if (str.Contains("rapgap")) {
0586     file = GetFile("rapgap");
0587   } else if (str.Contains("djangoh")) {
0588     file = GetFile("djangoh");
0589   } else if (str.Contains("milou")) {
0590     file = GetFile("milou");
0591   } else if (str.Contains("beagle")) {
0592     file = GetFile("beagle");
0593   } else if (str.Contains("gmctrans")) {
0594     file = GetFile("gmctrans");
0595   } else if (str.Contains("dpmjet")) {
0596     file = GetFile("dpmjet");
0597   } else if (str.Contains("simple")) {
0598     file = GetFile("simple");
0599   } else if (str.Contains("demp")) {
0600     file = GetFile("demp");
0601   } else if (str.Contains("sartre")) {
0602     file = GetFile("sartre");
0603   } else if (str.Contains("hepmc")) {
0604 
0605     // We have to repair the stream by reading it fresh
0606     // Open the input file for reading.
0607     if ( TString(fileName).EndsWith("gz", TString::kIgnoreCase) ||
0608      TString(fileName).EndsWith("zip", TString::kIgnoreCase)){
0609 #if HEPMC3_VERSION_CODE < 3002005      
0610       // Can't accept gzstreams before 3.2.5
0611       std::cerr << "HepMC before v 3.2.5 only supports ifstream (no compressed files)." << endl;
0612       throw;
0613 #endif // HEPMC3_VERSION_CODE < 3002004
0614       
0615       auto tmp = std::make_shared<igzstream>();
0616       tmp->open(fileName.c_str());
0617       // Throw a runtime_error if the file could not be opened.
0618       if (!tmp->good()) {
0619     std::string message("Unable to open file ");
0620     throw std::runtime_error(message.append(fileName));
0621       }  // if
0622       isp=tmp;
0623     } else {
0624       auto tmp = std::make_shared<std::ifstream>();
0625       tmp->open(fileName.c_str());
0626       // Throw a runtime_error if the file could not be opened.
0627       if (!isp->good()) {
0628     std::string message("Unable to open file ");
0629     throw std::runtime_error(message.append(fileName));
0630       }  // if
0631       isp=tmp;
0632     }  // if
0633     file = GetFile("hepmc");
0634   }
0635   return file;
0636 }
0637 
0638 FileFactory::FileFactory() {
0639   prototypes_.insert(std::make_pair("djangoh",
0640                                     new File<EventDjangoh>()));
0641   prototypes_.insert(std::make_pair("dpmjet",
0642                                     new File<EventDpmjet>()));
0643   prototypes_.insert(std::make_pair("milou",
0644                                     new File<EventMilou>()));
0645   prototypes_.insert(std::make_pair("pepsi",
0646                                     new File<EventPepsi>()));
0647   prototypes_.insert(std::make_pair("pythia",
0648                                     new File<EventPythia>()));
0649   prototypes_.insert(std::make_pair("beagle",
0650                                     new File<EventBeagle>()));
0651   prototypes_.insert(std::make_pair("rapgap",
0652                                     new File<EventRapgap>()));
0653   prototypes_.insert(std::make_pair("gmctrans",
0654                                     new File<EventGmcTrans>()));
0655   prototypes_.insert(std::make_pair("simple",
0656                                     new File<EventSimple>()));
0657   prototypes_.insert(std::make_pair("demp",
0658                                     new File<EventDEMP>()));
0659   prototypes_.insert(std::make_pair("sartre",
0660                                     new File<EventSartre>()));
0661   prototypes_.insert(std::make_pair("hepmc",
0662                                     new File<EventHepMC>()));
0663 
0664 }
0665 
0666 FileFactory::~FileFactory() {
0667   Map::iterator i = prototypes_.begin();
0668   for (; i != prototypes_.end(); ++i) {
0669     if (i->second) delete i->second;
0670   }  // for
0671 }
0672 
0673 }  // namespace erhic