Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-01 07:51:28

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file TrackingAction.cc
0027 /// \brief Implementation of the TrackingAction class
0028 
0029 #include "TrackingAction.hh"
0030 
0031 #include "EventAction.hh"
0032 #include "HistoManager.hh"
0033 #include "Run.hh"
0034 #include "TrackingMessenger.hh"
0035 
0036 #include "G4IonTable.hh"
0037 #include "G4ParticleTypes.hh"
0038 #include "G4RunManager.hh"
0039 #include "G4SystemOfUnits.hh"
0040 #include "G4Track.hh"
0041 #include "G4UnitsTable.hh"
0042 
0043 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0044 
0045 TrackingAction::TrackingAction(EventAction* event) : fEvent(event)
0046 
0047 {
0048   fTrackMessenger = new TrackingMessenger(this);
0049 }
0050 
0051 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0052 
0053 TrackingAction::~TrackingAction()
0054 {
0055   delete fTrackMessenger;
0056 }
0057 
0058 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0059 
0060 void TrackingAction::SetTimeWindow(G4double t1, G4double dt)
0061 {
0062   fTimeWindow1 = t1;
0063   fTimeWindow2 = fTimeWindow1 + dt;
0064 }
0065 
0066 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0067 
0068 void TrackingAction::PreUserTrackingAction(const G4Track* track)
0069 {
0070   Run* run = static_cast<Run*>(G4RunManager::GetRunManager()->GetNonConstCurrentRun());
0071 
0072   G4ParticleDefinition* particle = track->GetDefinition();
0073   G4String name = particle->GetParticleName();
0074   fCharge = particle->GetPDGCharge();
0075   fMass = particle->GetPDGMass();
0076 
0077   G4double Ekin = track->GetKineticEnergy();
0078   G4int ID = track->GetTrackID();
0079 
0080   G4bool condition = false;
0081 
0082   // check LifeTime
0083   //
0084   G4double meanLife = particle->GetPDGLifeTime();
0085 
0086   // count particles
0087   //
0088   run->ParticleCount(name, Ekin, meanLife);
0089 
0090   // energy spectrum
0091   //
0092   G4int ih = 0;
0093   if (particle == G4Electron::Electron() || particle == G4Positron::Positron())
0094     ih = 1;
0095   else if (particle == G4NeutrinoE::NeutrinoE() || particle == G4AntiNeutrinoE::AntiNeutrinoE())
0096     ih = 2;
0097   else if (particle == G4Gamma::Gamma())
0098     ih = 3;
0099   else if (particle == G4Alpha::Alpha())
0100     ih = 4;
0101   else if (fCharge > 2.)
0102     ih = 5;
0103   if (ih) G4AnalysisManager::Instance()->FillH1(ih, Ekin);
0104 
0105   // Ion
0106   //
0107   if (fCharge > 2.) {
0108     // build decay chain
0109     if (ID == 1)
0110       fEvent->AddDecayChain(name);
0111     else
0112       fEvent->AddDecayChain(" ---> " + name);
0113     //
0114     // full chain: put at rest; if not: kill secondary
0115     G4Track* tr = (G4Track*)track;
0116     if (fFullChain) {
0117       tr->SetKineticEnergy(0.);
0118       tr->SetTrackStatus(fStopButAlive);
0119     }
0120     else if (ID > 1)
0121       tr->SetTrackStatus(fStopAndKill);
0122     //
0123     fTimeBirth = track->GetGlobalTime();
0124   }
0125 
0126   // example of saving random number seed of this fEvent, under condition
0127   //
0128   ////condition = (ih == 3);
0129   if (condition) G4RunManager::GetRunManager()->rndmSaveThisEvent();
0130 }
0131 
0132 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0133 
0134 void TrackingAction::PostUserTrackingAction(const G4Track* track)
0135 {
0136   // keep only ions
0137   //
0138   if (fCharge < 3.) return;
0139 
0140   Run* run = static_cast<Run*>(G4RunManager::GetRunManager()->GetNonConstCurrentRun());
0141 
0142   G4AnalysisManager* analysis = G4AnalysisManager::Instance();
0143 
0144   // get time
0145   //
0146   G4double time = track->GetGlobalTime();
0147   G4int ID = track->GetTrackID();
0148   if (ID == 1) run->PrimaryTiming(time);  // time of life of primary ion
0149   fTimeEnd = time;
0150 
0151   // energy and momentum balance (from secondaries)
0152   //
0153   const std::vector<const G4Track*>* secondaries = track->GetStep()->GetSecondaryInCurrentStep();
0154   size_t nbtrk = (*secondaries).size();
0155   if (nbtrk) {
0156     // there are secondaries --> it is a decay
0157     //
0158     // balance
0159     G4double EkinTot = 0., EkinVis = 0.;
0160     G4ThreeVector Pbalance = -track->GetMomentum();
0161     for (size_t itr = 0; itr < nbtrk; itr++) {
0162       const G4Track* trk = (*secondaries)[itr];
0163       G4ParticleDefinition* particle = trk->GetDefinition();
0164       G4double Ekin = trk->GetKineticEnergy();
0165       EkinTot += Ekin;
0166       G4bool visible =
0167         !((particle == G4NeutrinoE::NeutrinoE()) || (particle == G4AntiNeutrinoE::AntiNeutrinoE()));
0168       if (visible) EkinVis += Ekin;
0169       // exclude gamma desexcitation from momentum balance
0170       if (particle != G4Gamma::Gamma()) Pbalance += trk->GetMomentum();
0171     }
0172     G4double Pbal = Pbalance.mag();
0173     run->Balance(EkinTot, Pbal);
0174     analysis->FillH1(6, EkinTot);
0175     analysis->FillH1(7, Pbal);
0176     fEvent->AddEvisible(EkinVis);
0177   }
0178 
0179   // no secondaries --> end of chain
0180   //
0181   if (!nbtrk) {
0182     run->EventTiming(time);  // total time of life
0183     G4double weight = track->GetWeight();
0184     analysis->FillH1(8, time, weight);
0185     ////    analysis->FillH1(8,time);
0186     fTimeEnd = DBL_MAX;
0187   }
0188 
0189   // count activity in time window
0190   //
0191   run->SetTimeWindow(fTimeWindow1, fTimeWindow2);
0192 
0193   G4String name = track->GetDefinition()->GetParticleName();
0194   G4bool life1(false), life2(false), decay(false);
0195   if ((fTimeBirth <= fTimeWindow1) && (fTimeEnd > fTimeWindow1)) life1 = true;
0196   if ((fTimeBirth <= fTimeWindow2) && (fTimeEnd > fTimeWindow2)) life2 = true;
0197   if ((fTimeEnd > fTimeWindow1) && (fTimeEnd < fTimeWindow2)) decay = true;
0198   if (life1 || life2 || decay) run->CountInTimeWindow(name, life1, life2, decay);
0199 }
0200 
0201 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......