28 bool table_exists(sqlite3* db,
const char* name) {
29 sqlite3_stmt* stmt =
nullptr;
30 if (sqlite3_prepare_v2(db,
"SELECT 1 FROM sqlite_master WHERE type='table' AND name=?",
31 -1, &stmt,
nullptr) != SQLITE_OK) {
34 sqlite3_bind_text(stmt, 1, name, -1, SQLITE_TRANSIENT);
35 bool exists = (sqlite3_step(stmt) == SQLITE_ROW);
36 sqlite3_finalize(stmt);
41 bool mirrors_column_exists(sqlite3* db,
const std::string& column_name) {
42 sqlite3_stmt* stmt =
nullptr;
43 if (sqlite3_prepare_v2(db,
"SELECT name FROM PRAGMA_TABLE_INFO('mirrors')", -1, &stmt,
nullptr) != SQLITE_OK) {
47 while (sqlite3_step(stmt) == SQLITE_ROW) {
48 const unsigned char* colText = sqlite3_column_text(stmt, 0);
49 if (colText !=
nullptr && column_name ==
reinterpret_cast<const char*
>(colText)) {
54 sqlite3_finalize(stmt);
59void GSystemCADFactory::loadMirrors(
GSystem* s) {
67 vector<string> dirs = {
78 sqlite3* db =
nullptr;
79 if (sqlite3_open_v2(dbPath.value().c_str(), &db, SQLITE_OPEN_READONLY,
nullptr) != SQLITE_OK) {
81 log->error(
ERR_GSQLITEERROR,
"CAD factory: failed to open sqlite database <" + dbhost +
">.");
87 if (!table_exists(db,
"mirrors") || !mirrors_column_exists(db,
"name")) {
88 log->info(2,
"CAD factory: no usable 'mirrors' table (ok if the system defines no mirrors).");
95 const string transmittance_column = mirrors_column_exists(db,
"transmittance")
97 :
"NULL AS transmittance";
98 const string sql_query =
99 "SELECT name, description, type, finish, model, border, matOptProps, photonEnergy, "
100 "indexOfRefraction, reflectivity, efficiency, specularlobe, specularspike, backscatter, "
101 + transmittance_column +
102 ", sigmaAlpha FROM mirrors WHERE experiment = ? AND system = ? AND variation = ? AND run = ?";
104 sqlite3_stmt* stmt =
nullptr;
105 if (sqlite3_prepare_v2(db, sql_query.c_str(), -1, &stmt,
nullptr) != SQLITE_OK) {
106 log->error(
ERR_GSQLITEERROR,
"CAD factory: error preparing mirrors query: ", sqlite3_errmsg(db));
112 string system_name = s->
getName();
116 sqlite3_bind_text(stmt, 1, experiment.c_str(), -1, SQLITE_TRANSIENT);
117 sqlite3_bind_text(stmt, 2, system_name.c_str(), -1, SQLITE_TRANSIENT);
118 sqlite3_bind_text(stmt, 3, variation.c_str(), -1, SQLITE_TRANSIENT);
119 sqlite3_bind_int(stmt, 4, runno);
122 while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
123 vector<string> gmirrorPars;
124 const int ncols = sqlite3_column_count(stmt);
125 for (
int i = 0; i < ncols; ++i) {
127 (sqlite3_column_type(stmt, i) == SQLITE_NULL)
129 : reinterpret_cast<const char*>(sqlite3_column_text(stmt, i));
130 gmirrorPars.emplace_back(ctext);
135 if (rc != SQLITE_DONE) {
136 log->error(
ERR_GSQLITEERROR,
"CAD factory: sqlite error while reading mirrors: ", sqlite3_errmsg(db));
139 sqlite3_finalize(stmt);
std::shared_ptr< GLogger > log
Represents a single detector system (e.g., calorimeter, tracker).
std::string getExperiment() const
std::string getVariation() const
std::string getName() const
void addGMirror(std::vector< std::string > pars)
Build and add a mirror (optical surface) from a serialized parameter list.
std::string get_dbhost() const
Conventions and shared constants for the detector-system module.
#define GSYSTEMSQLITETDEFAULTFILE
Default sqlite DB filename used when the user does not specify one.
#define ROOTWORLDGVOLUMENAME
Canonical name for the ROOT/world gvolume entry.
std::filesystem::path gemc_root()
std::optional< std::string > searchForFileInLocations(const std::vector< std::string > &locations, std::string_view filename)