BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSLinkPrimaryGeneratorAction.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2024.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSBunch.hh"
20#include "BDSLinkBunch.hh"
21#include "BDSBunchSixTrackLink.hh"
22#include "BDSDebug.hh"
23#include "BDSEventInfo.hh"
24#include "BDSException.hh"
25#include "BDSExtent.hh"
26#include "BDSIonDefinition.hh"
27#include "BDSLinkDetectorConstruction.hh"
28#include "BDSLinkEventInfo.hh"
29#include "BDSLinkPrimaryGeneratorAction.hh"
30#include "BDSLinkRegistry.hh"
31#include "BDSPrimaryVertexInformation.hh"
32#include "BDSRandom.hh"
33
34#include "G4Event.hh"
35#include "G4IonTable.hh"
36#include "G4ParticleGun.hh"
37#include "G4Types.hh"
38
40 int* currentElementIndexIn,
41 BDSLinkDetectorConstruction* constructionIn,
42 G4bool debugIn):
43 bunch(bunchIn),
44 currentElementIndex(currentElementIndexIn),
45 construction(constructionIn),
46 debug(debugIn),
47 particleGun(nullptr)
48{
49 particleGun = new G4ParticleGun(1); // 1-particle gun
50
51 particleGun->SetParticleMomentumDirection(G4ThreeVector(0.,0.,1.));
52 particleGun->SetParticlePosition(G4ThreeVector());
53 particleGun->SetParticleTime(0);
54}
55
56BDSLinkPrimaryGeneratorAction::~BDSLinkPrimaryGeneratorAction()
57{
58 delete particleGun;
59}
60
62{
63 // always save seed state in output
64 BDSLinkEventInfo* eventInfo = new BDSLinkEventInfo();
65 anEvent->SetUserInformation(eventInfo);
66 eventInfo->SetSeedStateAtStart(BDSRandom::GetSeedState());
67
69 try
70 {
71 coords = bunch->GetNextParticleLocal();
72 auto bunchSTL = dynamic_cast<BDSLinkBunch*>(bunch);
73 if (bunchSTL)
74 {
75 eventInfo->externalParticleIDofPrimary = bunchSTL->CurrentExternalParticleID();
76 eventInfo->externalParentIDofPrimary = bunchSTL->CurrentExternalParentID();
77 }
78 }
79 catch (const BDSException& exception)
80 {// we couldn't safely generate a particle -> abort
81 // could be because of user input file
82 anEvent->SetEventAborted();
83 G4cout << exception.what() << G4endl;
84 G4cout << "Aborting this event (#" << anEvent->GetEventID() << ")" << G4endl;
85 return;
86 }
87
89 auto lr = construction->LinkRegistry();
90 const G4Transform3D tr = lr->Transform(*currentElementIndex);
91 if (lr->NoRotation(*currentElementIndex))
92 {
93 if (debug)
94 {
95 G4cout << "PGA: Coords before " << coords;
96 G4cout << "Offset " << tr.getTranslation() << G4endl;
97 }
98 BDSParticleCoords cgf = coords.ApplyOffset(tr.getTranslation());
99 cg = BDSParticleCoordsFullGlobal(coords, cgf);
100 if (debug)
101 {G4cout << "Coords after " << cg.global;}
102 }
103 else
104 {
106 }
107
108 particleGun->SetParticleDefinition(bunch->ParticleDefinition()->ParticleDefinition());
109
110 // always update the charge - ok for normal particles; fixes purposively specified ions.
111 particleGun->SetParticleCharge(bunch->ParticleDefinition()->Charge());
112
113 // check that kinetic energy is positive and finite anyway and abort if not.
114 // get the mass from the beamParticle as this takes into account any electrons
115 G4double EK = cg.local.totalEnergy - bunch->ParticleDefinition()->Mass();
116 if (EK <= 0)
117 {
118 G4cout << __METHOD_NAME__ << "Event #" << anEvent->GetEventID()
119 << " - Particle kinetic energy smaller than 0! "
120 << "This will not be tracked." << G4endl;
121 anEvent->SetEventAborted();
122 return;
123 }
124
125 // check the coordinates are valid
126 if (!worldExtent.Encompasses(cg.global))
127 {
128 G4cerr << __METHOD_NAME__ << "point: " << cg.global
129 << "mm lies outside the world volume with extent ("
130 << worldExtent << " - event aborted!" << G4endl << G4endl;
131 anEvent->SetEventAborted();
132 }
133
134#ifdef BDSDEBUG
135 G4cout << __METHOD_NAME__ << coords << G4endl;
136#endif
137
138 G4ThreeVector PartMomDir(cg.global.xp,cg.global.yp,cg.global.zp);
139 G4ThreeVector PartPosition(cg.global.x,cg.global.y,cg.global.z);
140
141 particleGun->SetParticlePosition(PartPosition);
142 particleGun->SetParticleEnergy(EK);
143 particleGun->SetParticleMomentumDirection(PartMomDir);
144 particleGun->SetParticleTime(cg.global.T);
145
146 particleGun->GeneratePrimaryVertex(anEvent);
147
148 // set the weight
149 auto vertex = anEvent->GetPrimaryVertex();
150 vertex->SetWeight(cg.local.weight);
151 //vertex->Print();
152
153 // associate full set of coordinates with vertex for writing to output after event
154 //vertex->SetUserInformation(new BDSPrimaryVertexInformation(coords,
155 // bunch->ParticleDefinition()));
156
157#ifdef BDSDEBUG
158 vertex->Print();
159#endif
160}
The base class for bunch distribution generators.
Definition BDSBunch.hh:47
virtual const BDSParticleDefinition * ParticleDefinition() const
Access the beam particle definition.
Definition BDSBunch.hh:96
virtual BDSParticleCoordsFull GetNextParticleLocal()
Definition BDSBunch.cc:272
void SetSeedStateAtStart(const G4String &seedStateAtStartIn)
Setters.
General exception with possible name of object and message.
const char * what() const noexcept override
Override message in std::exception.
G4bool Encompasses(const G4ThreeVector &point) const
Return whether the extent encompasses the point. True if point lies inside the extent.
Definition BDSExtent.cc:190
A bunch distribution that holds a bunch from a Link.
Construction of the geometry in the case of a link model.
BDSLinkRegistry * LinkRegistry() const
Accessor.
Simple extension to cache extra variables through an event.
BDSBunch * bunch
BDSIM particle generator.
virtual void GeneratePrimaries(G4Event *)
Main interface for Geant4. Prepare primary(ies) for the event.
int * currentElementIndex
External integer for which element to track in.
G4ParticleGun * particleGun
Geant4 particle gun that creates single particles.
BDSExtent worldExtent
World extent that particle coordinates are checked against to ensure they're inside it.
BDSLinkPrimaryGeneratorAction(BDSBunch *bunchIn, int *currentElementIndexIn, BDSLinkDetectorConstruction *constructionIn, G4bool debugIn=false)
Bunch must have a valid particle definition (ie not nullptr).
BDSLinkDetectorConstruction * construction
Cache of detector construction for link registry of transforms.
A set of particle coordinates in both local and global.
A set of particle coordinates including energy and weight.
A set of particle coordinates.
BDSParticleCoords ApplyTransform(const G4Transform3D &transform) const
Apply a transform to the coordinates and return a copy of them transformed.
BDSParticleCoords ApplyOffset(const G4ThreeVector &offset) const
Apply an offset to the spatial coordinates only and return a copy.
G4double Mass() const
Accessor.
G4double Charge() const
Accessor.
G4ParticleDefinition * ParticleDefinition() const
Accessor.