contrib/mul/mbl/mbl_progress_hierarchy.cxx
Go to the documentation of this file.
00001 
00002 //:
00003 // \file
00004 // \brief Assumes a hierarchy in the identifiers and reports a single float score.
00005 // \author Ian Scott
00006 // \date 10 Jan 2008
00007 
00008 #include "mbl_progress_hierarchy.h"
00009 #include <vcl_cmath.h>
00010 #include <vcl_algorithm.h>
00011 #include <mbl/mbl_log.h>
00012 
00013 
00014 inline mbl_logger& logger()
00015 {
00016   static mbl_logger my_logger("mul.mbl.progress.hierarchy");
00017   return my_logger;
00018 }
00019 
00020 
00021 //: Called when set_estimate_iterations() is called for a given identifier.
00022 //  Derived classes may take some action here.
00023 //  \param identifier The operation being monitored.
00024 void mbl_progress_hierarchy::on_set_estimated_iterations(const vcl_string& identifier,
00025   const int total_iterations)
00026 {
00027   if (vcl_find(identifier_stack_.begin(), identifier_stack_.end(), identifier) !=
00028     identifier_stack_.end())
00029   {
00030     MBL_LOG(WARN, logger(), "Trying to reset estimated_iterations "
00031       "for existing identifier: \"" << identifier << '"');
00032       return;
00033   }
00034   if (just_ended_)
00035     MBL_LOG(WARN, logger(), "No change in parent progress before starting new "
00036       "identifier: \"" << identifier << '"');
00037 
00038   just_ended_ = false;
00039   identifier_stack_.push_back(identifier);
00040 }
00041 
00042 //: Called when set_progress() is called for a given identifier.
00043 //  Derived classes may take some action here.
00044 //  \param identifier The operation being monitored.
00045 //  \param progress The new progress status.
00046 void mbl_progress_hierarchy::on_set_progress(const vcl_string& identifier,
00047                                const int progress)
00048 {
00049   just_ended_=false;
00050 
00051   if (identifier != identifier_stack_.back())
00052     MBL_LOG(WARN, logger(), "set progress for identifier \"" << identifier << 
00053       "\" rather than most recently created identifier \"" << identifier_stack_.back() << '"');
00054 
00055   double a=0.0, b=1.0; // The lower and upper bound on the current value
00056   for (vcl_vector<vcl_string>::const_iterator it=identifier_stack_.begin(),
00057     end=identifier_stack_.end(); it!=end; ++it)
00058   {
00059     int n_its = this->estimated_iterations(*it)+1;
00060     int its = this->progress(*it);
00061     double width = (b-a) / n_its;
00062     if (its < n_its)
00063     {
00064       a=a+width*its;
00065       b=a+width;
00066     }
00067     else
00068       a = b - width*vcl_exp(1.0 - its/(n_its-0.5));
00069   }
00070   on_changed_progress(a);
00071 }
00072   
00073 //: Called when end_progress() is called for a given identifier.
00074 //  Derived classes may take some action here.
00075 //  \param identifier The operation being monitored.
00076 void mbl_progress_hierarchy::on_end_progress(const vcl_string& identifier)
00077 {
00078   just_ended_ = true;
00079 
00080 
00081   double a=0.0, b=1.0; // The lower and upper bound on the current value
00082   for (vcl_vector<vcl_string>::const_iterator it=identifier_stack_.begin(),
00083     end=identifier_stack_.end(); it!=end; ++it)
00084   {
00085     int n_its = estimated_iterations(*it)+1;
00086     int its = progress(*it);
00087     double width = (b-a) / n_its;
00088     if (its < n_its)
00089     {
00090       a=a+width*its;
00091       b=a+width;
00092     }
00093     else
00094       a = b - width*vcl_exp(1.0 - its/(n_its-0.5));
00095 
00096   }
00097   on_changed_progress(0.1*a+0.9*b);
00098 
00099   if (identifier_stack_.back() != identifier)
00100     MBL_LOG(WARN, logger(), "Trying to end_progress on identifier: \"" << identifier <<
00101     "\" when most recently created identifier is \"" << identifier_stack_.back() << '"');
00102 
00103   identifier_stack_.pop_back();
00104 
00105 }