Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:31:16

0001 //
0002 //
0003 // File: src/Defaults_Text.cc
0004 // Purpose: A lightweight implementation of the Defaults interface
0005 //          that uses simple text files.
0006 // Created: Jul, 2000, sss.
0007 //
0008 // CMSSW File      : src/Defaults_Text.cc
0009 // Original Author : Scott Stuart Snyder <snyder@bnl.gov> for D0
0010 // Imported to CMSSW by Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>
0011 //
0012 
0013 /**
0014     @file Defaults_Text.cc
0015 
0016     @brief A lightweight implementation of the Defaults
0017     interface that uses simple text files.  See the documentation for
0018     the header file Defaults_Text.h for details.
0019 
0020     @par Creation date:
0021     Jul 2000
0022 
0023     @author
0024     Scott Stuart Snyder <snyder@bnl.gov> for D0.
0025 
0026     Apr 2009: Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>:
0027     Imported to CMSSW.<br>
0028     Oct 2009: Haryo Sumowidagdo <Suharyo.Sumowidagdo@cern.ch>:
0029     Added Doxygen tags for automatic generation of documentation.
0030 
0031     @par Terms of Usage:
0032     With consent from the original author (Scott Snyder).
0033 
0034  */
0035 
0036 #include "TopQuarkAnalysis/TopHitFit/interface/Defaults_Text.h"
0037 #include <cassert>
0038 #include <cstdlib>
0039 #include <fstream>
0040 #include <iostream>
0041 #include <cctype>
0042 #include <cstring>
0043 #include <map>
0044 
0045 using std::abort;
0046 using std::atof;
0047 using std::atoi;
0048 using std::cerr;
0049 using std::getline;
0050 using std::ifstream;
0051 using std::isspace;
0052 using std::map;
0053 using std::strchr;
0054 using std::string;
0055 using std::tolower;
0056 
0057 namespace {
0058 
0059   /**
0060     Helper function to remove comments (text starting with `;' or `#') and
0061     leading and trailing spaces from string <i>s</i>.
0062     @param s The string to strip.
0063     @par Return:
0064     The stripped string.
0065  */
0066   string strip(string s)
0067   //
0068   // Purpose: Remove comments (text starting with `;' or `#') and leading
0069   //          and trailing spaces from S.
0070   //
0071   // Inputs:
0072   //   s -           The string to strip.
0073   //
0074   // Returns:
0075   //  The stripped string.
0076   //
0077   {
0078     string::size_type j = s.find_first_of(";#");
0079     if (j == string::npos)
0080       j = s.size();
0081 
0082     while (j > 0 && isspace(s[j - 1]))
0083       --j;
0084 
0085     string::size_type i = 0;
0086     while (i < j && isspace(s[i]))
0087       ++i;
0088 
0089     return string(s, i, j - i);
0090   }
0091 
0092 }  // unnamed namespace
0093 
0094 namespace hitfit {
0095 
0096   //***************************************************************************
0097 
0098   /**
0099     @class Defaults_Textrep
0100     @brief The internal representation for a Defaults_Text object.
0101  */
0102   class Defaults_Textrep
0103   //
0104   // Purpose: The internal representation for a Defaults_Text object.
0105   //
0106   {
0107   public:
0108     // Constructor.
0109 
0110     /**
0111      @brief Constructor, construct a Defaults_Textrep instance from an
0112      ASCII text-file and command line arguments.
0113      @param file The name of the input ASCII file to read.  See the
0114      header file for a description of the format for this and the argument
0115      list. Pass an empty string to skip reading a file.
0116    */
0117     Defaults_Textrep(string file);
0118     /**
0119      @brief Constructor, construct a Defaults_Textrep instance from an
0120      ASCII text-file.
0121      @param file The name of the input ASCII file to read.  See the
0122      header file for a description of the format for this and the argument
0123      list. Pass an empty string to skip reading a file.
0124      @param argc The length of the argument list.
0125      @param argv The argument list.
0126    */
0127     Defaults_Textrep(string file, int argc, char** argv);
0128 
0129     // The data.  Maps from parameter names to values (which are stored
0130     // as strings).
0131     /**
0132      The data, maps from parameter names to values (which are stored
0133      as strings)
0134    */
0135     std::map<std::string, std::string> _map;
0136 
0137     // Look up parameter NAME and return its value.
0138     /**
0139      Look up parameter <i>name</i> and return its value.
0140      @param name The name of the parameter.
0141      @par Return:
0142      The value of the parameter in C++ string format.
0143    */
0144     string get_val(string name) const;
0145 
0146   private:
0147     // Read parameters from FILE and add them to our data.
0148     /**
0149      Read parameters from ASCII text file <i>file</i> and add the content
0150      to data.
0151      @param file The ASCII text file to read.
0152    */
0153     void read_file(string file);
0154 
0155     // Look for additional parameter settings in the argument list
0156     // ARGC, ARGV and add them to our data.
0157     /**
0158      Look for additional parameter settings in the argument list
0159      <i>argc</i> and <i>argv</i> and add the content to data.
0160      @param argc The length of the argument list.
0161      @param argv The argument list.
0162    */
0163     void process_args(int argc, char** argv);
0164 
0165     // Helper to process a line defining a single parameter.
0166     /**
0167      Helper function to process a line defining a single parameter.
0168      @param l The line to process.
0169    */
0170     void doline(string l);
0171   };
0172 
0173   Defaults_Textrep::Defaults_Textrep(string file)
0174   //
0175   // Purpose: Constructor.
0176   //
0177   // Inputs:
0178   //   file -        The name of the defaults file to read.
0179   //                 See the comments in the header for a description
0180   //                 of the format for this and for the argument list.
0181   //                 Pass an empty string to skip reading a file.
0182   //
0183   {
0184     read_file(file);
0185   }
0186 
0187   Defaults_Textrep::Defaults_Textrep(string file, int argc, char** argv)
0188   //
0189   // Purpose: Constructor.
0190   //
0191   // Inputs:
0192   //   file -        The name of the defaults file to read.
0193   //                 See the comments in the header for a description
0194   //                 of the format for this and for the argument list.
0195   //                 Pass an empty string to skip reading a file.
0196   //   argc -        The arglist length.
0197   //   argv -        The arglist.
0198   //
0199   {
0200     read_file(file);
0201     process_args(argc, argv);
0202   }
0203 
0204   void Defaults_Textrep::read_file(string file)
0205   //
0206   // Purpose: Read parameters from FILE and add them to our data.
0207   //
0208   // Inputs:
0209   //   s -           The name of the file to read.
0210   //
0211   {
0212     // Just return if we weren't given a file.
0213     if (file.empty())
0214       return;
0215 
0216     ifstream f(file.c_str());
0217     if (!f.good()) {
0218       cerr << "Can't open " << file << "\n";
0219       abort();
0220     }
0221 
0222     string l;
0223     while (getline(f, l)) {
0224       doline(l);
0225     }
0226 
0227     f.close();
0228   }
0229 
0230   void Defaults_Textrep::process_args(int argc, char** argv)
0231   //
0232   // Purpose: Process the argument list ARGC, ARGV and add additional
0233   //          parameters from it to our data (possibly overriding
0234   //          existing settings).  See the header file for more details.
0235   //
0236   // Inputs:
0237   //   argc -        The arglist length.
0238   //   argv -        The arglist.
0239   //
0240   {
0241     // Look for arguments starting with `--'.
0242     for (int i = 1; i < argc; i++) {
0243       if (argv[i][0] == '-' && argv[i][1] == '-') {
0244         // Found one.
0245         string l;
0246         if (strchr(argv[i], '=') != nullptr)
0247           // It was of the form `--NAME=VALUE'.  Change to `NAME=VALUE'.
0248           l = argv[i] + 2;
0249         else if (argv[i][2] == 'n' && argv[i][3] == 'o') {
0250           // It was of the form `--noNAME'.  Change to `NAME=0'.
0251           l = argv[i] + 4;
0252           l += "=0";
0253         } else {
0254           // It was of the form `--NAME'.  Change to `NAME=1'.
0255           l = argv[i] + 2;
0256           l += "=1";
0257         }
0258 
0259         // Process it like a line we read from a file.
0260         doline(l);
0261       }
0262     }
0263   }
0264 
0265   string Defaults_Textrep::get_val(string name) const
0266   //
0267   // Purpose: Look up parameter NAME and return its value.
0268   //          The parameter must exist.
0269   //
0270   // Inputs:
0271   //   name -        The name of the parameter.
0272   //
0273   // Returns:
0274   //   The value of the parameter.
0275   //
0276   {
0277     std::string val;
0278 
0279     if (_map.find(name) == _map.end()) {
0280       cerr << "can't find default for " << name << "\n";
0281       abort();
0282     } else {
0283       std::map<string, string>::const_iterator it = _map.find(name);
0284       val = it->second;
0285     }
0286 
0287     return val;
0288   }
0289 
0290   void Defaults_Textrep::doline(string l)
0291   //
0292   // Purpose: Helper to process a line defining a single parameter.
0293   //
0294   // Inputs:
0295   //   l -           The line to process.
0296   //
0297   {
0298     // Strip spaces from the line and ignore it if it's blank.
0299     l = strip(l);
0300     if (l.empty())
0301       return;
0302 
0303     // It must contain a `=' character.
0304     string::size_type pos = l.find('=');
0305     if (pos == string::npos) {
0306       cerr << "bad defaults line " << l << "\n";
0307       abort();
0308     }
0309 
0310     // Split off name and value parts.
0311     std::string name = strip(l.substr(0, pos));
0312     std::string val = strip(l.substr(pos + 1));
0313 
0314     // Add it to the map.
0315     _map[name] = val;
0316   }
0317 
0318   //***************************************************************************
0319 
0320   Defaults_Text::Defaults_Text(std::string def_file)
0321       //
0322       // Purpose: Constructor.
0323       //
0324       // Inputs:
0325       //   def_file -    The name of the defaults file to read.
0326       //                 See the comments in the header for a description
0327       //                 of the format for this and for the argument list.
0328       //                 Pass an empty string to skip reading a file.
0329       //
0330       : _rep(new Defaults_Textrep(def_file)) {}
0331 
0332   Defaults_Text::Defaults_Text(std::string def_file, int argc, char** argv)
0333       //
0334       // Purpose: Constructor.
0335       //
0336       // Inputs:
0337       //   def_file -    The name of the defaults file to read.
0338       //                 See the comments in the header for a description
0339       //                 of the format for this and for the argument list.
0340       //                 Pass an empty string to skip reading a file.
0341       //   argc -        The arglist length.
0342       //   argv -        The arglist.
0343       //
0344       : _rep(new Defaults_Textrep(def_file, argc, argv)) {}
0345 
0346   Defaults_Text::~Defaults_Text()
0347   //
0348   // Purpose: Destructor.
0349   //
0350   {
0351     delete _rep;
0352   }
0353 
0354   bool Defaults_Text::exists(std::string name) const
0355   //
0356   // Purpose: Test to see if parameter NAME exists.
0357   //
0358   // Inputs:
0359   //   name -        The name of the parameter to look up.
0360   //
0361   // Returns:
0362   //   True if NAME exists.
0363   //
0364   {
0365     std::string val;
0366     return (_rep->_map.find(name) != _rep->_map.end());
0367   }
0368 
0369   int Defaults_Text::get_int(std::string name) const
0370   //
0371   // Purpose: Get the value of NAME as an integer.
0372   //
0373   // Inputs:
0374   //   name -        The name of the parameter to look up.
0375   //
0376   // Returns:
0377   //   The parameter's value as an integer.
0378   //
0379   {
0380     return atoi(_rep->get_val(name).c_str());
0381   }
0382 
0383   double Defaults_Text::get_float(std::string name) const
0384   //
0385   // Purpose: Get the value of NAME as a float.
0386   //
0387   // Inputs:
0388   //   name -        The name of the parameter to look up.
0389   //
0390   // Returns:
0391   //   The parameter's value as a float.
0392   //
0393   {
0394     return atof(_rep->get_val(name).c_str());
0395   }
0396 
0397   bool Defaults_Text::get_bool(std::string name) const
0398   //
0399   // Purpose: Get the value of NAME as a bool.
0400   //
0401   // Inputs:
0402   //   name -        The name of the parameter to look up.
0403   //
0404   // Returns:
0405   //   The parameter's value as a bool.
0406   //
0407   {
0408     string val = _rep->get_val(name);
0409     if (tolower(val[0]) == 't' || tolower(val[0]) == 'y')
0410       return true;
0411     else if (tolower(val[0]) == 'f' || tolower(val[0]) == 'n')
0412       return false;
0413     return !!get_int(name);
0414   }
0415 
0416   string Defaults_Text::get_string(std::string name) const
0417   //
0418   // Purpose: Get the value of NAME as a string.
0419   //
0420   // Inputs:
0421   //   name -        The name of the parameter to look up.
0422   //
0423   // Returns:
0424   //   The parameter's value as a string.
0425   //
0426   {
0427     return _rep->get_val(name);
0428   }
0429 
0430   std::ostream& operator<<(std::ostream& s, const Defaults_Text& def)
0431   //
0432   // Purpose: Dump out all parameter settings.
0433   //
0434   // Inputs:
0435   //   s -           The stream to which we're writing.
0436   //   def -         The instance to dump.
0437   //
0438   // Returns:
0439   //   The stream S.
0440   //
0441   {
0442     for (std::map<std::string, std::string>::const_iterator it = def._rep->_map.begin(); it != def._rep->_map.end();
0443          it++) {
0444       s << "[" << it->first << "] = [" << it->second << "]\n";
0445     }
0446 
0447     return s;
0448   }
0449 
0450 }  // namespace hitfit