Geant4 10.7.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4GeneralParticleSource.cc
Go to the documentation of this file.
1//
2// ********************************************************************
3// * License and Disclaimer *
4// * *
5// * The Geant4 software is copyright of the Copyright Holders of *
6// * the Geant4 Collaboration. It is provided under the terms and *
7// * conditions of the Geant4 Software License, included in the file *
8// * LICENSE and available at http://cern.ch/geant4/license . These *
9// * include a list of copyright holders. *
10// * *
11// * Neither the authors of this software system, nor their employing *
12// * institutes,nor the agencies providing financial support for this *
13// * work make any representation or warranty, express or implied, *
14// * regarding this software system or assume any liability for its *
15// * use. Please see the license in the file LICENSE and URL above *
16// * for the full disclaimer and the limitation of liability. *
17// * *
18// * This code implementation is the result of the scientific and *
19// * technical work of the GEANT4 collaboration. *
20// * By using, copying, modifying or distributing the software (or *
21// * any work based on the software) you agree to acknowledge its *
22// * use in resulting scientific publications, and indicate your *
23// * acceptance of all terms of the Geant4 Software license. *
24// ********************************************************************
25//
26// G4GeneralParticleSource class implementation
27//
28// Author: Fan Lei, QinetiQ ltd - 05/02/2004
29// Customer: ESA/ESTEC
30// Version: 2.0
31// --------------------------------------------------------------------
32
33#include "G4Event.hh"
34#include "Randomize.hh"
37#include "G4UnitsTable.hh"
38
40
41#include "G4Threading.hh"
42#include "G4AutoLock.hh"
43
44namespace
45{
46 G4Mutex messangerInit = G4MUTEX_INITIALIZER;
47}
48
50{
52 // currentSource = GPSData->GetCurrentSource();
53 // currentSourceIdx = G4int(GPSData->GetSourceVectorSize() - 1);
54
55 // Messenger is special, only a worker should instantiate it.
56 // Singleton pattern
57 //
59
60 // Some initialization should be done only once
61 //
62 G4AutoLock l(&messangerInit);
63 static G4bool onlyOnce = false;
64 if ( !onlyOnce )
65 {
66 theMessenger->SetParticleGun(GPSData->GetCurrentSource());
67 IntensityNormalization();
68 onlyOnce = true;
69 }
70}
71
73{
74 theMessenger->Destroy();
75}
76
78{
79 GPSData->Lock();
80
81 GPSData->AddASource(aV);
82 theMessenger->SetParticleGun(GPSData->GetCurrentSource());
83
84 // TODO: But do we really normalize here after each source?
85 IntensityNormalization();
86
87 GPSData->Unlock();
88}
89
90void G4GeneralParticleSource::IntensityNormalization()
91{
92 GPSData->IntensityNormalise();
93 normalised=GPSData->Normalised();
94}
95
97{
98 G4cout << "The number of particle sources is: "
99 << GPSData->GetIntensityVectorSize() << G4endl;
100 G4cout << " Multiple Vertex sources: " << GPSData->GetMultipleVertex();
101 G4cout << " Flat Sampling flag: " << GPSData->GetFlatSampling() << G4endl;
102 const G4int currentIdx = GPSData->GetCurrentSourceIdx();
103 for(G4int i=0; i<GPSData->GetIntensityVectorSize(); ++i)
104 {
105 G4cout << "\tsource " << i << " with intensity: "
106 << GPSData->GetIntensity(i) << G4endl;
107 const G4SingleParticleSource* thisSrc = GPSData->GetCurrentSource(i);
108 G4cout << " \t\tNum Particles: "<<thisSrc->GetNumberOfParticles()
109 << "; Particle type: "
110 << thisSrc->GetParticleDefinition()->GetParticleName() << G4endl;
111 G4cout << " \t\tEnergy: "
112 << G4BestUnit(thisSrc->GetParticleEnergy(),"Energy") << G4endl;
113 G4cout << " \t\tDirection: "
114 << thisSrc->GetAngDist()->GetDirection() << "; Position: ";
115 G4cout << G4BestUnit(thisSrc->GetPosDist()->GetCentreCoords(),"Length")
116 << G4endl;
117 G4cout << " \t\tAngular Distribution: "
118 << thisSrc->GetAngDist()->GetDistType() << G4endl;
119 G4cout << " \t\tEnergy Distribution: "
120 << thisSrc->GetEneDist()->GetEnergyDisType() << G4endl;
121 G4cout << " \t\tPosition Distribution Type: "
122 << thisSrc->GetPosDist()->GetPosDisType();
123 G4cout << "; Position Shape: "
124 << thisSrc->GetPosDist()->GetPosDisShape() << G4endl;
125 }
126
127 // Set back previous source
128 GPSData->GetCurrentSource(currentIdx);
129}
130
132{
133 G4int id = aV;
134 if ( id < GPSData->GetIntensityVectorSize() )
135 {
136 // currentSourceIdx = aV;
137 // currentSource = GPSData->GetCurrentSource(id);
138 theMessenger->SetParticleGun(GPSData->GetCurrentSource(id));
139 }
140 else
141 {
143 msg << "Trying to set source to index " << aV << " but only "
144 << GPSData->GetIntensityVectorSize() << " sources are defined.";
145 G4Exception("G4GeneralParticleSoruce::SetCurrentSourceto", "G4GPS004",
146 FatalException, msg);
147 }
148}
149
151{
152 GPSData->Lock();
153 GPSData->SetCurrentSourceIntensity(aV);
154 GPSData->Unlock();
155 normalised = GPSData->Normalised();
156}
157
159{
160 GPSData->ClearSources();
161 normalised=GPSData->Normalised();
162}
163
165{
166 G4int id = aV;
167 if ( id <= GPSData->GetIntensityVectorSize() )
168 {
169 GPSData->DeleteASource(aV);
170 normalised=GPSData->Normalised();
171 }
172 else
173 {
174 G4cout << " source index is invalid " << G4endl;
175 G4cout << " it shall be <= "
176 << GPSData->GetIntensityVectorSize() << G4endl;
177 }
178}
179
181{
182 if (!GPSData->GetMultipleVertex())
183 {
184 G4SingleParticleSource* currentSource = GPSData->GetCurrentSource();
185 if (GPSData->GetIntensityVectorSize() > 1)
186 {
187 // Try to minimize locks
188 if (! normalised )
189 {
190 // According to local variable, normalization is needed
191 // Check with underlying shared resource, another
192 // thread could have already normalized this
193 GPSData->Lock();
194 G4bool norm = GPSData->Normalised();
195 if (!norm)
196 {
197 IntensityNormalization();
198 }
199 // This takes care of the case in which the local variable
200 // is False and the underlying resource is true.
201 normalised = GPSData->Normalised();
202 GPSData->Unlock();
203 }
204 G4double rndm = G4UniformRand();
205 std::size_t i = 0 ;
206 if (! GPSData->GetFlatSampling() )
207 {
208 while ( rndm > GPSData->GetSourceProbability(i) ) ++i;
209 currentSource = GPSData->GetCurrentSource(i);
210 }
211 else
212 {
213 i = std::size_t (GPSData->GetIntensityVectorSize()*rndm);
214 currentSource = GPSData->GetCurrentSource(i);
215 }
216 }
217 currentSource->GeneratePrimaryVertex(evt);
218 }
219 else
220 {
221 for (G4int i = 0; i < GPSData->GetIntensityVectorSize(); ++i)
222 {
223 GPSData->GetCurrentSource(i)->GeneratePrimaryVertex(evt);
224 }
225 }
226}
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:35
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
#define G4BestUnit(a, b)
#define G4MUTEX_INITIALIZER
Definition: G4Threading.hh:85
std::mutex G4Mutex
Definition: G4Threading.hh:81
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
G4SingleParticleSource * GetCurrentSource(G4int idx)
G4double GetSourceProbability(G4int idx) const
G4double GetIntensity(G4int idx) const
static G4GeneralParticleSourceData * Instance()
static G4GeneralParticleSourceMessenger * GetInstance(G4GeneralParticleSource *)
void SetParticleGun(G4SingleParticleSource *fpg)
const G4String & GetParticleName() const
const G4String & GetEnergyDisType()
const G4ThreeVector & GetCentreCoords() const
const G4String & GetPosDisType() const
const G4String & GetPosDisShape() const
G4SPSAngDistribution * GetAngDist() const
void GeneratePrimaryVertex(G4Event *evt)
G4SPSEneDistribution * GetEneDist() const
G4ParticleDefinition * GetParticleDefinition() const
G4SPSPosDistribution * GetPosDist() const