4 #if (__DARWIN_C_LEVEL < __DARWIN_C_FULL) && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L) && \
5 (!defined(__cplusplus) || __cplusplus < 201703L)
6 #include <boost/align/aligned_alloc.hpp>
7 using boost::alignment::aligned_alloc;
17 #include <sjef/util/Logger.h>
33 struct pugi_xml_document;
34 static constexpr
int recentMax = 128;
40 std::string m_project_suffix;
41 std::filesystem::path m_filename;
43 std::vector<std::filesystem::path> m_reserved_files = std::vector<std::filesystem::path>{
44 sjef::Project::s_propertyFile};
45 std::unique_ptr<pugi_xml_document> m_properties;
47 std::map<std::string, Backend> m_backends;
49 std::unique_ptr<pugi_xml_document> m_backend_doc;
52 struct unmovables_container {
53 std::mutex m_property_set_mutex;
55 mutable unmovables_container m_unmovables;
56 mutable std::string m_backend;
57 mutable std::string m_xml_cached;
59 static const std::string s_propertyFile;
61 std::shared_ptr<Locker> m_locker;
62 mutable Logger m_warn{std::cerr, Logger::Levels::warning, {
"sjef:: Error: ",
"sjef:: Warning: ",
"sjef:: Note:"}};
63 mutable Logger m_trace{std::cout, Logger::Levels::quiet};
65 mutable std::unique_ptr<util::Job> m_job;
79 explicit Project(
const std::filesystem::path&
filename,
bool construct =
true,
const std::string& default_suffix =
"",
80 const mapstringstring_t& suffixes = {{
"inp",
"inp"}, {
"out",
"out"}, {
"xml",
"xml"}});
100 bool copy(
const std::filesystem::path& destination_filename,
bool force =
false,
bool keep_hash =
false,
101 bool slave =
false,
int keep_run_directories = std::numeric_limits<int>::max(),
bool history =
true);
110 bool move(
const std::filesystem::path& destination_filename,
bool force =
false,
bool history =
true);
119 static void erase(
const std::filesystem::path&
filename,
const std::string& default_suffix =
"");
127 bool import_file(
const std::filesystem::path& file,
bool overwrite =
false);
128 bool import_file(
const std::vector<std::string>& files,
bool overwrite =
false) {
130 for (
const auto& file : files)
140 bool export_file(
const std::filesystem::path& file,
bool overwrite =
false);
141 bool export_file(
const std::vector<std::string>& files,
bool overwrite =
false) {
143 for (
const auto& file : files)
153 void set_warnings(
const Logger::Levels level = Logger::Levels::warning, std::ostream& stream = std::cerr,
154 std::vector<std::string> preambles = {
"sjef:: Error: ",
"sjef:: Warning: ",
"sjef:: Note:"}) {
155 m_warn = Logger{stream, level, std::move(preambles)};
157 void set_verbosity(
int verbosity, std::ostream& stream = std::cout) { m_trace = Logger(stream, verbosity); }
169 bool run(
int verbosity = 0,
bool force =
false,
bool wait =
false,
const std::string& options=
"");
170 bool run(
const std::string&
name,
int verbosity = 0,
bool force =
false,
bool wait =
false,
const std::string& options=
"") {
172 return run(verbosity, force,
wait);
197 void wait(
unsigned int maximum_microseconds = 10000)
const;
251 std::string
xml(
int run = 0,
bool sync =
true)
const;
266 bool sync =
true)
const;
272 void clean(
int keep_run_directories = 1);
279 void property_set(
const std::string& property,
const std::string& value);
321 std::filesystem::path
filename(std::string suffix =
"",
const std::string&
name =
"",
int run = -1)
const;
376 static std::string
recent(
const std::string& suffix,
int number = 1);
377 std::string
recent(
int number = 1)
const;
387 const std::map<std::string, Backend>&
backends()
const {
return m_backends; }
388 std::map<std::string, Backend>&
backends() {
return m_backends; }
391 Backend default_backend();
392 void throw_if_backend_invalid(std::string backend =
"")
const;
393 std::string get_project_suffix(
const std::filesystem::path&
filename,
const std::string& default_suffix)
const;
394 static void recent_edit(
const std::filesystem::path& add,
const std::filesystem::path& remove =
"");
395 mutable std::filesystem::file_time_type m_property_file_modification_time;
396 mutable std::map<std::string, std::filesystem::file_time_type, std::less<>> m_input_file_modification_time;
397 std::set<std::string, std::less<>> m_run_directory_ignore;
398 void property_delete_locked(
const std::string& property);
399 void check_property_file_locked()
const;
400 void check_property_file()
const;
401 void save_property_file_locked()
const;
402 void save_property_file()
const;
403 void load_property_file_locked()
const;
404 bool properties_last_written_by_me(
bool removeFile =
false)
const;
416 std::string cache(
const Backend& backend)
const;
417 void force_file_names(
const std::string& oldname);
418 static void backend_watcher(
sjef::Project& project_,
int min_wait_milliseconds,
int max_wait_milliseconds = 0,
419 int poll_milliseconds = 1);
420 void shutdown_backend_watcher();
428 std::string referenced_file_contents(
const std::string& line)
const;
456 std::string
backend_get(
const std::string& backend,
const std::string& key)
const;
493 if (p.find(
"!") == std::string::npos)
495 return p.substr(0, p.find(
"!"));
506 if (ps.count(
name) == 0)
519 if (ps.count(
name) == 0)
566 void take_run_files(
int run = 0,
const std::string& fromname =
"",
const std::string& toname =
"")
const;
596 std::vector<std::string>
xpath_search(
const std::string& xpath_query,
const std::string& attribute =
"",
606 std::vector<std::string>
xpath_xml(
const std::string& xpath_query,
int run = 0)
const;
633 std::filesystem::path
expand_path(
const std::filesystem::path& path,
const std::string& suffix =
"");
652 using std::runtime_error::runtime_error;
void property_delete(const std::vector< std::string > &properties)
std::string filename_string(std::string suffix="", const std::string &name="", int run=-1) const
size_t input_hash() const
Construct a hash that is unique to the contents of the input file and anything it references.
bool export_file(const std::vector< std::string > &files, bool overwrite=false)
Definition: sjef.h:141
friend class util::Job
Definition: sjef.h:64
void rewrite_input_file(const std::string &input_file_name, const std::string &old_name)
std::string backend_get(const std::string &backend, const std::string &key) const
Obtain the value of a field in a backend.
int local_pid_from_output() const
Try to get the process id of the job from its output, if the running program happens to offer that.
std::string run_directory_basename(int run=0) const
run_list_t run_list() const
bool copy(const std::filesystem::path &destination_filename, bool force=false, bool keep_hash=false, bool slave=false, int keep_run_directories=std::numeric_limits< int >::max(), bool history=true)
Copy the project to another location.
std::filesystem::path run_directory_new()
Create a new run directory. Also copy into it the input file, and any of its dependencies.
bool check_backend(const std::string &name) const
Check whether the specification of a backend is valid.
bool run(const std::string &name, int verbosity=0, bool force=false, bool wait=false, const std::string &options="")
Definition: sjef.h:170
const std::string backend_cache() const
Get the location of the backend cache.
int recent_find(const std::filesystem::path &filename) const
std::string backend_parameter_default(const std::string &backend, const std::string &name) const
Return the default value associated with a backend run parameter.
Definition: sjef.h:517
std::vector< std::string > xpath_search(const std::string &xpath_query, const std::string &attribute="", int run=0) const
Simple XPath search on the xml document. For each matching node found, return a string that contains ...
void backend_parameter_set(const std::string &backend, const std::string &name, const std::string &value)
Definition: sjef.h:483
void take_run_files(int run=0, const std::string &fromname="", const std::string &toname="") const
Copy files from a run directory to the main project.
bool import_file(const std::vector< std::string > &files, bool overwrite=false)
Definition: sjef.h:128
void delete_backend(const std::string &name)
Remove a backend from the project and from the user's global backend configuration for all projects o...
bool import_file(const std::filesystem::path &file, bool overwrite=false)
Import one or more files into the project. In the case of a .xml output file, if the corresponding in...
sjef::status status() const
Obtain the status of the job started by run()
void custom_initialisation()
Perform any project initialisation specific to the project suffix.
std::string file_contents(const std::string &suffix="", const std::string &name="", int run=0, bool sync=true) const
Obtain the contents of a project file.
std::filesystem::path propertyFile() const
void property_delete(const std::string &property)
Remove a variable.
Project(const Project &source)=delete
void wait(unsigned int maximum_microseconds=10000) const
Wait unconditionally for status() to return neither 'waiting' nor 'running'.
void custom_run_preface()
Before launching a job, perform any required actions specific to the project suffix.
mapstringstring_t property_get(const std::vector< std::string > &properties) const
Get the values of several properties.
std::string xml(int run=0, bool sync=true) const
Get the xml output, completing any open tags if necessary.
unsigned int current_run() const
Get the focussed run directory.
mapstringstring_t backend_parameters(const std::string &backend, bool doc=false) const
Get all of the parameters referenced in the run_command of a backend.
std::string input_from_output(bool sync=true) const
If possible, construct the input embedded in the output file.
std::string backend_parameter_expand(const std::string &backend, std::string templ="") const
Perform parameter substitution for a backend run_command template.
bool trash()
Move the project to the trash folder.
bool check_all_backends() const
Check the specification of all backends for validity.
int run_verify(int run) const
Check a run exists, and resolve most recent.
bool move(const std::filesystem::path &destination_filename, bool force=false, bool history=true)
Move the project to another location.
std::string property_get(const std::string &property) const
Get the value of a property.
void clean(int keep_run_directories=1)
Remove run directories from project.
std::filesystem::path filename(std::string suffix="", const std::string &name="", int run=-1) const
Get the file name of the bundle, or a primary file of particular type, or a general file in the bundl...
std::string backend_parameter_get(const std::string &backend, const std::string &name) const
Definition: sjef.h:491
void set_verbosity(int verbosity, std::ostream &stream=std::cout)
Definition: sjef.h:157
static int recent_find(const std::string &suffix, const std::filesystem::path &filename)
Look for a project by name in the user-global recent project list.
void add_backend(const std::string &name, const mapstringstring_t &fields)
Introduce a new backend to the project and to the user's global backend configuration for all project...
void set_warnings(const Logger::Levels level=Logger::Levels::warning, std::ostream &stream=std::cerr, std::vector< std::string > preambles={"sjef:: Error: ", "sjef:: Warning: ", "sjef:: Note:"})
Set the warning/error diagnostic level and destination.
Definition: sjef.h:153
void change_backend(std::string backend=std::string{""}, bool force=false)
Change the active backend.
bool export_file(const std::filesystem::path &file, bool overwrite=false)
Export one or more files from the project.
Project(const Project &&source)=delete
std::map< std::string, Backend > & backends()
Definition: sjef.h:388
std::vector< std::string > backend_names() const
Get the names of all the backend objects associated with the object.
void run_delete(int run)
Delete a run directory.
bool run(int verbosity=0, bool force=false, bool wait=false, const std::string &options="")
Start a sjef job.
void property_set(const std::string &property, const std::string &value)
Set a property.
static const std::vector< std::string > suffix_keys
Definition: sjef.h:431
std::string recent(int number=1) const
static std::string recent(const std::string &suffix, int number=1)
Look for a project by rank in the user-global recent project list.
std::string status_message(int verbosity=0) const
static void erase(const std::filesystem::path &filename, const std::string &default_suffix="")
Erase a project from the file system, and remove it from the recent projects file.
void property_set(const mapstringstring_t &properties)
Set one or more properties.
bool run_needed(int verbosity=0) const
Check whether the job output is believed to be out of date with respect to the input and any other fi...
void backend_parameter_delete(const std::string &backend, const std::string &name)
Definition: sjef.h:487
std::string backend_parameter_documentation(const std::string &backend, const std::string &name) const
Return the documentation associated with a backend run parameter.
Definition: sjef.h:504
const std::map< std::string, Backend > & backends() const
Definition: sjef.h:387
void set_current_run(unsigned int run=0)
Set the focussed run directory.
sjef::status status_from_output() const
Obtain the job status, if possible, by examining the output.
std::vector< std::string > property_names() const
Get the names of all assigned properties.
void refresh_backends()
Reload the backends from the configuration file.
pugi::xpath_node_set select_nodes(const std::string &xpath_query, int run=0) const
General XPath search on the xml document. Needs the pugixml library to parse the result.
std::vector< std::string > xpath_xml(const std::string &xpath_query, int run=0) const
Simple XPath search on the xml document. For each matching node found, return a string that contains ...
std::filesystem::path run_directory(int run=0) const
Obtain the path of a run directory.
void kill(int verbosity=0)
Kill the job started by run()
Project(const std::filesystem::path &filename, bool construct=true, const std::string &default_suffix="", const mapstringstring_t &suffixes={{"inp", "inp"}, {"out", "out"}, {"xml", "xml"}})
Construct, or attach to, a Molpro project bundle.
size_t project_hash()
Return a globally-unique hash to identify the project. The hash is generated on first call to this fu...
std::vector< std::string > run_list_t
Obtain the list of run directory names.
Definition: sjef.h:343
A thread-safe class for an inter-thread/inter-process lock. The lock mechanism is based on a locked f...
Definition: Locker.h:28
bool check_backends(const std::string &suffix)
Check whether a backend specification file is valid. Only the top-level structure of the file is chec...
status
Definition: sjef.h:35
@ failed
Definition: sjef.h:35
@ killed
Definition: sjef.h:35
@ completed
Definition: sjef.h:35
@ waiting
Definition: sjef.h:35
@ running
Definition: sjef.h:35
@ unevaluated
Definition: sjef.h:35
@ unknown
Definition: sjef.h:35
std::string xmlRepair(const std::string &source, const mapstringstring_t &injections={})
Repair an xml dataset by completing any open tags.
std::map< std::string, std::string > mapstringstring_t
Definition: sjef.h:36
std::filesystem::path expand_path(const std::filesystem::path &path, const std::string &suffix="")
Edit a file path name.
std::string version() noexcept
Report the software version.