19 bool numeric_value(
const std::string& value) {
22 std::stod(value, &parsed);
23 return parsed == value.size();
25 catch (
const std::exception&) {
return false; }
28 std::string cad_mesh_reference(
const std::string& parameters,
const std::string& description) {
31 (values.size() == 1 && (values[0] ==
"NULL" || numeric_value(values[0])))) {
37 void set_resolved_cad_mesh(std::vector<std::string>& row,
const std::string& resolved) {
38 constexpr int PARAMETERS_INDEX = 2;
39 constexpr int DESCRIPTION_INDEX = 19;
43 (values.size() == 1 && (values[0] ==
"NULL" || numeric_value(values[0])))) {
44 row[DESCRIPTION_INDEX] = resolved;
48 const auto delimiter = row[PARAMETERS_INDEX].find(
',');
49 const auto suffix = delimiter == std::string::npos ?
"" : row[PARAMETERS_INDEX].substr(delimiter);
50 row[PARAMETERS_INDEX] = resolved + suffix;
53 bool geometry_column_exists(sqlite3* db,
const std::string& column_name) {
54 sqlite3_stmt* stmt =
nullptr;
55 int rc = sqlite3_prepare_v2(db,
"SELECT name FROM PRAGMA_TABLE_INFO('geometry')", -1, &stmt,
nullptr);
56 if (rc != SQLITE_OK) {
return false; }
59 while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
60 const unsigned char* colText = sqlite3_column_text(stmt, 0);
61 if (colText !=
nullptr && column_name ==
reinterpret_cast<const char*
>(colText)) {
67 sqlite3_finalize(stmt);
72void GSystemSQLiteFactory::loadGeometry(
GSystem* system) {
77 if (db ==
nullptr) { initialize_sqlite_db(system); }
84 const std::string placement_column = geometry_column_exists(db,
"g4placement_type")
87 "' AS g4placement_type";
88 const std::string sql_query =
89 "SELECT DISTINCT name, solid, parameters, material, mother, position, rotations, " +
91 ", mfield, visible, style, color, opacity, digitization, identifier, copyOf, solidsOpr, mirror, "
92 "exist, description FROM geometry WHERE experiment = ? AND system = ? AND variation = ? AND run = ?";
93 sqlite3_stmt* stmt =
nullptr;
94 int rc = sqlite3_prepare_v2(db, sql_query.c_str(), -1, &stmt,
nullptr);
95 if (rc != SQLITE_OK) {
97 sqlite3_errmsg(db),
" (", rc,
") using query: ", sql_query);
102 std::string system_name = system->
getName();
106 rc = sqlite3_bind_text(stmt, 1, experiment.c_str(), -1, SQLITE_STATIC);
107 if (rc != SQLITE_OK) {
110 rc = sqlite3_bind_text(stmt, 2, system_name.c_str(), -1, SQLITE_STATIC);
111 if (rc != SQLITE_OK) {
114 rc = sqlite3_bind_text(stmt, 3, variation.c_str(), -1, SQLITE_STATIC);
115 if (rc != SQLITE_OK) {
118 rc = sqlite3_bind_int(stmt, 4, runno);
119 if (rc != SQLITE_OK) {
124 if (
auto sql = sqlite3_expanded_sql(stmt)) {
130 std::vector<std::string> gvolumePars;
131 std::vector<std::string> cadSearchDirectories;
134 if (!std::filesystem::is_directory(location, ec)) {
continue; }
136 cadSearchDirectories.push_back(location);
137 const auto systemLocation = std::filesystem::path(location) / system->
getName();
138 if (std::filesystem::is_directory(systemLocation, ec)) {
139 cadSearchDirectories.push_back(systemLocation.string());
142 while ((rc = sqlite3_step(stmt)) == SQLITE_ROW) {
143 int colCount = sqlite3_column_count(stmt);
144 for (
int i = 0; i < colCount; i++) {
145 const char* colName = sqlite3_column_name(stmt, i);
146 const unsigned char* colText = sqlite3_column_text(stmt, i);
148 log->info(2,
"<sqlite> column: ", (colName ? colName :
"NULL"),
" = ",
149 (colText ?
reinterpret_cast<const char*
>(colText) :
"NULL"),
" (column ", i,
")");
151 gvolumePars.emplace_back(colText ?
reinterpret_cast<const char*
>(colText) :
"");
157 const auto meshReference = cad_mesh_reference(gvolumePars[2], gvolumePars[19]);
161 log->warning(
"SQLite factory: CAD volume <", gvolumePars[0],
162 "> references missing mesh <", meshReference,
">; skipping.");
166 set_resolved_cad_mesh(gvolumePars, meshPath.value());
173 if (rc != SQLITE_DONE) {
175 sqlite3_errmsg(db),
" (", rc,
")");
178 sqlite3_finalize(stmt);
std::shared_ptr< GLogger > log
std::vector< std::string > possibleLocationOfFiles
List of candidate directories used by file-based factories.
Represents a single detector system (e.g., calorimeter, tracker).
std::string getExperiment() const
std::string getVariation() const
void addGVolume(std::vector< std::string > pars)
Build and add a volume from a serialized parameter list.
std::string getName() const
Conventions and shared constants for the detector-system module.
constexpr char DEFAULTG4PLACEMENTTYPE[]
constexpr char GSYSTEMCADTFACTORYLABEL[]
constexpr int ERR_GSQLITEERROR
constexpr char ROOTWORLDGVOLUMENAME[]
Canonical name for the ROOT/world gvolume entry.
vector< string > getStringVectorFromStringWithDelimiter(const string &input, const string &x)
std::optional< std::string > searchForFileInLocations(const std::vector< std::string > &locations, std::string_view filename)