diff --git a/examples/AlignDet/CMakeLists.txt b/examples/AlignDet/CMakeLists.txt index 9c0b330daf18f38f7c243a5bf7718feab203fe24..c921e924ab2fd55ae6c185177dde08310b1d18e4 100644 --- a/examples/AlignDet/CMakeLists.txt +++ b/examples/AlignDet/CMakeLists.txt @@ -19,9 +19,9 @@ dd4hep_package ( AlignDet MAJOR 0 MINOR 0 PATCH 1 OPTIONAL XERCESC INCLUDE_DIRS include ) - -dd4hep_add_plugin( AlignDetExample SOURCES src/*.cpp ) -dd4hep_install_dir( compact DESTINATION examples/AlignDet ) +set(AlignDet_INSTALL ${CMAKE_INSTALL_PREFIX}/examples/AlignDet) +dd4hep_add_plugin( AlignDetExample SOURCES src/*.cpp ) +dd4hep_install_dir( compact DESTINATION ${AlignDet_INSTALL} ) dd4hep_configure_scripts( AlignDet DEFAULT_SETUP WITH_TESTS) # @@ -29,7 +29,7 @@ dd4hep_configure_scripts( AlignDet DEFAULT_SETUP WITH_TESTS) dd4hep_add_test_reg( AlignDet_Telescope_dump_geometry COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy - -compact file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -compact file:${AlignDet_INSTALL}/compact/Telescope.xml -plugin DD4hep_DetectorDump REGEX_PASS "/world/Telescope/module_9 NumDau\\:1 VolID\\:00000903 Place" REGEX_FAIL " ERROR ;EXCEPTION;Exception" @@ -39,7 +39,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_dump_geometry dd4hep_add_test_reg( AlignDet_Telescope_populate COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_populate - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml -iovs 10 + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -iovs 10 REGEX_PASS "Summary INFO Processed a total 190 conditions \\(S:190,L:0,C:0,M:0\\) and \\(C:190,M:0\\) alignments. Created:200" REGEX_FAIL " ERROR ;EXCEPTION;Exception" ) @@ -48,7 +48,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_populate dd4hep_add_test_reg( AlignDet_Telescope_read_xml COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -deltas file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/repository.xml REGEX_PASS "20 conditions in slice. \\(T:20,S:20,L:0,C:0,M:0\\) Alignments accessed: 20 \\(A:19,M:0\\) for IOV:run\\(1\\)" REGEX_FAIL " ERROR ;EXCEPTION;Exception" @@ -58,7 +58,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_read_xml dd4hep_add_test_reg( AlignDet_Telescope_dump_xml COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -delta file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/repository.xml -plugin DD4hep_ConditionsXMLRepositoryWriter -iov_type run -iov_value 1500 REGEX_PASS "Summary: Converted 33 conditions. 0 conditions without recipe" @@ -69,7 +69,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_dump_xml dd4hep_add_test_reg( AlignDet_Telescope_write_xml COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -delta file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/repository.xml -plugin DD4hep_ConditionsXMLRepositoryWriter -iov_type run -iov_value 1500 -manager -output new_cond.xml REGEX_PASS "Successfully wrote 33 conditions \\(0 unconverted\\) to file: new_cond.xml" @@ -80,7 +80,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_write_xml dd4hep_add_test_reg( AlignDet_Telescope_stress COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_stress - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml -iovs 20 -runs 111 + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -iovs 20 -runs 111 REGEX_PASS "Summary: Total 4598 conditions used \\(S:4598,L:0,C:0,M:0\\) \\(A:380,M:0\\)" REGEX_FAIL " ERROR ;EXCEPTION;Exception" ) @@ -89,7 +89,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_stress dd4hep_add_test_reg( AlignDet_Telescope_align_new COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_align_telescope - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -setup file:${CMAKE_INSTALL_PREFIX}/examples/Conditions/data/manager.xml REGEX_PASS "World transformation of: /world/Telescope/module_3/sensor Tr:\\( 3.9e\\+02, 0, 4.9 \\[cm\\]\\)" REGEX_FAIL " ERROR ;EXCEPTION;Exception" @@ -99,7 +99,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_align_new dd4hep_add_test_reg( AlignDet_Telescope_align_nominal COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_nominal - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -input file:${AlignDet_INSTALL}/compact/Telescope.xml REGEX_PASS "Printed 20, scanned 20 and computed a total of 20 alignments \\(C:20,M:0\\)" REGEX_FAIL " ERROR ;EXCEPTION;Exception" ) @@ -108,7 +108,7 @@ dd4hep_add_test_reg( AlignDet_Telescope_align_nominal dd4hep_add_test_reg( AlignDet_Telescope_readback_xml COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun -volmgr -destroy -plugin DD4hep_AlignmentExample_read_xml - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/Telescope.xml + -input file:${AlignDet_INSTALL}/compact/Telescope.xml -deltas file:./new_cond.xml REGEX_PASS "33 conditions in slice. \\(T:33,S:33,L:0,C:0,M:0\\) Alignments accessed: 20 \\(A:19,M:0\\) for IOV:run\\(1\\)" REGEX_FAIL " ERROR ;EXCEPTION;Exception" @@ -136,7 +136,7 @@ dd4hep_add_test_reg( AlignDet_CLICSiD_align_nominal_LONGTEST dd4hep_add_test_reg( AlignDet_AlephTPC_load COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC.xml + -input file:${AlignDet_INSTALL}/compact/AlephTPC.xml -destroy -no-interpreter -plugin DD4hep_GlobalAlignmentInstall REGEX_PASS "189 nodes/ 24 volume UID's in Detector Geometry" REGEX_FAIL " ERROR ;EXCEPTION;Exception" @@ -146,10 +146,10 @@ dd4hep_add_test_reg( AlignDet_AlephTPC_load dd4hep_add_test_reg( AlignDet_AlephTPC_global_align COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC.xml + -input file:${AlignDet_INSTALL}/compact/AlephTPC.xml -destroy -no-interpreter -plugin DD4hep_GlobalAlignmentInstall - -plugin DD4hep_XMLLoader file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC_alignment.xml BUILD_DEFAULT + -plugin DD4hep_XMLLoader file:${AlignDet_INSTALL}/compact/AlephTPC_alignment.xml BUILD_DEFAULT REGEX_PASS "Successfully parsed XML: AlephTPC_alignment.xml" REGEX_FAIL " ERROR ;EXCEPTION;Exception" ) @@ -158,11 +158,11 @@ dd4hep_add_test_reg( AlignDet_AlephTPC_global_align dd4hep_add_test_reg( AlignDet_AlephTPC_global_reset COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_AlignDet.sh" EXEC_ARGS geoPluginRun - -input file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC.xml + -input file:${AlignDet_INSTALL}/compact/AlephTPC.xml -destroy -no-interpreter -plugin DD4hep_GlobalAlignmentInstall - -plugin DD4hep_XMLLoader file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC_alignment.xml - -plugin DD4hep_XMLLoader file:${CMAKE_INSTALL_PREFIX}/examples/AlignDet/compact/AlephTPC_reset.xml + -plugin DD4hep_XMLLoader file:${AlignDet_INSTALL}/compact/AlephTPC_alignment.xml + -plugin DD4hep_XMLLoader file:${AlignDet_INSTALL}/compact/AlephTPC_reset.xml REGEX_PASS "Successfully parsed XML: AlephTPC_reset.xml" REGEX_FAIL " ERROR ;EXCEPTION;Exception" ) diff --git a/examples/CMakeLists.txt b/examples/CMakeLists.txt index c06eea95d490b2f3919606a2367f8c075db3cf07..5a3025c4f78324bcb4dae769c2e8e2204d02d1e1 100644 --- a/examples/CMakeLists.txt +++ b/examples/CMakeLists.txt @@ -53,6 +53,7 @@ dd4hep_enable_tests ( DDG4 Persistency SimpleDetector + DDG4_MySensDet ) # # XercesC dependent stuff diff --git a/examples/ClientTests/scripts/FCC_Hcal.py b/examples/ClientTests/scripts/FCC_Hcal.py index 87460f6997394ca387275f8f33bad56f7443ab3f..6ce04c323dc22bd186983ea9ad0e657b002076f8 100644 --- a/examples/ClientTests/scripts/FCC_Hcal.py +++ b/examples/ClientTests/scripts/FCC_Hcal.py @@ -26,7 +26,7 @@ def run(): geant4.setupCshUI() # Configure field - field = geant4.setupfield(prt=True) + field = geant4.setupTrackingField(prt=True) # Configure I/O evt_root = geant4.setupROOTOutput('RootOutput','FCC_'+time.strftime('%Y-%m-%d_%H-%M'),mc_truth=False) # Setup particle gun diff --git a/examples/DDG4/CMakeLists.txt b/examples/DDG4/CMakeLists.txt index 7ca766b2440d19903834ec31c6abf16b6e4eea84..ed1ceb7156a38ad5ba6033d39fc0000625f674c3 100644 --- a/examples/DDG4/CMakeLists.txt +++ b/examples/DDG4/CMakeLists.txt @@ -20,6 +20,8 @@ dd4hep_package ( DDG4 MAJOR 0 MINOR 0 PATCH 1 #---Geant4 Testsing----------------------------------------------------------------- # if (DD4HEP_USE_GEANT4) + # + dd4hep_set_compiler_flags() # #---- Dictionary of classes to be written to the ROOT file -------------------- dd4hep_add_dictionary(G__DDG4UserDict diff --git a/examples/DDG4_MySensDet/CMakeLists.txt b/examples/DDG4_MySensDet/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..020c2bd4489b67acbdb4b91e7ebbaf66bbe0d9d0 --- /dev/null +++ b/examples/DDG4_MySensDet/CMakeLists.txt @@ -0,0 +1,54 @@ +#========================================================================== +# 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. +# +#========================================================================== +cmake_minimum_required(VERSION 3.3 FATAL_ERROR) +include ( ${DD4hep_DIR}/cmake/DD4hep.cmake ) + +#----------------------------------------------------------------------------------- +dd4hep_configure_output () +dd4hep_package ( DDG4_MySensDet MAJOR 0 MINOR 0 PATCH 1 + USES [GEANT4 REQUIRED] + [ROOT REQUIRED COMPONENTS Geom GenVector RIO] + [DD4hep REQUIRED COMPONENTS DDCore DDG4] +) +set(DDG4_MySensDet_INSTALL ${CMAKE_INSTALL_PREFIX}/examples/DDG4_MySensDet) +dd4hep_install_dir(scripts DESTINATION ${DDG4_MySensDet_INSTALL} ) +dd4hep_configure_scripts(DDG4_MySensDet DEFAULT_SETUP WITH_TESTS) +# +#---Geant4 Testsing----------------------------------------------------------------- +# +if (DD4HEP_USE_GEANT4) + # + dd4hep_set_compiler_flags() + #---- Example of a client library with user defined plugins -------------------- + dd4hep_add_plugin( DDG4_MySensDet + SOURCES src/*.cpp + USES [GEANT4 REQUIRED] + [ROOT REQUIRED COMPONENTS Geom GenVector RIO] + [DD4hep REQUIRED COMPONENTS DDCore DDG4] + ) + + # Geant4 material scan. From position=0,0,0 to end-of-world + dd4hep_add_test_reg( DDG4_MySensDet_g4material_scan_SiliconBlock_LONGTEST + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDG4_MySensDet.sh" + EXEC_ARGS python ${DD4hep_DIR}/python/g4MaterialScan.py + --compact=file:${CMAKE_INSTALL_PREFIX}/examples/ClientTests/compact/SiliconBlock.xml + "--position=0,0,0" "--direction=0,1,0" + REGEX_PASS " Terminate Geant4 and delete associated actions." + ) + + dd4hep_add_test_reg( DDG4_MySensDet_sim_SiliconBlock_LONGTEST + COMMAND "${CMAKE_INSTALL_PREFIX}/bin/run_test_DDG4_MySensDet.sh" + EXEC_ARGS python ${DDG4_MySensDet_INSTALL}/scripts/MyTrackerSD_sim.py + --compact=file:${CMAKE_INSTALL_PREFIX}/examples/ClientTests/compact/SiliconBlock.xml + REGEX_PASS NONE + REGEX_FAIL "Exception;EXCEPTION;ERROR;Error" ) + +endif() diff --git a/examples/DDG4_MySensDet/README.txt b/examples/DDG4_MySensDet/README.txt new file mode 100644 index 0000000000000000000000000000000000000000..9f2bb062cfba6c199a46f57ee3e48171a2156712 --- /dev/null +++ b/examples/DDG4_MySensDet/README.txt @@ -0,0 +1,8 @@ +This is an example how to implement a specialized sensitive detector in DDG4. +The sensitive detector is called MyTrackerSD. +As a hit class it uses the Geant4TrackerHit class. + +1) The example should illustrate how to setup the factory for a specialized sensitive detector action +2) In the scripts area there is a simple example to illustrate how to setup a small + simulation and use this factory. (scripts/MyTrackerSD_sim.py) + diff --git a/examples/DDG4_MySensDet/scripts/MyTrackerSD.py b/examples/DDG4_MySensDet/scripts/MyTrackerSD.py new file mode 100644 index 0000000000000000000000000000000000000000..a8db6afda49033a637c0690fb717b66f51a736e6 --- /dev/null +++ b/examples/DDG4_MySensDet/scripts/MyTrackerSD.py @@ -0,0 +1,87 @@ +# +# +import os, sys, time, DDG4 +from DDG4 import OutputLevel as Output +from SystemOfUnits import * +# +# +""" + + dd4hep simulation example setup using the python configuration + + @author M.Frank + @version 1.0 + +""" +def run(): + kernel = DDG4.Kernel() + install_dir = os.environ['DD4hepExamplesINSTALL'] + kernel.loadGeometry("file:"+install_dir+"/examples/ClientTests/compact/SiliconBlock.xml") + + DDG4.importConstants(kernel.detectorDescription(),debug=False) + + # ======================================================================================= + # ===> This is actually the ONLY difference to ClientTests/scripts/SiliconBlock.py + # ======================================================================================= + geant4 = DDG4.Geant4(kernel,tracker='MyTrackerSDAction') + + geant4.printDetectors() + # Configure UI + if len(sys.argv)>1: + geant4.setupCshUI(macro=sys.argv[1]) + else: + geant4.setupCshUI() + + # Configure field + field = geant4.setupTrackingField(prt=True) + # Configure Event actions + prt = DDG4.EventAction(kernel,'Geant4ParticlePrint/ParticlePrint') + prt.OutputLevel = Output.DEBUG + prt.OutputType = 3 # Print both: table and tree + kernel.eventAction().adopt(prt) + + generator_output_level = Output.INFO + + # Configure G4 geometry setup + seq,act = geant4.addDetectorConstruction("Geant4DetectorGeometryConstruction/ConstructGeo") + act.DebugMaterials = True + act.DebugElements = False + act.DebugVolumes = True + act.DebugShapes = True + + # Configure I/O + evt_root = geant4.setupROOTOutput('RootOutput','SiliconBlock_'+time.strftime('%Y-%m-%d_%H-%M')) + + # Setup particle gun + gun = geant4.setupGun("Gun",particle='mu-',energy=20*GeV,multiplicity=1) + gun.OutputLevel = generator_output_level + + # And handle the simulation particles. + part = DDG4.GeneratorAction(kernel,"Geant4ParticleHandler/ParticleHandler") + kernel.generatorAction().adopt(part) + part.SaveProcesses = ['Decay'] + part.MinimalKineticEnergy = 100*MeV + part.OutputLevel = Output.INFO #generator_output_level + part.enableUI() + user = DDG4.Action(kernel,"Geant4TCUserParticleHandler/UserParticleHandler") + user.TrackingVolume_Zmax = 3.0*m + user.TrackingVolume_Rmax = 3.0*m + user.enableUI() + part.adopt(user) + + geant4.setupTracker('SiliconBlockUpper') + geant4.setupTracker('SiliconBlockDown') + + # Now build the physics list: + phys = geant4.setupPhysics('QGSP_BERT') + ph = DDG4.PhysicsList(kernel,'Geant4PhysicsList/Myphysics') + ph.addParticleConstructor('G4Geantino') + ph.addParticleConstructor('G4BosonConstructor') + ph.enableUI() + phys.adopt(ph) + phys.dump() + + geant4.execute() + +if __name__ == "__main__": + run() diff --git a/examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py b/examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py new file mode 100644 index 0000000000000000000000000000000000000000..22da4a4aeb9fbea576d2480a7c61cc45791cf579 --- /dev/null +++ b/examples/DDG4_MySensDet/scripts/MyTrackerSD_sim.py @@ -0,0 +1,56 @@ +# +# +import os, sys, time, DDG4, dd4hep +from DDG4 import OutputLevel as Output +from SystemOfUnits import * +# +# +""" + + dd4hep simulation example setup using the python configuration + + @author M.Frank + @version 1.0 + +""" +def run(): + kernel = DDG4.Kernel() + install_dir = os.environ['DD4hepExamplesINSTALL'] + kernel.loadGeometry("file:"+install_dir+"/examples/ClientTests/compact/SiliconBlock.xml") + DDG4.importConstants(kernel.detectorDescription(),debug=False) + # ======================================================================================= + # ===> This is actually the ONLY difference to ClientTests/scripts/SiliconBlock.py + # ======================================================================================= + geant4 = DDG4.Geant4(kernel,tracker='MyTrackerSDAction') + + geant4.printDetectors() + kernel.NumEvents = 5 + kernel.UI = '' + + # Configure field + field = geant4.setupTrackingField(prt=True) + # Configure Event actions + prt = DDG4.EventAction(kernel,'Geant4ParticlePrint/ParticlePrint') + prt.OutputLevel = Output.WARNING + prt.OutputType = 3 # Print both: table and tree + kernel.eventAction().adopt(prt) + + # Configure I/O + evt_root = geant4.setupROOTOutput('RootOutput','MySD_'+time.strftime('%Y-%m-%d_%H-%M'),mc_truth=False) + # Setup particle gun + gun = geant4.setupGun("Gun",particle='mu-',energy=5*GeV,multiplicity=1,Standalone=True,position=(0,0,0)) + geant4.setupTracker('SiliconBlockUpper') + geant4.setupTracker('SiliconBlockDown') + # Now build the physics list: + phys = kernel.physicsList() + phys.extends = 'QGSP_BERT' + phys.enableUI() + phys.dump() + # run + kernel.configure() + kernel.initialize() + kernel.run() + kernel.terminate() + +if __name__ == "__main__": + run() diff --git a/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp b/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f960ea8c16141bb665bac2d3e7f53c581b22d9f0 --- /dev/null +++ b/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp @@ -0,0 +1,158 @@ +//========================================================================== +// 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/Geant4SensDetAction.inl" +#include "DDG4/Factories.h" + +using namespace CLHEP; + +namespace { + class MyTrackerSD { + public: + /// This is the hit definition. + /** I took here the same definition of the default Geant4Tracker class, + * (see DDG4/Geant4Data.h) but it could be anything else as well + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class MyHit : public dd4hep::sim::Geant4HitData { + public: + /// Hit position + dd4hep::Position position; + /// Hit direction + dd4hep::Direction momentum; + /// Length of the track segment contributing to this hit + double length = 0; + /// Monte Carlo / Geant4 information + Contribution truth; + /// Energy deposit in the tracker hit + double energyDeposit = 0; + public: + /// Default constructor + MyHit() = default; + /// Initializing constructor + MyHit(int track_id, int pdg_id, double deposit, double time_stamp) + : length(0.0), truth(track_id, pdg_id, deposit, time_stamp, 0.), energyDeposit(deposit) {} + /// Default destructor + virtual ~MyHit() = default; + /// Assignment operator + MyHit& operator=(const MyHit& c) { + if ( &c != this ) { + position = c.position; + momentum = c.momentum; + length = c.length; + truth = c.truth; + } + return *this; + } + /// Clear hit content + MyHit& clear() { + position.SetXYZ(0, 0, 0); + momentum.SetXYZ(0, 0, 0); + length = 0.0; + truth.clear(); + return *this; + } + + /// Store Geant4 point and step information into tracker hit structure. + MyHit& storePoint(const G4Step* step, const 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(); + position.SetXYZ(pos.x(), pos.y(), pos.z()); + momentum.SetXYZ(mom.x(), mom.y(), mom.z()); + length = 0; + return *this; + } + }; + + // If we need special data to personalize the action, be put it here + int mumDeposits = 0; + double integratedDeposit = 0; + }; +} + +/// Namespace for the AIDA detector description toolkit +namespace dd4hep { + + /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit + namespace sim { + + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + // Geant4SensitiveAction<MyTrackerSD> + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + /** \addtogroup Geant4SDActionPlugin + * + * @{ + * \package MyTrackerSDAction + * \brief Sensitive detector meant for tracking detectors, will produce one hit per step + * + * @} + */ + + /// Define collections created by this sensitivie action object + template <> void Geant4SensitiveAction<MyTrackerSD>::defineCollections() { + m_collectionID = declareReadoutFilteredCollection<MyTrackerSD::MyHit>(); + } + + /// Method for generating hit(s) using the information of G4Step object. + template <> bool Geant4SensitiveAction<MyTrackerSD>::process(G4Step* step,G4TouchableHistory* /*hist*/ ) { + Geant4StepHandler h(step); + Position prePos = h.prePos(); + Position postPos = h.postPos(); + Position direction = postPos - prePos; + Position position = mean_direction(prePos,postPos); + double hit_len = direction.R(); + + // Somehow extract here the physics you want + MyTrackerSD::MyHit* hit = new MyTrackerSD::MyHit(h.trkID(), h.trkPdgID(), h.deposit(), h.track->GetGlobalTime()); + HitContribution contrib = MyTrackerSD::MyHit::extractContribution(step); + hit->cellID = cellID(step); + hit->energyDeposit = contrib.deposit; + hit->position = position; + hit->momentum = 0.5*(h. preMom() + h.postMom()); + hit->length = hit_len; + collection(m_collectionID)->add(hit); + mark(h.track); + if ( 0 == hit->cellID ) { + hit->cellID = volumeID(step); + except("+++ Invalid CELL ID for hit!"); + } + printP1("Hit with deposit:%f Pos:%f %f %f ID=%016X", + step->GetTotalEnergyDeposit(),position.X(),position.Y(),position.Z(), + (void*)hit->cellID); + Geant4TouchableHandler handler(step); + print(" Geant4 path:%s",handler.path().c_str()); + + // Do something with my personal data (can be also something more clever ;-): + m_userData.integratedDeposit += contrib.deposit; + ++m_userData.mumDeposits; + return true; + } + + } +} + +//--- Factory declaration +namespace dd4hep { namespace sim { + typedef Geant4SensitiveAction<MyTrackerSD> MyTrackerSDAction; + }} +DECLARE_GEANT4SENSITIVE(MyTrackerSDAction)