00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049 #include "G4EmConfigurator.hh"
00050 #include "G4SystemOfUnits.hh"
00051 #include "G4ParticleTable.hh"
00052 #include "G4ParticleDefinition.hh"
00053 #include "G4ProcessManager.hh"
00054 #include "G4VProcess.hh"
00055 #include "G4ProcessVector.hh"
00056 #include "G4RegionStore.hh"
00057 #include "G4Region.hh"
00058 #include "G4DummyModel.hh"
00059 #include "G4VEnergyLossProcess.hh"
00060 #include "G4VEmProcess.hh"
00061 #include "G4VMultipleScattering.hh"
00062
00063
00064
00065 G4EmConfigurator::G4EmConfigurator(G4int val):verbose(val)
00066 {
00067 index = -10;
00068 }
00069
00070
00071
00072 G4EmConfigurator::~G4EmConfigurator()
00073 {}
00074
00075
00076
00077 void G4EmConfigurator::SetExtraEmModel(const G4String& particleName,
00078 const G4String& processName,
00079 G4VEmModel* mod,
00080 const G4String& regionName,
00081 G4double emin,
00082 G4double emax,
00083 G4VEmFluctuationModel* fm)
00084 {
00085 if(1 < verbose) {
00086 G4cout << " G4EmConfigurator::SetExtraEmModel " << mod->GetName()
00087 << " for " << particleName
00088 << " and " << processName
00089 << " in the region <" << regionName
00090 << "> Emin(MeV)= " << emin/MeV
00091 << " Emax(MeV)= " << emax/MeV
00092 << G4endl;
00093 }
00094 if(mod || fm) {
00095 models.push_back(mod);
00096 flucModels.push_back(fm);
00097 } else {
00098 models.push_back(new G4DummyModel());
00099 flucModels.push_back(0);
00100 }
00101
00102 particles.push_back(particleName);
00103 processes.push_back(processName);
00104 regions.push_back(regionName);
00105 lowEnergy.push_back(emin);
00106 highEnergy.push_back(emax);
00107 }
00108
00109
00110
00111 void G4EmConfigurator::AddModels()
00112 {
00113 size_t n = models.size();
00114 if(0 < verbose) {
00115 G4cout << "### G4EmConfigurator::AddModels n= " << n << G4endl;
00116 }
00117 if(n > 0) {
00118 for(size_t i=0; i<n; ++i) {
00119 if(models[i]) {
00120 G4Region* reg = FindRegion(regions[i]);
00121 if(reg) {
00122 --index;
00123 SetModelForRegion(models[i],flucModels[i],reg,
00124 particles[i],processes[i],
00125 lowEnergy[i],highEnergy[i]);
00126 }
00127 }
00128 }
00129 }
00130 Clear();
00131 }
00132
00133
00134
00135 void G4EmConfigurator::SetModelForRegion(G4VEmModel* mod,
00136 G4VEmFluctuationModel* fm,
00137 G4Region* reg,
00138 const G4String& particleName,
00139 const G4String& processName,
00140 G4double emin, G4double emax)
00141 {
00142 if(1 < verbose) {
00143 G4cout << " G4EmConfigurator::SetModelForRegion: " << mod->GetName()
00144 << G4endl;
00145 G4cout << " For " << particleName
00146 << " and " << processName
00147 << " in the region <" << reg->GetName()
00148 << " Emin(MeV)= " << emin/MeV
00149 << " Emax(MeV)= " << emax/MeV;
00150 if(fm) { G4cout << " FLmodel " << fm->GetName(); }
00151 G4cout << G4endl;
00152 }
00153 G4ParticleTable::G4PTblDicIterator* theParticleIterator =
00154 G4ParticleTable::GetParticleTable()->GetIterator();
00155
00156 theParticleIterator->reset();
00157 while( (*theParticleIterator)() ) {
00158 const G4ParticleDefinition* part = theParticleIterator->value();
00159
00160
00161
00162 if((part->GetParticleName() == particleName) ||
00163 (particleName == "all") ||
00164 (particleName == "charged" && part->GetPDGCharge() != 0.0)) {
00165
00166
00167 G4ProcessManager* pmanager = part->GetProcessManager();
00168 G4ProcessVector* plist = pmanager->GetProcessList();
00169 G4int np = pmanager->GetProcessListLength();
00170
00171
00172
00173 G4VProcess* proc = 0;
00174 for(G4int i=0; i<np; ++i) {
00175 if(processName == (*plist)[i]->GetProcessName()) {
00176 proc = (*plist)[i];
00177 break;
00178 }
00179 }
00180 if(!proc) {
00181 G4cout << "### G4EmConfigurator WARNING: fails to find a process <"
00182 << processName << "> for " << particleName << G4endl;
00183 return;
00184 }
00185
00186 if(mod) {
00187 if(!UpdateModelEnergyRange(mod, emin, emax)) { return; }
00188 }
00189
00190 G4int ii = proc->GetProcessSubType();
00191 if(10 == ii && mod) {
00192 G4VMultipleScattering* p = static_cast<G4VMultipleScattering*>(proc);
00193 p->AddEmModel(index,mod,reg);
00194 if(1 < verbose) {
00195 G4cout << "### Added msc model order= " << index << " for "
00196 << particleName << " and " << processName << G4endl;
00197 }
00198 return;
00199 } else if(2 <= ii && 4 >= ii) {
00200 G4VEnergyLossProcess* p = static_cast<G4VEnergyLossProcess*>(proc);
00201 if(!mod && fm) {
00202 p->SetFluctModel(fm);
00203 } else {
00204 p->AddEmModel(index,mod,fm,reg);
00205 if(1 < verbose) {
00206 G4cout << "### Added eloss model order= " << index << " for "
00207 << particleName << " and " << processName << G4endl;
00208 }
00209 }
00210 return;
00211 } else if(mod) {
00212 G4VEmProcess* p = static_cast<G4VEmProcess*>(proc);
00213 p->AddEmModel(index,mod,reg);
00214 if(1 < verbose) {
00215 G4cout << "### Added em model order= " << index << " for "
00216 << particleName << " and " << processName << G4endl;
00217 }
00218 return;
00219 } else {
00220 return;
00221 }
00222 }
00223 }
00224 }
00225
00226
00227
00228 void
00229 G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
00230 G4VEnergyLossProcess* p)
00231 {
00232 size_t n = particles.size();
00233 if(1 < verbose) {
00234 G4cout << " G4EmConfigurator::PrepareModels for EnergyLoss n= "
00235 << n << G4endl;
00236 }
00237 if(n > 0) {
00238 G4String particleName = aParticle->GetParticleName();
00239 G4String processName = p->GetProcessName();
00240
00241 for(size_t i=0; i<n; ++i) {
00242
00243 if(processName == processes[i]) {
00244 if((particleName == particles[i]) ||
00245 (particles[i] == "all") ||
00246 (particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
00247 G4Region* reg = FindRegion(regions[i]);
00248
00249 if(reg) {
00250 --index;
00251 G4VEmModel* mod = models[i];
00252 G4VEmFluctuationModel* fm = flucModels[i];
00253 if(mod) {
00254 if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
00255 p->AddEmModel(index,mod,fm,reg);
00256 if(1 < verbose) {
00257 G4cout << "### Added eloss model order= " << index << " for "
00258 << particleName << " and " << processName << G4endl;
00259 }
00260 }
00261 } else if(fm) {
00262 p->SetFluctModel(fm);
00263 }
00264 }
00265 }
00266 }
00267 }
00268 }
00269 }
00270
00271
00272
00273 void
00274 G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
00275 G4VEmProcess* p)
00276 {
00277 size_t n = particles.size();
00278 if(1 < verbose) {
00279 G4cout << " G4EmConfigurator::PrepareModels for EM process n= "
00280 << n << G4endl;
00281 }
00282 if(n > 0) {
00283 G4String particleName = aParticle->GetParticleName();
00284 G4String processName = p->GetProcessName();
00285
00286 for(size_t i=0; i<n; ++i) {
00287 if(processName == processes[i]) {
00288 if((particleName == particles[i]) ||
00289 (particles[i] == "all") ||
00290 (particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
00291 G4Region* reg = FindRegion(regions[i]);
00292
00293 if(reg) {
00294 --index;
00295 G4VEmModel* mod = models[i];
00296 if(mod) {
00297 if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
00298 p->AddEmModel(index,mod,reg);
00299 if(1 < verbose) {
00300 G4cout << "### Added em model order= " << index << " for "
00301 << particleName << " and " << processName << G4endl;
00302 }
00303 }
00304 }
00305 }
00306 }
00307 }
00308 }
00309 }
00310 }
00311
00312
00313
00314 void
00315 G4EmConfigurator::PrepareModels(const G4ParticleDefinition* aParticle,
00316 G4VMultipleScattering* p)
00317 {
00318 size_t n = particles.size();
00319 if(1 < verbose) {
00320 G4cout << " G4EmConfigurator::PrepareModels for MSC process n= "
00321 << n << G4endl;
00322 }
00323
00324 if(n > 0) {
00325 G4String particleName = aParticle->GetParticleName();
00326 G4String processName = p->GetProcessName();
00327 for(size_t i=0; i<n; ++i) {
00328 if(processName == processes[i]) {
00329 if((particleName == particles[i]) ||
00330 (particles[i] == "all") ||
00331 (particles[i] == "charged" && aParticle->GetPDGCharge() != 0.0)) {
00332 G4Region* reg = FindRegion(regions[i]);
00333 if(reg) {
00334 --index;
00335 G4VEmModel* mod = models[i];
00336 if(mod) {
00337 if(UpdateModelEnergyRange(mod, lowEnergy[i], highEnergy[i])) {
00338 p->AddEmModel(index,mod,reg);
00339 G4cout << "### Added msc model order= " << index << " for "
00340 << particleName << " and " << processName << G4endl;
00341 }
00342 }
00343 }
00344 }
00345 }
00346 }
00347 }
00348 }
00349
00350
00351
00352 void G4EmConfigurator::Clear()
00353 {
00354 particles.clear();
00355 processes.clear();
00356 models.clear();
00357 flucModels.clear();
00358 regions.clear();
00359 lowEnergy.clear();
00360 highEnergy.clear();
00361 }
00362
00363
00364
00365 G4Region* G4EmConfigurator::FindRegion(const G4String& regionName)
00366 {
00367
00368 G4Region* reg = 0;
00369 G4RegionStore* regStore = G4RegionStore::GetInstance();
00370 G4String r = regionName;
00371 if(r == "" || r == "world" || r == "World") {
00372 r = "DefaultRegionForTheWorld";
00373 }
00374 reg = regStore->GetRegion(r, true);
00375 if(!reg) {
00376 G4cout << "### G4EmConfigurator WARNING: fails to find a region <"
00377 << r << G4endl;
00378 } else if(verbose > 1) {
00379 G4cout << "### G4EmConfigurator finds out G4Region <" << r << ">"
00380 << G4endl;
00381 }
00382 return reg;
00383 }
00384
00385
00386
00387 G4bool G4EmConfigurator::UpdateModelEnergyRange(G4VEmModel* mod,
00388 G4double emin, G4double emax)
00389 {
00390
00391 G4double e1 = std::max(emin,mod->LowEnergyLimit());
00392 G4double e2 = std::min(emax,mod->HighEnergyLimit());
00393 if(e2 <= e1) {
00394 G4cout << "### G4EmConfigurator WARNING: empty energy interval"
00395 << " for <" << mod->GetName()
00396 << "> Emin(MeV)= " << e1/CLHEP::MeV
00397 << "> Emax(MeV)= " << e2/CLHEP::MeV
00398 << G4endl;
00399 return false;
00400 }
00401 mod->SetLowEnergyLimit(e1);
00402 mod->SetHighEnergyLimit(e2);
00403 if(verbose > 1) {
00404 G4cout << "### G4EmConfigurator for " << mod->GetName()
00405 << " Emin(MeV)= " << e1/MeV << " Emax(MeV)= " << e2/MeV
00406 << G4endl;
00407 }
00408 return true;
00409 }
00410
00411