diff --git a/GeoModelCore/GeoModelKernel/CMakeLists.txt b/GeoModelCore/GeoModelKernel/CMakeLists.txt index cd075745137fa0cddbd5193efd4ab401d86ae7a8..819c6c9521ce5d44334faedad600506537153082 100644 --- a/GeoModelCore/GeoModelKernel/CMakeLists.txt +++ b/GeoModelCore/GeoModelKernel/CMakeLists.txt @@ -47,8 +47,19 @@ install( FILES ${HEADERS} COMPONENT Development ) + file(GLOB_RECURSE files "tests/*.cxx") +foreach(_exeFile ${files}) + get_filename_component(_theExec ${_exeFile} NAME_WE) + get_filename_component(_theLoc ${_exeFile} DIRECTORY) + + if(${_theLoc} MATCHES "DoNotBuild") + continue() + endif() + + add_executable(${_theExec} ${_exeFile}) + target_link_libraries( ${_theExec} GeoModelKernel) + add_test(NAME ${_theExec} + COMMAND ${_theExec}) + +endforeach() -add_executable(testGeoIntrusivePtr tests/testGeoIntrusivePtr.cxx) -target_link_libraries( testGeoIntrusivePtr GeoModelKernel) -add_test(NAME testGeoIntrusivePtr - COMMAND testGeoIntrusivePtr) \ No newline at end of file diff --git a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h index cef5d0577f9de8ef952cc8453c2b854665646646..728767d358a5980bd679278f65769ade324a0178 100644 --- a/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h +++ b/GeoModelCore/GeoModelKernel/GeoModelKernel/GeoIntrusivePtr.h @@ -22,7 +22,7 @@ class GeoIntrusivePtr{ if (m_ptr) obj->ref(); } /// Copy constructor - GeoIntrusivePtr(const GeoIntrusivePtr& other) noexcept: + explicit GeoIntrusivePtr(const GeoIntrusivePtr& other) noexcept: GeoIntrusivePtr{other.get()} {} /// Copy constructor for derived types @@ -50,6 +50,13 @@ class GeoIntrusivePtr{ reset(other.get()); return *this; } + template <typename GeoTypeGrp, + typename = typename std::enable_if<!std::is_same<GeoType,GeoTypeGrp>::value, bool>> + GeoIntrusivePtr& operator=(const GeoIntrusivePtr<GeoTypeGrp>& other) { + reset(other.get()); + return *this; + } + GeoIntrusivePtr& operator=(GeoType* other) noexcept { reset(other); return *this; @@ -66,7 +73,7 @@ class GeoIntrusivePtr{ } template <typename GeoTypeGrp, typename = typename std::enable_if<!std::is_same<GeoType,GeoTypeGrp>::value, bool>> - GeoIntrusivePtr& operator=(GeoIntrusivePtr<GeoTypeGrp>&& other) { + GeoIntrusivePtr& operator=(GeoIntrusivePtr<GeoTypeGrp>&& other) { if (m_ptr && m_ptr == other.get()) { m_ptr->unref(); } else { diff --git a/GeoModelTools/CMakeLists.txt b/GeoModelTools/CMakeLists.txt index bed80fb75f6f943b19353885f3239e9281857724..828183c8aba1302b884cd16546da6963e2eecf03 100644 --- a/GeoModelTools/CMakeLists.txt +++ b/GeoModelTools/CMakeLists.txt @@ -47,6 +47,7 @@ include( GNUInstallDirs ) # Set up the build of the libraries of the project. add_subdirectory( GeoModelXML ) +add_subdirectory( GeoModelFuncSnippets ) add_subdirectory( GeoModelXMLParser ) add_subdirectory( GeoModelJSONParser ) add_subdirectory( ExpressionEvaluator ) diff --git a/GeoModelTools/GMCAT/CMakeLists.txt b/GeoModelTools/GMCAT/CMakeLists.txt index f6cc32c5238123cdbb5520ca164945a02f6b5dc9..62f3df273a4af424f150874b426c6ff3c9609edd 100644 --- a/GeoModelTools/GMCAT/CMakeLists.txt +++ b/GeoModelTools/GMCAT/CMakeLists.txt @@ -3,8 +3,10 @@ # Declare the package's executable. add_executable( gmcat src/gmcat.cxx src/publishMetaData.cpp) target_link_libraries( gmcat PRIVATE GeoModelCore::GeoModelKernel - GeoModelIO::GeoModelRead GeoModelIO::GeoModelWrite - GeoModelIO::GeoModelDBManager ) + GeoModelTools::GeoModelFuncSnippets + GeoModelIO::GeoModelRead + GeoModelIO::GeoModelWrite + GeoModelIO::GeoModelDBManager ) # Tweak how debug information should be attached to the executable, in Debug # builds. diff --git a/GeoModelTools/GMCAT/src/gmcat.cxx b/GeoModelTools/GMCAT/src/gmcat.cxx index 011ac969dc4bdb6dd5a8958a47a1b7a02f66606d..a7d9c68b8cf4874861e4733004e8f0f00ad614e5 100644 --- a/GeoModelTools/GMCAT/src/gmcat.cxx +++ b/GeoModelTools/GMCAT/src/gmcat.cxx @@ -6,6 +6,7 @@ #include "GeoModelDBManager/GMDBManager.h" #include "GeoModelRead/ReadGeoModel.h" #include "GeoModelWrite/WriteGeoModel.h" +#include "GeoModelFuncSnippets/defineWorld.h" #include "GeoModelKernel/GeoGeometryPluginLoader.h" #include "GeoModelKernel/GeoVolumeCursor.h" @@ -25,7 +26,6 @@ #include <unistd.h> #include <stdlib.h> -#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm' #ifdef __APPLE__ const std::string shared_obj_extension=".dylib"; #else @@ -117,33 +117,8 @@ int main(int argc, char ** argv) { // // Create elements and materials for the "World" volume, which is the container: // + GeoIntrusivePtr<GeoVPhysVol> world{createGeoWorld()}; - const double gr = SYSTEM_OF_UNITS::gram; - const double mole = SYSTEM_OF_UNITS::mole; - const double 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); - - 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(); - - // - // Create a huge world volume made of Air: - // - - const GeoBox* worldBox = new GeoBox(2000*SYSTEM_OF_UNITS::cm, 2000*SYSTEM_OF_UNITS::cm, 2500*SYSTEM_OF_UNITS::cm); - const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); - GeoPhysVol *world=new GeoPhysVol(worldLog); - world->ref(); // // Loop over plugins, create the geometry and put it under the world: // @@ -223,7 +198,6 @@ int main(int argc, char ** argv) { dumpGeoModelGraph.saveToDB(); } - world->unref(); publishMetaData(db,inputFiles,inputPlugins,outputFile); diff --git a/GeoModelTools/GMSTATISTICS/CMakeLists.txt b/GeoModelTools/GMSTATISTICS/CMakeLists.txt index 4a34fa2fb976749a23360eec3d434d9fdbaf7499..cad89c45a5fbf6ac4f2c3f8599ecedd565807fb1 100644 --- a/GeoModelTools/GMSTATISTICS/CMakeLists.txt +++ b/GeoModelTools/GMSTATISTICS/CMakeLists.txt @@ -3,8 +3,10 @@ # Declare the package's executable. add_executable( gmstatistics src/gmstatistics.cxx src/GeoInventoryGraphAction.cxx ) target_link_libraries( gmstatistics PRIVATE GeoModelCore::GeoModelKernel - GeoModelIO::GeoModelRead GeoModelIO::GeoModelWrite - GeoModelIO::GeoModelDBManager ) + GeoModelIO::GeoModelRead + GeoModelIO::GeoModelWrite + GeoModelIO::GeoModelDBManager + GeoModelTools::GeoModelFuncSnippets ) # Tweak how debug information should be attached to the executable, in Debug # builds. diff --git a/GeoModelTools/GMSTATISTICS/src/gmstatistics.cxx b/GeoModelTools/GMSTATISTICS/src/gmstatistics.cxx index 157c6dd091076ccf7a21849d64ea6b14f3e98e02..ac66b4f2d314f15b65f1173a20ee737953a90f92 100644 --- a/GeoModelTools/GMSTATISTICS/src/gmstatistics.cxx +++ b/GeoModelTools/GMSTATISTICS/src/gmstatistics.cxx @@ -11,6 +11,7 @@ #include "GeoModelKernel/GeoCountVolAction.h" #include "GeoModelKernel/GeoAccessVolumeAction.h" #include "GeoModelKernel/GeoNameTag.h" +#include "GeoModelFuncSnippets/defineWorld.h" #include "GeoInventoryGraphAction.h" #include <fstream> #include <iostream> @@ -43,7 +44,6 @@ const std::string shared_obj_extension=".so"; double factor=1000.0; #endif -#define SYSTEM_OF_UNITS GeoModelKernelUnits // --> 'GeoModelKernelUnits::cm' int snoop() { struct rusage usage; @@ -99,37 +99,7 @@ int main(int argc, char ** argv) { for (const std::string & plugin : inputPlugins) { - - // - // Create elements and materials: - // - - const double gr = SYSTEM_OF_UNITS::gram; - const double mole = SYSTEM_OF_UNITS::mole; - const double 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); - - 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(); - - // - // Create a huge world volume made of Air: - // - - const GeoBox* worldBox = new GeoBox(2000*SYSTEM_OF_UNITS::cm, 2000*SYSTEM_OF_UNITS::cm, 2500*SYSTEM_OF_UNITS::cm); - const GeoLogVol* worldLog = new GeoLogVol("WorldLog", worldBox, air); - GeoPhysVol *world=new GeoPhysVol(worldLog); - world->ref(); + GeoIntrusivePtr<GeoPhysVol> world{createGeoWorld()}; // // Loop over plugins, create the geometry and put it under the world: // diff --git a/GeoModelTools/GeoModelFuncSnippets/CMakeLists.txt b/GeoModelTools/GeoModelFuncSnippets/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..f7665ef21894f8ac9e1daaf45f719c33513bea78 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/CMakeLists.txt @@ -0,0 +1,59 @@ +# Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration + +# Find the header and source files. +file( GLOB SOURCES src/*.cxx ) +file( GLOB HEADERS GeoModelFuncSnippets/*.h GeoModelFuncSnippets/*.icc ) + +# Create the library. +add_library( GeoModelFuncSnippets SHARED ${HEADERS} ${SOURCES} ) + +target_link_libraries( GeoModelFuncSnippets PRIVATE GeoModelCore::GeoModelKernel ) + + +target_include_directories( GeoModelFuncSnippets PUBLIC + $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> + $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}> ) +source_group( "GeoModelFuncSnippets" FILES ${HEADERS} ) +source_group( "src" FILES ${SOURCES} ) +set_target_properties( GeoModelFuncSnippets PROPERTIES + VERSION ${PROJECT_VERSION} + SOVERSION ${PROJECT_VERSION_MAJOR} ) + +# Set up an alias with the same name that you would get by "finding" a pre-built +# version of the library. +add_library( GeoModelTools::GeoModelFuncSnippets ALIAS GeoModelFuncSnippets ) + +# Install the library. +install(TARGETS GeoModelFuncSnippets + EXPORT ${PROJECT_NAME}-export + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + COMPONENT Runtime + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT Runtime + NAMELINK_COMPONENT Development # Requires CMake 3.12 + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + COMPONENT Development + PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GeoModelFuncSnippets + COMPONENT Development + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install( FILES ${HEADERS} + DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/GeoModelFuncSnippets + COMPONENT Development ) + +file(GLOB_RECURSE files "tests/*.cxx") +foreach(_exeFile ${files}) + get_filename_component(_theExec ${_exeFile} NAME_WE) + get_filename_component(_theLoc ${_exeFile} DIRECTORY) + + if(${_theLoc} MATCHES "DoNotBuild") + continue() + endif() + + add_executable(${_theExec} ${_exeFile}) + target_link_libraries( ${_theExec} GeoModelTools::GeoModelFuncSnippets GeoModelCore::GeoModelKernel) + add_test(NAME ${_theExec} + COMMAND ${_theExec}) + +endforeach() diff --git a/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/FileUtils.h b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/FileUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..89381e64ee39f8edda13ba2774e012e9ab33dad4 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/FileUtils.h @@ -0,0 +1,27 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef GEOMODELFUNCSNIPPETS_FILEUTILS_H +#define GEOMODELFUNCSNIPPETS_FILEUTILS_H + +#include <string> +#include <string_view> +#include <vector> + +namespace GeoFileUtils { + bool doesFileExist(const std::string_view path); + bool doesDirectoryExist(const std::string_view path); + bool mkdir(const std::string_view path); + + std::vector<std::string> listDirectory(const std::string_view path, + bool recursive = false); + + std::vector<std::string> findFile(const std::string_view path, + const std::string_view file); + + bool copyFile(const std::string_view from, + const std::string_view to); + + +} +#endif \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/StringUtils.h b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/StringUtils.h new file mode 100644 index 0000000000000000000000000000000000000000..da93675a5aa3610c11c8c29eeb6a7c9b510271f9 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/StringUtils.h @@ -0,0 +1,66 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef GEOMODELFUNCSNIPPETS_STRINGUTILS_H +#define GEOMODELFUNCSNIPPETS_STRINGUTILS_H + +#include <string> +#include <string_view> +#include <vector> +#include <functional> + +namespace GeoStrUtils{ + + + /// @brief Replaces all occurances of pattern <A> by a substring <B> + /// @param str String to modify + /// @param exp Expression to be replaced + /// @param rep Replace it with + /// @return + std::string replaceExpInString(std::string str, + const std::string_view exp, + const std::string_view rep); + + /// @brief If a string contains a bash environment variable + /// E.g. ${GMX_FILES}/Blub.xml then the ${} expression is + /// replaced by the variable content + /// @param str + /// @return + std::string resolveEnviromentVariables(const std::string_view str); + + /// @brief returns the longest substring that's common between the + /// two given strings starting from character 0 + std::string_view longestCommonString(const std::string_view firstStr, + const std::string_view secondStr); + + /// @brief Returns a string consisting of N white spaces + std::string whiteSpaces(const unsigned int n, const std::string_view space =" "); + + /// Converts a string into an integer + int atoi(std::string_view str); + /// Converts a string into a double / float + double atof(std::string_view str); + /// Removes all trailing and starting whitespaces from a string + std::string_view eraseWhiteSpaces(std::string_view str); + + /// Splits the string into smaller substrings + std::vector<std::string> tokenize(const std::string& the_str, + std::string_view delimiter); + + std::vector<double> tokenizeDouble(const std::string& the_str, + std::string_view delimiter); + + std::vector<int> tokenizeInt(const std::string& the_str, + std::string_view delimiter); + + + template <class ObjType> std::string chainUp(unsigned int numEles, + const std::function<ObjType(unsigned int)>& func, + const std::string_view glue=";"); + + template <class ObjType> std::string chainUp(const std::vector<ObjType>& vector, + const std::string_view glue =";"); + +} +#include "GeoModelFuncSnippets/StringUtils.icc" +#endif \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/StringUtils.icc b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/StringUtils.icc new file mode 100644 index 0000000000000000000000000000000000000000..aaae117703a59b5c76b30f01b7857576a71a265a --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/StringUtils.icc @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef GEOMODELFUNCSNIPPETS_STRINGUTILS_ICC +#define GEOMODELFUNCSNIPPETS_STRINGUTILS_ICC + +#include <sstream> +namespace GeoStrUtils { + + + template <class ObjType> std::string chainUp(const std::vector<ObjType>& vector, + const std::string_view glue) { + return chainUp(vector.size(), [&vector](const unsigned int ele)->ObjType { + return vector.at(ele); + }, glue); + } + + template <class ObjType> std::string chainUp(unsigned int numEles, + const std::function<ObjType(unsigned int)>& func, + const std::string_view glue) { + std::stringstream chain{}; + for (unsigned int k =0; k < numEles; ++k) { + chain<<func(k); + if (k + 1 < numEles)chain<<glue; + } + return chain.str(); + } +} +#endif \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/defineWorld.h b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/defineWorld.h new file mode 100644 index 0000000000000000000000000000000000000000..2e32a64597b1a0f9d6a52430ce27bfeaded4fc32 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/defineWorld.h @@ -0,0 +1,23 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef GEOMODELUTILS_DEFINEWORLD_H +#define GEOMODELUTILS_DEFINEWORLD_H + +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/Units.h" + +/// @brief Common helper function that creates the top GeoWorld volume in the tree. +/// @returns A physical volume serving as world volume +namespace GeoWorldDim { + constexpr double worldBoxX = 20. * GeoModelKernelUnits::m; + constexpr double worldBoxY = 20. * GeoModelKernelUnits::m; + constexpr double worldBoxZ = 25. * GeoModelKernelUnits::m; +} + +/// Creates the basic GeoWorld +GeoIntrusivePtr<GeoPhysVol> createGeoWorld(const double worldBoxX = GeoWorldDim::worldBoxX, + const double worldBoxY = GeoWorldDim::worldBoxY, + const double worldBoxZ = GeoWorldDim::worldBoxZ); + +#endif \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/throwExcept.h b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/throwExcept.h new file mode 100644 index 0000000000000000000000000000000000000000..7be2db17993584667dc5005f3cc78fc831f591c6 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/GeoModelFuncSnippets/throwExcept.h @@ -0,0 +1,17 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#ifndef GEOMODELFUNCSNIPPETS_THROWEXCEPT_H +#define GEOMODELFUNCSNIPPETS_THROWEXCEPT_H + +#include <exception> +#include <sstream> + +#define THROW_EXCEPTION(MESSAGE) \ + { \ + std::stringstream except_str{}; \ + except_str<<__FILE__<<":"<<__LINE__<<" --- "; \ + except_str<<MESSAGE; \ + throw std::runtime_error(except_str.str()); \ + } +#endif \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/src/FileUtils.cxx b/GeoModelTools/GeoModelFuncSnippets/src/FileUtils.cxx new file mode 100644 index 0000000000000000000000000000000000000000..08b2c2fc3f59bab7d487d65798aedf6d36b1450f --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/src/FileUtils.cxx @@ -0,0 +1,79 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#include "GeoModelFuncSnippets/FileUtils.h" +#include "GeoModelFuncSnippets/StringUtils.h" + + +#include <filesystem> +#include <iostream> +#include <functional> +using namespace GeoStrUtils; + +namespace GeoFileUtils { + bool doesFileExist(const std::string_view path) { + const std::filesystem::path filePath{resolveEnviromentVariables(path)}; + return std::filesystem::exists(filePath) && std::filesystem::is_regular_file(filePath); + } + + bool doesDirectoryExist(const std::string_view path) { + const std::filesystem::path dirPath{resolveEnviromentVariables(path)}; + return std::filesystem::exists(dirPath) && std::filesystem::is_directory(dirPath); + } + + bool mkdir(const std::string_view path) { + std::filesystem::create_directories(resolveEnviromentVariables(path)); + return doesDirectoryExist(path); + } + + std::vector<std::string> listDirectory(const std::string_view path, + bool recursive) { + const std::filesystem::path dirPath{resolveEnviromentVariables(path)}; + + if (!doesDirectoryExist(path)) { + std::cout<<"WARNING - No directory "<<dirPath<<std::endl; + return {}; + } + std::vector<std::string> contents{}; + if (recursive){ + for (const auto& entry: std::filesystem::recursive_directory_iterator{dirPath}){ + contents.emplace_back(entry.path()); + } + } else { + for (const auto& entry: std::filesystem::directory_iterator{dirPath}){ + contents.emplace_back(entry.path()); + } + } + return contents; + } + std::vector<std::string> findFile(const std::string_view path, + const std::string_view file) { + + std::vector<std::string> foundFiles{}; + std::vector<std::string> contents{listDirectory(path, true)}; + std::copy_if(contents.begin(), contents.end(), + std::back_inserter(foundFiles), + [file](const std::string& entry) { + return entry.find(file) != std::string::npos; + }); + return foundFiles; + } + + bool copyFile(const std::string_view from, + const std::string_view to) { + + if (!doesFileExist(from)) { + std::cerr<<"copyFile() -- File "<<from<<" does not exist"<<std::endl; + return false; + } + if (to.find("/") != std::string::npos) { + if (!mkdir(to.substr(0, to.rfind("/")))){ + std::cerr<<"copyFile() -- Cannot create directory " + <<to.substr(0, to.rfind("/"))<<"."; + } + } + std::filesystem::copy(from, to, std::filesystem::copy_options::overwrite_existing); + return doesFileExist(to); + } + +} diff --git a/GeoModelTools/GeoModelFuncSnippets/src/StringUtils.cxx b/GeoModelTools/GeoModelFuncSnippets/src/StringUtils.cxx new file mode 100644 index 0000000000000000000000000000000000000000..89b7a0cd649389441f692c972552fe6e9f987ab4 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/src/StringUtils.cxx @@ -0,0 +1,138 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#include "GeoModelFuncSnippets/StringUtils.h" +#include "GeoModelFuncSnippets/throwExcept.h" +#include <limits> +#include <array> +#include <functional> +#include <iostream> +#include <sstream> +#include <charconv> +#include <algorithm> + +namespace GeoStrUtils { + + std::string whiteSpaces(const unsigned int n, const std::string_view space) { + return chainUp<std::string_view>(n , + [space](const unsigned int)->std::string_view{ return space; }, ""); + } + std::string replaceExpInString(std::string str, + const std::string_view exp, + const std::string_view rep) { + + std::size_t exPos = str.find(exp); + std::size_t expLen = exp.size(); + while(exPos != std::string::npos) { + str = str.substr(0, exPos) + std::string{rep} + str.substr(exPos + expLen, std::string::npos); + exPos = str.find(exp); + } + return str; + } + std::string_view longestCommonString(const std::string_view firstStr, + const std::string_view secondStr){ + if (firstStr.size() < secondStr.size()) return longestCommonString(secondStr, firstStr); + std::size_t commonPos{0}; + for ( ; commonPos <= secondStr.size(); ++commonPos) { + std::string_view sub_str = secondStr.substr(0, commonPos); + if (firstStr.find(sub_str) != 0) break; + } + return secondStr.substr(0, commonPos); + } + + + std::string resolveEnviromentVariables(const std::string_view inStr) { + std::string str{inStr}; + + while (str.find("${") != std::string::npos) { + std::string varName = str.substr(str.find("${") + 2, str.find("}") - str.find("${") - 2); + std::string envVar{std::getenv(varName.data()) ? std::getenv(varName.data()) : ""}; + str = replaceExpInString(str, str.substr(str.find("${"), str.find("}") - str.find("${") + 1), envVar); + } + return str; + } + + std::vector<std::string> tokenize(const std::string& str, + std::string_view delimiters) { + + std::vector<std::string> tokens{}; + // Skip delimiters at beginning. + std::string::size_type lastPos = str.find_first_not_of(delimiters, 0); + // Find first "non-delimiter". + std::string::size_type pos = str.find_first_of(delimiters, lastPos); + + while (std::string::npos != pos || std::string::npos != lastPos) { + // Found a token, add it to the vector. + tokens.push_back(str.substr(lastPos, pos - lastPos)); + // Skip delimiters. Note the "not_of" + lastPos = str.find_first_not_of(delimiters, pos); + // Find next "non-delimiter" + pos = str.find_first_of(delimiters, lastPos); + } + return tokens; + } + std::vector<double> tokenizeDouble(const std::string& the_str, + std::string_view delimiter){ + const std::vector<std::string> strTokens = tokenize(the_str, delimiter); + std::vector<double> toReturn{}; + std::transform(strTokens.begin(), strTokens.end(), std::back_inserter(toReturn), + [](const std::string& token){ + return atof(token); + }); + return toReturn; + } + std::string_view eraseWhiteSpaces(std::string_view str) { + if (str.empty()) return str; + size_t begin{0}, end{str.size() -1}; + while (std::isspace(str[begin])){ + ++begin; + } + while (end > 0 && std::isspace(str[end])){ + --end; + } + return str.substr(begin, end + 1); + } + std::vector<int> tokenizeInt(const std::string& the_str, + std::string_view delimiter) { + const std::vector<std::string> strTokens = tokenize(the_str, delimiter); + std::vector<int> toReturn{}; + std::transform(strTokens.begin(), strTokens.end(), std::back_inserter(toReturn), + [](const std::string& token){ + return atoi(token); + }); + return toReturn; + } + template <class dType> void convertToNumber(std::string_view str, dType& number) { + /// Allow for trailing & leading white spaces + if (str.empty()) { + number = 0; + return; + } + if (std::find_if(str.begin(), str.end(), [](const char c){ return std::isspace(c);}) != str.end()) { + std::string_view spaceFreeStr = eraseWhiteSpaces(str); + /// To avoid infinite recursion because of string like '42 24' check that white spaces have been indeed removed + if (spaceFreeStr.size() != str.size()) { + convertToNumber(spaceFreeStr, number); + return; + } + } + if (str[0]=='+') { + convertToNumber(str.substr(1), number); + return; + } + if (std::from_chars(str.data(), str.data() + str.size(), number).ec != std::errc{}) { + THROW_EXCEPTION("convertToNumber() - The string '"<<str<<"'. Contains unallowed chars"); + } + } + int atoi(std::string_view str) { + int result{std::numeric_limits<int>::max()}; + convertToNumber(str, result); + return result; + } + + double atof(std::string_view str) { + double result{std::numeric_limits<double>::max()}; + convertToNumber(str, result); + return result; + } +} \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/src/defineWorld.cxx b/GeoModelTools/GeoModelFuncSnippets/src/defineWorld.cxx new file mode 100644 index 0000000000000000000000000000000000000000..9c52a18ceb0cf41923d3584fd2762bdea21ca655 --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/src/defineWorld.cxx @@ -0,0 +1,41 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ +#include "GeoModelFuncSnippets/defineWorld.h" +#include "GeoModelKernel/GeoElement.h" +#include "GeoModelKernel/GeoMaterial.h" +#include "GeoModelKernel/GeoBox.h" +#include "GeoModelKernel/GeoPhysVol.h" +#include "GeoModelKernel/Units.h" + +GeoIntrusivePtr<GeoPhysVol> createGeoWorld(const double worldBoxX, + const double worldBoxY, + const double worldBoxZ) { + + + constexpr double gr = GeoModelKernelUnits::gram; + constexpr double mole = GeoModelKernelUnits::mole; + constexpr double cm3 = GeoModelKernelUnits::cm3; + + // Define the chemical elements + GeoIntrusivePtr<GeoElement> Nitrogen{new GeoElement ("Nitrogen" ,"N" , 7.0 , 14.0067 *gr/mole)}; + GeoIntrusivePtr<GeoElement> Oxygen{new GeoElement ("Oxygen" ,"O" , 8.0 , 15.9995 *gr/mole)}; + GeoIntrusivePtr<GeoElement> Argon{new GeoElement ("Argon" ,"Ar" , 18.0 , 39.948 *gr/mole)}; + GeoIntrusivePtr<GeoElement> Hydrogen{new GeoElement ("Hydrogen" ,"H" , 1.0 , 1.00797 *gr/mole)}; + + constexpr double densityOfAir=0.001214 *gr/cm3; + GeoIntrusivePtr<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(); + + + + GeoIntrusivePtr<GeoBox> worldBox{new GeoBox(worldBoxX, worldBoxY, worldBoxZ)}; + GeoIntrusivePtr<GeoLogVol> worldLog{new GeoLogVol("WorldLog", worldBox, air)}; + GeoIntrusivePtr<GeoPhysVol> world{new GeoPhysVol(worldLog)}; + + return world; +} \ No newline at end of file diff --git a/GeoModelTools/GeoModelFuncSnippets/tests/testStringUtils.cxx b/GeoModelTools/GeoModelFuncSnippets/tests/testStringUtils.cxx new file mode 100644 index 0000000000000000000000000000000000000000..c21262be73bb4f01f4e606f3860dec4f7146055c --- /dev/null +++ b/GeoModelTools/GeoModelFuncSnippets/tests/testStringUtils.cxx @@ -0,0 +1,29 @@ +/* + Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration +*/ + +#include "GeoModelFuncSnippets/StringUtils.h" +#include "GeoModelFuncSnippets/throwExcept.h" +#include <iostream> +#include <stdlib.h> +using namespace GeoStrUtils; + +namespace { + std::string getEnvVar(const std::string& varName){ + return std::getenv(varName.c_str()) ? std::string{std::getenv(varName.c_str())} : std::string{}; + } +} + +int main() { + if (resolveEnviromentVariables("${PWD}") != getEnvVar("PWD")) { + THROW_EXCEPTION("PWD has been resolved differently "<<resolveEnviromentVariables("${PWD}") + <<" vs. "<<getEnvVar("PWD")); + } + + if (resolveEnviromentVariables("${PWD}/Kuchen") != getEnvVar("PWD")+"/Kuchen") { + THROW_EXCEPTION("PWD/Kuchen has been resolved differently "<<resolveEnviromentVariables("${PWD}/Kuchen") + <<" vs. "<<getEnvVar("PWD")<<"/Kuchen"); + } + + return EXIT_SUCCESS; +} \ No newline at end of file diff --git a/GeoModelTools/GeoModelXML/GeoModelXml/CMakeLists.txt b/GeoModelTools/GeoModelXML/GeoModelXml/CMakeLists.txt index 29a9b69bcf7bfcc514125ad3feb088b01f2ea2b7..374cc28c8e865e5d3dfd009495036acb67cbcd34 100644 --- a/GeoModelTools/GeoModelXML/GeoModelXml/CMakeLists.txt +++ b/GeoModelTools/GeoModelXML/GeoModelXml/CMakeLists.txt @@ -13,7 +13,7 @@ find_package( ZLIB REQUIRED ) # Create the library. add_library( GeoModelXml SHARED ${HEADERS} ${SOURCES} ) # link libraries -target_link_libraries( GeoModelXml PUBLIC GeoModelCore::GeoModelKernel GeoModelTools::ExpressionEvaluator XercesC::XercesC PRIVATE ZLIB::ZLIB ) +target_link_libraries( GeoModelXml PUBLIC GeoModelCore::GeoModelKernel GeoModelTools::GeoModelFuncSnippets GeoModelTools::ExpressionEvaluator XercesC::XercesC PRIVATE ZLIB::ZLIB ) target_include_directories( GeoModelXml PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}> $<INSTALL_INTERFACE:include> )