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
The bug has been fixed. We appreciate very much your help, your ananlysis has been very sharp and collabarative. thank you very much, Alf