00001
00002
00003
00004
00005
00006
00007
00008
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
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 }
00040
00041 void
00042 ParameterSet::invalidate() const
00043 {
00044 id_ = ParameterSetID();
00045 }
00046
00047
00048
00049
00050
00051
00052 ParameterSet::ParameterSet() :
00053 tbl_(),
00054 id_()
00055 {
00056 validate();
00057 }
00058
00059
00060
00061
00062 ParameterSetID
00063 ParameterSet::id() const
00064 {
00065 if (!id_.isValid()) validate();
00066 return id_;
00067 }
00068
00069
00070
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
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 }
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 }
00153
00154
00155
00156 void
00157 ParameterSet::insert(bool okay_to_replace, std::string const& name, Entry const& value) {
00158
00159 invalidate();
00160
00161
00162
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 }
00175
00176
00177
00178
00179 void
00180 ParameterSet::augment(ParameterSet const& from) {
00181
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 }
00191
00192
00193
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 }
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
00263 invalidate();
00264
00265 std::vector<std::string> temp;
00266 if(! split(std::back_inserter(temp), from, '<', ';', '>'))
00267 return false;
00268
00269 tbl_.clear();
00270 for(std::vector<std::string>::const_iterator b = temp.begin(), e = temp.end(); b != e; ++b) {
00271
00272 std::string::const_iterator q
00273 = find_in_all(*b, '=');
00274 if(q == b->end())
00275 return false;
00276
00277
00278 std::string name = std::string(b->begin(), q);
00279 if(tbl_.find(name) != tbl_.end())
00280 return false;
00281
00282
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 }
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)
00355 {
00356 ++count;
00357 output.push_back(it->first);
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
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
00398
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
00424
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
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 }