From 8f111f0a36475090988c360500a650c0be4eb048 Mon Sep 17 00:00:00 2001 From: Markus Frank <Markus.Frank@cern.ch> Date: Wed, 13 Jul 2022 19:30:09 +0200 Subject: [PATCH] Implement GFlash for DDG4 with example examples/ClientTests/scripts/SiliconBlockGFlash.py --- DDCore/include/DD4hep/OpaqueData.h | 11 +- DDG4/include/DDG4/DDG4Dict.h | 2 + DDG4/include/DDG4/Geant4Data.h | 2 + DDG4/include/DDG4/Geant4Hits.h | 201 ------------------ DDG4/plugins/Geant4FastPhysics.cpp | 41 ++-- DDG4/plugins/Geant4GFlashShowerModel.cpp | 93 ++++++-- DDG4/plugins/Geant4SDActions.cpp | 80 +++++-- DDG4/plugins/Geant4TrackerWeightedSD.cpp | 9 +- DDG4/src/Geant4Converter.cpp | 104 ++++----- DDG4/src/Geant4Data.cpp | 19 ++ DDG4/src/Geant4Hits.cpp | 135 ------------ DDG4/src/Geant4PhysicsList.cpp | 20 ++ examples/ClientTests/compact/SiliconBlock.xml | 4 +- .../ClientTests/scripts/SiliconBlockGFlash.py | 41 ++-- .../Conditions/src/Conditions_any_basic.cpp | 6 +- 15 files changed, 310 insertions(+), 458 deletions(-) delete mode 100644 DDG4/include/DDG4/Geant4Hits.h delete mode 100644 DDG4/src/Geant4Hits.cpp diff --git a/DDCore/include/DD4hep/OpaqueData.h b/DDCore/include/DD4hep/OpaqueData.h index 45ce18864..ad19ca0a9 100644 --- a/DDCore/include/DD4hep/OpaqueData.h +++ b/DDCore/include/DD4hep/OpaqueData.h @@ -91,13 +91,21 @@ namespace dd4hep { */ class OpaqueDataBlock : public OpaqueData { + public: + /// Buffer size of the in-place data buffer + constexpr static const size_t BUFFER_SIZE = 40; + protected: /// Data buffer: plain data are allocated directly on this buffer /** This internal data buffer is sufficient to store any * STL vector, list, map, etc. and hence should be sufficient to * probably store normal relatively primitive basic objects. + * + * It appears that on clang the size of std::any is 32 bytes (16 bytes on g++_, + * whereas the size of std::vector is 24. Lets take 40 bytes and check it in the + * Conditions_any_basic example... */ - unsigned char data[sizeof(std::vector<void*>)]; + unsigned char data[BUFFER_SIZE]; public: enum _DataTypes { @@ -107,7 +115,6 @@ namespace dd4hep { BOUND_DATA = 1<<3, EXTERN_DATA = 1<<4 }; - /// Data buffer type: Must be a bitmap of enum _DataTypes! unsigned int type; diff --git a/DDG4/include/DDG4/DDG4Dict.h b/DDG4/include/DDG4/DDG4Dict.h index e7ce4879c..073f1239a 100644 --- a/DDG4/include/DDG4/DDG4Dict.h +++ b/DDG4/include/DDG4/DDG4Dict.h @@ -151,6 +151,8 @@ namespace dd4hep { inline Geant4Tracker::Hit& Geant4Tracker::Hit::clear() { return *this; } /// Store Geant4 point and step information into tracker hit structure. inline Geant4Tracker::Hit& Geant4Tracker::Hit::storePoint(const G4Step*, const G4StepPoint*) { return *this;} + /// Store Geant4 spot information into tracker hit structure. + inline Geant4Tracker::Hit& Geant4Tracker::Hit::storePoint(const G4GFlashSpot*) { return *this;} /// Default constructor inline Geant4Calorimeter::Hit::Hit() : energyDeposit(0e0) { } /// Initializing constructor diff --git a/DDG4/include/DDG4/Geant4Data.h b/DDG4/include/DDG4/Geant4Data.h index 699e1809b..5a5e6a5e0 100644 --- a/DDG4/include/DDG4/Geant4Data.h +++ b/DDG4/include/DDG4/Geant4Data.h @@ -263,6 +263,8 @@ namespace dd4hep { Hit& clear(); /// Store Geant4 point and step information into tracker hit structure. Hit& storePoint(const G4Step* step, const G4StepPoint* point); + /// Store Geant4 spot information into tracker hit structure. + Hit& storePoint(const G4GFlashSpot* spot); }; }; diff --git a/DDG4/include/DDG4/Geant4Hits.h b/DDG4/include/DDG4/Geant4Hits.h deleted file mode 100644 index 60fc18d47..000000000 --- a/DDG4/include/DDG4/Geant4Hits.h +++ /dev/null @@ -1,201 +0,0 @@ -//========================================================================== -// 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 -// -//========================================================================== - -#ifndef DDG4_GEANT4HITS_H -#define DDG4_GEANT4HITS_H - -// Framework include files -#include "DD4hep/Objects.h" -#include "DDG4/Geant4StepHandler.h" - -// Geant4 include files -#include "G4VHit.hh" -#include "G4Step.hh" -#include "G4StepPoint.hh" - -/// 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 Geant4Hit; - class Geant4TrackerHit; - class Geant4CalorimeterHit; - - /// Deprecated: Base class for hit comparisons. - /** @class HitCompare Geant4Hits.h DDG4/Geant4Hits.h - * - * @author M.Frank - * @version 1.0 - */ - template <class HIT> class HitCompare { - public: - /// Default destructor - virtual ~HitCompare() {} - /// Comparison function - virtual bool operator()(const HIT* h) const = 0; - }; - - /// Deprecated: Seek the hits of an arbitrary collection for the same position. - /** @class HitPositionCompare Geant4Hits.h DDG4/Geant4Hits.h - * - * @author M.Frank - * @version 1.0 - */ - template <class HIT> struct HitPositionCompare: public HitCompare<HIT> { - /// Reference to the hit position - const Position& pos; - /// Constructor - HitPositionCompare(const Position& p) : pos(p) {} - /// Default destructor - virtual ~HitPositionCompare() {} - /// Comparison function - virtual bool operator()(const HIT* h) const { - return pos == h->position; - } - }; - - /// Deprecated: basic geant4 hit class for deprecated sensitive detectors - /** @class Geant4Hit Geant4Hits.h DDG4/Geant4Hits.h - * - * Geant4 hit base class. Here only the basic - * quantites are stored such as the energy deposit and - * the time stamp. - * - * @author M.Frank - * @version 1.0 - */ - class Geant4Hit: public G4VHit { - public: - - // cellID - unsigned long cellID = 0; - - /// Deprecated!!! - struct MonteCarloContrib { - /// Geant 4 Track identifier - int trackID = -1; - /// Particle ID from the PDG table - int pdgID = -1; - /// Total energy deposit in this hit - double deposit = 0.0; - /// Timestamp when this energy was deposited - double time = 0.0; - /// Default constructor - MonteCarloContrib() = default; - /// Copy constructor - MonteCarloContrib(const MonteCarloContrib& c) = default; - /// Initializing constructor - MonteCarloContrib(int track_id, double dep, double time_stamp) - : trackID(track_id), pdgID(-1), deposit(dep), time(time_stamp) {} - /// Initializing constructor - MonteCarloContrib(int track_id, int pdg, double dep, double time_stamp) - : trackID(track_id), pdgID(pdg), deposit(dep), time(time_stamp) {} - /// Assignment operator - MonteCarloContrib& operator=(const MonteCarloContrib& c) = default; - /// Clear data - void clear() { - time = deposit = 0.0; - pdgID = trackID = -1; - } - }; - typedef MonteCarloContrib Contribution; - typedef std::vector<MonteCarloContrib> Contributions; - - public: - /// Standard constructor - Geant4Hit() = default; - /// Default destructor - virtual ~Geant4Hit() { } - /// Check if the Geant4 track is a Geantino - static bool isGeantino(G4Track* track); - /// Extract the MC contribution for a given hit from the step information - static Contribution extractContribution(G4Step* step); - }; - - /// Deprecated: Geant4 tracker hit class for deprecated sensitive detectors - /** @class Geant4TrackerHit Geant4Hits.h DDG4/Geant4Hits.h - * - * Geant4 tracker hit class. Tracker hits contain the momentum - * direction as well as the hit position. - * - * @author M.Frank - * @version 1.0 - */ - class Geant4TrackerHit: public Geant4Hit { - public: - /// Hit position - Position position; - /// Hit direction - Direction momentum; - /// Length of the track segment contributing to this hit - double length; - /// Monte Carlo / Geant4 information - Contribution truth; - /// Energy deposit of the hit - double energyDeposit; - - public: - /// Default constructor - Geant4TrackerHit(); - /// Standard initializing constructor - Geant4TrackerHit(int track_id, int pdg_id, double deposit, double time_stamp); - /// Default destructor - virtual ~Geant4TrackerHit() {} - /// Clear hit content - Geant4TrackerHit& clear(); - /// Store Geant4 point and step information into tracker hit structure. - Geant4TrackerHit& storePoint(G4Step* step, G4StepPoint* point); - - /// Assignment operator - Geant4TrackerHit& operator=(const Geant4TrackerHit& c); - /// Geant4 required object allocator - void *operator new(size_t); - /// Geat4 required object destroyer - void operator delete(void *ptr); - }; - - /// Deprecated: Geant4 calorimeter hit class for deprecated sensitive detectors - /** @class Geant4CalorimeterHit Geant4Hits.h DDG4/Geant4Hits.h - * - * Geant4 calorimeter hit class. Calorimeter hits contain the momentum - * direction as well as the hit position. - * - * @author M.Frank - * @version 1.0 - */ - class Geant4CalorimeterHit: public Geant4Hit { - public: - /// Hit position - Position position; - /// Hit contributions by individual particles - Contributions truth; - /// Total energy deposit - double energyDeposit; - public: - /// Standard constructor - Geant4CalorimeterHit(const Position& cell_pos); - /// Default destructor - virtual ~Geant4CalorimeterHit() { } - /// Geant4 required object allocator - void *operator new(size_t); - /// Geat4 required object destroyer - void operator delete(void *ptr); - }; - - } // End namespace sim -} // End namespace dd4hep - -#endif // DDG4_GEANT4HITS_H diff --git a/DDG4/plugins/Geant4FastPhysics.cpp b/DDG4/plugins/Geant4FastPhysics.cpp index 31ee544a4..9e59a52e0 100644 --- a/DDG4/plugins/Geant4FastPhysics.cpp +++ b/DDG4/plugins/Geant4FastPhysics.cpp @@ -15,9 +15,11 @@ // Framework include files #include <DDG4/Geant4Action.h> +#include <DDG4/Geant4PhysicsList.h> // Geant4 include files -#include <G4FastSimulationPhysics.hh> +#include <G4VModularPhysicsList.hh> +class G4FastSimulationPhysics; // C/C++ include files #include <vector> @@ -39,7 +41,7 @@ namespace dd4hep { * \version 1.0 * \ingroup DD4HEP_SIMULATION */ - class Geant4FastPhysics : public Geant4Action, public G4FastSimulationPhysics { + class Geant4FastPhysics : public Geant4PhysicsList { protected: /// Define standard assignments and constructors DDG4_DEFINE_ACTION_CONSTRUCTORS(Geant4FastPhysics); @@ -49,6 +51,9 @@ namespace dd4hep { /// Property to set verbosity flag on G4FastSimulationPhysics bool m_verbose { false }; + /// Reference to fast physics object + G4FastSimulationPhysics* m_fastPhysics { nullptr }; + public: /// Standard constructor Geant4FastPhysics(Geant4Context* context, const std::string& nam); @@ -56,8 +61,8 @@ namespace dd4hep { /// Default destructor virtual ~Geant4FastPhysics() = default; - /// This method will be invoked in the Construct() method. - virtual void ConstructProcess() override; + /// constructPhysics callback + virtual void constructPhysics(G4VModularPhysicsList* physics) override; }; } /* End namespace sim */ } /* End namespace dd4hep */ @@ -79,28 +84,38 @@ namespace dd4hep { /// Framework include files // #include <DDG4/Geant4FastPhysics.h> +// Geant4 include files +#include <G4FastSimulationPhysics.hh> + using namespace dd4hep; using namespace dd4hep::sim; /// Standard constructor Geant4FastPhysics::Geant4FastPhysics(Geant4Context* ctxt, const std::string& nam) -: Geant4Action(ctxt, nam), G4FastSimulationPhysics() +: Geant4PhysicsList(ctxt, nam) { declareProperty("EnabledParticles", m_enabledParticles); declareProperty("BeVerbose", m_verbose); } -/// This method will be invoked in the Construct() method. -void Geant4FastPhysics::ConstructProcess() { - if ( this->m_verbose ) this->BeVerbose(); +/// constructPhysics callback +void Geant4FastPhysics::constructPhysics(G4VModularPhysicsList* physics) { + /// Create and configure the fast simulation object according to properties + m_fastPhysics = new G4FastSimulationPhysics(this->name()); + if ( this->m_verbose ) m_fastPhysics->BeVerbose(); + + /// attach the particles the fast simulation object should act on for( const auto& part_name : m_enabledParticles ) { this->info("Enable fast simulation for particle type: %s", part_name.c_str()); - this->ActivateFastSimulation(part_name); + m_fastPhysics->ActivateFastSimulation(part_name); } - // -- Create a fast simulation physics constructor, used to augment - // -- the above physics list to allow for fast simulation - this->G4FastSimulationPhysics::ConstructProcess(); - this->info("Constructed and initialized Geant4 Fast Physics."); + /// -- Register this fastSimulationPhysics to the physicsList, + /// -- when the physics list will be called by the run manager + /// -- (will happen at initialization of the run manager) + /// -- for physics process construction, the fast simulation + /// -- configuration will be applied as well. + physics->RegisterPhysics(m_fastPhysics); + this->info("Constructed and initialized Geant4 Fast Physics [G4FastSimulationPhysics]."); } #include "DDG4/Factories.h" diff --git a/DDG4/plugins/Geant4GFlashShowerModel.cpp b/DDG4/plugins/Geant4GFlashShowerModel.cpp index 0603c7139..9c2b7e9d7 100644 --- a/DDG4/plugins/Geant4GFlashShowerModel.cpp +++ b/DDG4/plugins/Geant4GFlashShowerModel.cpp @@ -18,8 +18,9 @@ #include <DDG4/Geant4DetectorConstruction.h> // Geant4 include files -#include "G4FastSimulationPhysics.hh" +#include <G4FastSimulationPhysics.hh> class GVFlashShowerParameterisation; +class G4ParticleDefinition; class GFlashParticleBounds; class GFlashShowerModel; class GFlashHitMaker; @@ -51,6 +52,9 @@ namespace dd4hep { */ class Geant4GFlashShowerModel : public Geant4DetectorConstruction { protected: + // typedef std::vector<std::pair<std::string, double> > ParticleConfig; + typedef std::map<std::string, std::string> ParticleConfig; + /// Property: Region name to which this parametrization should be applied std::string m_regionName { "Region-name-not-specified"}; /// Property: Name of the Geant4Action implementing the parametrization @@ -64,6 +68,19 @@ namespace dd4hep { /// Property: Parameter 2 name for GFlashSamplingShowerParameterisation double m_parameter_2; + /// Property: Parametrisation control: Enable GFlash (is disabled by default in Geant4) + bool m_enable { false }; + /// Property: Defines if particle containment is checked + int m_particleCountainment { 1 }; + /// Property: Defines step lenght + double m_stepX0 { 0.1 }; + /// Property: Set minimum kinetic energy to trigger parametrisation + ParticleConfig m_eMin { }; + /// Property: Set maximum kinetic energy to trigger parametrisation + ParticleConfig m_eMax { }; + /// Property: Set maximum kinetic energy for electrons to be killed + ParticleConfig m_eKill { }; + /// Reference to the shower model GFlashShowerModel* m_showerModel { nullptr }; /// Reference to the parametrization @@ -80,6 +97,9 @@ namespace dd4hep { /// Get parametrization material G4Material* getMaterial(const std::string& name) const; + /// Access particle definition from string + G4ParticleDefinition* getParticleDefinition(const std::string& name) const; + public: /// Standard constructor Geant4GFlashShowerModel(Geant4Context* context, const std::string& nam); @@ -120,15 +140,17 @@ namespace dd4hep { #include <DDG4/Geant4Action.h> #include <DDG4/Geant4Kernel.h> #include <DDG4/Geant4Mapping.h> +#include <DD4hep/DD4hepUnits.h> // Geant4 include files -#include "GVFlashShowerParameterisation.hh" -#include "GFlashHomoShowerParameterisation.hh" -#include "GFlashSamplingShowerParameterisation.hh" -#include "G4FastSimulationManager.hh" -#include "GFlashShowerModel.hh" -#include "GFlashHitMaker.hh" -#include "GFlashParticleBounds.hh" +#include <GVFlashShowerParameterisation.hh> +#include <GFlashHomoShowerParameterisation.hh> +#include <GFlashSamplingShowerParameterisation.hh> +#include <G4FastSimulationManager.hh> +#include <GFlashShowerModel.hh> +#include <GFlashHitMaker.hh> +#include <GFlashParticleBounds.hh> +#include <G4ParticleTable.hh> #include <sstream> @@ -139,13 +161,19 @@ using namespace dd4hep::sim; Geant4GFlashShowerModel::Geant4GFlashShowerModel(Geant4Context* ctxt, const std::string& nam) : Geant4DetectorConstruction(ctxt, nam) { - declareProperty("RegionName", m_regionName); - declareProperty("Parametrization", m_paramName); - declareProperty("Material", m_material); - declareProperty("Material_1", m_material); - declareProperty("Material_2", m_material_2); - declareProperty("Parameter_1", m_parameter_1); - declareProperty("Parameter_2", m_parameter_2); + declareProperty("RegionName", m_regionName); + declareProperty("Parametrization", m_paramName); + declareProperty("Material", m_material); + declareProperty("Material_1", m_material); + declareProperty("Material_2", m_material_2); + declareProperty("Parameter_1", m_parameter_1); + declareProperty("Parameter_2", m_parameter_2); + declareProperty("Enable", m_enable); + declareProperty("CheckParticleContainment", m_particleCountainment); + declareProperty("StepLength", m_stepX0); + declareProperty("Emin", m_eMin); + declareProperty("Emax", m_eMax); + declareProperty("Ekill", m_eKill); } /// Default destructor @@ -162,6 +190,15 @@ Geant4GFlashShowerModel::~Geant4GFlashShowerModel() { m_hitMaker = nullptr; } +/// Access particle definition from string +G4ParticleDefinition* Geant4GFlashShowerModel::getParticleDefinition(const std::string& particle) const { + G4ParticleTable* pt = G4ParticleTable::GetParticleTable(); + G4ParticleDefinition* def = pt->FindParticle(particle); + if ( def ) return def; + except("Failed to access Geant4 particle definition: %s", particle.c_str()); + return nullptr; +} + G4Material* Geant4GFlashShowerModel::getMaterial(const std::string& mat_name) const { auto& kernel = this->context()->kernel(); Geant4GeometryInfo& mapping = Geant4Mapping::instance().data(); @@ -252,8 +289,32 @@ void Geant4GFlashShowerModel::constructSensitives(Geant4DetectorConstructionCont this->m_showerModel->SetParameterisation(*this->m_parametrization); this->m_showerModel->SetParticleBounds(*this->m_particleBounds); this->m_showerModel->SetHitMaker(*this->m_hitMaker); + + /// Now configure the shower model: + this->m_showerModel->SetFlagParamType(this->m_enable ? 1 : 0); + this->m_showerModel->SetFlagParticleContainment(this->m_particleCountainment); + this->m_showerModel->SetStepInX0(this->m_stepX0); + + for(const auto& prop : this->m_eMin) { + G4ParticleDefinition* def = this->getParticleDefinition(prop.first); + double val = dd4hep::_toDouble(prop.second) * dd4hep::GeV/CLHEP::GeV; + this->m_particleBounds->SetMinEneToParametrise(*def, val); + this->info("SetMinEneToParametrise [%-16s] = %8.4f GeV", prop.first.c_str(), val); + } + for(const auto& prop : this->m_eMax) { + G4ParticleDefinition* def = this->getParticleDefinition(prop.first); + double val = dd4hep::_toDouble(prop.second) * dd4hep::GeV/CLHEP::GeV; + this->m_particleBounds->SetMaxEneToParametrise(*def, val); + this->info("SetMaxEneToParametrise [%-16s] = %8.4f GeV", prop.first.c_str(), val); + } + for(const auto& prop : this->m_eKill) { + G4ParticleDefinition* def = this->getParticleDefinition(prop.first); + double val = dd4hep::_toDouble(prop.second) * dd4hep::GeV/CLHEP::GeV; + this->m_particleBounds->SetEneToKill(*def, val); + this->info("SetEneToKill [%-16s] = %8.4f GeV", prop.first.c_str(), val); + } this->info(logger.str().c_str()); } -#include "DDG4/Factories.h" +#include <DDG4/Factories.h> DECLARE_GEANT4ACTION(Geant4GFlashShowerModel) diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp index be59e9f4d..b2788a182 100644 --- a/DDG4/plugins/Geant4SDActions.cpp +++ b/DDG4/plugins/Geant4SDActions.cpp @@ -486,34 +486,42 @@ namespace dd4hep { struct TrackerCombine { Geant4Tracker::Hit pre, post; Position mean_pos; - Geant4Sensitive* sensitive; - double mean_time; - double e_cut; - int current; - int combined; - long long int cell; - - TrackerCombine() : pre(), post(), sensitive(0), mean_time(0.0), - e_cut(0.0), current(-1), combined(0), cell(0) - { + Geant4Sensitive* sensitive { nullptr }; + G4VPhysicalVolume* firstSpotVolume { nullptr }; + double mean_time { 0e0 }; + double e_cut { 0e0 }; + int current { -1 }; + int combined { 0 }; + long long int cell { 0 }; + + TrackerCombine() : pre(), post() { } /// Start a new hit - void start(G4Step* step, G4StepPoint* point) { - pre.storePoint(step,point); + void start_collecting(const G4Track* track) { pre.truth.deposit = 0.0; current = pre.truth.trackID; - sensitive->mark(step->GetTrack()); + sensitive->mark(track); mean_pos.SetXYZ(0,0,0); mean_time = 0; post.copyFrom(pre); combined = 0; cell = 0; } + void start(G4Step* step, G4StepPoint* point) { + pre.storePoint(step,point); + start_collecting(step->GetTrack()); + firstSpotVolume = step->GetPreStepPoint()->GetTouchableHandle()->GetVolume(); + } + void start(G4GFlashSpot* spot) { + const G4Track* track = spot->GetOriginatorTrack()->GetPrimaryTrack(); + pre.storePoint(spot); + start_collecting(track); + firstSpotVolume = spot->GetTouchableHandle()->GetVolume(); + } /// Update energy and track information during hit info accumulation - void update(G4Step* step) { - post.storePoint(step,step->GetPostStepPoint()); + template <typename T> inline void update_collected_hit(const T* step) { pre.truth.deposit += post.truth.deposit; mean_pos.SetX(mean_pos.x()+post.position.x()*post.truth.deposit); mean_pos.SetY(mean_pos.y()+post.position.y()*post.truth.deposit); @@ -528,6 +536,14 @@ namespace dd4hep { } ++combined; } + void update(G4Step* step) { + post.storePoint(step,step->GetPostStepPoint()); + update_collected_hit(step); + } + void update(G4GFlashSpot* spot) { + post.storePoint(spot); + update_collected_hit(spot); + } /// Clear collected information and restart for new hit void clear() { @@ -538,6 +554,7 @@ namespace dd4hep { current = -1; combined = 0; cell = 0; + firstSpotVolume = nullptr; } /// Helper function to decide if the hit has to be extracted and saved in the collection @@ -607,10 +624,37 @@ namespace dd4hep { } return true; } + /// Method for generating hit(s) using the information of G4Step object. - G4bool process(G4GFlashSpot* , G4TouchableHistory* ) { - sensitive->except("GFlash action is not implemented for SD: %s", sensitive->c_name()); - return false; + G4bool process(G4GFlashSpot* spot, G4TouchableHistory* ) { + Geant4GFlashSpotHandler h(spot); + G4VPhysicalVolume* prePV = firstSpotVolume, *postPV = h.volume(); + Geant4HitCollection* coll = sensitive->collection(0); + /// If we are handling a new track, then store the content of the previous one. + if ( mustSaveTrack(h.track) ) { + extractHit(coll); + } + /// Initialize the deposits of the next hit. + if ( current < 0 ) { + start(spot); + } + /// ....update ..... + update(spot); + + if ( firstSpotVolume && prePV != postPV ) { + void* postSD = h.sd(); + extractHit(coll); + if ( 0 != postSD ) { + void* preSD = prePV ? prePV->GetLogicalVolume()->GetSensitiveDetector() : nullptr; + if ( preSD == postSD ) { + start(spot); + } + } + } + else if ( h.track->GetTrackStatus() == fStopAndKill ) { + extractHit(coll); + } + return true; } /// Post-event action callback diff --git a/DDG4/plugins/Geant4TrackerWeightedSD.cpp b/DDG4/plugins/Geant4TrackerWeightedSD.cpp index b50c32218..8ee19a474 100644 --- a/DDG4/plugins/Geant4TrackerWeightedSD.cpp +++ b/DDG4/plugins/Geant4TrackerWeightedSD.cpp @@ -1,5 +1,5 @@ //========================================================================== -// AIDA Detector description implementation +// AIDA Detector description implementation //-------------------------------------------------------------------------- // Copyright (C) Organisation europeenne pour la Recherche nucleaire (CERN) // All rights reserved. @@ -426,6 +426,12 @@ namespace dd4hep { << ", PDG: " << s->GetTrack()->GetDefinition()->GetPDGEncoding(); std::cout << str.str() << std::endl; } + + /// GFLash processing callback + G4bool process(G4GFlashSpot* , G4TouchableHistory* ) { + sensitive->except("GFlash action is not implemented for SD: %s", sensitive->c_name()); + return false; + } }; /// Initialization overload for specialization @@ -461,7 +467,6 @@ namespace dd4hep { Geant4SensitiveAction<TrackerWeighted>::process(G4Step* step, G4TouchableHistory* history) { return m_userData.process(step, history); } - typedef Geant4SensitiveAction<TrackerWeighted> Geant4TrackerWeightedAction; } } diff --git a/DDG4/src/Geant4Converter.cpp b/DDG4/src/Geant4Converter.cpp index b8b86a216..9633af80c 100644 --- a/DDG4/src/Geant4Converter.cpp +++ b/DDG4/src/Geant4Converter.cpp @@ -13,65 +13,65 @@ // Framework include files -#include "DD4hep/Detector.h" -#include "DD4hep/Plugins.h" -#include "DD4hep/Shapes.h" -#include "DD4hep/Volumes.h" -#include "DD4hep/Printout.h" -#include "DD4hep/DD4hepUnits.h" -#include "DD4hep/PropertyTable.h" -#include "DD4hep/detail/ShapesInterna.h" -#include "DD4hep/detail/ObjectsInterna.h" -#include "DD4hep/detail/DetectorInterna.h" - -#include "DDG4/Geant4Field.h" -#include "DDG4/Geant4Converter.h" -#include "DDG4/Geant4UserLimits.h" +#include <DD4hep/Detector.h> +#include <DD4hep/Plugins.h> +#include <DD4hep/Shapes.h> +#include <DD4hep/Volumes.h> +#include <DD4hep/Printout.h> +#include <DD4hep/DD4hepUnits.h> +#include <DD4hep/PropertyTable.h> +#include <DD4hep/detail/ShapesInterna.h> +#include <DD4hep/detail/ObjectsInterna.h> +#include <DD4hep/detail/DetectorInterna.h> + +#include <DDG4/Geant4Field.h> +#include <DDG4/Geant4Converter.h> +#include <DDG4/Geant4UserLimits.h> #include "Geant4ShapeConverter.h" // ROOT includes -#include "TMath.h" -#include "TROOT.h" -//#include "TColor.h" -//#include "TGeoManager.h" -#include "TGeoBoolNode.h" +#include <TMath.h> +#include <TROOT.h> +//#include <TColor.h> +//#include <TGeoManager.h> +#include <TGeoBoolNode.h> // Geant4 include files -#include "G4Version.hh" -#include "G4VisAttributes.hh" -#include "G4ProductionCuts.hh" -#include "G4VUserRegionInformation.hh" - -#include "G4Box.hh" -#include "G4Tubs.hh" -#include "G4Ellipsoid.hh" -#include "G4UnionSolid.hh" -#include "G4ReflectedSolid.hh" -#include "G4SubtractionSolid.hh" -#include "G4IntersectionSolid.hh" -#include "G4VSensitiveDetector.hh" - -#include "G4Region.hh" -#include "G4Element.hh" -#include "G4Element.hh" -#include "G4Isotope.hh" -#include "G4Material.hh" -#include "G4UserLimits.hh" -#include "G4FieldManager.hh" -#include "G4LogicalVolume.hh" -#include "G4ReflectionFactory.hh" -#include "G4OpticalSurface.hh" -#include "G4LogicalSkinSurface.hh" -#include "G4ElectroMagneticField.hh" -#include "G4LogicalBorderSurface.hh" -#include "G4MaterialPropertiesTable.hh" +#include <G4Version.hh> +#include <G4VisAttributes.hh> +#include <G4ProductionCuts.hh> +#include <G4VUserRegionInformation.hh> + +#include <G4Box.hh> +#include <G4Tubs.hh> +#include <G4Ellipsoid.hh> +#include <G4UnionSolid.hh> +#include <G4ReflectedSolid.hh> +#include <G4SubtractionSolid.hh> +#include <G4IntersectionSolid.hh> +#include <G4VSensitiveDetector.hh> + +#include <G4Region.hh> +#include <G4Element.hh> +#include <G4Element.hh> +#include <G4Isotope.hh> +#include <G4Material.hh> +#include <G4UserLimits.hh> +#include <G4FieldManager.hh> +#include <G4LogicalVolume.hh> +#include <G4ReflectionFactory.hh> +#include <G4OpticalSurface.hh> +#include <G4LogicalSkinSurface.hh> +#include <G4ElectroMagneticField.hh> +#include <G4LogicalBorderSurface.hh> +#include <G4MaterialPropertiesTable.hh> #if G4VERSION_NUMBER >= 1040 -#include "G4MaterialPropertiesIndex.hh" +#include <G4MaterialPropertiesIndex.hh> #endif #if G4VERSION_NUMBER >= 1030 -#include "G4ScaledSolid.hh" +#include <G4ScaledSolid.hh> #endif -#include "CLHEP/Units/SystemOfUnits.h" +#include <CLHEP/Units/SystemOfUnits.h> // C/C++ include files #include <iostream> @@ -84,8 +84,8 @@ using namespace dd4hep::sim; using namespace dd4hep; using namespace std; -#include "DDG4/Geant4AssemblyVolume.h" -#include "DD4hep/DetectorTools.h" +#include <DDG4/Geant4AssemblyVolume.h> +#include <DD4hep/DetectorTools.h> static constexpr const double CM_2_MM = (CLHEP::centimeter/dd4hep::centimeter); static constexpr const char* GEANT4_TAG_IGNORE = "Geant4-ignore"; diff --git a/DDG4/src/Geant4Data.cpp b/DDG4/src/Geant4Data.cpp index 9755692ac..aa828acf9 100644 --- a/DDG4/src/Geant4Data.cpp +++ b/DDG4/src/Geant4Data.cpp @@ -152,6 +152,25 @@ Geant4Tracker::Hit& Geant4Tracker::Hit::storePoint(const G4Step* step, const G4S return *this; } +/// Store Geant4 spot information into tracker hit structure. +Geant4Tracker::Hit& Geant4Tracker::Hit::storePoint(const G4GFlashSpot* spot) { + const GFlashEnergySpot* espot = spot->GetEnergySpot(); + const G4FastTrack* ftrk = spot->GetOriginatorTrack(); + const G4Track* trk = ftrk->GetPrimaryTrack(); + G4ThreeVector pos = spot->GetPosition(); + G4ThreeVector mom = trk->GetMomentum().unit(); + double dep = espot->GetEnergy(); + truth.trackID = trk->GetTrackID(); + truth.pdgID = trk->GetDefinition()->GetPDGEncoding(); + truth.deposit = dep; + truth.time = trk->GetGlobalTime(); + energyDeposit = dep; + position.SetXYZ(pos.x(), pos.y(), pos.z()); + momentum.SetXYZ(mom.x()*dep, mom.y()*dep, mom.z()*dep); + length = 0; + return *this; +} + /// Default constructor (for ROOT) Geant4Calorimeter::Hit::Hit() : Geant4HitData(), position(), truth(), energyDeposit(0) { diff --git a/DDG4/src/Geant4Hits.cpp b/DDG4/src/Geant4Hits.cpp deleted file mode 100644 index 575be9d07..000000000 --- a/DDG4/src/Geant4Hits.cpp +++ /dev/null @@ -1,135 +0,0 @@ -//========================================================================== -// 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 -// -//========================================================================== - -// Framework include files -#include "DDG4/Geant4Hits.h" - -// Geant4 include files -#include "G4Allocator.hh" -#include "G4ParticleDefinition.hh" -#include "G4ChargedGeantino.hh" -#include "G4OpticalPhoton.hh" -#include "G4Geantino.hh" - -// C/C++ include files -#include <iostream> - -using namespace std; -using namespace dd4hep::sim; - -G4ThreadLocal G4Allocator<Geant4TrackerHit>* TrackerHitAllocator = 0; -G4ThreadLocal G4Allocator<Geant4CalorimeterHit>* CalorimeterHitAllocator = 0; - - -/// Check if the Geant4 track is a Geantino -bool Geant4Hit::isGeantino(G4Track* track) { - if (track) { - G4ParticleDefinition* def = track->GetDefinition(); - if (def == G4ChargedGeantino::Definition()) - return true; - if (def == G4Geantino::Definition()) { - return true; - } - } - return false; -} - -Geant4Hit::Contribution Geant4Hit::extractContribution(G4Step* step) { - G4Track* trk = step->GetTrack(); - double energy_deposit = - (trk->GetDefinition() == G4OpticalPhoton::OpticalPhotonDefinition()) ? - trk->GetTotalEnergy() : step->GetTotalEnergyDeposit(); - Contribution contrib(trk->GetTrackID(), trk->GetDefinition()->GetPDGEncoding(), energy_deposit, trk->GetGlobalTime()); - return contrib; -} - -/// Default constructor -Geant4TrackerHit::Geant4TrackerHit() - : Geant4Hit(), position(), momentum(), length(0.0), truth(), energyDeposit(0.0) { -} - -/// Standard initializing constructor -Geant4TrackerHit::Geant4TrackerHit(int track_id, int pdg_id, double deposit, double time_stamp) - : Geant4Hit(), position(), momentum(), length(0.0), truth(track_id, pdg_id, deposit, time_stamp), energyDeposit(deposit) { -} - -/// Assignment operator -Geant4TrackerHit& Geant4TrackerHit::operator=(const Geant4TrackerHit& c) { - if ( this != &c ) { - position = c.position; - momentum = c.momentum; - length = c.length; - truth = c.truth; - energyDeposit = c.energyDeposit; - } - return *this; -} - -/// Clear hit content -Geant4TrackerHit& Geant4TrackerHit::clear() { - position.SetXYZ(0, 0, 0); - momentum.SetXYZ(0, 0, 0); - length = 0.0; - truth.clear(); - energyDeposit = 0.0; - return *this; -} - -/// Store Geant4 point and step information into tracker hit structure. -Geant4TrackerHit& Geant4TrackerHit::storePoint(G4Step* step, G4StepPoint* pnt) { - G4Track* trk = step->GetTrack(); - G4ThreeVector pos = pnt->GetPosition(); - G4ThreeVector mom = pnt->GetMomentum(); - - truth.trackID = trk->GetTrackID(); - truth.pdgID = trk->GetDefinition()->GetPDGEncoding(); - truth.deposit = step->GetTotalEnergyDeposit(); - truth.time = trk->GetGlobalTime(); - energyDeposit = step->GetTotalEnergyDeposit(); - position.SetXYZ(pos.x(), pos.y(), pos.z()); - momentum.SetXYZ(mom.x(), mom.y(), mom.z()); - length = 0; - return *this; -} - -/// Geant4 required object allocator -void* Geant4TrackerHit::operator new(size_t) { - if ( TrackerHitAllocator ) - return TrackerHitAllocator->MallocSingle(); - TrackerHitAllocator = new G4Allocator<Geant4TrackerHit>; - return TrackerHitAllocator->MallocSingle(); -} - -/// Geat4 required object destroyer -void Geant4TrackerHit::operator delete(void *p) { - TrackerHitAllocator->FreeSingle((Geant4TrackerHit*) p); -} - -/// Standard constructor -Geant4CalorimeterHit::Geant4CalorimeterHit(const Position& pos) - : Geant4Hit(), position(pos), truth(), energyDeposit(0) { -} - -/// Geant4 required object allocator -void* Geant4CalorimeterHit::operator new(size_t) { - if ( CalorimeterHitAllocator ) - return CalorimeterHitAllocator->MallocSingle(); - CalorimeterHitAllocator = new G4Allocator<Geant4CalorimeterHit>; - return CalorimeterHitAllocator->MallocSingle(); -} - -/// Geat4 required object destroyer -void Geant4CalorimeterHit::operator delete(void *p) { - CalorimeterHitAllocator->FreeSingle((Geant4CalorimeterHit*) p); -} - diff --git a/DDG4/src/Geant4PhysicsList.cpp b/DDG4/src/Geant4PhysicsList.cpp index f63f863b2..fd505e7d0 100644 --- a/DDG4/src/Geant4PhysicsList.cpp +++ b/DDG4/src/Geant4PhysicsList.cpp @@ -333,11 +333,31 @@ Geant4PhysicsListActionSequence::~Geant4PhysicsListActionSequence() { InstanceCount::decrement(this); } +#include "G4FastSimulationPhysics.hh" + + /// Extend physics list from factory: G4VUserPhysicsList* Geant4PhysicsListActionSequence::extensionList() { G4VModularPhysicsList* physics = ( m_extends.empty() ) ? new EmptyPhysics() : G4PhysListFactory().GetReferencePhysList(m_extends); + +#if 0 + G4FastSimulationPhysics* fastSimulationPhysics = new G4FastSimulationPhysics(); + // -- We now configure the fastSimulationPhysics object. + // -- The gflash model (GFlashShowerModel, see ExGflashDetectorConstruction.cc) + // -- is applicable to e+ and e- : we augment the physics list for these + // -- particles (by adding a G4FastSimulationManagerProcess with below's + // -- calls), this will make the fast simulation to be activated: + fastSimulationPhysics->ActivateFastSimulation("e-"); + fastSimulationPhysics->ActivateFastSimulation("e+"); + // -- Register this fastSimulationPhysics to the physicsList, + // -- when the physics list will be called by the run manager + // -- (will happen at initialization of the run manager) + // -- for physics process construction, the fast simulation + // -- configuration will be applied as well. + physics->RegisterPhysics( fastSimulationPhysics ); +#endif // Register all physics constructors with the physics list constructPhysics(physics); // Ensure the particles and processes declared are also invoked. diff --git a/examples/ClientTests/compact/SiliconBlock.xml b/examples/ClientTests/compact/SiliconBlock.xml index 6e0d4431a..617b5b626 100644 --- a/examples/ClientTests/compact/SiliconBlock.xml +++ b/examples/ClientTests/compact/SiliconBlock.xml @@ -65,14 +65,14 @@ <detectors> <detector id="1" name="SiliconBlockUpper" type="DD4hep_BoxSegment" readout="SiliconUpperHits" vis="VisibleGreen" sensitive="true" region="SiRegion" limits="SiRegionLimitSet"> - <material name="G4_PbWO4"/> + <material name="Silicon"/> <sensitive type="tracker"/> <box x="30*mm" y="100*cm" z="100*cm"/> <position x="4*cm" y="0" z="0"/> <rotation x="0" y="0" z="0"/> </detector> <detector id="2" name="SiliconBlockDown" type="DD4hep_BoxSegment" readout="SiliconDownHits" vis="VisibleRed" sensitive="true" region="SiRegion" limits="SiRegionLimitSet"> - <material name="G4_PbWO4"/> + <material name="Silicon"/> <sensitive type="tracker"/> <box x="30*mm" y="100*cm" z="100*cm"/> <position x="-4*cm" y="0" z="0"/> diff --git a/examples/ClientTests/scripts/SiliconBlockGFlash.py b/examples/ClientTests/scripts/SiliconBlockGFlash.py index ecce98cc3..d49b2f73a 100644 --- a/examples/ClientTests/scripts/SiliconBlockGFlash.py +++ b/examples/ClientTests/scripts/SiliconBlockGFlash.py @@ -23,6 +23,11 @@ from g4units import GeV, MeV, m dd4hep simulation example setup using the python configuration + NOTE: + If you get to the command prompt, you must not forget to enable GFlash! + By default Geant4 does not enable it. Hence: + Idle> /GFlash/flag 1 + @author M.Frank @version 1.0 @@ -35,7 +40,7 @@ def run(): kernel.loadGeometry(str("file:" + install_dir + "/examples/ClientTests/compact/SiliconBlock.xml")) DDG4.importConstants(kernel.detectorDescription(), debug=False) - geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction') + geant4 = DDG4.Geant4(kernel, tracker='Geant4TrackerCombineAction', calo='Geant4CalorimeterAction') geant4.printDetectors() # Configure UI if len(sys.argv) > 1: @@ -48,22 +53,33 @@ def run(): # Configure Event actions prt = DDG4.EventAction(kernel, 'Geant4ParticlePrint/ParticlePrint') prt.OutputLevel = Output.DEBUG - prt.OutputType = 3 # Print both: table and tree + # prt.OutputType = 3 # Print both: table and tree kernel.eventAction().adopt(prt) - generator_output_level = Output.INFO + generator_output_level = prt.OutputLevel #Output.INFO # Configure G4 geometry setup - seq, act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo") + seq, act = geant4.addDetectorConstruction('Geant4DetectorGeometryConstruction/ConstructGeo') act.DebugMaterials = True act.DebugElements = False act.DebugVolumes = True act.DebugShapes = True + # Apply sensitive detectors + sensitives = DDG4.DetectorConstruction(kernel, str('Geant4DetectorSensitivesConstruction/ConstructSD')) + sensitives.enableUI() + seq.adopt(sensitives) + + # Enable GFlash shower model model = DDG4.DetectorConstruction(kernel, str('Geant4GFlashShowerModel/ShowerModel')) model.Parametrization = 'GFlashHomoShowerParameterisation' + # Mandatory model parameters model.RegionName = 'SiRegion' model.Material = 'Silicon' + model.Enable = True + # Energy boundaries are optional + model.Emin = {'e+': 0.1*GeV, 'e-': 0.1*GeV } # Units in GeV + model.Ekill = {'e+': 0.1*MeV, 'e-': 0.1*MeV } model.enableUI() seq.adopt(model) @@ -71,7 +87,7 @@ def run(): geant4.setupROOTOutput('RootOutput', 'SiliconBlock_' + time.strftime('%Y-%m-%d_%H-%M')) # Setup particle gun - gun = geant4.setupGun("Gun", particle='e-', energy=20 * GeV, multiplicity=1) + gun = geant4.setupGun("Gun", particle='e+', energy=50 * GeV, multiplicity=1) gun.OutputLevel = generator_output_level # And handle the simulation particles. @@ -91,22 +107,15 @@ def run(): geant4.setupTracker('SiliconBlockDown') # Now build the physics list: - phys = geant4.setupPhysics('QGSP_BERT') - ph = DDG4.PhysicsList(kernel, str('Geant4PhysicsList/Myphysics')) - ph.addParticleConstructor(str('G4Geantino')) - ph.addParticleConstructor(str('G4BosonConstructor')) - ph.enableUI() - phys.adopt(ph) - - ph = DDG4.PhysicsList(kernel, str('Geant4PhysicsList/FastPhysicsList')) - fast = DDG4.Action(kernel, str('Geant4FastPhysics/FastPhysics')) - ph.adoptPhysicsConstructor(fast) + phys = geant4.setupPhysics('FTFP_BERT') + ph = DDG4.PhysicsList(kernel, str('Geant4FastPhysics/FastPhysicsList')) + ph.EnabledParticles = ['e+', 'e-'] + ph.BeVerbose = True ph.enableUI() phys.adopt(ph) phys.dump() geant4.execute() - if __name__ == "__main__": run() diff --git a/examples/Conditions/src/Conditions_any_basic.cpp b/examples/Conditions/src/Conditions_any_basic.cpp index 7055450f4..7f0eaa57b 100644 --- a/examples/Conditions/src/Conditions_any_basic.cpp +++ b/examples/Conditions/src/Conditions_any_basic.cpp @@ -78,7 +78,11 @@ static int condition_any_basic (Detector& /* description */, int /* argc */, cha cout << endl << endl; cout << "Size std::any: " << sizeof(std::any) << endl; cout << "Size std::vector: " << sizeof(std::vector<int>) << endl; - if ( sizeof(std::any) > sizeof(std::vector<int>) ) { + if ( sizeof(std::any) > OpaqueDataBlock::BUFFER_SIZE ) { + cout << endl << "Test FAILED" << endl << endl; + return EINVAL; + } + if ( sizeof(std::vector<void*>) > OpaqueDataBlock::BUFFER_SIZE ) { cout << endl << "Test FAILED" << endl << endl; return EINVAL; } -- GitLab