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