Geant4 9.6.0
Toolkit for the simulation of the passage of particles through matter
Loading...
Searching...
No Matches
G4EnergyLossTables.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//
27// $Id$
28//
29// -------------------------------------------------------------------
30// first version created by P.Urban , 06/04/1998
31// modifications + "precise" functions added by L.Urban , 27/05/98
32// modifications , TOF functions , 26/10/98, L.Urban
33// cache mechanism in order to gain time, 11/02/99, L.Urban
34// bug fixed , 12/04/99 , L.Urban
35// 10.11.99: moved from RWT hash dictionary to STL map, G.Barrand, M.Maire
36// 27.09.01 L.Urban , bug fixed (negative energy deposit)
37// 26.10.01 all static functions moved from .icc files (mma)
38// 15.01.03 Add interfaces required for "cut per region" (V.Ivanchenko)
39// 12.03.03 Add warnings to obsolete interfaces (V.Ivanchenko)
40// 10.04.03 Add call to G4LossTableManager is particle is not registered (V.Ivanchenko)
41//
42// -------------------------------------------------------------------
43
44#include "G4EnergyLossTables.hh"
45#include "G4SystemOfUnits.hh"
47#include "G4RegionStore.hh"
48#include "G4LossTableManager.hh"
49
50
51//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
52
53G4EnergyLossTablesHelper G4EnergyLossTables::t ;
54G4EnergyLossTablesHelper G4EnergyLossTables::null_loss ;
55const G4ParticleDefinition* G4EnergyLossTables::lastParticle = 0;
56G4double G4EnergyLossTables::QQPositron = eplus*eplus ;
57G4double G4EnergyLossTables::Chargesquare ;
58G4int G4EnergyLossTables::oldIndex = -1 ;
59G4double G4EnergyLossTables::rmin = 0. ;
60G4double G4EnergyLossTables::rmax = 0. ;
61G4double G4EnergyLossTables::Thigh = 0. ;
62G4int G4EnergyLossTables::let_counter = 0;
63G4int G4EnergyLossTables::let_max_num_warnings = 100;
64G4bool G4EnergyLossTables::first_loss = true;
65
66G4EnergyLossTables::helper_map G4EnergyLossTables::dict;
67
68//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
69
71 const G4PhysicsTable* aDEDXTable,
72 const G4PhysicsTable* aRangeTable,
73 const G4PhysicsTable* anInverseRangeTable,
74 const G4PhysicsTable* aLabTimeTable,
75 const G4PhysicsTable* aProperTimeTable,
76 G4double aLowestKineticEnergy,
77 G4double aHighestKineticEnergy,
78 G4double aMassRatio,
79 G4int aNumberOfBins)
80 :
81 theDEDXTable(aDEDXTable), theRangeTable(aRangeTable),
82 theInverseRangeTable(anInverseRangeTable),
83 theLabTimeTable(aLabTimeTable),
84 theProperTimeTable(aProperTimeTable),
85 theLowestKineticEnergy(aLowestKineticEnergy),
86 theHighestKineticEnergy(aHighestKineticEnergy),
87 theMassRatio(aMassRatio),
88 theNumberOfBins(aNumberOfBins)
89{ }
90
91//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
92
94{
95 theLowestKineticEnergy = 0.0;
96 theHighestKineticEnergy= 0.0;
97 theMassRatio = 0.0;
98 theNumberOfBins = 0;
99}
100
101//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
102
104 const G4ParticleDefinition* p,
105 const G4PhysicsTable* tDEDX,
106 const G4PhysicsTable* tRange,
107 const G4PhysicsTable* tInverseRange,
108 const G4PhysicsTable* tLabTime,
109 const G4PhysicsTable* tProperTime,
110 G4double lowestKineticEnergy,
111 G4double highestKineticEnergy,
112 G4double massRatio,
113 G4int NumberOfBins)
114{
115 dict[p]= G4EnergyLossTablesHelper(tDEDX, tRange,tInverseRange,
116 tLabTime,tProperTime,lowestKineticEnergy,
117 highestKineticEnergy, massRatio,NumberOfBins);
118
119 t = GetTables(p) ; // important for cache !!!!!
120 lastParticle = p ;
121 Chargesquare = (p->GetPDGCharge())*(p->GetPDGCharge())/
122 QQPositron ;
123 if (first_loss ) {
124 null_loss = G4EnergyLossTablesHelper(0, 0, 0, 0, 0, 0.0, 0.0, 0.0, 0);
125 first_loss = false;
126 }
127}
128
129//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
130
132 const G4ParticleDefinition* p)
133{
134 helper_map::iterator it;
135 if((it=dict.find(p))==dict.end()) return 0;
136 return (*it).second.theDEDXTable;
137}
138
139//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
140
142 const G4ParticleDefinition* p)
143{
144 helper_map::iterator it;
145 if((it=dict.find(p))==dict.end()) return 0;
146 return (*it).second.theRangeTable;
147}
148
149//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
150
152 const G4ParticleDefinition* p)
153{
154 helper_map::iterator it;
155 if((it=dict.find(p))==dict.end()) return 0;
156 return (*it).second.theInverseRangeTable;
157}
158
159//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
160
162 const G4ParticleDefinition* p)
163{
164 helper_map::iterator it;
165 if((it=dict.find(p))==dict.end()) return 0;
166 return (*it).second.theLabTimeTable;
167}
168
169//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
170
172 const G4ParticleDefinition* p)
173{
174 helper_map::iterator it;
175 if((it=dict.find(p))==dict.end()) return 0;
176 return (*it).second.theProperTimeTable;
177}
178
179//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
180
181G4EnergyLossTablesHelper G4EnergyLossTables::GetTables(
182 const G4ParticleDefinition* p)
183{
184 helper_map::iterator it;
185 if ((it=dict.find(p))==dict.end()) {
186// G4cout << "Table is not found out for " << p->GetParticleName() << G4endl;
187// G4Exception("G4EnergyLossTables::GetTables: table not found!");
188// exit(1);
189 return null_loss;
190 }
191 return (*it).second;
192}
193
194//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
195
197 const G4ParticleDefinition *aParticle,
198 G4double KineticEnergy,
199 const G4Material *aMaterial)
200{
201 CPRWarning();
202 if(aParticle != lastParticle)
203 {
204 t= GetTables(aParticle);
205 lastParticle = aParticle ;
206 Chargesquare = (aParticle->GetPDGCharge())*
207 (aParticle->GetPDGCharge())/
208 QQPositron ;
209 oldIndex = -1 ;
210 }
211 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
212 if (!dEdxTable) {
213 ParticleHaveNoLoss(aParticle,"dEdx");
214 return 0.0;
215 }
216
217 G4int materialIndex = aMaterial->GetIndex();
218 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
219 G4double dEdx;
220 G4bool isOut;
221
222 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
223
224 dEdx =(*dEdxTable)(materialIndex)->GetValue(
225 t.theLowestKineticEnergy,isOut)
226 *std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
227
228 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
229
230 dEdx = (*dEdxTable)(materialIndex)->GetValue(
231 t.theHighestKineticEnergy,isOut);
232
233 } else {
234
235 dEdx = (*dEdxTable)(materialIndex)->GetValue(
236 scaledKineticEnergy,isOut);
237
238 }
239
240 return dEdx*Chargesquare;
241}
242
243//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
244
246 const G4ParticleDefinition *aParticle,
247 G4double KineticEnergy,
248 const G4Material *aMaterial)
249{
250 CPRWarning();
251 if(aParticle != lastParticle)
252 {
253 t= GetTables(aParticle);
254 lastParticle = aParticle ;
255 oldIndex = -1 ;
256 }
257 const G4PhysicsTable* labtimeTable= t.theLabTimeTable;
258 if (!labtimeTable) {
259 ParticleHaveNoLoss(aParticle,"LabTime");
260 return 0.0;
261 }
262
263 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
264 G4int materialIndex = aMaterial->GetIndex();
265 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
266 G4double time;
267 G4bool isOut;
268
269 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
270
271 time = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
272 (*labtimeTable)(materialIndex)->GetValue(
273 t.theLowestKineticEnergy,isOut);
274
275
276 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
277
278 time = (*labtimeTable)(materialIndex)->GetValue(
279 t.theHighestKineticEnergy,isOut);
280
281 } else {
282
283 time = (*labtimeTable)(materialIndex)->GetValue(
284 scaledKineticEnergy,isOut);
285
286 }
287
288 return time/t.theMassRatio ;
289}
290
291//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
292
294 const G4ParticleDefinition *aParticle,
295 G4double KineticEnergyStart,
296 G4double KineticEnergyEnd,
297 const G4Material *aMaterial)
298{
299 CPRWarning();
300 if(aParticle != lastParticle)
301 {
302 t= GetTables(aParticle);
303 lastParticle = aParticle ;
304 oldIndex = -1 ;
305 }
306 const G4PhysicsTable* labtimeTable= t.theLabTimeTable;
307 if (!labtimeTable) {
308 ParticleHaveNoLoss(aParticle,"LabTime");
309 return 0.0;
310 }
311
312 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
313 const G4double dToverT = 0.05 , facT = 1. -dToverT ;
314 G4double timestart,timeend,deltatime,dTT;
315 G4bool isOut;
316
317 G4int materialIndex = aMaterial->GetIndex();
318 G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio;
319
320 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
321
322 timestart = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
323 (*labtimeTable)(materialIndex)->GetValue(
324 t.theLowestKineticEnergy,isOut);
325
326
327 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
328
329 timestart = (*labtimeTable)(materialIndex)->GetValue(
330 t.theHighestKineticEnergy,isOut);
331
332 } else {
333
334 timestart = (*labtimeTable)(materialIndex)->GetValue(
335 scaledKineticEnergy,isOut);
336
337 }
338
339 dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
340
341 if( dTT < dToverT )
342 scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
343 else
344 scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
345
346 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
347
348 timeend = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
349 (*labtimeTable)(materialIndex)->GetValue(
350 t.theLowestKineticEnergy,isOut);
351
352
353 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
354
355 timeend = (*labtimeTable)(materialIndex)->GetValue(
356 t.theHighestKineticEnergy,isOut);
357
358 } else {
359
360 timeend = (*labtimeTable)(materialIndex)->GetValue(
361 scaledKineticEnergy,isOut);
362
363 }
364
365 deltatime = timestart - timeend ;
366
367 if( dTT < dToverT )
368 deltatime *= dTT/dToverT;
369
370 return deltatime/t.theMassRatio ;
371}
372
373//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
374
376 const G4ParticleDefinition *aParticle,
377 G4double KineticEnergy,
378 const G4Material *aMaterial)
379{
380 CPRWarning();
381 if(aParticle != lastParticle)
382 {
383 t= GetTables(aParticle);
384 lastParticle = aParticle ;
385 oldIndex = -1 ;
386 }
387 const G4PhysicsTable* propertimeTable= t.theProperTimeTable;
388 if (!propertimeTable) {
389 ParticleHaveNoLoss(aParticle,"ProperTime");
390 return 0.0;
391 }
392
393 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
394 G4int materialIndex = aMaterial->GetIndex();
395 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
396 G4double time;
397 G4bool isOut;
398
399 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
400
401 time = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
402 (*propertimeTable)(materialIndex)->GetValue(
403 t.theLowestKineticEnergy,isOut);
404
405
406 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
407
408 time = (*propertimeTable)(materialIndex)->GetValue(
409 t.theHighestKineticEnergy,isOut);
410
411 } else {
412
413 time = (*propertimeTable)(materialIndex)->GetValue(
414 scaledKineticEnergy,isOut);
415
416 }
417
418 return time/t.theMassRatio ;
419}
420
421//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
422
424 const G4ParticleDefinition *aParticle,
425 G4double KineticEnergyStart,
426 G4double KineticEnergyEnd,
427 const G4Material *aMaterial)
428{
429 CPRWarning();
430 if(aParticle != lastParticle)
431 {
432 t= GetTables(aParticle);
433 lastParticle = aParticle ;
434 oldIndex = -1 ;
435 }
436 const G4PhysicsTable* propertimeTable= t.theProperTimeTable;
437 if (!propertimeTable) {
438 ParticleHaveNoLoss(aParticle,"ProperTime");
439 return 0.0;
440 }
441
442 const G4double parlowen=0.4 , ppar=0.5-parlowen ;
443 const G4double dToverT = 0.05 , facT = 1. -dToverT ;
444 G4double timestart,timeend,deltatime,dTT;
445 G4bool isOut;
446
447 G4int materialIndex = aMaterial->GetIndex();
448 G4double scaledKineticEnergy = KineticEnergyStart*t.theMassRatio;
449
450 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
451
452 timestart = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
453 (*propertimeTable)(materialIndex)->GetValue(
454 t.theLowestKineticEnergy,isOut);
455
456
457 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
458
459 timestart = (*propertimeTable)(materialIndex)->GetValue(
460 t.theHighestKineticEnergy,isOut);
461
462 } else {
463
464 timestart = (*propertimeTable)(materialIndex)->GetValue(
465 scaledKineticEnergy,isOut);
466
467 }
468
469 dTT = (KineticEnergyStart - KineticEnergyEnd)/KineticEnergyStart ;
470
471 if( dTT < dToverT )
472 scaledKineticEnergy = facT*KineticEnergyStart*t.theMassRatio;
473 else
474 scaledKineticEnergy = KineticEnergyEnd*t.theMassRatio;
475
476 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
477
478 timeend = std::exp(ppar*std::log(scaledKineticEnergy/t.theLowestKineticEnergy))*
479 (*propertimeTable)(materialIndex)->GetValue(
480 t.theLowestKineticEnergy,isOut);
481
482
483 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
484
485 timeend = (*propertimeTable)(materialIndex)->GetValue(
486 t.theHighestKineticEnergy,isOut);
487
488 } else {
489
490 timeend = (*propertimeTable)(materialIndex)->GetValue(
491 scaledKineticEnergy,isOut);
492
493 }
494
495 deltatime = timestart - timeend ;
496
497 if( dTT < dToverT )
498 deltatime *= dTT/dToverT ;
499
500 return deltatime/t.theMassRatio ;
501}
502
503//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
504
506 const G4ParticleDefinition *aParticle,
507 G4double KineticEnergy,
508 const G4Material *aMaterial)
509{
510 CPRWarning();
511 if(aParticle != lastParticle)
512 {
513 t= GetTables(aParticle);
514 lastParticle = aParticle ;
515 Chargesquare = (aParticle->GetPDGCharge())*
516 (aParticle->GetPDGCharge())/
517 QQPositron ;
518 oldIndex = -1 ;
519 }
520 const G4PhysicsTable* rangeTable= t.theRangeTable;
521 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
522 if (!rangeTable) {
523 ParticleHaveNoLoss(aParticle,"Range");
524 return 0.0;
525 }
526
527 G4int materialIndex = aMaterial->GetIndex();
528 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
529 G4double Range;
530 G4bool isOut;
531
532 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
533
534 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
535 (*rangeTable)(materialIndex)->GetValue(
536 t.theLowestKineticEnergy,isOut);
537
538 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
539
540 Range = (*rangeTable)(materialIndex)->GetValue(
541 t.theHighestKineticEnergy,isOut)+
542 (scaledKineticEnergy-t.theHighestKineticEnergy)/
543 (*dEdxTable)(materialIndex)->GetValue(
544 t.theHighestKineticEnergy,isOut);
545
546 } else {
547
548 Range = (*rangeTable)(materialIndex)->GetValue(
549 scaledKineticEnergy,isOut);
550
551 }
552
553 return Range/(Chargesquare*t.theMassRatio);
554}
555
556//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
557
559 const G4ParticleDefinition *aParticle,
560 G4double range,
561 const G4Material *aMaterial)
562// it returns the value of the kinetic energy for a given range
563{
564 CPRWarning();
565 if( aParticle != lastParticle)
566 {
567 t= GetTables(aParticle);
568 lastParticle = aParticle;
569 Chargesquare = (aParticle->GetPDGCharge())*
570 (aParticle->GetPDGCharge())/
571 QQPositron ;
572 oldIndex = -1 ;
573 }
574 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
575 const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable;
576 if (!inverseRangeTable) {
577 ParticleHaveNoLoss(aParticle,"InverseRange");
578 return 0.0;
579 }
580
581 G4double scaledrange,scaledKineticEnergy ;
582 G4bool isOut ;
583
584 G4int materialIndex = aMaterial->GetIndex() ;
585
586 if(materialIndex != oldIndex)
587 {
588 oldIndex = materialIndex ;
589 rmin = (*inverseRangeTable)(materialIndex)->
590 GetLowEdgeEnergy(0) ;
591 rmax = (*inverseRangeTable)(materialIndex)->
592 GetLowEdgeEnergy(t.theNumberOfBins-2) ;
593 Thigh = (*inverseRangeTable)(materialIndex)->
594 GetValue(rmax,isOut) ;
595 }
596
597 scaledrange = range*Chargesquare*t.theMassRatio ;
598
599 if(scaledrange < rmin)
600 {
601 scaledKineticEnergy = t.theLowestKineticEnergy*
602 scaledrange*scaledrange/(rmin*rmin) ;
603 }
604 else
605 {
606 if(scaledrange < rmax)
607 {
608 scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
609 GetValue( scaledrange,isOut) ;
610 }
611 else
612 {
613 scaledKineticEnergy = Thigh +
614 (scaledrange-rmax)*
615 (*dEdxTable)(materialIndex)->
616 GetValue(Thigh,isOut) ;
617 }
618 }
619
620 return scaledKineticEnergy/t.theMassRatio ;
621}
622
623//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
624
626 const G4ParticleDefinition *aParticle,
627 G4double KineticEnergy,
628 const G4Material *aMaterial)
629{
630 CPRWarning();
631 if( aParticle != lastParticle)
632 {
633 t= GetTables(aParticle);
634 lastParticle = aParticle;
635 Chargesquare = (aParticle->GetPDGCharge())*
636 (aParticle->GetPDGCharge())/
637 QQPositron ;
638 oldIndex = -1 ;
639 }
640 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
641 if (!dEdxTable) {
642 ParticleHaveNoLoss(aParticle,"dEdx");
643 return 0.0;
644 }
645
646 G4int materialIndex = aMaterial->GetIndex();
647 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
648 G4double dEdx;
649 G4bool isOut;
650
651 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
652
653 dEdx = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
654 *(*dEdxTable)(materialIndex)->GetValue(
655 t.theLowestKineticEnergy,isOut);
656
657 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
658
659 dEdx = (*dEdxTable)(materialIndex)->GetValue(
660 t.theHighestKineticEnergy,isOut);
661
662 } else {
663
664 dEdx = (*dEdxTable)(materialIndex)->GetValue(
665 scaledKineticEnergy,isOut) ;
666
667 }
668
669 return dEdx*Chargesquare;
670}
671
672//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
673
675 const G4ParticleDefinition *aParticle,
676 G4double KineticEnergy,
677 const G4Material *aMaterial)
678{
679 CPRWarning();
680 if( aParticle != lastParticle)
681 {
682 t= GetTables(aParticle);
683 lastParticle = aParticle;
684 Chargesquare = (aParticle->GetPDGCharge())*
685 (aParticle->GetPDGCharge())/
686 QQPositron ;
687 oldIndex = -1 ;
688 }
689 const G4PhysicsTable* rangeTable= t.theRangeTable;
690 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
691 if (!rangeTable) {
692 ParticleHaveNoLoss(aParticle,"Range");
693 return 0.0;
694 }
695 G4int materialIndex = aMaterial->GetIndex();
696
697 G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
698 (*rangeTable)(materialIndex)->
699 GetLowEdgeEnergy(1) ;
700
701 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
702 G4double Range;
703 G4bool isOut;
704
705 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
706
707 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
708 (*rangeTable)(materialIndex)->GetValue(
709 t.theLowestKineticEnergy,isOut);
710
711 } else if (scaledKineticEnergy>Thighr) {
712
713 Range = (*rangeTable)(materialIndex)->GetValue(
714 Thighr,isOut)+
715 (scaledKineticEnergy-Thighr)/
716 (*dEdxTable)(materialIndex)->GetValue(
717 Thighr,isOut);
718
719 } else {
720
721 Range = (*rangeTable)(materialIndex)->GetValue(
722 scaledKineticEnergy,isOut) ;
723
724 }
725
726 return Range/(Chargesquare*t.theMassRatio);
727}
728
729//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
730
732 const G4ParticleDefinition *aParticle,
733 G4double KineticEnergy,
734 const G4MaterialCutsCouple *couple,
735 G4bool check)
736{
737 if(aParticle != lastParticle)
738 {
739 t= GetTables(aParticle);
740 lastParticle = aParticle ;
741 Chargesquare = (aParticle->GetPDGCharge())*
742 (aParticle->GetPDGCharge())/
743 QQPositron ;
744 oldIndex = -1 ;
745 }
746 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
747
748 if (!dEdxTable ) {
749 if (check) return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
750 else ParticleHaveNoLoss(aParticle, "dEdx");
751 return 0.0;
752 }
753
754 G4int materialIndex = couple->GetIndex();
755 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
756 G4double dEdx;
757 G4bool isOut;
758
759 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
760
761 dEdx =(*dEdxTable)(materialIndex)->GetValue(
762 t.theLowestKineticEnergy,isOut)
763 *std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy);
764
765 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
766
767 dEdx = (*dEdxTable)(materialIndex)->GetValue(
768 t.theHighestKineticEnergy,isOut);
769
770 } else {
771
772 dEdx = (*dEdxTable)(materialIndex)->GetValue(
773 scaledKineticEnergy,isOut);
774
775 }
776
777 return dEdx*Chargesquare;
778}
779
780//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
781
783 const G4ParticleDefinition *aParticle,
784 G4double KineticEnergy,
785 const G4MaterialCutsCouple *couple,
786 G4bool check)
787{
788 if(aParticle != lastParticle)
789 {
790 t= GetTables(aParticle);
791 lastParticle = aParticle ;
792 Chargesquare = (aParticle->GetPDGCharge())*
793 (aParticle->GetPDGCharge())/
794 QQPositron ;
795 oldIndex = -1 ;
796 }
797 const G4PhysicsTable* rangeTable= t.theRangeTable;
798 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
799 if (!rangeTable) {
800 if(check) return G4LossTableManager::Instance()->GetRange(aParticle,KineticEnergy,couple);
801 else return DBL_MAX;
802 //ParticleHaveNoLoss(aParticle,"Range");
803 }
804
805 G4int materialIndex = couple->GetIndex();
806 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
807 G4double Range;
808 G4bool isOut;
809
810 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
811
812 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
813 (*rangeTable)(materialIndex)->GetValue(
814 t.theLowestKineticEnergy,isOut);
815
816 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
817
818 Range = (*rangeTable)(materialIndex)->GetValue(
819 t.theHighestKineticEnergy,isOut)+
820 (scaledKineticEnergy-t.theHighestKineticEnergy)/
821 (*dEdxTable)(materialIndex)->GetValue(
822 t.theHighestKineticEnergy,isOut);
823
824 } else {
825
826 Range = (*rangeTable)(materialIndex)->GetValue(
827 scaledKineticEnergy,isOut);
828
829 }
830
831 return Range/(Chargesquare*t.theMassRatio);
832}
833
834//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
835
837 const G4ParticleDefinition *aParticle,
838 G4double range,
839 const G4MaterialCutsCouple *couple,
840 G4bool check)
841// it returns the value of the kinetic energy for a given range
842{
843 if( aParticle != lastParticle)
844 {
845 t= GetTables(aParticle);
846 lastParticle = aParticle;
847 Chargesquare = (aParticle->GetPDGCharge())*
848 (aParticle->GetPDGCharge())/
849 QQPositron ;
850 oldIndex = -1 ;
851 }
852 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
853 const G4PhysicsTable* inverseRangeTable= t.theInverseRangeTable;
854
855 if (!inverseRangeTable) {
856 if(check) return G4LossTableManager::Instance()->GetEnergy(aParticle,range,couple);
857 else return DBL_MAX;
858 // else ParticleHaveNoLoss(aParticle,"InverseRange");
859 }
860
861 G4double scaledrange,scaledKineticEnergy ;
862 G4bool isOut ;
863
864 G4int materialIndex = couple->GetIndex() ;
865
866 if(materialIndex != oldIndex)
867 {
868 oldIndex = materialIndex ;
869 rmin = (*inverseRangeTable)(materialIndex)->
870 GetLowEdgeEnergy(0) ;
871 rmax = (*inverseRangeTable)(materialIndex)->
872 GetLowEdgeEnergy(t.theNumberOfBins-2) ;
873 Thigh = (*inverseRangeTable)(materialIndex)->
874 GetValue(rmax,isOut) ;
875 }
876
877 scaledrange = range*Chargesquare*t.theMassRatio ;
878
879 if(scaledrange < rmin)
880 {
881 scaledKineticEnergy = t.theLowestKineticEnergy*
882 scaledrange*scaledrange/(rmin*rmin) ;
883 }
884 else
885 {
886 if(scaledrange < rmax)
887 {
888 scaledKineticEnergy = (*inverseRangeTable)(materialIndex)->
889 GetValue( scaledrange,isOut) ;
890 }
891 else
892 {
893 scaledKineticEnergy = Thigh +
894 (scaledrange-rmax)*
895 (*dEdxTable)(materialIndex)->
896 GetValue(Thigh,isOut) ;
897 }
898 }
899
900 return scaledKineticEnergy/t.theMassRatio ;
901}
902
903//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
904
906 const G4ParticleDefinition *aParticle,
907 G4double KineticEnergy,
908 const G4MaterialCutsCouple *couple)
909{
910
911 if( aParticle != lastParticle)
912 {
913 t= GetTables(aParticle);
914 lastParticle = aParticle;
915 Chargesquare = (aParticle->GetPDGCharge())*
916 (aParticle->GetPDGCharge())/
917 QQPositron ;
918 oldIndex = -1 ;
919 }
920 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
921 if ( !dEdxTable )
922 return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
923
924 G4int materialIndex = couple->GetIndex();
925 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
926 G4double dEdx;
927 G4bool isOut;
928
929 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
930
931 dEdx = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)
932 *(*dEdxTable)(materialIndex)->GetValue(
933 t.theLowestKineticEnergy,isOut);
934
935 } else if (scaledKineticEnergy>t.theHighestKineticEnergy) {
936
937 dEdx = (*dEdxTable)(materialIndex)->GetValue(
938 t.theHighestKineticEnergy,isOut);
939
940 } else {
941
942 dEdx = (*dEdxTable)(materialIndex)->GetValue(
943 scaledKineticEnergy,isOut) ;
944
945 }
946
947 return dEdx*Chargesquare;
948}
949
950//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
951
953 const G4ParticleDefinition *aParticle,
954 G4double KineticEnergy,
955 const G4MaterialCutsCouple *couple)
956{
957 if( aParticle != lastParticle)
958 {
959 t= GetTables(aParticle);
960 lastParticle = aParticle;
961 Chargesquare = (aParticle->GetPDGCharge())*
962 (aParticle->GetPDGCharge())/
963 QQPositron ;
964 oldIndex = -1 ;
965 }
966 const G4PhysicsTable* rangeTable= t.theRangeTable;
967 const G4PhysicsTable* dEdxTable= t.theDEDXTable;
968 if ( !dEdxTable || !rangeTable)
969 return G4LossTableManager::Instance()->GetDEDX(aParticle,KineticEnergy,couple);
970
971 G4int materialIndex = couple->GetIndex();
972
973 G4double Thighr = t.theHighestKineticEnergy*t.theLowestKineticEnergy/
974 (*rangeTable)(materialIndex)->
975 GetLowEdgeEnergy(1) ;
976
977 G4double scaledKineticEnergy = KineticEnergy*t.theMassRatio;
978 G4double Range;
979 G4bool isOut;
980
981 if (scaledKineticEnergy<t.theLowestKineticEnergy) {
982
983 Range = std::sqrt(scaledKineticEnergy/t.theLowestKineticEnergy)*
984 (*rangeTable)(materialIndex)->GetValue(
985 t.theLowestKineticEnergy,isOut);
986
987 } else if (scaledKineticEnergy>Thighr) {
988
989 Range = (*rangeTable)(materialIndex)->GetValue(
990 Thighr,isOut)+
991 (scaledKineticEnergy-Thighr)/
992 (*dEdxTable)(materialIndex)->GetValue(
993 Thighr,isOut);
994
995 } else {
996
997 Range = (*rangeTable)(materialIndex)->GetValue(
998 scaledKineticEnergy,isOut) ;
999
1000 }
1001
1002 return Range/(Chargesquare*t.theMassRatio);
1003}
1004
1005//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1006
1007void G4EnergyLossTables::CPRWarning()
1008{
1009 if (let_counter < let_max_num_warnings) {
1010
1011 G4cout << G4endl;
1012 G4cout << "##### G4EnergyLossTable WARNING: The obsolete interface is used!" << G4endl;
1013 G4cout << "##### RESULTS ARE NOT GARANTEED!" << G4endl;
1014 G4cout << "##### Please, substitute G4Material by G4MaterialCutsCouple" << G4endl;
1015 G4cout << "##### Obsolete interface will be removed soon" << G4endl;
1016 G4cout << G4endl;
1017 let_counter++;
1018// if ((G4RegionStore::GetInstance())->size() > 1) {
1019// G4Exception("G4EnergyLossTables:: More than 1 region - table can't be accessed with obsolete interface");
1020// exit(1);
1021// }
1022
1023 } else if (let_counter == let_max_num_warnings) {
1024
1025 G4cout << "##### G4EnergyLossTable WARNING closed" << G4endl;
1026 let_counter++;
1027 }
1028}
1029
1030//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
1031
1032void
1033G4EnergyLossTables::ParticleHaveNoLoss(const G4ParticleDefinition*,
1034 const G4String& /*q*/)
1035{
1036 //G4String s = " " + q + " table not found for "
1037 // + aParticle->GetParticleName() + " !";
1038 //G4Exception("G4EnergyLossTables::ParticleHaveNoLoss", "EM01",
1039 // FatalException, s);
1040}
1041
1042//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
double G4double
Definition: G4Types.hh:64
int G4int
Definition: G4Types.hh:66
bool G4bool
Definition: G4Types.hh:67
#define G4endl
Definition: G4ios.hh:52
G4DLLIMPORT std::ostream G4cout
static G4double GetRange(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static const G4PhysicsTable * GetLabTimeTable(const G4ParticleDefinition *p)
static void Register(const G4ParticleDefinition *p, const G4PhysicsTable *tDEDX, const G4PhysicsTable *tRange, const G4PhysicsTable *tInverseRange, const G4PhysicsTable *tLabTime, const G4PhysicsTable *tProperTime, G4double lowestKineticEnergy, G4double highestKineticEnergy, G4double massRatio, G4int NumberOfBins)
static G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetDeltaProperTime(const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, const G4Material *aMaterial)
static G4double GetLabTime(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetPreciseDEDX(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetPreciseEnergyFromRange(const G4ParticleDefinition *aParticle, G4double range, const G4Material *aMaterial)
static const G4PhysicsTable * GetDEDXTable(const G4ParticleDefinition *p)
static const G4PhysicsTable * GetRangeTable(const G4ParticleDefinition *p)
static const G4PhysicsTable * GetInverseRangeTable(const G4ParticleDefinition *p)
static G4double GetDeltaLabTime(const G4ParticleDefinition *aParticle, G4double KineticEnergyStart, G4double KineticEnergyEnd, const G4Material *aMaterial)
static G4double GetPreciseRangeFromEnergy(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static G4double GetProperTime(const G4ParticleDefinition *aParticle, G4double KineticEnergy, const G4Material *aMaterial)
static const G4PhysicsTable * GetProperTimeTable(const G4ParticleDefinition *p)
static G4LossTableManager * Instance()
G4double GetEnergy(const G4ParticleDefinition *aParticle, G4double range, const G4MaterialCutsCouple *couple)
G4double GetRange(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
G4double GetDEDX(const G4ParticleDefinition *aParticle, G4double kineticEnergy, const G4MaterialCutsCouple *couple)
size_t GetIndex() const
Definition: G4Material.hh:261
G4double GetPDGCharge() const
#define DBL_MAX
Definition: templates.hh:83