diff --git a/DDCore/include/DD4hep/VolumeProcessor.h b/DDCore/include/DD4hep/VolumeProcessor.h index 243ea97d2f8c28de9e65182965944cbfd049bc74..73901a18dc410c7847e45cacb3c3085d2193f9c9 100644 --- a/DDCore/include/DD4hep/VolumeProcessor.h +++ b/DDCore/include/DD4hep/VolumeProcessor.h @@ -43,7 +43,7 @@ namespace dd4hep { /// Default copy constructor PlacedVolumeProcessor(const PlacedVolumeProcessor& copy) = default; /// Default destructor - virtual ~PlacedVolumeProcessor(); + virtual ~PlacedVolumeProcessor() noexcept(false); /// Default assignment PlacedVolumeProcessor& operator=(const PlacedVolumeProcessor& copy) = default; /// Callback to output PlacedVolume information of an single Placement diff --git a/DDCore/src/DetectorImp.cpp b/DDCore/src/DetectorImp.cpp index 20aabfd49a00e13bb77aede39921ab7854be50ba..6d0edb1220e14a8af29bb1c54748e48b96db65eb 100644 --- a/DDCore/src/DetectorImp.cpp +++ b/DDCore/src/DetectorImp.cpp @@ -199,6 +199,7 @@ DetectorImp::DetectorImp() DetectorImp::DetectorImp(const string& name) : TNamed(), DetectorData(), DetectorLoad(this), m_buildType(BUILD_NONE) { + static bool first = true; #if defined(DD4HEP_USE_GEANT4_UNITS) && ROOT_VERSION_CODE >= ROOT_VERSION(6,22,7) printout(WARNING,"DD4hep","++ Using globally Geant4 unit system (mm,ns,MeV)"); if ( TGeoManager::GetDefaultUnits() != TGeoManager::kG4Units ) { @@ -213,9 +214,7 @@ DetectorImp::DetectorImp(const string& name) TGeoManager::LockDefaultUnits(kTRUE); } #else - static bool first = true; if ( first ) { - first = false; #if defined(DD4HEP_USE_GEANT4_UNITS) && ROOT_VERSION_CODE >= ROOT_VERSION(6,20,0) printout(WARNING,"DD4hep","++ Using globally Geant4 unit system (mm,ns,MeV)"); TGeoManager::SetDefaultG4Units(); @@ -226,10 +225,15 @@ DetectorImp::DetectorImp(const string& name) #endif } #endif + + if ( first ) { + first = false; + set_terminate( description_unexpected ); + } + SetName(name.c_str()); SetTitle("DD4hep detector description object"); - set_terminate( description_unexpected ); - DetectorGuard(this).lock(gGeoManager); + //DetectorGuard(this).lock(gGeoManager); gGeoManager = nullptr; InstanceCount::increment(this); m_manager = new TGeoManager(name.c_str(), "Detector Geometry"); @@ -742,8 +746,6 @@ void DetectorImp::endDocument(bool close_geometry) { #endif m_worldVol.solid()->ComputeBBox(); // Propagating reflections: This is useless now and unused!!!! - //ReflectionBuilder rb(*this); - //rb.execute(); // Since we allow now for anonymous shapes, // we will rename them to use the name of the volume they are assigned to mgr->CloseGeometry(); @@ -753,7 +755,7 @@ void DetectorImp::endDocument(bool close_geometry) { patcher.patchShapes(); mapDetectorTypes(); m_state = READY; - DetectorGuard(this).unlock(); + //DetectorGuard(this).unlock(); } /// Initialize the geometry and set the bounding box of the world volume diff --git a/DDCore/src/Plugins.cpp b/DDCore/src/Plugins.cpp index d2a3d7f3e4c7d69c6e79dee75cc3ec2e67bc78d3..1e53d00e793813a1b4fbd3da2f31ba4f75c9fb30 100644 --- a/DDCore/src/Plugins.cpp +++ b/DDCore/src/Plugins.cpp @@ -104,18 +104,22 @@ namespace { if ( 0 == plugin_name ) plugin_name = "libDD4hepGaudiPluginMgr"; #endif #if defined(DD4HEP_PARSERS_NO_ROOT) - handle = ::dlopen(plugin_name, RTLD_LAZY | RTLD_GLOBAL); + struct handle_guard { + void* _handle {nullptr}; + handle_guard(void* hdl) : _handle(hdl) { + } + ~handle_guard() { + if ( _handle ) ::dlclose(_handle); + _handle = nullptr; + } + }; + static handle_guard _guard(nullptr); + if ( nullptr == _guard._handle ) { + _guard._handle = handle = ::dlopen(plugin_name, RTLD_LAZY | RTLD_GLOBAL); + } if ( !handle ) { throw runtime_error("Failed to load plugin manager library: "+string(plugin_name)); } - else { - struct handle_guard { - void* _handle {nullptr}; - handle_guard(void* hdl) : _handle(hdl) {} - ~handle_guard() { if ( _handle ) ::dlclose(_handle); _handle = nullptr; } - }; - static handle_guard _guard(handle); - } #else if ( 0 != gSystem->Load(plugin_name) ) {} #endif diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 4cb317678030071e83c2e5f65330988c086ec055..812ced7be7214410cd11ea04268147feb6fe0be6 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -766,7 +766,7 @@ void Polyhedra::make(const string& nam, int nsides, double start, double delta, } /// Helper function to create the polyhedron -void ExtrudedPolygon::make(const string& nam, +void ExtrudedPolygon::make(const string& nam, const vector<double>& pt_x, const vector<double>& pt_y, const vector<double>& sec_z, diff --git a/DDCore/src/VolumeProcessor.cpp b/DDCore/src/VolumeProcessor.cpp index a5819bd5c8fea8574669eb194d0e088146d9daea..79b50d6639ce55abaa379bb4abbadf64d0a8daf5 100644 --- a/DDCore/src/VolumeProcessor.cpp +++ b/DDCore/src/VolumeProcessor.cpp @@ -18,7 +18,7 @@ using namespace dd4hep; /// Default destructor -PlacedVolumeProcessor::~PlacedVolumeProcessor() { +PlacedVolumeProcessor::~PlacedVolumeProcessor() noexcept(false) { } /// Callback to output PlacedVolume information of an entire DetElement diff --git a/DDCore/src/gdml/DetElementCreator.cpp b/DDCore/src/gdml/DetElementCreator.cpp index f339514d921f2094b32d233824e336d230859bab..7247cc02bced87d62c9c9557dfcf09c32553346b 100644 --- a/DDCore/src/gdml/DetElementCreator.cpp +++ b/DDCore/src/gdml/DetElementCreator.cpp @@ -96,7 +96,7 @@ namespace dd4hep { int sd_lvl, PrintLevel p); /// Default destructor - virtual ~DetElementCreator(); + virtual ~DetElementCreator() noexcept(false); /// Callback to output PlacedVolume information of an single Placement virtual int operator()(PlacedVolume pv, int level); /// Callback to output PlacedVolume information of an entire Placement @@ -140,7 +140,7 @@ DetElementCreator::DetElementCreator(Detector& desc, } /// Default destructor -DetElementCreator::~DetElementCreator() { +DetElementCreator::~DetElementCreator() noexcept(false) { Count total; stringstream str, id_str; const char* pref = detector_volume_match.c_str(); diff --git a/DDG4/include/DDG4/Geant4AssemblyVolume.h b/DDG4/include/DDG4/Geant4AssemblyVolume.h index 58949b4259304a866f7ea69115dca927d84a45ad..7e204068744b60d9dd165f00a1794cfd91797047 100644 --- a/DDG4/include/DDG4/Geant4AssemblyVolume.h +++ b/DDG4/include/DDG4/Geant4AssemblyVolume.h @@ -1,6 +1,3 @@ -#ifndef DDG4_GEANT4ASSEMBLYVOLUME_H -#define DDG4_GEANT4ASSEMBLYVOLUME_H - //========================================================================== // AIDA Detector description implementation //-------------------------------------------------------------------------- @@ -13,6 +10,8 @@ // Author : M.Frank // //========================================================================== +#ifndef DDG4_GEANT4ASSEMBLYVOLUME_H +#define DDG4_GEANT4ASSEMBLYVOLUME_H // Disable diagnostics for ROOT dictionaries #ifdef __clang__ @@ -28,12 +27,21 @@ #pragma clang diagnostic pop #endif +// ROOT includes +#include "TGeoNode.h" + +/// C/C++ include files +#include <vector> + /// Namespace for the AIDA detector description toolkit namespace dd4hep { /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit namespace sim { + /// Forward declarations + class Geant4GeometryInfo; + /// Hack! Wrapper around G4AssemblyVolume to access protected members. /** * \author M.Frank diff --git a/DDG4/src/Geant4AssemblyVolume.cpp b/DDG4/src/Geant4AssemblyVolume.cpp new file mode 100644 index 0000000000000000000000000000000000000000..cf3fdb9580c0182c8060f5c6b41e2d11d14e6972 --- /dev/null +++ b/DDG4/src/Geant4AssemblyVolume.cpp @@ -0,0 +1,146 @@ +//========================================================================== +// AIDA Detector description implementation +//-------------------------------------------------------------------------- +// Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) +// All rights reserved. +// +// For the licensing terms see $DD4hepINSTALL/LICENSE. +// For the list of contributors see $DD4hepINSTALL/doc/CREDITS. +// +// Author : M.Frank +// +//========================================================================== + +// Geant4 include files +#include "DD4hep/DetectorTools.h" +#include "G4LogicalVolume.hh" +#include "G4VPhysicalVolume.hh" +#include "G4ReflectionFactory.hh" + +// C/C++ include files +#include <sstream> +#include <string> + +// Framework include files +#include "DDG4/Geant4GeometryInfo.h" +#include "DDG4/Geant4AssemblyVolume.h" + +using namespace dd4hep::sim; + +void Geant4AssemblyVolume::imprint(Geant4GeometryInfo& info, + const TGeoNode* parent, + Chain chain, + Geant4AssemblyVolume* pParentAssembly, + G4LogicalVolume* pMotherLV, + G4Transform3D& transformation, + G4int copyNumBase, + G4bool surfCheck) +{ + static int level=0; + TGeoVolume* vol = parent->GetVolume(); + unsigned int numberOfDaughters = (copyNumBase == 0) ? pMotherLV->GetNoDaughters() : copyNumBase; + + ++level; + + // We start from the first available index + // + numberOfDaughters++; + ImprintsCountPlus(); + + std::vector<G4AssemblyTriplet> triplets = pParentAssembly->fTriplets; + //cout << " Assembly:" << detail::tools::placementPath(chain) << endl; + + for( unsigned int i = 0; i < triplets.size(); i++ ) { + const TGeoNode* node = pParentAssembly->m_entries[i]; + Chain new_chain = chain; + new_chain.emplace_back(node); + //cout << " Assembly: Entry: " << detail::tools::placementPath(new_chain) << endl; + + G4Transform3D Ta( *(triplets[i].GetRotation()), triplets[i].GetTranslation() ); + if ( triplets[i].IsReflection() ) { + Ta = Ta * G4ReflectZ3D(); + } + G4Transform3D Tfinal = transformation * Ta; + if ( triplets[i].GetVolume() ) { + // Generate the unique name for the next PV instance + // The name has format: + // + // av_WWW_impr_XXX_YYY_ZZZ + // where the fields mean: + // WWW - assembly volume instance number + // XXX - assembly volume imprint number + // YYY - the name of a log. volume we want to make a placement of + // ZZZ - the log. volume index inside the assembly volume + // + std::stringstream pvName; +#if 0 + pvName << "av_" + << GetAssemblyID() + << "_impr_" + << GetImprintsCount() + << "_" + << triplets[i].GetVolume()->GetName().c_str() + << "_pv_" + << i + << ends; +#endif + pvName << "AV_" + << GetAssemblyID() + << '#' + << parent->GetName() + << ':' + << parent->GetNumber() + << '#' + << m_entries[i]->GetName() + << ':' + << m_entries[i]->GetNumber() + << std::ends; + // Generate a new physical volume instance inside a mother + // (as we allow 3D transformation use G4ReflectionFactory to + // take into account eventual reflection) + // +#if 0 + printout(INFO,"Geant4Converter","++ Place %svolume %s in assembly.", + triplets[i].IsReflection() ? "REFLECTED " : "", + detail::tools::placementPath(new_chain).c_str()); +#endif + G4PhysicalVolumesPair pvPlaced + = G4ReflectionFactory::Instance()->Place( Tfinal, + pvName.str().c_str(), + triplets[i].GetVolume(), + pMotherLV, + false, + numberOfDaughters + i, + surfCheck ); + + // Register the physical volume created by us so we can delete it later + // + //fPVStore.emplace_back( pvPlaced.first ); + info.g4VolumeImprints[vol].emplace_back(new_chain,pvPlaced.first); +#if 0 + cout << " Assembly:Parent:" << parent->GetName() << " " << node->GetName() + << " " << (void*)node << " G4:" << pvName.str() << " Daughter:" + << detail::tools::placementPath(new_chain) << endl; + cout << endl; +#endif + + if ( pvPlaced.second ) { + G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException, + "Fancy construct popping new mother from the stack!"); + //fPVStore.emplace_back( pvPlaced.second ); + } + } + else if ( triplets[i].GetAssembly() ) { + // Place volumes in this assembly with composed transformation + imprint(info, parent, new_chain, (Geant4AssemblyVolume*)triplets[i].GetAssembly(), + pMotherLV, Tfinal, i*100+copyNumBase, surfCheck ); + } + else { + --level; + G4Exception("Geant4AssemblyVolume::imprint(..)", "GeomVol0003", FatalException, + "Triplet has no volume and no assembly"); + } + } + //cout << "Imprinted assembly level:" << level << " in mother:" << pMotherLV->GetName() << endl; + --level; +} diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index b922bf1cf898c022218fc0fb3db776f8fa6bed37..6adcf9d3ba301f12d94f12008e3b35a4a6a77c1f 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -30,17 +30,11 @@ #include "Geant4ShapeConverter.h" // ROOT includes +#include "TMath.h" #include "TROOT.h" -#include "TColor.h" -#include "TGeoNode.h" - -#include "TGeoMatrix.h" +//#include "TColor.h" +//#include "TGeoManager.h" #include "TGeoBoolNode.h" -#include "TGeoParaboloid.h" -#include "TGeoScaledShape.h" -#include "TGeoManager.h" -#include "TClass.h" -#include "TMath.h" // Geant4 include files #include "G4VisAttributes.hh" @@ -52,25 +46,20 @@ #include "G4Ellipsoid.hh" #include "G4UnionSolid.hh" #include "G4ReflectedSolid.hh" -#include "G4EllipticalTube.hh" #include "G4SubtractionSolid.hh" #include "G4IntersectionSolid.hh" -#include "G4Element.hh" #include "G4Region.hh" -#include "G4UserLimits.hh" -#include "G4LogicalVolume.hh" -#include "G4Material.hh" +#include "G4Element.hh" #include "G4Element.hh" #include "G4Isotope.hh" -#include "G4Transform3D.hh" -#include "G4ThreeVector.hh" -#include "G4PVPlacement.hh" -#include "G4ElectroMagneticField.hh" +#include "G4Material.hh" +#include "G4UserLimits.hh" #include "G4FieldManager.hh" #include "G4ReflectionFactory.hh" #include "G4OpticalSurface.hh" #include "G4LogicalSkinSurface.hh" +#include "G4ElectroMagneticField.hh" #include "G4LogicalBorderSurface.hh" #include "G4MaterialPropertiesTable.hh" #if G4VERSION_NUMBER >= 1040 @@ -94,123 +83,9 @@ using namespace std; #include "DDG4/Geant4AssemblyVolume.h" #include "DD4hep/DetectorTools.h" -#include "G4RotationMatrix.hh" -#include "G4AffineTransform.hh" -#include "G4LogicalVolume.hh" -#include "G4VPhysicalVolume.hh" -#include "G4ReflectionFactory.hh" static const double CM_2_MM = (CLHEP::centimeter/dd4hep::centimeter); -void Geant4AssemblyVolume::imprint(Geant4GeometryInfo& info, - const TGeoNode* parent, - Chain chain, - Geant4AssemblyVolume* pAssembly, - G4LogicalVolume* pMotherLV, - G4Transform3D& transformation, - G4int copyNumBase, - G4bool surfCheck) -{ - static int level=0; - TGeoVolume* vol = parent->GetVolume(); - unsigned int numberOfDaughters = (copyNumBase == 0) ? pMotherLV->GetNoDaughters() : copyNumBase; - - ++level; - - // We start from the first available index - // - numberOfDaughters++; - ImprintsCountPlus(); - - vector<G4AssemblyTriplet> triplets = pAssembly->fTriplets; - //cout << " Assembly:" << detail::tools::placementPath(chain) << endl; - - for( unsigned int i = 0; i < triplets.size(); i++ ) { - const TGeoNode* node = pAssembly->m_entries[i]; - Chain new_chain = chain; - new_chain.emplace_back(node); - //cout << " Assembly: Entry: " << detail::tools::placementPath(new_chain) << endl; - - G4Transform3D Ta( *(triplets[i].GetRotation()), - triplets[i].GetTranslation() ); - if ( triplets[i].IsReflection() ) { - Ta = Ta * G4ReflectZ3D(); - } - - G4Transform3D Tfinal = transformation * Ta; - if ( triplets[i].GetVolume() ) { - // Generate the unique name for the next PV instance - // The name has format: - // - // av_WWW_impr_XXX_YYY_ZZZ - // where the fields mean: - // WWW - assembly volume instance number - // XXX - assembly volume imprint number - // YYY - the name of a log. volume we want to make a placement of - // ZZZ - the log. volume index inside the assembly volume - // - stringstream pvName; - pvName << "av_" - << GetAssemblyID() - << "_impr_" - << GetImprintsCount() - << "_" - << triplets[i].GetVolume()->GetName().c_str() - << "_pv_" - << i - << ends; - - // Generate a new physical volume instance inside a mother - // (as we allow 3D transformation use G4ReflectionFactory to - // take into account eventual reflection) - // -#if 0 - printout(INFO,"Geant4Converter","++ Place %svolume %s in assembly.", - triplets[i].IsReflection() ? "REFLECTED " : "", - detail::tools::placementPath(new_chain).c_str()); -#endif - G4PhysicalVolumesPair pvPlaced - = G4ReflectionFactory::Instance()->Place( Tfinal, - pvName.str().c_str(), - triplets[i].GetVolume(), - pMotherLV, - false, - numberOfDaughters + i, - surfCheck ); - - // Register the physical volume created by us so we can delete it later - // - //fPVStore.emplace_back( pvPlaced.first ); - info.g4VolumeImprints[vol].emplace_back(new_chain,pvPlaced.first); -#if 0 - cout << " Assembly:Parent:" << parent->GetName() << " " << node->GetName() - << " " << (void*)node << " G4:" << pvName.str() << " Daughter:" - << detail::tools::placementPath(new_chain) << endl; - cout << endl; -#endif - - if ( pvPlaced.second ) { - G4Exception("G4AssemblyVolume::MakeImprint(..)", "GeomVol0003", FatalException, - "Fancy construct popping new mother from the stack!"); - //fPVStore.emplace_back( pvPlaced.second ); - } - } - else if ( triplets[i].GetAssembly() ) { - // Place volumes in this assembly with composed transformation - imprint(info, parent, new_chain, (Geant4AssemblyVolume*)triplets[i].GetAssembly(), - pMotherLV, Tfinal, i*100+copyNumBase, surfCheck ); - } - else { - --level; - G4Exception("G4AssemblyVolume::MakeImprint(..)", - "GeomVol0003", FatalException, - "Triplet has no volume and no assembly"); - } - } - //cout << "Imprinted assembly level:" << level << " in mother:" << pMotherLV->GetName() << endl; - --level; -} - namespace { static string indent = ""; static Double_t s_identity_rot[] = { 1., 0., 0., 0., 1., 0., 0., 0., 1. }; @@ -897,7 +772,7 @@ void* Geant4Converter::handlePlacement(const string& name, const TGeoNode* node) Geant4AssemblyVolume* ass = (Geant4AssemblyVolume*)info.g4AssemblyVolumes[node]; Geant4AssemblyVolume::Chain chain; chain.emplace_back(node); - ass->imprint(info,node,chain,ass,(*volIt).second, transform, copy, checkOverlaps); + ass->imprint(info, node, chain, ass, (*volIt).second, transform, copy, checkOverlaps); return nullptr; } else if ( node != info.manager->GetTopNode() && volIt == info.g4Volumes.end() ) {