mcpele  1.0.0
The Monte Carlo Python Energy Landscape Explorer
mcpele/progress.h
00001 #ifndef _MCPELE_PROGRESS_H
00002 #define _MCPELE_PROGRESS_H
00003 
00004 #include <ctime>
00005 #include <utility>
00006 #include <iostream>
00007 #include <string>
00008 #include <algorithm>
00009 
00010 namespace mcpele{
00011 
00012 /*
00013  * For a loop of total_iterations steps (assumed to take on average the same time),
00014  * progress keeps track of the time that elapsed, computes the likely total time
00015  * the whole loop will take, prints the local time at which the loop will likely
00016  * terminate, and prints how much time is left until loop terimnation.
00017  * Output is printed 100 times, for each percent of the loop that is done.
00018  *
00019  * The usage is as follows:
00020  *
00021  * const int iterations = 100000;
00022  * progress status(iterations);
00023  * size_t niter = 0;
00024  * while (niter < iterations) {
00025  *      do_something;
00026  *      ++niter;
00027  *      status.next(niter);
00028  * }
00029  *
00030  * Example output:
00031  *
00032  * 28 %. done: 3 s. todo: 10 s. total: 14 s. ends: Thu Jul 24 13:56:51 2014
00033  *
00034  */
00035 
00036 class progress{
00037 public:
00038     typedef size_t index_t;
00039     typedef double float_t;
00040     typedef long long int long_t;
00041 private:
00042     const float_t m_inverse_of_total_iterations;
00043     const index_t m_total_iterations;
00044     index_t m_curr;
00045     index_t m_prev;
00046     const long_t m_start_time;
00047 public:
00048 
00049     progress(const index_t totalin)
00050         : m_inverse_of_total_iterations(1.0/static_cast<float_t>(totalin)),
00051           m_total_iterations(totalin),
00052           m_curr(0),
00053           m_prev(0),
00054           m_start_time(clock())
00055     {}
00056     
00057     index_t get_current_percentage() const { return m_curr; }
00058 
00059     void next(const index_t idx, std::ostream& stm = std::cout)
00060     {
00061         m_curr = std::round((static_cast<float_t>(idx) / static_cast<float_t>(m_total_iterations)) * float_t(100));
00062         if (m_curr != m_prev) {
00063             print_time_percentage(idx - 1, stm);
00064             if (m_curr == 100) {
00065                 stm << "\n";
00066             }
00067         }
00068     }
00069 
00070     void print_time_percentage(const index_t smp, std::ostream& stm)
00071     {
00072         stm << "\r";
00073         // percentage done
00074         update_and_print_percentage_complete(stm);
00075         stm <<  ". ";
00076         // time elapsed
00077         get_and_print_elapsed_time(stm);
00078         stm <<  ". ";
00079         // estimated time to completion
00080         estimate_and_print_time_to_complete(smp, stm);
00081         stm <<  ". ";
00082         // estimated total time
00083         estimate_and_print_total_time(smp, stm);
00084         stm <<  ". ";
00085         // estimated completion time in local time
00086         estimate_and_print_completion_local_time(smp, stm);
00087         stm << "       ";
00088         stm.flush();
00089     }
00090 
00091     void update_and_print_percentage_complete(std::ostream& stm)
00092     {
00093         stm << m_curr << " %";
00094         m_prev = m_curr;
00095     }
00096 
00097     void get_and_print_elapsed_time(std::ostream& stm)
00098     {
00099         stm << "done" <<  ": ";
00100         print_estimated_time(clock() - m_start_time, stm);
00101     }
00102 
00103     void estimate_and_print_time_to_complete(const index_t smp, std::ostream& stm)
00104     {
00105         stm << "todo" <<  ": ";
00106         print_estimated_time(((float_t)(m_total_iterations - smp - 1) / (float_t)(smp + 1)) * (float_t)(clock() - m_start_time), stm);
00107     }
00108 
00109     void estimate_and_print_total_time(const index_t smp, std::ostream& stm)
00110     {
00111         stm << "total" <<  ": ";
00112         print_estimated_time(((float_t)m_total_iterations / (float_t)(smp + 1)) * (float_t)(clock() - m_start_time), stm);
00113     }
00114 
00115     void estimate_and_print_completion_local_time(const index_t smp, std::ostream& stm)
00116     {
00117         stm << "ends" <<  ": ";
00118         time_t timer = time(NULL);
00119         timer += (((float_t)(m_total_iterations - smp - 1) / (float_t)(smp + 1)) * (float_t)(clock() - m_start_time)) / CLOCKS_PER_SEC;
00120         std::string tmp(ctime(&timer));
00121         tmp.erase(std::remove(tmp.begin(), tmp.end(), '\n'), tmp.end());
00122         stm << tmp;
00123     }
00124 
00125     void print_estimated_time(const long_t inp, std::ostream& stm)
00126     {
00127         long_t tm = inp;
00128         long_t days = tm / ((long_t)CLOCKS_PER_SEC * (long_t)60 * (long_t)60 * (long_t)24);
00129         tm %= ((long_t)CLOCKS_PER_SEC * (long_t)60 * (long_t)60 * (long_t)24);
00130         long_t hours = tm / ((long_t)CLOCKS_PER_SEC * (long_t)60 * (long_t)60);
00131         tm %= ((long_t)CLOCKS_PER_SEC * (long_t)60 * (long_t)60);
00132         long_t minutes = tm / ((long_t)CLOCKS_PER_SEC * (long_t)60);
00133         tm %= ((long_t)CLOCKS_PER_SEC * (long_t)60);
00134         long_t seconds = tm / ((long_t)CLOCKS_PER_SEC);
00135         if (days) {
00136             stm << days << " d ";
00137         }
00138         if (hours) {
00139             stm << hours << " h ";
00140         }
00141         if (minutes) {
00142             stm << minutes << " m ";
00143         }
00144         if (seconds) {
00145             stm << seconds << " s";
00146         }
00147     }
00148 
00149 };
00150 
00151 
00152 }//namespace mcpele
00153 
00154 #endif//#ifndef _MCPELE_PROGRESS_H
 All Classes Namespaces Functions Variables Typedefs