ECCE @ EIC Software
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
G4LossTableManager.cc
Go to the documentation of this file. Or view the newest version in sPHENIX GitHub for file G4LossTableManager.cc
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 // -------------------------------------------------------------------
27 //
28 // GEANT4 Class file
29 //
30 //
31 // File name: G4LossTableManager
32 //
33 // Author: Vladimir Ivanchenko
34 //
35 // Creation date: 03.01.2002
36 //
37 // Modifications: by V.Ivanchenko
38 //
39 //
40 // Class Description:
41 //
42 // -------------------------------------------------------------------
43 //
44 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
45 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
46 
47 #include "G4LossTableManager.hh"
48 #include "G4SystemOfUnits.hh"
49 
50 #include "G4VMultipleScattering.hh"
51 #include "G4VEmProcess.hh"
52 
53 #include "G4EmParameters.hh"
54 #include "G4EmSaturation.hh"
55 #include "G4EmConfigurator.hh"
56 #include "G4ElectronIonPair.hh"
57 #include "G4NIELCalculator.hh"
58 #include "G4EmCorrections.hh"
59 #include "G4LossTableBuilder.hh"
60 #include "G4VAtomDeexcitation.hh"
61 #include "G4VSubCutProducer.hh"
62 
63 #include "G4PhysicsTable.hh"
64 #include "G4ParticleDefinition.hh"
65 #include "G4MaterialCutsCouple.hh"
66 #include "G4ProcessManager.hh"
67 #include "G4Electron.hh"
68 #include "G4Proton.hh"
69 #include "G4ProductionCutsTable.hh"
70 #include "G4PhysicsTableHelper.hh"
71 #include "G4EmTableType.hh"
72 #include "G4Region.hh"
73 #include "G4PhysicalConstants.hh"
74 #include "G4Threading.hh"
75 
76 #include "G4Gamma.hh"
77 #include "G4Positron.hh"
78 #include "G4OpticalPhoton.hh"
79 #include "G4Neutron.hh"
80 #include "G4MuonPlus.hh"
81 #include "G4MuonMinus.hh"
82 
83 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
84 
86 
88 {
89  if(!instance) {
91  instance = inst.Instance();
92  }
93  return instance;
94 }
95 
96 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
97 
99 {
100  for (G4int i=0; i<n_loss; ++i) {
101  delete loss_vector[i];
102  }
103  size_t msc = msc_vector.size();
104  for (size_t j=0; j<msc; ++j) {
105  delete msc_vector[j];
106  }
107  size_t emp = emp_vector.size();
108  for (size_t k=0; k<emp; ++k) {
109  delete emp_vector[k];
110  }
111  emp = p_vector.size();
112  for (size_t k=0; k<emp; ++k) {
113  delete p_vector[k];
114  }
115  size_t mod = mod_vector.size();
116  size_t fmod = fmod_vector.size();
117  //G4cout << " Nmod" << mod << " Nfluc= " << fmod << G4endl;
118  for (size_t a=0; a<mod; ++a) {
119  //G4cout << "Delete model #" << a << " " << mod_vector[a] << G4endl;
120  if( nullptr != mod_vector[a] ) {
121  for (size_t b=0; b<fmod; ++b) {
122  if((G4VEmModel*)(fmod_vector[b]) == mod_vector[a]) {
123  fmod_vector[b] = nullptr;
124  }
125  }
126  delete mod_vector[a];
127  mod_vector[a] = nullptr;
128  }
129  }
130  for (size_t b=0; b<fmod; ++b) {
131  delete fmod_vector[b];
132  }
133  Clear();
134  delete tableBuilder;
135  delete emCorrections;
136  delete emConfigurator;
137  delete emElectronIonPair;
138  delete nielCalculator;
139  delete atomDeexcitation;
140  delete subcutProducer;
141 }
142 
143 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
144 
146 {
148  n_loss = 0;
149  run = -1;
150  startInitialisation = false;
151  all_tables_are_built = false;
152  currentLoss = nullptr;
153  currentParticle = nullptr;
154  firstParticle = nullptr;
155  isMaster = true;
158  theGenericIon= nullptr;
161  isMaster = false;
162  }
165  emConfigurator = nullptr;
166  emElectronIonPair = nullptr;
167  atomDeexcitation = nullptr;
168  subcutProducer = nullptr;
169  nielCalculator = nullptr;
170  gGeneral = nullptr;
171  eGeneral = nullptr;
172 }
173 
174 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
175 
177 {
178  all_tables_are_built = false;
179  currentLoss = nullptr;
180  currentParticle = nullptr;
181  if(n_loss) {
182  dedx_vector.clear();
183  range_vector.clear();
184  inv_range_vector.clear();
185  loss_map.clear();
186  loss_vector.clear();
187  part_vector.clear();
188  base_part_vector.clear();
189  tables_are_built.clear();
190  isActive.clear();
191  n_loss = 0;
192  }
193 }
194 
195 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
196 
198 {
199  if(!p) { return; }
200  for (G4int i=0; i<n_loss; ++i) {
201  if(loss_vector[i] == p) { return; }
202  }
203  if(verbose > 1) {
204  G4cout << "G4LossTableManager::Register G4VEnergyLossProcess : "
205  << p->GetProcessName() << " idx= " << n_loss << G4endl;
206  }
207  ++n_loss;
208  loss_vector.push_back(p);
209  part_vector.push_back(nullptr);
210  base_part_vector.push_back(nullptr);
211  dedx_vector.push_back(nullptr);
212  range_vector.push_back(nullptr);
213  inv_range_vector.push_back(nullptr);
214  tables_are_built.push_back(false);
215  isActive.push_back(true);
216  all_tables_are_built = false;
217 }
218 
219 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
220 
222 {
224  if(!isMaster) {
226  }
232  if(atomDeexcitation) {
235  }
236 }
237 
238 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
239 
241 {
242  if(!p) { return; }
243  for (G4int i=0; i<n_loss; ++i) {
244  if(loss_vector[i] == p) {
245  loss_vector[i] = nullptr;
246  break;
247  }
248  }
249 }
250 
251 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
252 
254 {
255  if(!p) { return; }
256  G4int n = msc_vector.size();
257  for (G4int i=0; i<n; ++i) {
258  if(msc_vector[i] == p) { return; }
259  }
260  if(verbose > 1) {
261  G4cout << "G4LossTableManager::Register G4VMultipleScattering : "
262  << p->GetProcessName() << " idx= " << msc_vector.size() << G4endl;
263  }
264  msc_vector.push_back(p);
265 }
266 
267 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
268 
270 {
271  if(!p) { return; }
272  size_t msc = msc_vector.size();
273  for (size_t i=0; i<msc; ++i) {
274  if(msc_vector[i] == p) {
275  msc_vector[i] = nullptr;
276  break;
277  }
278  }
279 }
280 
281 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
282 
284 {
285  if(!p) { return; }
286  G4int n = emp_vector.size();
287  for (G4int i=0; i<n; ++i) {
288  if(emp_vector[i] == p) { return; }
289  }
290  if(verbose > 1) {
291  G4cout << "G4LossTableManager::Register G4VEmProcess : "
292  << p->GetProcessName() << " idx= " << emp_vector.size() << G4endl;
293  }
294  emp_vector.push_back(p);
295 }
296 
297 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
298 
300 {
301  if(!p) { return; }
302  size_t emp = emp_vector.size();
303  for (size_t i=0; i<emp; ++i) {
304  if(emp_vector[i] == p) {
305  emp_vector[i] = nullptr;
306  break;
307  }
308  }
309 }
310 
311 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
312 
314 {
315  if(!p) { return; }
316  G4int n = p_vector.size();
317  for (G4int i=0; i<n; ++i) {
318  if(p_vector[i] == p) { return; }
319  }
320  if(verbose > 1) {
321  G4cout << "G4LossTableManager::Register G4VProcess : "
322  << p->GetProcessName() << " idx= " << p_vector.size() << G4endl;
323  }
324  p_vector.push_back(p);
325 }
326 
327 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
328 
330 {
331  if(!p) { return; }
332  size_t emp = p_vector.size();
333  for (size_t i=0; i<emp; ++i) {
334  if(p_vector[i] == p) {
335  p_vector[i] = nullptr;
336  break;
337  }
338  }
339 }
340 
341 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
342 
344 {
345  mod_vector.push_back(p);
346  if(verbose > 1) {
347  G4cout << "G4LossTableManager::Register G4VEmModel : "
348  << p->GetName() << " " << p << " " << mod_vector.size() << G4endl;
349  }
350 }
351 
352 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
353 
355 {
356  //G4cout << "G4LossTableManager::DeRegister G4VEmModel : " << p << G4endl;
357  size_t n = mod_vector.size();
358  for (size_t i=0; i<n; ++i) {
359  if(mod_vector[i] == p) {
360  mod_vector[i] = nullptr;
361  break;
362  }
363  }
364 }
365 
366 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
367 
369 {
370  fmod_vector.push_back(p);
371  if(verbose > 1) {
372  G4cout << "G4LossTableManager::Register G4VEmFluctuationModel : "
373  << p->GetName() << " " << fmod_vector.size() << G4endl;
374  }
375 }
376 
377 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
378 
380 {
381  size_t n = fmod_vector.size();
382  for (size_t i=0; i<n; ++i) {
383  if(fmod_vector[i] == p) { fmod_vector[i] = nullptr; }
384  }
385 }
386 
387 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
388 
390  const G4ParticleDefinition* part,
392 {
393  if(!p || !part) { return; }
394  for (G4int i=0; i<n_loss; ++i) {
395  if(loss_vector[i] == p) { return; }
396  }
397  if(verbose > 1) {
398  G4cout << "G4LossTableManager::RegisterExtraParticle "
399  << part->GetParticleName() << " G4VEnergyLossProcess : "
400  << p->GetProcessName() << " idx= " << n_loss << G4endl;
401  }
402  ++n_loss;
403  loss_vector.push_back(p);
404  part_vector.push_back(part);
405  base_part_vector.push_back(p->BaseParticle());
406  dedx_vector.push_back(nullptr);
407  range_vector.push_back(nullptr);
408  inv_range_vector.push_back(nullptr);
409  tables_are_built.push_back(false);
410  all_tables_are_built = false;
411 }
412 
413 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
414 
417 {
418  //G4cout << "G4LossTableManager::GetEnergyLossProcess: "
419  //<< aParticle << " " << currentParticle << " " << currentLoss << G4endl;
420  if(aParticle != currentParticle) {
421  currentParticle = aParticle;
422  std::map<PD,G4VEnergyLossProcess*,std::less<PD> >::const_iterator pos;
423  if ((pos = loss_map.find(aParticle)) != loss_map.end()) {
424  currentLoss = (*pos).second;
425  } else {
426  currentLoss = nullptr;
427  if ((pos = loss_map.find(theGenericIon)) != loss_map.end()) {
428  currentLoss = (*pos).second;
429  }
430  }
431  }
432  return currentLoss;
433 }
434 
435 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
436 
437 void
440  G4bool theMaster)
441 {
442  if (1 < verbose) {
443  G4cout << "G4LossTableManager::PreparePhysicsTable for "
444  << particle->GetParticleName()
445  << " and " << p->GetProcessName() << " run= " << run
446  << " loss_vector " << loss_vector.size() << G4endl;
447  }
448 
449  isMaster = theMaster;
450 
451  if(!startInitialisation) {
452  ResetParameters();
453  if (1 < verbose) {
454  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
455  << G4endl;
456  }
457  }
458 
459  // start initialisation for the first run
460  if( -1 == run ) {
461  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
462 
463  // initialise particles for given process
464  for (G4int j=0; j<n_loss; ++j) {
465  if (p == loss_vector[j] && !part_vector[j]) {
466  part_vector[j] = particle;
467  if(particle->GetParticleName() == "GenericIon") {
469  }
470  }
471  }
472  }
473  startInitialisation = true;
474 }
475 
476 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
477 
478 void
480  G4VEmProcess* p, G4bool theMaster)
481 {
482  if (1 < verbose) {
483  G4cout << "G4LossTableManager::PreparePhysicsTable for "
484  << particle->GetParticleName()
485  << " and " << p->GetProcessName() << G4endl;
486  }
487  isMaster = theMaster;
488 
489  if(!startInitialisation) {
490  ResetParameters();
491  if (1 < verbose) {
492  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
493  << G4endl;
494  }
495  }
496 
497  // start initialisation for the first run
498  if( -1 == run ) {
499  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
500  }
501  startInitialisation = true;
502 }
503 
504 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
505 
506 void
509  G4bool theMaster)
510 {
511  if (1 < verbose) {
512  G4cout << "G4LossTableManager::PreparePhysicsTable for "
513  << particle->GetParticleName()
514  << " and " << p->GetProcessName() << G4endl;
515  }
516 
517  isMaster = theMaster;
518 
519  if(!startInitialisation) {
520  ResetParameters();
521  if (1 < verbose) {
522  G4cout << "====== G4LossTableManager::PreparePhysicsTable start ====="
523  << G4endl;
524  }
525  }
526 
527  // start initialisation for the first run
528  if( -1 == run ) {
529  if(emConfigurator) { emConfigurator->PrepareModels(particle, p); }
530  }
531  startInitialisation = true;
532 }
533 
534 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
535 
536 void
538 {
539  if(-1 == run && startInitialisation) {
541  }
542 }
543 
544 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
545 
547  const G4ParticleDefinition* aParticle,
549 {
550  if(1 < verbose) {
551  G4cout << "### G4LossTableManager::LocalPhysicsTable() for "
552  << aParticle->GetParticleName()
553  << " and process " << p->GetProcessName()
554  << G4endl;
555  }
556 
557  if(-1 == run && startInitialisation) {
559  firstParticle = aParticle;
560  }
561 
562  if(startInitialisation) {
563  ++run;
564  if(1 < verbose) {
565  G4cout << "===== G4LossTableManager::LocalPhysicsTable() for run "
566  << run << " =====" << G4endl;
567  }
568  currentParticle = nullptr;
569  startInitialisation = false;
570  for (G4int i=0; i<n_loss; ++i) {
571  if(loss_vector[i]) {
572  tables_are_built[i] = false;
573  } else {
574  tables_are_built[i] = true;
575  part_vector[i] = nullptr;
576  }
577  }
578  }
579 
580  all_tables_are_built= true;
581  for (G4int i=0; i<n_loss; ++i) {
582  if(p == loss_vector[i]) {
583  tables_are_built[i] = true;
584  isActive[i] = true;
585  part_vector[i] = p->Particle();
586  base_part_vector[i] = p->BaseParticle();
587  dedx_vector[i] = p->DEDXTable();
590  if(0 == run && p->IsIonisationProcess()) {
591  loss_map[part_vector[i]] = p;
592  //G4cout << "G4LossTableManager::LocalPhysicsTable " << part_vector[i]->GetParticleName()
593  // << " added to map " << p << G4endl;
594  }
595 
596  if(1 < verbose) {
597  G4cout << i <<". "<< p->GetProcessName();
598  if(part_vector[i]) {
599  G4cout << " for " << part_vector[i]->GetParticleName();
600  }
601  G4cout << " active= " << isActive[i]
602  << " table= " << tables_are_built[i]
603  << " isIonisation= " << p->IsIonisationProcess()
604  << G4endl;
605  }
606  break;
607  } else if(!tables_are_built[i]) {
608  all_tables_are_built = false;
609  }
610  }
611 
612  if(1 < verbose) {
613  G4cout << "### G4LossTableManager::LocalPhysicsTable end"
614  << G4endl;
615  }
616  if(all_tables_are_built) {
617  if(1 < verbose) {
618  G4cout << "%%%%% All dEdx and Range tables for worker are ready for run "
619  << run << " %%%%%" << G4endl;
620  }
621  }
622 }
623 
624 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
625 
627  const G4ParticleDefinition* aParticle,
629 {
630  if(1 < verbose) {
631  G4cout << "### G4LossTableManager::BuildPhysicsTable() for "
632  << aParticle->GetParticleName()
633  << " and process " << p->GetProcessName() << G4endl;
634  }
635  // clear configurator
636  if(-1 == run && startInitialisation) {
638  firstParticle = aParticle;
639  }
640  if(startInitialisation) {
641  ++run;
642  if(1 < verbose) {
643  G4cout << "===== G4LossTableManager::BuildPhysicsTable() for run "
644  << run << " ===== " << atomDeexcitation << G4endl;
645  }
646  currentParticle = nullptr;
647  all_tables_are_built= true;
648  }
649 
650  // initialisation before any table is built
651  if ( startInitialisation && aParticle == firstParticle ) {
652 
653  startInitialisation = false;
654  if(1 < verbose) {
655  G4cout << "### G4LossTableManager start initilisation for first particle "
657  << G4endl;
658  }
659 
661 
662  for (G4int i=0; i<n_loss; ++i) {
664 
665  if(el) {
666  isActive[i] = true;
667  base_part_vector[i] = el->BaseParticle();
668  tables_are_built[i] = false;
669  all_tables_are_built= false;
670  if(!isActive[i]) {
671  el->SetIonisation(false);
672  tables_are_built[i] = true;
673  }
674 
675  if(1 < verbose) {
676  G4cout << i <<". "<< el->GetProcessName();
677  if(el->Particle()) {
678  G4cout << " for " << el->Particle()->GetParticleName();
679  }
680  G4cout << " active= " << isActive[i]
681  << " table= " << tables_are_built[i]
682  << " isIonisation= " << el->IsIonisationProcess();
683  if(base_part_vector[i]) {
684  G4cout << " base particle "
685  << base_part_vector[i]->GetParticleName();
686  }
687  G4cout << G4endl;
688  }
689  } else {
690  tables_are_built[i] = true;
691  part_vector[i] = nullptr;
692  isActive[i] = false;
693  }
694  }
695  }
696 
697  if (all_tables_are_built) { return; }
698 
699  // Build tables for given particle
700  all_tables_are_built = true;
701 
702  for(G4int i=0; i<n_loss; ++i) {
703  if(p == loss_vector[i] && !tables_are_built[i] && !base_part_vector[i]) {
704  const G4ParticleDefinition* curr_part = part_vector[i];
705  if(1 < verbose) {
706  G4cout << "### Build Table for " << p->GetProcessName()
707  << " and " << curr_part->GetParticleName()
708  << " " << tables_are_built[i] << " " << base_part_vector[i]
709  << G4endl;
710  }
711  G4VEnergyLossProcess* curr_proc = BuildTables(curr_part);
712  if(curr_proc) {
713  CopyTables(curr_part, curr_proc);
714  if(p == curr_proc && 0 == run && p->IsIonisationProcess()) {
715  loss_map[aParticle] = p;
716  //G4cout << "G4LossTableManager::BuildPhysicsTable: "
717  // << aParticle->GetParticleName()
718  // << " added to map " << p << G4endl;
719  }
720  }
721  }
722  if ( !tables_are_built[i] ) { all_tables_are_built = false; }
723  }
724  if(1 < verbose) {
725  G4cout << "### G4LossTableManager::BuildPhysicsTable end: "
726  << "all_tables_are_built= " << all_tables_are_built << " "
727  << aParticle->GetParticleName() << " proc: " << p << G4endl;
728  }
729  if(all_tables_are_built) {
730  if(1 < verbose) {
731  G4cout << "%%%%% All dEdx and Range tables are built for master run= "
732  << run << " %%%%%" << G4endl;
733  }
734  }
735 }
736 
737 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
738 
740  G4VEnergyLossProcess* base_proc)
741 {
742  for (G4int j=0; j<n_loss; ++j) {
743 
745 
746  if (!tables_are_built[j] && part == base_part_vector[j]) {
747  tables_are_built[j] = true;
748  proc->SetDEDXTable(base_proc->IonisationTable(),fRestricted);
749  proc->SetDEDXTable(base_proc->DEDXTableForSubsec(),fSubRestricted);
750  proc->SetDEDXTable(base_proc->DEDXunRestrictedTable(),fTotal);
751  proc->SetCSDARangeTable(base_proc->CSDARangeTable());
752  proc->SetRangeTableForLoss(base_proc->RangeTableForLoss());
753  proc->SetInverseRangeTable(base_proc->InverseRangeTable());
754  proc->SetLambdaTable(base_proc->LambdaTable());
755  proc->SetSubLambdaTable(base_proc->SubLambdaTable());
756  proc->SetIonisation(base_proc->IsIonisationProcess());
757  if(proc->IsIonisationProcess()) {
758  range_vector[j] = base_proc->RangeTableForLoss();
759  inv_range_vector[j] = base_proc->InverseRangeTable();
760  loss_map[part_vector[j]] = proc;
761  //G4cout << "G4LossTableManager::CopyTable "
762  // << part_vector[j]->GetParticleName()
763  // << " added to map " << proc << G4endl;
764  }
765  if (1 < verbose) {
766  G4cout << "For " << proc->GetProcessName()
767  << " for " << part_vector[j]->GetParticleName()
768  << " base_part= " << part->GetParticleName()
769  << " tables are assigned"
770  << G4endl;
771  }
772  }
773 
774  if (theElectron == part && theElectron == proc->SecondaryParticle() ) {
775  proc->SetSecondaryRangeTable(base_proc->RangeTableForLoss());
776  }
777  }
778 }
779 
780 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
781 
783  const G4ParticleDefinition* aParticle)
784 {
785  if(1 < verbose) {
786  G4cout << "G4LossTableManager::BuildTables() for "
787  << aParticle->GetParticleName() << G4endl;
788  }
789 
790  std::vector<G4PhysicsTable*> t_list;
791  std::vector<G4VEnergyLossProcess*> loss_list;
792  std::vector<G4bool> build_flags;
793  G4VEnergyLossProcess* em = nullptr;
794  G4VEnergyLossProcess* p = nullptr;
795  G4int iem = 0;
796  G4PhysicsTable* dedx = nullptr;
797  G4int i;
798 
799  G4ProcessVector* pvec =
800  aParticle->GetProcessManager()->GetProcessList();
801  G4int nvec = pvec->size();
802 
803  for (i=0; i<n_loss; ++i) {
804  p = loss_vector[i];
805  if (p) {
806  G4bool yes = (aParticle == part_vector[i]);
807 
808  // possible case of process sharing between particle/anti-particle
809  if(!yes) {
810  G4VProcess* ptr = static_cast<G4VProcess*>(p);
811  for(G4int j=0; j<nvec; ++j) {
812  //G4cout << "j= " << j << " " << (*pvec)[j] << " " << ptr << G4endl;
813  if(ptr == (*pvec)[j]) {
814  yes = true;
815  break;
816  }
817  }
818  }
819  // process belong to this particle
820  if(yes && isActive[i]) {
821  if (p->IsIonisationProcess() || !em) {
822  em = p;
823  iem= i;
824  }
825  // tables may be shared between particle/anti-particle
826  G4bool val = false;
827  if (!tables_are_built[i]) {
828  val = true;
829  dedx = p->BuildDEDXTable(fRestricted);
830  //G4cout << "Build DEDX table for " << p->GetProcessName()
831  // << " idx= " << i << dedx << " " << dedx->length() << G4endl;
832  p->SetDEDXTable(dedx,fRestricted);
833  tables_are_built[i] = true;
834  } else {
835  dedx = p->DEDXTable();
836  }
837  t_list.push_back(dedx);
838  loss_list.push_back(p);
839  build_flags.push_back(val);
840  }
841  }
842  }
843 
844  G4int n_dedx = t_list.size();
845  if (0 == n_dedx || !em) {
846  G4cout << "G4LossTableManager WARNING: no DEDX processes for "
847  << aParticle->GetParticleName() << G4endl;
848  return 0;
849  }
850  G4int nSubRegions = em->NumberOfSubCutoffRegions();
851 
852  if (1 < verbose) {
853  G4cout << "G4LossTableManager::BuildTables() start to build range tables"
854  << " and the sum of " << n_dedx << " processes"
855  << " iem= " << iem << " em= " << em->GetProcessName()
856  << " buildCSDARange= " << theParameters->BuildCSDARange()
857  << " nSubRegions= " << nSubRegions;
858  if(subcutProducer) {
859  G4cout << " SubCutProducer " << subcutProducer->GetName();
860  }
861  G4cout << G4endl;
862  }
863  // do not build tables if producer class is defined
864  if(subcutProducer) { nSubRegions = 0; }
865 
866  dedx = em->DEDXTable();
867  em->SetIonisation(true);
868  em->SetDEDXTable(dedx, fIsIonisation);
869 
870  if (1 < n_dedx) {
871  dedx = 0;
873  tableBuilder->BuildDEDXTable(dedx, t_list);
874  em->SetDEDXTable(dedx, fRestricted);
875  }
876 
877  /*
878  if(2==run && "e-" == aParticle->GetParticleName()) {
879  G4cout << "G4LossTableManager::BuildTables for e- " << dedx << G4endl;
880  G4cout << (*dedx) << G4endl;
881  G4cout << "%%%%% Instance ID= " << (*dedx)[0]->GetInstanceID() << G4endl;
882  G4cout << "%%%%% LastValue= " << (*dedx)[0]->GetLastValue() << G4endl;
883  G4cout << "%%%%% 1.2 " << (*(dedx))[0]->Value(1.2) << G4endl;
884  }
885  */
886  dedx_vector[iem] = dedx;
887 
888  G4PhysicsTable* range = em->RangeTableForLoss();
889  if(!range) range = G4PhysicsTableHelper::PreparePhysicsTable(range);
890  range_vector[iem] = range;
891 
892  G4PhysicsTable* invrange = em->InverseRangeTable();
893  if(!invrange) invrange = G4PhysicsTableHelper::PreparePhysicsTable(invrange);
894  inv_range_vector[iem] = invrange;
895 
896  tableBuilder->BuildRangeTable(dedx, range, true);
897  tableBuilder->BuildInverseRangeTable(range, invrange, true);
898 
899  // if(1<verbose) G4cout << *dedx << G4endl;
900 
901  em->SetRangeTableForLoss(range);
902  em->SetInverseRangeTable(invrange);
903 
904  // if(1<verbose) G4cout << *range << G4endl;
905 
906  std::vector<G4PhysicsTable*> listSub;
907  std::vector<G4PhysicsTable*> listCSDA;
908 
909  for (i=0; i<n_dedx; ++i) {
910  p = loss_list[i];
911  if(p != em) { p->SetIonisation(false); }
912  if(build_flags[i]) {
914  }
915  if (0 < nSubRegions) {
916  dedx = p->BuildDEDXTable(fSubRestricted);
917  p->SetDEDXTable(dedx,fSubRestricted);
918  listSub.push_back(dedx);
919  if(build_flags[i]) {
921  if(p != em) { em->AddCollaborativeProcess(p); }
922  }
923  }
924  if(theParameters->BuildCSDARange()) {
925  dedx = p->BuildDEDXTable(fTotal);
926  p->SetDEDXTable(dedx,fTotal);
927  listCSDA.push_back(dedx);
928  }
929  }
930 
931  if (0 < nSubRegions) {
932  G4PhysicsTable* dedxSub = em->IonisationTableForSubsec();
933  if (1 < listSub.size()) {
934  em->SetDEDXTable(dedxSub, fIsSubIonisation);
935  dedxSub = 0;
937  tableBuilder->BuildDEDXTable(dedxSub, listSub);
938  em->SetDEDXTable(dedxSub, fSubRestricted);
939  }
940  }
942  G4PhysicsTable* dedxCSDA = em->DEDXunRestrictedTable();
943  if (1 < n_dedx) {
944  dedxCSDA = nullptr;
945  dedxCSDA = G4PhysicsTableHelper::PreparePhysicsTable(dedxCSDA);
946  tableBuilder->BuildDEDXTable(dedxCSDA, listCSDA);
947  em->SetDEDXTable(dedxCSDA,fTotal);
948  }
949  G4PhysicsTable* rCSDA = em->CSDARangeTable();
950  if(!rCSDA) { rCSDA = G4PhysicsTableHelper::PreparePhysicsTable(rCSDA); }
951  tableBuilder->BuildRangeTable(dedxCSDA, rCSDA, true);
952  em->SetCSDARangeTable(rCSDA);
953  }
954 
955  if (1 < verbose) {
956  G4cout << "G4LossTableManager::BuildTables: Tables are built for "
957  << aParticle->GetParticleName()
958  << "; ionisation process: " << em->GetProcessName()
959  << " " << em
960  << G4endl;
961  }
962  return em;
963 }
964 
965 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
966 
968  const G4ParticleDefinition* aParticle)
969 {
971  ed << "Energy loss process not found for " << aParticle->GetParticleName()
972  << " !";
973  G4Exception("G4LossTableManager::ParticleHaveNoLoss", "em0001",
974  FatalException, ed);
975 }
976 
977 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
978 
980 {
981  verbose = val;
982 }
983 
984 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
985 
986 const std::vector<G4VEnergyLossProcess*>&
988 {
989  return loss_vector;
990 }
991 
992 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
993 
994 const std::vector<G4VEmProcess*>& G4LossTableManager::GetEmProcessVector()
995 {
996  return emp_vector;
997 }
998 
999 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1000 
1001 const std::vector<G4VMultipleScattering*>&
1003 {
1004  return msc_vector;
1005 }
1006 
1007 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1008 
1010 {
1011  return theParameters->GetEmSaturation();
1012 }
1013 
1014 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1015 
1017 {
1018  if(!emConfigurator) {
1020  }
1021  return emConfigurator;
1022 }
1023 
1024 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1025 
1027 {
1028  if(!emElectronIonPair) {
1030  }
1031  return emElectronIonPair;
1032 }
1033 
1034 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1035 
1037 {
1038  if(ptr && ptr != nielCalculator) {
1039  delete nielCalculator;
1040  nielCalculator = ptr;
1041  }
1042 }
1043 
1044 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1045 
1047 {
1048  if(!nielCalculator) {
1049  nielCalculator = new G4NIELCalculator(nullptr, verbose);
1050  }
1051  return nielCalculator;
1052 }
1053 
1054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1055 
1057 {
1058  if(atomDeexcitation != p) {
1059  delete atomDeexcitation;
1060  atomDeexcitation = p;
1061  }
1062 }
1063 
1064 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1065 
1067 {
1068  if(subcutProducer != p) {
1069  delete subcutProducer;
1070  subcutProducer = p;
1071  }
1072 }
1073 
1074 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1075 
1077 {
1078  G4String ss = "G4LossTableManager::" + tit;
1080  /*
1081  ed << "Parameter is out of range: " << val
1082  << " it will have no effect!\n" << " ## "
1083  << " nbins= " << nbinsLambda
1084  << " nbinsPerDecade= " << nbinsPerDecade
1085  << " Emin(keV)= " << minKinEnergy/keV
1086  << " Emax(GeV)= " << maxKinEnergy/GeV;
1087  */
1088  G4Exception(ss, "em0044", JustWarning, ed);
1089 }
1090 
1091 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo....
1092 
1094 {
1095  // Automatic generation of html documentation page for physics lists
1096  // List processes and models for the most important
1097  // particles in descending order of importance
1098  // NB. for model names with length > 18 characters the .rst file needs
1099  // to be edited by hand. Or modify G4EmModelManager::DumpModelList
1100 
1101  char* dirName = std::getenv("G4PhysListDocDir");
1102  char* physList = std::getenv("G4PhysListName");
1103  if (dirName && physList) {
1104  G4String physListName = G4String(physList);
1105  G4String pathName = G4String(dirName) + "/" + physListName + ".rst";
1106 
1107  std::ofstream outFile;
1108  outFile.open(pathName);
1109 
1110  outFile << physListName << G4endl;
1111  outFile << std::string(physListName.length(), '=') << G4endl;
1112 
1113  std::vector<G4ParticleDefinition*> particles {
1114  G4Gamma::Gamma(),
1120  };
1121 
1122  std::vector<G4VEmProcess*> emproc_vector = GetEmProcessVector();
1123  std::vector<G4VEnergyLossProcess*> enloss_vector =
1125  std::vector<G4VMultipleScattering*> mscat_vector =
1127 
1128  for (auto theParticle : particles) {
1129  outFile << G4endl << "**" << theParticle->GetParticleName()
1130  << "**" << G4endl << G4endl << " .. code-block:: none" << G4endl;
1131 
1132  G4ProcessManager* pm = theParticle->GetProcessManager();
1133  G4ProcessVector* pv = pm->GetProcessList();
1134  G4int plen = pm->GetProcessListLength();
1135 
1136  for (auto emproc : emproc_vector) {
1137  for (G4int i = 0; i < plen; ++i) {
1138  G4VProcess* proc = (*pv)[i];
1139  if (proc == emproc) {
1140  outFile << G4endl;
1141  proc->ProcessDescription(outFile);
1142  break;
1143  }
1144  }
1145  }
1146 
1147  for (auto mscproc : mscat_vector) {
1148  for (G4int i = 0; i < plen; ++i) {
1149  G4VProcess* proc = (*pv)[i];
1150  if (proc == mscproc) {
1151  outFile << G4endl;
1152  proc->ProcessDescription(outFile);
1153  break;
1154  }
1155  }
1156  }
1157 
1158  for (auto enlossproc : enloss_vector) {
1159  for (G4int i = 0; i < plen; ++i) {
1160  G4VProcess* proc = (*pv)[i];
1161  if (proc == enlossproc) {
1162  outFile << G4endl;
1163  proc->ProcessDescription(outFile);
1164  break;
1165  }
1166  }
1167  }
1168  }
1169  outFile.close();
1170  }
1171 }
1172 
1173 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo.....
1174