feat(const): added constants class

constants class can parse and get physical constants from datafile including value, unit, uncertainity, and reference
This commit is contained in:
2025-02-11 18:02:07 -05:00
parent 078269fb4a
commit 795ee2e3bf
4 changed files with 666 additions and 27 deletions

18
src/const/meson.build Normal file
View File

@@ -0,0 +1,18 @@
# Define the library
const_sources = files(
'private/const.cpp',
)
const_headers = files(
'public/const.h'
)
# Define the libconst library so it can be linked against by other parts of the build system
libconst = library('const',
const_sources,
include_directories: include_directories('public'),
cpp_args: ['-fvisibility=default'],
install : true)
# Make headers accessible
install_headers(const_headers, subdir : '4DSSE/const')

112
src/const/private/const.cpp Normal file
View File

@@ -0,0 +1,112 @@
#include <iostream>
#include <map>
#include <vector>
#include <string>
#include <fstream>
#include <set>
#include "const.h"
constants::constants() {
loaded_ = false;
}
constants::constants(const std::string& filename) {
loaded_ = initialize(filename);
}
bool constants::initialize(const std::string& filename) {
return load(filename);
}
constant constants::get(const std::string& name) {
return constants_[name];
}
constant constants::operator[](const std::string& name) const {
auto it = constants_.find(name);
if (it != constants_.end()) {
return it->second;
} else {
throw std::out_of_range("Constant '" + name + "' not found.");
}
}
bool constants::has(const std::string& name) const {
return constants_.find(name) != constants_.end();
}
std::set<std::string> constants::keys() const {
std::set<std::string> keys;
for (const auto& pair : constants_) {
keys.insert(pair.first);
}
return keys;
}
std::string constants::trim(const std::string& str) {
size_t first = str.find_first_not_of(" \t");
if (first == std::string::npos) return "";
size_t last = str.find_last_not_of(" \t");
return str.substr(first, last - first + 1);
}
bool constants::load(const std::string& filename) {
std::ifstream file(filename);
std::map<std::string, constant> constants_temp;
if (!file.is_open()) {
std::cerr << "Error: Unable to open file " << filename << std::endl;
return false;
}
std::string line;
bool data_section = false;
int line_count = 0;
while (std::getline(file, line)) {
line_count++;
// Detect start of data section (double divider line)
if (!data_section) {
if (line.find("Symbol") != std::string::npos) { // Find header row
std::getline(file, line); // Skip dashed divider
std::getline(file, line); // Skip second dashed divider
data_section = true;
}
continue;
}
// Ensure the line is long enough to contain all fields
if (line.length() < 125) continue;
// Define exact column widths from Python script
int start = 0;
std::string symbol = trim(line.substr(start, col_widths_[0])); start += col_widths_[0];
std::string name = line.substr(start, col_widths_[1]); start += col_widths_[1];
std::string valueStr = line.substr(start, col_widths_[2]); start += col_widths_[2];
std::string unit = trim(line.substr(start, col_widths_[3])); start += col_widths_[3]; // Only trim the unit
std::string uncertaintyStr = line.substr(start, col_widths_[4]); start += col_widths_[4];
std::string reference = trim(line.substr(start, col_widths_[5])); // Only trim reference
// Convert numerical fields safely
double value = 0.0, uncertainty = 0.0;
try {
value = std::stod(valueStr);
} catch (...) {
std::cerr << "Warning: Invalid value in line " << line_count << ": " << valueStr << std::endl;
}
try {
uncertainty = std::stod(uncertaintyStr);
} catch (...) {
std::cerr << "Warning: Invalid uncertainty in line " << line_count << ": " << uncertaintyStr << std::endl;
}
// Store in map
constants_temp[symbol] = {name, value, uncertainty, unit, reference};
}
file.close();
constants_ = constants_temp;
loaded_ = true;
return true;
}

View File

@@ -7,52 +7,92 @@
#include <vector>
#include <map>
/**
* @brief Structure to hold a constant's details.
*/
struct constant {
std::string name;
double value;
double uncertainty;
std::string unit;
std::string reference;
}
std::string name; ///< Name of the constant
double value; ///< Value of the constant
double uncertainty; ///< Uncertainty in the constant's value
std::string unit; ///< Unit of the constant
std::string reference; ///< Reference for the constant's value
};
/**
* @brief Class to manage a collection of constants.
*/
class constants {
private:
bool loaded_ = false;
std::map<std::string, constant> constants_;
bool loaded_ = false; ///< Flag to indicate if constants are loaded
const int col_widths_[6] = {25, 52, 20, 20, 17, 45}; // From the python script used to generate the constants file
std::map<std::string, constant> constants_; ///< Map to store constants by name
/**
* @brief Load constants from a file.
* @param filename The name of the file to load constants from.
* @return True if loading was successful, false otherwise.
*/
bool load(const std::string& filename);
/**
* @brief Trim leading and trailing whitespace from a string.
* @param str The string to trim.
* @return The trimmed string.
*/
std::string trim(const std::string& str);
public:
/**
* @brief Default constructor.
*/
constants();
/**
* @brief Constructor that initializes constants from a file.
* @param filename The name of the file to load constants from.
*/
constants(const std::string& filename);
/**
* @brief Check if constants are loaded.
* @return True if constants are loaded, false otherwise.
*/
bool is_loaded() { return loaded_; }
/**
* @brief Initialize constants from a file.
* @param filename The name of the file to load constants from.
* @return True if initialization was successful, false otherwise.
*/
bool initialize(const std::string& filename);
/**
* @brief Get a constant by key.
* @param key The name of the constant to retrieve.
* @return The constant associated with the given key.
*/
constant get(const std::string& key);
constant operator[](const std::string& key) const {
auto it = constants_.find(key);
if (it != constants_.end()) {
return it->second;
} else {
throw std::out_of_range("Constant '" + key + "' not found.");
}
};
bool has(const std::string& key) const {
return constants_.find(key) != constants_.end();
};
/**
* @brief Overloaded subscript operator to access constants by key.
* @param key The name of the constant to retrieve.
* @return The constant associated with the given key.
* @throws std::out_of_range if the key is not found.
*/
constant operator[](const std::string& key) const;
std::Vector<std::string> keys() const {
std::Vector<std::string> keys;
for (auto it = constants_.begin(); it != constants_.end(); ++it) {
keys.push_back(it->first);
}
return keys;
};
/**
* @brief Check if a constant exists by key.
* @param key The name of the constant to check.
* @return True if the constant exists, false otherwise.
*/
bool has(const std::string& key) const;
/**
* @brief Get a list of all constant keys.
* @return A vector of all constant keys.
*/
std::set<std::string> keys() const;
};