diff --git a/DDG4/include/DDG4/Geant4Data.h b/DDG4/include/DDG4/Geant4Data.h index a9980b4157d244420af593342d91bee49efa43ba..24e69275eea0730111be119bd2b762f3af32ddec 100644 --- a/DDG4/include/DDG4/Geant4Data.h +++ b/DDG4/include/DDG4/Geant4Data.h @@ -270,10 +270,10 @@ namespace dd4hep { Direction momentum; /// Length of the track segment contributing to this hit double length; - /// Monte Carlo / Geant4 information - Contribution truth; /// Energy deposit in the tracker hit double energyDeposit; + /// Monte Carlo / Geant4 information + Contribution truth; public: /// Default constructor Hit(); @@ -283,6 +283,8 @@ namespace dd4hep { Hit(const Hit& c) = delete; /// Initializing constructor Hit(int track_id, int pdg_id, double deposit, double time_stamp, double len=0.0, const Position& p={0.0, 0.0, 0.0}, const Direction& d={0.0, 0.0, 0.0}); + /// Optimized constructor for sensitive detectors + Hit(const Geant4HitData::Contribution& contrib, const Direction& mom, double deposit); /// Default destructor virtual ~Hit(); /// Move assignment operator diff --git a/DDG4/plugins/Geant4SDActions.cpp b/DDG4/plugins/Geant4SDActions.cpp index 9aa13e1898e159fd094153cfb9e54c8c3da5217b..c9bc75ecd9c604ab6e56d5561758ded7fcce9831 100644 --- a/DDG4/plugins/Geant4SDActions.cpp +++ b/DDG4/plugins/Geant4SDActions.cpp @@ -82,27 +82,21 @@ namespace dd4hep { template <> bool Geant4SensitiveAction<Geant4Tracker>::process(const G4Step* step,G4TouchableHistory* /* hist */) { typedef Geant4Tracker::Hit Hit; + // Note: 1) We store in the hit the hit-direction, which is not the same as the track direction. + // 2) The energy deposit is the difference between incoming and outcoming energy. Geant4StepHandler h(step); - Position prePos = h.prePos(); - Position postPos = h.postPos(); - Position direction = postPos - prePos; - Position pos = mean_direction(prePos, postPos); - Direction mom = 0.5 * (h.preMom() + h.postMom()); - double hit_len = direction.R(); - - // if (hit_len > 0) { - // double new_len = mean_length(h.preMom(),h.postMom())/hit_len; - // direction *= new_len/hit_len; - // } - Hit* hit = new Hit(h.trkID(), h.trkPdgID(), h.deposit(), h.track->GetGlobalTime(), hit_len, pos, mom); - hit->truth = Hit::extractContribution(step); + auto contrib = Hit::extractContribution(step); + Direction hit_momentum = 0.5 * (h.preMom() + h.postMom()); + double hit_deposit = h.deposit(); + Hit* hit = new Hit(contrib, hit_momentum, hit_deposit); + hit->cellID = cellID(step); - collection(m_collectionID)->add(hit); - mark(h.track); if ( 0 == hit->cellID ) { hit->cellID = volumeID(step); except("+++ Invalid CELL ID for hit!"); } + collection(m_collectionID)->add(hit); + mark(h.track); print("Hit with deposit:%f Pos:%f %f %f ID=%016X", hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(void*)hit->cellID); Geant4TouchableHandler handler(step); @@ -117,16 +111,16 @@ namespace dd4hep { { typedef Geant4Tracker::Hit Hit; Geant4FastSimHandler h(spot); - Hit* hit = new Hit(h.trkID(), h.trkPdgID(), h.deposit(), h.track->GetGlobalTime(), - 0e0, h.avgPosition(), h.momentum()); + auto contrib = Hit::extractContribution(spot); + Hit* hit = new Hit(contrib, h.momentum(), h.deposit()); + hit->cellID = cellID(h.touchable(), h.avgPositionG4()); - hit->truth = Hit::extractContribution(spot); - collection(m_collectionID)->add(hit); - mark(h.track); if ( 0 == hit->cellID ) { hit->cellID = volumeID(h.touchable()); except("+++ Invalid CELL ID for hit!"); } + collection(m_collectionID)->add(hit); + mark(h.track); print("Hit with deposit:%f Pos:%f %f %f ID=%016X", hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(void*)hit->cellID); Geant4TouchableHandler handler(h.touchable()); @@ -160,30 +154,25 @@ namespace dd4hep { /// Method for generating hit(s) using the information of G4Step object. template <> bool Geant4SensitiveAction<Geant4OpticalTracker>::process(const G4Step* step,G4TouchableHistory* /* hist */) { - G4Track * track = step->GetTrack(); + // Note: 1) We store in the hit the hit-direction, which is not the same as the track direction. + // 2) The energy deposit is the track momentum typedef Geant4Tracker::Hit Hit; Geant4StepHandler h(step); - Position prePos = h.prePos(); - Position postPos = h.postPos(); - Position direction = postPos - prePos; - Position pos = mean_direction(prePos, postPos); - Direction mom = 0.5 * ( h.preMom() + h.postMom() ) ; - double tim = h.track->GetGlobalTime(); - double hit_len = direction.R(); - auto contrib = Hit::extractContribution(step); - - Hit* hit = new Hit(h.trkID(), h.trkPdgID(), contrib.deposit, tim, hit_len, pos, mom); - hit->truth = contrib; - hit->cellID = cellID(step); - if (track->GetDefinition() != G4OpticalPhoton::OpticalPhotonDefinition()) { - track->SetTrackStatus(fStopAndKill); + auto contrib = Hit::extractContribution(step); + Direction hit_momentum = 0.5 * (h.preMom() + h.postMom()); + double hit_deposit = contrib.deposit; + Hit* hit = new Hit(contrib, hit_momentum, hit_deposit); + + if (h.trackDef() != G4OpticalPhoton::OpticalPhotonDefinition()) { + step->GetTrack()->SetTrackStatus(fStopAndKill); } - collection(m_collectionID)->add(hit); - mark(h.track); + hit->cellID = cellID(step); if ( 0 == hit->cellID ) { hit->cellID = volumeID( step ) ; except("+++ Invalid CELL ID for hit!"); } + collection(m_collectionID)->add(hit); + mark(h.track); print("Hit with deposit:%f Pos:%f %f %f ID=%016X", hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(void*)hit->cellID); Geant4TouchableHandler handler(step); @@ -198,18 +187,16 @@ namespace dd4hep { { typedef Geant4Tracker::Hit Hit; Geant4FastSimHandler h(spot); - auto contrib = Hit::extractContribution(spot); - Hit* hit = new Hit(h.trkID(), h.trkPdgID(), contrib.deposit, h.track->GetGlobalTime(), - 0e0, h.avgPosition(), h.momentum()); - hit->cellID = cellID(h.touchable(), h.avgPositionG4()); - hit->truth = contrib; + auto contrib = Hit::extractContribution(spot); + Hit* hit = new Hit(contrib, h.momentum(), contrib.deposit); - collection(m_collectionID)->add(hit); - mark(h.track); + hit->cellID = cellID(h.touchable(), h.avgPositionG4()); if ( 0 == hit->cellID ) { hit->cellID = volumeID(h.touchable()); except("+++ Invalid CELL ID for hit!"); } + collection(m_collectionID)->add(hit); + mark(h.track); print("Hit with deposit:%f Pos:%f %f %f ID=%016X", hit->energyDeposit,hit->position.X(),hit->position.Y(),hit->position.Z(),(void*)hit->cellID); Geant4TouchableHandler handler(h.touchable()); diff --git a/DDG4/src/Geant4Data.cpp b/DDG4/src/Geant4Data.cpp index e6f6e7bf5f6af2cbaf7777ce4f641eef57a7a0ab..20961700ca0851bcaa4bf1356022c0e91388b4ce 100644 --- a/DDG4/src/Geant4Data.cpp +++ b/DDG4/src/Geant4Data.cpp @@ -106,7 +106,7 @@ Geant4HitData::Contribution Geant4HitData::extractContribution(const Geant4FastS /// Default constructor Geant4Tracker::Hit::Hit() -: Geant4HitData(), position(), momentum(), length(0.0), truth(), energyDeposit(0.0) +: Geant4HitData(), position(), momentum(), length(0.0), energyDeposit(0.0), truth() { InstanceCount::increment(this); } @@ -114,14 +114,22 @@ Geant4Tracker::Hit::Hit() /// Standard initializing constructor Geant4Tracker::Hit::Hit(int track_id, int pdg_id, double deposit, double time_stamp, double len, const Position& pos, const Direction& mom) - : Geant4HitData(), position(pos), momentum(mom), length(len), - truth(track_id, pdg_id, deposit, time_stamp, len, pos, mom), - energyDeposit(deposit) + : Geant4HitData(), position(pos), momentum(mom), length(len), energyDeposit(deposit), + truth(track_id, pdg_id, deposit, time_stamp, len, pos, mom) { g4ID = track_id; InstanceCount::increment(this); } +/// Optimized constructor for sensitive detectors +Geant4Tracker::Hit::Hit(const Geant4HitData::Contribution& contrib, const Direction& mom, double depo) + : Geant4HitData(), position(contrib.x, contrib.y, contrib.z), + momentum(mom), length(contrib.length), energyDeposit(depo), truth(contrib) +{ + g4ID = truth.trackID; + InstanceCount::increment(this); +} + /// Default destructor Geant4Tracker::Hit::~Hit() { InstanceCount::decrement(this);