/** * @file * @author Caleb Fangmeier * @version 0.1 * * @section LICENSE * * * MIT License * * Copyright (c) 2017 Caleb Fangmeier * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in all * copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. * */ #ifndef config_hpp #define config_hpp #include #include #include #include #include #include #include #include "yaml-cpp/yaml.h" namespace fv_util { struct DataFileDescriptor { std::string filename; std::string label; std::string category; int file_number; int n_events; DataFileDescriptor() : filename(""), label(""), category(""), file_number(-1), n_events(-1) {} DataFileDescriptor(const std::string filename, const std::string label, const std::string category, const int n_events) : filename(filename), label(label), category(category), file_number(-1), n_events(n_events) {} DataFileDescriptor(const std::string filename, const std::string label, const std::string category, const int file_number, const int n_events) : filename(filename), label(label), category(category), file_number(file_number), n_events(n_events) {} }; } namespace YAML { template<> struct convert { static Node encode(const fv_util::DataFileDescriptor &rhs) { Node node; node["filename"] = rhs.filename; node["label"] = rhs.label; node["category"] = rhs.category; node["n_events"] = rhs.n_events; return node; } static bool decode(const Node &node, fv_util::DataFileDescriptor &rhs) { if (!node.IsMap()) { return false; } if (!node["filename"]) return false; rhs.filename = node["filename"].as(); if (node["label"]) rhs.label = node["label"].as(); if (node["category"]) rhs.category = node["category"].as(); if (node["n_events"]) rhs.n_events = node["n_events"].as(); return true; } }; } namespace fv_util { std::vector glob(const std::string& base) { std::hash s_hash; std::stringstream ss; std::stringstream tmp_filename; tmp_filename << "__tmp" << s_hash(base) << "__"; ss << "ls -1 " << base << " > " << tmp_filename.str(); system(ss.str().c_str()); std::vector filenames; std::ifstream f(tmp_filename.str()); std::string line; while (std::getline(f, line)) { filenames.push_back(line); } std::remove(tmp_filename.str().c_str()); return filenames; } class Config { private: std::string input_filename; YAML::Node root; public: Config() : root(), input_filename("") {} Config(const Config &c) : root(c.root), input_filename(c.input_filename) {} Config(const std::string &input_filename) : root(YAML::LoadFile(input_filename)), input_filename(input_filename) {} template YAML::Node get(const KEY_TYPE &key) { auto val = root[key]; return val; } template void update_key(const std::string &key, const T &val) { root[key] = val; } std::string as_string() { std::stringstream config; std::ifstream s(input_filename); for (std::string line; std::getline(s, line);) { config << line << std::endl; } return config.str(); } size_t get_max_events() { YAML::Node max_events = root["max-events"]; if (!max_events) { return 0; } return max_events.as(); } bool get_debug() { YAML::Node debug_node = root["debug"]; if (!debug_node) { return false; } return debug_node.as(); } std::string get_output_filename() { YAML::Node output_file = root["output-file"]; YAML::Node output_dir = root["output-dir"]; YAML::Node key = root["source-file-key"]; std::string full_path = "."; if (output_dir) { full_path = output_dir.as(); } if (output_file) { full_path = full_path + "/" + output_file.as(); } else { if (key) { full_path += "/" + key.as() + ".root"; } else { full_path += "/output.root"; } } return full_path; } std::vector get_source_files() { std::vector source_files; std::string source_file_key = "source-files"; if (root["source-file-key"]) { source_file_key = root["source-file-key"].as(); } YAML::Node source_files_nd = root[source_file_key]; if (source_files_nd.IsMap()) { auto filenames = glob(source_files_nd["files"].as()); DataFileDescriptor dfd; for (const auto& filename : filenames) { dfd.filename = filename; source_files.push_back(dfd); } } else if (source_files_nd.IsSequence()) { for (const auto &f : source_files_nd) { source_files.push_back(f.as()); } } else { std::cout << "source-files missing or not a sequence" << std::endl; } return source_files; } }; Config *the_config = nullptr; bool debug_on = false; void init_config(const std::string &input_filename) { if (the_config) delete the_config; the_config = new Config(input_filename); debug_on = the_config->get_debug(); } } #endif // config_hpp