From d0c733dce6f61f89d9971d9030cee7fb207f57c2 Mon Sep 17 00:00:00 2001 From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> Date: Mon, 8 Jul 2024 13:04:40 +0200 Subject: [PATCH 1/3] Add conditional load of newest classes/nodes. To be able to have new GeoModel nodes/classes while not breaking the load of DBs generated with an earlier version of GeoModel, I added an 'optional' flag to the calls loading the new nodes from the DB. In that way, when loading a DB where we don't expect to see those new nodes, we have no errors as expected. To achieve that, I also added the optional flag to the 'checkDBTable' and 'getPublishedNodes' methods. --- .../step2_read_geo_and_published_nodes.cpp | 6 +- .../GeoModelDBManager/GMDBManager.h | 8 +- .../GeoModelDBManager/src/GMDBManager.cpp | 118 +++++++++++------- .../GeoModelRead/GeoModelRead/ReadGeoModel.h | 3 +- .../GeoModelRead/ReadGeoModel.tpp | 8 +- GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp | 30 ++++- 6 files changed, 115 insertions(+), 58 deletions(-) diff --git a/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp b/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp index 654d70c3d..c2a2bb34d 100644 --- a/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp +++ b/GeoModelExamples/HelloToy/step2_read_geo_and_published_nodes.cpp @@ -156,12 +156,12 @@ int main(int argc, char *argv[]) //check for a table we know doesn't exist if (db->checkTableFromDB("PublishedFullPhysVols_HelloToyExample")) std::cout<<"We find the table that we expected - good!"<<std::endl; else std::cout<<"Uh oh, we don't find the expected table - bad!"<<std::endl; - if(!db->checkTableFromDB("PublishedFullPhysVols_ByeByeToyExample")) std::cout<<"We don't find the table that we didn't expect - good!"<<std::endl; + if(!db->checkTableFromDB("PublishedFullPhysVols_ByeByeToyExample", true)) std::cout<<"We don't find the table that we didn't expect - good!"<<std::endl; else std::cout<<"Uh oh, we found a table which doesn't exist - bad!"<<std::endl; //Now test via the specific accessors with additional checks - std::map<unsigned int, GeoFullPhysVol*> mapFPV_test = readInGeo.getPublishedNodes<unsigned int, GeoFullPhysVol*>("ByeByeToyExample",true); - std::map<std::string, GeoAlignableTransform*> mapAXF_test = readInGeo.getPublishedNodes<std::string, GeoAlignableTransform*>("ByeByeToyExample",true); + std::map<unsigned int, GeoFullPhysVol*> mapFPV_test = readInGeo.getPublishedNodes<unsigned int, GeoFullPhysVol*>("ByeByeToyExample",true, true); + std::map<std::string, GeoAlignableTransform*> mapAXF_test = readInGeo.getPublishedNodes<std::string, GeoAlignableTransform*>("ByeByeToyExample",true, true); if(mapFPV_test.size()==0) std::cout<<"Returned an empty FPV map when using checks for a non-existing table - good!"<<std::endl; if(mapAXF_test.size()==0) std::cout<<"Returned an empty AXF map when using checks for a non-existing table - good!"<<std::endl; diff --git a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h index 404eab0f6..b1d1f18b1 100644 --- a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h +++ b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h @@ -295,12 +295,12 @@ class GMDBManager { std::vector<std::vector<std::string>> getTableFromNodeType_String( std::string nodeType); DBRowsList getTableFromNodeType_VecVecData( - std::string nodeType); + std::string nodeType, const bool optional = false); DBRowEntry getTableFromTableName_VecData( - std::string tableName); + std::string tableName, const bool optional = false); DBRowsList getTableFromTableName_VecVecData( - std::string tableName); + std::string tableName, const bool optional = false); // specializations std::vector<double> getTableFromTableName_VectorDouble(std::string tableName); std::deque<double> getTableFromTableName_DequeDouble(std::string tableName); @@ -314,7 +314,7 @@ class GMDBManager { //! Test if a given table exists //! This requires the *full* table name (i.e. prefix_suffix) - bool checkTableFromDB(std::string tableName) const; + bool checkTableFromDB(std::string tableName, const bool optional = false) const; //! Test if a table has been loaded from a DB, that is it exists in the cache bool checkTableFromCache(const std::string_view tableName) const; diff --git a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp index 91e033551..9e5f4ede1 100644 --- a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp +++ b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp @@ -522,7 +522,6 @@ std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType_String( } else { - // if (!checkTable(tableName)) if (!checkTableFromDB(tableName)) { THROW_EXCEPTION("ERROR!!! Table name '" << tableName << "' does not exist in the DB!"); @@ -533,7 +532,7 @@ std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType_String( } DBRowsList GMDBManager::getTableFromNodeType_VecVecData( - std::string nodeType) + std::string nodeType, const bool optional) { DBRowsList out; std::string tableName = getTableNameFromNodeType(nodeType); @@ -553,68 +552,85 @@ DBRowsList GMDBManager::getTableFromNodeType_VecVecData( } else { - if (!checkTableFromDB(tableName)) - { - THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB!"); - } + // if (!checkTableFromDB(tableName, optional)) + // { + // if (optional) { + // if (m_debug) { + // std::cout << "WARNING! We could not find the table '" << tableName + // << "'. However, it has flagged as 'optional', so it is fine not to find it " + // << "if you are running on a DB that has been generated with an earlier version of GeoModel." + // << std::endl; + // } + // } else { + // THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB!"); + // } + // } + checkTableFromDB(tableName, optional); out = getTableRecords_VecVecData(tableName); } return out; } DBRowsList GMDBManager::getTableFromTableName_VecVecData( - std::string tableName) + std::string tableName, const bool optional) { DBRowsList out; if (tableName.empty()) { - std::mutex coutMutex; - coutMutex.lock(); - std::cout << - "\t ===> WARNING! The geometry input file does not contain a " - "table for the " - << tableName - << "nodes. That means that you are probably using an " - << "old " - << "geometry file. Unless you know exactly what you are doing, " - << "please " - << "expect to see incomplete geometries or crashes.\n" - << std::endl; - coutMutex.unlock(); + if (m_debug) + { + std::mutex coutMutex; + coutMutex.lock(); + std::cout << "\t ===> WARNING! The geometry input file does not contain a " + "table for the " + << tableName + << "nodes. That means that you are probably using an " + << "old " + << "geometry file. Unless you know exactly what you are doing, " + << "please " + << "expect to see incomplete geometries or crashes.\n" + << std::endl; + coutMutex.unlock(); + } } else { - if (!checkTableFromDB(tableName)) - { - THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB!"); - } + // if (!checkTableFromDB(tableName)) + // { + // THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB!"); + // } + checkTableFromDB(tableName, optional); out = getTableRecords_VecVecData(tableName); } return out; } DBRowEntry GMDBManager::getTableFromTableName_VecData( - std::string tableName) + std::string tableName, const bool optional) { DBRowEntry out; if (tableName.empty()) { - std::mutex coutMutex; - coutMutex.lock(); - std::cout << "\t ===> WARNING! The geometry input file does not contain a " - << "table " - << "for the " - << tableName - << "nodes. That means that you are probably using an " - << "old geometry file. Unless you know exactly what you are doing, " - << "please expect to see incomplete geometries or crashes.\n" - << std::endl; - coutMutex.unlock(); + if (m_debug) + { + std::mutex coutMutex; + coutMutex.lock(); + std::cout << "\t ===> WARNING! The geometry input file does not contain a " + << "table " + << "for the " + << tableName + << "nodes. That means that you are probably using an " + << "old geometry file. Unless you know exactly what you are doing, " + << "please expect to see incomplete geometries or crashes.\n" + << std::endl; + coutMutex.unlock(); + } } else { - if (!checkTableFromDB(tableName)) - { - THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB!"); - } + // if (!checkTableFromDB(tableName)) + // { + // THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB!"); + // } + checkTableFromDB(tableName, optional); out = getTableRecords_VecData(tableName); } return out; @@ -1383,8 +1399,26 @@ DBRowsList GMDBManager::getPublishedAXFTable( return getTableRecords_VecVecData(tableName); } -bool GMDBManager::checkTableFromDB(std::string tableName) const { - return m_d->checkTableFromDB_imp(tableName); +bool GMDBManager::checkTableFromDB(std::string tableName, const bool optional) const { + const bool checkTableExistsInDB = m_d->checkTableFromDB_imp(tableName); + if (!checkTableExistsInDB) + { + if (optional) + { + if (m_debug) + { + std::cout << "WARNING! We could not find the table '" << tableName + << "'. However, it has flagged as 'optional', so it is fine not to find it in the DB " + << "if you are running on a DB that has been generated with an earlier version of GeoModel." + << std::endl; + } + } + else + { + THROW_EXCEPTION("ERROR!!! Table name '" + tableName + "' does not exist in the DB! [and it was not set to 'optional']"); + } + } + return checkTableExistsInDB; } // create a user-defined custom table to store the published nodes diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h index d659f787a..1f934e1d3 100644 --- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h +++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h @@ -142,7 +142,8 @@ class ReadGeoModel { template <typename T, class N> std::map<T, N> getPublishedNodes( std::string publisherName = "" /*optional variable*/, - bool doCheckTable = false); + const bool doCheckTable = false /*optional variable*/, + const bool optionalTable = false /*optional variable*/); void printDBTable(const std::string& tableName) { m_dbManager->printAllRecords(tableName); diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp index 006813743..aea205d5b 100644 --- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp +++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp @@ -21,10 +21,8 @@ namespace GeoModelIO { - template <typename T, class N> std::map<T,N> ReadGeoModel::getPublishedNodes(std::string publisherName, bool doCheckTable /*optional variables*/) + template <typename T, class N> std::map<T,N> ReadGeoModel::getPublishedNodes(std::string publisherName, bool doCheckTable /*optional variables*/, bool optionalTable /*optional variables*/) { - - std::map<T, N> mapNodes; std::string keyType = ""; @@ -36,13 +34,13 @@ namespace GeoModelIO { if constexpr ( std::is_same_v<GeoFullPhysVol*, N> ) { if(doCheckTable){ - bool tableExists = m_dbManager->checkTableFromDB("PublishedFullPhysVols_"+publisherName); + bool tableExists = m_dbManager->checkTableFromDB("PublishedFullPhysVols_"+publisherName, optionalTable); if(!tableExists) return mapNodes; } vecRecords = m_dbManager->getPublishedFPVTable( publisherName ); } else if constexpr ( std::is_same_v<GeoAlignableTransform*, N> ) { if(doCheckTable){ - bool tableExists = m_dbManager->checkTableFromDB("PublishedAlignableTransforms_"+publisherName); + bool tableExists = m_dbManager->checkTableFromDB("PublishedAlignableTransforms_"+publisherName, optionalTable); if(!tableExists) return mapNodes; } vecRecords = m_dbManager->getPublishedAXFTable( publisherName ); diff --git a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp index 95f0a56f1..06e6a264b 100644 --- a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp +++ b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp @@ -288,6 +288,30 @@ void ReadGeoModel::loadDB() { // timing: get start time std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); // get all GeoModel nodes from the DB + + /*NOTE: + * The GeoModel toolkit has been developed at the beginning + of the design phase of the ATLAS experiment. + + The original toolkit featured a set of classes and graph nodes: + GeoPhysVol, GeoLogVol, GeoMaterial, and so forth. + + During the latest years, more classes have been added, + and being added, to the toolkit. + + To ensure that adding new classes and nodes to the toolkit does not interfere + with the reading of databases created with an earlier GeoModel version + that did not have those, we now can set an "optional" falg to the + load function, such as 'getTableFrom...()'. + + Please note, a set of GeoModel nodes are **compulsory**: we cannot have a functional + GeoModel tree without, for example, GeoPhysVols, LogVols, GeoElements, GeoMaterials, + and GeoBox (we can't even instanciate the top/root 'World' volume without those!). + For those compulsory classes/nodes, the flag should be set to 'false', + which is the default value. However, for other classes/nodes that can be set to 'true'; + e.g., for shapes like the recently introduced 'GeoTorus' and 'GeoGenericTrap', + and all the new shapes and classes that will be added to the toolkit in the future. + */ // m_shapes = m_dbManager->getTableFromNodeType("GeoShape"); m_physVols = m_dbManager->getTableFromNodeType_String("GeoPhysVol"); m_fullPhysVols = m_dbManager->getTableFromNodeType_String("GeoFullPhysVol"); @@ -318,7 +342,7 @@ void ReadGeoModel::loadDB() { m_shapes_Trap = m_dbManager->getTableFromNodeType_VecVecData("GeoTrap"); m_shapes_Trd = m_dbManager->getTableFromNodeType_VecVecData("GeoTrd"); m_shapes_Tubs = m_dbManager->getTableFromNodeType_VecVecData("GeoTubs"); - m_shapes_Torus = m_dbManager->getTableFromNodeType_VecVecData("GeoTorus"); + m_shapes_Torus = m_dbManager->getTableFromNodeType_VecVecData("GeoTorus", true); // // optional GeoModel node m_shapes_TwistedTrap = m_dbManager->getTableFromNodeType_VecVecData("GeoTwistedTrap"); m_shapes_UnidentifiedShape = m_dbManager->getTableFromNodeType_VecVecData("GeoUnidentifiedShape"); @@ -326,13 +350,13 @@ void ReadGeoModel::loadDB() { m_shapes_Pcon = m_dbManager->getTableFromNodeType_VecVecData("GeoPcon"); m_shapes_Pgon = m_dbManager->getTableFromNodeType_VecVecData("GeoPgon"); m_shapes_SimplePolygonBrep = m_dbManager->getTableFromNodeType_VecVecData("GeoSimplePolygonBrep"); - m_shapes_GenericTrap = m_dbManager->getTableFromNodeType_VecVecData("GeoGenericTrap"); + m_shapes_GenericTrap = m_dbManager->getTableFromNodeType_VecVecData("GeoGenericTrap", true); // optional GeoModel node // shapes' data, when needed by shapes that have variable numbers of build parameters m_shapes_Pcon_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_Pcon_Data"); m_shapes_Pgon_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_Pgon_Data"); m_shapes_SimplePolygonBrep_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_SimplePolygonBrep_Data"); - m_shapes_GenericTrap_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_GenericTrap_Data"); + m_shapes_GenericTrap_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_GenericTrap_Data", true); // optional GeoModel node // shape operators & boolean shapes m_shapes_Shift = m_dbManager->getTableFromNodeType_VecVecData("GeoShapeShift"); -- GitLab From 9b67afc21130509c472c48059a3caa8d8933ea88 Mon Sep 17 00:00:00 2001 From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> Date: Mon, 8 Jul 2024 13:16:37 +0200 Subject: [PATCH 2/3] fix signature, add missing 'const' --- GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp index aea205d5b..1a45473d1 100644 --- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp +++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp @@ -21,7 +21,7 @@ namespace GeoModelIO { - template <typename T, class N> std::map<T,N> ReadGeoModel::getPublishedNodes(std::string publisherName, bool doCheckTable /*optional variables*/, bool optionalTable /*optional variables*/) + template <typename T, class N> std::map<T,N> ReadGeoModel::getPublishedNodes(std::string publisherName, const bool doCheckTable /*optional variables*/, const bool optionalTable /*optional variables*/) { std::map<T, N> mapNodes; std::string keyType = ""; -- GitLab From efa3afc90c9fa0eb72ad3e9e974bc216567e6c2f Mon Sep 17 00:00:00 2001 From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch> Date: Tue, 9 Jul 2024 23:16:40 +0200 Subject: [PATCH 3/3] add include to silence warning in VS Code --- GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp index 1a45473d1..f89704cbf 100644 --- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp +++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.tpp @@ -17,11 +17,13 @@ #include "GeoModelHelpers/variantHelpers.h" #include "GeoModelHelpers/throwExcept.h" - +#include <map> namespace GeoModelIO { - template <typename T, class N> std::map<T,N> ReadGeoModel::getPublishedNodes(std::string publisherName, const bool doCheckTable /*optional variables*/, const bool optionalTable /*optional variables*/) + template <typename T, class N> std::map<T,N> ReadGeoModel::getPublishedNodes(std::string publisherName, + const bool doCheckTable /*optional variables*/, + const bool optionalTable /*optional variables*/) { std::map<T, N> mapNodes; std::string keyType = ""; -- GitLab