diff --git a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h index 22949c4618370ff990e74ea518f16add513124e4..2f639d8064c2f452d99acf77f9e7a2d1a8747e94 100644 --- a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h +++ b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h @@ -326,6 +326,18 @@ class GMDBManager { // tableColTypes, const std::vector<std::vector<std::string>> &records ); // // not used anymore!! + bool addListOfRecordsToTable( + const std::string tableName, + const std::vector<std::vector<std::string>> records); + bool addListOfRecordsToTable( + const std::string tableName, + const std::vector< + std::vector<std::variant<int, long, float, double, std::string>>> + records); + // bool addListOfRecordsToTableOld(const QString tableName, const + // std::vector<QStringList> records); // for the old SQlite only + + private: /** * @brief Create all the default DB tables. @@ -341,17 +353,6 @@ class GMDBManager { const std::string nodeType, const std::type_info *keyType); - bool addListOfRecordsToTable( - const std::string tableName, - const std::vector<std::vector<std::string>> records); - bool addListOfRecordsToTable( - const std::string tableName, - const std::vector< - std::vector<std::variant<int, long, float, double, std::string>>> - records); - // bool addListOfRecordsToTableOld(const QString tableName, const - // std::vector<QStringList> records); // for the old SQlite only - void addDBversion(std::string version); // void loadTestData(); // for debug only diff --git a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp index dcc7a00bcf711d758b1dd08e2ae74edabe356ebe..15dcf7c0076f73b14d86cb3d370dfa0dbaf7c643 100644 --- a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp +++ b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp @@ -743,6 +743,7 @@ bool GMDBManager::addListOfRecords( bool GMDBManager::addListOfRecordsToTable( const std::string tableName, const std::vector<std::vector<std::string>> records) { + // get table columns and format them for query std::string tableColString = "(" + GeoModelIO::CppHelper::joinVectorStrings(m_tableNames.at(tableName), ", ") + ")"; @@ -791,6 +792,7 @@ bool GMDBManager::addListOfRecordsToTable( const std::vector< std::vector<std::variant<int, long, float, double, std::string>>> records) { + if (records.size() > 0) { // get table columns and format them for query std::string tableColString = "(" + GeoModelIO::CppHelper::joinVectorStrings(m_tableNames.at(tableName), ", ") + ")"; @@ -798,7 +800,8 @@ bool GMDBManager::addListOfRecordsToTable( unsigned int nRecords = records.size(); std::cout << "Info: number of " << tableName - << " records to dump into the DB:" << nRecords << std::endl; + << " records to dump into the DB: " << nRecords << std::endl; + // preparing the SQL query std::string sql = @@ -851,6 +854,8 @@ bool GMDBManager::addListOfRecordsToTable( return false; } return true; + } + return false; } @@ -860,6 +865,7 @@ bool GMDBManager::addRecordsToTable( const std::vector<std::variant<int, long, float, double, std::string>> records) { + if (records.size() > 0) { // get table columns and format them for query std::string tableColString = "(" + GeoModelIO::CppHelper::joinVectorStrings(m_tableNames.at(tableName), ", ") + ")"; @@ -867,8 +873,9 @@ bool GMDBManager::addRecordsToTable( std::cout << "tableColString:" << tableColString << std::endl; unsigned int nRecords = records.size(); + std::cout << "Info: number of " << tableName - << " records to dump into the DB:" << nRecords << std::endl; + << " records to dump into the DB: " << nRecords << std::endl; // preparing the SQL query std::string sql = @@ -939,6 +946,8 @@ bool GMDBManager::addRecordsToTable( return false; } return true; + } + return false; } @@ -1540,8 +1549,7 @@ bool GMDBManager::createTables() { tab.clear(); - // create a table to store information about the 'root' volume (also - // known as the 'world' volume) + // create a table to store the numeric data used in Functions tableName = "FuncExprData"; tab.push_back(tableName); tab.push_back("id"); @@ -1552,6 +1560,20 @@ bool GMDBManager::createTables() { tab[0], tab[1], tab[2]); rc = execQuery(queryStr); tab.clear(); + + // create a table to store the numeric data used in GeoPcon shapes + tableName = "Shapes_Pcon_Data"; + tab.push_back(tableName); + tab.push_back("id"); + tab.push_back("ZPos"); + tab.push_back("ZRmin"); + tab.push_back("ZRmax"); + storeTableColumnNames(tab); + queryStr = fmt::format( + "create table {0}({1} integer primary key, {2} real, {3} real, {4} real )", + tab[0], tab[1], tab[2], tab[3], tab[4]); + rc = execQuery(queryStr); + tab.clear(); // create a table to store information about the 'root' volume (also @@ -1681,6 +1703,68 @@ bool GMDBManager::createTables() { } tab.clear(); + // Shapes-Box table + // ID, 'Box', XHalfLength, YHalfLength, ZHalfLength + geoNode = "GeoBox"; + tableName = "Shapes_Box"; + m_childType_tableName[geoNode] = tableName; + tab.push_back(tableName); + tab.push_back("id"); + tab.push_back("XHalfLength"); + tab.push_back("YHalfLength"); + tab.push_back("ZHalfLength"); + storeTableColumnNames(tab); + queryStr = fmt::format( + "create table {0}({1} integer primary key, {2} varchar, {3} real, {4} real, {5} real " + "varchar)", + tab[0], tab[1], tab[2], tab[3], tab[4], tab[5]); + if (0 == (rc = execQuery(queryStr))) { + storeNodeType(geoNode, tableName); + } + tab.clear(); + + // Shapes-Box table + // ID, 'Box', XHalfLength, YHalfLength, ZHalfLength + geoNode = "GeoTube"; + tableName = "Shapes_Tube"; + m_childType_tableName[geoNode] = tableName; + tab.push_back(tableName); + tab.push_back("id"); + tab.push_back("RMin"); + tab.push_back("RMax"); + tab.push_back("ZHalfLength"); + storeTableColumnNames(tab); + queryStr = fmt::format( + "create table {0}({1} integer primary key, {2} varchar, {3} real, {4} real, {5} real " + "varchar)", + tab[0], tab[1], tab[2], tab[3], tab[4], tab[5]); + if (0 == (rc = execQuery(queryStr))) { + storeNodeType(geoNode, tableName); + } + tab.clear(); + + // Shapes-Box table + // ID, 'Box', XHalfLength, YHalfLength, ZHalfLength + geoNode = "GeoPcon"; + tableName = "Shapes_Pcon"; + m_childType_tableName[geoNode] = tableName; + tab.push_back(tableName); + tab.push_back("id"); + tab.push_back("SPhi"); + tab.push_back("DPhi"); + tab.push_back("NZPlanes"); + tab.push_back("dataStart"); + tab.push_back("dataEnd"); + storeTableColumnNames(tab); + queryStr = fmt::format( + "create table {0}({1} integer primary key, {2} varchar, {3} real, {4} real, {5} integer, {6} integer, {7} integer " + "varchar)", + tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7]); + if (0 == (rc = execQuery(queryStr))) { + storeNodeType(geoNode, tableName); + } + tab.clear(); + // SerialDenominators table geoNode = "GeoSerialDenominator"; tableName = "SerialDenominators"; diff --git a/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h b/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h index 0866360b41c3d4898a6d408c32f1cfb9e32c81e8..01d26f879e3f8994d181ed70efdea2a3f41f447c 100644 --- a/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h +++ b/GeoModelIO/GeoModelWrite/GeoModelWrite/WriteGeoModel.h @@ -178,6 +178,8 @@ class WriteGeoModel : public GeoNodeAction { const double &elA); unsigned int storeObj(const GeoShape *pointer, const std::string &type, const std::string ¶meters); + unsigned int storeObj(const GeoShape *pointer, const std::string &type, + const std::vector<std::variant<int, long, float, double, std::string>> ¶meters); unsigned int storeObj(const GeoLogVol *pointer, const std::string &name, const unsigned int &shapeId, const unsigned int &materialId); @@ -230,6 +232,10 @@ class WriteGeoModel : public GeoNodeAction { const unsigned int &copies); unsigned int addShape(const std::string &type, const std::string ¶meters); + unsigned int addShape(const std::string &type, + const std::vector<std::variant<int, long, float, double, std::string>> ¶meters); + std::vector<unsigned> addShapeData(const std::string type, + const std::vector<std::variant<int, long, float, double, std::string>> &shapeData); unsigned int addSerialDenominator(const std::string &baseName); unsigned int addSerialIdentifier(const int &baseId); unsigned int addIdentifierTag(const int &identifier); @@ -294,6 +300,9 @@ class WriteGeoModel : public GeoNodeAction { // moved to an Utility class, so we can use it // from TransFunctionRecorder as well. std::string getShapeParameters(const GeoShape *); + std::pair<std::vector<std::variant<int, long, float, double, std::string>>, + std::vector<std::variant<int, long, float, double, std::string>>> + getShapeParametersV(const GeoShape *, const bool data = false); std::string getGeoTypeFromVPhysVol(const GeoVPhysVol *vol); @@ -342,6 +351,10 @@ class WriteGeoModel : public GeoNodeAction { std::vector<std::vector<std::string>> m_serialTransformers; std::vector<std::vector<std::string>> m_nameTags; std::vector<std::vector<std::string>> m_shapes; + std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Box; + std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Tube; + std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pcon; + std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_shapes_Pcon_Data; // std::vector<std::vector<std::string>> m_functions; std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_functions; // operators used in Function's expression diff --git a/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp b/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp index 14338e03c8593f2fb4ee132081380ed6ab768bdd..f7af8b0e8d6a4e398ac808329415dd450219e998 100644 --- a/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp +++ b/GeoModelIO/GeoModelWrite/src/WriteGeoModel.cpp @@ -699,11 +699,43 @@ unsigned int WriteGeoModel::storeShape(const GeoShape* shape) { // LArCustomShape is deprecated. Write it out as a GeoUnidentifiedShape; if (shapeType == "CustomShape") shapeType = "UnidentifiedShape"; + const std::set<std::string> shapesNewDB{"Box", "Tube"}; + // get shape parameters - std::string shapePars = getShapeParameters(shape); + if (std::count(shapesNewDB.begin(), shapesNewDB.end(), shapeType)) + { + std::pair<std::vector<std::variant<int, long, float, double, std::string>>, + std::vector<std::variant<int, long, float, double, std::string>>> + shapePair = getShapeParametersV(shape); + + std::vector<std::variant<int, long, float, double, std::string>> shapePars = shapePair.first; + std::vector<std::variant<int, long, float, double, std::string>> shapeData = shapePair.second; + + if (shapeData.size() > 0) + { + // Store the Function's numbers + std::vector<unsigned> dataRows = addShapeData(shapeType, shapeData); + unsigned dataStart = dataRows[0]; + unsigned dataEnd = dataRows[1]; + shapePars.push_back(dataStart); + shapePars.push_back(dataEnd); + } + // DEBUG MSGS + // std::cout << "shape: " << shapeType << std::endl; + // GeoModelIO::CppHelper::printStdVectorVariants(shapePars); + // std::cout << std::endl; + // store the shape in the DB and returns the ID + return storeObj(shape, shapeType, shapePars); + + } + else + { + std::string shapePars = getShapeParameters(shape); // store the shape in the DB and returns the ID return storeObj(shape, shapeType, shapePars); + } + return 1; // we should not be here } //______________________________________________________________________ @@ -925,6 +957,56 @@ void WriteGeoModel::handleReferencedVPhysVol(const GeoVPhysVol* vol) { m_unconnectedTree = false; } +// Get shape parameters +std::pair<std::vector<std::variant<int, long, float, double, std::string>>, + std::vector<std::variant<int, long, float, double, std::string>>> +WriteGeoModel::getShapeParametersV(const GeoShape *shape, const bool data) +{ + const std::string shapeType = shape->type(); + + std::vector<std::variant<int, long, float, double, std::string>> shapePars; + std::vector<std::variant<int, long, float, double, std::string>> shapeData; + std::pair<std::vector<std::variant<int, long, float, double, std::string>>, std::vector<std::variant<int, long, float, double, std::string>>> shapePair; + + if ("Box" == shapeType) + { + const GeoBox *box = dynamic_cast<const GeoBox *>(shape); + shapePars.push_back(box->getXHalfLength()); + shapePars.push_back(box->getYHalfLength()); + shapePars.push_back(box->getZHalfLength()); + } + else if ("Tube" == shapeType) + { + const GeoTube *tube = dynamic_cast<const GeoTube *>(shape); + shapePars.push_back(tube->getRMin()); + shapePars.push_back(tube->getRMax()); + shapePars.push_back(tube->getZHalfLength()); + } + else if (shapeType == "Pcon") + { + const GeoPcon* shapeIn = dynamic_cast<const GeoPcon*>(shape); + shapePars.push_back(shapeIn->getSPhi()); + shapePars.push_back(shapeIn->getDPhi()); + // get number of Z planes and loop over them + const int nZplanes = shapeIn->getNPlanes(); + shapePars.push_back(nZplanes); + for (int i = 0; i < nZplanes; ++i) { + shapeData.push_back(shapeIn->getZPlane(i)); + shapeData.push_back(shapeIn->getRMinPlane(i)); + shapeData.push_back(shapeIn->getRMaxPlane(i)); + } + } + else + { + std::cout << "\n\tGeoModelWrite -- WARNING!!! - Shape '" << shapeType + << "' is not supported in the new DB format, yet.\n\n"; + // CppHelper::printStdVectorStrings(m_objectsNotPersistified); + } + + shapePair.first = shapePars; + shapePair.second = shapeData; + return shapePair; +} // Get shape parameters std::string WriteGeoModel::getShapeParameters(const GeoShape* shape) { const std::string shapeType = shape->type(); @@ -932,16 +1014,17 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape) { std::string shapePars = ""; std::vector<std::string> pars; - if (shapeType == "Box") { - const GeoBox* box = dynamic_cast<const GeoBox*>(shape); - pars.push_back("XHalfLength=" + - CppHelper::to_string_with_precision(box->getXHalfLength())); - pars.push_back("YHalfLength=" + - CppHelper::to_string_with_precision(box->getYHalfLength())); - pars.push_back("ZHalfLength=" + - CppHelper::to_string_with_precision(box->getZHalfLength())); - shapePars = joinVectorStrings(pars, ";"); - } else if (shapeType == "Cons") { + if (false) {} + // if (shapeType == "Box") { + // const GeoBox* box = dynamic_cast<const GeoBox*>(shape); + // pars.push_back("XHalfLength=" + + // CppHelper::to_string_with_precision(box->getXHalfLength())); + // pars.push_back("YHalfLength=" + + // CppHelper::to_string_with_precision(box->getYHalfLength())); + // pars.push_back("ZHalfLength=" + + // CppHelper::to_string_with_precision(box->getZHalfLength())); + // } + else if (shapeType == "Cons") { const GeoCons* shapeIn = dynamic_cast<const GeoCons*>(shape); pars.push_back("RMin1=" + CppHelper::to_string_with_precision(shapeIn->getRMin1())); @@ -982,22 +1065,24 @@ std::string WriteGeoModel::getShapeParameters(const GeoShape* shape) { pars.push_back("Theta=" + CppHelper::to_string_with_precision(shapeIn->getTheta())); pars.push_back("Phi=" + CppHelper::to_string_with_precision(shapeIn->getPhi())); - } else if (shapeType == "Pcon") { - const GeoPcon* shapeIn = dynamic_cast<const GeoPcon*>(shape); - pars.push_back("SPhi=" + CppHelper::to_string_with_precision(shapeIn->getSPhi())); - pars.push_back("DPhi=" + CppHelper::to_string_with_precision(shapeIn->getDPhi())); - // get number of Z planes and loop over them - const int nZplanes = shapeIn->getNPlanes(); - pars.push_back("NZPlanes=" + std::to_string(nZplanes)); // INT - for (int i = 0; i < nZplanes; ++i) { - pars.push_back("ZPos=" + - CppHelper::to_string_with_precision(shapeIn->getZPlane(i))); - pars.push_back("ZRmin=" + - CppHelper::to_string_with_precision(shapeIn->getRMinPlane(i))); - pars.push_back("ZRmax=" + - CppHelper::to_string_with_precision(shapeIn->getRMaxPlane(i))); - } - } else if (shapeType == "Pgon") { + } + // else if (shapeType == "Pcon") { + // const GeoPcon* shapeIn = dynamic_cast<const GeoPcon*>(shape); + // pars.push_back("SPhi=" + CppHelper::to_string_with_precision(shapeIn->getSPhi())); + // pars.push_back("DPhi=" + CppHelper::to_string_with_precision(shapeIn->getDPhi())); + // // get number of Z planes and loop over them + // const int nZplanes = shapeIn->getNPlanes(); + // pars.push_back("NZPlanes=" + std::to_string(nZplanes)); // INT + // for (int i = 0; i < nZplanes; ++i) { + // pars.push_back("ZPos=" + + // CppHelper::to_string_with_precision(shapeIn->getZPlane(i))); + // pars.push_back("ZRmin=" + + // CppHelper::to_string_with_precision(shapeIn->getRMinPlane(i))); + // pars.push_back("ZRmax=" + + // CppHelper::to_string_with_precision(shapeIn->getRMaxPlane(i))); + // } + // } + else if (shapeType == "Pgon") { const GeoPgon* shapeIn = dynamic_cast<const GeoPgon*>(shape); pars.push_back("SPhi=" + CppHelper::to_string_with_precision(shapeIn->getSPhi())); pars.push_back("DPhi=" + CppHelper::to_string_with_precision(shapeIn->getDPhi())); @@ -1335,13 +1420,27 @@ unsigned int WriteGeoModel::storeObj(const GeoElement* pointer, } unsigned int WriteGeoModel::storeObj(const GeoShape* pointer, - const std::string& name, + const std::string& shapeName, const std::string& parameters) { std::string address = getAddressStringFromPointer(pointer); unsigned int shapeId; if (!isAddressStored(address)) { - shapeId = addShape(name, parameters); + shapeId = addShape(shapeName, parameters); + storeAddress(address, shapeId); + } else { + shapeId = getStoredIdFromAddress(address); + } + return shapeId; +} +unsigned int WriteGeoModel::storeObj(const GeoShape* pointer, + const std::string& shapeName, + const std::vector<std::variant<int, long, float, double, std::string>>& parameters) { + std::string address = getAddressStringFromPointer(pointer); + + unsigned int shapeId; + if (!isAddressStored(address)) { + shapeId = addShape(shapeName, parameters); storeAddress(address, shapeId); } else { shapeId = getStoredIdFromAddress(address); @@ -1649,6 +1748,29 @@ std::vector<unsigned> WriteGeoModel::addExprData( return dataRows; } +std::vector<unsigned> WriteGeoModel::addShapeData(const std::string type, + const std::vector<std::variant<int, long, float, double, std::string>>& shapeData) +{ + std::vector<std::vector<std::variant<int, long, float, double, std::string>>> *container = nullptr; + + if ("Pcon" == type) { + container = &m_shapes_Pcon_Data; + } + + const unsigned dataStart = container->size(); + + unsigned dataEnd = addRecord(container, shapeData); + // ^ index of pushed element = size after pushing, to + // match ID starting at 1 in the DB + + std::vector<unsigned> dataRows; + dataRows.push_back(dataStart); + dataRows.push_back(dataEnd); + return dataRows; +} + + + unsigned int WriteGeoModel::addMaterial(const std::string& name, const double& density, const std::string& elements) { @@ -2038,6 +2160,31 @@ unsigned int WriteGeoModel::addShape(const std::string& type, values.push_back(parameters); return addRecord(container, values); } +unsigned int WriteGeoModel::addShape(const std::string &type, + const std::vector<std::variant<int, long, float, double, std::string>> ¶meters) +{ + std::vector<std::vector<std::variant<int, long, float, double, std::string>>> *container = nullptr; + if ("Box" == type) + { + container = &m_shapes_Box; + } + else if ("Tube" == type) + { + container = &m_shapes_Tube; + } + else if ("Pcon" == type) + { + container = &m_shapes_Pcon; + } + else + { + std::cout << "ERROR! Shape type '" << type + << "' still needs to be ported to the new DB schema. Ask to 'geomodel-developers@cern.ch." + << std::endl; + exit(EXIT_FAILURE); + } + return addRecord(container, parameters); +} unsigned int WriteGeoModel::addPhysVol(const unsigned int& logVolId, const unsigned int& /*parentPhysVolId*/, @@ -2130,7 +2277,6 @@ void WriteGeoModel::saveToDB(std::vector<GeoPublisher*>& publishers) { m_dbManager->addListOfRecords("GeoTransform", m_transforms); m_dbManager->addListOfRecords("Function", m_functions); m_dbManager->addListOfRecords("GeoSerialTransformer", m_serialTransformers); - m_dbManager->addListOfRecords("GeoShape", m_shapes); m_dbManager->addListOfRecords("GeoSerialDenominator", m_serialDenominators); m_dbManager->addListOfRecords("GeoSerialIdentifier", m_serialIdentifiers); m_dbManager->addListOfRecords("GeoIdentifierTag", m_identifierTags); @@ -2140,6 +2286,16 @@ void WriteGeoModel::saveToDB(std::vector<GeoPublisher*>& publishers) { m_dbManager->addRecordsToTable("FuncExprData", m_exprData); + m_dbManager->addListOfRecords("GeoShape", m_shapes); // old version, with shape's parameters as trings + m_dbManager->addListOfRecords("GeoBox", m_shapes_Box); // new version, with shape's parameters as numbers + m_dbManager->addListOfRecords("GeoTube", m_shapes_Tube); // new version, with shape's parameters as numbers + m_dbManager->addListOfRecords("GeoPcon", m_shapes_Pcon); // new version, with shape's parameters as numbers + + // store shapes' data // TODO: maybe this should be encapsulated with shapes? + // To do this, I moved addListOfRecordsToTable() from private to public, maybe I could add a method to store shapes with data and put back that into private + + m_dbManager->addListOfRecordsToTable("Shapes_Pcon_Data", m_shapes_Pcon_Data); // new version, with shape's parameters as numbers + m_dbManager->addListOfChildrenPositions(m_childrenPositions); m_dbManager->addRootVolume(m_rootVolume);