Hello. I have revisited the code in G4ParticleHPInelasticCompFS::CompositeApply() after switching to G4ParticleHPNucLevel. That bug at G4ParticleHPInelasticCompFS.cc:419 is pretty resilient. Consider the replacement of 419 if (useQI) { 420 eExcitation = std::max(0., QI[0] - QI[it]); // Bug fix 2333 421 422 // Re-evaluate iLevel based on this eExcitation 423 iLevel = 0; 424 G4bool find = false; 425 const G4double level_tolerance = 1.0 * CLHEP::keV; 426 427 // VI: the first level is ground 428 if (0 < imaxEx) { 429 for (iLevel = 1; iLevel <= imaxEx; ++iLevel) { 430 G4double elevel = theGammas.GetLevelEnergy(iLevel); 431 if (std::abs(eExcitation - elevel) < level_tolerance) { 432 find = true; 433 break; 434 } 435 if (eExcitation < elevel) { 436 find = true; 437 iLevel = std::max(iLevel - 1, 0); 438 break; 439 } 440 } 441 442 // If proper level cannot be found, use the maximum level 443 if (!find) iLevel = imaxEx; 444 } 445 } with just this: if (useQI) { eExcitation = std::max(0., QI[0] - QI[it]); // Bug fix 2333 iLevel = (theTrack.GetDefinition() == aDefinition) ? 1 : 0; G4bool find = false; for ( ; iLevel < imaxEx; ++iLevel) { G4double dE = std::abs(eExcitation - theGammas.GetLevelEnergy(iLevel)); G4double dE_next = std::abs(eExcitation - theGammas.GetLevelEnergy(iLevel+1)); if (dE_next > dE) { find = true; break; } } if (!find) iLevel = imaxEx; } The loop starts from the level #1 if there is a (n,n'). Otherwise, e.g. (n,p), (n,a), it starts from the ground level. When dE_next becomes larger than dE, it means that the minimum level difference is met and the correct level is found. See #1789, #1838 for previous discussion. There could be some errors due to unordered levels (see #2332, it has not been fixed yet, G4NDL4.7 still contains old data).