diff --git a/DDG4/include/DDG4/Geant4Data.h b/DDG4/include/DDG4/Geant4Data.h index 89cd369cfc000a70a2d6c96d87c51be7f6bbd754..12347d918b4c3a932f41b9317a268285cd05986d 100644 --- a/DDG4/include/DDG4/Geant4Data.h +++ b/DDG4/include/DDG4/Geant4Data.h @@ -118,11 +118,11 @@ namespace dd4hep { HIT_ENDED_OUTSIDE = 1<<15 }; /// cellID - long long int cellID; + long long int cellID = 0; /// User flag to classify hits - long flag; + long flag = 0; /// Original Geant 4 track identifier of the creating track (debugging) - long g4ID; + long g4ID = -1; /// User data extension if required #ifdef DD4HEP_DD4HEP_PTR_AUTO dd4hep_ptr<DataExtension> extension; diff --git a/DDG4/src/Geant4Data.cpp b/DDG4/src/Geant4Data.cpp index e481fbba5a1b860b78747ab02a366f7ee9458a77..ac8a87381a088dfa136c91f5f5001a1300247ead 100644 --- a/DDG4/src/Geant4Data.cpp +++ b/DDG4/src/Geant4Data.cpp @@ -75,6 +75,7 @@ Geant4HitData::Contribution Geant4HitData::extractContribution(const G4Step* ste Contribution contrib(h.trkID(),h.trkPdgID(),deposit,h.trkTime(),length,pos); return contrib; } + /// Extract the MC contribution for a given hit from the step information with BirksLaw effect option Geant4HitData::Contribution Geant4HitData::extractContribution(const G4Step* step, bool ApplyBirksLaw) { Geant4StepHandler h(step); diff --git a/examples/DDG4_MySensDet/CMakeLists.txt b/examples/DDG4_MySensDet/CMakeLists.txt index 020c2bd4489b67acbdb4b91e7ebbaf66bbe0d9d0..8391f42f8c5755935721b4c351773a24eb9cc617 100644 --- a/examples/DDG4_MySensDet/CMakeLists.txt +++ b/examples/DDG4_MySensDet/CMakeLists.txt @@ -27,8 +27,15 @@ dd4hep_configure_scripts(DDG4_MySensDet DEFAULT_SETUP WITH_TESTS) if (DD4HEP_USE_GEANT4) # dd4hep_set_compiler_flags() + #--------------------------- Plugin library for the simulation framework --------- + dd4hep_add_dictionary(G__DDG4_MySensDet + SOURCES ${DD4hep_DIR}/include/ROOT/Warnings.h src/MyTrackerHit.h + LINKDEF ${DD4hep_DIR}/include/ROOT/LinkDef.h + ) + #---- Example of a client library with user defined plugins -------------------- dd4hep_add_plugin( DDG4_MySensDet + GENERATED G__DDG4_MySensDet.cxx SOURCES src/*.cpp USES [GEANT4 REQUIRED] [ROOT REQUIRED COMPONENTS Geom GenVector RIO] diff --git a/examples/DDG4_MySensDet/README.txt b/examples/DDG4_MySensDet/README.txt index 9f2bb062cfba6c199a46f57ee3e48171a2156712..ef65da00471034d306879e8e27f43107a9d11001 100644 --- a/examples/DDG4_MySensDet/README.txt +++ b/examples/DDG4_MySensDet/README.txt @@ -5,4 +5,35 @@ 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) - + + +For issues concerning the MC truth and the (consistent) persistency +please visit the MyTrackerHit include file. + +After running DDG4 with the command line: +$> python $DD4hepExamplesINSTALL/examples/DDG4_MySensDet/scripts/MyTrackerSD_siy \ + --compact=file:$DD4hepExamplesINSTALL/examples/ClientTests/compact/SiliconBlock.xml + +You can then directly inspect the produced hits and the energy deposits: + +$> root.exe + ------------------------------------------------------------ + | Welcome to ROOT 6.12/06 http://root.cern.ch | + | (c) 1995-2017, The ROOT Team | + | Built for linuxx8664gcc | + | From tag v6-12-06, 9 February 2018 | + | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' | + ------------------------------------------------------------ + +root [0] gSystem->Load("libDDG4_MySensDet.so") +(int) 0 +root [1] gSystem->Load("libDDG4Plugins.so") +(int) 0 +root [2] TFile* f=TFile::Open("MySD_2018-06-26_19-03.root") +(TFile *) 0x41a4ba0 +root [3] TBrowser b +(TBrowser &) Name: Browser Title: ROOT Object Browser +root [4] +root [4] + +Then click through the browser into the file.... diff --git a/examples/DDG4_MySensDet/src/MyTrackerHit.h b/examples/DDG4_MySensDet/src/MyTrackerHit.h new file mode 100644 index 0000000000000000000000000000000000000000..85ec336ea9dc6f10e895554a7d10ae149c73e4ba --- /dev/null +++ b/examples/DDG4_MySensDet/src/MyTrackerHit.h @@ -0,0 +1,120 @@ +//========================================================================== +// 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 SOMEEXPERIMENT_MYTRACKERHIT_H +#define SOMEEXPERIMENT_MYTRACKERHIT_H + +#include "DDG4/Geant4Data.h" +#include "G4Track.hh" +#include "G4Step.hh" + +namespace SomeExperiment { + + /// 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. + * + * Please note: + * ============ + * The MC truth handling as implemented in the Geant4ParticleHandler + * will not work with this class if the object(s) are saved with + * the standard Geant4Output2ROOT event action. If the hit is + * specialized, the output writing also must be specialized if + * MC truth handling should be supported. + * Otherwise it is sufficient to provide a ROOT dictionary as long as the + * base class dd4hep::sim::Geant4HitData is kept. + * + * \author M.Frank + * \version 1.0 + * \ingroup DD4HEP_SIMULATION + */ + class MyTrackerHit /* : public dd4hep::sim::Geant4HitData */ { + + public: + /// dd4hep::sim::Geant4HitData: cellID + long long int cellID = 0; + /// dd4hep::sim::Geant4HitData: User flag to classify hits + long flag = 0; + /// dd4hep::sim::Geant4HitData: Original Geant 4 track identifier of the creating track (debugging) + long g4ID = -1; + + + /// 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 + dd4hep::sim::Geant4HitData::MonteCarloContrib truth; + /// Energy deposit in the tracker hit + double energyDeposit = 0; + + public: + /// Default constructor + MyTrackerHit() = default; + /// Initializing constructor + MyTrackerHit(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 ~MyTrackerHit() = default; + /// Assignment operator + MyTrackerHit& operator=(const MyTrackerHit& c) { + if ( &c != this ) { + position = c.position; + momentum = c.momentum; + length = c.length; + truth = c.truth; + } + return *this; + } + /// Clear hit content + MyTrackerHit& 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. + MyTrackerHit& 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; + } + }; +} + +// CINT configuration +#if defined(__CINT__) || defined(__MAKECINT__) || defined(__CLING__) || defined(__ROOTCLING__) +#pragma link off all globals; +#pragma link off all classes; +#pragma link off all functions; + +/// Define namespaces +#pragma link C++ namespace dd4hep; +#pragma link C++ namespace dd4hep::sim; +#pragma link C++ namespace SomeExperiment; +#pragma link C++ class SomeExperiment::MyTrackerHit+; +#endif + +#endif /* SOMEEXPERIMENT_MYTRACKERHIT_H */ diff --git a/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp b/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp index f960ea8c16141bb665bac2d3e7f53c581b22d9f0..13af17abcf5a0c6a78d9f3cdcbdbd575b91df114 100644 --- a/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp +++ b/examples/DDG4_MySensDet/src/MyTrackerSDAction.cpp @@ -12,78 +12,17 @@ //========================================================================== // Framework include files +#include "MyTrackerHit.h" #include "DDG4/Geant4SensDetAction.inl" #include "DDG4/Factories.h" -using namespace CLHEP; +//using namespace CLHEP; + +namespace SomeExperiment { -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; - } - }; - + typedef MyTrackerHit Hit; // If we need special data to personalize the action, be put it here int mumDeposits = 0; double integratedDeposit = 0; @@ -96,6 +35,8 @@ namespace dd4hep { /// Namespace for the Geant4 based simulation part of the AIDA detector description toolkit namespace sim { + using namespace SomeExperiment; + // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ // Geant4SensitiveAction<MyTrackerSD> // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -110,7 +51,7 @@ namespace dd4hep { /// Define collections created by this sensitivie action object template <> void Geant4SensitiveAction<MyTrackerSD>::defineCollections() { - m_collectionID = declareReadoutFilteredCollection<MyTrackerSD::MyHit>(); + m_collectionID = declareReadoutFilteredCollection<MyTrackerSD::Hit>(); } /// Method for generating hit(s) using the information of G4Step object. @@ -123,8 +64,8 @@ namespace dd4hep { 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); + MyTrackerSD::Hit* hit = new MyTrackerSD::Hit(h.trkID(), h.trkPdgID(), h.deposit(), h.track->GetGlobalTime()); + Geant4HitData::MonteCarloContrib contrib = Geant4HitData::extractContribution(step); hit->cellID = cellID(step); hit->energyDeposit = contrib.deposit; hit->position = position;