Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-08-17 23:10:44

0001 // -*- C++ -*-
0002 //
0003 // Package:     Core
0004 // Class  :     FWConfigurationManager
0005 //
0006 // Implementation:
0007 //     <Notes on implementation>
0008 //
0009 // Original Author:  Chris Jones
0010 //         Created:  Sun Feb 24 14:42:32 EST 2008
0011 //
0012 
0013 // system include files
0014 #include <fstream>
0015 #include <iostream>
0016 #include <memory>
0017 #include <stdexcept>
0018 #include "TROOT.h"
0019 #include "TSystem.h"
0020 #include "TStopwatch.h"
0021 
0022 // user include files
0023 #include "Fireworks/Core/interface/FWConfigurationManager.h"
0024 #include "Fireworks/Core/interface/FWConfiguration.h"
0025 #include "Fireworks/Core/interface/FWConfigurable.h"
0026 #include "Fireworks/Core/interface/fwLog.h"
0027 #include "Fireworks/Core/interface/SimpleSAXParser.h"
0028 #include "Fireworks/Core/interface/FWJobMetadataManager.h"
0029 #include "Fireworks/Core/interface/fwLog.h"
0030 #include "Fireworks/Core/interface/FWXMLConfigParser.h"
0031 
0032 //
0033 // constants, enums and typedefs
0034 //
0035 
0036 //
0037 // static data member definitions
0038 //
0039 
0040 //
0041 // constructors and destructor
0042 //
0043 FWConfigurationManager::FWConfigurationManager() : m_ignore(false) {}
0044 
0045 // FWConfigurationManager::FWConfigurationManager(const FWConfigurationManager& rhs)
0046 // {
0047 //    // do actual copying here;
0048 // }
0049 
0050 FWConfigurationManager::~FWConfigurationManager() {}
0051 
0052 //
0053 // assignment operators
0054 //
0055 // const FWConfigurationManager& FWConfigurationManager::operator=(const FWConfigurationManager& rhs)
0056 // {
0057 //   //An exception safe implementation is
0058 //   FWConfigurationManager temp(rhs);
0059 //   swap(rhs);
0060 //
0061 //   return *this;
0062 // }
0063 
0064 //
0065 // member functions
0066 //
0067 void FWConfigurationManager::add(const std::string& iName, FWConfigurable* iConf) {
0068   assert(nullptr != iConf);
0069   m_configurables[iName] = iConf;
0070 }
0071 
0072 //
0073 // const member functions
0074 //
0075 void FWConfigurationManager::setFrom(const FWConfiguration& iConfig) const {
0076   assert(nullptr != iConfig.keyValues());
0077   for (FWConfiguration::KeyValues::const_iterator it = iConfig.keyValues()->begin(), itEnd = iConfig.keyValues()->end();
0078        it != itEnd;
0079        ++it) {
0080     std::map<std::string, FWConfigurable*>::const_iterator itFound = m_configurables.find(it->first);
0081     assert(itFound != m_configurables.end());
0082     itFound->second->setFrom(it->second);
0083   }
0084 }
0085 
0086 void FWConfigurationManager::to(FWConfiguration& oConfig) const {
0087   FWConfiguration config;
0088   for (std::map<std::string, FWConfigurable*>::const_iterator it = m_configurables.begin(),
0089                                                               itEnd = m_configurables.end();
0090        it != itEnd;
0091        ++it) {
0092     it->second->addTo(config);
0093     oConfig.addKeyValue(it->first, config, true);
0094   }
0095 }
0096 
0097 void FWConfigurationManager::writeToFile(const std::string& iName) const {
0098   try {
0099     std::ofstream file(iName.c_str());
0100     if (not file) {
0101       std::string message = "unable to open file " + iName;
0102       message += iName;
0103       throw std::runtime_error(message.c_str());
0104     }
0105     FWConfiguration top;
0106     to(top);
0107     fwLog(fwlog::kInfo) << "Writing to file " << iName.c_str() << "...\n";
0108     fflush(stdout);
0109 
0110     FWConfiguration::streamTo(file, top, "top");
0111   } catch (std::runtime_error& e) {
0112     fwLog(fwlog::kError) << "FWConfigurationManager::writeToFile() " << e.what() << std::endl;
0113   }
0114 }
0115 
0116 void FWConfigurationManager::readFromOldFile(const std::string& iName) const {
0117   Int_t error = 0;
0118   // Int_t value =
0119   gROOT->LoadMacro(iName.c_str(), &error);
0120   if (0 != error) {
0121     std::string message("unable to load macro file ");
0122     message += iName;
0123     throw std::runtime_error(message.c_str());
0124   }
0125 
0126   const std::string command("(Long_t)(fwConfig() )");
0127 
0128   error = 0;
0129   Long_t lConfig = gROOT->ProcessLineFast(command.c_str(), &error);
0130 
0131   {
0132     //need to unload this macro so that we can load a new configuration
0133     // which uses the same function name in the macro
0134     Int_t error = 0;
0135     gROOT->ProcessLineSync((std::string(".U ") + iName).c_str(), &error);
0136   }
0137   if (0 != error) {
0138     std::string message("unable to properly parse configuration file ");
0139     message += iName;
0140     throw std::runtime_error(message.c_str());
0141   }
0142   std::unique_ptr<FWConfiguration> config(reinterpret_cast<FWConfiguration*>(lConfig));
0143 
0144   setFrom(*config);
0145 }
0146 
0147 /** Reads the configuration specified in @a iName and creates the internal 
0148     representation in terms of FWConfigutation objects.
0149     
0150     Notice that if the file does not start with '<' the old CINT macro based
0151     system is used.
0152   */
0153 void FWConfigurationManager::readFromFile(const std::string& iName) const {
0154   std::ifstream f(iName.c_str());
0155   if (f.peek() != (int)'<')
0156     return readFromOldFile(iName);
0157 
0158   // Check that the syntax is correct.
0159   SimpleSAXParser syntaxTest(f);
0160   syntaxTest.parse();
0161   f.close();
0162 
0163   // Read again, this time actually parse.
0164   std::ifstream g(iName.c_str());
0165   // Actually parse the results.
0166   FWXMLConfigParser parser(g);
0167   parser.parse();
0168   setFrom(*parser.config());
0169 }
0170 
0171 std::string FWConfigurationManager::guessAndReadFromFile(FWJobMetadataManager* dataMng) const {
0172   struct CMatch {
0173     std::string file;
0174     int cnt;
0175     const FWConfiguration* cfg;
0176 
0177     CMatch(std::string f) : file(f), cnt(0), cfg(nullptr) {}
0178     bool operator<(const CMatch& x) const { return cnt < x.cnt; }
0179   };
0180 
0181   std::vector<CMatch> clist;
0182   clist.push_back(CMatch("reco.fwc"));
0183   clist.push_back(CMatch("miniaod.fwc"));
0184   clist.push_back(CMatch("aod.fwc"));
0185   std::vector<FWJobMetadataManager::Data>& sdata = dataMng->usableData();
0186 
0187   for (std::vector<CMatch>::iterator c = clist.begin(); c != clist.end(); ++c) {
0188     std::string iName = gSystem->Which(TROOT::GetMacroPath(), c->file.c_str(), kReadPermission);
0189     std::ifstream f(iName.c_str());
0190     if (f.peek() != (int)'<') {
0191       fwLog(fwlog::kWarning) << "FWConfigurationManager::guessAndReadFromFile can't open " << iName << std::endl;
0192       continue;
0193     }
0194 
0195     // Read again, this time actually parse.
0196     std::ifstream g(iName.c_str());
0197     FWXMLConfigParser* parser = new FWXMLConfigParser(g);
0198     parser->parse();
0199 
0200     c->cfg = parser->config();
0201     const FWConfiguration::KeyValues* keyValues = nullptr;
0202     for (FWConfiguration::KeyValues::const_iterator it = c->cfg->keyValues()->begin(),
0203                                                     itEnd = c->cfg->keyValues()->end();
0204          it != itEnd;
0205          ++it) {
0206       if (it->first == "EventItems") {
0207         keyValues = it->second.keyValues();
0208         break;
0209       }
0210     }
0211 
0212     for (FWConfiguration::KeyValues::const_iterator it = keyValues->begin(); it != keyValues->end(); ++it) {
0213       const FWConfiguration& conf = it->second;
0214       const FWConfiguration::KeyValues* keyValues = conf.keyValues();
0215       const std::string& type = (*keyValues)[0].second.value();
0216       for (std::vector<FWJobMetadataManager::Data>::iterator di = sdata.begin(); di != sdata.end(); ++di) {
0217         if (di->type_ == type) {
0218           c->cnt++;
0219           break;
0220         }
0221       }
0222     }
0223     // printf("%s file %d matches\n", iName.c_str(), c->cnt);
0224   }
0225   std::sort(clist.begin(), clist.end());
0226   fwLog(fwlog::kInfo) << "Loading configuration file " << clist.back().file << std::endl;
0227   setFrom(*(clist.back().cfg));
0228 
0229   return clist.back().file;
0230 }
0231 
0232 //
0233 // static member functions
0234 //