From e7e22d85d33a7f5cb0d77a9ea995a7d4bd678af9 Mon Sep 17 00:00:00 2001
From: Riccardo Maria Bianchi <riccardo.maria.bianchi@cern.ch>
Date: Thu, 13 Jun 2024 02:41:52 +0200
Subject: [PATCH] Update Read to load Materials and Elements from the new DB
 schema

---
 .../GeoModelDBManager/src/GMDBManager.cpp     |  6 +-
 .../GeoModelRead/GeoModelRead/ReadGeoModel.h  | 78 +++++++++---------
 GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp  | 81 ++++++++++---------
 3 files changed, 85 insertions(+), 80 deletions(-)

diff --git a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
index c037426df..98b725ad9 100644
--- a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
+++ b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp
@@ -822,9 +822,7 @@ bool GMDBManager::addListOfRecordsToTable(
 
 bool GMDBManager::addListOfRecordsToTable(
     const std::string tableName,
-    const std::vector<
-        DBRowEntry>
-        records) {
+    const DBRowsList records) {
 
     if ( !(hasTableBeenCreatedInDB(tableName)) ) {
         THROW_EXCEPTION("ERROR!!! The DB has no '" << tableName << "' table; probably, the table has not been created in the DB.");
@@ -1747,7 +1745,7 @@ bool GMDBManager::createTables() {
     storeTableColumnNames(tab);
     queryStr = fmt::format(
         "create table {0}({1} integer primary key, "
-        "{2} integer not null REFERENCES Elements(id), "
+        "{2} integer not null, "
         "{3} real )",
         tab[0], tab[1], tab[2], tab[3]);
     rc = execQuery(queryStr);
diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
index e1476035d..d61779b6f 100644
--- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
+++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h
@@ -222,26 +222,26 @@ class ReadGeoModel {
 
     GeoVPhysVol* getRootVolume();
 
-    GeoVPhysVol* buildVPhysVolInstance(const unsigned int id,
-                                       const unsigned int tableId,
-                                       const unsigned int copyNumber);
-    GeoVPhysVol* buildVPhysVol(const unsigned int id,
-                               const unsigned int tableId,
-                               unsigned int logVol_ID = 0);
-
-    GeoLogVol* buildLogVol(const unsigned int id);
+    GeoVPhysVol* buildVPhysVolInstance(const unsigned id,
+                                       const unsigned tableId,
+                                       const unsigned copyNumber);
+    GeoVPhysVol* buildVPhysVol(const unsigned id,
+                               const unsigned tableId,
+                               unsigned logVol_ID = 0);
+
+    GeoLogVol* buildLogVol(const unsigned id);
     
-    GeoShape* buildShape(const unsigned int id,
+    GeoShape* buildShape(const unsigned id,
                          type_shapes_boolean_info* shapes_info_sub);
     GeoShape *buildShapeOperator(const std::string_view shapeType, const DBRowEntry row,
                                  boolean_shapes_operands_info *shapes_info_sub);
 
     GeoMaterial* buildMaterial(const unsigned id);
-    GeoElement* buildElement(const unsigned int id);
-    GeoAlignableTransform* buildAlignableTransform(const unsigned int id);
+    GeoElement* buildElement(const unsigned id);
+    GeoAlignableTransform* buildAlignableTransform(const unsigned id);
     GeoTransform* buildTransform(const unsigned int id);
-    GeoSerialTransformer* buildSerialTransformer(const unsigned int id);
-    TRANSFUNCTION buildFunction(const unsigned int id);
+    GeoSerialTransformer* buildSerialTransformer(const unsigned id);
+    TRANSFUNCTION buildFunction(const unsigned id);
 
     void checkNodePtr(GeoGraphNode* nodePtr, std::string varName = "",
                       std::string funcName = "",
@@ -250,21 +250,21 @@ class ReadGeoModel {
     void volAddHelper(GeoVPhysVol* vol, GeoGraphNode* volChild);
 
     // methods for shapes
-    std::string getShapeType(const unsigned int shapeId);
-    bool isShapeOperator(const unsigned int shapeId);
+    std::string getShapeType(const unsigned shapeId);
+    bool isShapeOperator(const unsigned shapeId);
     bool isShapeOperator(const std::string_view type);
-    bool isShapeBoolean(const unsigned int shapeId);
+    bool isShapeBoolean(const unsigned shapeId);
     bool isShapeBoolean(const std::string_view type);
     void createBooleanShapeOperands(type_shapes_boolean_info* shapes_info_sub);
     void createBooleanShapeOperands(boolean_shapes_operands_info* shapes_info_sub);
-    std::pair<unsigned int, unsigned int> getBooleanShapeOperands(
-        const unsigned int shape);
-    std::tuple<std::string, unsigned int, std::string, unsigned int> getBooleanShapeOperands(
+    std::pair<unsigned, unsigned> getBooleanShapeOperands(
+        const unsigned shape);
+    std::tuple<std::string, unsigned int, std::string, unsigned> getBooleanShapeOperands(
         const std::string_view shapeType, const unsigned shapeId);
     GeoShape* addEmptyBooleanShapeForCompletion(
-        const unsigned int shapeID, type_shapes_boolean_info* shapes_info_sub);
+        const unsigned shapeID, type_shapes_boolean_info* shapes_info_sub);
     GeoShape* getBooleanReferencedShape(
-        const unsigned int shapeID, type_shapes_boolean_info* shapes_info_sub);
+        const unsigned shapeID, type_shapes_boolean_info* shapes_info_sub);
     GeoShape* addEmptyBooleanShapeForCompletion(
         const std::string_view shapeType, const unsigned shapeID, boolean_shapes_operands_info* shapes_info_sub);
     GeoShape* getBooleanReferencedShape(
@@ -273,28 +273,28 @@ class ReadGeoModel {
     // caching methods
     // TODO: perhaps we could merge all those 'isBuiltYYY' methods in a single
     // one, with the GeoModel class as a second argument ? (RMB)
-    bool isBuiltShape(const unsigned int id);
-    bool isBuiltShape_Operators_Shift(const unsigned int id);
-    bool isBuiltShape_Operators_Subtraction(const unsigned int id);
-    bool isBuiltShape_Operators_Intersection(const unsigned int id);
-    bool isBuiltShape_Operators_Union(const unsigned int id);
-    bool isBuiltShape(std::string_view shapeType, const unsigned int id);
-    void storeBuiltShape(const unsigned int, GeoShape* node);
+    bool isBuiltShape(const unsigned id);
+    bool isBuiltShape_Operators_Shift(const unsigned id);
+    bool isBuiltShape_Operators_Subtraction(const unsigned id);
+    bool isBuiltShape_Operators_Intersection(const unsigned id);
+    bool isBuiltShape_Operators_Union(const unsigned id);
+    bool isBuiltShape(std::string_view shapeType, const unsigned id);
+    void storeBuiltShape(const unsigned, GeoShape* node);
     void storeBuiltShape(const std::string_view type, const unsigned id, GeoShape *nodePtr);
-    GeoShape* getBuiltShape(const unsigned int shapeId, std::string_view shapeType = "");
+    GeoShape* getBuiltShape(const unsigned shapeId, std::string_view shapeType = "");
 
-    void storeBuiltShapeOperators_Shift(const unsigned int, GeoShape* node);
-    void storeBuiltShapeOperators_Subtraction(const unsigned int, GeoShape* node);
-    void storeBuiltShapeOperators_Union(const unsigned int, GeoShape* node);
-    void storeBuiltShapeOperators_Intersection(const unsigned int, GeoShape* node);
+    void storeBuiltShapeOperators_Shift(const unsigned, GeoShape* node);
+    void storeBuiltShapeOperators_Subtraction(const unsigned, GeoShape* node);
+    void storeBuiltShapeOperators_Union(const unsigned, GeoShape* node);
+    void storeBuiltShapeOperators_Intersection(const unsigned, GeoShape* node);
 
-    bool isBuiltTransform(const unsigned int id);
+    bool isBuiltTransform(const unsigned id);
     void storeBuiltTransform(GeoTransform* node);
-    GeoTransform* getBuiltTransform(const unsigned int id);
+    GeoTransform* getBuiltTransform(const unsigned id);
 
-    bool isBuiltAlignableTransform(const unsigned int id);
+    bool isBuiltAlignableTransform(const unsigned id);
     void storeBuiltAlignableTransform(GeoAlignableTransform* node);
-    GeoAlignableTransform* getBuiltAlignableTransform(const unsigned int id);
+    GeoAlignableTransform* getBuiltAlignableTransform(const unsigned id);
 
     // void storeVPhysVol(const unsigned int id, const unsigned int tableId,
     // const unsigned int copyNumber, GeoGraphNode* node); GeoGraphNode*
@@ -400,11 +400,13 @@ class ReadGeoModel {
     std::vector<std::vector<std::string>> m_identifierTags;
     std::vector<std::vector<std::string>> m_serialTransformers;
     std::vector<std::vector<std::string>> m_nameTags;
-    std::vector<std::vector<std::string>> m_materials;
+    // std::vector<std::vector<std::string>> m_materials;
     // std::vector<std::vector<std::string>> m_elements;
     std::vector<std::vector<std::string>> m_shapes;
 
     DBRowsList m_elements;
+    DBRowsList m_materials;
+    DBRowsList m_materials_Data;
     DBRowsList m_logVols;
     DBRowsList m_allchildren;
 
diff --git a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
index e64f19254..0f14d5f98 100644
--- a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
+++ b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp
@@ -282,11 +282,6 @@ void ReadGeoModel::loadDB() {
     std::chrono::system_clock::time_point start = std::chrono::system_clock::now();  
     // get all GeoModel nodes from the DB
     // m_shapes = m_dbManager->getTableFromNodeType("GeoShape");
-    m_elements = m_dbManager->getTableFromNodeType_VecVecData("GeoElement");
-    GeoModelHelpers::variantHelper::printStdVectorVariants(m_elements[0]);
-    GeoModelHelpers::variantHelper::getFromVariant_Type(m_elements[0][3]);
-
-    m_materials = m_dbManager->getTableFromNodeType_String("GeoMaterial");
     m_physVols = m_dbManager->getTableFromNodeType_String("GeoPhysVol");
     m_fullPhysVols = m_dbManager->getTableFromNodeType_String("GeoFullPhysVol");
     m_transforms = m_dbManager->getTableFromNodeType_String("GeoTransform");
@@ -304,6 +299,9 @@ void ReadGeoModel::loadDB() {
     // containers to store data that have been moved to the new DB schema
     m_functions = m_dbManager->getTableFromNodeType_VecVecData("Function");
     m_logVols = m_dbManager->getTableFromNodeType_VecVecData("GeoLogVol");
+    m_elements = m_dbManager->getTableFromNodeType_VecVecData("GeoElement");
+    m_materials = m_dbManager->getTableFromNodeType_VecVecData("GeoMaterial");
+    m_materials_Data = m_dbManager->getTableFromTableName_VecVecData("Materials_Data");
 
     // shapes from the new DB schema
     m_shapes_Box = m_dbManager->getTableFromNodeType_VecVecData("GeoBox");
@@ -955,7 +953,7 @@ void ReadGeoModel::buildAllMaterials() {
     size_t nSize = m_materials.size();
     m_memMapMaterials.reserve(nSize);
     for (unsigned int ii = 0; ii < nSize; ++ii) {
-        const unsigned int nodeID = std::stoi(m_materials[ii][0]);
+        const unsigned nodeID = GeoModelHelpers::variantHelper::getFromVariant_Int(m_materials[ii][0], "MaterialElement:ID");
         buildMaterial(nodeID);  // nodes' IDs start from 1
     }
     if (nSize > 0)
@@ -1849,7 +1847,7 @@ GeoVPhysVol* ReadGeoModel::getRootVolume() {
     return root;
 }
 
-GeoMaterial* ReadGeoModel::buildMaterial(const unsigned int id) {
+GeoMaterial* ReadGeoModel::buildMaterial(const unsigned id) {
     if (isBuiltMaterial(id)) {
         return getBuiltMaterial(id);
     }
@@ -1861,49 +1859,56 @@ GeoMaterial* ReadGeoModel::buildMaterial(const unsigned int id) {
     }
 
     // OLD
-    std::vector<std::string> values = m_materials[id - 1];
-    const unsigned int matId = std::stoi(values[0]);
-    const std::string matName = values[1];
-    double matDensity = std::stod(values[2]);
-    std::string matElements = values[3];
+    // std::vector<std::string> values = m_materials[id - 1];
+    // const unsigned int matId = std::stoi(values[0]);
+    // const std::string matName = values[1];
+    // double matDensity = std::stod(values[2]);
+    // std::string matElements = values[3];
 
     // NEW
-    // DBRowEntry values = m_materials[id - 1];
-    // const unsigned int matId = GeoModelHelpers::variantHelper::getFromVariant_Int(values[0], "Material:id");
-    // const std::string matName = GeoModelHelpers::variantHelper::getFromVariant_String(values[0], "Material:matName");
-    // const double matDensity = GeoModelHelpers::variantHelper::getFromVariant_Int(values[0], "Material:matDensity");
-    // const std::string matElements = GeoModelHelpers::variantHelper::getFromVariant_String(values[0], "Material:matElements");
+    DBRowEntry values = m_materials[id - 1];
+    const unsigned int matId = GeoModelHelpers::variantHelper::getFromVariant_Int(values[0], "Material:id");
+    const std::string matName = GeoModelHelpers::variantHelper::getFromVariant_String(values[1], "Material:matName");
+    const double matDensity = GeoModelHelpers::variantHelper::getFromVariant_Double(values[2], "Material:matDensity");
+    const unsigned dataStart = GeoModelHelpers::variantHelper::getFromVariant_Int(values[3], "Material:dataStart");
+    const unsigned dataEnd = GeoModelHelpers::variantHelper::getFromVariant_Int(values[3], "Material:dataEnd");
 
-    if (m_loglevel >= 2) {
-        muxCout.lock();
-        std::cout << "\tMaterial - ID:" << matId << ", name:" << matName
-                  << ", density:" << matDensity << " ( "
-                  << matDensity / (SYSTEM_OF_UNITS::g / SYSTEM_OF_UNITS::cm3)
-                  << "[g/cm3] )"
-                  << ", elements:" << matElements;
-        muxCout.unlock();
-    }
+
+    // debug msg
+    // if (m_loglevel >= 2) {
+    //     muxCout.lock();
+    //     std::cout << "\tMaterial - ID:" << matId << ", name:" << matName
+    //               << ", density:" << matDensity << " ( "
+    //               << matDensity / (SYSTEM_OF_UNITS::g / SYSTEM_OF_UNITS::cm3)
+    //               << "[g/cm3] )"
+    //               << ", elements:" << matElements;
+    //     muxCout.unlock();
+    // }
 
     GeoMaterial* mat = new GeoMaterial(matName, matDensity);
 
+    DBRowsList matElements(m_materials_Data.begin() + (dataStart-1),
+                           m_materials_Data.begin() + (dataEnd) );
+
     if (matElements.size() > 0) {
-        // get parameters from DB string
-        const std::vector<std::string> elements = splitString(matElements, ';');
-        for (auto& par : elements) {
-            if (m_loglevel >= 2) {
-                muxCout.lock();
-                std::cout << "par: " << par << std::endl;
-                muxCout.unlock();
-            }
-            std::vector<std::string> vars = splitString(par, ':');
-            const unsigned int elId = std::stoi(vars[0]);
-            double elFraction = std::stod(vars[1]);
+        // get parameters from DB
+
+        // const std::vector<std::string> elements = splitString(matElements, ';');
+        for (const auto& row : matElements) {
+        //     if (m_loglevel >= 2) {
+        //         muxCout.lock();
+        //         std::cout << "par: " << par << std::endl;
+        //         muxCout.unlock();
+        //     }
+        //     std::vector<std::string> vars = splitString(par, ':');
+            const unsigned elId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[1], "MatElement:id");
+            double elFraction = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "MatElement:fraction");
             //      GeoElement* el = buildElement(elId);
             GeoElement* el = getBuiltElement(elId);
             mat->add(el, elFraction);
         }
         mat->lock();
-    }
+    } 
     storeBuiltMaterial(mat);
     return mat;
 }
-- 
GitLab