1 #ifndef CASM_DB_Import_impl
2 #define CASM_DB_Import_impl
4 #include <boost/filesystem/fstream.hpp>
21 template <
typename OutputIterator>
24 OutputIterator result) {
25 const po::variables_map &vm = import_opt.
vm();
27 bool missing_files(
false);
30 auto lambda = [&](
const fs::path &p) {
34 err_log() <<
"*** ERROR: Missing file(s):\n";
37 err_log() <<
" " << fs::absolute(p) <<
"\n";
39 *result++ = fs::absolute(p);
44 std::for_each(import_opt.
pos_vec().begin(), import_opt.
pos_vec().end(),
48 if (vm.count(
"batch")) {
50 err_log() <<
"ERROR: Batch import file does not exist at "
55 fs::ifstream batchfile(import_opt.
batch_path());
57 while (batchfile >> tpath) {
62 if (tpath.string().size() != 0 && fs::exists(tpath)) {
68 err_log() <<
"ERROR: No files specified for import.\n";
69 if (vm.count(
"batch")) {
70 err_log() <<
" Check batch file for errors.\n";
79 return std::make_pair(result, 0);
85 template <
typename _ConfigType>
89 std::string report_dir)
91 m_structure_mapper(mapper),
93 m_report_dir(report_dir) {}
95 template <
typename _ConfigType>
96 template <
typename PathIterator>
100 std::vector<ConfigIO::Result> results;
104 std::map<std::string, bool> preexisting;
106 auto const &project_settings = this->
primclex().settings();
107 auto calctype = project_settings.default_clex().calctype;
108 auto required_properties =
113 for (; it != end; ++it) {
114 log <<
"Importing " << resolve_struc_path(it->string(),
primclex())
118 std::vector<ConfigIO::Result> tvec;
123 m_structure_mapper.map(resolve_struc_path(it->string(),
primclex()),
124 required_properties,
nullptr,
125 std::back_inserter(tvec));
126 for (
auto &res : tvec) {
148 if (!res.properties.to.empty() && res.has_data && settings().
import) {
155 auto p_it = preexisting.find(res.properties.to);
156 if (p_it == preexisting.end()) {
158 .emplace(res.properties.to,
159 has_existing_data_or_files(res.properties.to))
162 res.import_data.preexisting = p_it->second;
165 db_props().insert(res.properties);
168 results.push_back(res);
173 this->_copy_files(results);
175 this->_import_report(results);
177 db_supercell().commit();
178 db_config<ConfigType>().commit();
184 template <
typename _ConfigType>
186 std::vector<ConfigIO::Result> &results)
const {
187 if (!settings().
import ||
188 !(settings().copy_files || settings().additional_files))
191 for (
auto res : results) {
192 std::string to_config = res.properties.to;
193 if (to_config.empty())
continue;
195 auto db_it = db_props().find_via_to(to_config);
196 std::string origin = db_it->origin;
198 if (origin != res.properties.origin)
continue;
201 res.import_data.is_best =
true;
206 if (res.import_data.preexisting && !settings().overwrite) {
210 db_props().erase(db_it);
214 rm_files(to_config,
false);
215 this->cp_files(res,
false, settings().additional_files);
216 db_props().insert(res.properties);
222 template <
typename _ConfigType>
224 std::vector<ConfigIO::Result> &results)
const {
234 std::vector<ConfigIO::Result> map_fail;
237 std::vector<ConfigIO::Result> map_success;
241 std::vector<ConfigIO::Result> import_data_fail;
243 std::string prefix =
"import_";
246 std::map<std::string, int> all_to;
248 for (
auto const &res : results) {
249 if (res.properties.to.empty()) {
250 map_fail.push_back(res);
252 auto it = all_to.find(res.properties.to);
253 if (it == all_to.end()) {
254 it = all_to.insert(std::make_pair(res.properties.to, 0)).first;
258 map_success.push_back(res);
259 if (res.has_data && settings().import &&
260 db_props().find_via_to(res.properties.to) != db_props().end() &&
261 db_props().score(res.properties) <
262 db_props().best_score(res.properties.to)) {
263 import_data_fail.push_back(res);
269 std::vector<ConfigIO::Result> conflict;
270 for (
auto const &res : results) {
271 if (!res.properties.to.empty() && all_to[res.properties.to] > 1) {
272 conflict.push_back(res);
277 if (map_fail.size()) {
278 fs::path p = fs::path(m_report_dir) / (prefix +
"_fail");
279 fs::ofstream sout(p);
281 log() <<
"WARNING: Could not import " << map_fail.size() <<
" structures."
283 log() <<
" See detailed report: " << p << std::endl << std::endl;
287 auto formatter = dict.
parse({
"initial_path",
"fail_msg"});
288 sout << formatter(map_fail.begin(), map_fail.end());
293 auto formatter = _import_formatter();
295 if (map_success.size()) {
296 fs::path p = fs::path(m_report_dir) / (prefix +
"_success");
297 fs::ofstream sout(p);
299 log() <<
"Successfully imported " << map_success.size() <<
" structures."
301 log() <<
" See detailed report: " << p << std::endl << std::endl;
303 sout << formatter(map_success.begin(), map_success.end());
306 if (import_data_fail.size()) {
307 fs::path p = fs::path(m_report_dir) / (prefix +
"_data_fail");
308 fs::ofstream sout(p);
310 log() <<
"WARNING: Did not import data from " << import_data_fail.size()
311 <<
" structures which have are a mapping score"
312 " better than the existing data."
314 log() <<
" You may wish to inspect these structures and allow overwriting "
315 "or remove existing data manually."
317 log() <<
" See detailed report: " << p << std::endl << std::endl;
319 sout << formatter(import_data_fail.begin(), import_data_fail.end());
322 if (conflict.size()) {
323 fs::path p = fs::path(m_report_dir) / (prefix +
"_conflict");
324 fs::ofstream sout(p);
327 <<
"WARNING: Imported data from structures that mapped to the same "
330 <<
" Data can only be imported from one of the conflicting structures."
332 <<
" Based on the current conflict resolution method the 'best' "
333 "result was automatically chosen, "
335 <<
" but you may wish to inspect these results and manually select "
336 "which structures to import."
338 log() <<
" See detailed report: " << p << std::endl << std::endl;
340 sout << formatter(conflict.begin(), conflict.end());
#define ERR_MISSING_INPUT_FILE
#define ERR_INVALID_INPUT_FILE
const std::vector< fs::path > & pos_vec() const
const fs::path & batch_path() const
po::variables_map & vm()
Get the variables map.
Generic ConfigType-dependent part of Import.
ImportT(const PrimClex &primclex, const StructureMap< ConfigType > &mapper, ImportSettings const &_set, std::string report_dir)
Constructor.
PrimClex is the top-level data structure for a CASM project.
GenericDatumFormatter< std::string, Result > initial_path()
GenericDatumFormatter< std::string, Result > fail_msg()
std::pair< OutputIterator, int > construct_pos_paths(const PrimClex &primclex, const Completer::ImportOption &import_opt, OutputIterator result)
Construct pos_paths from input args –pos && –batch.
INDEX_TYPE Index
For long integer indexing:
T max(const T &A, const T &B)
Struct with optional parameters for Config/Data Import Specifies default parameters for all values,...