Problem 986 - Missing Auger electrons from atomic relaxation
Summary: Missing Auger electrons from atomic relaxation
Status: RESOLVED FIXED
Alias: None
Product: Geant4
Classification: Unclassified
Component: processes/electromagnetic/lowenergy (show other problems)
Version: 9.0
Hardware: All All
: P2 normal
Assignee: alfonso.mantero
URL:
Depends on:
Blocks:
 
Reported: 2007-11-14 22:17 CET by Andreas
Modified: 2007-11-19 17:29 CET (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this problem.
Description Andreas 2007-11-14 22:17:22 CET
Symptoms:
========

Even if all cuts and production thresholds are set below 1 keV and Auger electron and fluorescence X-ray production is activated, in some cases (not all!) a vacancy in the K-shell of Germanium does not lead to either generation of an Auger electron or a fluorescence gamma-ray, which is required by physics. In those cases only the primary photo-effect electron is generated as secondary particle and the remaining energy is simply deposited locally.


Cause:
=====

Debugging G4LowEnergyPhotoElectric and G4AtomicDeexcitation results in the suspicion of a problem in G4AtomicDeexcitation::GenerateAuger(...): In all the above cases, where neither an Auger electron nor a Fluorescence X-ray is produced, this function is called and it always returns at the line
"if (!foundFlag) {return 0;}" 
This means no Auger transition has been found.

Taking a closer look reveals that the routine sampling all possible Auger transitions and choosing one of them might be flawed.

The following source code is from G4AtomicDeexcitation::GenerateAuger:

In the following loop a sum of all transition probabilities is generated called "partSum"

// ------
while (transitionLoopShellIndex < transitionSize) {

  std::vector<G4int>::const_iterator pos = 
    anAugerTransition->TransitionOriginatingShellIds()->begin();

  G4int transitionLoopShellId = *(pos+transitionLoopShellIndex);
  G4int numberOfPossibleAuger = 
    (anAugerTransition->AugerTransitionProbabilities(transitionLoopShellId))->size();
  G4int augerIndex = 0;
  //      G4int partSum2 = 0;

	if (augerIndex < numberOfPossibleAuger) {
	  
	  do {
	    G4double thisProb = anAugerTransition->AugerTransitionProbability(augerIndex, 
									transitionLoopShellId);
	    partSum += thisProb;
	    augerIndex++;
	      
	  } while (augerIndex < numberOfPossibleAuger);
 }
 transitionLoopShellIndex++;
}
// ------

PartSum is later renamed to:
G4double totalVacancyAugerProbability = partSum;

In the following loop a random Auger electron from a random shell transition is intended to be chosen. This is done by generating a random number between [0..1], called partialProb. Using this number, a random value between [0..totalVacancyAugerProbability] is intended to be chosen in order to select a random Auger electron from all possible ones.

// ------
G4double partialProb = G4UniformRand();
// G4int augerOriginatingShellId = 0;
      
G4int numberOfPossibleAuger = 
 (anAugerTransition->AugerTransitionProbabilities(transitionRandomShellId))->size();
G4bool foundFlag = false;

while (transitionRandomShellIndex < transitionSize) {

  std::vector<G4int>::const_iterator pos = 
    anAugerTransition->TransitionOriginatingShellIds()->begin();

  transitionRandomShellId = *(pos+transitionRandomShellIndex);
        
	augerIndex = 0;
	numberOfPossibleAuger = (anAugerTransition-> 
  AugerTransitionProbabilities(transitionRandomShellId))->size();

  while (augerIndex < numberOfPossibleAuger) {
	  G4double thisProb =anAugerTransition->AugerTransitionProbability(augerIndex, 
									   transitionRandomShellId);

    partSum += thisProb;
          
    if (partSum >= (partialProb/totalVacancyAugerProbability) ) {
	    foundFlag = true;
	    break;
	  }
    augerIndex++;
  }
  if (partSum >= (partialProb/totalVacancyAugerProbability) ) {break;}

  transitionRandomShellIndex++;
}
// ------

The key lines to the problem are 
    
partSum += thisProb;
          
if (partSum >= (partialProb/totalVacancyAugerProbability) ) {
  foundFlag = true;
  break;
}

partSum is the same value as in the original loop, i.e. it's value goes from 0 to totalVacancyAugerProbability.
With the line "if (partSum >= (partialProb/totalVacancyAugerProbability)" a random Auger electron of all probably should be chosen.
However, since partSum goes form [0..totalVacancyAugerProbability] and partialProb from [0..1], the division is WRONG and a MULTIPLICATION needs to be performed so that the result of "(partialProb/totalVacancyAugerProbability)" is between [0..totalVacancyAugerProbability]!



Solution:
========

Replace 
if (partSum >= (partialProb/totalVacancyAugerProbability) )
with
if (partSum >= (partialProb*totalVacancyAugerProbability) )
THIS LINE APPEARS TWICE!


Then the original problem of not always generating an Auger electron or Fluorescence gamma-ray when a shell vacancy is given (even if the thresholds are all low enough), is solved. 



Additional comments:
===================

This problem does not harm any of the published validations of the Geant4 Atomic Relaxation such as S. Guatelli et al., "Validation of Geant4 Atomic Relaxation Against the NIST Physical Reference Data", 2007, since in those publications only the energy peak positions and not their strength have been validated. 



Version:
=======
 
Geant4.9.0-p01



Thanks for taking care of this problem,
Andreas Zoglauer
Comment 1 alfonso.mantero 2007-11-19 17:29:57 CET
The bug has been fixed.

We appreciate very much your help, your ananlysis has been very sharp and collabarative.

thank you very much,

Alf