CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Log.cc
Go to the documentation of this file.
1 #include "casm/casm_io/Log.hh"
2 
3 #include <boost/algorithm/string/classification.hpp>
4 #include <boost/algorithm/string/split.hpp>
5 
6 #include "casm/external/MersenneTwister/MersenneTwister.h"
7 
8 namespace CASM {
9 
11 
12 void LogVerbatim::print(Log &log) const {
14 }
15 
16 const int Log::none;
17 const int Log::quiet;
18 const int Log::standard;
19 const int Log::verbose;
20 const int Log::debug;
21 
22 Log::Log(std::ostream &_ostream, int _verbosity, bool _show_clock,
23  int _indent_space)
24  : m_verbosity(_verbosity),
25  m_show_clock(_show_clock),
26  m_indent_space(_indent_space),
27  m_indent_level(0),
28  m_indent_spaces(0),
29  m_paragraph_width(100),
30  m_justification(JustificationType::Left),
31  m_ostream(&_ostream) {
32  begin_section();
33 }
34 
35 void Log::restart_clock() { m_start_time = boost::chrono::steady_clock::now(); }
36 
37 void Log::show_clock() { m_show_clock = true; }
38 
39 void Log::hide_clock() { m_show_clock = false; }
40 
41 double Log::time_s() const {
42  using namespace boost::chrono;
43  auto curr_time = steady_clock::now();
44  return duration_cast<duration<double> >(curr_time - m_start_time).count();
45 }
46 
47 void Log::begin_lap() { m_lap_start_time = boost::chrono::steady_clock::now(); }
48 
49 double Log::lap_time() const {
50  using namespace boost::chrono;
51  auto curr_time = steady_clock::now();
52  return duration_cast<duration<double> >(curr_time - m_lap_start_time).count();
53 }
54 
55 int Log::verbosity() const { return m_verbosity; }
56 
57 void Log::set_verbosity(int _verbosity) { m_verbosity = _verbosity; }
58 
59 void Log::reset(std::ostream &_ostream) { m_ostream = &_ostream; }
60 
62 std::vector<int> rand_unique(int n, int c, MTRand &mtrand) {
63  std::vector<int> index;
64  for (int i = 0; i < n; ++i) {
65  index.push_back(i);
66  }
67  using std::swap;
68  int choice;
69  int s = index.size();
70  std::vector<int> res;
71  for (int i = 0; i < c; ++i) {
72  choice = mtrand.randInt(s - 1);
73  res.push_back(index[choice]);
74  swap(index[s - 1], index[choice]);
75  s--;
76  }
77 
78  return res;
79 }
80 
81 void Log::_print_justified_line(std::vector<std::string> &line,
82  int curr_width) {
83  // treat too-long case as left justified
85  curr_width + line.size() - 1 >= width()) {
86  _print_left_justified_line(line, curr_width);
87  } else if (justification() == JustificationType::Right) {
88  _print_right_justified_line(line, curr_width);
89  } else if (justification() == JustificationType::Center) {
90  _print_center_justified_line(line, curr_width);
91  } else if (justification() == JustificationType::Full) {
92  _print_full_justified_line(line, curr_width);
93  } else {
94  throw std::runtime_error("Log print justification error");
95  }
96 }
97 
98 void Log::_print_left_justified_line(std::vector<std::string> &line,
99  int curr_width) {
100  indent();
101  for (int i = 0; i < line.size(); ++i) {
102  if (i != 0) {
103  *this << " ";
104  }
105  *this << line[i];
106  }
107  *this << std::endl;
108 }
109 
110 void Log::_print_right_justified_line(std::vector<std::string> &line,
111  int curr_width) {
112  indent();
113  std::stringstream ss;
114  for (int i = 0; i < line.size(); ++i) {
115  if (i != 0) {
116  ss << " ";
117  }
118  ss << line[i];
119  }
120  if (indent_str().size() + ss.str().size() >= width()) {
121  *this << std::string(width() - indent_str().size() - ss.str().size(), ' ')
122  << ss.str() << std::endl;
123  }
124 }
125 
126 void Log::_print_center_justified_line(std::vector<std::string> &line,
127  int curr_width) {
128  indent();
129  std::stringstream ss;
130  for (int i = 0; i < line.size(); ++i) {
131  if (i != 0) {
132  ss << " ";
133  }
134  ss << line[i];
135  }
136  std::string str = ss.str();
137  std::string before = std::string((width() - str.size()) / 2, ' ');
138  std::string after = std::string(width() - before.size() - str.size(), ' ');
139  *this << before << str << after << std::endl;
140 }
141 
142 void Log::_print_full_justified_line(std::vector<std::string> &line,
143  int curr_width) {
144  indent();
145  // add ' ' evenly as much as possible
146  while (width() - curr_width >= line.size() - 1) {
147  for (int i = 0; i < line.size() - 1; ++i) {
148  line[i] += ' ';
149  curr_width++;
150  }
151  }
152  // add extra uneven ' ' using random number generator to choose locations
153  // but seed based on curr_width to give consistent results
154  MTRand mtrand(curr_width);
155  std::vector<int> index =
156  rand_unique(line.size() - 1, width() - curr_width, mtrand);
157  for (int i = 0; i < index.size(); ++i) {
158  line[i] += ' ';
159  }
160  // print words (which now include spaces)
161  for (auto &word : line) {
162  *this << word;
163  }
164  *this << std::endl;
165 }
166 
168 Log &Log::paragraph(std::string text) {
169  std::vector<std::string> words;
170  boost::split(words, text, boost::is_any_of(" "), boost::token_compress_on);
171 
172  // 'curr_width' includes indent and words, but not spaces between them
173  int curr_width = indent_str().size();
174  std::vector<std::string> line;
175  for (int i = 0; i < words.size(); ++i) {
176  if (line.size() == 0 ||
177  curr_width + line.size() + words[i].size() <= width()) {
178  line.push_back(words[i]);
179  curr_width += words[i].size();
180  } else {
181  // print not-last line
182  _print_justified_line(line, curr_width);
183 
184  // begin next line
185  line.clear();
186  line.push_back(words[i]);
187  curr_width = indent_str().size() + words[i].size();
188  }
189  }
190  // print last line
192  _print_left_justified_line(line, curr_width);
193  } else {
194  _print_justified_line(line, curr_width);
195  }
196 
197  return *this;
198 }
199 
201 Log &Log::verbatim(std::string text, bool indent_first_line) {
202  std::istringstream input;
203  input.str(text);
204  std::string first_line;
205  if (std::getline(input, first_line)) {
206  if (indent_first_line) {
207  *this << indent_str();
208  }
209  *this << first_line << std::endl;
210  for (std::string line; std::getline(input, line);) {
211  indent() << line << std::endl;
212  }
213  }
214  return *this;
215 }
216 
217 Log::operator std::ostream &() { return ostream(); }
218 
219 std::string Log::invalid_verbosity_msg(std::string s) {
220  return std::string("Error: Received '") + s +
221  "', expected one of 'none', 'quiet', 'standard', 'verbose', 'debug', "
222  "or an int in range [0, 100]";
223 }
224 
231 std::pair<bool, int> Log::verbosity_level(std::string s) {
232  auto is_int = [](std::string s) {
233  int val;
234  if (s.empty() || !isdigit(s[0])) {
235  return std::make_pair(false, val);
236  }
237  char *p;
238  val = strtol(s.c_str(), &p, 10);
239  return std::make_pair(*p == 0 && val >= 0 && val <= 100, val);
240  };
241 
242  auto res = is_int(s);
243  if (res.first) {
244  return res;
245  } else if (s == "none") {
246  return std::make_pair(true, 0);
247  } else if (s == "quiet") {
248  return std::make_pair(true, 5);
249  } else if (s == "standard") {
250  return std::make_pair(true, 10);
251  } else if (s == "verbose") {
252  return std::make_pair(true, 20);
253  } else if (s == "debug") {
254  return std::make_pair(true, 100);
255  } else {
256  return std::make_pair(false, 0);
257  }
258 };
259 
260 bool Log::print() const { return _print(); }
261 
263  if (m_show_clock) {
264  ostream() << "Time: " << time_s() << " (s)";
265  }
266 }
267 
268 bool Log::_print() const { return m_print; }
269 
270 Log &operator<<(Log &log, std::ostream &(*fptr)(std::ostream &)) {
271  if (log._print()) {
272  fptr(static_cast<std::ostream &>(log));
273  }
274  return log;
275 }
276 
277 FixedLog::FixedLog(std::ostream &_ostream) : Log(_ostream) {}
278 
279 } // namespace CASM
std::set< std::string > & s
Index count
FixedLog(std::ostream &_ostream)
Definition: Log.cc:277
Definition: Log.hh:48
boost::chrono::steady_clock::time_point m_lap_start_time
Definition: Log.hh:356
int width() const
Definition: Log.hh:234
static const int none
Definition: Log.hh:50
bool m_print
Whether to print.
Definition: Log.hh:341
static const int quiet
Definition: Log.hh:51
static std::string invalid_verbosity_msg(std::string s)
Definition: Log.cc:219
void _print_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:81
std::string indent_str() const
Definition: Log.hh:273
bool m_show_clock
Definition: Log.hh:343
void _add_time()
Definition: Log.cc:262
Log(std::ostream &_ostream=std::cout, int _verbosity=standard, bool _show_clock=false, int _indent_space=2)
Construct a Log.
Definition: Log.cc:22
bool print() const
Definition: Log.cc:260
void set_verbosity(int _verbosity)
Definition: Log.cc:57
void _print_center_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:126
static const int debug
Definition: Log.hh:54
bool _print() const
Definition: Log.cc:268
boost::chrono::steady_clock::time_point m_start_time
Definition: Log.hh:354
JustificationType justification()
Definition: Log.hh:240
void begin_section()
Begin a section, without header.
Definition: Log.hh:158
std::ostream * m_ostream
Definition: Log.hh:358
void begin_lap()
Definition: Log.cc:47
int verbosity() const
Definition: Log.cc:55
friend Log & operator<<(Log &log, const T &msg_details)
Definition: Log.hh:394
Log & indent()
Definition: Log.hh:289
int m_verbosity
If m_verbosity >= required verbosity, then print.
Definition: Log.hh:338
Log & verbatim(std::string text, bool indent_first_line=true)
Print verbatim, but with indentation (optional on first line)
Definition: Log.cc:201
void hide_clock()
Definition: Log.cc:39
static const int verbose
Definition: Log.hh:53
void reset(std::ostream &_ostream=std::cout)
Definition: Log.cc:59
Log & paragraph(std::string text)
Print indented paragraph with wrapping at Log::width()
Definition: Log.cc:168
std::ostream & ostream()
Definition: Log.hh:262
void _print_full_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:142
void show_clock()
Definition: Log.cc:37
static const int standard
Definition: Log.hh:52
double lap_time() const
Definition: Log.cc:49
double time_s() const
Definition: Log.cc:41
static std::pair< bool, int > verbosity_level(std::string s)
Read verbosity level from a string.
Definition: Log.cc:231
void _print_right_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:110
void _print_left_justified_line(std::vector< std::string > &line, int curr_width)
Definition: Log.cc:98
void restart_clock()
Definition: Log.cc:35
Main CASM namespace.
Definition: APICommand.hh:8
Log & log()
Definition: Log.hh:424
void swap(ConfigDoF &A, ConfigDoF &B)
Definition: ConfigDoF.cc:260
JustificationType
Definition: Log.hh:17
std::vector< int > rand_unique(int n, int c, MTRand &mtrand)
Choose c random unique numbers in [0,n)
Definition: Log.cc:62
virtual void print(Log &log) const override
Definition: Log.cc:10
std::string text
Definition: Log.hh:24
bool indent_first_line
Definition: Log.hh:43
virtual void print(Log &log) const override
Definition: Log.cc:12