CMS 3D CMS Logo

ParameterSet.cc

Go to the documentation of this file.
00001 // ----------------------------------------------------------------------
00002 // $Id: ParameterSet.cc,v 1.36 2007/11/11 00:24:43 wmtan Exp $
00003 //
00004 // definition of ParameterSet's function members
00005 // ----------------------------------------------------------------------
00006 
00007 // ----------------------------------------------------------------------
00008 // prerequisite source files and headers
00009 // ----------------------------------------------------------------------
00010 
00011 #include "FWCore/Utilities/interface/Digest.h"
00012 
00013 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00014 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00015 #include "FWCore/ParameterSet/interface/Registry.h"
00016 
00017 #include "FWCore/ParameterSet/interface/split.h"
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019 #include "FWCore/Utilities/interface/EDMException.h"
00020 #include "FWCore/Utilities/interface/Algorithms.h"
00021 
00022 #include "boost/bind.hpp"
00023 
00024 #include <algorithm>
00025 
00026 // ----------------------------------------------------------------------
00027 // class invariant checker
00028 // ----------------------------------------------------------------------
00029 
00030 namespace edm {
00031 
00032   void
00033   ParameterSet::validate() const
00034   {
00035     std::string stringrep = this->toStringOfTracked();
00036     cms::Digest md5alg(stringrep);
00037     id_ = ParameterSetID(md5alg.digest().toString());
00038     
00039   }  // ParameterSet::validate()
00040 
00041   void
00042   ParameterSet::invalidate() const
00043   {
00044     id_ = ParameterSetID();
00045   }
00046 
00047 
00048   // ----------------------------------------------------------------------
00049   // constructors
00050   // ----------------------------------------------------------------------
00051 
00052   ParameterSet::ParameterSet() :
00053     tbl_(),
00054     id_()
00055   {
00056     validate();
00057   }
00058 
00059 
00060   // ----------------------------------------------------------------------
00061   // identification
00062   ParameterSetID
00063   ParameterSet::id() const
00064   {
00065     if (!id_.isValid()) validate();
00066     return id_;
00067   }
00068 
00069   // ----------------------------------------------------------------------
00070   // coded string
00071 
00072   ParameterSet::ParameterSet(std::string const& code) :
00073     tbl_(),
00074     id_()
00075   {
00076     if(! fromString(code))
00077       throw edm::Exception(errors::Configuration,"InvalidInput")
00078         << "The encoded configuration string "
00079         << "passed to a ParameterSet during construction is invalid:\n"
00080         << code;
00081 
00082     validate();
00083   }
00084 
00085 
00086 
00087   // ----------------------------------------------------------------------
00088   // Entry-handling
00089   // ----------------------------------------------------------------------
00090 
00091   Entry const*
00092   ParameterSet::getEntryPointerOrThrow_(std::string const& name) const {
00093     Entry const* result = retrieveUntracked(name);
00094     if (result == 0)
00095       throw edm::Exception(errors::Configuration, "MissingParameter:")
00096         << "The required parameter '" << name
00097         << "' was not specified.\n";
00098     return result;
00099   }
00100 
00101 
00102 
00103   template <class T, class U> T first(std::pair<T,U> const& p)
00104   { return p.first; }
00105 
00106   template <class T, class U> U second(std::pair<T,U> const& p)
00107   { return p.second; }
00108 
00109   Entry const&
00110   ParameterSet::retrieve(std::string const& name) const {
00111     table::const_iterator  it = tbl_.find(name);
00112     if (it == tbl_.end()) {
00113         throw edm::Exception(errors::Configuration,"MissingParameter:")
00114           << "Parameter '" << name
00115           << "' not found.";
00116     }
00117     if (it->second.isTracked() == false) {
00118       if (name[0] == '@') {
00119         throw edm::Exception(errors::Configuration,"StatusMismatch:")
00120           << "Framework Error:  Parameter '" << name
00121           << "' is incorrectly designated as tracked in the framework.";
00122       } else {
00123         throw edm::Exception(errors::Configuration,"StatusMismatch:")
00124           << "Parameter '" << name
00125           << "' is designated as tracked in the code,\n"
00126           << "but is designated as untracked in the configuration file.\n"
00127           << "Please remove 'untracked' from the configuration file for parameter '"<< name << "'.";
00128       }
00129     }
00130     return it->second;
00131   }  // retrieve()
00132 
00133   Entry const* const
00134   ParameterSet::retrieveUntracked(std::string const& name) const {
00135     table::const_iterator  it = tbl_.find(name);
00136 
00137     if (it == tbl_.end()) return 0;
00138     if (it->second.isTracked()) {
00139       if (name[0] == '@') {
00140         throw edm::Exception(errors::Configuration,"StatusMismatch:")
00141           << "Framework Error:  Parameter '" << name
00142           << "' is incorrectly designated as untracked in the framework.";
00143       } else {
00144         throw edm::Exception(errors::Configuration,"StatusMismatch:")
00145           << "Parameter '" << name
00146           << "' is designated as untracked in the code,\n"
00147           << "but is not designated as untracked in the configuration file.\n"
00148           << "Please change the configuration file to 'untracked <type> " << name << "'.";
00149       }
00150     }
00151     return &it->second;
00152   }  // retrieve()
00153 
00154   // ----------------------------------------------------------------------
00155 
00156   void
00157   ParameterSet::insert(bool okay_to_replace, std::string const& name, Entry const& value) {
00158     // This preemptive invalidation may be more agressive than necessary.
00159     invalidate();
00160 
00161     // We should probably get rid of 'okay_to_replace', which will
00162     // simplify the logic in this function.
00163     table::iterator  it = tbl_.find(name);
00164 
00165     if(it == tbl_.end())  {
00166       if(! tbl_.insert(std::make_pair(name, value)).second)
00167         throw edm::Exception(errors::Configuration,"InsertFailure")
00168           << "cannot insert " << name
00169           << " into a ParmeterSet\n";
00170     }
00171     else if(okay_to_replace)  {
00172       it->second = value;
00173     }
00174   }  // insert()
00175 
00176   // ----------------------------------------------------------------------
00177   // copy without overwriting
00178   // ----------------------------------------------------------------------
00179   void
00180   ParameterSet::augment(ParameterSet const& from) {
00181     // This preemptive invalidation may be more agressive than necessary.
00182     invalidate();
00183 
00184     if(& from == this)
00185       return;
00186 
00187     for(table::const_iterator b = from.tbl_.begin(), e = from.tbl_.end(); b != e; ++b) {
00188       this->insert(false, b->first, b->second);
00189     }
00190   }  // augment()
00191 
00192   // ----------------------------------------------------------------------
00193   // coding
00194   // ----------------------------------------------------------------------
00195 
00196   std::string
00197   ParameterSet::toString() const {
00198     if (tbl_.empty()) {
00199       std::string emptyPSet = "<>";
00200       return emptyPSet;
00201     }
00202     size_t size = 1;
00203     for(table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
00204       size += 2;
00205       size += b->first.size();
00206       size += b->second.sizeOfString();
00207     }
00208     std::string rep;
00209     rep.reserve(size);
00210     rep += '<';
00211     for(table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
00212       if(b != tbl_.begin()) rep += ';';
00213       rep += b->first;
00214       rep += '=';
00215       rep += b->second.toString();
00216     }
00217     rep += '>';
00218     return rep;
00219   }  // to_string()
00220 
00221   // ----------------------------------------------------------------------
00222 
00223   std::string
00224   ParameterSet::toStringOfTracked() const {
00225     size_t size = 0;
00226     bool need_sep = false;
00227     for(table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
00228       if(b->second.isTracked())  {
00229         if(need_sep) ++size;
00230         ++size;
00231         size += b->first.size();
00232         size += b->second.sizeOfStringOfTracked();
00233         need_sep = true;
00234       }
00235     }
00236     if (size == 0) {
00237       std::string emptyPSet = "<>";
00238       return emptyPSet;
00239     }
00240     size += 2;
00241     std::string rep;
00242     rep.reserve(size);
00243     rep += '<';
00244     need_sep = false;
00245     for(table::const_iterator b = tbl_.begin(), e = tbl_.end(); b != e; ++b) {
00246       if(b->second.isTracked())  {
00247         if(need_sep) rep += ';';
00248         rep += b->first;
00249         rep += '=';
00250         rep += b->second.toStringOfTracked();
00251         need_sep = true;
00252       }
00253     }
00254     rep += '>';    
00255     return rep;
00256   } 
00257 
00258   // ----------------------------------------------------------------------
00259 
00260   bool
00261   ParameterSet::fromString(std::string const& from) {
00262     // This preemptive invalidation may be more agressive than necessary.
00263     invalidate();
00264 
00265     std::vector<std::string> temp;
00266     if(! split(std::back_inserter(temp), from, '<', ';', '>'))
00267       return false;
00268 
00269     tbl_.clear();  // precaution
00270     for(std::vector<std::string>::const_iterator b = temp.begin(), e = temp.end(); b != e; ++b) {
00271       // locate required name/value separator
00272       std::string::const_iterator  q
00273         = find_in_all(*b, '=');
00274       if(q == b->end())
00275         return false;
00276 
00277       // form name unique to this ParameterSet
00278       std::string  name = std::string(b->begin(), q);
00279       if(tbl_.find(name) != tbl_.end())
00280         return false;
00281 
00282       // form value and insert name/value pair
00283       Entry  value(name, std::string(q+1, b->end()));
00284       if(! tbl_.insert(std::make_pair(name, value)).second)
00285         return false;
00286     }
00287 
00288     return true;
00289   }  // from_string()
00290 
00291   std::vector<edm::FileInPath>::size_type
00292   ParameterSet::getAllFileInPaths(std::vector<edm::FileInPath>& output) const {
00293     std::vector<edm::FileInPath>::size_type count = 0;
00294     table::const_iterator it = tbl_.begin();
00295     table::const_iterator end = tbl_.end();
00296     while (it != end) {
00297         Entry const& e = it->second;
00298         if (e.typeCode() == 'F') {
00299             ++count;
00300             output.push_back(e.getFileInPath());
00301         }
00302         ++it;
00303     }
00304     return count;
00305   }
00306 
00307   std::vector<std::string>
00308   ParameterSet::getParameterNames() const {
00309     std::vector<std::string> returnValue(tbl_.size());
00310     std::transform(tbl_.begin(), tbl_.end(),returnValue.begin(),
00311                    boost::bind(&std::pair<std::string const, Entry>::first,_1));
00312     return returnValue;
00313   }
00314 
00315 
00316   bool ParameterSet::exists(const std::string & parameterName) const
00317   {
00318     return( tbl_.find(parameterName) != tbl_.end() );
00319   }
00320 
00321 
00322   ParameterSet
00323   ParameterSet::trackedPart() const
00324   {
00325     return ParameterSet(this->toStringOfTracked());
00326   }
00327 
00328    size_t
00329    ParameterSet::getParameterSetNames(std::vector<std::string>& output,
00330                                       bool trackiness) const
00331    {
00332      return getNamesByCode_('P', trackiness, output);
00333    }
00334 
00335    size_t
00336    ParameterSet::getParameterSetVectorNames(std::vector<std::string>& output,
00337                                             bool trackiness) const
00338    {
00339      return getNamesByCode_('p', trackiness, output);
00340    }
00341 
00342   size_t
00343   ParameterSet::getNamesByCode_(char code,
00344                                 bool trackiness,
00345                                 std::vector<std::string>& output) const
00346   {
00347     size_t count = 0;
00348     table::const_iterator it = tbl_.begin();
00349     table::const_iterator end = tbl_.end();
00350     while ( it != end )
00351     {
00352       Entry const& e = it->second;
00353       if (e.typeCode() == code &&
00354           e.isTracked() == trackiness) // if it is a vector of ParameterSet
00355         {
00356           ++count;
00357           output.push_back(it->first); // save the name
00358         }
00359       ++it;
00360     }
00361     return count;
00362 
00363   }
00364 
00365 
00366   std::string ParameterSet::dump() const
00367   {
00368     std::ostringstream os;
00369     table::const_iterator i(tbl_.begin()), e(tbl_.end());
00370     os << "{" << std::endl;
00371     for( ; i != e; ++i)
00372     {
00373       // indent a bit
00374       os << "  " << i->first << ": " << i->second << std::endl;
00375     }
00376     os << "}";
00377     return os.str();
00378   }
00379 
00380 
00381   std::ostream & operator<<(std::ostream & os, const ParameterSet & pset)
00382   {
00383     os << pset.dump();
00384     return os;
00385   }
00386 
00387   
00388     
00389   namespace pset
00390   {
00391     void explode(edm::ParameterSet const& top,
00392                std::vector<edm::ParameterSet>& results)
00393     {
00394       using namespace edm;
00395       results.push_back(top);
00396 
00397       // Get names of all ParameterSets; iterate through them,
00398       // recursively calling explode...
00399       std::vector<std::string> names;
00400       const bool tracked = true;
00401       const bool untracked = false;
00402       top.getParameterSetNames(names, tracked);
00403       std::vector<std::string>::const_iterator it = names.begin();
00404       std::vector<std::string>::const_iterator end = names.end();
00405       for( ; it != end; ++it )
00406       {
00407         ParameterSet next_top =
00408           top.getParameter<ParameterSet>(*it);
00409         explode(next_top, results);
00410       }
00411 
00412       names.clear();
00413       top.getParameterSetNames(names, untracked);
00414       it = names.begin();
00415       end = names.end();
00416       for( ; it != end; ++it )
00417       {
00418         ParameterSet next_top =
00419           top.getUntrackedParameter<ParameterSet>(*it);
00420         explode(next_top, results);
00421       }
00422  
00423       // Get names of all ParameterSets vectors; iterate through them,
00424       // recursively calling explode...
00425       names.clear();
00426       top.getParameterSetVectorNames(names, tracked);
00427       it = names.begin();
00428       end = names.end();
00429       for( ; it != end; ++it )
00430       {
00431         std::vector<ParameterSet> next_bunch =
00432           top.getParameter<std::vector<ParameterSet> >(*it);
00433 
00434         std::vector<ParameterSet>::const_iterator first =
00435           next_bunch.begin();
00436         std::vector<ParameterSet>::const_iterator last
00437           = next_bunch.end();
00438 
00439         for( ; first != last; ++first )
00440         {
00441             explode(*first, results);
00442         }       
00443       }
00444 
00445       names.clear();
00446       top.getParameterSetVectorNames(names, untracked);
00447       it = names.begin();
00448       end = names.end();
00449       for( ; it != end; ++it )
00450       {
00451         std::vector<ParameterSet> next_bunch =
00452           top.getUntrackedParameter<std::vector<ParameterSet> >(*it);
00453 
00454         std::vector<ParameterSet>::const_iterator first =
00455           next_bunch.begin();
00456         std::vector<ParameterSet>::const_iterator last
00457           = next_bunch.end();
00458 
00459         for( ; first != last; ++first )
00460         {
00461             explode(*first, results);
00462         }       
00463       }
00464     }
00465   }
00466 
00467   // Free function to return a parameterSet given its ID.
00468   ParameterSet
00469   getParameterSet(ParameterSetID const& id) {
00470     ParameterSet result;
00471     if(!pset::Registry::instance()->getMapped(id, result)) {
00472         throw edm::Exception(errors::Configuration,"MissingParameterSet:")
00473           << "Parameter Set ID '" << id
00474           << "' not found.";
00475     }
00476     return result;
00477   }
00478   void ParameterSet::depricatedInputTagWarning(std::string const& name, 
00479                                                std::string const& label) const
00480   {
00481     edm::LogWarning("Configuration") << "Warning:\n\tstring " << name 
00482                                      << " = \"" << label 
00483                                      << "\"\nis deprecated, "
00484                                      << "please update your config file to use\n\tInputTag " 
00485                                      << name << " = " << label;
00486   }
00487 } // namespace edm

Generated on Tue Jun 9 17:36:28 2009 for CMSSW by  doxygen 1.5.4