File indexing completed on 2025-08-06 08:19:23
0001 #include "PHG4PrimaryGeneratorAction.h"
0002
0003 #include "PHG4InEvent.h"
0004 #include "PHG4Particle.h"
0005 #include "PHG4UserPrimaryParticleInformation.h"
0006 #include "PHG4VtxPoint.h"
0007
0008 #include <phool/phool.h>
0009
0010 #include <Geant4/G4Event.hh>
0011 #include <Geant4/G4IonTable.hh>
0012 #include <Geant4/G4ParticleDefinition.hh> // for G4ParticleDefinition
0013 #include <Geant4/G4ParticleTable.hh>
0014 #include <Geant4/G4PrimaryParticle.hh>
0015 #include <Geant4/G4PrimaryVertex.hh>
0016 #include <Geant4/G4String.hh> // for G4String
0017 #include <Geant4/G4SystemOfUnits.hh>
0018 #include <Geant4/G4ThreeVector.hh>
0019 #include <Geant4/G4Types.hh> // for G4double
0020
0021 #include <cmath> // for sqrt
0022 #include <cstdlib>
0023 #include <iostream>
0024 #include <map>
0025 #include <string> // for operator<<
0026 #include <utility> // for pair
0027
0028 using namespace std;
0029
0030 void PHG4PrimaryGeneratorAction::GeneratePrimaries(G4Event* anEvent)
0031 {
0032 if (!inEvent)
0033 {
0034 return;
0035 }
0036 map<int, PHG4VtxPoint*>::const_iterator vtxiter;
0037 multimap<int, PHG4Particle*>::const_iterator particle_iter;
0038 std::pair<std::map<int, PHG4VtxPoint*>::const_iterator, std::map<int, PHG4VtxPoint*>::const_iterator> vtxbegin_end = inEvent->GetVertices();
0039
0040 for (vtxiter = vtxbegin_end.first; vtxiter != vtxbegin_end.second; ++vtxiter)
0041 {
0042
0043
0044
0045 G4ThreeVector position((*vtxiter->second).get_x() * cm, (*vtxiter->second).get_y() * cm, (*vtxiter->second).get_z() * cm);
0046 G4PrimaryVertex* vertex = new G4PrimaryVertex(position, (*vtxiter->second).get_t() * nanosecond);
0047 pair<multimap<int, PHG4Particle*>::const_iterator, multimap<int, PHG4Particle*>::const_iterator> particlebegin_end = inEvent->GetParticles(vtxiter->first);
0048 for (particle_iter = particlebegin_end.first; particle_iter != particlebegin_end.second; ++particle_iter)
0049 {
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061 if (!(*particle_iter->second).get_pid())
0062 {
0063 G4String particleName = (*particle_iter->second).get_name();
0064 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0065 G4ParticleDefinition* particledef = particleTable->FindParticle(particleName);
0066 if (particledef)
0067 {
0068 (*particle_iter->second).set_pid(particledef->GetPDGEncoding());
0069 }
0070 else
0071 {
0072 cout << PHWHERE << "Cannot get PDG value for particle " << particleName
0073 << ", dropping it" << endl;
0074 continue;
0075 }
0076 }
0077 G4PrimaryParticle* g4part = nullptr;
0078 if (!(*particle_iter->second).get_pid())
0079 {
0080 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
0081 G4ParticleDefinition* particle_definition = particleTable->FindParticle((*particle_iter->second).get_name());
0082 if (particle_definition)
0083 {
0084 G4double mass = particle_definition->GetPDGMass();
0085 g4part = new G4PrimaryParticle(particle_definition);
0086 double ekin = sqrt((*particle_iter->second).get_px() * (*particle_iter->second).get_px() +
0087 (*particle_iter->second).get_py() * (*particle_iter->second).get_py() +
0088 (*particle_iter->second).get_pz() * (*particle_iter->second).get_pz());
0089
0090
0091 g4part->SetKineticEnergy(ekin * GeV);
0092 g4part->SetMass(mass);
0093 G4ThreeVector v((*particle_iter->second).get_px(), (*particle_iter->second).get_py(), (*particle_iter->second).get_pz());
0094 G4ThreeVector vunit = v.unit();
0095 g4part->SetMomentumDirection(vunit);
0096 g4part->SetCharge(particle_definition->GetPDGCharge());
0097 G4ThreeVector particle_polarization;
0098 g4part->SetPolarization(particle_polarization.x(),
0099 particle_polarization.y(),
0100 particle_polarization.z());
0101 }
0102 else
0103 {
0104 cout << PHWHERE << " cannot get G4 particle definition" << endl;
0105 cout << "you should have never gotten here, please check this in detail" << endl;
0106 cout << "exiting now" << endl;
0107 exit(1);
0108 }
0109 }
0110 else
0111 {
0112
0113 if ((*particle_iter->second).isIon())
0114 {
0115 G4ParticleDefinition* ion = G4IonTable::GetIonTable()->GetIon((*particle_iter->second).get_Z(), (*particle_iter->second).get_A(), (*particle_iter->second).get_ExcitEnergy() * GeV);
0116 g4part = new G4PrimaryParticle(ion);
0117 g4part->SetCharge((*particle_iter->second).get_IonCharge());
0118 g4part->SetMomentum((*particle_iter->second).get_px() * GeV,
0119 (*particle_iter->second).get_py() * GeV,
0120 (*particle_iter->second).get_pz() * GeV);
0121 }
0122 else if ((*particle_iter->second).get_pid() > 1000000000)
0123 {
0124 G4ParticleDefinition* ion = G4IonTable::GetIonTable()->GetIon((*particle_iter->second).get_pid());
0125 if (ion)
0126 {
0127 g4part = new G4PrimaryParticle(ion);
0128
0129
0130 g4part->SetCharge(ion->GetPDGCharge());
0131 g4part->SetMomentum((*particle_iter->second).get_px() * GeV,
0132 (*particle_iter->second).get_py() * GeV,
0133 (*particle_iter->second).get_pz() * GeV);
0134 }
0135 else
0136 {
0137 cout << __PRETTY_FUNCTION__ << ": WARNING : PDG ID of " << (*particle_iter->second).get_pid() << " is not a valid ion! Therefore, this particle is ignored in processing :";
0138 (*particle_iter->second).identify();
0139 }
0140 }
0141 else
0142 {
0143 g4part = new G4PrimaryParticle((*particle_iter->second).get_pid(),
0144 (*particle_iter->second).get_px() * GeV,
0145 (*particle_iter->second).get_py() * GeV,
0146 (*particle_iter->second).get_pz() * GeV);
0147 }
0148 }
0149
0150
0151
0152
0153
0154 if (g4part)
0155 {
0156 PHG4UserPrimaryParticleInformation* userdata = new PHG4UserPrimaryParticleInformation(inEvent->isEmbeded(particle_iter->second));
0157 userdata->set_user_barcode((*particle_iter->second).get_barcode());
0158 g4part->SetUserInformation(userdata);
0159 vertex->SetPrimary(g4part);
0160 }
0161 }
0162
0163 anEvent->AddPrimaryVertex(vertex);
0164 }
0165 return;
0166 }