- Timestamp:
- Nov 5, 2010, 3:45:55 PM (14 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/source/processes/electromagnetic/xrays/src/G4Scintillation.cc
r1337 r1340 25 25 // 26 26 // 27 // $Id: G4Scintillation.cc,v 1.3 2 2010/06/16 15:34:15 gcosmoExp $28 // GEANT4 tag $Name: geant4-09-04-beta-01$27 // $Id: G4Scintillation.cc,v 1.36 2010/11/03 19:23:48 gum Exp $ 28 // GEANT4 tag $Name: xrays-V09-03-05 $ 29 29 // 30 30 //////////////////////////////////////////////////////////////////////// … … 32 32 //////////////////////////////////////////////////////////////////////// 33 33 // 34 // File: G4Scintillation.cc 34 // File: G4Scintillation.cc 35 35 // Description: RestDiscrete Process - Generation of Scintillation Photons 36 36 // Version: 1.0 37 // Created: 1998-11-07 37 // Created: 1998-11-07 38 38 // Author: Peter Gumplinger 39 // Updated: 2010-92-22 by Peter Gumplinger 39 // Updated: 2010-10-20 Allow the scintillation yield to be a function 40 // of energy deposited by particle type 41 // Thanks to Zach Hartwig (Department of Nuclear 42 // Science and Engineeering - MIT) 43 // 2010-09-22 by Peter Gumplinger 40 44 // > scintillation rise time included, thanks to 41 45 // > Martin Goettlich/DESY … … 59 63 // > change: aSecondaryPosition=x0+rand*aStep.GetDeltaPosition(); 60 64 // aSecondaryTrack->SetTouchable(0); 61 // 2001-09-17, migration of Materials to pure STL (mma) 65 // 2001-09-17, migration of Materials to pure STL (mma) 62 66 // 2003-06-03, V.Ivanchenko fix compilation warnings 63 67 // … … 67 71 68 72 #include "G4ios.hh" 73 #include "G4ParticleTypes.hh" 69 74 #include "G4EmProcessSubType.hh" 70 75 … … 72 77 73 78 ///////////////////////// 74 // Class Implementation 79 // Class Implementation 75 80 ///////////////////////// 76 81 … … 93 98 SetProcessSubType(fScintillation); 94 99 95 100 fTrackSecondariesFirst = false; 96 101 fFiniteRiseTime = false; 97 102 … … 99 104 ExcitationRatio = 1.0; 100 105 106 scintillationByParticleType = false; 107 101 108 theFastIntegralTable = NULL; 102 109 theSlowIntegralTable = NULL; 103 110 104 111 if (verboseLevel>0) { 105 112 G4cout << GetProcessName() << " is created " << G4endl; 106 107 108 113 } 114 115 BuildThePhysicsTable(); 109 116 110 117 emSaturation = NULL; … … 115 122 //////////////// 116 123 117 G4Scintillation::~G4Scintillation() 124 G4Scintillation::~G4Scintillation() 118 125 { 119 126 if (theFastIntegralTable != NULL) { 120 127 theFastIntegralTable->clearAndDestroy(); 121 128 delete theFastIntegralTable; 122 129 } 123 130 if (theSlowIntegralTable != NULL) { 124 131 theSlowIntegralTable->clearAndDestroy(); … … 161 168 const G4Material* aMaterial = aTrack.GetMaterial(); 162 169 163 164 165 166 170 G4StepPoint* pPreStepPoint = aStep.GetPreStepPoint(); 171 G4StepPoint* pPostStepPoint = aStep.GetPostStepPoint(); 172 173 G4ThreeVector x0 = pPreStepPoint->GetPosition(); 167 174 G4ThreeVector p0 = aStep.GetDeltaPosition().unit(); 168 175 G4double t0 = pPreStepPoint->GetGlobalTime(); 169 176 170 177 G4double TotalEnergyDeposit = aStep.GetTotalEnergyDeposit(); … … 175 182 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep); 176 183 177 184 const G4MaterialPropertyVector* Fast_Intensity = 178 185 aMaterialPropertiesTable->GetProperty("FASTCOMPONENT"); 179 186 const G4MaterialPropertyVector* Slow_Intensity = … … 186 193 if (Fast_Intensity && Slow_Intensity) nscnt = 2; 187 194 188 G4double ScintillationYield = aMaterialPropertiesTable-> 195 G4double ScintillationYield = 0.; 196 197 if (scintillationByParticleType) { 198 // The scintillation response is a function of the energy 199 // deposited by particle types. 200 201 // Get the definition of the current particle 202 G4ParticleDefinition *pDef = aParticle->GetDefinition(); 203 const G4MaterialPropertyVector *Scint_Yield_Vector = NULL; 204 205 // Obtain the G4MaterialPropertyVectory containing the 206 // scintillation light yield as a function of the deposited 207 // energy for the current particle type 208 209 // Protons 210 if(pDef==G4Proton::ProtonDefinition()) 211 Scint_Yield_Vector = aMaterialPropertiesTable-> 212 GetProperty("PROTONSCINTILLATIONYIELD"); 213 214 // Deuterons 215 else if(pDef==G4Deuteron::DeuteronDefinition()) 216 Scint_Yield_Vector = aMaterialPropertiesTable-> 217 GetProperty("DEUTERONSCINTILLATIONYIELD"); 218 219 // Tritons 220 else if(pDef==G4Triton::TritonDefinition()) 221 Scint_Yield_Vector = aMaterialPropertiesTable-> 222 GetProperty("TRITONSCINTILLATIONYIELD"); 223 224 // Alphas 225 else if(pDef==G4Alpha::AlphaDefinition()) 226 Scint_Yield_Vector = aMaterialPropertiesTable-> 227 GetProperty("ALPHASCINTILLATIONYIELD"); 228 229 // Ions (particles derived from G4VIon and G4Ions) 230 // and recoil ions below tracking cut from neutrons after hElastic 231 else if(pDef->GetParticleType()== "nucleus" || 232 pDef==G4Neutron::NeutronDefinition()) 233 Scint_Yield_Vector = aMaterialPropertiesTable-> 234 GetProperty("IONSCINTILLATIONYIELD"); 235 236 // Electrons (must also account for shell-binding energy 237 // attributed to gamma from standard PhotoElectricEffect) 238 else if(pDef==G4Electron::ElectronDefinition() || 239 pDef==G4Gamma::GammaDefinition()) 240 Scint_Yield_Vector = aMaterialPropertiesTable-> 241 GetProperty("ELECTRONSCINTILLATIONYIELD"); 242 243 // Default for particles not enumerated/listed above 244 else 245 Scint_Yield_Vector = aMaterialPropertiesTable-> 246 GetProperty("ELECTRONSCINTILLATIONYIELD"); 247 248 // If the user has not specified yields for (p,d,t,a,carbon) 249 // then these unspecified particles will default to the 250 // electron's scintillation yield 251 if(!Scint_Yield_Vector){ 252 Scint_Yield_Vector = aMaterialPropertiesTable-> 253 GetProperty("ELECTRONSCINTILLATIONYIELD"); 254 } 255 256 // Throw an exception if no scintillation yield is found 257 if (!Scint_Yield_Vector) { 258 G4cerr << "\nG4Scintillation::PostStepDoIt(): " 259 << "Request for scintillation yield for energy deposit and particle type without correct entry in MaterialPropertiesTable\n" 260 << "ScintillationByParticleType requires at minimum that ELECTRONSCINTILLATIONYIELD is set by the user\n" 261 << G4endl; 262 G4Exception("G4Scintillation::PostStepDoIt", 263 "No correct entry in MaterialPropertiesTable", 264 FatalException,"Missing MaterialPropertiesTable entry."); 265 } 266 267 if (verboseLevel>1) { 268 G4cout << "\n" 269 << "Particle = " << pDef->GetParticleName() << "\n" 270 << "Energy Dep. = " << TotalEnergyDeposit/MeV << "\n" 271 << "Yield = " 272 << Scint_Yield_Vector->GetProperty(TotalEnergyDeposit) 273 << "\n" << G4endl; 274 } 275 276 // Obtain the scintillation yield using the total energy 277 // deposited by the particle in this step. 278 279 // Units: [# scintillation photons] 280 ScintillationYield = Scint_Yield_Vector-> 281 GetProperty(TotalEnergyDeposit); 282 } else { 283 // The default linear scintillation process 284 G4double ScintillationYield = aMaterialPropertiesTable-> 189 285 GetConstProperty("SCINTILLATIONYIELD"); 190 ScintillationYield *= YieldFactor; 286 287 // Units: [# scintillation photons / MeV] 288 ScintillationYield *= YieldFactor; 289 } 191 290 192 291 G4double ResolutionScale = aMaterialPropertiesTable-> … … 201 300 G4double MeanNumberOfPhotons; 202 301 203 if (emSaturation) { 302 // Birk's correction via emSaturation and specifying scintillation by 303 // by particle type are physically mutually exclusive 304 305 if (scintillationByParticleType) 306 MeanNumberOfPhotons = ScintillationYield; 307 else if (emSaturation) 204 308 MeanNumberOfPhotons = ScintillationYield* 205 309 (emSaturation->VisibleEnergyDeposition(&aStep)); 206 } else {310 else 207 311 MeanNumberOfPhotons = ScintillationYield*TotalEnergyDeposit; 208 }209 312 210 313 G4int NumPhotons; … … 220 323 } 221 324 222 325 if (NumPhotons <= 0) 223 326 { 224 225 226 327 // return unchanged particle and no secondaries 328 329 aParticleChange.SetNumberOfSecondaries(0); 227 330 228 331 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep); 229 230 231 232 233 234 235 332 } 333 334 //////////////////////////////////////////////////////////////// 335 336 aParticleChange.SetNumberOfSecondaries(NumPhotons); 337 338 if (fTrackSecondariesFirst) { 236 339 if (aTrack.GetTrackStatus() == fAlive ) 237 238 } 239 240 241 242 243 244 245 340 aParticleChange.ProposeTrackStatus(fSuspend); 341 } 342 343 //////////////////////////////////////////////////////////////// 344 345 G4int materialIndex = aMaterial->GetIndex(); 346 347 // Retrieve the Scintillation Integral for this material 348 // new G4PhysicsOrderedFreeVector allocated to hold CII's 246 349 247 350 G4int Num = NumPhotons; … … 270 373 if (fFiniteRiseTime) { 271 374 ScintillationRiseTime = aMaterialPropertiesTable-> 272 GetConstProperty("SLOWSCINTILLATIONRISETIME"); } 375 GetConstProperty("SLOWSCINTILLATIONRISETIME"); 376 } 273 377 ScintillationIntegral = 274 378 (G4PhysicsOrderedFreeVector*)((*theSlowIntegralTable)(materialIndex)); … … 310 414 // Max Scintillation Integral 311 415 312 313 314 315 316 416 G4double CIImax = ScintillationIntegral->GetMaxValue(); 417 418 for (G4int i = 0; i < Num; i++) { 419 420 // Determine photon energy 317 421 318 422 G4double CIIvalue = G4UniformRand()*CIImax; 319 423 G4double sampledEnergy = 320 424 ScintillationIntegral->GetEnergy(CIIvalue); 321 425 322 426 if (verboseLevel>1) { 323 427 G4cout << "sampledEnergy = " << sampledEnergy << G4endl; 324 325 326 327 428 G4cout << "CIIvalue = " << CIIvalue << G4endl; 429 } 430 431 // Generate random photon direction 328 432 329 433 G4double cost = 1. - 2.*G4UniformRand(); 330 434 G4double sint = std::sqrt((1.-cost)*(1.+cost)); 331 435 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 436 G4double phi = twopi*G4UniformRand(); 437 G4double sinp = std::sin(phi); 438 G4double cosp = std::cos(phi); 439 440 G4double px = sint*cosp; 441 G4double py = sint*sinp; 442 G4double pz = cost; 443 444 // Create photon momentum direction vector 445 446 G4ParticleMomentum photonMomentum(px, py, pz); 447 448 // Determine polarization of new photon 449 450 G4double sx = cost*cosp; 451 G4double sy = cost*sinp; 452 G4double sz = -sint; 453 454 G4ThreeVector photonPolarization(sx, sy, sz); 351 455 352 456 G4ThreeVector perp = photonMomentum.cross(photonPolarization); 353 457 354 355 356 458 phi = twopi*G4UniformRand(); 459 sinp = std::sin(phi); 460 cosp = std::cos(phi); 357 461 358 462 photonPolarization = cosp * photonPolarization + sinp * perp; … … 364 468 G4DynamicParticle* aScintillationPhoton = 365 469 new G4DynamicParticle(G4OpticalPhoton::OpticalPhoton(), 366 367 368 369 370 371 372 470 photonMomentum); 471 aScintillationPhoton->SetPolarization 472 (photonPolarization.x(), 473 photonPolarization.y(), 474 photonPolarization.z()); 475 476 aScintillationPhoton->SetKineticEnergy(sampledEnergy); 373 477 374 478 // Generate new G4Track object: … … 401 505 x0 + rand * aStep.GetDeltaPosition(); 402 506 403 404 507 G4Track* aSecondaryTrack = 508 new G4Track(aScintillationPhoton,aSecondaryTime,aSecondaryPosition); 405 509 406 510 aSecondaryTrack->SetTouchableHandle( … … 410 514 aSecondaryTrack->SetParentID(aTrack.GetTrackID()); 411 515 412 413 414 415 } 416 417 418 419 420 421 422 516 aParticleChange.AddSecondary(aSecondaryTrack); 517 518 } 519 } 520 521 if (verboseLevel>0) { 522 G4cout << "\n Exiting from G4Scintillation::DoIt -- NumberOfSecondaries = " 523 << aParticleChange.GetNumberOfSecondaries() << G4endl; 524 } 525 526 return G4VRestDiscreteProcess::PostStepDoIt(aTrack, aStep); 423 527 } 424 528 … … 429 533 void G4Scintillation::BuildThePhysicsTable() 430 534 { 431 432 433 535 if (theFastIntegralTable && theSlowIntegralTable) return; 536 537 const G4MaterialTable* theMaterialTable = 434 538 G4Material::GetMaterialTable(); 435 436 437 539 G4int numOfMaterials = G4Material::GetNumberOfMaterials(); 540 541 // create new physics table 438 542 439 543 if(!theFastIntegralTable)theFastIntegralTable = new G4PhysicsTable(numOfMaterials); 440 544 if(!theSlowIntegralTable)theSlowIntegralTable = new G4PhysicsTable(numOfMaterials); 441 545 442 443 444 445 446 546 // loop for materials 547 548 for (G4int i=0 ; i < numOfMaterials; i++) 549 { 550 G4PhysicsOrderedFreeVector* aPhysicsOrderedFreeVector = 447 551 new G4PhysicsOrderedFreeVector(); 448 552 G4PhysicsOrderedFreeVector* bPhysicsOrderedFreeVector = 449 553 new G4PhysicsOrderedFreeVector(); 450 554 451 555 // Retrieve vector of scintillation wavelength intensity for 452 556 // the material from the material's optical properties table. 453 557 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 ++(*theFastLightVector);// advance to 1st entry471 472 473 474 475 476 477 558 G4Material* aMaterial = (*theMaterialTable)[i]; 559 560 G4MaterialPropertiesTable* aMaterialPropertiesTable = 561 aMaterial->GetMaterialPropertiesTable(); 562 563 if (aMaterialPropertiesTable) { 564 565 G4MaterialPropertyVector* theFastLightVector = 566 aMaterialPropertiesTable->GetProperty("FASTCOMPONENT"); 567 568 if (theFastLightVector) { 569 570 // Retrieve the first intensity point in vector 571 // of (photon energy, intensity) pairs 572 573 theFastLightVector->ResetIterator(); 574 ++(*theFastLightVector); // advance to 1st entry 575 576 G4double currentIN = theFastLightVector-> 577 GetProperty(); 578 579 if (currentIN >= 0.0) { 580 581 // Create first (photon energy, Scintillation 478 582 // Integral pair 479 583 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 currentIN=theFastLightVector->503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 584 G4double currentPM = theFastLightVector-> 585 GetPhotonEnergy(); 586 587 G4double currentCII = 0.0; 588 589 aPhysicsOrderedFreeVector-> 590 InsertValues(currentPM , currentCII); 591 592 // Set previous values to current ones prior to loop 593 594 G4double prevPM = currentPM; 595 G4double prevCII = currentCII; 596 G4double prevIN = currentIN; 597 598 // loop over all (photon energy, intensity) 599 // pairs stored for this material 600 601 while(++(*theFastLightVector)) 602 { 603 currentPM = theFastLightVector-> 604 GetPhotonEnergy(); 605 606 currentIN = theFastLightVector-> 607 GetProperty(); 608 609 currentCII = 0.5 * (prevIN + currentIN); 610 611 currentCII = prevCII + 612 (currentPM - prevPM) * currentCII; 613 614 aPhysicsOrderedFreeVector-> 615 InsertValues(currentPM, currentCII); 616 617 prevPM = currentPM; 618 prevCII = currentCII; 619 prevIN = currentIN; 620 } 621 622 } 623 } 520 624 521 625 G4MaterialPropertyVector* theSlowLightVector = … … 578 682 } 579 683 } 580 581 582 583 584 585 586 684 } 685 686 // The scintillation integral(s) for a given material 687 // will be inserted in the table(s) according to the 688 // position of the material in the material table. 689 690 theFastIntegralTable->insertAt(i,aPhysicsOrderedFreeVector); 587 691 theSlowIntegralTable->insertAt(i,bPhysicsOrderedFreeVector); 588 692 589 } 693 } 694 } 695 696 // Called by the user to set the scintillation yield as a function 697 // of energy deposited by particle type 698 699 void G4Scintillation::SetScintillationByParticleType(const G4bool scintType) 700 { 701 if (emSaturation) { 702 G4Exception("G4Scintillation::SetScintillationByParticleType", "Redefinition", 703 JustWarning, "Birks Saturation is replaced by ScintillationByParticleType!"); 704 RemoveSaturation(); 705 } 706 scintillationByParticleType = scintType; 590 707 } 591 708 … … 600 717 *condition = StronglyForced; 601 718 602 719 return DBL_MAX; 603 720 604 721 }
Note: See TracChangeset
for help on using the changeset viewer.