Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-06 08:18:55

0001 #include "PHG4ConeSteppingAction.h"
0002 #include "PHG4ConeDetector.h"
0003 
0004 #include <g4main/PHG4Hit.h>
0005 #include <g4main/PHG4HitContainer.h>
0006 #include <g4main/PHG4Hitv1.h>
0007 #include <g4main/PHG4Shower.h>
0008 #include <g4main/PHG4SteppingAction.h>  // for PHG4SteppingAction
0009 #include <g4main/PHG4TrackUserInfoV1.h>
0010 
0011 #include <phool/getClass.h>
0012 
0013 #include <Geant4/G4ParticleDefinition.hh>  // for G4ParticleDefinition
0014 #include <Geant4/G4Step.hh>
0015 #include <Geant4/G4StepPoint.hh>              // for G4StepPoint
0016 #include <Geant4/G4StepStatus.hh>             // for fGeomBoundary, fUndefined
0017 #include <Geant4/G4String.hh>                 // for G4String
0018 #include <Geant4/G4SystemOfUnits.hh>          // for cm, nanosecond, GeV
0019 #include <Geant4/G4ThreeVector.hh>            // for G4ThreeVector
0020 #include <Geant4/G4TouchableHandle.hh>        // for G4TouchableHandle
0021 #include <Geant4/G4Track.hh>                  // for G4Track
0022 #include <Geant4/G4TrackStatus.hh>            // for fStopAndKill
0023 #include <Geant4/G4Types.hh>                  // for G4double
0024 #include <Geant4/G4VTouchable.hh>             // for G4VTouchable
0025 #include <Geant4/G4VUserTrackInformation.hh>  // for G4VUserTrackInformation
0026 
0027 #include <iostream>
0028 #include <string>  // for string, operator+, oper...
0029 
0030 class G4VPhysicalVolume;
0031 class PHCompositeNode;
0032 
0033 using namespace std;
0034 //____________________________________________________________________________..
0035 PHG4ConeSteppingAction::PHG4ConeSteppingAction(PHG4ConeDetector* detector)
0036   : PHG4SteppingAction(detector->GetName())
0037   , detector_(detector)
0038   , hits_(nullptr)
0039   , hit(nullptr)
0040   , saveshower(nullptr)
0041 {
0042 }
0043 
0044 PHG4ConeSteppingAction::~PHG4ConeSteppingAction()
0045 {
0046   // if the last hit was a zero energie deposit hit, it is just reset
0047   // and the memory is still allocated, so we need to delete it here
0048   // if the last hit was saved, hit is a nullptr pointer which are
0049   // legal to delete (it results in a no operation)
0050   delete hit;
0051 }
0052 
0053 //____________________________________________________________________________..
0054 bool PHG4ConeSteppingAction::UserSteppingAction(const G4Step* aStep, bool /*was_used*/)
0055 {
0056   // get volume of the current step
0057   G4VPhysicalVolume* volume = aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
0058 
0059   // collect energy and track length step by step
0060   G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0061 
0062   const G4Track* aTrack = aStep->GetTrack();
0063 
0064   int layer_id = detector_->get_Layer();
0065   // make sure we are in a volume
0066   if (detector_->IsInConeActive(volume))
0067   {
0068     bool geantino = false;
0069     // the check for the pdg code speeds things up, I do not want to make
0070     // an expensive string compare for every track when we know
0071     // geantino or chargedgeantino has pid=0
0072     if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 &&
0073         aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != string::npos)
0074     {
0075       geantino = true;
0076     }
0077     G4StepPoint* prePoint = aStep->GetPreStepPoint();
0078     G4StepPoint* postPoint = aStep->GetPostStepPoint();
0079     //       cout << "track id " << aTrack->GetTrackID() << endl;
0080     //       cout << "time prepoint: " << prePoint->GetGlobalTime() << endl;
0081     //       cout << "time postpoint: " << postPoint->GetGlobalTime() << endl;
0082     switch (prePoint->GetStepStatus())
0083     {
0084     case fGeomBoundary:
0085     case fUndefined:
0086       if (!hit)
0087       {
0088         hit = new PHG4Hitv1();
0089       }
0090       // here we set the entrance values in cm
0091       hit->set_x(0, prePoint->GetPosition().x() / cm);
0092       hit->set_y(0, prePoint->GetPosition().y() / cm);
0093       hit->set_z(0, prePoint->GetPosition().z() / cm);
0094       // time in ns
0095       hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0096       // set the track ID
0097       hit->set_trkid(aTrack->GetTrackID());
0098       // set the initial energy deposit
0099       hit->set_edep(0);
0100 
0101       if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0102       {
0103         if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0104         {
0105           hit->set_trkid(pp->GetUserTrackId());
0106           hit->set_shower_id(pp->GetShower()->get_id());
0107           saveshower = pp->GetShower();
0108         }
0109       }
0110 
0111       break;
0112     default:
0113       break;
0114     }
0115     // here we just update the exit values, it will be overwritten
0116     // for every step until we leave the volume or the particle
0117     // ceases to exist
0118     hit->set_x(1, postPoint->GetPosition().x() / cm);
0119     hit->set_y(1, postPoint->GetPosition().y() / cm);
0120     hit->set_z(1, postPoint->GetPosition().z() / cm);
0121 
0122     hit->set_t(1, postPoint->GetGlobalTime() / nanosecond);
0123     // sum up the energy to get total deposited
0124     hit->set_edep(hit->get_edep() + edep);
0125     if (geantino)
0126     {
0127       hit->set_edep(-1);  // only energy=0 g4hits get dropped, this way geantinos survive the g4hit compression
0128     }
0129     if (edep > 0)
0130     {
0131       if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0132       {
0133         if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0134         {
0135           pp->SetKeep(1);  // we want to keep the track
0136         }
0137       }
0138     }
0139 
0140     // if any of these conditions is true this is the last step in
0141     // this volume and we need to save the hit
0142     // postPoint->GetStepStatus() == fGeomBoundary: track leaves this volume
0143     // postPoint->GetStepStatus() == fWorldBoundary: track leaves this world
0144     // (not sure if this will ever be the case)
0145     // aTrack->GetTrackStatus() == fStopAndKill: track ends
0146     if (postPoint->GetStepStatus() == fGeomBoundary || postPoint->GetStepStatus() == fWorldBoundary || aTrack->GetTrackStatus() == fStopAndKill)
0147     {
0148       // save only hits with energy deposit (or -1 for geantino)
0149       if (hit->get_edep())
0150       {
0151         hits_->AddHit(layer_id, hit);
0152         if (saveshower)
0153         {
0154           saveshower->add_g4hit_id(hits_->GetID(), hit->get_hit_id());
0155         }
0156         // ownership has been transferred to container, set to null
0157         // so we will create a new hit for the next track
0158         hit = nullptr;
0159       }
0160       else
0161       {
0162         // if this hit has no energy deposit, just reset it for reuse
0163         // this means we have to delete it in the dtor. If this was
0164         // the last hit we processed the memory is still allocated
0165         hit->Reset();
0166       }
0167     }
0168     // return true to indicate the hit was used
0169     return true;
0170   }
0171   else
0172   {
0173     return false;
0174   }
0175 }
0176 
0177 //____________________________________________________________________________..
0178 void PHG4ConeSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0179 {
0180   string hitnodename;
0181   if (detector_->SuperDetector() != "NONE")
0182   {
0183     hitnodename = "G4HIT_" + detector_->SuperDetector();
0184   }
0185   else
0186   {
0187     hitnodename = "G4HIT_" + detector_->GetName();
0188   }
0189 
0190   // now look for the map and grab a pointer to it.
0191   hits_ = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
0192 
0193   // if we do not find the node we need to scream.
0194   if (!hits_)
0195   {
0196     std::cout << "PHG4ConeSteppingAction::SetTopNode - unable to find " << hitnodename << std::endl;
0197   }
0198 }