CASM  1.1.0
A Clusters Approach to Statistical Mechanics
Update_impl.hh
Go to the documentation of this file.
1 #ifndef CASM_DB_Update_impl
2 #define CASM_DB_Update_impl
3 
4 #include <boost/filesystem/fstream.hpp>
5 
10 
11 namespace CASM {
12 namespace DB {
13 
14 // --- UpdateT ---
15 
17 template <typename _ConfigType>
19  const StructureMap<ConfigType> &mapper,
20  std::string report_dir)
22  m_structure_mapper(mapper),
23  m_report_dir(report_dir) {}
24 
26 template <typename _ConfigType>
28  bool force) {
29  Log &log = CASM::log();
30  auto const &project_settings = this->primclex().settings();
31  auto calctype = project_settings.default_clex().calctype;
32  auto required_properties =
33  project_settings.required_properties(traits<ConfigType>::name, calctype);
34 
35  // vector of Mapping results
36  std::vector<ConfigIO::Result> results;
37  for (const auto &val : selection.data()) {
38  // if not selected, skip
39  if (!val.second) {
40  continue;
41  }
42  std::string name = val.first;
43  std::string pos = CASM::calc_properties_path(this->primclex(), name);
44 
45  // reasons to update data or not:
46  //
47  // for each selected 'from' config:
48  //
49  // if no existing files:
50  // continue
51  // if existing data or files:
52  // if !force && no change:
53  // continue
54  // erase existing props && read && map
55  // if could not map:
56  // 'to' = ""; continue;
57  // else:
58  // update props
59  //
60 
61  if ((!force && this->no_change(name))) {
62  continue;
63  }
64 
65  // erase existing data (not files), unlinking relaxation mappings &&
66  // resetting 'best' data
67  db_props().erase_via_origin(pos);
68 
69  if (!fs::exists(pos)) continue;
70 
71  log << "Updating data records for " << name << std::endl;
72  std::vector<ConfigIO::Result> tvec;
73  auto config_it = db_config<ConfigType>().find(name);
74  if (config_it == db_config<ConfigType>().end())
75  m_structure_mapper.map(resolve_struc_path(pos, primclex()),
76  required_properties, nullptr,
77  std::back_inserter(tvec));
78  else
79  m_structure_mapper.map(resolve_struc_path(pos, primclex()),
80  required_properties,
81  notstd::make_unique<ConfigType>(*config_it),
82  std::back_inserter(tvec));
83  for (auto &res : tvec) {
84  results.push_back(res);
85  // if mapped && has data, insert
86  if (!res.properties.to.empty() && res.has_data) {
87  // insert data:
88  db_props().insert(res.properties);
89  }
90  }
91  }
92  _update_report(results, selection);
93 
94  db_supercell().commit();
95  db_config<ConfigType>().commit();
96  db_props().commit();
97 }
98 
99 template <typename _ConfigType>
101  std::vector<ConfigIO::Result> &results,
102  const DB::Selection<ConfigType> &selection) const {
103  // report:
104  // update_map_fail: all 'from' config that were not successfully mapped
105  // update_map_success: all 'from' config that were successfully mapped
106  // update_map_conflict: all 'from' config that map to same 'to' config,
107  // sorted by 'to' config update_unstable: all 'from' config where 'from' !=
108  // 'to', sorted by 'to' config update_unselected: update_unstable, where
109  // 'to' is not selected, sorted by 'to' config
110 
111  // list of structures that could (not) be mapped
112  std::vector<ConfigIO::Result> fail;
113  std::vector<ConfigIO::Result> success;
114  std::vector<ConfigIO::Result> conflict;
115  std::vector<ConfigIO::Result> unstable;
116  std::vector<ConfigIO::Result> unselected;
117  std::vector<ConfigIO::Result> new_config;
118 
119  std::string prefix = "update_";
121 
122  std::map<std::string, int> all_to;
123 
124  for (auto const &res : results) {
125  if (res.properties.to.empty()) {
126  fail.push_back(res);
127  } else {
128  auto it = all_to.find(res.properties.to);
129  if (it == all_to.end()) {
130  it = all_to.insert(std::make_pair(res.properties.to, 0)).first;
131  }
132  ++(it->second);
133  if (res.properties.origin !=
134  CASM::calc_properties_path(this->primclex(), res.properties.to)) {
135  unstable.push_back(res);
136  if (res.is_new_config) {
137  new_config.push_back(res);
138  }
139  if (!selection.is_selected(res.properties.to)) {
140  unselected.push_back(res);
141  }
142  }
143  success.push_back(res);
144  }
145  }
146 
147  for (auto const &res : results) {
148  if (all_to[res.properties.to] > 1) {
149  conflict.push_back(res);
150  }
151  }
152 
153  auto formatter = _update_formatter();
154 
155  if (fail.size()) {
156  fs::path p = fs::path(m_report_dir) / (prefix + "_fail");
157  fs::ofstream sout(p);
158 
159  log() << "WARNING: Could not map " << fail.size() << " results."
160  << std::endl;
161  log() << " See detailed report: " << p << std::endl << std::endl;
162 
163  sout << formatter(fail.begin(), fail.end());
164  }
165 
166  if (success.size()) {
167  fs::path p = fs::path(m_report_dir) / (prefix + "_success");
168  fs::ofstream sout(p);
169 
170  log() << "Successfully mapped " << success.size() << " results."
171  << std::endl;
172  log() << " See detailed report: " << p << std::endl << std::endl;
173 
174  sout << formatter(success.begin(), success.end());
175  }
176 
177  if (conflict.size()) {
178  fs::path p = fs::path(m_report_dir) / (prefix + "_conflict");
179  fs::ofstream sout(p);
180 
181  log() << "WARNING: Found " << conflict.size()
182  << " conflicting relaxation results." << std::endl;
183  log() << " See detailed report: " << p << std::endl << std::endl;
184 
185  sout << formatter(conflict.begin(), conflict.end());
186  }
187 
188  if (unstable.size()) {
189  fs::path p = fs::path(m_report_dir) / (prefix + "_unstable");
190  fs::ofstream sout(p);
191 
192  log() << "WARNING: Found " << unstable.size() << " unstable relaxations."
193  << std::endl;
194  log() << " See detailed report: " << p << std::endl << std::endl;
195 
196  sout << formatter(unstable.begin(), unstable.end());
197  }
198 
199  if (unselected.size()) {
200  fs::path p = fs::path(m_report_dir) / (prefix + "_unselected");
201  fs::ofstream sout(p);
202 
203  log() << "WARNING: Found " << unselected.size()
204  << " unstable relaxations to unselected configurations." << std::endl;
205  log() << " See detailed report: " << p << std::endl << std::endl;
206 
207  sout << formatter(unselected.begin(), unselected.end());
208  }
209 
210  if (new_config.size()) {
211  fs::path p = fs::path(m_report_dir) / (prefix + "_new");
212  fs::ofstream sout(p);
213 
214  log() << "WARNING: Found " << new_config.size()
215  << " unstable relaxations to new configurations." << std::endl
216  << " These configurations have been added to the project."
217  << std::endl;
218  log() << " See detailed report: " << p << std::endl << std::endl;
219 
220  sout << formatter(unselected.begin(), unselected.end());
221  }
222 }
223 
224 } // namespace DB
225 } // namespace CASM
226 
227 #endif
map_type & data()
Definition: Selection.cc:250
bool is_selected(const std::string &name_or_alias) const
True if obj is in Selection and is selected; false otherwise.
Definition: Selection.cc:281
UpdateT(const PrimClex &primclex, const StructureMap< ConfigType > &mapper, std::string report_dir)
Constructor.
Definition: Update_impl.hh:18
void _update_report(std::vector< ConfigIO::Result > &results, const DB::Selection< ConfigType > &selection) const
Definition: Update_impl.hh:100
_ConfigType ConfigType
Definition: Update.hh:32
void update(const DB::Selection< ConfigType > &selection, bool force)
Re-parse calculations 'from' all selected configurations.
Definition: Update_impl.hh:27
Definition: Log.hh:48
PrimClex is the top-level data structure for a CASM project.
Definition: PrimClex.hh:55
Main CASM namespace.
Definition: APICommand.hh:8
std::string calc_properties_path(const ConfigType &config, std::string calctype="")
Definition: Calculable.cc:197
Log & log()
Definition: Log.hh:424
GenericDatumFormatter< std::string, DataObject > name()
PrimClex * primclex
Definition: settings.cc:135
pair_type calctype
Definition: settings.cc:143