diff --git a/DDG4/include/DDG4/Geant4InputHandling.h b/DDG4/include/DDG4/Geant4InputHandling.h index 3bcf54c9076b592bd29496c644da7def9d7b5a7d..44bbd3ac32199b45214d7adfae8ea52b3468b40f 100644 --- a/DDG4/include/DDG4/Geant4InputHandling.h +++ b/DDG4/include/DDG4/Geant4InputHandling.h @@ -43,7 +43,7 @@ namespace DD4hep { Geant4Particle* createPrimary(int particle_id, const Geant4Vertex* v, const G4PrimaryParticle* g4p); /// Create a DDG4 interaction record from a Geant4 interaction defined by a primary vertex - Geant4PrimaryInteraction* createPrimary(int mask, const G4PrimaryVertex* gv); + Geant4PrimaryInteraction* createPrimary(int mask, Geant4PrimaryMap* pm, const G4PrimaryVertex* gv); /// Initialize the generation of one event int generationInitialization(const Geant4Action* caller,const Geant4Context* context); diff --git a/DDG4/src/Geant4GeneratorWrapper.cpp b/DDG4/src/Geant4GeneratorWrapper.cpp index 4016a367cc54b947599ba8eaf1c797d5f9e6308a..47005db888566088ee2e1fed1ebac3b7e17916cf 100644 --- a/DDG4/src/Geant4GeneratorWrapper.cpp +++ b/DDG4/src/Geant4GeneratorWrapper.cpp @@ -19,13 +19,13 @@ #include "DD4hep/Plugins.h" #include "DD4hep/Printout.h" #include "DDG4/Geant4Context.h" -//#include "DDG4/Geant4Primary.h" +#include "DDG4/Geant4Primary.h" #include "DDG4/Geant4InputHandling.h" // Geant4 include files #include "G4Event.hh" #include "G4PrimaryVertex.hh" -//#include "G4PrimaryParticle.hh" +#include "G4PrimaryParticle.hh" #include "G4VPrimaryGenerator.hh" // C/C++ include files @@ -68,6 +68,7 @@ G4VPrimaryGenerator* Geant4GeneratorWrapper::generator() { /// Event generation action callback void Geant4GeneratorWrapper::operator()(G4Event* event) { Geant4PrimaryEvent* prim = context()->event().extension<Geant4PrimaryEvent>(); + Geant4PrimaryMap* primaryMap = context()->event().extension<Geant4PrimaryMap>(); set<G4PrimaryVertex*> primaries; /// Collect all existing interactions (primary vertices) @@ -78,9 +79,9 @@ void Geant4GeneratorWrapper::operator()(G4Event* event) { generator()->GeneratePrimaryVertex(event); /// Add all the missing interactions (primary vertices) to the primary event record. - for(G4PrimaryVertex* v=event->GetPrimaryVertex(); v; v=v->GetNext()) { - if ( primaries.find(v) == primaries.end() ) { - Geant4PrimaryInteraction* inter = createPrimary(m_mask, v); + for(G4PrimaryVertex* gv=event->GetPrimaryVertex(); gv; gv=gv->GetNext()) { + if ( primaries.find(gv) == primaries.end() ) { + Geant4PrimaryInteraction* inter = createPrimary(m_mask, primaryMap, gv); prim->add(m_mask, inter); } } diff --git a/DDG4/src/Geant4InputHandling.cpp b/DDG4/src/Geant4InputHandling.cpp index 9c4a358b92d99427f449d3cdbe8eb11f538b68d5..4460c61491da4a289b66731451aabf8c9169176a 100644 --- a/DDG4/src/Geant4InputHandling.cpp +++ b/DDG4/src/Geant4InputHandling.cpp @@ -82,32 +82,45 @@ DD4hep::Simulation::createPrimary(int particle_id, return p; } -/// Helper to recursively collect interaction data -void collectPrimaries(Geant4PrimaryInteraction* interaction, - Geant4Vertex* particle_origine, - const G4PrimaryParticle* gp) +/// Helper to recursively build a DDG4 interaction from an existing G4 interaction (primary vertex) +static void collectPrimaries(Geant4PrimaryMap* pm, + Geant4PrimaryInteraction* interaction, + Geant4Vertex* particle_origine, + const G4PrimaryParticle* gp) { int pid = int(interaction->particles.size()); Geant4Particle* p = createPrimary(pid,particle_origine,gp); G4PrimaryParticle* dau = gp->GetDaughter(); + PropertyMask status(p->status); int mask = interaction->mask; interaction->particles.insert(make_pair(p->id,p)); + status.set(G4PARTICLE_PRIMARY); p->mask = mask; particle_origine->out.insert(p->id); + // Insert pair in map. Do not forget to increase reference count! + pm->primaryMap.insert(make_pair(gp,p->addRef())); + if ( dau ) { Geant4Vertex* dv = new Geant4Vertex(*particle_origine); int vid = int(interaction->vertices.size()); + PropertyMask reason(p->reason); + reason.set(G4PARTICLE_HAS_SECONDARIES); + dv->mask = mask; dv->in.insert(p->id); interaction->vertices.insert(make_pair(vid,dv)); for(; dau; dau = dau->GetNext()) - collectPrimaries(interaction, dv, dau); + collectPrimaries(pm, interaction, dv, dau); } } /// Import a Geant4 interaction defined by a primary vertex into a DDG4 interaction record -Geant4PrimaryInteraction* DD4hep::Simulation::createPrimary(int mask, const G4PrimaryVertex* gv) { +Geant4PrimaryInteraction* +DD4hep::Simulation::createPrimary(int mask, + Geant4PrimaryMap* pm, + const G4PrimaryVertex* gv) +{ Geant4PrimaryInteraction* interaction = new Geant4PrimaryInteraction(); Geant4Vertex* v = createPrimary(gv); int vid = int(interaction->vertices.size()); @@ -116,7 +129,7 @@ Geant4PrimaryInteraction* DD4hep::Simulation::createPrimary(int mask, const G4Pr v->mask = mask; interaction->vertices.insert(make_pair(vid,v)); for (G4PrimaryParticle *gp = gv->GetPrimary(); gp; gp = gp->GetNext() ) - collectPrimaries(interaction, v, gp); + collectPrimaries(pm, interaction, v, gp); return interaction; } diff --git a/examples/CLICSiD/scripts/CLIC_G4Gun.py b/examples/CLICSiD/scripts/CLIC_G4Gun.py new file mode 100644 index 0000000000000000000000000000000000000000..92d13de77160d7b7864db58a4993fd164bfa8da8 --- /dev/null +++ b/examples/CLICSiD/scripts/CLIC_G4Gun.py @@ -0,0 +1,62 @@ +""" + + Subtest using CLICSid showing the usage of the G4Particle gun using + the Geant4GeneratorWrapper object. + + @author M.Frank + @version 1.0 + +""" +def run(): + import CLICSid, DDG4 + from DDG4 import OutputLevel as Output + + sid = CLICSid.CLICSid() + geant4 = sid.geant4 + kernel = sid.kernel + sid.loadGeometry() + geant4.printDetectors() + kernel.UI = "UI" + geant4.setupCshUI() + sid.setupField(quiet=False) + DDG4.importConstants(kernel.lcdd(),debug=False) + + prt = DDG4.EventAction(kernel,'Geant4ParticlePrint/ParticlePrint') + prt.OutputLevel = Output.INFO + prt.OutputType = 3 # Print both: table and tree + kernel.eventAction().adopt(prt) + + gen = DDG4.GeneratorAction(kernel,"Geant4GeneratorActionInit/GenerationInit") + kernel.generatorAction().adopt(gen) + print "# First particle generator: gun" + gun = DDG4.GeneratorAction(kernel,"Geant4GeneratorWrapper/Gun"); + gun.Uses = 'G4ParticleGun' + gun.Mask = 1 + kernel.generatorAction().adopt(gun) + + # Merge all existing interaction records + merger = DDG4.GeneratorAction(kernel,"Geant4InteractionMerger/InteractionMerger") + merger.enableUI() + kernel.generatorAction().adopt(merger) + + + # And handle the simulation particles. + part = DDG4.GeneratorAction(kernel,"Geant4ParticleHandler/ParticleHandler") + kernel.generatorAction().adopt(part) + part.OutputLevel = Output.INFO + part.enableUI() + user = DDG4.Action(kernel,"Geant4TCUserParticleHandler/UserParticleHandler") + user.TrackingVolume_Zmax = DDG4.EcalEndcap_zmin + user.TrackingVolume_Rmax = DDG4.EcalBarrel_rmin + user.enableUI() + part.adopt(user) + + sid.setupDetectors() + sid.setupPhysics('QGSP_BERT') + sid.test_config() + gun.generator() # Instantiate gun to be able to set properties from G4 prompt + kernel.run() + kernel.terminate() + +if __name__ == "__main__": + run() diff --git a/examples/CLICSiD/scripts/G4Gun.mac b/examples/CLICSiD/scripts/G4Gun.mac new file mode 100644 index 0000000000000000000000000000000000000000..6cb716bf09c8ca8f2eda89a97b076893f4aaf0f7 --- /dev/null +++ b/examples/CLICSiD/scripts/G4Gun.mac @@ -0,0 +1,4 @@ +/gun/position 0 cm,0 cm,0 cm +/gun/particle e- +/gun/energy 20 GeV +/gun/number 1