diff --git a/GeoModelExamples/HelloToyWrite/CMakeLists.txt b/GeoModelExamples/HelloToyWrite/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..63164e06728d79a3a8b6c2262066c01d03ee292e --- /dev/null +++ b/GeoModelExamples/HelloToyWrite/CMakeLists.txt @@ -0,0 +1,33 @@ +# Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration + +################################################################################ +# Package: HelloToy +# author: Riccardo Maria BIANCHI @ CERN - Aug, 2020 +################################################################################ + +cmake_minimum_required(VERSION 3.16...3.26) + +project(HelloToyWrite) + +# Compile with C++17 +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS ON) + +# Find the needed dependencies, when building individually +if(CMAKE_SOURCE_DIR STREQUAL PROJECT_SOURCE_DIR) + find_package( GeoModelCore REQUIRED ) + find_package( GeoModelIO REQUIRED ) +endif() + +# Find includes in current dir +set(CMAKE_INCLUDE_CURRENT_DIR ON) + +# Populate a CMake variable with the sources +set(SRCS main.cpp ) + +# Tell CMake to create the 'helloToy' executable +add_executable( helloToyWrite ${SRCS} ) + +# Link all needed libraries +target_link_libraries( helloToyWrite GeoModelCore::GeoModelKernel GeoModelIO::GeoModelWrite ) diff --git a/GeoModelExamples/HelloToyWrite/main.cpp b/GeoModelExamples/HelloToyWrite/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..9f6b35e3ba9e85b85b3c236ef3bd84d2e6b7c66f --- /dev/null +++ b/GeoModelExamples/HelloToyWrite/main.cpp @@ -0,0 +1,270 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +/* +* author: Riccardo Maria Bianchi @ CERN - 2020 +* +* The example show how to write a more complex Toy detector geometry, +* through the use of GeoSerialTransformers. +* It also shows how to publish the list of FullPhysVol and AlignableTransform nodes, +* to be retrieved later (for example, when setting the readout geometry up). +* +*/ + +#include "GeoModelKernel/GeoDefinitions.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoTube.h" +#include "GeoModelKernel/GeoLogVol.h" +#include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/GeoFullPhysVol.h" +#include "GeoModelKernel/GeoTransform.h" +#include "GeoModelKernel/GeoSerialDenominator.h" +#include "GeoModelKernel/GeoAlignableTransform.h" +#include "GeoModelKernel/GeoSerialTransformer.h" +#include "GeoModelKernel/GeoPublisher.h" +#include "GeoModelKernel/GeoUtilFunctions.h" + +#include "GeoGenericFunctions/AbsFunction.h" +#include "GeoGenericFunctions/Variable.h" +#include "GeoGenericFunctions/Sin.h" +#include "GeoGenericFunctions/Cos.h" + +#include "GeoModelDBManager/GMDBManager.h" + +#include "GeoModelWrite/WriteGeoModel.h" + +// Units +#include "GeoModelKernel/Units.h" +#define SYSTEM_OF_UNITS GeoModelKernelUnits // so we will get, e.g., 'SYSTEM_OF_UNITS::cm' + +// C++ includes +#include <iostream> +#include <fstream> +#include <cstdlib> // EXIT_FAILURE + +using namespace GeoGenfun; +using namespace GeoXF; + +int main(int argc, char *argv[]) +{ + //-----------------------------------------------------------------------------------// + // 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); + GeoElement* Iron = new GeoElement ("Iron" ,"Fe" , 26.0 , 55.847 *gr/mole); + GeoElement* Carbon = new GeoElement ("Carbon" ,"C" , 6.0 , 12.0107 *gr/mole); + GeoElement* Sillicon = new GeoElement ("Silicon" ,"Si" , 14.0 , 28.085 *gr/mole); + + // Define the materials + + // Air: Nitrogen + Oxygen + Argon + Hydrogen + 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(); + + // Steel: Iron + Carbon + GeoMaterial* steel = new GeoMaterial("Steel", 7.9 *gr/cm3); + steel->add(Iron , 0.98); + steel->add(Carbon, 0.02); + steel->lock(); + + // Silicon 100% (Detector) + GeoMaterial* silicon = new GeoMaterial("Silicon", 2.329 *gr/cm3); + silicon->add(const_cast<GeoElement*> (Sillicon), 1.0); + silicon->lock(); + + // Carbon + GeoMaterial* carbon = new GeoMaterial("Carbon", 2.329 *gr/cm3); + carbon->add(const_cast<GeoElement*> (Carbon), 1.0); + carbon->lock(); + + + //--------------------------------------// + // Next make the box that describes + // the shape of the toy volume: + //--------------------------------------// + const GeoBox *toyBox = new GeoBox(1200*SYSTEM_OF_UNITS::cm,1200*SYSTEM_OF_UNITS::cm, 1200*SYSTEM_OF_UNITS::cm); + + //--------------------------------------// + // Bundle this with a material + // into a logical volume: + //--------------------------------------// + const GeoLogVol *toyLog = new GeoLogVol("ToyLog", toyBox, air); // + + //--------------------------------------// + // ..And create a physical volume: + //--------------------------------------// + GeoPhysVol *toyPhys = new GeoPhysVol(toyLog); + + //--------------------------------------// + // Daughters + //--------------------------------------// + const GeoTube *ringTube = new GeoTube(500*SYSTEM_OF_UNITS::cm, 1000*SYSTEM_OF_UNITS::cm, 5.0*SYSTEM_OF_UNITS::cm); + + // Bundle this with a material // + // into a logical volume: // + const GeoLogVol *ringLog = new GeoLogVol("RingLog", ringTube, carbon); + + // Make 100 of these // + // within the volume of the toy: // + GeoSerialDenominator *ringName = new GeoSerialDenominator("RING"); + toyPhys->add(ringName); + + // Instanciate a GeoPublisher, to publish the list of FullPhysVol and AlignableTransforms nodes + GeoPublisher* publisher = new GeoPublisher; + // Optional - We set a name for the publisher: it will be appended to the name of the DB tables that host our published AXF and FPV nodes. + // Note : This is not compulsory: if not set, the default table name will be used; + // however, it helps to keep the output data well organized. + publisher->setName("HelloToyExample"); + + for (int i=0;i<100;i++) { + GeoFullPhysVol *ringPhys = new GeoFullPhysVol(ringLog); + GeoAlignableTransform *xform = new GeoAlignableTransform(GeoTrf::TranslateZ3D((i-50)*20*SYSTEM_OF_UNITS::cm)); + toyPhys->add(xform); + toyPhys->add(ringPhys); + + + // *** publish the list of FPV and AXF nodes *** + // in this example, we use integer-based keys for FullPhysVols... + unsigned int keyInt = i+1; + publisher->publishNode<GeoVFullPhysVol*,unsigned>(ringPhys, keyInt); + // ...and string-based keys for AlignableTransforms + std::string keyStr = "HelloToy-AXF-" + std::to_string(i+1); + publisher->publishNode<GeoAlignableTransform*,std::string>(xform, keyStr); + + // std::cout << "step1 - FPV, key: " << keyInt << std::endl; + // << " - xf: " // we cannot get the XF of a FPV direct;y anymore, it seems... + // GeoUtilFunctions::printTrf(ringPhys->getAbsoluteTransform()); + + } + + + //--------------------------------------// + // Now, in addition to active daughters, + // add some passive material. + // This is done here using + // the "SerialTransformer", + // our way of parameterizing volumes. + // It does not need to be done this way, + // but we want to provide an example of + // parametrizations in the Toy + //--------------------------------------// + + GeoBox *sPass = new GeoBox(5.0*SYSTEM_OF_UNITS::cm, 30*SYSTEM_OF_UNITS::cm, 30*SYSTEM_OF_UNITS::cm); + GeoLogVol *lPass = new GeoLogVol("Passive", sPass, steel); + GeoPhysVol *pPass = new GeoPhysVol(lPass); + + GeoBox *sIPass = new GeoBox(4*SYSTEM_OF_UNITS::cm, 25*SYSTEM_OF_UNITS::cm, 25*SYSTEM_OF_UNITS::cm); + GeoLogVol *lIPass = new GeoLogVol("InnerPassive", sIPass, silicon); + GeoPhysVol *pIPass = new GeoPhysVol(lIPass); + + pPass->add(pIPass); + + const unsigned int NPLATES=100; + Variable i; + Sin sin; + GENFUNCTION f = 360*SYSTEM_OF_UNITS::deg/NPLATES*i; + GENFUNCTION g = sin(4*f); + GENFUNCTION h = -g; + TRANSFUNCTION t1 = Pow(GeoTrf::RotateZ3D(1.0),f)*GeoTrf::TranslateX3D(1100*SYSTEM_OF_UNITS::cm)*Pow(GeoTrf::TranslateZ3D(800*SYSTEM_OF_UNITS::cm),g); + TRANSFUNCTION t2 = Pow(GeoTrf::RotateZ3D(1.0),f)*GeoTrf::TranslateX3D(1100*SYSTEM_OF_UNITS::cm)*Pow(GeoTrf::TranslateZ3D(800*SYSTEM_OF_UNITS::cm),h); + + //--------------------------------------// + // Inside, by the way, the serial transformer + // will evaluate the functions: + // HepTransform3D xf = t1(i), for i=1,NPLATES.... + //--------------------------------------// + + GeoSerialDenominator *pass1Name = new GeoSerialDenominator("PASSIVE-1-"); + GeoSerialTransformer *s1 = new GeoSerialTransformer(pPass,&t1, NPLATES); + toyPhys->add(pass1Name); + toyPhys->add(s1); + + GeoSerialDenominator *pass2Name = new GeoSerialDenominator("PASSIVE-2-"); + GeoSerialTransformer *s2 = new GeoSerialTransformer(pPass,&t2, NPLATES); + toyPhys->add(pass2Name); + toyPhys->add(s2); + + + + //------------------------------------------------------------------------------------// + // Writing the geometry to file + //------------------------------------------------------------------------------------// + std::string path = "geometry.db"; + + // check if DB file exists. If yes, delete it. + std::ifstream infile(path.c_str()); + if ( infile.good() ) { + if( remove( path.c_str() ) != 0 ) + perror( "Error deleting file" ); + else { + std::string msg = "Previously existing " + path + " successfully deleted"; + puts( msg.c_str() ); + } + } + infile.close(); + + // open the DB connection + GMDBManager db(path); + + // check the DB connection + if (db.checkIsDBOpen()) { + std::cout << "OK! Database is open!" << std::endl; + } else { + std::cout << "Database ERROR!! Exiting..." << std::endl; + exit(EXIT_FAILURE); + } + + // Dump the tree volumes to a local file + std::cout << "Dumping the GeoModel geometry to the DB file..." << std::endl; + GeoModelIO::WriteGeoModel dumpGeoModelGraph(db); // init the GeoModel node action + toyPhys->exec(&dumpGeoModelGraph); // visit all GeoModel nodes + + // Save the GeoModel tree to the SQlite DB file. + // We pass a pointer to the GeoPublisher as well, so the list of published + // FullPhysVol and AlignableTransform nodes will be stored into the DB too. + dumpGeoModelGraph.saveToDB( publisher ); + + std::cout << "\n-----\nDONE. Geometry saved.\n-----\n" <<std::endl; + + + //------------------------------------------------------------------------------------// + // Testing the persitified geometry + //------------------------------------------------------------------------------------// +/* + std::cout << "\nTest - list of all the GeoFullPhysVol nodes in the persistified geometry:" << std::endl; + db.printAllFullPhysVols(); + std::cout << "\nTest - list of all the GeoAlignableTransform nodes in the persistified geometry:" << std::endl; + db.printAllAlignableTransforms(); + + std::cout << "\nTest - list of all the 'published' GeoFullPhysVol nodes in the persistified geometry:" << std::endl; + db.printAllPublishedFullPhysVols( publisher->getName() ); + std::cout << "\nTest - list of all the 'published' GeoAlignableTransform nodes in the persistified geometry:" << std::endl; + db.printAllPublishedAlignableTransforms( publisher->getName() ); +*/ + // cleaning + delete publisher; + publisher = nullptr; + + + return 0; + +} + diff --git a/GeoModelIO/CMakeLists.txt b/GeoModelIO/CMakeLists.txt index 6cb40e33ebe7250a82f1705d1a27dc54a369dbec..42da54bdab8163c44c63ab87ec31907e40b7cf1c 100644 --- a/GeoModelIO/CMakeLists.txt +++ b/GeoModelIO/CMakeLists.txt @@ -7,9 +7,10 @@ project( "GeoModelIO" VERSION ${GeoModel_VERSION} LANGUAGES CXX ) # add_subdirectory( GeoModelErrorHandler ) // unused at the moment. add_subdirectory( GeoModelDBManager ) add_subdirectory( TFPersistification ) -#add_subdirectory( GeoModelRead ) -#add_subdirectory( GeoModelWrite ) -#add_subdirectory( GeoModelIOHelpers ) +# add_subdirectory( GeoModelRead ) +add_subdirectory( GeoModelWrite ) +# add_subdirectory( GeoModelIOHelpers ) +add_subdirectory( GeoModelCppHelpers ) # Create and install the version description of the project. include( CMakePackageConfigHelpers )