Geant4 11.1.1
Toolkit for the simulation of the passage of particles through matter
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Pages
G4Scintillation.cc
Go to the documentation of this file.
1// ********************************************************************
2// * License and Disclaimer *
3// * *
4// * The Geant4 software is copyright of the Copyright Holders of *
5// * the Geant4 Collaboration. It is provided under the terms and *
6// * conditions of the Geant4 Software License, included in the file *
7// * LICENSE and available at http://cern.ch/geant4/license . These *
8// * include a list of copyright holders. *
9// * *
10// * Neither the authors of this software system, nor their employing *
11// * institutes,nor the agencies providing financial support for this *
12// * work make any representation or warranty, express or implied, *
13// * regarding this software system or assume any liability for its *
14// * use. Please see the license in the file LICENSE and URL above *
15// * for the full disclaimer and the limitation of liability. *
16// * *
17// * This code implementation is the result of the scientific and *
18// * technical work of the GEANT4 collaboration. *
19// * By using, copying, modifying or distributing the software (or *
20// * any work based on the software) you agree to acknowledge its *
21// * use in resulting scientific publications, and indicate your *
22// * acceptance of all terms of the Geant4 Software license. *
23// ********************************************************************
24//
25////////////////////////////////////////////////////////////////////////
26// Scintillation Light Class Implementation
27////////////////////////////////////////////////////////////////////////
28//
29// File: G4Scintillation.cc
30// Description: RestDiscrete Process - Generation of Scintillation Photons
31// Version: 1.0
32// Created: 1998-11-07
33// Author: Peter Gumplinger
34// Updated: 2010-10-20 Allow the scintillation yield to be a function
35// of energy deposited by particle type
36// Thanks to Zach Hartwig (Department of Nuclear
37// Science and Engineeering - MIT)
38// 2010-09-22 by Peter Gumplinger
39// > scintillation rise time included, thanks to
40// > Martin Goettlich/DESY
41// 2005-08-17 by Peter Gumplinger
42// > change variable name MeanNumPhotons -> MeanNumberOfPhotons
43// 2005-07-28 by Peter Gumplinger
44// > add G4ProcessType to constructor
45// 2004-08-05 by Peter Gumplinger
46// > changed StronglyForced back to Forced in GetMeanLifeTime
47// 2002-11-21 by Peter Gumplinger
48// > change to use G4Poisson for small MeanNumberOfPhotons
49// 2002-11-07 by Peter Gumplinger
50// > now allow for fast and slow scintillation component
51// 2002-11-05 by Peter Gumplinger
52// > now use scintillation constants from G4Material
53// 2002-05-09 by Peter Gumplinger
54// > use only the PostStepPoint location for the origin of
55// scintillation photons when energy is lost to the medium
56// by a neutral particle
57// 2000-09-18 by Peter Gumplinger
58// > change: aSecondaryPosition=x0+rand*aStep.GetDeltaPosition();
59// aSecondaryTrack->SetTouchable(0);
60// 2001-09-17, migration of Materials to pure STL (mma)
61// 2003-06-03, V.Ivanchenko fix compilation warnings
62//
63////////////////////////////////////////////////////////////////////////
64
65#include "G4Scintillation.hh"
66
67#include "globals.hh"
68#include "G4DynamicParticle.hh"
69#include "G4EmProcessSubType.hh"
70#include "G4Material.hh"
74#include "G4ParticleMomentum.hh"
75#include "G4ParticleTypes.hh"
78#include "G4PhysicsTable.hh"
79#include "G4Poisson.hh"
81#include "G4StepPoint.hh"
82#include "G4SystemOfUnits.hh"
83#include "G4ThreeVector.hh"
84#include "Randomize.hh"
86
87//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
89 G4ProcessType type)
90 : G4VRestDiscreteProcess(processName, type)
91 , fIntegralTable1(nullptr)
92 , fIntegralTable2(nullptr)
93 , fIntegralTable3(nullptr)
94 , fEmSaturation(nullptr)
95 , fNumPhotons(0)
96{
97 secID = G4PhysicsModelCatalog::GetModelID("model_Scintillation");
99
100#ifdef G4DEBUG_SCINTILLATION
101 ScintTrackEDep = 0.;
102 ScintTrackYield = 0.;
103#endif
104
105 if(verboseLevel > 0)
106 {
107 G4cout << GetProcessName() << " is created " << G4endl;
108 }
109 Initialise();
110}
111
112//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
114{
115 if(fIntegralTable1 != nullptr)
116 {
117 fIntegralTable1->clearAndDestroy();
118 delete fIntegralTable1;
119 }
120 if(fIntegralTable2 != nullptr)
121 {
122 fIntegralTable2->clearAndDestroy();
123 delete fIntegralTable2;
124 }
125 if(fIntegralTable3 != nullptr)
126 {
127 fIntegralTable3->clearAndDestroy();
128 delete fIntegralTable3;
129 }
130}
131
132//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
133void G4Scintillation::ProcessDescription(std::ostream& out) const
134{
135 out << "Scintillation simulates production of optical photons produced\n"
136 "by a high energy particle traversing matter.\n"
137 "Various material properties need to be defined.\n";
139
141 out << "Track secondaries first: " << params->GetScintTrackSecondariesFirst();
142 out << "Finite rise time: " << params->GetScintFiniteRiseTime();
143 out << "Scintillation by particle type: " << params->GetScintByParticleType();
144 out << "Save track information: " << params->GetScintTrackInfo();
145 out << "Stack photons: " << params->GetScintStackPhotons();
146 out << "Verbose level: " << params->GetScintVerboseLevel();
147}
148
149//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
151{
152 if(aParticleType.GetParticleName() == "opticalphoton")
153 return false;
154 if(aParticleType.IsShortLived())
155 return false;
156 return true;
157}
158
159//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
161{
162 Initialise();
163}
164
165//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
167{
175}
176
177//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
179{
180 if(fIntegralTable1 != nullptr)
181 {
182 fIntegralTable1->clearAndDestroy();
183 delete fIntegralTable1;
184 fIntegralTable1 = nullptr;
185 }
186 if(fIntegralTable2 != nullptr)
187 {
188 fIntegralTable2->clearAndDestroy();
189 delete fIntegralTable2;
190 fIntegralTable2 = nullptr;
191 }
192 if(fIntegralTable3 != nullptr)
193 {
194 fIntegralTable3->clearAndDestroy();
195 delete fIntegralTable3;
196 fIntegralTable3 = nullptr;
197 }
198
199 const G4MaterialTable* materialTable = G4Material::GetMaterialTable();
200 std::size_t numOfMaterials = G4Material::GetNumberOfMaterials();
201
202 // create new physics table
203 if(!fIntegralTable1)
204 fIntegralTable1 = new G4PhysicsTable(numOfMaterials);
205 if(!fIntegralTable2)
206 fIntegralTable2 = new G4PhysicsTable(numOfMaterials);
207 if(!fIntegralTable3)
208 fIntegralTable3 = new G4PhysicsTable(numOfMaterials);
209
210 for(std::size_t i = 0; i < numOfMaterials; ++i)
211 {
212 auto vector1 = new G4PhysicsFreeVector();
213 auto vector2 = new G4PhysicsFreeVector();
214 auto vector3 = new G4PhysicsFreeVector();
215
216 // Retrieve vector of scintillation wavelength intensity for
217 // the material from the material's optical properties table.
219 ((*materialTable)[i])->GetMaterialPropertiesTable();
220
221 if(MPT)
222 {
225 if(MPV)
226 {
227 // Retrieve the first intensity point in vector
228 // of (photon energy, intensity) pairs
229 G4double currentIN = (*MPV)[0];
230 if(currentIN >= 0.0)
231 {
232 // Create first (photon energy, Scintillation Integral pair
233 G4double currentPM = MPV->Energy(0);
234 G4double currentCII = 0.0;
235 vector1->InsertValues(currentPM, currentCII);
236
237 // Set previous values to current ones prior to loop
238 G4double prevPM = currentPM;
239 G4double prevCII = currentCII;
240 G4double prevIN = currentIN;
241
242 // loop over all (photon energy, intensity)
243 // pairs stored for this material
244 for(std::size_t ii = 1; ii < MPV->GetVectorLength(); ++ii)
245 {
246 currentPM = MPV->Energy(ii);
247 currentIN = (*MPV)[ii];
248 currentCII =
249 prevCII + 0.5 * (currentPM - prevPM) * (prevIN + currentIN);
250
251 vector1->InsertValues(currentPM, currentCII);
252
253 prevPM = currentPM;
254 prevCII = currentCII;
255 prevIN = currentIN;
256 }
257 }
258 }
259
261 if(MPV)
262 {
263 // Retrieve the first intensity point in vector
264 // of (photon energy, intensity) pairs
265 G4double currentIN = (*MPV)[0];
266 if(currentIN >= 0.0)
267 {
268 // Create first (photon energy, Scintillation Integral pair
269 G4double currentPM = MPV->Energy(0);
270 G4double currentCII = 0.0;
271 vector2->InsertValues(currentPM, currentCII);
272
273 // Set previous values to current ones prior to loop
274 G4double prevPM = currentPM;
275 G4double prevCII = currentCII;
276 G4double prevIN = currentIN;
277
278 // loop over all (photon energy, intensity)
279 // pairs stored for this material
280 for(std::size_t ii = 1; ii < MPV->GetVectorLength(); ++ii)
281 {
282 currentPM = MPV->Energy(ii);
283 currentIN = (*MPV)[ii];
284 currentCII =
285 prevCII + 0.5 * (currentPM - prevPM) * (prevIN + currentIN);
286
287 vector2->InsertValues(currentPM, currentCII);
288
289 prevPM = currentPM;
290 prevCII = currentCII;
291 prevIN = currentIN;
292 }
293 }
294 }
296 if(MPV)
297 {
298 // Retrieve the first intensity point in vector
299 // of (photon energy, intensity) pairs
300 G4double currentIN = (*MPV)[0];
301 if(currentIN >= 0.0)
302 {
303 // Create first (photon energy, Scintillation Integral pair
304 G4double currentPM = MPV->Energy(0);
305 G4double currentCII = 0.0;
306 vector3->InsertValues(currentPM, currentCII);
307
308 // Set previous values to current ones prior to loop
309 G4double prevPM = currentPM;
310 G4double prevCII = currentCII;
311 G4double prevIN = currentIN;
312
313 // loop over all (photon energy, intensity)
314 // pairs stored for this material
315 for(std::size_t ii = 1; ii < MPV->GetVectorLength(); ++ii)
316 {
317 currentPM = MPV->Energy(ii);
318 currentIN = (*MPV)[ii];
319 currentCII =
320 prevCII + 0.5 * (currentPM - prevPM) * (prevIN + currentIN);
321
322 vector3->InsertValues(currentPM, currentCII);
323
324 prevPM = currentPM;
325 prevCII = currentCII;
326 prevIN = currentIN;
327 }
328 }
329 }
330 }
331 fIntegralTable1->insertAt(i, vector1);
332 fIntegralTable2->insertAt(i, vector2);
333 fIntegralTable3->insertAt(i, vector3);
334 }
335}
336
337//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
339 const G4Step& aStep)
340// This routine simply calls the equivalent PostStepDoIt since all the
341// necessary information resides in aStep.GetTotalEnergyDeposit()
342{
343 return G4Scintillation::PostStepDoIt(aTrack, aStep);
344}
345
346//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
348 const G4Step& aStep)
349// This routine is called for each tracking step of a charged particle
350// in a scintillator. A Poisson/Gauss-distributed number of photons is
351// generated according to the scintillation yield formula, distributed
352// evenly along the track segment and uniformly into 4pi.
353{
355 fNumPhotons = 0;
356
357 const G4DynamicParticle* aParticle = aTrack.GetDynamicParticle();
358 const G4Material* aMaterial = aTrack.GetMaterial();
359
360 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint();
361 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint();
362
363 G4ThreeVector x0 = pPreStepPoint->GetPosition();
364 G4ThreeVector p0 = aStep.GetDeltaPosition().unit();
365 G4double t0 = pPreStepPoint->GetGlobalTime();
366
367 G4double TotalEnergyDeposit = aStep.GetTotalEnergyDeposit();
368
370 if(!MPT)
371 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
372
373 G4int N_timeconstants = 1;
374
376 N_timeconstants = 3;
378 N_timeconstants = 2;
379 else if(!(MPT->GetProperty(kSCINTILLATIONCOMPONENT1)))
380 {
381 // no components were specified
382 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
383 }
384
385 G4double ResolutionScale = MPT->GetConstProperty(kRESOLUTIONSCALE);
386 G4double MeanNumberOfPhotons;
387
388 G4double yield1 = 0.;
389 G4double yield2 = 0.;
390 G4double yield3 = 0.;
391 G4double sum_yields = 0.;
392
393 if(fScintillationByParticleType)
394 {
395 MeanNumberOfPhotons = GetScintillationYieldByParticleType(
396 aTrack, aStep, yield1, yield2, yield3);
397 }
398 else
399 {
402 : 1.;
405 : 0.;
408 : 0.;
409 // The default linear scintillation process
410 // Units: [# scintillation photons / MeV]
411 MeanNumberOfPhotons = MPT->GetConstProperty(kSCINTILLATIONYIELD);
412 // Birk's correction via fEmSaturation and specifying scintillation by
413 // by particle type are physically mutually exclusive
414 if(fEmSaturation)
415 MeanNumberOfPhotons *=
416 (fEmSaturation->VisibleEnergyDepositionAtAStep(&aStep));
417 else
418 MeanNumberOfPhotons *= TotalEnergyDeposit;
419 }
420 sum_yields = yield1 + yield2 + yield3;
421
422 if(MeanNumberOfPhotons > 10.)
423 {
424 G4double sigma = ResolutionScale * std::sqrt(MeanNumberOfPhotons);
425 fNumPhotons = G4int(G4RandGauss::shoot(MeanNumberOfPhotons, sigma) + 0.5);
426 }
427 else
428 {
429 fNumPhotons = G4int(G4Poisson(MeanNumberOfPhotons));
430 }
431
432 if(fNumPhotons <= 0 || !fStackingFlag)
433 {
434 // return unchanged particle and no secondaries
436 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
437 }
438
440
441 if(fTrackSecondariesFirst)
442 {
443 if(aTrack.GetTrackStatus() == fAlive)
445 }
446
447 G4int materialIndex = (G4int)aMaterial->GetIndex();
448
449 // Retrieve the Scintillation Integral for this material
450 // new G4PhysicsFreeVector allocated to hold CII's
451 std::size_t numPhot = fNumPhotons;
452 G4double scintTime = 0.;
453 G4double riseTime = 0.;
454 G4PhysicsFreeVector* scintIntegral = nullptr;
455 G4ScintillationType scintType = Slow;
456
457 for(G4int scnt = 0; scnt < N_timeconstants; ++scnt)
458 {
459 // if there is 1 time constant it is #1, etc.
460 if(scnt == 0)
461 {
462 if(N_timeconstants == 1)
463 {
464 numPhot = fNumPhotons;
465 }
466 else
467 {
468 numPhot = yield1 / sum_yields * fNumPhotons;
469 }
471 if(fFiniteRiseTime)
472 {
474 }
475 scintType = Fast;
476 scintIntegral =
477 (G4PhysicsFreeVector*) ((*fIntegralTable1)(materialIndex));
478 }
479 else if(scnt == 1)
480 {
481 // to be consistent with old version (due to double->int conversion)
482 if(N_timeconstants == 2)
483 {
484 numPhot = fNumPhotons - numPhot;
485 }
486 else
487 {
488 numPhot = yield2 / sum_yields * fNumPhotons;
489 }
491 if(fFiniteRiseTime)
492 {
494 }
495 scintType = Medium;
496 scintIntegral =
497 (G4PhysicsFreeVector*) ((*fIntegralTable2)(materialIndex));
498 }
499 else if(scnt == 2)
500 {
501 numPhot = yield3 / sum_yields * fNumPhotons;
503 if(fFiniteRiseTime)
504 {
506 }
507 scintType = Slow;
508 scintIntegral =
509 (G4PhysicsFreeVector*) ((*fIntegralTable3)(materialIndex));
510 }
511
512 if(!scintIntegral)
513 continue;
514
515 G4double CIImax = scintIntegral->GetMaxValue();
516 for(std::size_t i = 0; i < numPhot; ++i)
517 {
518 // Determine photon energy
519 G4double CIIvalue = G4UniformRand() * CIImax;
520 G4double sampledEnergy = scintIntegral->GetEnergy(CIIvalue);
521
522 if(verboseLevel > 1)
523 {
524 G4cout << "sampledEnergy = " << sampledEnergy << G4endl;
525 G4cout << "CIIvalue = " << CIIvalue << G4endl;
526 }
527
528 // Generate random photon direction
529 G4double cost = 1. - 2. * G4UniformRand();
530 G4double sint = std::sqrt((1. - cost) * (1. + cost));
531 G4double phi = twopi * G4UniformRand();
532 G4double sinp = std::sin(phi);
533 G4double cosp = std::cos(phi);
534 G4ParticleMomentum photonMomentum(sint * cosp, sint * sinp, cost);
535
536 // Determine polarization of new photon
537 G4ThreeVector photonPolarization(cost * cosp, cost * sinp, -sint);
538 G4ThreeVector perp = photonMomentum.cross(photonPolarization);
539 phi = twopi * G4UniformRand();
540 sinp = std::sin(phi);
541 cosp = std::cos(phi);
542 photonPolarization = (cosp * photonPolarization + sinp * perp).unit();
543
544 // Generate a new photon:
545 auto scintPhoton = new G4DynamicParticle(opticalphoton, photonMomentum);
546 scintPhoton->SetPolarization(photonPolarization);
547 scintPhoton->SetKineticEnergy(sampledEnergy);
548
549 // Generate new G4Track object:
550 G4double rand = G4UniformRand();
551 if(aParticle->GetDefinition()->GetPDGCharge() == 0)
552 {
553 rand = 1.0;
554 }
555
556 // emission time distribution
557 G4double delta = rand * aStep.GetStepLength();
558 G4double deltaTime =
559 delta /
560 (pPreStepPoint->GetVelocity() +
561 rand * (pPostStepPoint->GetVelocity() - pPreStepPoint->GetVelocity()) /
562 2.);
563 if(riseTime == 0.0)
564 {
565 deltaTime -= scintTime * std::log(G4UniformRand());
566 }
567 else
568 {
569 deltaTime += sample_time(riseTime, scintTime);
570 }
571
572 G4double secTime = t0 + deltaTime;
573 G4ThreeVector secPosition = x0 + rand * aStep.GetDeltaPosition();
574
575 G4Track* secTrack = new G4Track(scintPhoton, secTime, secPosition);
576 secTrack->SetTouchableHandle(
578 secTrack->SetParentID(aTrack.GetTrackID());
579 secTrack->SetCreatorModelID(secID);
580 if(fScintillationTrackInfo)
581 secTrack->SetUserInformation(
582 new G4ScintillationTrackInformation(scintType));
584 }
585 }
586
587 if(verboseLevel > 1)
588 {
589 G4cout << "\n Exiting from G4Scintillation::DoIt -- NumberOfSecondaries = "
591 }
592
593 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep);
594}
595
596//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
599{
601 return DBL_MAX;
602}
603
604//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
607{
608 *condition = Forced;
609 return DBL_MAX;
610}
611
612//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
613G4double G4Scintillation::sample_time(G4double tau1, G4double tau2)
614{
615 // tau1: rise time and tau2: decay time
616 // Loop checking, 07-Aug-2015, Vladimir Ivanchenko
617 while(true)
618 {
619 G4double ran1 = G4UniformRand();
620 G4double ran2 = G4UniformRand();
621
622 // exponential distribution as envelope function: very efficient
623 G4double d = (tau1 + tau2) / tau2;
624 // make sure the envelope function is
625 // always larger than the bi-exponential
626 G4double t = -1.0 * tau2 * std::log(1. - ran1);
627 G4double gg = d * single_exp(t, tau2);
628 if(ran2 <= bi_exp(t, tau1, tau2) / gg)
629 return t;
630 }
631 return -1.0;
632}
633
634//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
636 const G4Track& aTrack, const G4Step& aStep, G4double& yield1,
637 G4double& yield2, G4double& yield3)
638{
639 // new in 10.7, allow multiple time constants with ScintByParticleType
640 // Get the G4MaterialPropertyVector containing the scintillation
641 // yield as a function of the energy deposited and particle type
642
644 G4MaterialPropertyVector* yieldVector = nullptr;
647
648 // Protons
649 if(pDef == G4Proton::ProtonDefinition())
650 {
651 yieldVector = MPT->GetProperty(kPROTONSCINTILLATIONYIELD);
654 : 1.;
657 : 0.;
660 : 0.;
661 }
662
663 // Deuterons
664 else if(pDef == G4Deuteron::DeuteronDefinition())
665 {
666 yieldVector = MPT->GetProperty(kDEUTERONSCINTILLATIONYIELD);
669 : 1.;
672 : 0.;
675 : 0.;
676 }
677
678 // Tritons
679 else if(pDef == G4Triton::TritonDefinition())
680 {
681 yieldVector = MPT->GetProperty(kTRITONSCINTILLATIONYIELD);
684 : 1.;
687 : 0.;
690 : 0.;
691 }
692
693 // Alphas
694 else if(pDef == G4Alpha::AlphaDefinition())
695 {
696 yieldVector = MPT->GetProperty(kALPHASCINTILLATIONYIELD);
699 : 1.;
702 : 0.;
705 : 0.;
706 }
707
708 // Ions (particles derived from G4VIon and G4Ions) and recoil ions
709 // below the production cut from neutrons after hElastic
710 else if(pDef->GetParticleType() == "nucleus" ||
712 {
713 yieldVector = MPT->GetProperty(kIONSCINTILLATIONYIELD);
716 : 1.;
719 : 0.;
722 : 0.;
723 }
724
725 // Electrons (must also account for shell-binding energy
726 // attributed to gamma from standard photoelectric effect)
727 // and, default for particles not enumerated/listed above
728 else
729 {
730 yieldVector = MPT->GetProperty(kELECTRONSCINTILLATIONYIELD);
733 : 1.;
736 : 0.;
739 : 0.;
740 }
741
742 // Throw an exception if no scintillation yield vector is found
743 if(!yieldVector)
744 {
746 ed << "\nG4Scintillation::PostStepDoIt(): "
747 << "Request for scintillation yield for energy deposit and particle\n"
748 << "type without correct entry in MaterialPropertiesTable.\n"
749 << "ScintillationByParticleType requires at minimum that \n"
750 << "ELECTRONSCINTILLATIONYIELD is set by the user\n"
751 << G4endl;
752 G4String comments = "Missing MaterialPropertiesTable entry - No correct "
753 "entry in MaterialPropertiesTable";
754 G4Exception("G4Scintillation::PostStepDoIt", "Scint01", FatalException, ed,
755 comments);
756 }
757
758 ///////////////////////////////////////
759 // Calculate the scintillation light //
760 ///////////////////////////////////////
761 // To account for potential nonlinearity and scintillation photon
762 // density along the track, light (L) is produced according to:
763 // L_currentStep = L(PreStepKE) - L(PreStepKE - EDep)
764
765 G4double ScintillationYield = 0.;
766 G4double StepEnergyDeposit = aStep.GetTotalEnergyDeposit();
767 G4double PreStepKineticEnergy = aStep.GetPreStepPoint()->GetKineticEnergy();
768
769 if(PreStepKineticEnergy <= yieldVector->GetMaxEnergy())
770 {
771 // G4double Yield1 = yieldVector->Value(PreStepKineticEnergy);
772 // G4double Yield2 = yieldVector->Value(PreStepKineticEnergy -
773 // StepEnergyDeposit); ScintillationYield = Yield1 - Yield2;
774 ScintillationYield =
775 yieldVector->Value(PreStepKineticEnergy) -
776 yieldVector->Value(PreStepKineticEnergy - StepEnergyDeposit);
777 }
778 else
779 {
781 ed << "\nG4Scintillation::GetScintillationYieldByParticleType(): Request\n"
782 << "for scintillation light yield above the available energy range\n"
783 << "specified in G4MaterialPropertiesTable. A linear interpolation\n"
784 << "will be performed to compute the scintillation light yield using\n"
785 << "(L_max / E_max) as the photon yield per unit energy." << G4endl;
786 G4String cmt = "\nScintillation yield may be unphysical!\n";
787 G4Exception("G4Scintillation::GetScintillationYieldByParticleType()",
788 "Scint03", JustWarning, ed, cmt);
789
790 // Units: [# scintillation photons]
791 ScintillationYield = yieldVector->GetMaxValue() /
792 yieldVector->GetMaxEnergy() * StepEnergyDeposit;
793 }
794
795#ifdef G4DEBUG_SCINTILLATION
796 // Increment track aggregators
797 ScintTrackYield += ScintillationYield;
798 ScintTrackEDep += StepEnergyDeposit;
799
800 G4cout << "\n--- G4Scintillation::GetScintillationYieldByParticleType() ---\n"
801 << "--\n"
802 << "-- Name = "
803 << aTrack.GetParticleDefinition()->GetParticleName() << "\n"
804 << "-- TrackID = " << aTrack.GetTrackID() << "\n"
805 << "-- ParentID = " << aTrack.GetParentID() << "\n"
806 << "-- Current KE = " << aTrack.GetKineticEnergy() / MeV
807 << " MeV\n"
808 << "-- Step EDep = " << aStep.GetTotalEnergyDeposit() / MeV
809 << " MeV\n"
810 << "-- Track EDep = " << ScintTrackEDep / MeV << " MeV\n"
811 << "-- Vertex KE = " << aTrack.GetVertexKineticEnergy() / MeV
812 << " MeV\n"
813 << "-- Step yield = " << ScintillationYield << " photons\n"
814 << "-- Track yield = " << ScintTrackYield << " photons\n"
815 << G4endl;
816
817 // The track has terminated within or has left the scintillator volume
818 if((aTrack.GetTrackStatus() == fStopButAlive) or
820 {
821 // Reset aggregators for the next track
822 ScintTrackEDep = 0.;
823 ScintTrackYield = 0.;
824 }
825#endif
826
827 return ScintillationYield;
828}
829
830//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
832{
833 if(fIntegralTable1)
834 {
835 for(std::size_t i = 0; i < fIntegralTable1->entries(); ++i)
836 {
837 ((G4PhysicsFreeVector*) (*fIntegralTable1)[i])->DumpValues();
838 }
839 }
840 if(fIntegralTable2)
841 {
842 for(std::size_t i = 0; i < fIntegralTable2->entries(); ++i)
843 {
844 ((G4PhysicsFreeVector*) (*fIntegralTable2)[i])->DumpValues();
845 }
846 }
847 if(fIntegralTable3)
848 {
849 for(std::size_t i = 0; i < fIntegralTable3->entries(); ++i)
850 {
851 ((G4PhysicsFreeVector*) (*fIntegralTable3)[i])->DumpValues();
852 }
853 }
854}
855
856//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
858{
859 fTrackSecondariesFirst = state;
861 fTrackSecondariesFirst);
862}
863
864//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
866{
867 fFiniteRiseTime = state;
869}
870
871//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
873{
874 if(fEmSaturation && scintType)
875 {
876 G4Exception("G4Scintillation::SetScintillationByParticleType", "Scint02",
878 "Redefinition: Birks Saturation is replaced by "
879 "ScintillationByParticleType!");
881 }
882 fScintillationByParticleType = scintType;
884 fScintillationByParticleType);
885}
886
887//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
889{
890 fScintillationTrackInfo = trackType;
891 G4OpticalParameters::Instance()->SetScintTrackInfo(fScintillationTrackInfo);
892}
893
894//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
896{
897 fStackingFlag = stackingFlag;
899}
900
901//....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
903{
904 verboseLevel = verbose;
906}
@ fScintillation
G4double condition(const G4ErrorSymMatrix &m)
@ JustWarning
@ FatalException
void G4Exception(const char *originOfException, const char *exceptionCode, G4ExceptionSeverity severity, const char *description)
Definition: G4Exception.cc:59
std::ostringstream G4ExceptionDescription
Definition: G4Exception.hh:40
G4ForceCondition
@ StronglyForced
@ Forced
@ kSCINTILLATIONCOMPONENT1
@ kSCINTILLATIONCOMPONENT2
@ kSCINTILLATIONCOMPONENT3
@ kELECTRONSCINTILLATIONYIELD
@ kALPHASCINTILLATIONYIELD
@ kPROTONSCINTILLATIONYIELD
@ kDEUTERONSCINTILLATIONYIELD
@ kIONSCINTILLATIONYIELD
@ kTRITONSCINTILLATIONYIELD
@ kSCINTILLATIONTIMECONSTANT1
@ kSCINTILLATIONRISETIME2
@ kTRITONSCINTILLATIONYIELD1
@ kDEUTERONSCINTILLATIONYIELD3
@ kIONSCINTILLATIONYIELD1
@ kSCINTILLATIONRISETIME1
@ kDEUTERONSCINTILLATIONYIELD2
@ kTRITONSCINTILLATIONYIELD2
@ kALPHASCINTILLATIONYIELD2
@ kELECTRONSCINTILLATIONYIELD3
@ kALPHASCINTILLATIONYIELD1
@ kELECTRONSCINTILLATIONYIELD2
@ kIONSCINTILLATIONYIELD2
@ kIONSCINTILLATIONYIELD3
@ kSCINTILLATIONRISETIME3
@ kPROTONSCINTILLATIONYIELD2
@ kDEUTERONSCINTILLATIONYIELD1
@ kTRITONSCINTILLATIONYIELD3
@ kSCINTILLATIONTIMECONSTANT3
@ kPROTONSCINTILLATIONYIELD3
@ kELECTRONSCINTILLATIONYIELD1
@ kALPHASCINTILLATIONYIELD3
@ kSCINTILLATIONTIMECONSTANT2
@ kPROTONSCINTILLATIONYIELD1
std::vector< G4Material * > G4MaterialTable
G4long G4Poisson(G4double mean)
Definition: G4Poisson.hh:50
G4ProcessType
@ fGeomBoundary
Definition: G4StepStatus.hh:43
@ fSuspend
@ fAlive
@ fStopButAlive
double G4double
Definition: G4Types.hh:83
bool G4bool
Definition: G4Types.hh:86
int G4int
Definition: G4Types.hh:85
#define G4endl
Definition: G4ios.hh:57
G4GLOB_DLL std::ostream G4cout
#define G4UniformRand()
Definition: Randomize.hh:52
Hep3Vector unit() const
Hep3Vector cross(const Hep3Vector &) const
static G4Alpha * AlphaDefinition()
Definition: G4Alpha.cc:83
static G4Deuteron * DeuteronDefinition()
Definition: G4Deuteron.cc:88
G4ParticleDefinition * GetDefinition() const
G4double VisibleEnergyDepositionAtAStep(const G4Step *) const
G4bool ConstPropertyExists(const G4String &key) const
G4double GetConstProperty(const G4String &key) const
G4MaterialPropertyVector * GetProperty(const char *key) const
G4MaterialPropertiesTable * GetMaterialPropertiesTable() const
Definition: G4Material.hh:251
static size_t GetNumberOfMaterials()
Definition: G4Material.cc:684
static G4MaterialTable * GetMaterialTable()
Definition: G4Material.cc:677
size_t GetIndex() const
Definition: G4Material.hh:255
static G4Neutron * NeutronDefinition()
Definition: G4Neutron.cc:98
void SetScintByParticleType(G4bool)
void SetScintTrackSecondariesFirst(G4bool)
G4int GetScintVerboseLevel() const
void SetScintStackPhotons(G4bool)
G4bool GetScintStackPhotons() const
static G4OpticalParameters * Instance()
void SetScintFiniteRiseTime(G4bool)
G4bool GetScintByParticleType() const
G4bool GetScintFiniteRiseTime() const
G4bool GetScintTrackInfo() const
G4bool GetScintTrackSecondariesFirst() const
void AddSecondary(G4Track *aSecondary)
void Initialize(const G4Track &) override
const G4String & GetParticleType() const
G4double GetPDGCharge() const
const G4String & GetParticleName() const
static G4int GetModelID(const G4int modelIndex)
void clearAndDestroy()
std::size_t entries() const
void insertAt(std::size_t, G4PhysicsVector *)
G4double GetEnergy(const G4double value) const
G4double GetMaxEnergy() const
G4double GetMaxValue() const
G4double Energy(const std::size_t index) const
G4double Value(const G4double energy, std::size_t &lastidx) const
std::size_t GetVectorLength() const
static G4Proton * ProtonDefinition()
Definition: G4Proton.cc:87
G4VParticleChange * AtRestDoIt(const G4Track &aTrack, const G4Step &aStep) override
G4double GetScintillationYieldByParticleType(const G4Track &aTrack, const G4Step &aStep, G4double &yield1, G4double &yield2, G4double &yield3)
void SetTrackSecondariesFirst(const G4bool state)
void SetStackPhotons(const G4bool)
G4double GetMeanFreePath(const G4Track &aTrack, G4double, G4ForceCondition *) override
void BuildPhysicsTable(const G4ParticleDefinition &aParticleType) override
void SetVerboseLevel(G4int)
void SetScintillationTrackInfo(const G4bool trackType)
G4double GetMeanLifeTime(const G4Track &aTrack, G4ForceCondition *) override
G4VParticleChange * PostStepDoIt(const G4Track &aTrack, const G4Step &aStep) override
G4bool IsApplicable(const G4ParticleDefinition &aParticleType) override
void DumpPhysicsTable() const
void SetFiniteRiseTime(const G4bool state)
G4Scintillation(const G4String &processName="Scintillation", G4ProcessType type=fElectromagnetic)
void PreparePhysicsTable(const G4ParticleDefinition &part) override
void SetScintillationByParticleType(const G4bool)
void ProcessDescription(std::ostream &) const override
G4StepStatus GetStepStatus() const
G4double GetVelocity() const
G4double GetGlobalTime() const
const G4ThreeVector & GetPosition() const
const G4TouchableHandle & GetTouchableHandle() const
G4double GetKineticEnergy() const
Definition: G4Step.hh:62
G4ThreeVector GetDeltaPosition() const
G4StepPoint * GetPreStepPoint() const
G4double GetStepLength() const
G4double GetTotalEnergyDeposit() const
G4StepPoint * GetPostStepPoint() const
G4TrackStatus GetTrackStatus() const
G4double GetVertexKineticEnergy() const
G4int GetTrackID() const
const G4ParticleDefinition * GetParticleDefinition() const
void SetTouchableHandle(const G4TouchableHandle &apValue)
G4Material * GetMaterial() const
const G4DynamicParticle * GetDynamicParticle() const
G4double GetKineticEnergy() const
void SetUserInformation(G4VUserTrackInformation *aValue) const
void SetCreatorModelID(const G4int id)
G4int GetParentID() const
void SetParentID(const G4int aValue)
static G4Triton * TritonDefinition()
Definition: G4Triton.cc:88
void ProposeTrackStatus(G4TrackStatus status)
G4int GetNumberOfSecondaries() const
void SetNumberOfSecondaries(G4int totSecondaries)
G4ParticleChange aParticleChange
Definition: G4VProcess.hh:331
G4int verboseLevel
Definition: G4VProcess.hh:360
void SetProcessSubType(G4int)
Definition: G4VProcess.hh:410
virtual void DumpInfo() const
Definition: G4VProcess.cc:173
const G4String & GetProcessName() const
Definition: G4VProcess.hh:386
virtual G4VParticleChange * PostStepDoIt(const G4Track &, const G4Step &)
#define DBL_MAX
Definition: templates.hh:62