00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <opspace/Parameter.hpp>
00023 #include <fstream>
00024
00025 using namespace jspace;
00026
00027 namespace opspace {
00028
00029
00030 Parameter::
00031 Parameter(std::string const & name,
00032 parameter_type_t type,
00033 parameter_flags_t flags,
00034 ParameterReflection const * checker)
00035 : name_(name),
00036 type_(type),
00037 flags_(flags),
00038 checker_(checker)
00039 {
00040 switch (type) {
00041 case PARAMETER_TYPE_VOID:
00042 case PARAMETER_TYPE_INTEGER:
00043 case PARAMETER_TYPE_STRING:
00044 case PARAMETER_TYPE_REAL:
00045 case PARAMETER_TYPE_VECTOR:
00046 case PARAMETER_TYPE_MATRIX:
00047 break;
00048 default:
00049 const_cast<parameter_type_t &>(type_) = PARAMETER_TYPE_VOID;
00050 }
00051 }
00052
00053
00054 Parameter::
00055 ~Parameter()
00056 {
00057 }
00058
00059
00060 int const * Parameter::
00061 getInteger() const
00062 {
00063 return 0;
00064 }
00065
00066
00067 std::string const * Parameter::
00068 getString() const
00069 {
00070 return 0;
00071 }
00072
00073
00074 double const * Parameter::
00075 getReal() const
00076 {
00077 return 0;
00078 }
00079
00080
00081 Vector const * Parameter::
00082 getVector() const
00083 {
00084 return 0;
00085 }
00086
00087
00088 Matrix const * Parameter::
00089 getMatrix() const
00090 {
00091 return 0;
00092 }
00093
00094
00095 Status Parameter::
00096 set(int value)
00097 {
00098 Status err(false, "type mismatch");
00099 return err;
00100 }
00101
00102
00103 Status Parameter::
00104 set(std::string const & value)
00105 {
00106 Status err(false, "type mismatch");
00107 return err;
00108 }
00109
00110
00111 Status Parameter::
00112 set(double value)
00113 {
00114 Status err(false, "type mismatch");
00115 return err;
00116 }
00117
00118
00119 Status Parameter::
00120 set(Vector const & value)
00121 {
00122 Status err(false, "type mismatch");
00123 return err;
00124 }
00125
00126
00127 Status Parameter::
00128 set(Matrix const & value)
00129 {
00130 Status err(false, "type mismatch");
00131 return err;
00132 }
00133
00134
00135 void Parameter::
00136 dump(std::ostream & os, std::string const & prefix) const
00137 {
00138 os << prefix << name_ << " : void\n";
00139 }
00140
00141
00142 IntegerParameter::
00143 IntegerParameter(std::string const & name,
00144 parameter_flags_t flags,
00145 ParameterReflection const * checker,
00146 int * integer)
00147 : Parameter(name, PARAMETER_TYPE_INTEGER, flags, checker),
00148 integer_(integer)
00149 {
00150 }
00151
00152
00153 Status IntegerParameter::
00154 set(int integer)
00155 {
00156 Status st;
00157 if (flags_ & PARAMETER_FLAG_READONLY) {
00158 st.ok = false;
00159 st.errstr = "read-only parameter";
00160 return st;
00161 }
00162 if (checker_) {
00163 st = checker_->check(integer_, integer);
00164 if ( ! st) {
00165 return st;
00166 }
00167 }
00168 *integer_ = integer;
00169 return st;
00170 }
00171
00172
00173 void IntegerParameter::
00174 dump(std::ostream & os, std::string const & prefix) const
00175 {
00176 os << prefix << name_ << " : integer = " << *integer_ << "\n";
00177 }
00178
00179
00180 StringParameter::
00181 StringParameter(std::string const & name,
00182 parameter_flags_t flags,
00183 ParameterReflection const * checker,
00184 std::string * instance)
00185 : Parameter(name, PARAMETER_TYPE_STRING, flags, checker),
00186 string_(instance)
00187 {
00188 }
00189
00190
00191 Status StringParameter::
00192 set(std::string const & value)
00193 {
00194 Status st;
00195 if (flags_ & PARAMETER_FLAG_READONLY) {
00196 st.ok = false;
00197 st.errstr = "read-only parameter";
00198 return st;
00199 }
00200 if (checker_) {
00201 st = checker_->check(string_, value);
00202 if ( ! st) {
00203 return st;
00204 }
00205 }
00206 *string_ = value;
00207 return st;
00208 }
00209
00210
00211 void StringParameter::
00212 dump(std::ostream & os, std::string const & prefix) const
00213 {
00214 os << prefix << name_ << " : string = " << *string_ << "\n";
00215 }
00216
00217
00218 RealParameter::
00219 RealParameter(std::string const & name,
00220 parameter_flags_t flags,
00221 ParameterReflection const * checker,
00222 double * real)
00223 : Parameter(name, PARAMETER_TYPE_REAL, flags, checker),
00224 real_(real)
00225 {
00226 }
00227
00228
00229 Status RealParameter::
00230 set(double real)
00231 {
00232 Status st;
00233 if (flags_ & PARAMETER_FLAG_READONLY) {
00234 st.ok = false;
00235 st.errstr = "read-only parameter";
00236 return st;
00237 }
00238 if (checker_) {
00239 st = checker_->check(real_, real);
00240 if ( ! st) {
00241 return st;
00242 }
00243 }
00244 *real_ = real;
00245 return st;
00246 }
00247
00248
00249 void RealParameter::
00250 dump(std::ostream & os, std::string const & prefix) const
00251 {
00252 os << prefix << name_ << " : real = " << *real_ << "\n";
00253 }
00254
00255
00256 VectorParameter::
00257 VectorParameter(std::string const & name,
00258 parameter_flags_t flags,
00259 ParameterReflection const * checker,
00260 Vector * vector)
00261 : Parameter(name, PARAMETER_TYPE_VECTOR, flags, checker),
00262 vector_(vector)
00263 {
00264 }
00265
00266
00267 Status VectorParameter::
00268 set(Vector const & vector)
00269 {
00270 Status st;
00271 if (flags_ & PARAMETER_FLAG_READONLY) {
00272 st.ok = false;
00273 st.errstr = "read-only parameter";
00274 return st;
00275 }
00276 if (checker_) {
00277 st = checker_->check(vector_, vector);
00278 if ( ! st) {
00279 return st;
00280 }
00281 }
00282 *vector_ = vector;
00283 return st;
00284 }
00285
00286
00287 void VectorParameter::
00288 dump(std::ostream & os, std::string const & prefix) const
00289 {
00290 os << prefix << name_ << " : vector =\n"
00291 << prefix << " " << pretty_string(*vector_) << "\n";
00292 }
00293
00294
00295 MatrixParameter::
00296 MatrixParameter(std::string const & name,
00297 parameter_flags_t flags,
00298 ParameterReflection const * checker,
00299 Matrix * matrix)
00300 : Parameter(name, PARAMETER_TYPE_MATRIX, flags, checker),
00301 matrix_(matrix)
00302 {
00303 }
00304
00305
00306 Status MatrixParameter::
00307 set(Matrix const & matrix)
00308 {
00309 Status st;
00310 if (flags_ & PARAMETER_FLAG_READONLY) {
00311 st.ok = false;
00312 st.errstr = "read-only parameter";
00313 return st;
00314 }
00315 if (checker_) {
00316 st = checker_->check(matrix_, matrix);
00317 if ( ! st) {
00318 return st;
00319 }
00320 }
00321 *matrix_ = matrix;
00322 return st;
00323 }
00324
00325
00326 void MatrixParameter::
00327 dump(std::ostream & os, std::string const & prefix) const
00328 {
00329 os << prefix << name_ << " : matrix =\n"
00330 << pretty_string(*matrix_, prefix + " ") << "\n";
00331 }
00332
00333
00334 ParameterReflection::
00335 ParameterReflection(std::string const & type_name,
00336 std::string const & instance_name)
00337 : type_name_(type_name),
00338 instance_name_(instance_name)
00339 {
00340 }
00341
00342
00343 ParameterReflection::
00344 ~ParameterReflection()
00345 {
00346 for (parameter_lookup_t::iterator ii(parameter_lookup_.begin());
00347 ii != parameter_lookup_.end(); ++ii) {
00348 delete ii->second;
00349 }
00350 }
00351
00352
00353 Parameter * ParameterReflection::
00354 lookupParameter(std::string const & name)
00355 {
00356 parameter_lookup_t::iterator ii(parameter_lookup_.find(name));
00357 if (parameter_lookup_.end() == ii) {
00358 return 0;
00359 }
00360 return ii->second;
00361 }
00362
00363
00364 Parameter const * ParameterReflection::
00365 lookupParameter(std::string const & name) const
00366 {
00367 parameter_lookup_t::const_iterator ii(parameter_lookup_.find(name));
00368 if (parameter_lookup_.end() == ii) {
00369 return 0;
00370 }
00371 return ii->second;
00372 }
00373
00374
00375 Parameter * ParameterReflection::
00376 lookupParameter(std::string const & name, parameter_type_t type)
00377 {
00378 parameter_lookup_t::iterator ii(parameter_lookup_.find(name));
00379 if (parameter_lookup_.end() == ii) {
00380 return 0;
00381 }
00382 if (type != ii->second->type_) {
00383 return 0;
00384 }
00385 return ii->second;
00386 }
00387
00388
00389 Parameter const * ParameterReflection::
00390 lookupParameter(std::string const & name, parameter_type_t type) const
00391 {
00392 parameter_lookup_t::const_iterator ii(parameter_lookup_.find(name));
00393 if (parameter_lookup_.end() == ii) {
00394 return 0;
00395 }
00396 if (type != ii->second->type_) {
00397 return 0;
00398 }
00399 return ii->second;
00400 }
00401
00402
00403 Status ParameterReflection::
00404 check(int const * param, int value) const
00405 {
00406 Status ok;
00407 return ok;
00408 }
00409
00410
00411 Status ParameterReflection::
00412 check(std::string const * param, std::string const & value) const
00413 {
00414 Status ok;
00415 return ok;
00416 }
00417
00418
00419 Status ParameterReflection::
00420 check(double const * param, double value) const
00421 {
00422 Status ok;
00423 return ok;
00424 }
00425
00426
00427 Status ParameterReflection::
00428 check(Vector const * param, Vector const & value) const
00429 {
00430 Status ok;
00431 return ok;
00432 }
00433
00434
00435 Status ParameterReflection::
00436 check(Matrix const * param, Matrix const & value) const
00437 {
00438 Status ok; return ok;
00439 }
00440
00441
00442 void ParameterReflection::
00443 dump(std::ostream & os, std::string const & title, std::string const & prefix) const
00444 {
00445 if ( ! title.empty()) {
00446 os << title << "\n";
00447 }
00448 for (parameter_lookup_t::const_iterator ii(parameter_lookup_.begin());
00449 ii != parameter_lookup_.end(); ++ii) {
00450 ii->second->dump(os, prefix + " ");
00451 }
00452 }
00453
00454
00455 IntegerParameter * ParameterReflection::
00456 declareParameter(std::string const & name, int * integer, parameter_flags_t flags)
00457 {
00458 IntegerParameter * entry(new IntegerParameter(name, flags, this, integer));
00459 parameter_lookup_.insert(std::make_pair(name, entry));
00460 return entry;
00461 }
00462
00463
00464 StringParameter * ParameterReflection::
00465 declareParameter(std::string const & name, std::string * instance, parameter_flags_t flags)
00466 {
00467 StringParameter * entry(new StringParameter(name, flags, this, instance));
00468 parameter_lookup_.insert(std::make_pair(name, entry));
00469 return entry;
00470 }
00471
00472
00473 RealParameter * ParameterReflection::
00474 declareParameter(std::string const & name, double * real, parameter_flags_t flags)
00475 {
00476 RealParameter * entry(new RealParameter(name, flags, this, real));
00477 parameter_lookup_.insert(std::make_pair(name, entry));
00478 return entry;
00479 }
00480
00481
00482 VectorParameter * ParameterReflection::
00483 declareParameter(std::string const & name, Vector * vector, parameter_flags_t flags)
00484 {
00485 VectorParameter * entry(new VectorParameter(name, flags, this, vector));
00486 parameter_lookup_.insert(std::make_pair(name, entry));
00487 return entry;
00488 }
00489
00490
00491 MatrixParameter * ParameterReflection::
00492 declareParameter(std::string const & name, Matrix * matrix, parameter_flags_t flags)
00493 {
00494 MatrixParameter * entry(new MatrixParameter(name, flags, this, matrix));
00495 parameter_lookup_.insert(std::make_pair(name, entry));
00496 return entry;
00497 }
00498
00499
00500 template<typename parameter_t, typename storage_t>
00501 bool maybe_append(std::vector<ParameterLog::log_s<parameter_t, storage_t> > & collection,
00502 Parameter const * parameter)
00503 {
00504 parameter_t const * pp(dynamic_cast<parameter_t const *>(parameter));
00505 if (pp) {
00506 if (pp->flags_ & PARAMETER_FLAG_NOLOG) {
00507 return true;
00508 }
00509 collection.push_back(ParameterLog::log_s<parameter_t, storage_t>(pp));
00510 return true;
00511 }
00512 return false;
00513 }
00514
00515
00516 ParameterLog::
00517 ParameterLog(std::string const & nn, parameter_lookup_t const & parameter_lookup)
00518 : name(nn)
00519 {
00520 for (parameter_lookup_t::const_iterator ii(parameter_lookup.begin());
00521 ii != parameter_lookup.end(); ++ii) {
00522 if (maybe_append(intlog, ii->second)) {
00523 continue;
00524 }
00525 if (maybe_append(strlog, ii->second)) {
00526 continue;
00527 }
00528 if (maybe_append(reallog, ii->second)) {
00529 continue;
00530 }
00531 if (maybe_append(veclog, ii->second)) {
00532 continue;
00533 }
00534 if (maybe_append(mxlog, ii->second)) {
00535 continue;
00536 }
00537 }
00538 }
00539
00540
00541 void ParameterLog::
00542 update(long long timestamp_)
00543 {
00544 timestamp.push_back(timestamp_);
00545 for (size_t ii(0); ii < intlog.size(); ++ii) {
00546 intlog[ii].log.push_back(*intlog[ii].parameter->getInteger());
00547 }
00548 for (size_t ii(0); ii < strlog.size(); ++ii) {
00549 strlog[ii].log.push_back(*strlog[ii].parameter->getString());
00550 }
00551 for (size_t ii(0); ii < reallog.size(); ++ii) {
00552 reallog[ii].log.push_back(*reallog[ii].parameter->getReal());
00553 }
00554 for (size_t ii(0); ii < veclog.size(); ++ii) {
00555 veclog[ii].log.push_back(*veclog[ii].parameter->getVector());
00556 }
00557 for (size_t ii(0); ii < mxlog.size(); ++ii) {
00558 mxlog[ii].log.push_back(*mxlog[ii].parameter->getMatrix());
00559 }
00560 }
00561
00562
00563 void ParameterLog::
00564 writeFiles(std::string const & prefix, std::ostream * progress) const
00565 {
00566 if (progress) {
00567 *progress << "writing parameter log: " << name << "\n";
00568 }
00569
00570 if ( ! intlog.empty()) {
00571 if (progress) {
00572 *progress << " integers:";
00573 }
00574 for (size_t ii(0); ii < intlog.size(); ++ii) {
00575 log_s<IntegerParameter, int> const & log(intlog[ii]);
00576 if ( ! log.log.empty()) {
00577 if (progress) {
00578 *progress << " " << log.parameter->name_ << "...";
00579 }
00580 std::string const fn(prefix + "-" + name + "-" + log.parameter->name_ + ".dump");
00581 std::ofstream os(fn.c_str());
00582 if (os) {
00583 size_t const nn(log.log.size());
00584 os << "# name: " << name << "\n"
00585 << "# parameter: " << log.parameter->name_ << "\n"
00586 << "# type: integer\n"
00587 << "# size: " << nn << "\n";
00588 for (size_t jj(0); jj < nn; ++jj) {
00589 os << timestamp[jj] << " " << log.log[jj] << "\n";
00590 }
00591 }
00592 }
00593 }
00594 if (progress) {
00595 *progress << " DONE\n";
00596 }
00597 }
00598
00599 if ( ! strlog.empty()) {
00600 if (progress) {
00601 *progress << " strings:";
00602 }
00603 for (size_t ii(0); ii < strlog.size(); ++ii) {
00604 log_s<StringParameter, std::string> const & log(strlog[ii]);
00605 if ( ! log.log.empty()) {
00606 if (progress) {
00607 *progress << " " << log.parameter->name_ << "...";
00608 }
00609 std::string const fn(prefix + "-" + name + "-" + log.parameter->name_ + ".dump");
00610 std::ofstream os(fn.c_str());
00611 if (os) {
00612 size_t const nn(log.log.size());
00613 os << "# name: " << name << "\n"
00614 << "# parameter: " << log.parameter->name_ << "\n"
00615 << "# type: string\n"
00616 << "# size: " << nn << "\n";
00617 for (size_t jj(0); jj < nn; ++jj) {
00618 os << timestamp[jj] << " " << log.log[jj] << "\n";
00619 }
00620 }
00621 }
00622 }
00623 if (progress) {
00624 *progress << " DONE\n";
00625 }
00626 }
00627
00628 if ( ! reallog.empty()) {
00629 if (progress) {
00630 *progress << " reals:";
00631 }
00632 for (size_t ii(0); ii < reallog.size(); ++ii) {
00633 log_s<RealParameter, double> const & log(reallog[ii]);
00634 if ( ! log.log.empty()) {
00635 if (progress) {
00636 *progress << " " << log.parameter->name_ << "...";
00637 }
00638 std::string const fn(prefix + "-" + name + "-" + log.parameter->name_ + ".dump");
00639 std::ofstream os(fn.c_str());
00640 if (os) {
00641 size_t const nn(log.log.size());
00642 os << "# name: " << name << "\n"
00643 << "# parameter: " << log.parameter->name_ << "\n"
00644 << "# type: real\n"
00645 << "# size: " << nn << "\n";
00646 for (size_t jj(0); jj < nn; ++jj) {
00647 os << timestamp[jj] << " " << log.log[jj] << "\n";
00648 }
00649 }
00650 }
00651 }
00652 if (progress) {
00653 *progress << " DONE\n";
00654 }
00655 }
00656
00657 if ( ! veclog.empty()) {
00658 if (progress) {
00659 *progress << " vectors:";
00660 }
00661 for (size_t ii(0); ii < veclog.size(); ++ii) {
00662 log_s<VectorParameter, Vector> const & log(veclog[ii]);
00663 if ( ! log.log.empty()) {
00664 if (progress) {
00665 *progress << " " << log.parameter->name_ << "...";
00666 }
00667 std::string const fn(prefix + "-" + name + "-" + log.parameter->name_ + ".dump");
00668 std::ofstream os(fn.c_str());
00669 if (os) {
00670 size_t const nn(log.log.size());
00671 os << "# name: " << name << "\n"
00672 << "# parameter: " << log.parameter->name_ << "\n"
00673 << "# type: vector\n"
00674 << "# size: " << nn << "\n";
00675 for (size_t jj(0); jj < nn; ++jj) {
00676 os << timestamp[jj] << " ";
00677 jspace::pretty_print(log.log[jj], os, "", "");
00678 }
00679 }
00680 }
00681 }
00682 if (progress) {
00683 *progress << " DONE\n";
00684 }
00685 }
00686
00687 if ( ! mxlog.empty()) {
00688 if (progress) {
00689 *progress << " matrices:";
00690 }
00691 for (size_t ii(0); ii < mxlog.size(); ++ii) {
00692 log_s<MatrixParameter, Matrix> const & log(mxlog[ii]);
00693 if ( ! log.log.empty()) {
00694 if (progress) {
00695 *progress << " " << log.parameter->name_ << "...";
00696 }
00697 std::string const fn(prefix + "-" + name + "-" + log.parameter->name_ + ".dump");
00698 std::ofstream os(fn.c_str());
00699 if (os) {
00700 size_t const nn(log.log.size());
00701 os << "# name: " << name << "\n"
00702 << "# parameter: " << log.parameter->name_ << "\n"
00703 << "# type: matrix\n"
00704 << "# size: " << nn << "\n"
00705 << "# line format: tstamp nrows ncols row_0 row_1 ...\n";
00706 for (size_t jj(0); jj < nn; ++jj) {
00707 Matrix const & mx(log.log[jj]);
00708 os << timestamp[jj] << " " << mx.rows() << " " << mx.cols();
00709 for (int kk(0); kk < mx.rows(); ++kk) {
00710 os << " ";
00711 for (int ll(0); ll < mx.cols(); ++ll) {
00712 os << jspace::pretty_string(mx.coeff(kk, ll));
00713 }
00714 }
00715 os << "\n";
00716 }
00717 }
00718 }
00719 }
00720 if (progress) {
00721 *progress << " DONE\n";
00722 }
00723 }
00724
00725 }
00726
00727
00728 void ReflectionRegistry::
00729 add(boost::shared_ptr<ParameterReflection> instance)
00730 {
00731 type_map_[instance->getTypeName()].insert(make_pair(instance->getName(), instance));
00732 }
00733
00734
00735 boost::shared_ptr<ParameterReflection> ReflectionRegistry::
00736 find(std::string const & type_name,
00737 std::string const & instance_name)
00738 {
00739 boost::shared_ptr<ParameterReflection> instance;
00740 type_map_t::iterator it(type_map_.find(type_name));
00741 if (type_map_.end() == it) {
00742 return instance;
00743 }
00744 instance_map_t::iterator ii(it->second.find(instance_name));
00745 if (it->second.end() == ii) {
00746 return instance;
00747 }
00748 instance = ii->second;
00749 return instance;
00750 }
00751
00752
00753 void ReflectionRegistry::
00754 enumerate(enumeration_t & enumeration)
00755 {
00756 enumeration_entry_s entry;
00757 for (type_map_t::iterator it(type_map_.begin()); type_map_.end() != it; ++it) {
00758 entry.type_name = it->first;
00759 for (instance_map_t::iterator ii(it->second.begin()); it->second.end() != ii; ++ii) {
00760 entry.instance_name = ii->first;
00761 parameter_lookup_t const & pt(ii->second->getParameterTable());
00762 for (parameter_lookup_t::const_iterator ip(pt.begin()); pt.end() != ip; ++ip) {
00763 entry.parameter_name = ip->first;
00764 entry.parameter = ip->second;
00765 enumeration.push_back(entry);
00766 }
00767 }
00768 }
00769 }
00770
00771
00772 Parameter * ReflectionRegistry::
00773 lookupParameter(std::string const & type_name,
00774 std::string const & instance_name,
00775 std::string const & parameter_name)
00776 {
00777 boost::shared_ptr<ParameterReflection> ref(find(type_name, instance_name));
00778 if ( ! ref) {
00779 return 0;
00780 }
00781 return ref->lookupParameter(parameter_name);
00782 }
00783
00784
00785 Parameter const * ReflectionRegistry::
00786 lookupParameter(std::string const & type_name,
00787 std::string const & instance_name,
00788 std::string const & parameter_name) const
00789 {
00790 boost::shared_ptr<ParameterReflection const>
00791 ref(const_cast<ReflectionRegistry*>(this)->find(type_name, instance_name));
00792 if ( ! ref) {
00793 return 0;
00794 }
00795 return ref->lookupParameter(parameter_name);
00796 }
00797
00798
00799 Parameter * ReflectionRegistry::
00800 lookupParameter(std::string const & type_name,
00801 std::string const & instance_name,
00802 std::string const & parameter_name,
00803 parameter_type_t parameter_type)
00804 {
00805 boost::shared_ptr<ParameterReflection> ref(find(type_name, instance_name));
00806 if ( ! ref) {
00807 return 0;
00808 }
00809 return ref->lookupParameter(parameter_name, parameter_type);
00810 }
00811
00812
00813 Parameter const * ReflectionRegistry::
00814 lookupParameter(std::string const & type_name,
00815 std::string const & instance_name,
00816 std::string const & parameter_name,
00817 parameter_type_t parameter_type) const
00818 {
00819 boost::shared_ptr<ParameterReflection const>
00820 ref(const_cast<ReflectionRegistry*>(this)->find(type_name, instance_name));
00821 if ( ! ref) {
00822 return 0;
00823 }
00824 return ref->lookupParameter(parameter_name, parameter_type);
00825 }
00826
00827 }