diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index eabdf128ecad3f207991af29cc569d9309305fcc..6d9a1dda16423e0def6d03a9a1c0dffa6bcbd710 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -253,6 +253,26 @@ mac-gm-fullsimlight: CMAKE_ARGS: ${CMAKE_BASE_ARGS} CMAKE_CONFIG_FLAGS: -DGEOMODEL_BUILD_FULLSIMLIGHT=TRUE + +mac-gm-fsl: + <<: *macos-job + <<: *geomodel-job + stage: step-A + variables: + CMAKE_ARGS: ${CMAKE_BASE_ARGS} + CMAKE_EXTRA_FLAGS: -DGEOMODEL_BUILD_FSL=TRUE + + +mac-gm-all: + <<: *macos-job + <<: *geomodel-job + stage: step-C + needs: ["mac-coin", "mac-soqt"] + variables: + CMAKE_ARGS: ${CMAKE_BASE_ARGS} + CMAKE_EXTRA_FLAGS: -DGEOMODEL_BUILD_ALL=TRUE + + mac-gm-atlasextras: <<: *macos-job <<: *geomodel-job @@ -347,6 +367,27 @@ ubu-gm-fullsimlight: CMAKE_ARGS: ${CMAKE_BASE_ARGS} CMAKE_CONFIG_FLAGS: -DGEOMODEL_BUILD_FULLSIMLIGHT=TRUE + +ubu-gm-fsl: + <<: *ubuntu-job + <<: *geomodel-job + stage: step-B + needs: ["ubu-geant4"] + variables: + CMAKE_ARGS: ${CMAKE_BASE_ARGS} + CMAKE_CONFIG_FLAGS: -DGEOMODEL_BUILD_FSL=TRUE + + +ubu-gm-all: + <<: *ubuntu-job + <<: *geomodel-job + stage: step-C + needs: ["ubu-coin", "ubu-soqt", "ubu-geant4"] + variables: + CMAKE_ARGS: ${CMAKE_BASE_ARGS} + CMAKE_CONFIG_FLAGS: -DGEOMODEL_BUILD_ALL=TRUE + + ubu-gm-atlasextras: <<: *ubuntu-job <<: *geomodel-job diff --git a/CMakeLists.txt b/CMakeLists.txt index 34e5af4de4e5be0362ab1d2046824454d68f815e..0f5fae860f14bc27c8998673eeb6bd279b45c5ac 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,6 +52,13 @@ option(GEOMODEL_BUILD_FULLSIMLIGHT_PROFILING "Enable FullSimLight profiling targ option(GEOMODEL_BUILD_FSL "Enable the build of FSL and FullSimLight" OFF) option(GEOMODEL_BUILD_ATLASEXTENSIONS "Build the Custom ATLAS Extensions" OFF) + +if(GEOMODEL_BUILD_FSL AND GEOMODEL_BUILD_FULLSIMLIGHT) + message(STATUS "==> NOTE: You enabled both BUILD_FSL and BUILD_FULLSIMLIGHT. Since BUILD_FSL triggers the build of the FullSimLight package as well, I set BUILD_FULLSIMLIGHT to FALSE to avoid errors of 'double inclusion'") + set(GEOMODEL_BUILD_FULLSIMLIGHT FALSE) +endif() + + if(GEOMODEL_BUILD_FULLSIMLIGHT_PROFILING) set(GEOMODEL_BUILD_FULLSIMLIGHT ON CACHE BOOL "Enable the build of FullSimLight" FORCE) include(CTest) # needs to be included at the top level @@ -68,7 +75,6 @@ list( APPEND BUILT_PACKAGES "GeoModelIO") if(GEOMODEL_BUILD_ALL) set(GEOMODEL_BUILD_TOOLS TRUE) set(GEOMODEL_BUILD_VISUALIZATION TRUE) - set(GEOMODEL_BUILD_FULLSIMLIGHT TRUE) set(GEOMODEL_BUILD_FSL TRUE) endif() diff --git a/GeoModelExamples/HelloGeoRead/main.cpp b/GeoModelExamples/HelloGeoRead/main.cpp index 78d5ca48df2b8fb817c0f5bc5c0d5c8205364ae4..2fd5d85a646e56594d319e9fde7e9ac2106ffd8f 100644 --- a/GeoModelExamples/HelloGeoRead/main.cpp +++ b/GeoModelExamples/HelloGeoRead/main.cpp @@ -1,183 +1,196 @@ -// Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration +// Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration /* - * HelloGeo.cpp + * HelloGeoRead.cpp * * Author: Riccardo Maria BIANCHI @ CERN * Created on: Nov, 2018 + * Updated on: Jul, 2023 * */ // GeoModel includes #include "GeoModelDBManager/GMDBManager.h" -#include "GeoModelRead/ReadGeoModel.h" #include "GeoModelKernel/GeoBox.h" -#include "GeoModelKernel/GeoPhysVol.h" #include "GeoModelKernel/GeoFullPhysVol.h" #include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelRead/ReadGeoModel.h" // C++ includes -#include <iostream> +#include <cstdlib> // EXIT_FAILURE #include <fstream> -#include <cstdlib> // EXIT_FAILURE - +#include <iostream> // Units #include "GeoModelKernel/Units.h" -#define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' - - -GeoPhysVol* createTheWorld(GeoPhysVol* world) -{ - if (world == nullptr) - { - //-----------------------------------------------------------------------------------// - // Define the materials that we shall use. // - // ----------------------------------------------------------------------------------// - - // Define the units - #define gr SYSTEM_OF_UNITS::gram - #define mole SYSTEM_OF_UNITS::mole - #define cm3 SYSTEM_OF_UNITS::cm3 - - // Define the chemical elements - GeoElement* Nitrogen = new GeoElement ("Nitrogen" ,"N" , 7.0 , 14.0067 *gr/mole); - GeoElement* Oxygen = new GeoElement ("Oxygen" ,"O" , 8.0 , 15.9995 *gr/mole); - GeoElement* Argon = new GeoElement ("Argon" ,"Ar" , 18.0 , 39.948 *gr/mole); - GeoElement* Hydrogen = new GeoElement ("Hydrogen" ,"H" , 1.0 , 1.00797 *gr/mole); - - // Define the materials - double densityOfAir=0.001214 *gr/cm3; - GeoMaterial *air = new GeoMaterial("Air", densityOfAir); - air->add(Nitrogen , 0.7494); - air->add(Oxygen, 0.2369); - air->add(Argon, 0.0129); - air->add(Hydrogen, 0.0008); - air->lock(); - - const GeoBox* worldBox = new GeoBox(1000*SYSTEM_OF_UNITS::cm, 1000*SYSTEM_OF_UNITS::cm, 1000*SYSTEM_OF_UNITS::cm); - const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); - world = new GeoPhysVol(worldLog); - } - return world; +#define SYSTEM_OF_UNITS \ + GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' + +GeoPhysVol* createTheWorld(GeoPhysVol* world) { + if (world == nullptr) { + //-----------------------------------------------------------------------------------// +// Define the materials that we shall use. // +// ----------------------------------------------------------------------------------// + +// Define the units +#define gr SYSTEM_OF_UNITS::gram +#define mole SYSTEM_OF_UNITS::mole +#define cm3 SYSTEM_OF_UNITS::cm3 + + // Define the chemical elements + GeoElement* Nitrogen = + new GeoElement("Nitrogen", "N", 7.0, 14.0067 * gr / mole); + GeoElement* Oxygen = + new GeoElement("Oxygen", "O", 8.0, 15.9995 * gr / mole); + GeoElement* Argon = + new GeoElement("Argon", "Ar", 18.0, 39.948 * gr / mole); + GeoElement* Hydrogen = + new GeoElement("Hydrogen", "H", 1.0, 1.00797 * gr / mole); + + // Define the materials + double densityOfAir = 0.001214 * gr / cm3; + GeoMaterial* air = new GeoMaterial("Air", densityOfAir); + air->add(Nitrogen, 0.7494); + air->add(Oxygen, 0.2369); + air->add(Argon, 0.0129); + air->add(Hydrogen, 0.0008); + air->lock(); + + const GeoBox* worldBox = + new GeoBox(1000 * SYSTEM_OF_UNITS::cm, 1000 * SYSTEM_OF_UNITS::cm, + 1000 * SYSTEM_OF_UNITS::cm); + const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); + world = new GeoPhysVol(worldLog); + } + return world; } - - -int main(int argc, char *argv[]) -{ - - if(argc != 2) - { - fprintf(stderr, "\nERROR!\nUsage: %s geometry.db\n\n", argv[0]); +int main(int argc, char* argv[]) { + if (argc != 2) { + fprintf(stderr, "\nERROR!\nUsage: %s <geometry.db>\n\n", argv[0]); return 1; } + // Get the input SQLite '.db' file containing the geometry std::string line; std::string fileName; fileName = argv[1]; std::cout << "Using this SQLite '.db' file:" << fileName << std::endl; + // check if DB file exists. If not, return. + // FIXME: TODO: this check should go in the 'GMDBManager' constructor. + std::ifstream infile(fileName.c_str()); + if (!infile.good()) { + std::cout << "\n\tERROR!! A '" << fileName + << "' file does not exist!! Please, check the path of the " + "input file before running this program. Exiting..."; + exit(EXIT_FAILURE); + } + infile.close(); + + // GET GEOMETRY FROM LOCAL DB + + // open the DB + GMDBManager* db = new GMDBManager(fileName); + /* Open database */ + if (db->checkIsDBOpen()) { + std::cout << "OK! Database is open!\n"; + } else { + std::cout << "Database is not open!\n"; + // return; + throw; + } + + // -- testing the input database + // std::cout << "Printing the list of all GeoMaterial nodes" << std::endl; + // db->printAllMaterials(); + // std::cout << "Printing the list of all GeoElement nodes" << std::endl; + // db->printAllElements(); + + /* setup the GeoModel reader */ + GeoModelIO::ReadGeoModel geoReader = GeoModelIO::ReadGeoModel(db); + std::cout << "OK! ReadGeoModel is set." << std::endl; + + /* build the GeoModel geometry */ + GeoPhysVol* dbPhys = + geoReader.buildGeoModel(); // builds the whole GeoModel tree in memory + std::cout << "ReadGeoModel::buildGeoModel() done." << std::endl; + + std::cout << "Reading records from the imported geometry DB file..." + << std::endl; + geoReader.printDBTable("SerialIdentifiers"); + geoReader.printDBTable("IdentifierTags"); + + // create the world volume container and + // get the 'world' volume, i.e. the root volume of the GeoModel tree + std::cout << "Getting the 'world' GeoPhysVol, i.e. the root volume of the " + "GeoModel tree" + << std::endl; + GeoPhysVol* world = createTheWorld(dbPhys); + std::cout << "Getting the GeoLogVol used by the 'world' volume" + << std::endl; + const GeoLogVol* logVol = world->getLogVol(); + std::cout << "'world' GeoLogVol name: " << logVol->getName() << std::endl; + std::cout << "'world' GeoMaterial name: " + << logVol->getMaterial()->getName() << std::endl; + + // --- testing the imported Geometry + + // get number of children volumes + unsigned int nChil = world->getNChildVols(); + std::cout << "'world' number of children: " << nChil << std::endl; + + // loop over all children nodes + std::cout << "Looping over all 'volume' children (i.e., GeoPhysVol and " + "GeoFullPhysVol)..." + << std::endl; + for (unsigned int idx = 0; idx < nChil; ++idx) { + PVConstLink nodeLink = world->getChildVol(idx); + + if (dynamic_cast<const GeoVPhysVol*>(&(*(nodeLink)))) { + std::cout << "\t" + << "the child n. " << idx << " "; + const GeoVPhysVol* childVolV = &(*(nodeLink)); + + if (dynamic_cast<const GeoPhysVol*>(childVolV)) { + const GeoPhysVol* childVol = + dynamic_cast<const GeoPhysVol*>(childVolV); + std::cout << "is a GeoPhysVol, whose GeoLogVol name is: " + << childVol->getLogVol()->getName(); + std::cout << " and it has " << childVol->getNChildVols() + << " child volumes" << std::endl; + } else if (dynamic_cast<const GeoFullPhysVol*>(childVolV)) { + const GeoFullPhysVol* childVol = + dynamic_cast<const GeoFullPhysVol*>(childVolV); + std::cout << "is a GeoFullPhysVol, whose GeoLogVol name is: " + << childVol->getLogVol()->getName(); + std::cout << " and it has " << childVol->getNChildVols() + << " child volumes" << std::endl; + } + } else if (dynamic_cast<const GeoNameTag*>(&(*(nodeLink)))) { + std::cout << "\t" + << "the child n. " << idx << " is a GeoNameTag" + << std::endl; + const GeoNameTag* childVol = + dynamic_cast<const GeoNameTag*>(&(*(nodeLink))); + std::cout << "\t\t GeoNameTag's name: " << childVol->getName() + << std::endl; + } else if (dynamic_cast<const GeoMaterial*>(&(*(nodeLink)))) { + std::cout << "\t" + << "the child n. " << idx << " is a GeoMaterial" + << std::endl; + const GeoMaterial* childVol = + dynamic_cast<const GeoMaterial*>(&(*(nodeLink))); + std::cout << "\t\t GeoMaterial's name: " << childVol->getName() + << std::endl; + std::cout << "\t\t GeoMaterial's number of elements: " + << childVol->getNumElements() << std::endl; + } + } + + std::cout << "Everything done." << std::endl; - // check if DB file exists. If not, return. - // FIXME: TODO: this check should go in the 'GMDBManager' constructor. - std::ifstream infile(fileName.c_str()); - if ( ! infile.good() ) { - std::cout << "\n\tERROR!! A '" << fileName << "' file does not exist!! Please, check the path of the input file before running this program. Exiting..."; - exit(EXIT_FAILURE); - } - infile.close(); - - - // GET GEOMETRY FROM LOCAL DB - - - - // open the DB - GMDBManager* db = new GMDBManager(fileName); - /* Open database */ - if (db->checkIsDBOpen()) { - std::cout << "OK! Database is open!\n"; - } - else { - std::cout << "Database is not open!\n"; - // return; - throw; - } - - // -- testing the input database -// std::cout << "Printing the list of all GeoMaterial nodes" << std::endl; -// db->printAllMaterials(); -// std::cout << "Printing the list of all GeoElement nodes" << std::endl; -// db->printAllElements(); - - /* setup the GeoModel reader */ - GeoModelIO::ReadGeoModel geoReader = GeoModelIO::ReadGeoModel(db); - std::cout << "OK! ReadGeoModel is set." << std::endl; - - - /* build the GeoModel geometry */ - GeoPhysVol* dbPhys = geoReader.buildGeoModel(); // builds the whole GeoModel tree in memory - std::cout << "ReadGeoModel::buildGeoModel() done." << std::endl; - - std::cout << "Reading records from the imported geometry DB file..." << std::endl; - geoReader.printDBTable("SerialIdentifiers"); - geoReader.printDBTable("IdentifierTags"); - - - // create the world volume container and - // get the 'world' volume, i.e. the root volume of the GeoModel tree - std::cout << "Getting the 'world' GeoPhysVol, i.e. the root volume of the GeoModel tree" << std::endl; - GeoPhysVol* world = createTheWorld(dbPhys); - std::cout << "Getting the GeoLogVol used by the 'world' volume" << std::endl; - const GeoLogVol* logVol = world->getLogVol(); - std::cout << "'world' GeoLogVol name: " << logVol->getName() << std::endl; - std::cout << "'world' GeoMaterial name: " << logVol->getMaterial()->getName() << std::endl; - - - // --- testing the imported Geometry - - // get number of children volumes - unsigned int nChil = world->getNChildVols(); - std:: cout << "'world' number of children: " << nChil << std::endl; - - // loop over all children nodes - std::cout << "Looping over all 'volume' children (i.e., GeoPhysVol and GeoFullPhysVol)..." << std::endl; - for (unsigned int idx=0; idx<nChil; ++idx) { - PVConstLink nodeLink = world->getChildVol(idx); - - if ( dynamic_cast<const GeoVPhysVol*>( &(*( nodeLink ))) ) { - - std::cout << "\t" << "the child n. " << idx << " "; - const GeoVPhysVol *childVolV = &(*( nodeLink )); - - if ( dynamic_cast<const GeoPhysVol*>(childVolV) ) { - const GeoPhysVol* childVol = dynamic_cast<const GeoPhysVol*>(childVolV); - std::cout << "is a GeoPhysVol, whose GeoLogVol name is: " << childVol->getLogVol()->getName(); - std::cout<< " and it has "<<childVol->getNChildVols()<<" child volumes" << std::endl; - } - else if ( dynamic_cast<const GeoFullPhysVol*>(childVolV) ) { - const GeoFullPhysVol* childVol = dynamic_cast<const GeoFullPhysVol*>(childVolV); - std::cout << "is a GeoFullPhysVol, whose GeoLogVol name is: " << childVol->getLogVol()->getName(); - std::cout<< " and it has "<<childVol->getNChildVols()<<" child volumes" << std::endl; - } - } - else if ( dynamic_cast<const GeoNameTag*>( &(*( nodeLink ))) ) { - std::cout << "\t" << "the child n. " << idx << " is a GeoNameTag" << std::endl; - const GeoNameTag *childVol = dynamic_cast<const GeoNameTag*>(&(*( nodeLink ))); - std::cout << "\t\t GeoNameTag's name: " << childVol->getName() << std::endl; - } - else if ( dynamic_cast<const GeoMaterial*>( &(*( nodeLink ))) ) { - std::cout << "\t" << "the child n. " << idx << " is a GeoMaterial" << std::endl; - const GeoMaterial *childVol = dynamic_cast<const GeoMaterial*>(&(*( nodeLink ))); - std::cout << "\t\t GeoMaterial's name: " << childVol->getName() << std::endl; - std::cout << "\t\t GeoMaterial's number of elements: " << childVol->getNumElements() << std::endl; - } - } - - - std::cout << "Everything done." << std::endl; - - // return app.exec(); - return 0; + // return app.exec(); + return 0; } diff --git a/GeoModelExamples/HelloGeoRead2G4/CMakeLists.txt b/GeoModelExamples/HelloGeoRead2G4/CMakeLists.txt index 76b8e265a2f9ffe0ac941a1f3fd73aa975798a08..db4e5b1ec7a8a6051037de39131b80a2d8b3c4ce 100644 --- a/GeoModelExamples/HelloGeoRead2G4/CMakeLists.txt +++ b/GeoModelExamples/HelloGeoRead2G4/CMakeLists.txt @@ -1,21 +1,25 @@ -# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration +# Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration ################################################################################ # Package: HelloGeoRead2G4 # author: Riccardo Maria BIANCHI @ CERN - Nov, 2018 +# update: Riccardo Maria BIANCHI @ CERN - Jul, 2023 ################################################################################ cmake_minimum_required(VERSION 3.16...3.26) -#project(HelloGeoRead2G4) +project(HelloGeoRead2G4) # Find includes in current dir set(CMAKE_INCLUDE_CURRENT_DIR ON) # Find the needed dependencies, when building individually if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + message(STATUS "Compiling the example '${PROJECT_NAME}' as a standalone project...") find_package( GeoModelCore REQUIRED ) find_package( GeoModelIO REQUIRED ) + find_package( GeoModelG4 REQUIRED ) + find_package( Eigen3 REQUIRED ) endif() ## External dependencies. @@ -24,10 +28,10 @@ find_package( Geant4 REQUIRED ) include(${Geant4_USE_FILE}) # Populate a CMake variable with the sources -set( SRCS main.cpp ) +set( SRCS HelloGeoReadG4.cpp ) # Tell CMake to create the helloworld executable add_executable( hellogeoRead2G4 ${SRCS} ) # Link all needed libraries -target_link_libraries( hellogeoRead2G4 GeoModelDBManager GeoModelRead GeoModelKernel GeoModel2G4 ${Geant4_LIBRARIES}) +target_link_libraries( hellogeoRead2G4 GeoModelIO::GeoModelDBManager GeoModelIO::GeoModelRead GeoModelCore::GeoModelKernel GeoModel2G4 Eigen3::Eigen ${Geant4_LIBRARIES}) diff --git a/GeoModelExamples/HelloGeoRead2G4/HelloGeoReadG4.cpp b/GeoModelExamples/HelloGeoRead2G4/HelloGeoReadG4.cpp new file mode 100644 index 0000000000000000000000000000000000000000..b656e33e35f172eb3faeaec6bde5a9ee655b880e --- /dev/null +++ b/GeoModelExamples/HelloGeoRead2G4/HelloGeoReadG4.cpp @@ -0,0 +1,173 @@ +// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + +/* + * HelloGeoReadG4.cpp + * + * Author: Riccardo Maria BIANCHI @ CERN + * Created on: Nov, 2018 + * + */ + +// GeoModel includes +#include "GeoModel2G4/ExtParameterisedVolumeBuilder.h" +#include "GeoModelDBManager/GMDBManager.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelRead/ReadGeoModel.h" + +// Geant4 includes +#include "G4LogicalVolume.hh" + +// C++ includes +#include <cstdlib> // EXIT_FAILURE +#include <fstream> +#include <iostream> + +// Units +#include "GeoModelKernel/Units.h" +#define SYSTEM_OF_UNITS \ + GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' + +/* +// TODO: int main(int argc, char *argv[]) +int main() { + // Set a valid local geometry db path before first run + static const std::string path = "../geometry.db"; + + std::cout << "Using this DB file:" << path << std::endl; + + // check if DB file exists. If not, return. + // FIXME: TODO: this check should go in the 'GMDBManager' constructor. + std::ifstream infile(path.c_str()); + if (infile.good()) { + std::cout << "\n\tERROR!! A '" << path + << "' file exists already!! Please, remove, move, or rename " + "it before running this program. Exiting..."; + exit(EXIT_FAILURE); + } + infile.close(); +*/ +int main(int argc, char* argv[]) { + if (argc != 2) { + fprintf(stderr, "\nERROR!\nusage: %s <input_database.db>\n\n", argv[0]); + return 1; + } + // Get the input SQLite '.db' file containing the geometry + std::string line; + std::string fileName; + fileName = argv[1]; + std::cout << "Using this SQLite '.db' file:" << fileName << std::endl; + + // check if DB file exists. If not, return. + // FIXME: TODO: this check should go in the 'GMDBManager' constructor. + std::ifstream infile(fileName.c_str()); + if (!infile.good()) { + std::cout << "\n\tERROR!! A '" << fileName + << "' file does not exist!! Please, check the path of the " + "input file before running this program. Exiting..."; + exit(EXIT_FAILURE); + } + infile.close(); + + // open the DB + GMDBManager* db = new GMDBManager(fileName); + + /* Open database */ + if (db->checkIsDBOpen()) { + std::cout << "OK! Database is open!\n"; + } else { + std::cout << "Database is not open!\n"; + exit(EXIT_FAILURE); + } + + // -- testing the input database + std::cout << "\n=== Printing the list of all tables in the input DB:" + << std::endl; + db->printAllDBTables(); + std::cout << "\n=== Printing the list of all GeoMaterial nodes:" + << std::endl; + db->printAllMaterials(); + std::cout << "\n=== Printing the list of all GeoLogVol nodes:" << std::endl; + db->printAllLogVols(); + + /* setup the GeoModel reader */ + GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); + std::cout << "ReadGeoModel set.\n"; + + /* build the GeoModel geometry */ + GeoPhysVol* world = + readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory + // and get an handle to the 'world' volume + std::cout << "ReadGeoModel::buildGeoModel() done.\n"; + + // --- testing the imported ATLAS Geometry + + // get the GeoLogVol used for the 'world' volume + std::cout << "Getting the GeoLogVol used by the 'world' volume" + << std::endl; + const GeoLogVol* logVol = world->getLogVol(); + std::cout << "'world' GeoLogVol name: " << logVol->getName() << std::endl; + std::cout << "'world' GeoMaterial name: " + << logVol->getMaterial()->getName() << std::endl; + + // get number of children volumes + unsigned int nChil = world->getNChildVols(); + std::cout << "'world' number of children: " << nChil << std::endl; + + // loop over all children nodes + std::cout << "Looping over all 'volume' children (i.e., GeoPhysVol and " + "GeoFullPhysVol)..." + << std::endl; + for (unsigned int idx = 0; idx < nChil; ++idx) { + PVConstLink nodeLink = world->getChildVol(idx); + + if (dynamic_cast<const GeoVPhysVol*>(&(*(nodeLink)))) { + std::cout << "\t" + << "the child n. " << idx << " "; + const GeoVPhysVol* childVolV = &(*(nodeLink)); + if (dynamic_cast<const GeoPhysVol*>(childVolV)) + + { + const GeoPhysVol* childVol = + dynamic_cast<const GeoPhysVol*>(childVolV); + std::cout << "is a GeoPhysVol, whose GeoLogVol name is: " + << childVol->getLogVol()->getName() << std::endl; + std::cout << " and it has " << childVol->getNChildVols() + << " child volumes\n"; + + } else if (dynamic_cast<const GeoFullPhysVol*>(childVolV)) { + const GeoFullPhysVol* childVol = + dynamic_cast<const GeoFullPhysVol*>(childVolV); + std::cout << "is a GeoFullPhysVol, whose GeoLogVol name is: " + << childVol->getLogVol()->getName() << std::endl; + std::cout << " and it has " << childVol->getNChildVols() + << " child volumes\n"; + } + } else if (dynamic_cast<const GeoNameTag*>(&(*(nodeLink)))) { + std::cout << "\t" + << "the child n. " << idx << " is a GeoNameTag\n"; + const GeoNameTag* childVol = + dynamic_cast<const GeoNameTag*>(&(*(nodeLink))); + std::cout << "\t\tGeoNameTag's name: " << childVol->getName() + << std::endl; + // std::cout<< " and it has "<<childVol->getNChildVols()<<" child + // volumes\n"; + } + } + + // build the Geant4 geometry and get an hanlde to the world' volume + ExtParameterisedVolumeBuilder* builder = + new ExtParameterisedVolumeBuilder("ATLAS"); + std::cout << "Building G4 geometry." << std::endl; + G4LogicalVolume* g4World = builder->Build(world); + + std::cout << "This is the newly-created Geant4 G4LogicalVolume, ready to " + "be used: " + << g4World << std::endl; + + std::cout << "Everything done.\n"; + + return 0; +} diff --git a/GeoModelExamples/HelloGeoRead2G4/main.cpp b/GeoModelExamples/HelloGeoRead2G4/main.cpp deleted file mode 100644 index 229ba91de5aca341fe8725ba27041548f5bd098a..0000000000000000000000000000000000000000 --- a/GeoModelExamples/HelloGeoRead2G4/main.cpp +++ /dev/null @@ -1,136 +0,0 @@ -// Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration - -/* - * HelloGeoReadG4.cpp - * - * Author: Riccardo Maria BIANCHI @ CERN - * Created on: Nov, 2018 - * Updated on: Jul, 2023 by Marilena Bandieramonte - * - */ - -// GeoModel includes -#include "GeoModel2G4/ExtParameterisedVolumeBuilder.h" -#include "GeoModelDBManager/GMDBManager.h" -#include "GeoModelRead/ReadGeoModel.h" -#include "GeoModelKernel/GeoBox.h" -#include "GeoModelKernel/GeoPhysVol.h" -#include "GeoModelKernel/GeoFullPhysVol.h" -#include "GeoModelKernel/GeoNameTag.h" - -// Geant4 includes -#include "G4LogicalVolume.hh" - -// C++ includes -#include <iostream> -#include <fstream> -#include <cstdlib> // EXIT_FAILURE - - -// Units -#include "GeoModelKernel/Units.h" -#define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'GeoModelKernelUnits::cm' - - -int main(int argc, char *argv[]) -{ - - if(argc != 2) - { - fprintf(stderr, "\nERROR!\nUsage: %s geometry.db\n\n", argv[0]); - return 1; - } - // Get the input SQLite '.db' file containing the geometry - std::string line; - std::string fileName; - fileName = argv[1]; - std::cout << "Using this SQLite '.db' file:" << fileName << std::endl; - - - // check if DB file exists. If not, return. - // FIXME: TODO: this check should go in the 'GMDBManager' constructor. - std::ifstream infile(fileName.c_str()); - if ( ! infile.good() ) { - std::cout << "\n\tERROR!! A '" << fileName << "' file does not exist!! Please, check the path of the input file before running this program. Exiting..."; - exit(EXIT_FAILURE); - } - infile.close(); - - // open the DB - GMDBManager* db = new GMDBManager(fileName); - - /* Open database */ - if (db->checkIsDBOpen()) { - std::cout << "OK! Database is open!\n"; - } - else { - std::cout << "Database is not open!\n"; - exit(EXIT_FAILURE); - } - - // -- testing the input database - std::cout << "Printing the list of all GeoMaterial nodes" << std::endl; - db->printAllMaterials(); - - /* setup the GeoModel reader */ - GeoModelIO::ReadGeoModel readInGeo = GeoModelIO::ReadGeoModel(db); - std::cout << "ReadGeoModel set.\n"; - - - /* build the GeoModel geometry */ - GeoPhysVol* world = readInGeo.buildGeoModel(); // builds the whole GeoModel tree in memory and get an handle to the 'world' volume - std::cout << "ReadGeoModel::buildGeoModel() done.\n"; - - - - // --- testing the imported ATLAS Geometry - - // get the GeoLogVol used for the 'world' volume - std::cout << "Getting the GeoLogVol used by the 'world' volume" << std::endl; - const GeoLogVol* logVol = world->getLogVol(); - std::cout << "'world' GeoLogVol name: " << logVol->getName() << std::endl; - std::cout << "'world' GeoMaterial name: " << logVol->getMaterial()->getName() << std::endl; - - // get number of children volumes - unsigned int nChil = world->getNChildVols(); - std:: cout << "'world' number of children: " << nChil << std::endl; - - // loop over all children nodes - std::cout << "Looping over all 'volume' children (i.e., GeoPhysVol and GeoFullPhysVol)..." << std::endl; - for (unsigned int idx=0; idx<nChil; ++idx) { - PVConstLink nodeLink = world->getChildVol(idx); - - if ( dynamic_cast<const GeoVPhysVol*>( &(*( nodeLink ))) ) { - std::cout << "\t" << "the child n. " << idx << " "; - const GeoVPhysVol *childVolV = &(*( nodeLink )); - if ( dynamic_cast<const GeoPhysVol*>(childVolV) ) - - { - const GeoPhysVol* childVol = dynamic_cast<const GeoPhysVol*>(childVolV); - std::cout << "is a GeoPhysVol, whose GeoLogVol name is: " << childVol->getLogVol()->getName() << std::endl; - std::cout<< " and it has "<<childVol->getNChildVols()<<" child volumes\n"; - - } else if ( dynamic_cast<const GeoFullPhysVol*>(childVolV) ) { - const GeoFullPhysVol* childVol = dynamic_cast<const GeoFullPhysVol*>(childVolV); - std::cout << "is a GeoFullPhysVol, whose GeoLogVol name is: " << childVol->getLogVol()->getName() << std::endl; - std::cout<< " and it has "<<childVol->getNChildVols()<<" child volumes\n"; - } - } else if ( dynamic_cast<const GeoNameTag*>( &(*( nodeLink ))) ) { - std::cout << "\t" << "the child n. " << idx << " is a GeoNameTag\n"; - const GeoNameTag *childVol = dynamic_cast<const GeoNameTag*>(&(*( nodeLink ))); - std::cout << "\t\tGeoNameTag's name: " << childVol->getName() << std::endl; - //std::cout<< " and it has "<<childVol->getNChildVols()<<" child volumes\n"; - } - } - - // build the Geant4 geometry and get an hanlde to the world' volume - ExtParameterisedVolumeBuilder* builder = new ExtParameterisedVolumeBuilder("ATLAS"); - std::cout << "Building G4 geometry."<<std::endl; - G4LogicalVolume* g4World = builder->Build(world); - - std::cout << "This is the newly-created Geant4 G4LogicalVolume, ready to be used: " << g4World << std::endl; - - std::cout << "Everything done.\n"; - - return 0; -} diff --git a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h index 6bc29909c3d65daade334fe6ad765ecea8b44595..2b9e92f2f4edfc0f712366f3544d93e13d6afbb4 100644 --- a/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h +++ b/GeoModelIO/GeoModelDBManager/GeoModelDBManager/GMDBManager.h @@ -189,8 +189,16 @@ class GMDBManager { void printAllDBTables(); + /// Get tables and tables' columns from the input DB, if any, + /// and populate the cache that stores them void createTableDataCaches(); + + /// Get all tables from the input DB, if any, + /// and populate the cache that stores them void getAllDBTables(); + + /// Get tables' columns from the input DB, if any, + /// and populate the cache that stores them void getAllDBTableColumns(); int execQuery(std::string queryStr); @@ -247,12 +255,12 @@ class GMDBManager { /// methods to dump the DB std::vector<std::vector<std::string>> getChildrenTable(); - //Table names for Aux tables are of the form prefix_suffix - //where prefix depends on the type of data in the table - //and suffix depends on the plugin/publisher that provided it + // Table names for Aux tables are of the form prefix_suffix + // where prefix depends on the type of data in the table + // and suffix depends on the plugin/publisher that provided it - //These two require only the suffix, the prefix is already specified based on the - //table type being accessed + // These two require only the suffix, the prefix is already specified based + // on the table type being accessed std::vector<std::vector<std::string>> getPublishedFPVTable( std::string suffix = ""); std::vector<std::vector<std::string>> getPublishedAXFTable( @@ -264,10 +272,11 @@ class GMDBManager { std::unordered_map<unsigned int, std::string> getAll_TableIDsNodeTypes(); std::unordered_map<std::string, unsigned int> getAll_NodeTypesTableIDs(); - std::vector<std::vector<std::string>> getTableRecords(std::string tableName) const; // TODO: should be private? + std::vector<std::vector<std::string>> getTableRecords( + std::string tableName) const; // TODO: should be private? - //Test if a given table exists - //This requires the *full* table name (i.e. prefix_suffix) + // Test if a given table exists + // This requires the *full* table name (i.e. prefix_suffix) bool checkTable(std::string tableName) const; /** @@ -347,12 +356,14 @@ class GMDBManager { // verbosity level int m_verbose; - std::unordered_map<std::string, std::vector<std::string>> - m_tableNames; /// stores the column names for each table + /// stores the column names for each table + std::unordered_map<std::string, std::vector<std::string>> m_tableNames; + std::unordered_map<std::string, std::string> m_childType_tableName; - std::vector<std::string> - m_cache_tables; /// cache for the list of tables in the DB + /// cache for the list of tables in the DB + std::vector<std::string> m_cache_tables; + std::unordered_map<unsigned int, std::string> m_cache_tableId_tableName; /// cache for tableID-->tableName std::unordered_map<unsigned int, std::string> diff --git a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp index 1a9652d47b06f1917779dbf3766bda934485a234..33917ef935eb0f8f434f5469c0941d28486e0ba4 100644 --- a/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp +++ b/GeoModelIO/GeoModelDBManager/src/GMDBManager.cpp @@ -1,5 +1,5 @@ /* - Copyright (C) 2002-2022 CERN for the benefit of the ATLAS collaboration + Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration */ /* @@ -8,9 +8,12 @@ * - Aug 2018, R.M.Bianchi * - Jun 2020, R.M.Bianchi * - Aug 2020, R.M.Bianchi - Added support to publish lists of FullPhysVol and - * AlignableTransform nodes + * AlignableTransform nodes * - Jun 2022 - Riccardo Maria Bianchi, <riccardo.maria.bianchi@cern.ch>, * Added support for "Verbose" output + * - Jul 2023 - Riccardo Maria Bianchi, <riccardo.maria.bianchi@cern.ch>, + * Populate the caches in the constructor, so all print methods are + * available as soon as the input file is opened by the GMDBManager */ #include <GeoModelDBManager/GMDBManager.h> @@ -99,7 +102,9 @@ GMDBManager::GMDBManager(const std::string& path) m_dbIsOK = false; // FIXME: TODO: we should check the existence of the file, otherwise SQLite - // will create a new file from scratch Save the connection result + // will create a new file from scratch + + // Save the connection result int exit = sqlite3_open(path.c_str(), &m_d->m_dbSqlite); // Test if there was an error @@ -121,16 +126,12 @@ GMDBManager::GMDBManager(const std::string& path) m_verbose = std::stoi(env_p); } - // if (m_dbIsOK) { - // if ( ! (initDB()) ) { - // std::cout << "Error: database initialization failed" << std::endl; - // m_dbIsOK = false; - // } - // } - - // populate DB with fake data, only for debug - // loadTestData(); // TODO: we should move initDB() here, only for debug and - // Write + /// get info from the input DB, if populated, + /// and create caches storing those pieces of information + /// This call is only useful when reading an existing DB file. + /// If the file is new (that is, when we use GMDBManager to write a piece of + /// geometry into a new file, the call below does nothing. + createTableDataCaches(); } GMDBManager::~GMDBManager() { @@ -207,7 +208,7 @@ void GMDBManager::createTableDataCaches() { void GMDBManager::printAllRecords(const std::string& tableName) const { // --- print table name - std::cout << "\n---" << std::endl; + std::cout << "---" << std::endl; std::cout << "'" << tableName << "' in db:" << std::endl; // --- check if we stored table's data if (m_tableNames.find(tableName) == m_tableNames.end()) { @@ -232,16 +233,16 @@ void GMDBManager::printAllRecords(const std::string& tableName) const { } } std::cout << "---" << std::endl; - // TODO: I want to have a symbol like '---' to mean empty line when query - // gives 0 results. + // TODO: I want to have a symbol like '---' to mean empty line when + // query gives 0 results. } -// FIXME: TODO: we now return all records as text, but should we get double/int -// instead when appropriate? In that case, we should create dedicated methods -// for all tables, I guess. +// FIXME: TODO: we now return all records as text, but should we get +// double/int instead when appropriate? In that case, we should create +// dedicated methods for all tables, I guess. // TODO: fill a cache and returns that if asked a second time -std::vector<std::vector<std::string>> GMDBManager::getTableRecords(std::string tableName) const { - +std::vector<std::vector<std::string>> GMDBManager::getTableRecords( + std::string tableName) const { // container to be returned std::vector<std::vector<std::string>> records; // get the query statetement ready to be executed @@ -261,16 +262,17 @@ std::vector<std::vector<std::string>> GMDBManager::getTableRecords(std::string t res = sqlite3_step(stmt); // Execute SQL Statement. if (res == SQLITE_ROW) { std::vector<std::string> - nodeParams; // stores the data items contained in a single - // row + nodeParams; // stores the data items contained in a + // single row for (int i = 0; i < ctotal; i++) // Loop times the number of columns in the table { std::string s; const char* cc = (char*)sqlite3_column_text( - stmt, i); // Read each Column in the row as text FIXME: - // is there a method to get the right type, - // e.g. double, instead of text? + stmt, + i); // Read each Column in the row as text FIXME: + // is there a method to get the right type, + // e.g. double, instead of text? if (cc == NULL) s = "NULL"; else @@ -303,9 +305,12 @@ std::vector<std::vector<std::string>> GMDBManager::getTableFromNodeType( std::mutex coutMutex; coutMutex.lock(); printf( - "\t ===> WARNING! The geometry input file does not contain a table " - "for the %s nodes. That means that you are probably using an old " - "geometry file. Unless you know exactly what you are doing, please " + "\t ===> WARNING! The geometry input file does not contain a " + "table " + "for the %s 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", nodeType.c_str()); coutMutex.unlock(); @@ -328,8 +333,8 @@ bool GMDBManager::addListOfChildrenPositions( // NOTE: Choose the right function for your version of SQLite!! return addListOfRecordsToTable("ChildrenPositions", records); // needs SQLite >= 3.7.11 - // return addListOfRecordsToTableOld("ChildrenPositions", records); // - // old SQLite versions + // return addListOfRecordsToTableOld("ChildrenPositions", records); + // // old SQLite versions } return false; } @@ -346,16 +351,16 @@ bool GMDBManager::addListOfPublishedAlignableTransforms( tableName += "_"; tableName += suffix; // debug msg - // std::cout << "\nSaving the published '"<< nodeType << "' nodes to the - // custom table: '" + // std::cout << "\nSaving the published '"<< nodeType << "' nodes to + // the custom table: '" // << tableName << "'." << std::endl; } // create custom table first then add to it createTableCustomPublishedNodes(tableName, nodeType, &keyType); return addListOfRecordsToTable(tableName, records); // needs SQLite >= 3.7.11 - // return addListOfRecordsToTableOld( tableName, records ); // old SQLite - // versions + // return addListOfRecordsToTableOld( tableName, records ); // old + // SQLite versions } bool GMDBManager::addListOfPublishedFullPhysVols( @@ -368,16 +373,16 @@ bool GMDBManager::addListOfPublishedFullPhysVols( if ("" != suffix) { tableName += "_"; tableName += suffix; - // std::cout << "\nSaving the published '"<< nodeType << "' nodes to the - // custom table: '" + // std::cout << "\nSaving the published '"<< nodeType << "' nodes to + // the custom table: '" // << tableName << "'." << std::endl; } // create custom table first then add to it createTableCustomPublishedNodes(tableName, nodeType, &keyType); return addListOfRecordsToTable(tableName, records); // needs SQLite >= 3.7.11 - // return addListOfRecordsToTableOld( tableName, records ); // old SQLite - // versions + // return addListOfRecordsToTableOld( tableName, records ); // old + // SQLite versions } /* @@ -385,8 +390,8 @@ bool GMDBManager::addListOfRecordsToCustomTable(const std::vector<std::vector<std::string>> &records, std::string tableName ) { std::string nodeType = "GeoFullPhysVol"; - const std::type_info &keyType(typeid(std::string));//TODO: type should be -custom too!! + const std::type_info &keyType(typeid(std::string));//TODO: type should +be custom too!! // create custom table first createTableCustomPublishedNodes( tableName, nodeType, &keyType ); // add records to the newly-created table @@ -400,7 +405,8 @@ versions bool GMDBManager::addListOfRecords( const std::string geoType, const std::vector<std::vector<std::string>> records) { - // if (m_debug) qDebug() << "GMDBManager::addListOfRecords():" << geoType; + // if (m_debug) qDebug() << "GMDBManager::addListOfRecords():" << + // geoType; std::string tableName = m_childType_tableName[geoType]; @@ -415,8 +421,8 @@ bool GMDBManager::addListOfRecords( // NOTE: Choose the right function!! return addListOfRecordsToTable( tableName, records); // better, but needs SQLite >= 3.7.11 - // return addListOfRecordsToTableOld(tableName, records); // old SQLite - // versions + // return addListOfRecordsToTableOld(tableName, records); // old + // SQLite versions } else { if (m_debug) std::cout << "Info: no records to save for geoType '" << geoType @@ -457,8 +463,8 @@ bool GMDBManager::addListOfRecordsToTable( items.push_back( "'" + item + "'"); // TODO: we should differentiate strings from other - // values when inserting them in the table, as we now do - // for the std::variant version! + // values when inserting them in the table, as we now + // do for the std::variant version! } std::string values = joinVectorStrings(items, ","); sql += " (" + std::to_string(id) + "," + values + ")"; @@ -520,9 +526,9 @@ bool GMDBManager::addListOfRecordsToTable( else if (std::holds_alternative<std::string>(item)) { std::string str = std::get<std::string>(item); // NOTE: if item is a "NULL" string, we don't encapsulate it - // into quotes, so it is taken as the SQL's NULL value in the - // SQL string, and inserted as a NULL value in the table, - // instead of as a "NULL" text string + // into quotes, so it is taken as the SQL's NULL value in + // the SQL string, and inserted as a NULL value in the + // table, instead of as a "NULL" text string if (str == "NULL") items.push_back(str); else @@ -549,10 +555,10 @@ bool GMDBManager::addListOfRecordsToTable( return true; } -// TODO: this is for the old SQLite. Not needed anymore, I guess. ==> Just put a -// requirement on the newer version of SQLite3 in CMakeLists.txt. Perhaps, also -// check that GeoModelIO can run smoothly on older ATLAS releases, like 21.9 by -// taking a newer SQLite3 from LCG. +// TODO: this is for the old SQLite. Not needed anymore, I guess. ==> Just +// put a requirement on the newer version of SQLite3 in CMakeLists.txt. +// Perhaps, also check that GeoModelIO can run smoothly on older ATLAS +// releases, like 21.9 by taking a newer SQLite3 from LCG. // ***Note*** // old syntax, for SQLite in SLC6 // here below we build the syntax for multiple INSERT @@ -560,8 +566,9 @@ bool GMDBManager::addListOfRecordsToTable( // see: stackoverflow.com/questions/1609637 // // we want to build a query like this: -// queryStr = QString("INSERT INTO Materials (id, name) SELECT 1 as id, 'Air' -// as name UNION ALL SELECT 2,'Silicon' UNION ALL SELECT 368,'ShieldSteel' ") +// queryStr = QString("INSERT INTO Materials (id, name) SELECT 1 as id, +// 'Air' as name UNION ALL SELECT 2,'Silicon' UNION ALL SELECT +// 368,'ShieldSteel' ") // /* bool GMDBManager::addListOfRecordsToTableOld(const QString tableName, const @@ -576,18 +583,19 @@ tableColString = "(" + QString::fromStdString(tabColNames) + ")"; QStringList colNames = m_tableNames.at(tableName); unsigned int nRecords = records.size(); - qInfo() << "number of " << tableName << "records to insert into the DB:" << -nRecords; + qInfo() << "number of " << tableName << "records to insert into the DB:" +<< nRecords; - // SQLite has a limit on 'union' items, set at 500. So we have to split the -items if we have more. + // SQLite has a limit on 'union' items, set at 500. So we have to split +the items if we have more. // See: stackoverflow.com/questions/9527851/ unsigned int bunchSize = 500; if ( nRecords > bunchSize ) { qWarning() << "WARNING! " << nRecords << " records of type " << -tableName << "to store in the DB in one call! Call limit is " << bunchSize << " +tableName << "to store in the DB in one call! Call limit is " << bunchSize +<< " --> We split them in bunches..."; std::vector<QStringList> recordsCopy( records ); // TODO: maybe we @@ -606,22 +614,22 @@ should use a deque or queue, which have fast pop of first element? queryStr = queryStr.arg(tableColString); // insert table columns first = recordsCopy.begin(); - last = recordsCopy.size() > bunchSize ? recordsCopy.begin() + bunchSize -: recordsCopy.end(); + last = recordsCopy.size() > bunchSize ? recordsCopy.begin() + +bunchSize : recordsCopy.end(); std::vector<QStringList> recordsBunch( first, last ); // we take the -first 500 records recordsCopy.erase( first, last ); // we delete the first 500 -records if (m_debug) qDebug() << "start:" << start << "recordsBunch size:" << -recordsBunch.size() << "- recordsCopy size after removal:" << +first 500 records recordsCopy.erase( first, last ); // we delete the first +500 records if (m_debug) qDebug() << "start:" << start << "recordsBunch +size:" << recordsBunch.size() << "- recordsCopy size after removal:" << recordsCopy.size(); // --- first record // outcome should be like: " 1 as id, 'Air' as name " unsigned int id = start+1; // set the first ID as 'start' - QStringList recFirst = recordsBunch.front(); // access first record from -vector recordsBunch.erase( recordsBunch.begin() ); // delete first record if -(m_debug) qDebug() << "after taking first record - recordsBunch size:" << -recordsBunch.size(); + QStringList recFirst = recordsBunch.front(); // access first record +from vector recordsBunch.erase( recordsBunch.begin() ); // delete first +record if (m_debug) qDebug() << "after taking first record - recordsBunch +size:" << recordsBunch.size(); // first item in the first record (it is the ID) QString firstCol = colNames[0]; @@ -647,9 +655,9 @@ recordsBunch.size(); // DEBUG if (tableName == -"Functions") { if (recs[1].length() > 65000) { std::cout << "LONG STRING! size: -" << recs[1].length() << std::endl; std::cout << "LONG STRING! string: " << -recs[1].toStdString() << std::endl << std::endl; +"Functions") { if (recs[1].length() > 65000) { std::cout << "LONG STRING! +size: " << recs[1].length() << std::endl; std::cout << "LONG STRING! string: +" << recs[1].toStdString() << std::endl << std::endl; } } //------ @@ -662,8 +670,8 @@ recs[1].toStdString() << std::endl << std::endl; } // join items into a string and add the SQL commands QString itemsStr = items.join(", "); - queryStr += " UNION ALL SELECT " + QString::number(id) + ", " + -itemsStr; + queryStr += " UNION ALL SELECT " + QString::number(id) + ", +" + itemsStr; } //qDebug() << "queryStr:" << queryStr; @@ -812,8 +820,8 @@ std::vector<std::string> GMDBManager::getItemAndType(unsigned int tableId, std::vector<std::string> GMDBManager::getItemFromTableName( std::string tableName, unsigned int id) { - // FIXME: when you create caches for all tables, replace this method with a - // lookup action in the cache. + // FIXME: when you create caches for all tables, replace this method + // with a lookup action in the cache. /* * Get the object from DB. */ @@ -844,9 +852,10 @@ std::vector<std::string> GMDBManager::getItemFromTableName( i++) // Loop times the number of columns in the table { std::string s = (char*)sqlite3_column_text( - stmt, i); // Read each Column in the row as text FIXME: - // is there a method to get the right type, - // e.g. double, instead of text? + stmt, + i); // Read each Column in the row as text FIXME: + // is there a method to get the right type, + // e.g. double, instead of text? item.push_back(s); } } @@ -953,8 +962,9 @@ int GMDBManager::loadGeoNodeTypesAndBuildCache() { return rc; } -// FIXME: should throw an error if the method `loadGeoNodeTypesAndBuildCache()` -// was not called before calling this method +// FIXME: should throw an error if the method +// `loadGeoNodeTypesAndBuildCache()` was not called before calling this +// method std::string GMDBManager::getTableNameFromTableId(unsigned int tabId) { return m_cache_tableId_tableName[tabId]; } @@ -999,14 +1009,12 @@ sqlite3_stmt* GMDBManager::Imp::selectAllFromTableSortBy( return st; } -bool GMDBManager::Imp::checkTable_imp( - std::string tableName) const { +bool GMDBManager::Imp::checkTable_imp(std::string tableName) const { theManager->checkIsDBOpen(); sqlite3_stmt* st = nullptr; // SQLite statement to be returned int rc = -1; // SQLite return code // set the SQL query string - std::string sql = - fmt::format("SELECT * FROM {0}", tableName); + std::string sql = fmt::format("SELECT * FROM {0}", tableName); // prepare the query rc = sqlite3_prepare_v2(m_dbSqlite, sql.c_str(), -1, &st, NULL); if (rc != SQLITE_OK) return false; @@ -1051,7 +1059,8 @@ void GMDBManager::getAllDBTables() { std::vector<std::string> tables; // define a query string containing the necessary SQL instructions std::string queryStr = - "SELECT name FROM sqlite_master WHERE type ='table' AND name NOT LIKE " + "SELECT name FROM sqlite_master WHERE type ='table' AND name NOT " + "LIKE " "'sqlite_%';"; // prepare the query with the query string sqlite3_stmt* stmt; @@ -1098,15 +1107,15 @@ void GMDBManager::getAllDBTableColumns() { &stmt, NULL); if (rc == SQLITE_OK) { // OK, now looping over table's columns... - // will continue to go down the rows (columns in your table) till - // there are no more + // will continue to go down the rows (columns in your table) + // till there are no more while (sqlite3_step(stmt) == SQLITE_ROW) { // sprintf(colName, "%s", sqlite3_column_text(stmt, 1)); colName = std::string(reinterpret_cast<const char*>( sqlite3_column_text(stmt, 0))); - // do something with colName because it contains the column's - // name + // do something with colName because it contains the + // column's name m_tableNames[tableName].push_back(colName); } } @@ -1115,7 +1124,8 @@ void GMDBManager::getAllDBTableColumns() { // TODO: currently, we retrieve published data as strings, but we want to // retrieve that according to the original data type -std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable( std::string suffix ) { +std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable( + std::string suffix) { std::string tableName = "PublishedFullPhysVols"; // default table name if ("" != suffix) { tableName += "_"; @@ -1126,7 +1136,8 @@ std::vector<std::vector<std::string>> GMDBManager::getPublishedFPVTable( std::st } // TODO: currently, we retrieve published data as strings, but we want to // retrieve that according to the original data type -std::vector<std::vector<std::string>> GMDBManager::getPublishedAXFTable( std::string suffix ) { +std::vector<std::vector<std::string>> GMDBManager::getPublishedAXFTable( + std::string suffix) { std::string tableName = "PublishedAlignableTransforms"; // default table name if ("" != suffix) { @@ -1207,10 +1218,10 @@ std::vector<std::string> tableColTypes, const std::vector<std::vector<std::string>> &records ) { if( tableColNames.size() == 0 ) throw -std::runtime_error("GMDBManager::createCustomTable -- The list of columns' names -is empty!!"); if( tableColTypes.size() == 0 ) throw -std::runtime_error("GMDBManager::createCustomTable -- The list of columns' types -is empty!!"); +std::runtime_error("GMDBManager::createCustomTable -- The list of columns' +names is empty!!"); if( tableColTypes.size() == 0 ) throw +std::runtime_error("GMDBManager::createCustomTable -- The list of columns' +types is empty!!"); int rc = -1; // sqlite's return code std::string queryStr; @@ -1225,10 +1236,11 @@ is empty!!"); storeTableColumnNames(tab); // prepare the dynamic query to create the custom table - queryStr = fmt::format( "create table {0} ( id integer primary key ", tab[0] + queryStr = fmt::format( "create table {0} ( id integer primary key ", +tab[0] ); for( int ii=0; ii<tableColNames.size(); ++ii) { std::string colStr = -fmt::format( ", {0} {1} ", tableColNames[ii], tableColTypes[ii] ); queryStr += -colStr; +fmt::format( ", {0} {1} ", tableColNames[ii], tableColTypes[ii] ); queryStr ++= colStr; } queryStr += ")"; @@ -1249,11 +1261,13 @@ bool GMDBManager::createCustomTable( records) { if (tableColNames.size() == 0) throw std::runtime_error( - "GMDBManager::createCustomTable -- The list of columns' names is " + "GMDBManager::createCustomTable -- The list of columns' names " + "is " "empty!!"); if (tableColTypes.size() == 0) throw std::runtime_error( - "GMDBManager::createCustomTable -- The list of columns' types is " + "GMDBManager::createCustomTable -- The list of columns' types " + "is " "empty!!"); std::string queryStr; @@ -1272,22 +1286,23 @@ bool GMDBManager::createCustomTable( for (size_t ii = 0; ii < tableColNames.size(); ++ii) { std::string colType = ""; - // -- Here we check the datum's type, which is more universal than using - // string-encoded types + // -- Here we check the datum's type, which is more universal than + // using string-encoded types // -- but this does not work if the first entry of a given column is // empty. - // -- If so, the 'null' entry is taken as string, and the column is set - // as containing TEXT... convert std::variant types to SQLite data types - // (see SQLite documentation) + // -- If so, the 'null' entry is taken as string, and the column is + // set as containing TEXT... convert std::variant types to SQLite + // data types (see SQLite documentation) /* - if( std::holds_alternative<int>(records[0][ii]) ) colType = + if( std::holds_alternative<int>(records[0][ii]) ) colType = "INTEGER"; else if( std::holds_alternative<long>(records[0][ii]) ) colType = "INTEGER"; else if( - std::holds_alternative<float>(records[0][ii]) ) colType = "REAL"; - else if( std::holds_alternative<double>(records[0][ii]) ) colType = - "REAL"; else if( std::holds_alternative<std::string>(records[0][ii]) ) - colType = "TEXT"; else throw std::runtime_error("No std::variant - alternative has been found!\n"); + std::holds_alternative<float>(records[0][ii]) ) colType = + "REAL"; else if( std::holds_alternative<double>(records[0][ii]) ) + colType = "REAL"; else if( + std::holds_alternative<std::string>(records[0][ii]) ) colType = + "TEXT"; else throw std::runtime_error("No std::variant alternative + has been found!\n"); */ if (tableColTypes[ii] == "INT") @@ -1329,8 +1344,8 @@ bool GMDBManager::createTables() { std::string tableName; std::vector<std::string> tab; - // create a table to store the relation between the types of GeoNodes and - // the name of the table + // create a table to store the relation between the types of GeoNodes + // and the name of the table tableName = "dbversion"; tab.insert(tab.begin(), {tableName, "id", "version"}); storeTableColumnNames(tab); @@ -1340,19 +1355,21 @@ bool GMDBManager::createTables() { rc = execQuery(queryStr); tab.clear(); - // create a table to store the relation between the types of GeoNodes and - // the name of the table + // create a table to store the relation between the types of GeoNodes + // and the name of the table tableName = "GeoNodesTypes"; tab.insert(tab.begin(), {tableName, "id", "nodeType", "tableName"}); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} varchar, {3} varchar)", + "create table {0}({1} integer primary key, {2} varchar, {3} " + "varchar)", tab[0], tab[1], tab[2], tab[3]); rc = execQuery(queryStr); tab.clear(); - // create a table to store the mother-daughter relationships between nodes - // (notably, between the [Full]PhysVols as the parents and their children) + // create a table to store the mother-daughter relationships between + // nodes (notably, between the [Full]PhysVols as the parents and their + // children) tableName = "ChildrenPositions"; tab.push_back(tableName); tab.push_back("id"); @@ -1365,16 +1382,19 @@ bool GMDBManager::createTables() { tab.push_back("childCopyNumber"); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} integer, {3} integer " - "not null REFERENCES GeoNodesTypes(id), {4} integer, {5} integer, {6} " - "integer not null REFERENCES GeoNodesTypes(id), {7} integer not null, " + "create table {0}({1} integer primary key, {2} integer, {3} " + "integer " + "not null REFERENCES GeoNodesTypes(id), {4} integer, {5} integer, " + "{6} " + "integer not null REFERENCES GeoNodesTypes(id), {7} integer not " + "null, " "{8} integer not null)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8]); rc = execQuery(queryStr); tab.clear(); - // create a table to store information about the 'root' volume (also known - // as the 'world' volume) + // create a table to store information about the 'root' volume (also + // known as the 'world' volume) tableName = "RootVolume"; tab.push_back(tableName); tab.push_back("id"); @@ -1382,7 +1402,8 @@ bool GMDBManager::createTables() { tab.push_back("volTable"); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} integer not null, {3} " + "create table {0}({1} integer primary key, {2} integer not null, " + "{3} " "integer not null REFERENCES GeoNodesTypes(id))", tab[0], tab[1], tab[2], tab[3]); rc = execQuery(queryStr); @@ -1431,7 +1452,8 @@ bool GMDBManager::createTables() { tab.push_back("material"); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} varchar, {3} integer " + "create table {0}({1} integer primary key, {2} varchar, {3} " + "integer " "not null, {4} integer not null)", tab[0], tab[1], tab[2], tab[3], tab[4]); if (0 == (rc = execQuery(queryStr))) { @@ -1450,7 +1472,8 @@ bool GMDBManager::createTables() { tab.push_back("elements"); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} varchar, {3} varchar, " + "create table {0}({1} integer primary key, {2} varchar, {3} " + "varchar, " "{4} varchar)", tab[0], tab[1], tab[2], tab[3], tab[4]); if (0 == (rc = execQuery(queryStr))) { @@ -1470,7 +1493,8 @@ bool GMDBManager::createTables() { tab.push_back("A"); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} varchar, {3} varchar, " + "create table {0}({1} integer primary key, {2} varchar, {3} " + "varchar, " "{4} varchar, {5} varchar)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5]); if (0 == (rc = execQuery(queryStr))) { @@ -1488,7 +1512,8 @@ bool GMDBManager::createTables() { tab.push_back("parameters"); storeTableColumnNames(tab); queryStr = fmt::format( - "create table {0}({1} integer primary key, {2} varchar, {3} varchar)", + "create table {0}({1} integer primary key, {2} varchar, {3} " + "varchar)", tab[0], tab[1], tab[2], tab[3]); if (0 == (rc = execQuery(queryStr))) { storeNodeType(geoNode, tableName); @@ -1572,7 +1597,8 @@ bool GMDBManager::createTables() { storeTableColumnNames(tab); queryStr = fmt::format( "create table {0}({1} integer primary key, {2} integer not null " - "REFERENCES Functions(id), {3} integer not null, {4} integer not null " + "REFERENCES Functions(id), {3} integer not null, {4} integer not " + "null " "REFERENCES GeoNodesTypes(id), {5} integer)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5]); if (0 == (rc = execQuery(queryStr))) { @@ -1601,7 +1627,8 @@ bool GMDBManager::createTables() { storeTableColumnNames(tab); queryStr = fmt::format( "create table {0}({1} integer primary key, {2} real, {3} real, {4} " - "real, {5} real, {6} real, {7} real, {8} real, {9} real, {10} real, " + "real, {5} real, {6} real, {7} real, {8} real, {9} real, {10} " + "real, " "{11} real, {12} real, {13} real)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8], tab[9], tab[10], tab[11], tab[12], tab[13]); @@ -1631,7 +1658,8 @@ bool GMDBManager::createTables() { storeTableColumnNames(tab); queryStr = fmt::format( "create table {0}({1} integer primary key, {2} real, {3} real, {4} " - "real, {5} real, {6} real, {7} real, {8} real, {9} real, {10} real, " + "real, {5} real, {6} real, {7} real, {8} real, {9} real, {10} " + "real, " "{11} real, {12} real, {13} real)", tab[0], tab[1], tab[2], tab[3], tab[4], tab[5], tab[6], tab[7], tab[8], tab[9], tab[10], tab[11], tab[12], tab[13]); @@ -1740,7 +1768,8 @@ void GMDBManager::storeNodeType(std::string nodeType, std::string tableName) { // QSqlQuery q; // // // // qDebug() << "Loading Shapes..."; -// // if (!q.prepare(QLatin1String("insert into Shapes(name) values(?)"))) { +// // if (!q.prepare(QLatin1String("insert into Shapes(name) values(?)"))) +// { // // showError(q.lastError()); // // return; // // } @@ -1757,8 +1786,9 @@ void GMDBManager::storeNodeType(std::string nodeType, std::string tableName) { // QVariant leadId = // addMaterial(QLatin1String("Lead"),QLatin1String("density"),QLatin1String("elements")); // -// QVariant worldLogId = addLogVol(QLatin1String("WorldLog"), boxId, airId); -// QVariant toyLogId = addLogVol(QLatin1String("ToyLog"), coneId, leadId); +// QVariant worldLogId = addLogVol(QLatin1String("WorldLog"), boxId, +// airId); QVariant toyLogId = addLogVol(QLatin1String("ToyLog"), coneId, +// leadId); // // QVariant rootPhysId = addPhysVol(worldLogId, QVariant()); // no parent // QVariant childPhysId = addPhysVol(toyLogId, rootPhysId); diff --git a/documentation/docs/dev/troubleshooting.md b/documentation/docs/dev/troubleshooting.md index af2b2414d9998198a1921bc070c5feff8f385a11..65218e92ad17cfcbb5cac35f78b798daf6686d30 100644 --- a/documentation/docs/dev/troubleshooting.md +++ b/documentation/docs/dev/troubleshooting.md @@ -10,6 +10,18 @@ If, after starting `gmex`, you get a window that tells you that was not possible * try to restart your machine. Seriously! :-) Sometimes, after updates to the graphical packages (those can happen behind the scene, without you to notice them), the system needs to be restarted. I experienced that personally: `gmex` was failing to start, when I was trying a new version of our 3D engine, Coin3D, and I was trying to find for the cause in the code of Coin3D itself... But then my OpenGL-accelerated terminal emulator, Alacritty, had stopped working as well; and that gave me a hint that something global was happening... So, I Googled, and I found a suggestion to resart the machine to get the graphics drivers sync between each others. Try that first, it can help! ;-) * your OpenGL installation / support is not correct / fully-installed. In that case, you should look for instructions to install proper OpenGL support on your system. +### GMEX crashes on the latest Ubuntu + +The GeoModelExplorer (GMEX) application appears to crash when run on the latest version of the Ubuntu "Wayland" window manager. + +The problem is that the SoQt/Coin third-party packages we use in GMEX have not been ported to work to the latest Wayland yet. As far as we know, all applications that use the Coin/SoQt graphics layers as their graphics interface crash on the latest Wayland. + +The Coin3D community is aware of the problem but there are no fixes, yet. + +Therefore, we strongly suggest to use the alternative X11 window manager when running GEMX (or all other SoQt/Coin3D-based applications) on Ubuntu, for the time being. + + + ## Packages ### macOS / Homebrew diff --git a/documentation/docs/start/install.md b/documentation/docs/start/install.md index 807d27ee92f14e29bb76f706c0a4e27add718cbe..b30c47468c612a5554019b2952967d0bd67cf4e2 100644 --- a/documentation/docs/start/install.md +++ b/documentation/docs/start/install.md @@ -42,6 +42,13 @@ sudo apt install geomodel-visualization-dev If you have outdated packages, these commands will replace those packages with the most recent version. +!!! warning + + The GeoModelExplorer (GMEX) application appears to crash when run on the latest version of the Ubuntu "Wayland" window manager. The problem is that the SoQt/Coin third-party packages we use in GMEX have not been ported to work to the latest Wayland yet. As far as we know, all applications that use the Coin/SoQt graphics layers as their graphics interface crash on the latest Wayland. The Coin3D community is aware of the problem but there are no fixes, yet. + + We strongly suggest to use the alternative X11 window manager when running GEMX (or all other SoQt/Coin3D-based applications) on Ubuntu, for the time being. + + ## macOS On macOS, we use the [Homebrew package manager](http://brew.sh) to handle and install the GeoModel packages. If you don't have Homebrew installed on your machine, you should first install it by following the instructions on the Homebrew website: <http://brew.sh>. Please be attentive to any instructions printed after the installation procedure; there might be environment variables to set.