diff --git a/GeoModelIO/GeoModelCppHelpers/CMakeLists.txt b/GeoModelIO/GeoModelCppHelpers/CMakeLists.txt index f56a3ad5349bcaa59699ee83327433a92097a247..9a8262afab2138f94ae33dee72ce09959448021e 100644 --- a/GeoModelIO/GeoModelCppHelpers/CMakeLists.txt +++ b/GeoModelIO/GeoModelCppHelpers/CMakeLists.txt @@ -11,7 +11,7 @@ file( GLOB HEADERS GeoModelCppHelpers/*.h ) # Set up the library. add_library( GeoModelCppHelpers SHARED ${HEADERS} ${SOURCES} ) # target_link_libraries( GeoModelCppHelpers PUBLIC -# GeoModelRead GeoModelWrite ) +# GeoModelHelpers ) # We link those to carry on the needed libs when including GeoModelCppHelpers, # even if the latter is headers only diff --git a/GeoModelIO/GeoModelCppHelpers/GeoModelCppHelpers/GMCppHelpers.h b/GeoModelIO/GeoModelCppHelpers/GeoModelCppHelpers/GMCppHelpers.h index 982bfcc6e5f473ba74274e05407c7dd05e668068..f928076a23b60da5967e7b05a704c03dc02200d4 100644 --- a/GeoModelIO/GeoModelCppHelpers/GeoModelCppHelpers/GMCppHelpers.h +++ b/GeoModelIO/GeoModelCppHelpers/GeoModelCppHelpers/GMCppHelpers.h @@ -13,11 +13,15 @@ #ifndef GMCPPHelper_H #define GMCPPHelper_H + // C++ includes #include <cstdlib> // EXIT_FAILURE #include <fstream> #include <string> #include <sstream> +#include <iostream> +#include <variant> +#include <type_traits> namespace GeoModelIO { @@ -74,25 +78,97 @@ namespace GeoModelIO { return val == NULL ? std::string("") : std::string(val); } - static void printStdVectorVariants(const std::vector<std::variant<int, long, float, double, std::string>> vec) - { - for (const auto &item : vec) - { - if (std::holds_alternative<int>(item)) - std::cout << std::get<int>(item); // INT - else if (std::holds_alternative<long>(item)) - std::cout << std::get<long>(item); - else if (std::holds_alternative<float>(item)) - std::cout << std::get<float>(item); - else if (std::holds_alternative<double>(item)) - std::cout << std::get<double>(item); - else if (std::holds_alternative<std::string>(item)) - std::cout << std::get<std::string>(item); - - std::cout << ", "; - } - std::cout << std::endl; - } + // static void printStdVectorVariants(const std::vector<std::variant<int, long, float, double, std::string>> vec) + // { + // for (const auto &item : vec) + // { + // if (std::holds_alternative<int>(item)) + // std::cout << std::get<int>(item); // INT + // else if (std::holds_alternative<long>(item)) + // std::cout << std::get<long>(item); + // else if (std::holds_alternative<float>(item)) + // std::cout << std::get<float>(item); + // else if (std::holds_alternative<double>(item)) + // std::cout << std::get<double>(item); + // else if (std::holds_alternative<std::string>(item)) + // std::cout << std::get<std::string>(item); + + // std::cout << ", "; + // } + // std::cout << std::endl; + // } + + // static std::string getFromVariant_String(const std::variant<int, long, float, double, std::string> &record, std::string_view logMsg = "") + // { + // std::string_view type{"string"}; + // std::string ret; + // try + // { + // ret = std::get<std::string>(record); + // } + // catch (std::bad_variant_access const &ex) + // { + // std::cout << ex.what() << ": '" << logMsg << "' is not a 'string'!\n"; + // } + // return ret; + // } + // static int getFromVariant_Int(const std::variant<int, long, float, double, std::string> &record, std::string_view logMsg = "") + // { + // std::string_view type{"int"}; + // int ret; + + // try + // { + // ret = std::get<int>(record); + // } + // catch (std::bad_variant_access const &ex) + // { + // std::cout << ex.what() << ": '" << logMsg << "' is not a '" << type << "'!\n"; + // } + // return ret; + // } + // static int getFromVariant_Double(const std::variant<int, long, float, double, std::string> &record, std::string_view logMsg = "") + // { + // std::string_view type{"double"}; + // double ret; + // try + // { + // ret = std::get<double>(record); + // } + // catch (std::bad_variant_access const &ex) + // { + // std::cout << ex.what() << ": '" << logMsg << "' is not a '" << type << "'!\n"; + // } + // return ret; + // } + // static std::string getFromVariant_Type(const std::variant<int, long, float, double, std::string> &record) + // { + // std::string type; + // if (std::holds_alternative<int>(record)) + // { + // type = "int"; + // } + // else if (std::holds_alternative<long>(record)) + // { + // type = "long"; + // } + // else if (std::holds_alternative<float>(record)) + // { + // type = "float"; + // } + // else if (std::holds_alternative<double>(record)) + // { + // type = "double"; + // } + // else if (std::holds_alternative<std::string>(record)) + // { + // type = "string"; + // } else { + // type = "UNKOWN"; + // } + // std::cout << "Variant is of type '" << type << "'" << std::endl; + // return type; + // } }; } // namespace GeoModelIO diff --git a/GeoModelIO/GeoModelRead/CMakeLists.txt b/GeoModelIO/GeoModelRead/CMakeLists.txt index 904b659790da82ef70b2fda58fc6fdd750099c5a..5db6153b0611fde1effdb51928372aec6aae27c8 100644 --- a/GeoModelIO/GeoModelRead/CMakeLists.txt +++ b/GeoModelIO/GeoModelRead/CMakeLists.txt @@ -12,7 +12,7 @@ file( GLOB HEADERS GeoModelRead/*.h GeoModelRead/*.tpp ) # Set up the library. add_library( GeoModelRead SHARED ${HEADERS} ${SOURCES} ) target_link_libraries( GeoModelRead PUBLIC -GeoModelKernel GeoModelDBManager TFPersistification ) +GeoModelKernel GeoModelDBManager TFPersistification GeoModelCppHelpers GeoModelHelpers ) target_include_directories( GeoModelRead PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) diff --git a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h index 717c2808d7129373beaac98bb0218efda489d54a..c689d3d598793027962c1350342d7aa3d0669887 100644 --- a/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h +++ b/GeoModelIO/GeoModelRead/GeoModelRead/ReadGeoModel.h @@ -53,8 +53,10 @@ typedef GeoModelIO::ReadGeoModel Persistifier; // **************************************************************** // **************************************************************** -// local includes +// GeoModel includes #include "GeoModelDBManager/GMDBManager.h" +#include "GeoModelDBManager/definitions.h" + #include "GeoModelKernel/GeoXF.h" // C++ includes @@ -86,6 +88,11 @@ class GeoGraphNode; class GeoShapeSubtraction; class GeoBox; +class BuildGeoShapes_Box; +class BuildGeoShapes_Tube; +class BuildGeoShapes_Pcon; +class BuildGeoShapes_Cons; + // type definitions typedef const GeoXF::Function& TRANSFUNCTION; // containers for boolean shapes' information @@ -94,6 +101,8 @@ typedef std::tuple<unsigned int /*shape ID*/, GeoShape*, tuple_shapes_boolean_info; typedef std::vector<tuple_shapes_boolean_info> type_shapes_boolean_info; + + namespace GeoModelIO { class ReadGeoModel { @@ -156,6 +165,11 @@ class ReadGeoModel { }; private: + void buildAllShapes_Box(); + void buildAllShapes_Tube(); + void buildAllShapes_Pcon(); + void buildAllShapes_Cons(); + void buildAllShapes(); void buildAllElements(); void buildAllMaterials(); @@ -224,7 +238,7 @@ class ReadGeoModel { // one, with the GeoModel class as a second argument ? (RMB) bool isBuiltShape(const unsigned int id); void storeBuiltShape(const unsigned int, GeoShape* node); - GeoShape* getBuiltShape(const unsigned int id); + GeoShape* getBuiltShape(const unsigned int shapeId, std::string_view shapeType = ""); bool isBuiltTransform(const unsigned int id); void storeBuiltTransform(GeoTransform* node); @@ -314,6 +328,14 @@ class ReadGeoModel { // callback handles unsigned long* m_progress; + //! builders + // std::unique_ptr<BuildGeoShapes_Box> m_builderShape_Box; + BuildGeoShapes_Box* m_builderShape_Box; + BuildGeoShapes_Tube* m_builderShape_Tube; + BuildGeoShapes_Pcon* m_builderShape_Pcon; + BuildGeoShapes_Cons* m_builderShape_Cons; + + //! containers to store the list of GeoModel nodes coming from the DB std::vector<std::vector<std::string>> m_physVols; std::vector<std::vector<std::string>> m_fullPhysVols; @@ -324,12 +346,23 @@ 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_logVols; std::vector<std::vector<std::string>> m_materials; std::vector<std::vector<std::string>> m_elements; std::vector<std::vector<std::string>> m_shapes; std::vector<std::vector<std::string>> m_allchildren; + // std::vector<std::vector<std::variant<int, long, float, double, std::string>>> m_logVols; + DBRowsList m_logVols; + + // containers to store shapes' parameters + 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_Cons; + + // containers to store shapes' data, for shapes with a variable number of build parameters + DBRowsList 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; std::deque<double> m_funcExprData; diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f29b3fffdcd623ad5509a8ebc70e8e20b24e8cc6 --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.cpp @@ -0,0 +1,44 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + */ + +#include "BuildGeoShapes.h" + +#include "GeoModelKernel/GeoShape.h" + +#include <vector> +#include <iostream> + +BuildGeoShapes::BuildGeoShapes(std::string_view shapeType, const unsigned size) +{ + m_shapeType = shapeType; + m_memMapShapes.reserve(size); +} + +BuildGeoShapes::BuildGeoShapes(std::string_view shapeType, const unsigned size, const DBRowsList shapeData) +{ + m_shapeType = shapeType; + m_memMapShapes.reserve(size); + m_shape_data = shapeData; +} + +bool BuildGeoShapes::isBuiltShape(const unsigned id) { + return (!(m_memMapShapes.find(id) == m_memMapShapes.end())); +} +void BuildGeoShapes::storeBuiltShape(const unsigned id, GeoShape* nodePtr) { + m_memMapShapes[id] = nodePtr; +} +GeoShape* BuildGeoShapes::getBuiltShape(const unsigned id) { + return m_memMapShapes[id]; // this is a map, and 'id' is the key +} + +void BuildGeoShapes::printBuiltShapes() { + for (unsigned id{1}; id<=m_memMapShapes.size(); ++id) { + std::cout << "shape " << m_shapeType << " -- id: " << id << ", shapePtr: " << m_memMapShapes[id] << std::endl; + } +} \ No newline at end of file diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h new file mode 100644 index 0000000000000000000000000000000000000000..14be15faca89de0c7782148ea5db55d997bc98fc --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes.h @@ -0,0 +1,47 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * BuildGeoShapes.h + * + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + * + */ + +#ifndef GEOMODELREAD_BUILDGEOSHAPES_H +#define GEOMODELREAD_BUILDGEOSHAPES_H + +#include "GeoModelDBManager/definitions.h" + +#include <vector> +#include <variant> +#include <string> +#include <unordered_map> + +class GeoShape; + +class BuildGeoShapes +{ +protected: + std::unordered_map<unsigned, GeoShape *> m_memMapShapes; + std::string m_shapeType; + DBRowsList m_shape_data; + +public: + //! contructors + BuildGeoShapes(std::string_view shapeType, const unsigned size); + BuildGeoShapes(std::string_view shapeType, const unsigned size, DBRowsList shapesData); + + virtual void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) = 0; + + // --- methods for caching GeoShape nodes --- + void storeBuiltShape(const unsigned id, GeoShape *nodePtr); + bool isBuiltShape(const unsigned id); + GeoShape *getBuiltShape(const unsigned id); + // --- print the list of built/cached shapes + void printBuiltShapes(); +}; + +#endif diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Box.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Box.cpp new file mode 100644 index 0000000000000000000000000000000000000000..e352753e0d1e20979711d41e701580efbb6ada14 --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Box.cpp @@ -0,0 +1,36 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + */ + +#include "BuildGeoShapes_Box.h" + +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelHelpers/variantHelpers.h" + +#include <vector> +#include <iostream> + +void BuildGeoShapes_Box::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) +{ + // === get shape numeric data from the DB row + // shape ID + const unsigned shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Tube:shapeID"); + // shape volume + const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Tube:shapeVolume"); + // shape parameters + const double XHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Tube:XHalfLength"); + const double YHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Tube:YHalfLength"); + const double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Tube:ZHalfLength"); + + GeoBox *shape = new GeoBox(XHalfLength, YHalfLength, ZHalfLength); + + storeBuiltShape(shapeId, shape); + + // return shape; + return; +} diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Box.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Box.h new file mode 100644 index 0000000000000000000000000000000000000000..1489796a32101e7401348aae023136c17c50e7bf --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Box.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * BuildGeoShapes_Box.h + * + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + * + */ + +#ifndef GEOMODELREAD_BUILDGEOSHAPES_BOX_H +#define GEOMODELREAD_BUILDGEOSHAPES_BOX_H + +#include "BuildGeoShapes.h" + +#include <vector> +#include <variant> + +class BuildGeoShapes_Box : public BuildGeoShapes +{ +public: + BuildGeoShapes_Box(const unsigned size):BuildGeoShapes("Box", size){}; + void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override; +}; + +#endif diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9645e2a787df403c347ff5ef693676c69baa8f4a --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.cpp @@ -0,0 +1,39 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + */ + +#include "BuildGeoShapes_Cons.h" + +#include "GeoModelKernel/GeoCons.h" +#include "GeoModelHelpers/variantHelpers.h" + +#include <vector> +#include <iostream> + +void BuildGeoShapes_Cons::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) +{ + // === get shape numeric data from the DB row + // shape ID + const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Cons:shapeID"); + // shape volume + const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Cons:shapeVolume"); + // shape parameters + const double RMin1 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Cons:RMin1"); + const double RMin2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Cons:RMin2"); + const double RMax1 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:RMax1"); + const double RMax2 = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:RMax2"); + const double DZ = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:DZ"); + const double SPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:SPhi"); + const double DPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Cons:DPhi"); + + GeoCons *shape = new GeoCons(RMin1, RMin2, RMax1, RMax2, DZ, SPhi, DPhi); + + storeBuiltShape(shapeId, shape); + + return; +} diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h new file mode 100644 index 0000000000000000000000000000000000000000..b54b849b4bc0b6b61661ec19a91568f13ed61a6e --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Cons.h @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * BuildGeoShapes_Cons.h + * + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + * + */ + +#ifndef GEOMODELREAD_BuildGeoShapes_Cons_H +#define GEOMODELREAD_BuildGeoShapes_Cons_H + +#include "BuildGeoShapes.h" + +#include <vector> +#include <variant> +#include <string> + +class BuildGeoShapes_Cons : public BuildGeoShapes +{ +public: + BuildGeoShapes_Cons(const unsigned size):BuildGeoShapes("Cons", size){}; + void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override; +}; + +#endif diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pcon.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pcon.cpp new file mode 100644 index 0000000000000000000000000000000000000000..0d9cf455f21ba566aa20f8a24d120aa185ec5ee0 --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pcon.cpp @@ -0,0 +1,80 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + */ + +#include "BuildGeoShapes_Pcon.h" + +#include "GeoModelKernel/GeoPcon.h" +#include "GeoModelHelpers/variantHelpers.h" +#include "GeoModelHelpers/throwExcept.h" + +#include <vector> +#include <iostream> + +void BuildGeoShapes_Pcon::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) +{ + if (!(m_shape_data.size())) { + THROW_EXCEPTION("ERROR! GeoPcon shape has no ZPlanes data!! [m_shape_data.size() == 0]"); + } + + // === get shape numeric data from the DB row + // shape ID + const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Pcon:shapeID"); + // shape volume + const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Pcon:shapeVolume"); + // shape parameters + const double SPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Pcon:SPhi"); + const double DPhi = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Pcon:DPhi"); + const int NZPlanes = GeoModelHelpers::variantHelper::getFromVariant_Int(row[4], "Pcon:NZPlanes"); + // pointers to variable shape data stored in a separate table + const int dataStart = GeoModelHelpers::variantHelper::getFromVariant_Int(row[5], "Pcon:dataStart"); + const int dataEnd = GeoModelHelpers::variantHelper::getFromVariant_Int(row[6], "Pcon:dataEnd"); + + // build the basic GeoPcon shape + GeoPcon *pcon = new GeoPcon(SPhi, DPhi); + + // and now loop over the additional shape's data, + // to get the parameters of all Z planes + + // get ZPlanes' data, extract subvector + // NOTE: we use (dataStart-1) to cope with the difference between the DB rows starting from '1', + // which is what the 'dataStart' stores, and the vector items, which start '0'; + // also, the constructor of the sub-vector takes the element from 'begin+dataStart-1' included + // and 'begin+dataEnd' excluded. + const DBRowsList zplanesData(m_shape_data.begin() + (dataStart-1), + m_shape_data.begin() + (dataEnd) ); + if (!(zplanesData.size())) { + THROW_EXCEPTION("ERROR! GeoPcon shape ZPlanes data have not been retrieved!!"); + } + if (!( NZPlanes == zplanesData.size())) { + THROW_EXCEPTION("ERROR! GeoPcon shape : size of ZPlanes data does not correspond to the number of ZPlanes declared!!"); + } + // loop over the data defining the ZPlanes + for (const DBRowEntry &dataRow : zplanesData) + { + const double zpos = GeoModelHelpers::variantHelper::getFromVariant_Double(dataRow[1], "Pcon:data_ZPos"); + const double rmin = GeoModelHelpers::variantHelper::getFromVariant_Double(dataRow[2], "Pcon:data_RMin"); + const double rmax = GeoModelHelpers::variantHelper::getFromVariant_Double(dataRow[3], "Pcon:data_RMax"); + // add a Z plane to the GeoPcon + pcon->addPlane(zpos, rmin, rmax); + } + + // sanity checks on the resulting Pcon shape + if (pcon->getNPlanes() != NZPlanes) + { + THROW_EXCEPTION("ERROR! GeoPcon actual number of planes: " + std::to_string(pcon->getNPlanes()) + " is not equal to the original size! --> " + std::to_string(NZPlanes)); + } + if (!pcon->isValid()) + { + THROW_EXCEPTION("ERROR! GeoPcon shape is not valid!!"); + } + + storeBuiltShape(shapeId, pcon); + + return; +} diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pcon.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pcon.h new file mode 100644 index 0000000000000000000000000000000000000000..6721ba1eab740d5eb80e435f37a0b4eee2ef5b65 --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Pcon.h @@ -0,0 +1,30 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * BuildGeoShapes_Pcon.h + * + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + * + */ + +#ifndef GEOMODELREAD_BuildGeoShapes_Pcon_H +#define GEOMODELREAD_BuildGeoShapes_Pcon_H + +#include "BuildGeoShapes.h" + +#include "GeoModelDBManager/definitions.h" + +#include <vector> +#include <variant> + +class BuildGeoShapes_Pcon : public BuildGeoShapes +{ +public: + BuildGeoShapes_Pcon(const unsigned size, DBRowsList shapeData):BuildGeoShapes("Pcon", size, shapeData){}; + void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override; +}; + +#endif diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp new file mode 100644 index 0000000000000000000000000000000000000000..6897821271abee6690544a75bcd6d23758f9fc30 --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.cpp @@ -0,0 +1,35 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + */ + +#include "BuildGeoShapes_Tube.h" + +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelHelpers/variantHelpers.h" + +#include <vector> +#include <iostream> + +void BuildGeoShapes_Tube::buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) +{ + // === get shape numeric data from the DB row + // shape ID + const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(row[0], "Tube:shapeID"); + // shape volume + const double shapeVolume = GeoModelHelpers::variantHelper::getFromVariant_Double(row[1], "Tube:shapeVolume"); + // shape parameters + const double RMin = GeoModelHelpers::variantHelper::getFromVariant_Double(row[2], "Tube:RMin"); + const double RMax = GeoModelHelpers::variantHelper::getFromVariant_Double(row[3], "Tube:RMax"); + const double ZHalfLength = GeoModelHelpers::variantHelper::getFromVariant_Double(row[4], "Tube:ZHalfLength"); + + GeoTube *shape = new GeoTube(RMin, RMax, ZHalfLength); + + storeBuiltShape(shapeId, shape); + + return; +} diff --git a/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h new file mode 100644 index 0000000000000000000000000000000000000000..fa1933e12d9b1482ff242428be288b01a54f2c08 --- /dev/null +++ b/GeoModelIO/GeoModelRead/src/BuildGeoShapes_Tube.h @@ -0,0 +1,28 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* + * BuildGeoShapes_Tube.h + * + * Created on: May 7, 2024 + * Author: Riccardo Maria BIANCHI <riccardo.maria.bianchi@cern.ch> + * + */ + +#ifndef GEOMODELREAD_BuildGeoShapes_Tube_H +#define GEOMODELREAD_BuildGeoShapes_Tube_H + +#include "BuildGeoShapes.h" + +#include <vector> +#include <variant> + +class BuildGeoShapes_Tube : public BuildGeoShapes +{ +public: + BuildGeoShapes_Tube(const unsigned size):BuildGeoShapes("Tube", size){}; + void buildShape(const std::vector<std::variant<int, long, float, double, std::string>> row) override; +}; + +#endif diff --git a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp index b71a69fdb053398b999565132d530f1888087220..01543f9f1b0d7d73adcc6b0aaf63a6a176f9f63e 100644 --- a/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp +++ b/GeoModelIO/GeoModelRead/src/ReadGeoModel.cpp @@ -26,6 +26,11 @@ */ // local includes +#include "BuildGeoShapes_Box.h" +#include "BuildGeoShapes_Tube.h" +#include "BuildGeoShapes_Pcon.h" +#include "BuildGeoShapes_Cons.h" + #include "GeoModelRead/ReadGeoModel.h" // TFPersistification includes @@ -70,6 +75,9 @@ #include "GeoModelKernel/GeoTwistedTrap.h" #include "GeoModelKernel/GeoUnidentifiedShape.h" +#include "GeoModelHelpers/variantHelpers.h" +#include "GeoModelHelpers/throwExcept.h" + // Units #include "GeoModelKernel/Units.h" #define SYSTEM_OF_UNITS \ @@ -94,6 +102,8 @@ #include <unordered_map> #include <unordered_set> #include <vector> +#include <variant> +#include <memory> // mutexes for synchronized access to containers and output streams in // multi-threading mode @@ -162,6 +172,9 @@ ReadGeoModel::ReadGeoModel(GMDBManager* db, unsigned long* progress) m_dbManager->loadGeoNodeTypesAndBuildCache(); m_dbManager->createTableDataCaches(); + // prepare builders + // m_builderShape_Box = std::make_unique<BuildGeoShapes_Box>(); + // Check if the user asked for running in serial or multi-threading mode if ("" != getEnvVar("GEOMODEL_ENV_IO_NTHREADS")) { int nThreads = std::stoi(getEnvVar("GEOMODEL_ENV_IO_NTHREADS")); @@ -201,7 +214,14 @@ ReadGeoModel::ReadGeoModel(GMDBManager* db, unsigned long* progress) } ReadGeoModel::~ReadGeoModel() { - // FIXME: some cleaning...?? + delete m_builderShape_Box; + delete m_builderShape_Tube; + delete m_builderShape_Pcon; + delete m_builderShape_Cons; + m_builderShape_Box = nullptr; + m_builderShape_Tube = nullptr; + m_builderShape_Pcon = nullptr; + m_builderShape_Cons = nullptr; } // FIXME: TODO: move to an utility class @@ -236,11 +256,9 @@ void ReadGeoModel::loadDB() { std::chrono::system_clock::time_point start = std::chrono::system_clock::now(); // timing: get start time // get all GeoModel nodes from the DB - m_logVols = m_dbManager->getTableFromNodeType("GeoLogVol"); m_shapes = m_dbManager->getTableFromNodeType("GeoShape"); m_materials = m_dbManager->getTableFromNodeType("GeoMaterial"); m_elements = m_dbManager->getTableFromNodeType("GeoElement"); - m_functions = m_dbManager->getTableFromNodeType_VecVecData("Function"); m_physVols = m_dbManager->getTableFromNodeType("GeoPhysVol"); m_fullPhysVols = m_dbManager->getTableFromNodeType("GeoFullPhysVol"); m_transforms = m_dbManager->getTableFromNodeType("GeoTransform"); @@ -254,9 +272,25 @@ void ReadGeoModel::loadDB() { m_serialTransformers = m_dbManager->getTableFromNodeType("GeoSerialTransformer"); m_nameTags = m_dbManager->getTableFromNodeType("GeoNameTag"); + + // 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"); + + // shapes from the new DB schema + m_shapes_Box = m_dbManager->getTableFromNodeType_VecVecData("GeoBox"); + m_shapes_Tube = m_dbManager->getTableFromNodeType_VecVecData("GeoTube"); + m_shapes_Pcon = m_dbManager->getTableFromNodeType_VecVecData("GeoPcon"); + m_shapes_Cons = m_dbManager->getTableFromNodeType_VecVecData("GeoCons"); + + // shapes' data, when needed by shapes that have variable numbers of build parameters + m_shapes_Pcon_data = m_dbManager->getTableFromTableName_VecVecData("Shapes_Pcon_Data"); + // get the Function's expression data // m_funcExprData = m_dbManager->getTableFromTableNameVecVecData("FuncExprData"); m_funcExprData = m_dbManager->getTableFromTableName_DequeDouble("FuncExprData"); + + // get the children table from DB m_allchildren = m_dbManager->getChildrenTable(); // get the root volume data @@ -295,14 +329,21 @@ GeoVPhysVol* ReadGeoModel::buildGeoModelPrivate() { t8.join(); // ok, all Transforms have been built t9.join(); // ok, all AlignableTransforms have been built + // needs Transforms and AlignableTransforms for Shift boolean shapes std::thread t1(&ReadGeoModel::buildAllShapes, this); + std::thread t15(&ReadGeoModel::buildAllShapes_Box, this); + std::thread t16(&ReadGeoModel::buildAllShapes_Tube, this); + std::thread t17(&ReadGeoModel::buildAllShapes_Pcon, this); + std::thread t18(&ReadGeoModel::buildAllShapes_Cons, this); t2.join(); // ok, all Elements have been built // needs Elements std::thread t3(&ReadGeoModel::buildAllMaterials, this); t1.join(); // ok, all Shapes have been built + t15.join(); // ok, all Shapes-Box have been built + t16.join(); // ok, all Shapes-Tube have been built t3.join(); // ok, all Materials have been built // needs Shapes and Materials std::thread t4(&ReadGeoModel::buildAllLogVols, this); @@ -337,6 +378,10 @@ GeoVPhysVol* ReadGeoModel::buildGeoModelPrivate() { buildAllIdentifierTags(); buildAllNameTags(); buildAllShapes(); + buildAllShapes_Box(); + buildAllShapes_Tube(); + buildAllShapes_Pcon(); + buildAllShapes_Cons(); buildAllMaterials(); buildAllLogVols(); buildAllPhysVols(); @@ -419,6 +464,84 @@ void ReadGeoModel::buildAllShapes() { if (nSize > 0) std::cout << "All " << nSize << " Shapes have been built!\n"; } +//! Iterate over the list of shapes, build them all, and store their +//! pointers +void ReadGeoModel::buildAllShapes_Box() +{ + if (m_loglevel >= 1) { + std::cout << "Building all shapes -- Box ...\n"; + } + + // create a builder and reserve size of memory map + size_t nSize = m_shapes_Box.size(); + m_builderShape_Box = new BuildGeoShapes_Box(nSize); + + // loop over the DB rows and build the shapes + for (const auto &row : m_shapes_Box) + { + // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG + m_builderShape_Box->buildShape(row); + } + m_builderShape_Box->printBuiltShapes(); // DEBUG MSG + if (nSize > 0) { + std::cout << "All " << nSize << " Shapes-Box have been built!\n"; + } +} +//! Iterate over the list of shapes, build them all, and store their +//! pointers +void ReadGeoModel::buildAllShapes_Tube() +{ + // create a builder and reserve size of memory map + size_t nSize = m_shapes_Tube.size(); + m_builderShape_Tube = new BuildGeoShapes_Tube(nSize); + // loop over the DB rows and build the shapes + for (const auto &row : m_shapes_Tube) + { + // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG + m_builderShape_Tube->buildShape(row); + } + m_builderShape_Tube->printBuiltShapes(); // DEBUG MSG + if (nSize > 0) { + std::cout << "All " << nSize << " Shapes-Tube have been built!\n"; + } +} +//! Iterate over the list of shapes, build them all, and store their +//! pointers +void ReadGeoModel::buildAllShapes_Pcon() +{ + // create a builder and reserve size of memory map + size_t nSize = m_shapes_Pcon.size(); + m_builderShape_Pcon = new BuildGeoShapes_Pcon(nSize, m_shapes_Pcon_data); + // loop over the DB rows and build the shapes + for (const auto &row : m_shapes_Pcon) + { + // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG + m_builderShape_Pcon->buildShape(row); + } + m_builderShape_Pcon->printBuiltShapes(); // DEBUG MSG + if (nSize > 0) { + std::cout << "All " << nSize << " Shapes-Pcon have been built!\n"; + } +} +//! Iterate over the list of shapes, build them all, and store their +//! pointers +void ReadGeoModel::buildAllShapes_Cons() +{ + // create a builder and reserve size of memory map + size_t nSize = m_shapes_Cons.size(); + m_builderShape_Cons = new BuildGeoShapes_Cons(nSize); + // loop over the DB rows and build the shapes + for (const auto &row : m_shapes_Cons) + { + // GeoModelIO::CppHelper::printStdVectorVariants(row); // DEBUG MSG + m_builderShape_Cons->buildShape(row); + } + m_builderShape_Cons->printBuiltShapes(); // DEBUG MSG + if (nSize > 0) { + std::cout << "All " << nSize << " Shapes-Cons have been built!\n"; + } +} + //! Iterate over the list of GeoSerialDenominator nodes, build them all, and //! store their pointers void ReadGeoModel::buildAllSerialDenominators() { @@ -446,8 +569,7 @@ void ReadGeoModel::buildAllSerialIdentifiers() { if (m_loglevel >= 1) std::cout << "Building all SerialIdentifier nodes...\n"; size_t nSize = m_serialIdentifiers.size(); - m_memMapSerialIdentifiers.reserve( - nSize * 2); // TODO: check if *2 is good or redundant... + m_memMapSerialIdentifiers.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { // const unsigned int nodeID = std::stoi(m_seriaIdentifiers[ii][0]); // // RMB: not used at the moment, commented to avoid warnings @@ -464,8 +586,7 @@ void ReadGeoModel::buildAllSerialIdentifiers() { void ReadGeoModel::buildAllIdentifierTags() { if (m_loglevel >= 1) std::cout << "Building all IdentifierTag nodes...\n"; size_t nSize = m_identifierTags.size(); - m_memMapIdentifierTags.reserve( - nSize * 2); // TODO: check if *2 is good or redundant... + m_memMapIdentifierTags.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { // const unsigned int nodeID = std::stoi(m_identifierTags[ii][0]); // // RMB: not used at the moment, commented to avoid warnings @@ -482,8 +603,7 @@ void ReadGeoModel::buildAllIdentifierTags() { void ReadGeoModel::buildAllNameTags() { if (m_loglevel >= 1) std::cout << "Building all NameTag nodes...\n"; size_t nSize = m_nameTags.size(); - m_memMapNameTags.reserve(nSize * - 2); // TODO: check if *2 is good or redundant... + m_memMapNameTags.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { // const unsigned int nodeID = std::stoi(m_nameTags[ii][0]); // RMB: // not used at teh moment, commented to avoid warnings @@ -499,8 +619,7 @@ void ReadGeoModel::buildAllNameTags() { void ReadGeoModel::buildAllElements() { if (m_loglevel >= 1) std::cout << "Building all Elements...\n"; size_t nSize = m_elements.size(); - m_memMapElements.reserve(nSize * - 2); // TODO: check if *2 is good or redundant... + m_memMapElements.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int nodeID = std::stoi(m_elements[ii][0]); buildElement(nodeID); // nodes' IDs start from 1 @@ -513,8 +632,7 @@ void ReadGeoModel::buildAllElements() { void ReadGeoModel::buildAllMaterials() { if (m_loglevel >= 1) std::cout << "Building all Materials...\n"; size_t nSize = m_materials.size(); - m_memMapMaterials.reserve(nSize * - 2); // TODO: check if *2 is good or redundant... + m_memMapMaterials.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int nodeID = std::stoi(m_materials[ii][0]); buildMaterial(nodeID); // nodes' IDs start from 1 @@ -524,14 +642,23 @@ void ReadGeoModel::buildAllMaterials() { } //! Iterate over the list of nodes, build them all, and store their pointers -void ReadGeoModel::buildAllLogVols() { - if (m_loglevel >= 1) std::cout << "Building all LogVols...\n"; +void ReadGeoModel::buildAllLogVols() +{ + if (m_loglevel >= 1) + std::cout << "Building all LogVols...\n"; size_t nSize = m_logVols.size(); - m_memMapLogVols.reserve(nSize * - 2); // TODO: check if *2 is good or redundant... - for (unsigned int ii = 0; ii < nSize; ++ii) { - const unsigned int nodeID = std::stoi(m_logVols[ii][0]); - buildLogVol(nodeID); + m_memMapLogVols.reserve(nSize); + for (unsigned int ii = 0; ii < nSize; ++ii) + { + try + { + const unsigned int nodeID = std::get<int>(m_logVols[ii][0]); + buildLogVol(nodeID); + } + catch (std::bad_variant_access const &ex) + { + std::cout << ex.what() << ": logVol 'ID' is not an 'int' value!\n"; + } } if (nSize > 0) std::cout << "All " << nSize << " LogVols have been built!\n"; @@ -555,8 +682,7 @@ void ReadGeoModel::buildAllPhysVols() { } const unsigned int tableID = m_tableName_toTableID["GeoPhysVol"]; size_t nSize = m_physVols.size(); - m_memMapPhysVols.reserve(nSize * - 2); // TODO: check if *2 is good or redundant... + m_memMapPhysVols.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int volID = std::stoi(m_physVols[ii][0]); const unsigned int logVolID = std::stoi(m_physVols[ii][1]); @@ -573,8 +699,7 @@ void ReadGeoModel::buildAllFullPhysVols() { if (m_debug) std::cout << "Building all FullPhysVols...\n"; const unsigned int tableID = m_tableName_toTableID["GeoFullPhysVol"]; size_t nSize = m_fullPhysVols.size(); - m_memMapFullPhysVols.reserve( - nSize * 2); // TODO: check if *2 is good or redundant... + m_memMapFullPhysVols.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int volID = std::stoi(m_fullPhysVols[ii][0]); const unsigned int logVolID = std::stoi(m_fullPhysVols[ii][1]); @@ -591,8 +716,7 @@ void ReadGeoModel::buildAllFullPhysVols() { void ReadGeoModel::buildAllAlignableTransforms() { if (m_debug) std::cout << "Building all AlignableTransforms...\n"; size_t nSize = m_alignableTransforms.size(); - m_memMapAlignableTransforms.reserve( - nSize * 2); // TODO: check if *2 is good or redundant... + m_memMapAlignableTransforms.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int volID = std::stoi(m_alignableTransforms[ii][0]); buildAlignableTransform(volID); @@ -607,8 +731,7 @@ void ReadGeoModel::buildAllAlignableTransforms() { void ReadGeoModel::buildAllTransforms() { if (m_debug) std::cout << "Building all Transforms...\n"; size_t nSize = m_transforms.size(); - m_memMapTransforms.reserve(nSize * - 2); // TODO: check if *2 is good or redundant... + m_memMapTransforms.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int volID = std::stoi(m_transforms[ii][0]); buildTransform(volID); @@ -622,8 +745,7 @@ void ReadGeoModel::buildAllTransforms() { void ReadGeoModel::buildAllSerialTransformers() { if (m_debug) std::cout << "Building all SerialTransformers...\n"; size_t nSize = m_serialTransformers.size(); - m_memMapSerialTransformers.reserve( - nSize * 2); // TODO: check if 2 is good or redundant... + m_memMapSerialTransformers.reserve(nSize); for (unsigned int ii = 0; ii < nSize; ++ii) { const unsigned int volID = std::stoi(m_serialTransformers[ii][0]); buildSerialTransformer(volID); @@ -1301,6 +1423,7 @@ std::string ReadGeoModel::getShapeType(const unsigned int shapeId) { return type; } + // TODO: move shapes in different files, so code here is more managable /// Recursive function, to build GeoShape nodes GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId, @@ -1330,7 +1453,9 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId, GeoShape* shape = nullptr; - if (type == "Box") { + if (false) { + } + else if (type == "Box") { // shape parameters double XHalfLength = 0.; double YHalfLength = 0.; @@ -1348,38 +1473,40 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId, ZHalfLength = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; } shape = new GeoBox(XHalfLength, YHalfLength, ZHalfLength); - } else if (type == "Cons") { - // shape parameters - double RMin1 = 0.; - double RMin2 = 0.; - double RMax1 = 0.; - double RMax2 = 0.; - double DZ = 0.; - double SPhi = 0.; - double DPhi = 0.; - // get parameters from DB string - for (auto& par : shapePars) { - std::vector<std::string> vars = splitString(par, '='); - std::string varName = vars[0]; - std::string varValue = vars[1]; - // std::cout << "varValue Cons:" << varValue; - if (varName == "RMin1") - RMin1 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - if (varName == "RMin2") - RMin2 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - if (varName == "RMax1") - RMax1 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - if (varName == "RMax2") - RMax2 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - if (varName == "DZ") - DZ = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - if (varName == "SPhi") - SPhi = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - if (varName == "DPhi") - DPhi = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; - } - shape = new GeoCons(RMin1, RMin2, RMax1, RMax2, DZ, SPhi, DPhi); - } else if (type == "Torus") { + } + // else if (type == "Cons") { + // // shape parameters + // double RMin1 = 0.; + // double RMin2 = 0.; + // double RMax1 = 0.; + // double RMax2 = 0.; + // double DZ = 0.; + // double SPhi = 0.; + // double DPhi = 0.; + // // get parameters from DB string + // for (auto& par : shapePars) { + // std::vector<std::string> vars = splitString(par, '='); + // std::string varName = vars[0]; + // std::string varValue = vars[1]; + // // std::cout << "varValue Cons:" << varValue; + // if (varName == "RMin1") + // RMin1 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // if (varName == "RMin2") + // RMin2 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // if (varName == "RMax1") + // RMax1 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // if (varName == "RMax2") + // RMax2 = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // if (varName == "DZ") + // DZ = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // if (varName == "SPhi") + // SPhi = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // if (varName == "DPhi") + // DPhi = std::stod(varValue); // * SYSTEM_OF_UNITS::mm; + // } + // shape = new GeoCons(RMin1, RMin2, RMax1, RMax2, DZ, SPhi, DPhi); + // } + else if (type == "Torus") { // Member Data: // * Rmax - outside radius of the torus tube // * Rmin - inside radius of the torus tube (Rmin=0 if not hollow) @@ -1439,127 +1566,129 @@ GeoShape* ReadGeoModel::buildShape(const unsigned int shapeId, } shape = new GeoPara(XHalfLength, YHalfLength, ZHalfLength, Alpha, Theta, Phi); - } else if (type == "Pcon") { - // shape parameters - double SPhi = 0.; - double DPhi = 0.; - unsigned int NZPlanes = 0; - - bool error = 0; - std::string par; - std::vector<std::string> vars; - std::string varName; - std::string varValue; - - GeoPcon* pcon = nullptr; - - int sizePars = shapePars.size(); - // check if we have more than 3 parameters - if (sizePars > 3) { - // get the three first GeoPcon parameters: the SPhi and DPhi angles, - // plus the number of Z planes - for (int it = 0; it < 3; it++) { - par = shapePars[it]; - vars = splitString(par, '='); - varName = vars[0]; - varValue = vars[1]; - if (varName == "SPhi") SPhi = std::stod(varValue); - if (varName == "DPhi") DPhi = std::stod(varValue); - if (varName == "NZPlanes") NZPlanes = std::stoi(varValue); - } - // build the basic GeoPcon shape - pcon = new GeoPcon(SPhi, DPhi); - - // and now loop over the rest of the list, to get the parameters of - // all Z planes - for (int it = 3; it < sizePars; it++) { - par = shapePars[it]; - vars = splitString(par, '='); - varName = vars[0]; - varValue = vars[1]; - - if (varName == "ZPos") { - double zpos = std::stod(varValue); - double rmin = 0., rmax = 0.; - - it++; // go to next variable - - par = shapePars[it]; - vars = splitString(par, '='); - varName = vars[0]; - varValue = vars[1]; - if (varName == "ZRmin") - rmin = std::stod(varValue); - else - error = 1; - it++; // go to next variable - - par = shapePars[it]; - vars = splitString(par, '='); - varName = vars[0]; - varValue = vars[1]; - if (varName == "ZRmax") - rmax = std::stod(varValue); - else - error = 1; - - if (error) { - muxCout.lock(); - std::cout << "ERROR! GeoPcon 'ZRmin' and 'ZRmax' " - "values are not at the right place! --> "; - printStdVectorStrings(shapePars); - muxCout.unlock(); - } - - // add a Z plane to the GeoPcon - pcon->addPlane(zpos, rmin, rmax); - } else { - error = 1; - muxCout.lock(); - std::cout << "ERROR! GeoPcon 'ZPos' value is not at the " - "right place! --> "; - printStdVectorStrings(shapePars); - muxCout.unlock(); - } - } - - // sanity check on the resulting Pcon shape - if (pcon->getNPlanes() != NZPlanes) { - error = 1; - muxCout.lock(); - std::cout << "ERROR! GeoPcon number of planes: " - << pcon->getNPlanes() - << " is not equal to the original size! --> "; - printStdVectorStrings(shapePars); - muxCout.unlock(); - } - if (!pcon->isValid()) { - error = 1; - muxCout.lock(); - std::cout << "ERROR! GeoPcon shape is not valid!! -- input: "; - printStdVectorStrings(shapePars); - muxCout.unlock(); - } - } // end if (size>3) - else { - muxCout.lock(); - std::cout << "ERROR!! GeoPcon has no Z planes!! --> shape input " - "parameters: "; - printStdVectorStrings(shapePars); - muxCout.unlock(); - error = 1; - } - - if (error) { - muxCout.lock(); - std::cout << "FATAL ERROR!!! - GeoPcon shape error!!! Aborting..." - << std::endl; - muxCout.unlock(); - exit(EXIT_FAILURE); - } - - shape = pcon; - } else if (type == "Pgon") { + } + // else if (type == "Pcon") { + // // shape parameters + // double SPhi = 0.; + // double DPhi = 0.; + // unsigned int NZPlanes = 0; + + // bool error = 0; + // std::string par; + // std::vector<std::string> vars; + // std::string varName; + // std::string varValue; + + // GeoPcon* pcon = nullptr; + + // int sizePars = shapePars.size(); + // // check if we have more than 3 parameters + // if (sizePars > 3) { + // // get the three first GeoPcon parameters: the SPhi and DPhi angles, + // // plus the number of Z planes + // for (int it = 0; it < 3; it++) { + // par = shapePars[it]; + // vars = splitString(par, '='); + // varName = vars[0]; + // varValue = vars[1]; + // if (varName == "SPhi") SPhi = std::stod(varValue); + // if (varName == "DPhi") DPhi = std::stod(varValue); + // if (varName == "NZPlanes") NZPlanes = std::stoi(varValue); + // } + // // build the basic GeoPcon shape + // pcon = new GeoPcon(SPhi, DPhi); + + // // and now loop over the rest of the list, to get the parameters of + // // all Z planes + // for (int it = 3; it < sizePars; it++) { + // par = shapePars[it]; + // vars = splitString(par, '='); + // varName = vars[0]; + // varValue = vars[1]; + + // if (varName == "ZPos") { + // double zpos = std::stod(varValue); + // double rmin = 0., rmax = 0.; + + // it++; // go to next variable + + // par = shapePars[it]; + // vars = splitString(par, '='); + // varName = vars[0]; + // varValue = vars[1]; + // if (varName == "ZRmin") + // rmin = std::stod(varValue); + // else + // error = 1; + // it++; // go to next variable + + // par = shapePars[it]; + // vars = splitString(par, '='); + // varName = vars[0]; + // varValue = vars[1]; + // if (varName == "ZRmax") + // rmax = std::stod(varValue); + // else + // error = 1; + + // if (error) { + // muxCout.lock(); + // std::cout << "ERROR! GeoPcon 'ZRmin' and 'ZRmax' " + // "values are not at the right place! --> "; + // printStdVectorStrings(shapePars); + // muxCout.unlock(); + // } + + // // add a Z plane to the GeoPcon + // pcon->addPlane(zpos, rmin, rmax); + // } else { + // error = 1; + // muxCout.lock(); + // std::cout << "ERROR! GeoPcon 'ZPos' value is not at the " + // "right place! --> "; + // printStdVectorStrings(shapePars); + // muxCout.unlock(); + // } + // } + + // // sanity check on the resulting Pcon shape + // if (pcon->getNPlanes() != NZPlanes) { + // error = 1; + // muxCout.lock(); + // std::cout << "ERROR! GeoPcon number of planes: " + // << pcon->getNPlanes() + // << " is not equal to the original size! --> "; + // printStdVectorStrings(shapePars); + // muxCout.unlock(); + // } + // if (!pcon->isValid()) { + // error = 1; + // muxCout.lock(); + // std::cout << "ERROR! GeoPcon shape is not valid!! -- input: "; + // printStdVectorStrings(shapePars); + // muxCout.unlock(); + // } + // } // end if (size>3) + // else { + // muxCout.lock(); + // std::cout << "ERROR!! GeoPcon has no Z planes!! --> shape input " + // "parameters: "; + // printStdVectorStrings(shapePars); + // muxCout.unlock(); + // error = 1; + // } + + // if (error) { + // muxCout.lock(); + // std::cout << "FATAL ERROR!!! - GeoPcon shape error!!! Aborting..." + // << std::endl; + // muxCout.unlock(); + // exit(EXIT_FAILURE); + // } + + // shape = pcon; + // } + else if (type == "Pgon") { // shape parameters double SPhi = 0.; double DPhi = 0.; @@ -3005,23 +3134,24 @@ GeoLogVol* ReadGeoModel::buildLogVol(const unsigned int id) { } // get logVol properties from the DB - std::vector<std::string> values = m_logVols[id - 1]; - - // get the parameters to build the GeoLogVol node - std::string logVolName = values[1]; - - // build the referenced GeoShape node - const unsigned int shapeId = std::stoi(values[2]); - GeoShape* shape = getBuiltShape(shapeId); + // std::vector<std::string> values = m_logVols[id - 1]; + DBRowEntry values = m_logVols[id - 1]; + + // --- get the parameters to build the GeoLogVol node + // get the name of the LogVol + const std::string logVolName = GeoModelHelpers::variantHelper::getFromVariant_String(values[1], "LogVol_name"); + // get the ID and the type of the referenced GeoShape node + const int shapeId = GeoModelHelpers::variantHelper::getFromVariant_Int(values[2], "LogVol_shapeID"); + const std::string shapeType = GeoModelHelpers::variantHelper::getFromVariant_String(values[3], "LogVol_shapeType"); + GeoShape* shape = getBuiltShape(shapeId, shapeType); if (!shape) { - std::cout - << "ERROR!! While building a LogVol, Shape is NULL! Exiting..." - << std::endl; - exit(EXIT_FAILURE); + THROW_EXCEPTION("ERROR!! While building a LogVol, Shape of type '" + shapeType + "' is NULL! Exiting..."); } // build the referenced GeoMaterial node - const unsigned int matId = std::stoi(values[3]); + // const unsigned int matId = std::stoi(values[3]); + const int matId = GeoModelHelpers::variantHelper::getFromVariant_Int(values[4], "LogVol_MaterialID"); + if (m_loglevel >= 2) { muxCout.lock(); std::cout << "buildLogVol() - material Id:" << matId << std::endl; @@ -3029,10 +3159,7 @@ GeoLogVol* ReadGeoModel::buildLogVol(const unsigned int id) { } GeoMaterial* mat = getBuiltMaterial(matId); if (!mat) { - std::cout - << "ERROR!! While building a LogVol, Material is NULL! Exiting..." - << std::endl; - exit(EXIT_FAILURE); + THROW_EXCEPTION("ERROR!! While building a LogVol, Material of ID '" + std::to_string(matId) + "' is NULL! Exiting..."); } GeoLogVol* logPtr = new GeoLogVol(logVolName, shape, mat); @@ -3046,6 +3173,7 @@ GeoLogVol* ReadGeoModel::buildLogVol(const unsigned int id) { return logPtr; } + //// TODO: should go in a QtUtils header-only class, to be used in other /// packages // QList<double> ReadGeoModel::convertQstringListToDouble(QStringList listin) { @@ -3231,15 +3359,17 @@ TRANSFUNCTION ReadGeoModel::buildFunction(const unsigned int id) { if (0 == expr.size()) { muxCout.lock(); - std::cout << "FATAL ERROR!! Function expression is empty!! Aborting..." - << std::endl; + THROW_EXCEPTION("FATAL ERROR!! Function expression is empty!! Aborting..."); muxCout.unlock(); - exit(EXIT_FAILURE); } // get exprData, extract subvector - std::deque<double> sub_vector(m_funcExprData.begin() + dataStart, - m_funcExprData.begin() + dataEnd); + // NOTE: we use (dataStart-1) to cope with the difference between the DB rows starting from '1', + // which is what the 'dataStart' stores, and the vector items, which start '0'; + // also, the constructor of the sub-vector takes the element from 'begin+dataStart-1' included + // and 'begin+dataEnd' excluded. + std::deque<double> sub_vector(m_funcExprData.begin() + (dataStart-1), + m_funcExprData.begin() + (dataEnd) ); TransFunctionInterpreter interpreter; TFPTR func = interpreter.interpret(expr, &sub_vector); @@ -3269,8 +3399,35 @@ bool ReadGeoModel::isBuiltShape(const unsigned int id) { void ReadGeoModel::storeBuiltShape(const unsigned int id, GeoShape* nodePtr) { m_memMapShapes[id] = nodePtr; } -GeoShape* ReadGeoModel::getBuiltShape(const unsigned int id) { - return m_memMapShapes[id]; // this is a map, and 'id' is the key +GeoShape *ReadGeoModel::getBuiltShape(const unsigned int shapeId, std::string_view shapeType) +{ + + const std::set<std::string> shapesNewDB{"Box", "Tube", "Pcon", "Cons"}; + // get shape parameters + if (std::count(shapesNewDB.begin(), shapesNewDB.end(), shapeType)) + { + if ("Box" == shapeType) + { + return m_builderShape_Box->getBuiltShape(shapeId); + } + else if ("Tube" == shapeType) + { + return m_builderShape_Tube->getBuiltShape(shapeId); + } + else if ("Pcon" == shapeType) + { + return m_builderShape_Pcon->getBuiltShape(shapeId); + } + else if ("Cons" == shapeType) + { + return m_builderShape_Cons->getBuiltShape(shapeId); + } + else { + THROW_EXCEPTION("ERROR!!! Shape '" + std::string(shapeType) + "' is not handled correctly!"); + } + } + std::cout << "WARNING! For the shape '" << shapeType << "' we're using the old DB schema..." << std::endl; + return m_memMapShapes[shapeId]; // this is a map, and 'id' is the key } // --- methods for caching GeoLogVol nodes ---