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 /////////////////////////////////////////////////////////////////////////////// >> 27 // >> 28 // MODULE: G4GeneralParticleSource.cc >> 29 // >> 30 // Version: 2.0 >> 31 // Date: 5/02/04 >> 32 // Author: Fan Lei >> 33 // Organisation: QinetiQ ltd. >> 34 // Customer: ESA/ESTEC >> 35 // >> 36 // Documentation avaialable at http://reat.space.qinetiq.com/gps >> 37 // These include: >> 38 // User Requirement Document (URD) >> 39 // Software Specification Documents (SSD) >> 40 // Software User Manual (SUM): on-line version available >> 41 // Technical Note (TN) on the physics and algorithms >> 42 // >> 43 /////////////////////////////////////////////////////////////////////////////// >> 44 // >> 45 // CHANGE HISTORY >> 46 // -------------- >> 47 // >> 48 // Version 2.0, 05/02/2004, Fan Lei, Created. >> 49 // After changes to version 1.1 as in Geant4 v6.0 >> 50 // - Mutilple particle source definition >> 51 // - Re-structured commands >> 52 // - Split the task into smaller classes >> 53 // >> 54 // - old commonds have been retained for backward compatibility, will be >> 55 // removed in the future. >> 56 // >> 57 // 25/03/2014, Andrew Green >> 58 // Various changes to use the new G4GeneralParticleSourceData class, mostly >> 59 // just transparent wrappers around the thread safe object. >> 60 // >> 61 /////////////////////////////////////////////////////////////////////////////// 27 // 62 // 28 // Author: Fan Lei, QinetiQ ltd - 05/02/2004 << 29 // Customer: ESA/ESTEC << 30 // Version: 2.0 << 31 // ------------------------------------------- << 32 << 33 #include "G4Event.hh" 63 #include "G4Event.hh" 34 #include "Randomize.hh" 64 #include "Randomize.hh" 35 #include "G4GeneralParticleSource.hh" 65 #include "G4GeneralParticleSource.hh" 36 #include "G4SingleParticleSource.hh" 66 #include "G4SingleParticleSource.hh" 37 #include "G4UnitsTable.hh" << 38 67 39 #include "G4GeneralParticleSourceData.hh" 68 #include "G4GeneralParticleSourceData.hh" 40 69 41 #include "G4Threading.hh" 70 #include "G4Threading.hh" 42 #include "G4AutoLock.hh" 71 #include "G4AutoLock.hh" 43 72 44 namespace << 73 namespace { 45 { << 74 G4Mutex messangerInit = G4MUTEX_INITIALIZER; 46 G4Mutex messangerInit = G4MUTEX_INITIALIZER; << 47 } 75 } 48 76 49 G4GeneralParticleSource::G4GeneralParticleSour << 77 G4GeneralParticleSource::G4GeneralParticleSource() : multiple_vertex(false), flat_sampling(false),normalised(false), >> 78 theMessenger(0) 50 { 79 { 51 GPSData = G4GeneralParticleSourceData::Insta << 80 GPSData = G4GeneralParticleSourceData::Instance(); 52 // currentSource = GPSData->GetCurrentSource << 81 currentSource = GPSData->GetCurrentSource(); 53 // currentSourceIdx = G4int(GPSData->GetSour << 82 currentSourceIdx = G4int(GPSData->GetSourceVectorSize() - 1); 54 << 83 55 // Messenger is special, only a worker shoul << 84 //Messenger is special, only a worker should instantiate it. Singleton pattern 56 // Singleton pattern << 85 theMessenger = G4GeneralParticleSourceMessenger::GetInstance(this); 57 // << 86 //Some initialization should be done only once 58 theMessenger = G4GeneralParticleSourceMessen << 87 G4AutoLock l(&messangerInit); >> 88 static G4bool onlyOnce = false; >> 89 if ( !onlyOnce ) { >> 90 theMessenger->SetParticleGun(currentSource); >> 91 IntensityNormalization(); >> 92 onlyOnce = true; >> 93 } 59 94 60 // Some initialization should be done only o << 61 // << 62 G4AutoLock l(&messangerInit); << 63 static G4bool onlyOnce = false; << 64 if ( !onlyOnce ) << 65 { << 66 theMessenger->SetParticleGun(GPSData->GetC << 67 IntensityNormalization(); << 68 onlyOnce = true; << 69 } << 70 } 95 } 71 96 72 G4GeneralParticleSource::~G4GeneralParticleSou 97 G4GeneralParticleSource::~G4GeneralParticleSource() 73 { 98 { 74 theMessenger->Destroy(); << 99 theMessenger->Destroy(); 75 } 100 } 76 101 77 void G4GeneralParticleSource::AddaSource(G4dou 102 void G4GeneralParticleSource::AddaSource(G4double aV) 78 { 103 { 79 GPSData->Lock(); << 104 normalised=false; 80 << 105 GPSData->Lock(); 81 GPSData->AddASource(aV); << 106 GPSData->AddASource(aV); 82 theMessenger->SetParticleGun(GPSData->GetCur << 107 currentSource = GPSData->GetCurrentSource(); 83 << 108 theMessenger->SetParticleGun(currentSource); 84 // TODO: But do we really normalize here aft << 109 currentSourceIdx = G4int(GPSData->GetSourceVectorSize() - 1); 85 IntensityNormalization(); << 110 IntensityNormalization(); 86 << 111 GPSData->Unlock(); 87 GPSData->Unlock(); << 88 } 112 } 89 113 90 void G4GeneralParticleSource::IntensityNormali 114 void G4GeneralParticleSource::IntensityNormalization() 91 { 115 { 92 GPSData->IntensityNormalise(); << 116 GPSData->IntensityNormalise(); 93 normalised=GPSData->Normalised(); << 117 normalised=true; 94 } 118 } 95 119 96 void G4GeneralParticleSource::ListSource() 120 void G4GeneralParticleSource::ListSource() 97 { 121 { 98 G4cout << "The number of particle sources is << 122 G4cout << "The number of particle sources is: " << GPSData->GetIntensityVectorSize() << G4endl; 99 << GPSData->GetIntensityVectorSize() << 123 for(G4int i=0; i<GPSData->GetIntensityVectorSize(); i++) 100 G4cout << " Multiple Vertex sources: " << GP << 124 { 101 G4cout << " Flat Sampling flag: " << GPSData << 125 G4cout << "\tsource " << i << " intensity is: " << GPSData->GetIntensity(i) << G4endl;; 102 const G4int currentIdx = GPSData->GetCurrent << 126 } 103 for(G4int i=0; i<GPSData->GetIntensityVector << 104 { << 105 G4cout << "\tsource " << i << " with inten << 106 << GPSData->GetIntensity(i) << G4en << 107 const G4SingleParticleSource* thisSrc = GP << 108 G4cout << " \t\tNum Particles: "<<thisSrc- << 109 << "; Particle type: " << 110 << thisSrc->GetParticleDefinition() << 111 G4cout << " \t\tEnergy: " << 112 << G4BestUnit(thisSrc->GetEneDist()->GetM << 113 G4cout << " \t\tDirection: " << 114 << thisSrc->GetAngDist()->GetDirect << 115 G4cout << G4BestUnit(thisSrc->GetPosDist() << 116 << G4endl; << 117 G4cout << " \t\tAngular Distribution: " << 118 << thisSrc->GetAngDist()->GetDistTy << 119 G4cout << " \t\tEnergy Distribution: " << 120 << thisSrc->GetEneDist()->GetEnergy << 121 G4cout << " \t\tPosition Distribution Type << 122 << thisSrc->GetPosDist()->GetPosDis << 123 G4cout << "; Position Shape: " << 124 << thisSrc->GetPosDist()->GetPosDis << 125 } << 126 << 127 // Set back previous source << 128 GPSData->GetCurrentSource(currentIdx); << 129 } 127 } 130 128 131 void G4GeneralParticleSource::SetCurrentSource 129 void G4GeneralParticleSource::SetCurrentSourceto(G4int aV) 132 { 130 { 133 G4int id = aV; << 131 G4int id = aV; 134 if ( id < GPSData->GetIntensityVectorSize() << 132 if ( id <= GPSData->GetIntensityVectorSize() ) 135 { << 133 { 136 // currentSourceIdx = aV; << 134 currentSourceIdx = aV; 137 // currentSource = GPSData->GetCurrentSour << 135 currentSource = GPSData->GetCurrentSource(id); 138 theMessenger->SetParticleGun(GPSData->GetC << 136 theMessenger->SetParticleGun(currentSource); 139 } << 137 } 140 else << 138 else 141 { << 139 { 142 G4ExceptionDescription msg; << 140 G4cout << " source index is invalid " << G4endl; 143 msg << "Trying to set source to index " << << 141 G4cout << " it shall be <= " << GPSData->GetIntensityVectorSize() << G4endl; 144 << GPSData->GetIntensityVectorSize() < << 142 } 145 G4Exception("G4GeneralParticleSoruce::SetC << 146 FatalException, msg); << 147 } << 148 } 143 } 149 144 150 void G4GeneralParticleSource::SetCurrentSource 145 void G4GeneralParticleSource::SetCurrentSourceIntensity(G4double aV) 151 { 146 { 152 GPSData->Lock(); << 147 GPSData->Lock(); 153 GPSData->SetCurrentSourceIntensity(aV); << 148 GPSData->SetCurrentSourceIntensity(aV); 154 GPSData->Unlock(); << 149 GPSData->Unlock(); 155 normalised = GPSData->Normalised(); << 150 normalised = false; 156 } 151 } 157 152 158 void G4GeneralParticleSource::ClearAll() 153 void G4GeneralParticleSource::ClearAll() 159 { 154 { 160 GPSData->ClearSources(); << 155 currentSourceIdx = -1; 161 normalised=GPSData->Normalised(); << 156 currentSource = 0; >> 157 GPSData->ClearSources(); >> 158 normalised=false; 162 } 159 } 163 160 164 void G4GeneralParticleSource::DeleteaSource(G4 161 void G4GeneralParticleSource::DeleteaSource(G4int aV) 165 { 162 { 166 G4int id = aV; << 163 G4int id = aV; 167 if ( id <= GPSData->GetIntensityVectorSize() << 164 if ( id <= GPSData->GetIntensityVectorSize() ) 168 { << 165 { 169 GPSData->DeleteASource(aV); << 166 GPSData->DeleteASource(aV); 170 normalised=GPSData->Normalised(); << 167 normalised=false; 171 } << 168 } 172 else << 169 else 173 { << 170 { 174 G4cout << " source index is invalid " << G << 171 G4cout << " source index is invalid " << G4endl; 175 G4cout << " it shall be <= " << 172 G4cout << " it shall be <= " << GPSData->GetIntensityVectorSize() << G4endl; 176 << GPSData->GetIntensityVectorSize( << 173 } 177 } << 178 } 174 } 179 175 180 void G4GeneralParticleSource::GeneratePrimaryV 176 void G4GeneralParticleSource::GeneratePrimaryVertex(G4Event* evt) 181 { 177 { 182 if (!GPSData->GetMultipleVertex()) << 178 if (!multiple_vertex) 183 { << 179 { 184 G4SingleParticleSource* currentSource = GP << 180 if (GPSData->GetIntensityVectorSize() > 1) 185 if (GPSData->GetIntensityVectorSize() > 1) << 186 { << 187 // Try to minimize locks << 188 if (! normalised ) << 189 { << 190 // According to local variable, normal << 191 // Check with underlying shared resour << 192 // thread could have already normalize << 193 GPSData->Lock(); << 194 G4bool norm = GPSData->Normalised(); << 195 if (!norm) << 196 { 181 { 197 IntensityNormalization(); << 182 //Try to minimize locks >> 183 if (! normalised ) { >> 184 //According to local variable, normalization is needed >> 185 //Check with underlying (shared resource), another >> 186 //thread could have already normalized this >> 187 GPSData->Lock(); >> 188 G4bool norm = GPSData->Normalised(); >> 189 if (!norm) { >> 190 IntensityNormalization(); >> 191 } >> 192 //This takes care of the case in which the local variable >> 193 //is False and the underlying source is. >> 194 normalised = GPSData->Normalised(); >> 195 GPSData->Unlock(); >> 196 } >> 197 G4double rndm = G4UniformRand(); >> 198 size_t i = 0 ; >> 199 if (!flat_sampling) >> 200 { >> 201 while ( rndm > GPSData->GetSourceProbability(i) ) i++; >> 202 (currentSource = GPSData->GetCurrentSource(i)); >> 203 } >> 204 else >> 205 { >> 206 i = size_t (GPSData->GetIntensityVectorSize()*rndm); >> 207 currentSource = GPSData->GetCurrentSource(i); >> 208 } 198 } 209 } 199 // This takes care of the case in whic << 210 currentSource-> GeneratePrimaryVertex(evt); 200 // is False and the underlying resourc << 211 } 201 normalised = GPSData->Normalised(); << 212 else 202 GPSData->Unlock(); << 203 } << 204 G4double rndm = G4UniformRand(); << 205 G4int i = 0 ; << 206 if (! GPSData->GetFlatSampling() ) << 207 { << 208 while ( rndm > GPSData->GetSourceProba << 209 currentSource = GPSData->GetCurrentS << 210 } << 211 else << 212 { << 213 i = G4int (GPSData->GetIntensityVector << 214 currentSource = GPSData->GetCurrentSou << 215 } << 216 } << 217 currentSource->GeneratePrimaryVertex(evt); << 218 } << 219 else << 220 { << 221 for (G4int i = 0; i < GPSData->GetIntensi << 222 { 213 { 223 GPSData->GetCurrentSource(i)->GeneratePr << 214 for (G4int i = 0; i < GPSData->GetIntensityVectorSize(); i++) >> 215 { >> 216 GPSData->GetCurrentSource(i)->GeneratePrimaryVertex(evt); >> 217 } 224 } 218 } 225 } << 226 } 219 } 227 220