#include "phigrape.h" #include #include #include #include #include using Dictionary = std::unordered_map; std::string strip(const std::string str) { std::string str_new = str; auto pos = str_new.find_first_not_of(" \t"); if (pos != std::string::npos) str_new = str_new.substr(pos, str_new.size()); pos = str_new.find_last_not_of(" \t"); if (pos != std::string::npos) str_new = str_new.substr(0, pos+1); return str_new; } Dictionary read_config_file(const std::string file_name) { std::unordered_map dictionary; std::ifstream file(file_name); if (!file.good()) throw std::runtime_error("File not found."); std::string str; int line_number = 0; while (std::getline(file, str)) { line_number++; auto pos = str.find('#'); if (pos != std::string::npos) str = str.substr(0, pos); str = strip(str); if (str.size() == 0) continue; pos = str.find_first_of("="); if (pos == std::string::npos) throw std::runtime_error("Error: expected a key-value pair in line " + std::to_string(line_number) + " of file " + file_name); std::string key = strip(str.substr(0, pos)); pos = str.find_first_not_of(" \t", pos+1); std::string val = strip(str.substr(pos, str.size())); dictionary[key] = val; } return dictionary; } template T string_cast(const std::string str); template<> std::string string_cast(const std::string str) { return str; } template<> double string_cast(const std::string str) { size_t idx; auto value = std::stod(str, &idx); if (idx == str.size()) return value; else throw std::runtime_error("Cannot convert \"" + str + "\" into a double"); } template<> int string_cast(const std::string str) { size_t idx; auto value = std::stoi(str, &idx); if (idx == str.size()) return value; else throw std::runtime_error("Cannot convert \"" + str + "\" into an int"); } template<> bool string_cast(const std::string str) { if ((str=="true") || (str=="True") || (str=="yes") || (str=="Yes") || (str=="1")) return true; else if ((str=="false") || (str=="False") || (str=="no") || (str=="No") || (str=="0")) return false; throw std::runtime_error("Cannot convert \"" + str + "\" into a bool"); } // For mandatory parameters template T get_parameter(Dictionary dictionary, std::string name) { auto item = dictionary.find(name); if (item==dictionary.end()) throw std::runtime_error("Mandatory parameter " + name + " must be defined"); else return string_cast((*item).second); } // For optional parameters template T get_parameter(Dictionary dictionary, std::string name, T default_value) { auto item = dictionary.find(name); if (item==dictionary.end()) return default_value; else return string_cast((*item).second); } int main() { auto dictionary = read_config_file("phigrape.conf"); for (auto key_value : dictionary) { auto key = key_value.first; auto value = key_value.second; printf("dictionary[\"%s\"] = \"%s\"\n", key.c_str(), value.c_str()); } Parameters parameters; // TODO check if dt_disk and dt_contr are powers of two parameters.dt_bh = get_parameter(dictionary, "eps"); parameters.t_end = get_parameter(dictionary, "t_end"); parameters.dt_disk = get_parameter(dictionary, "dt_disk"); parameters.dt_contr = get_parameter(dictionary, "dt_contr"); parameters.dt_bh = get_parameter(dictionary, "dt_bh", parameters.dt_contr); parameters.eta = get_parameter(dictionary, "eta"); parameters.input_file_name = get_parameter(dictionary, "dt_bh", "data.con"); parameters.dt_min_warning = get_parameter(dictionary, "dt_min_warning", false); parameters.live_smbh_count = get_parameter(dictionary, "live_smbh_count", 0); parameters.live_smbh_custom_eps = get_parameter(dictionary, "live_smbh_custom_eps", -1); parameters.live_smbh_output = get_parameter(dictionary, "live_smbh_output", false); parameters.live_smbh_neighbor_output = get_parameter(dictionary, "live_smbh_neighbor_output", false); parameters.live_smbh_neighbor_number = get_parameter(dictionary, "live_smbh_neighbor_number", 10); parameters.binary_smbh_pn = get_parameter(dictionary, "binary_smbh_pn", false); parameters.binary_smbh_influence_sphere_output = get_parameter(dictionary, "binary_smbh_influence_sphere_output", false); parameters.binary_smbh_influence_radius_factor = get_parameter(dictionary, "binary_smbh_influence_radius_factor", 10.); }