CASM  1.1.0
A Clusters Approach to Statistical Mechanics
DataFormatter_impl.hh
Go to the documentation of this file.
1 #ifndef CASM_DataFormatter_impl
2 #define CASM_DataFormatter_impl
3 #include <boost/lexical_cast.hpp>
4 #include <boost/tokenizer.hpp>
5 
11 
12 namespace CASM {
13 
14 template <typename DataObject>
16  const std::string &_expr) {
17  auto bounds = index_expression_to_bounds(_expr);
18  std::vector<difference_type> ind_begin(bounds.first.rbegin(),
19  bounds.first.rend());
20  std::vector<difference_type> ind_end(bounds.second.rbegin(),
21  bounds.second.rend());
22 
24  ind_begin, ind_end, std::vector<difference_type>(ind_begin.size(), 1));
25 
26  for (; ind_count.valid(); ++ind_count) {
27  m_index_rules.push_back(
28  std::vector<difference_type>(ind_count().rbegin(), ind_count().rend()));
29  }
30 }
31 
32 //******************************************************************************
33 
34 template <typename DataObject>
36  initialize(_obj);
37  for (Index i = 0; i < m_data_formatters.size(); i++)
38  if (!m_data_formatters[i]->validate(_obj)) return false;
39 
40  return true;
41 }
42 
43 //******************************************************************************
44 
45 template <typename DataObject>
47  DataStream &_stream) const {
48  initialize(_obj);
49 
50  Index num_pass(1), tnum;
51  for (Index i = 0; i < m_data_formatters.size(); i++) {
52  tnum = m_data_formatters[i]->num_passes(_obj);
53  if (tnum == 1) continue;
54  if (num_pass == 1 || tnum == num_pass)
55  num_pass = tnum;
56  else {
57  std::cerr << "CRITICAL ERROR: Requesting to print formatted data "
58  "elements that require different number of lines.\n"
59  << " Exiting...\n";
60  exit(1);
61  }
62  }
63  for (Index np = 0; np < num_pass; np++) {
64  for (Index i = 0; i < m_data_formatters.size(); i++) {
65  m_data_formatters[i]->inject(_obj, _stream, np);
66  }
67  _stream.newline();
68  }
69 
70  return;
71 }
72 
73 //******************************************************************************
74 
76 template <typename DataObject>
77 template <typename ValueType>
79  const DataObject &_obj) const {
80  ValueDataStream<ValueType> value_stream;
81  value_stream << FormattedObject(this, _obj);
82  return value_stream.value();
83 }
84 
85 //******************************************************************************
86 
88 template <typename DataObject>
89 template <typename ValueType>
91  const DataObject &_obj) const {
92  VectorDataStream<ValueType> value_stream;
93  value_stream << FormattedObject(this, _obj);
94  return value_stream.value();
95 }
96 
97 //******************************************************************************
98 
100 template <typename DataObject>
102  const DataObject &_obj) const {
103  MatrixXdDataStream value_stream;
104  value_stream << FormattedObject(this, _obj);
105  return value_stream.matrix();
106 }
107 
108 //******************************************************************************
109 
111 template <typename DataObject>
112 template <typename ValueType, typename IteratorType>
114  IteratorType begin, IteratorType end) const {
115  VectorDataStream<ValueType> value_stream;
116  value_stream << FormattedObject(this, begin, end);
117  return value_stream.value();
118 }
119 
120 //******************************************************************************
121 
123 template <typename DataObject>
124 template <typename IteratorType>
126  IteratorType begin, IteratorType end) const {
127  MatrixXdDataStream value_stream;
128  value_stream << FormattedIteratorPair<IteratorType>(this, begin, end);
129  return value_stream.matrix();
130 }
131 
132 //******************************************************************************
133 
134 template <typename DataObject>
136  std::ostream &_stream) const {
137  initialize(_obj);
138  _stream << std::setprecision(m_prec) << std::fixed;
139  Index num_pass(1), tnum;
140  for (Index i = 0; i < m_data_formatters.size(); i++) {
141  tnum = m_data_formatters[i]->num_passes(_obj);
142  if (tnum == 1) continue;
143  if (num_pass == 1 || tnum == num_pass)
144  num_pass = tnum;
145  else {
146  std::cerr << "CRITICAL ERROR: Requesting to print formatted data "
147  "elements that require different number of lines.\n"
148  << " Exiting...\n";
149  exit(1);
150  }
151  }
152  std::stringstream t_ss;
153  int depad_request;
154  for (Index np = 0; np < num_pass; np++) {
155  depad_request = 0;
156  for (Index i = 0; i < m_data_formatters.size(); i++) {
157  t_ss.clear();
158  t_ss.str(std::string());
159  m_data_formatters[i]->print(_obj, t_ss, np);
160 
161  // two space fixed separator
162  _stream << " ";
163  // variable separator
164  if (depad_request + 2 < m_col_sep[i])
165  _stream << std::string(m_col_sep[i] - depad_request - 2, ' ');
166  _stream << t_ss.str();
167  depad_request = m_col_sep[i] + int(t_ss.str().size()) - m_col_width[i];
168  }
169  _stream << std::endl;
170  }
171 
172  return;
173 }
174 
175 //******************************************************************************
176 
177 template <typename DataObject>
179  jsonParser &json) const {
180  initialize(_obj);
181  for (Index i = 0; i < m_data_formatters.size(); i++) {
182  m_data_formatters[i]->to_json(
183  _obj, json[m_data_formatters[i]->short_header(_obj)]);
184  }
185 
186  return json;
187 }
188 
189 //******************************************************************************
190 
191 template <typename DataObject>
193  jsonParser &json) const {
194  initialize(_obj);
195 
197  jsonParser::iterator end = json.end();
198 
199  for (Index i = 0; i < m_data_formatters.size(); i++) {
200  jsonParser tmp;
201  m_data_formatters[i]->to_json(_obj, tmp);
202  it = json.find(m_data_formatters[i]->short_header(_obj));
203  if (it == end) {
204  json[m_data_formatters[i]->short_header(_obj)].put_array().push_back(tmp);
205  } else {
206  it->push_back(tmp);
207  }
208  }
209 
210  return json;
211 }
212 
213 //******************************************************************************
214 
215 template <typename DataObject>
217  std::ostream &_stream) const {
218  _stream << m_comment;
219 
220  initialize(_template_obj);
221 
222  int header_size, twidth;
223  for (Index i = 0; i < m_data_formatters.size(); i++) {
224  std::stringstream t_ss;
225  m_data_formatters[i]->print(_template_obj, t_ss);
226  header_size = (m_data_formatters[i]->long_header(_template_obj)).size();
227  twidth = m_sep;
228  if (i == 0)
229  twidth += max(t_ss.str().size(), header_size + m_comment.size());
230  else
231  twidth += max(int(t_ss.str().size()), header_size);
232  m_col_width[i] = twidth;
233  m_col_sep[i] = twidth - int(t_ss.str().size());
234  if (i == 0) twidth -= m_comment.size();
235  _stream << std::string(twidth - header_size, ' ')
236  << m_data_formatters[i]->long_header(_template_obj);
237  }
238  _stream << std::endl;
239  return;
240 }
241 
242 //******************************************************************************
243 
245 template <typename DataObject>
246 std::vector<std::string> DataFormatter<DataObject>::col_header(
247  const DataObject &_template_obj) const {
248  std::vector<std::string> col;
249  for (Index i = 0; i < m_data_formatters.size(); i++) {
250  auto v2 = m_data_formatters[i]->col_header(_template_obj);
251  col.insert(col.end(), v2.begin(), v2.end());
252  }
253  return col;
254 }
255 
256 //******************************************************************************
257 
258 template <typename DataObject>
260  const DataObject &_template_obj) const {
261  if (!m_initialized) {
262  m_initialized = true;
263  for (Index i = 0; i < m_data_formatters.size(); i++)
264  m_initialized =
265  m_data_formatters[i]->init(_template_obj) && m_initialized;
266  }
267  return m_initialized;
268 }
269 
270 //******************************************************************************
271 
274 template <typename DataObject, typename DatumFormatterType>
277  const key_type &_name) const {
278  // typedef DataFormatterDictionary<DataObject, DatumFormatterType> dict_type;
279 
280  auto res = this->find(_name);
281  if (res != this->end()) {
282  res->set_home(*this);
283  return res;
284  } else {
285  // If no match, try to use demerescau-levenshtein distance to make a helpful
286  // suggestion
287  int min_dist(-1);
288  auto it = this->begin();
289  for (; it != this->end(); ++it) {
290  int dist = dl_string_dist(_name, it->name());
291  if (min_dist < 0 || dist < min_dist) {
292  min_dist = dist;
293  // std::cout << "New best: \"" << it->first << "\" aka \"" <<
294  // it->second->name() << "\"\n";
295  res = it;
296  }
297  }
298 
299  throw std::runtime_error(
300  "CRITICAL ERROR: Invalid format flag \"" + _name + "\" specified.\n" +
301  " Did you mean \"" + res->name() + "\"?\n");
302  }
303 }
304 
308 template <typename DataObject, typename DatumFormatterType>
310  std::ostream &_stream, DatumFormatterClass ftype, int width,
311  int separation) const {
312  const_iterator it_begin(this->cbegin()), it_end(this->cend());
313  std::string::size_type len(0);
314  for (auto it = it_begin; it != it_end; ++it) {
315  if (ftype == it->type()) len = max(len, it->name().size());
316  }
317  for (auto it = it_begin; it != it_end; ++it) {
318  if (ftype != it->type()) continue;
319  _stream << std::string(5, ' ') << it->name()
320  << std::string(len - it->name().size() + separation, ' ');
321  std::string::size_type wcount(0);
322  std::string::const_iterator str_end(it->description().cend());
323  for (std::string::const_iterator str_it = it->description().cbegin();
324  str_it != str_end; ++str_it) {
325  if (wcount >= width && isspace(*str_it)) {
326  _stream << std::endl << std::string(5 + len + separation, ' ');
327  wcount = 0;
328  } else {
329  _stream << *str_it;
330  wcount++;
331  }
332  }
333  _stream << std::endl << std::endl;
334  }
335 }
336 
344 template <typename DataObject, typename DatumFormatterType>
347  const std::vector<std::string> &input) const {
348  DataFormatter<DataObject> formatter;
349  std::vector<std::string> format_tags, format_args;
350  for (Index i = 0; i < input.size(); i++) {
351  split_formatter_expression(input[i], format_tags, format_args);
352  }
353  for (Index i = 0; i < format_tags.size(); i++) {
354  formatter.push_back(*lookup(format_tags[i]), format_args[i]);
355  }
356  return formatter;
357 }
358 
367 template <typename DataObject, typename DatumFormatterType>
370  const std::string &input) const {
371  DataFormatter<DataObject> formatter;
372  std::vector<std::string> format_tags, format_args;
373  split_formatter_expression(input, format_tags, format_args);
374 
375  for (Index i = 0; i < format_tags.size(); i++) {
376  formatter.push_back(*lookup(format_tags[i]), format_args[i]);
377  }
378  return formatter;
379 }
380 
382 template <typename DataObject, typename DatumFormatterType>
385  std::initializer_list<std::string> input) const {
386  return parse(std::vector<std::string>(input));
387 }
388 
389 } // namespace CASM
390 
391 #endif
bool valid() const
Definition: BaseCounter.hh:160
void _parse_index_expression(const std::string &_expr)
A Counter allows looping over many incrementing variables in one loop.
Definition: Counter.hh:109
Implements generic formatting member functions for individual data objects.
Parsing dictionary for constructing a DataFormatter<DataObject> object.
UniqueMapType::key_type key_type
Extract data from objects of 'DataObject' class.
void push_back(const BaseDatumFormatter< DataObject > &new_formatter, const std::string &args)
std::vector< std::string > col_header(const DataObject &_template_obj) const
Returns all column header strings as std::vector<std::string>
_DataObject DataObject
virtual DataStream & newline()
Definition: DataStream.hh:53
const Eigen::MatrixXd & matrix()
const T & value() const
Definition: DataStream.hh:256
iterator end()
Returns iterator to end of JSON object or JSON array.
Definition: jsonParser.cc:520
iterator find(const std::string &name)
Return iterator to JSON object value with 'name'.
Definition: jsonParser.cc:543
jsonParser & put_array()
Puts new empty JSON array.
Definition: jsonParser.hh:362
An iterator over a UniqueMap.
Definition: unique_map.hh:19
jsonParser & push_back(const T &value, Args &&... args)
Definition: jsonParser.hh:684
Validator validate(OccupationDoFSpecs const &occ_specs, const Structure &prim)
static int initialize()
Main CASM namespace.
Definition: APICommand.hh:8
std::pair< std::vector< long >, std::vector< long > > index_expression_to_bounds(const std::string &_expr)
Eigen::MatrixXd MatrixXd
jsonParser & to_json(const ClexDescription &desc, jsonParser &json)
DatumFormatterClass
void split_formatter_expression(const std::string &input_expr, std::vector< std::string > &tag_names, std::vector< std::string > &sub_exprs)
int dl_string_dist(const std::string &a, const std::string &b)
Computes the Damerescau-Levenshtein distance – the number of edits (deletions, insertions,...
Definition: CASM_math.cc:45
Iterator find(Iterator begin, Iterator end, const T &value, BinaryCompare q)
Equivalent to std::find(begin, end, value), but with custom comparison.
Definition: algorithm.hh:16
INDEX_TYPE Index
For long integer indexing:
Definition: definitions.hh:39
void parse(InputParser< ConfigEnumOptions > &parser, std::string method_name, PrimClex const &primclex, DataFormatterDictionary< Configuration > const &dict)
T max(const T &A, const T &B)
Definition: CASM_math.hh:95