Back to home page

sPhenix code displayed by LXR

 
 

    


File indexing completed on 2025-08-05 08:17:51

0001 #include "PHG4SectorSteppingAction.h"
0002 #include "PHG4SectorDetector.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, fAtRestD...
0017 #include <Geant4/G4String.hh>                 // for G4String
0018 #include <Geant4/G4SystemOfUnits.hh>          // for cm, GeV, nanosecond
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 //____________________________________________________________________________..
0034 PHG4SectorSteppingAction::PHG4SectorSteppingAction(PHG4SectorDetector* detector)
0035   : PHG4SteppingAction(detector->GetName())
0036   , detector_(detector)
0037 {
0038 }
0039 
0040 PHG4SectorSteppingAction::~PHG4SectorSteppingAction()
0041 {
0042   // if the last hit was a zero energie deposit hit, it is just reset
0043   // and the memory is still allocated, so we need to delete it here
0044   // if the last hit was saved, hit is a nullptr pointer which are
0045   // legal to delete (it results in a no operation)
0046   delete hit;
0047 }
0048 
0049 //____________________________________________________________________________..
0050 bool PHG4SectorSteppingAction::UserSteppingAction(const G4Step* aStep, bool /*was_used*/)
0051 {
0052   // get volume of the current step
0053   G4VPhysicalVolume* volume =
0054       aStep->GetPreStepPoint()->GetTouchableHandle()->GetVolume();
0055 
0056   // collect energy and track length step by step
0057   G4double edep = aStep->GetTotalEnergyDeposit() / GeV;
0058   G4double eion = (aStep->GetTotalEnergyDeposit() - aStep->GetNonIonizingEnergyDeposit()) / GeV;
0059 
0060   const G4Track* aTrack = aStep->GetTrack();
0061 
0062   // make sure we are in a volume
0063   if (detector_->IsInSectorActive(volume))
0064   {
0065     bool geantino = false;
0066     // the check for the pdg code speeds things up, I do not want to make
0067     // an expensive string compare for every track when we know
0068     // geantino or chargedgeantino has pid=0
0069     if (aTrack->GetParticleDefinition()->GetPDGEncoding() == 0 && aTrack->GetParticleDefinition()->GetParticleName().find("geantino") != std::string::npos)
0070     {
0071       geantino = true;
0072     }
0073     G4StepPoint* prePoint = aStep->GetPreStepPoint();
0074     G4StepPoint* postPoint = aStep->GetPostStepPoint();
0075     //       std::cout << "track id " << aTrack->GetTrackID() << std::endl;
0076     //       std::cout << "time prepoint: " << prePoint->GetGlobalTime() << std::endl;
0077     //       std::cout << "time postpoint: " << postPoint->GetGlobalTime() << std::endl;
0078     // layer_id is sector number
0079     switch (prePoint->GetStepStatus())
0080     {
0081     case fGeomBoundary:
0082     case fUndefined:
0083       if (!hit)
0084       {
0085         hit = new PHG4Hitv1();
0086       }
0087       // here we set the entrance values in cm
0088       hit->set_x(0, prePoint->GetPosition().x() / cm);
0089       hit->set_y(0, prePoint->GetPosition().y() / cm);
0090       hit->set_z(0, prePoint->GetPosition().z() / cm);
0091       // time in ns
0092       hit->set_t(0, prePoint->GetGlobalTime() / nanosecond);
0093       // set the track ID
0094       hit->set_trkid(aTrack->GetTrackID());
0095       if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0096       {
0097         if (PHG4TrackUserInfoV1* pp = dynamic_cast<PHG4TrackUserInfoV1*>(p))
0098         {
0099           hit->set_trkid(pp->GetUserTrackId());
0100           hit->set_shower_id(pp->GetShower()->get_id());
0101           saveshower = pp->GetShower();
0102         }
0103       }
0104 
0105       // set the initial energy deposit
0106       hit->set_edep(0);
0107       hit->set_eion(0);  // only implemented for v5 otherwise empty
0108       layer_id = aStep->GetPreStepPoint()->GetTouchable()->GetReplicaNumber(1);
0109       //        hit->set_light_yield(0);
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     hit->set_eion(hit->get_eion() + eion);
0126     hit->set_path_length(aTrack->GetTrackLength() / cm);
0127     if (geantino)
0128     {
0129       hit->set_edep(-1);  // only energy=0 g4hits get dropped, this way geantinos survive the g4hit compression
0130     }
0131     if (edep > 0)
0132     {
0133       if (G4VUserTrackInformation* p = aTrack->GetUserInformation())
0134       {
0135         if (PHG4TrackUserInfoV1* pp =
0136                 dynamic_cast<PHG4TrackUserInfoV1*>(p))
0137         {
0138           pp->SetKeep(1);  // we want to keep the track
0139         }
0140       }
0141     }
0142     // if any of these conditions is true this is the last step in
0143     // this volume and we need to save the hit
0144     // postPoint->GetStepStatus() == fGeomBoundary: track leaves this volume
0145     // postPoint->GetStepStatus() == fWorldBoundary: track leaves this world
0146     // (not sure if this will ever be the case)
0147     // aTrack->GetTrackStatus() == fStopAndKill: track ends
0148     if (postPoint->GetStepStatus() == fGeomBoundary ||
0149         postPoint->GetStepStatus() == fWorldBoundary ||
0150         postPoint->GetStepStatus() == fAtRestDoItProc ||
0151         aTrack->GetTrackStatus() == fStopAndKill)
0152     {
0153       // save only hits with energy deposit (or -1 for geantino)
0154       if (hit->get_edep())
0155       {
0156         hits_->AddHit(layer_id, hit);
0157         if (saveshower)
0158         {
0159           saveshower->add_g4hit_id(hits_->GetID(), hit->get_hit_id());
0160         }
0161         // ownership has been transferred to container, set to null
0162         // so we will create a new hit for the next track
0163         hit = nullptr;
0164       }
0165       else
0166       {
0167         // if this hit has no energy deposit, just reset it for reuse
0168         // this means we have to delete it in the dtor. If this was
0169         // the last hit we processed the memory is still allocated
0170         hit->Reset();
0171       }
0172     }
0173 
0174     //       hit->identify();
0175     // return true to indicate the hit was used
0176     return true;
0177   }
0178   else
0179   {
0180     return false;
0181   }
0182 }
0183 
0184 //____________________________________________________________________________..
0185 void PHG4SectorSteppingAction::SetInterfacePointers(PHCompositeNode* topNode)
0186 {
0187   std::string hitnodename;
0188   if (detector_->SuperDetector() != "NONE")
0189   {
0190     hitnodename = "G4HIT_" + detector_->SuperDetector();
0191   }
0192   else
0193   {
0194     hitnodename = "G4HIT_" + detector_->GetName();
0195   }
0196 
0197   // now look for the map and grab a pointer to it.
0198   hits_ = findNode::getClass<PHG4HitContainer>(topNode, hitnodename);
0199 
0200   // if we do not find the node we need to make it.
0201   if (!hits_)
0202   {
0203     std::cout << "PHG4SectorSteppingAction::SetTopNode - unable to find "
0204               << hitnodename << std::endl;
0205   }
0206 }