def adjustMF13Gammas( reaction ) : MT = reaction.ENDF_MT crossSection = None allproducts = list( reaction.outputChannel ) for prod in reaction.outputChannel : if prod.outputChannel is not None : allproducts.extend( list( prod.outputChannel ) ) for product in allproducts : multiplicity = product.multiplicity[info.style] if( hasattr( multiplicity, '_temp_divideByCrossSection' ) ) : if( crossSection is None ) : crossSection = reaction.crossSection.toPointwise_withLinearXYs( accuracy = 1e-3, upperEps = 1e-8 ) adjustMF13Multiplicity( multiplicity, crossSection ) del multiplicity._temp_divideByCrossSection if( MT in info.totalMF6_12_13Gammas ) : MF, multiplicity = info.totalMF6_12_13Gammas[MT] if( MF == 13 ) : adjustMF13Multiplicity( multiplicity, crossSection ) gammaProduction = [ tmp for tmp in reactionSuite.reactions if tmp.ENDF_MT == MT ] # raises ValueError if more than one match found gammaProduction += [ tmp for tmp in reactionSuite.orphanProducts if tmp.ENDF_MT == MT ] if( len( gammaProduction ) != 1 ) : raise ValueError( "No unique match found." ) gammaProduction = gammaProduction[0] summands = [ sumsModule.add( link = r.multiplicity ) for r in gammaProduction.outputChannel.getProductsWithName( IDsPoPsModule.photon ) ] if len(summands)==0: for _product in gammaProduction.outputChannel: if _product.outputChannel is not None: summands += [ sumsModule.add( link = r.multiplicity ) for r in _product.outputChannel.getProductsWithName( IDsPoPsModule.photon ) ] if( MT in channelIDs ) : name = channelIDs[MT] else : name = str( gammaProduction.outputChannel ) multiplicitySum = sumsModule.multiplicitySum( label = name + " total gamma multiplicity", ENDF_MT = MT, summands = sumsModule.listOfSummands( summands ) ) multiplicitySum.multiplicity.add( multiplicity ) reactionSuite.sums.multiplicities.add( multiplicitySum )
def ITYPE_3(MTDatas, info, reactionSuite, singleMTOnly, parseCrossSectionOnly, verbose=False): MTs = sorted(MTDatas.keys()) if (451 in MTs): MTs.remove(451) MTList = endfFileToGNDMisc.niceSortOfMTs(MTs, verbose=verbose, logFile=info.logs) MT505 = extractMT505or506(info, 505, MTList, MTDatas, 'imaginary part of anomalous scattering factor') MT506 = extractMT505or506(info, 506, MTList, MTDatas, 'real part of anomalous scattering factor') iChannel = 0 summedReactions = {501: None, 516: None, 522: None} for MT in MTList: if (MT == 500): raise Exception("MT %d not supported" % MT) if ((singleMTOnly is not None) and (MT != singleMTOnly)): continue if (MT in [523]): print ' Skipping MT %d as I do not know what it really is' % MT continue warningList = [] MTData = MTDatas[MT] info.logs.write(' %3d %s' % (MT, sorted(MTData.keys()))) EPE, EFL, crossSection, LR, breakupProducts = readMF3( info, MT, MTData[23], warningList) del MTData[23] isTwoBody, productList = MT == 526, [] undefinedLevelInfo = { 'ZA': None, 'level': 0, 'levelIndex': None, 'count': 0 } if (26 in MTData): isTwoBody = readMF6(MT, info, MTData[26], productList, warningList, undefinedLevelInfo, isTwoBody, crossSection) del MTData[26] addTargetAsResidual = True productsNeeded = [] try: process = { 502: 'coherent', 504: 'incoherent', 522: None, 515: 'electron field', 517: 'nuclear field', 526: 'large angle Coulomb scattering', 527: 'bremsstrahlung', 528: 'excitation' }[MT] except KeyError: process = None if (MT in [502, 504, 522]): outputChannel = channelsModule.twoBodyOutputChannel( process=process) outputChannel.Q.add( toGNDMiscModule.returnConstantQ(info.style, 0, crossSection)) if (MT in [502, 504]): product = toGNDMiscModule.getTypeNameGamma(info, 0) product = toGNDMiscModule.newGNDParticle( info, product, crossSection) outputChannel.products.add( outputChannel.products.uniqueLabel(product)) if (MT == 502): formFactor = readMF27(info, MT, MTData, 'coherent scattering function', warningList) form = photonScatteringModule.coherent.form( info.style, standardsModule.frames.labToken, formFactor, MT506, MT505) else: subform = readMF27(info, MT, MTData, 'incoherent scattering function', warningList) form = photonScatteringModule.incoherent.form( info.style, standardsModule.frames.labToken, subform) product.distribution.add(form) elif (MT in [526, 527, 528]): if (isTwoBody): outputChannel = channelsModule.twoBodyOutputChannel( process=process) else: outputChannel = channelsModule.NBodyOutputChannel( process=process) outputChannel.Q.add( toGNDMiscModule.returnConstantQ(info.style, 0, crossSection)) productsNeeded = ['e-'] if (MT == 527): productsNeeded.insert(0, IDsPoPsModule.photon) else: outputChannel = channelsModule.NBodyOutputChannel(process=process) outputChannel.Q.add( toGNDMiscModule.returnConstantQ(info.style, EPE, crossSection)) if (MT in MT_AtomicConfigurations): productsNeeded = ['e-'] elif (MT in [515, 517]): productsNeeded = ['e-', 'e+'] else: addTargetAsResidual = False if (MT in [526, 527, 528]): productList[0].addAttribute('ENDFconversionFlag', 'MF26') for name in productsNeeded: product = None for i1, product in enumerate(productList): if (name == product.name): break product = None if (product is None): product = toGNDMiscModule.getTypeNameGamma( info, { "photon": 0, "e+": 8, "e-": 9 }[name]) product = toGNDMiscModule.newGNDParticle( info, product, crossSection) outputChannel.products.add( outputChannel.products.uniqueLabel(product)) if ((MT >= 534) and (reactionSuite.projectile == 'e-')): product = toGNDMiscModule.getTypeNameGamma(info, 9) product = toGNDMiscModule.newGNDParticle(info, product, crossSection) outputChannel.products.add( outputChannel.products.uniqueLabel(product)) if (addTargetAsResidual): elementSymbol = nuclearModule.elementSymbolFromZ(info.targetZA / 1000) if (MT >= 534): elementSymbol += '{%s}' % MT_AtomicConfigurations[MT] element = xParticleModule.element(elementSymbol) residual = toGNDMiscModule.newGNDParticle(info, element, crossSection) outputChannel.products.add( outputChannel.products.uniqueLabel(residual)) if (len(MTData) > 0): raise Exception('Untranslated MF data: MFs = %s' % MTData.keys()) if (MT in summedReactions): summedReactions[MT] = [crossSection, outputChannel] info.logs.write('\n') continue EFL = PQUModule.PQU(PQUModule.pqu_float.surmiseSignificantDigits(EFL), 'eV') reaction = reactionModule.reaction(outputChannel, ENDF_MT=MT, EFL=EFL) reaction.crossSection.add(crossSection) reactionSuite.reactions.add(reaction) info.logs.write('\n') for warning in warningList: info.logs.write(" WARNING: %s\n" % warning, stderrWriting=True) if (True): # Need to test for gamma as projectile. for MT in sorted(summedReactions.keys()): if (summedReactions[MT] is None): continue crossSection, outputChannel = summedReactions[MT] summands = [] summandMTs = { 501: range(502, 573), 516: (515, 517), 522: range(534, 573) }[MT] for reaction in reactionSuite: if (reaction.ENDF_MT in summandMTs): summands.append(sumsModule.add(link=reaction.crossSection)) summedCrossSection = sumsModule.crossSectionSum( label=photonSumLabels[MT], ENDF_MT=MT, summands=sumsModule.listOfSummands(summandList=summands), crossSection=crossSection) Q = outputChannel.Q[info.style] if (Q is not None): summedCrossSection.Q.add(Q) reactionSuite.sums.crossSections.add(summedCrossSection) iChannel += 1
def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSectionOnly, doCovariances, verbose): warningList = [] info.totalOrPromptFissionNeutrons = {} info.totalMF6_12_13Gammas = {} if (452 in MTDatas): info.totalOrPromptFissionNeutrons['total'] = getTotalOrPromptFission( info, MTDatas[452][1], 'total', warningList) #MTDatas.pop( 452 ) # don't remove these yet, still need the covariance info if (455 in MTDatas): info.delayedFissionDecayChannel = getDelayedFission( info, MTDatas[455], warningList) #MTDatas.pop( 455 ) if (456 in MTDatas): info.totalOrPromptFissionNeutrons[ tokensModule.promptToken] = getTotalOrPromptFission( info, MTDatas[456][1], tokensModule.promptToken, warningList) #MTDatas.pop( 456 ) if (458 in MTDatas): info.fissionEnergies = getFissionEnergies(info, MTDatas[458], warningList) #MTDatas.pop( 458 ) if (454 in MTDatas): info.independentFissionYields = readMF8_454_459( info, 454, MTDatas[454], warningList) if (459 in MTDatas): info.cumulativeFissionYields = readMF8_454_459(info, 459, MTDatas[459], warningList) sys.stdout.flush() for warning in warningList: info.logs.write(" WARNING: %s\n" % warning, stderrWriting=True) MTList = endfFileToGNDMiscModule.niceSortOfMTs(MTDatas.keys(), verbose=False, logFile=info.logs) haveTotalFission = (18 in MTList) fissionMTs = [mt for mt in MTList if mt in (19, 20, 21, 38)] summedReactions = {} summedReactionsInfo = { 4: range(50, 92), 103: range(600, 650), 104: range(650, 700), 105: range(700, 750), 106: range(750, 800), 107: range(800, 850) } for summedMT, partialReactions in summedReactionsInfo.items(): if (summedMT not in MTList): continue for MT in MTList: if (MT in partialReactions): summedReactions[summedMT] = None break for summedMT in (1, 3): if (summedMT in MTList): summedReactions[summedMT] = None MT5Reaction = None reactions = [] fissionComponents = [] productions = [] nonElastic = [] delayInsertingSummedReaction = [] for MT in MTList: if (MT in MTs2Skip): continue if ((singleMTOnly is not None) and (MT != singleMTOnly)): continue warningList = [] MTData = MTDatas[MT] # Sometimes excited states are identified in MF8. Read this before reading distributions to make sure info is present. LMF, radioactiveDatas = readMF8(info, MT, MTData, warningList) doParseReaction = 3 in MTData if (not (doParseReaction)): if (MT == 3): doParseReaction = (12 in MTData) or (13 in MTData) if (doParseReaction ): # normal reaction, with cross section and distributions try: crossSection, outputChannel, MFKeys = parseReaction( info, info.target, info.projectileZA, info.targetZA, MT, MTData, warningList, parseCrossSectionOnly=parseCrossSectionOnly) except KeyboardInterrupt: raise except: import traceback info.logs.write(traceback.format_exc(), stderrWriting=True) info.doRaise.append(traceback.format_exc()) info.logs.write('\n') sys.stdout.flush() continue info.logs.write('\n') sys.stdout.flush() if (len(MFKeys)): warningList.append( 'For reaction MT = %d, the following MFs were not converted: %s\n' % (MT, MFKeys)) if (outputChannel is None): break if (MT in summedReactions): summedReactions[MT] = [crossSection, outputChannel] else: if (MT != 2): nonElastic.append(MT) reaction = reactionModule.reaction(outputChannel, "%s" % 0, ENDF_MT=MT, date=info.Date) reaction.crossSection.add(crossSection) if (MT == 5): MT5Reaction = reaction elif MT in fissionMTs and haveTotalFission: # this is 1st, 2nd, etc fission but total is also present fissionComponents.append(reaction) else: if (MT in summedReactionsInfo): delayInsertingSummedReaction.append(reaction) else: reactions.append([MT, reaction]) else: MFList = [] for MF in [4, 5, 6, 12, 13, 14, 15]: if (MF in MTData): MFList.append('%d' % MF) if (MFList != ''): warningList.append( 'MT = %d has MF = %s data and no MF 3 data' % (MT, ', '.join(MFList))) for radioactiveData in radioactiveDatas: # Get radioactive production data (if any) from MF 8-10. Cross section form depends on value of LMF. if (LMF in [3, 6, 9]): # Cross section is reference to MF3. productionCrossSection = crossSectionModule.reference( link=reaction.crossSection, label=info.style) elif ( LMF == 10 ): # MF10 data is cross section. Product's multipliticy is 1. productionCrossSection = radioactiveData[2] else: raise Exception( "Unknown LMF=%d encountered in MF=8 for MT=%d" % (LMF, MT)) Q = outputChannel.Q[info.style] if (LMF in [9, 10]): Q = toGNDMisc.returnConstantQ(info.style, radioactiveData[4]) if ( LMF == 6 ): # Product multiplicity is in MF6, so production channel multiplicity needs to refer to it: MF6prod = outputChannel.getProductsWithName( radioactiveData[1].name) if (len(MF6prod) != 1): # CMM: I'm not sure if we need this test anymore warningList.append( 'Unique MT%d radioactive product %s not found in product list!' % (MT, radioactiveData[1].name)) info.doRaise.append(warningList[-1]) continue radioactiveData[1].multiplicity.add( multiplicityModule.reference(label=info.style, link=MF6prod[0].multiplicity)) radioactiveData[1].multiplicity.remove( 'unknown' ) # 'unknown' was put in as a place-holder by readMF8 productionOutputChannel = channelsModule.productionChannel() productionOutputChannel.Q.add(Q) productionOutputChannel.products.add( productionOutputChannel.products.uniqueLabel( radioactiveData[1])) production = productionModule.production(productionOutputChannel, label=-1, ENDF_MT=MT, date=info.Date) production.crossSection.add(productionCrossSection) productions.append(production) for warning in warningList: info.logs.write(" WARNING: %s\n" % warning, stderrWriting=True) iChannel = 0 for MT, reaction in reactions: reaction.setLabel(str(iChannel)) reactionSuite.reactions.add(reaction) iChannel += 1 for reaction in delayInsertingSummedReaction: reaction.setLabel('%s' % iChannel) reactionSuite.reactions.add(reaction) iChannel += 1 if (MT5Reaction is not None): MT5Reaction.setLabel("%s" % iChannel) reactionSuite.reactions.add(MT5Reaction) iChannel += 1 # BRB, The channelIDs should be in a common area????? channelIDs = { 1: 'total', 3: 'nonelastic', 4: '(z,n)', 103: '(z,p)', 104: '(z,d)', 105: '(z,t)', 106: '(z,He3)', 107: '(z,alpha)' } if (3 in summedReactions): summedReactionsInfo[3] = nonElastic if ((1 in summedReactions) and (2 in MTList)): summedReactionsInfo[1] = [2] + nonElastic summedReactionMTs = endfFileToGNDMiscModule.niceSortOfMTs( summedReactions.keys(), verbose=False, logFile=info.logs) for MT in (4, 3, 1): if (MT in summedReactionMTs): summedReactionMTs.remove(MT) summedReactionMTs.insert(0, MT) for i1, MT in enumerate(summedReactionMTs): if (summedReactions[MT] is None): continue crossSection, outputChannel = summedReactions[MT] if ((MT == 3) and (crossSection is None)): crossSection = deriveMT3MF3FromMT1_2(info, reactionSuite) summands = [ sumsModule.add(link=r.crossSection) for r in reactionSuite.reactions if r.ENDF_MT in summedReactionsInfo[MT] ] summedCrossSection = sumsModule.crossSectionSum( name=channelIDs[MT], label=str(i1), ENDF_MT=MT, summands=sumsModule.listOfSummands(summandList=summands), date=info.Date) summedCrossSection.Q.add(outputChannel.Q[info.style]) summedCrossSection.crossSection.add(crossSection) reactionSuite.sums.add(summedCrossSection) gammas = [] for product in outputChannel: if (isinstance(product.particle, xParticleModule.photon)): gammas.append(product) else: if (product.outputChannel is not None): for product2 in product.outputChannel: if (isinstance(product2.particle, xParticleModule.photon)): gammas.append(product2) if (len(gammas) > 0): productChannel = channelsModule.NBodyOutputChannel() for QForm in outputChannel.Q: productChannel.Q.add(QForm) for gamma in gammas: productChannel.products.add( productChannel.products.uniqueLabel(gamma)) productionReaction = productionModule.production(productChannel, str(iChannel), MT, date=info.Date) crossSectionLink = crossSectionModule.reference( link=summedCrossSection.crossSection, label=info.style) productionReaction.crossSection.add(crossSectionLink) reactionSuite.reactions.add(productionReaction) iChannel += 1 for i1, reaction in enumerate( fissionComponents ): # 1st-chance, 2nd-chance, etc. Convert them to fissionComponent instances: fissionComponent = fissionComponentModule.fissionComponent( reaction.outputChannel, str(i1), reaction.ENDF_MT, date=reaction.date) for crossSection in reaction.crossSection: fissionComponent.crossSection.add(crossSection) reactionSuite.fissionComponents.add(fissionComponent) for i1, production in enumerate(productions): production.setLabel("%s" % i1) reactionSuite.productions.add(production) warningList = [] try: # Parse resonance section. mf2 = None if (151 in MTDatas and not parseCrossSectionOnly): mf2 = MTDatas.get(151).get(2) # Resonance data available. if (mf2): info.logs.write(' Reading resonances (MF=2 MT=151)\n') resonances, resonanceMTs = readMF2(info, mf2, warningList) resonances.reconstructCrossSection = ( info.LRP == 1) # LRP was read in from first line of ENDF file if resonances.unresolved and not resonances.resolved: if resonances.unresolved.tabulatedWidths.forSelfShieldingOnly: resonances.reconstructCrossSection = False reactionSuite.addResonances(resonances) # add spins appearing in resonance region to the particle list for particle, spinParity in info.particleSpins.items(): if particle == 'target': particle = reactionSuite.target else: particle = reactionSuite.getParticle(particle) if isinstance(particle, xParticleModule.isotope ) and particle.name not in ('gamma', 'n', 'H1'): # spin should be associated with ground state level: particle.addLevel( xParticleModule.nuclearLevel( name=particle.name + '_e0', energy=PQUModule.PQU('0 eV'), label=0)) particle = particle.levels[0] particle.attributes['spin'] = spinParity[0] if spinParity[1]: particle.attributes['parity'] = spinParity[1] if resonances.reconstructCrossSection: # modify cross sections for relevant channels to indicate resonance contribution is needed: resonanceLink = crossSectionModule.resonanceLink( link=resonances) for MT in resonanceMTs: MTChannels = [ r1 for r1 in reactionSuite.reactions if (r1.getENDL_CS_ENDF_MT()['MT'] == MT) and isinstance(r1, reactionModule.reaction) ] MTChannels += [ r1 for r1 in reactionSuite.sums if (r1.ENDF_MT == MT) ] MTChannels += [ r1 for r1 in reactionSuite.fissionComponents if (r1.getENDL_CS_ENDF_MT()['MT'] == MT) ] if (len(MTChannels) == 0): if (MT in (3, 18, 19)): continue else: warningList.append( 'Unable to find channel corresponding to resonance data for MT%d' % MT) elif (len(MTChannels) == 1): crossSectionComponent = MTChannels[0].crossSection backgroundForm = crossSectionComponent[info.style] crossSectionComponent.remove(backgroundForm.label) crossSectionComponent.add( crossSectionModule.resonancesWithBackground( info.style, backgroundForm, resonanceLink)) else: raise 'hell - FIXME' # This may not be correct. crossSectionComponent = MTChannels[0].crossSection backgroundComponent = crossSectionComponent[ info.style].crossSection backgroundForm = backgroundComponent[info.style] backgroundComponent.remove(backgroundForm.label) referredXSecForm = crossSectionModule.resonancesWithBackground( info.style, backgroundForm, resonanceLink) backgroundComponent.add(referredXSecForm) except BadResonances as e: warningList.append( ' ERROR: unable to parse resonances! Error message: %s' % e) info.doRaise.append(warningList[-1]) if (doCovariances): covarianceMFs = sorted( set([mf for mt in MTDatas.values() for mf in mt.keys() if mf > 30])) if covarianceMFs: info.logs.write(' Reading covariances (MFs %s)\n' % ','.join(map(str, covarianceMFs))) try: """ parse covariances. This also requires setting up links from data to covariances, so we must ensure the links are synchronized """ MTdict = {} for reaction in reactionSuite: MT = reaction.ENDF_MT if MT in MTdict: MTdict[MT].append(reaction) else: MTdict[MT] = [reaction] covarianceSuite, linkData = parseCovariances( info, MTDatas, MTdict, singleMTOnly=singleMTOnly, resonances=getattr(reactionSuite, 'resonances', None)) if (len(covarianceSuite) > 0): covarianceSuite.target = str(info.target) covarianceSuite.projectile = str(info.projectile) covarianceSuite.styles.add(info.evaluatedStyle) #covarianceSuite.removeExtraZeros() # disable for easier comparison to ENDF else: covarianceSuite = None except Exception as e: warningList.append( "Couldn't parse covariances! Error message: %s" % e) info.doRaise.append(warningList[-1]) covarianceSuite = None raise else: covarianceSuite = None for ZA in info.ZA_AWRMasses: mostCount = 0 for AWR in info.ZA_AWRMasses[ZA]: if (info.ZA_AWRMasses[ZA][AWR] > mostCount): mostCount = info.ZA_AWRMasses[ZA][AWR] mostAWR = AWR info.ZA_AWRMasses[ZA] = mostAWR * info.masses.getMassFromZA(1) if (info.level > 0): # AWR is for isomer mass. Adjust info.ZAMasses to GS mass: info.ZA_AWRMasses[info.targetZA] -= PQUModule.PQU( PQUModule.pqu_float.surmiseSignificantDigits(info.level), 'eV/c**2').getValueAs('amu') for particle in reactionSuite.particles: # Fix up any particle whose mass is not defined (i.e., is None). if (particle.name == 'gamma'): continue ZA = nuclear.getZ_A_suffix_andZAFromName(particle.name)[3] mass = particle.getMass('amu') if (ZA in info.ZA_AWRMasses): mass = info.ZA_AWRMasses[ZA] elif ((mass is None) or (ZA in info.ZAMasses)): if (info.ZAMasses[ZA] is None): mass = info.masses.getMassFromZA(ZA) else: mass = abs(info.ZAMasses[ZA]) particle.setMass( PQUModule.PQU(PQUModule.pqu_float.surmiseSignificantDigits(mass), 'amu')) # also add ground state level if there are discrete excited levels. levels = particle.levels.keys() if ('s' in levels): levels.remove('s') if ('c' in levels): levels.remove('c') if ((len(levels) > 0) and (0 not in levels)): # BRB, Caleb, we should not hardwire the '_e0' here, need to implements naming in the xParticle.py module. particle.addLevel( xParticleModule.nuclearLevel( name=particle.name + '_e0', energy=PQUModule.PQU( PQUModule.pqu_float.surmiseSignificantDigits(0), 'eV'), label=0)) MF12BaseMTsAndRange = [[50, 92], [600, 650], [650, 700], [700, 750], [750, 800], [800, 850]] if (singleMTOnly is None): branchingData = None #if( len( info.MF12_LO2 ) > 0 ) : reactionSuite.gammaBranching = {} for MTLO2, MF12_LO2 in sorted(info.MF12_LO2.items( )): # The logic below assumes MTs are in ascending order per base MT. branchingBaseMT = None for MTBase, MTEnd in MF12BaseMTsAndRange: # Determine base MT for this MTLO2 if (MTBase < MTLO2 < MTEnd): branchingBaseMT = MTBase break if (branchingBaseMT is not None): residualZA = endf_endl.ENDF_MTZAEquation( info.projectileZA, info.targetZA, branchingBaseMT)[0][-1] residual = toGNDMisc.getTypeNameENDF(info, residualZA, None) residualName = residual.name level = MTLO2 - branchingBaseMT levelName, levelEnergy = '_e%d' % level, MF12_LO2[0]['ES'] fullName = residualName + levelName levelEnergy_eV = PQUModule.PQU( PQUModule.pqu_float.surmiseSignificantDigits(levelEnergy), 'eV') # compare this value to level energy from the particle list (from MF3 Q-value). particleLevelEnergy_eV = reactionSuite.getParticle( fullName).energy if (levelEnergy_eV.value != particleLevelEnergy_eV.value): if (particleLevelEnergy_eV.value < 1e-12): warningList.append( "MF12 parent level energy (%s) set to zero?" % particleLevelEnergy_eV) info.doRaise.append(warningList[-1]) elif (abs(levelEnergy_eV - particleLevelEnergy_eV) / particleLevelEnergy_eV < 1e-4): MFLabel = '3' # Value with most precision wins. str1 = PQUModule.floatToShortestString( levelEnergy_eV * 1e-20) # 1e-20 to insure e-form is returned. str2 = PQUModule.floatToShortestString( particleLevelEnergy_eV * 1e-20) # Want 1.23e-16 and not 12300 to differ if (len(str1) > len(str2) ): # length from 1.2345e-16 and not 12345. reactionSuite.getParticle( fullName).energy = levelEnergy_eV MFLabel = '12' warningList.append( "MF12 level energy %s differs from MF3 value %s. Setting to MF%s value." % \ ( levelEnergy_eV, particleLevelEnergy_eV, MFLabel ) ) else: warningList.append( "MF12 parent level energy (%s) doesn't match known level" % particleLevelEnergy_eV) info.doRaise.append(warningList[-1]) for MF12 in MF12_LO2: try: finalLevelEnergy = MF12['ESk'] if (finalLevelEnergy > 0.): # find particle in the particleList with energy == finalLevelEnergy finalParticles = [ lev for lev in reactionSuite.getParticle( residualName).levels.values() if lev.energy.getValueAs('eV') == finalLevelEnergy ] if (len(finalParticles) == 1): finalParticle = finalParticles[0] else: # no exact match, look for levels within .01% of the exact value. idx = 0 while (True): idx += 1 finalParticleName = residualName + '_e%i' % idx if (not reactionSuite.hasParticle( finalParticleName)): warningList.append( "MF12 final level energy (%s eV) doesn't match known level when decaying out of level %s " % \ ( finalLevelEnergy, MTLO2 ) ) info.doRaise.append(warningList[-1]) thisLevelEnergy = reactionSuite.getParticle( finalParticleName).energy.getValueAs( 'eV') if (abs(thisLevelEnergy - finalLevelEnergy) < 1e-4 * finalLevelEnergy): finalParticle = reactionSuite.getParticle( finalParticleName) break # found it else: finalParticle = reactionSuite.getParticle( residualName + '_e0') gammaTransition = 1. if (len(MF12['branching']) > 2): gammaTransition = MF12['branching'][1] gamma = xParticleModule.nuclearLevelGamma( finalParticle, MF12['angularSubform'], MF12['branching'][0], 1 - gammaTransition) reactionSuite.getParticle(fullName).addGamma(gamma) except Exception, err: warningList.append( 'raise somewhere in "for MF12 in MF12_LO2" loop: MT%d, %s' % (MT, str(err))) info.doRaise.append(warningList[-1]) else: raise Exception( "Could not determine base MT for MF=12's MT=%s" % MTLO2)
multiplicity = product.multiplicity[info.style] if (hasattr(multiplicity, '_temp_divideByCrossSection')): if (crossSection is None): crossSection = reaction.crossSection.toPointwise_withLinearXYs( ) adjustMF13Multiplicity(multiplicity, crossSection) del multiplicity._temp_divideByCrossSection if (MT in info.totalMF6_12_13Gammas): MF, multiplicity = info.totalMF6_12_13Gammas[MT] if (MF == 13): adjustMF13Multiplicity(multiplicity, crossSection) # BRB, Caleb, why the ',' after gammaProduction. gammaProduction, = [ tmp for tmp in reactionSuite.reactions if tmp.ENDF_MT == MT ] summands = [ sumsModule.add(link=r.multiplicity) for r in gammaProduction.outputChannel.getProductsWithName('gamma') ] if len(summands) == 0: for _product in gammaProduction.outputChannel: if _product.outputChannel is not None: summands += [ sumsModule.add(link=r.multiplicity) for r in _product.outputChannel.getProductsWithName('gamma') ] if MT in channelIDs: name = channelIDs[MT] else: name = str(gammaProduction.outputChannel) multiplicitySum = sumsModule.multiplicitySum( name=name + " total gamma multiplicity", label=str(len(reactionSuite.sums) + 1),
def ITYPE_0( MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSectionOnly, doCovariances, verbose, reconstructResonances=True ) : warningList = [] info.totalOrPromptFissionNeutrons = {} info.totalMF6_12_13Gammas = {} if( 452 in MTDatas ) : info.totalOrPromptFissionNeutrons['total'] = getTotalOrPromptFission( info, MTDatas[452][1], 'total', warningList ) #MTDatas.pop( 452 ) # don't remove these yet, still need the covariance info if( 455 in MTDatas ) : info.delayedFissionDecayChannel = getDelayedFission( info, MTDatas[455], warningList ) #MTDatas.pop( 455 ) if( 456 in MTDatas ) : info.totalOrPromptFissionNeutrons[tokensModule.promptToken] = getTotalOrPromptFission( info, MTDatas[456][1], tokensModule.promptToken, warningList ) #MTDatas.pop( 456 ) if( 458 in MTDatas ) : info.fissionEnergyReleaseData = MTDatas[458] #MTDatas.pop( 458 ) if ( 454 in MTDatas ) : info.independentFissionYields = readMF8_454_459( info, 454, MTDatas[454], warningList ) if ( 459 in MTDatas ) : info.cumulativeFissionYields = readMF8_454_459( info, 459, MTDatas[459], warningList ) sys.stdout.flush( ) for warning in warningList : info.logs.write( " WARNING: %s\n" % warning, stderrWriting = True ) MTList = endfFileToGNDMiscModule.niceSortOfMTs( MTDatas.keys( ), verbose = False, logFile = info.logs ) haveTotalFission = (18 in MTList) fissionMTs = [mt for mt in MTList if mt in (19,20,21,38)] summedReactions = {} summedReactionsInfo = { 4 : range( 50, 92 ), 103 : range( 600, 650 ), 104 : range( 650, 700 ), 105 : range( 700, 750 ), 106 : range( 750, 800 ), 107 : range( 800, 850 ) } for summedMT, partialReactions in summedReactionsInfo.items( ) : if( summedMT not in MTList ) : continue for MT in MTList : if( MT in partialReactions ) : summedReactions[summedMT] = None break for summedMT in ( 1, 3 ) : if( summedMT in MTList ) : summedReactions[summedMT] = None MT5Reaction = None reactions = [] fissionComponents = [] productions = [] nonElastic = [] delayInsertingSummedReaction = [] linksToCheck = [] # links that may need to be updated after reading resonances for MT in MTList : if( MT in MTs2Skip ) : continue if( ( singleMTOnly is not None ) and ( MT != singleMTOnly ) ) : continue warningList = [] MTData = MTDatas[MT] # Sometimes excited states are identified in MF8. Read this before reading distributions to make sure info is present. LMF, radioactiveDatas = readMF8( info, MT, MTData, warningList ) doParseReaction = 3 in MTData if( not( doParseReaction ) ) : if( MT == 3 ) : doParseReaction = ( 12 in MTData ) or ( 13 in MTData ) if( doParseReaction ) : # normal reaction, with cross section and distributions try : crossSection, outputChannel, MFKeys = parseReaction( info, info.target, info.projectileZA, info.targetZA, MT, MTData, warningList, parseCrossSectionOnly = parseCrossSectionOnly ) except KeyboardInterrupt: raise except: import traceback info.logs.write( traceback.format_exc( ), stderrWriting = True ) info.doRaise.append( traceback.format_exc( ) ) info.logs.write( '\n' ) sys.stdout.flush( ) continue info.logs.write( '\n' ) sys.stdout.flush( ) if( len( MFKeys ) ) : warningList.append( 'For reaction MT = %d, the following MFs were not converted: %s\n' % ( MT, MFKeys ) ) if( outputChannel is None ) : break if( MT in summedReactions ) : summedReactions[MT] = [ crossSection, outputChannel ] else : if( MT != 2 ) : nonElastic.append( MT ) reaction = reactionModule.reaction( outputChannel, ENDF_MT = MT ) if( hasattr( info, 'dSigma_form' ) ) : reaction.dCrossSection_dOmega.add( info.dSigma_form ) del info.dSigma_form crossSection = crossSectionModule.CoulombElasticReference( link = reaction.dCrossSection_dOmega.evaluated, label = info.style, relative = True ) reaction.crossSection.add( crossSection ) if( MT == 5 ) : MT5Reaction = reaction elif MT in fissionMTs and haveTotalFission: # this is 1st, 2nd, etc fission but total is also present from fudge.gnd.channelData.fissionEnergyReleased import fissionEnergyReleased if isinstance( reaction.outputChannel.Q.evaluated, fissionEnergyReleased ): Qcomponent = reaction.outputChannel.Q qval = toGNDMiscModule.returnConstantQ( info.style, Qcomponent.evaluated.nonNeutrinoEnergy.data.coefficients[0], crossSection ) Qcomponent.remove( info.style ) Qcomponent.add( qval ) # just put the approximate constant Q-value on 1st-chance, 2nd-chance etc. fissionComponents.append( reaction ) else : if( MT in summedReactionsInfo ) : delayInsertingSummedReaction.append( reaction ) else : reactions.append( [ MT, reaction ] ) else : MFList = [] for MF in [ 4, 5, 6, 12, 13, 14, 15 ] : if( MF in MTData ) : MFList.append( '%d' % MF ) if( MFList != [] ) : warningList.append( 'MT = %d has MF = %s data and no MF 3 data' % ( MT, ', '.join( MFList ) ) ) for radioactiveData in radioactiveDatas : # Get radioactive production data (if any) from MF 8-10. Cross section form depends on value of LMF. if( LMF in [ 3, 6, 9 ] ) : # Cross section is reference to MF3. productionCrossSection = crossSectionModule.reference( link = reaction.crossSection.evaluated, label = info.style ) linksToCheck.append( productionCrossSection ) elif( LMF == 10 ) : # MF10 data is cross section. Product's multipliticy is 1. productionCrossSection = radioactiveData[4] else : raise Exception( "Unknown LMF=%d encountered in MF=8 for MT=%d" % ( LMF, MT ) ) ZAP = radioactiveData[0] ELFS = radioactiveData[1] LFS = radioactiveData[2] Q = outputChannel.Q[info.style] if( LMF in [ 9, 10 ] ) : Q = toGNDMiscModule.returnConstantQ( info.style, radioactiveData[6], crossSection ) if( LMF == 6 ) : # Product multiplicity is in MF6, so production channel multiplicity needs to refer to it: residual = toGNDMiscModule.getTypeNameGamma( info, ZAP, level = ELFS, levelIndex = LFS ) MF6prod = outputChannel.getProductsWithName( residual.id ) if( len( MF6prod ) != 1 ) : # problem appears in JEFF-3.2 Y90 and Y91 warningList.append( 'Unique MT%d radioactive product %s not found in product list!' % ( MT, residual.id ) ) info.doRaise.append( warningList[-1] ) continue multiplicity = multiplicityModule.reference( label = info.style, link = MF6prod[0].multiplicity ) else : multiplicity = radioactiveData[3] try : residual = toGNDMiscModule.newGNDParticle( info, toGNDMiscModule.getTypeNameGamma( info, ZAP, level = ELFS, levelIndex = LFS ), crossSection, multiplicity = multiplicity ) except : info.logs.write( '\nMT = %s\n' % MT ) raise productionOutputChannel = channelsModule.productionChannel( ) productionOutputChannel.Q.add( Q ) productionOutputChannel.products.add( productionOutputChannel.products.uniqueLabel( residual ) ) productionOutputChannel.process = "%s%s" % (reactionSuite.target, endf_endlModule.endfMTtoC_ProductLists[MT].reactionLabel.replace('z,', reactionSuite.projectile+',') ) production = productionModule.production( productionOutputChannel, ENDF_MT = MT ) production.crossSection.add( productionCrossSection ) productions.append( production ) for warning in warningList : info.logs.write( " WARNING: %s\n" % warning, stderrWriting = True ) for MT, reaction in reactions : reactionSuite.reactions.add( reaction ) for reaction in delayInsertingSummedReaction : reactionSuite.reactions.add( reaction ) if( MT5Reaction is not None ) : reactionSuite.reactions.add( MT5Reaction ) # BRB, The channelIDs should be in a common area????? channelIDs = { 1 : 'total', 3 : 'nonelastic', 4 : '(z,n)', 103 : '(z,p)', 104 : '(z,d)', 105 : '(z,t)', 106 : '(z,He3)', 107 :'(z,alpha)' } if( 3 in summedReactions ) : summedReactionsInfo[3] = nonElastic if( ( 1 in summedReactions ) and ( 2 in MTList ) ) : summedReactionsInfo[1] = [ 2 ] + nonElastic summedReactionMTs = endfFileToGNDMiscModule.niceSortOfMTs( summedReactions.keys( ), verbose = False, logFile = info.logs ) for MT in ( 4, 3, 1 ) : if( MT in summedReactionMTs ) : summedReactionMTs.remove( MT ) summedReactionMTs.insert( 0, MT ) for i1, MT in enumerate( summedReactionMTs ) : if( summedReactions[MT] is None ) : continue crossSection, outputChannel = summedReactions[MT] if( ( MT == 3 ) and ( crossSection is None ) ) : crossSection = deriveMT3MF3FromMT1_2( info, reactionSuite ) summands = [ sumsModule.add( link = r.crossSection ) for r in reactionSuite.reactions if r.ENDF_MT in summedReactionsInfo[MT] ] summedCrossSection = sumsModule.crossSectionSum( label = channelIDs[MT], ENDF_MT = MT, summands = sumsModule.listOfSummands( summandList = summands ) ) summedCrossSection.Q.add( outputChannel.Q[info.style] ) summedCrossSection.crossSection.add( crossSection ) reactionSuite.sums.crossSections.add( summedCrossSection ) gammas = [] for product in outputChannel : particle = reactionSuite.PoPs[product.id] if( isinstance( particle, gaugeBosonModule.particle ) ) : gammas.append( product ) else : if( product.outputChannel is not None ) : for product2 in product.outputChannel : particle = reactionSuite.PoPs[product2.id] if( isinstance( particle, gaugeBosonModule.particle ) ) : gammas.append( product2 ) if( len( gammas ) > 0 ) : productChannel = channelsModule.NBodyOutputChannel( ) for QForm in outputChannel.Q : productChannel.Q.add( QForm ) for gamma in gammas : productChannel.products.add( productChannel.products.uniqueLabel( gamma ) ) productionReaction = reactionModule.reaction( productChannel, ENDF_MT = MT, label = str( i1 ) ) crossSectionLink = crossSectionModule.reference( link = summedCrossSection.crossSection.evaluated, label = info.style ) linksToCheck.append( crossSectionLink ) productionReaction.crossSection.add( crossSectionLink ) reactionSuite.orphanProducts.add( productionReaction ) for i1, reaction in enumerate( fissionComponents ) : # 1st-chance, 2nd-chance, etc. Convert them to fissionComponent instances: fissionComponent = fissionComponentModule.fissionComponent( reaction.outputChannel, reaction.ENDF_MT ) for crossSection in reaction.crossSection : fissionComponent.crossSection.add( crossSection ) reactionSuite.fissionComponents.add( fissionComponent ) for i1, production in enumerate( productions ) : reactionSuite.productions.add( production ) if hasattr( info, 'totalDelayedMultiplicity' ): prompt, delayed = [], [] for neutron in reactionSuite.getReaction('fission').outputChannel.getProductsWithName( IDsPoPsModule.neutron ): link_ = sumsModule.add( link = neutron.multiplicity ) if neutron.getAttribute('emissionMode') == tokensModule.delayedToken: delayed.append( link_ ) else: prompt.append( link_ ) delayedNubar = sumsModule.multiplicitySum( label = "delayed fission neutron multiplicity", ENDF_MT = 455, summands = sumsModule.listOfSummands(delayed) ) delayedNubar.multiplicity.add( info.totalDelayedMultiplicity ) reactionSuite.sums.multiplicities.add( delayedNubar ) total = prompt + [sumsModule.add( link = delayedNubar.multiplicity )] totalNubar = sumsModule.multiplicitySum( label = "total fission neutron multiplicity", ENDF_MT = 452, summands = sumsModule.listOfSummands(total) ) totalNubar.multiplicity.add( info.totalOrPromptFissionNeutrons['total'] ) reactionSuite.sums.multiplicities.add( totalNubar ) warningList = [] try : # Parse resonance section. mf2 = None if( 151 in MTDatas and not parseCrossSectionOnly ) : mf2 = MTDatas.get( 151 ).get( 2 ) # Resonance data available. if( mf2 ) : info.logs.write( ' Reading resonances (MF=2 MT=151)\n' ) resonances, resonanceMTs = readMF2( info, mf2, warningList ) kReconstruct = ( info.LRP == 1 ) # LRP was read in from first line of ENDF file if resonances.resolved: resonances.resolved.reconstructCrossSection = kReconstruct reactionSuite.addResonances( resonances ) if resonances.reconstructCrossSection: # modify cross sections for relevant channels to indicate resonance contribution is needed: resonanceLink = crossSectionModule.resonanceLink( link = resonances ) for MT in resonanceMTs : MTChannels = [ r1 for r1 in reactionSuite.reactions if( r1.getENDL_CS_ENDF_MT()['MT'] == MT ) and isinstance(r1, reactionModule.reaction) ] MTChannels += [ r1 for r1 in reactionSuite.sums.crossSections if( r1.ENDF_MT == MT ) ] MTChannels += [ r1 for r1 in reactionSuite.fissionComponents if( r1.getENDL_CS_ENDF_MT()['MT'] == MT ) ] if( len( MTChannels ) == 0 ) : if( MT in ( 3, 18, 19 ) ) : continue else : warningList.append( 'Unable to find channel corresponding to resonance data for MT%d' % MT ) elif( len( MTChannels ) == 1 ) : crossSectionComponent = MTChannels[0].crossSection backgroundForm = crossSectionComponent[info.style] backgroundForm.label = None crossSectionComponent.remove( backgroundForm.label ) crossSectionComponent.add( crossSectionModule.resonancesWithBackground( info.style, backgroundForm, resonanceLink ) ) for link in linksToCheck: if link.link is backgroundForm: link.link = crossSectionComponent[ info.style ] else : raise 'hell - FIXME' # This may not be correct. crossSectionComponent = MTChannels[0].crossSection backgroundComponent = crossSectionComponent[info.style].crossSection backgroundForm = backgroundComponent[info.style] backgroundComponent.remove( backgroundForm.label ) referredXSecForm = crossSectionModule.resonancesWithBackground( info.style, backgroundForm, resonanceLink ) backgroundComponent.add( referredXSecForm ) except BadResonances as e: warningList.append( ' ERROR: unable to parse resonances! Error message: %s' % e ) info.doRaise.append( warningList[-1] ) if( doCovariances ) : covarianceMFs = sorted( set( [mf for mt in MTDatas.values() for mf in mt.keys() if mf>30] ) ) if covarianceMFs: info.logs.write( ' Reading covariances (MFs %s)\n' % ','.join(map(str,covarianceMFs) ) ) try: """ parse covariances. This also requires setting up links from data to covariances, so we must ensure the links are synchronized """ MTdict = {} for reaction in ( list( reactionSuite.reactions ) + list( reactionSuite.sums.crossSections ) + list( reactionSuite.productions ) + list( reactionSuite.fissionComponents ) ) : MT = reaction.ENDF_MT if MT in MTdict: MTdict[MT].append( reaction ) else: MTdict[MT] = [reaction] covarianceSuite, linkData = parseCovariances( info, MTDatas, MTdict, singleMTOnly = singleMTOnly, resonances = getattr( reactionSuite, 'resonances', None ) ) if( len( covarianceSuite ) > 0 ) : covarianceSuite.target = str(info.target) covarianceSuite.projectile = str(info.projectile) covarianceSuite.styles.add( info.evaluatedStyle ) #covarianceSuite.removeExtraZeros() # disable for easier comparison to ENDF else : covarianceSuite = None except Exception as e: warningList.append( "Couldn't parse covariances! Error message: %s" % e ) info.doRaise.append( warningList[-1] ) covarianceSuite = None raise else : covarianceSuite = None info.massTracker.useMostCommonAMUmasses() if( info.level > 0 ) : # AWR is for isomer mass. Adjust info.ZAMasses to GS mass: groundStateMass = info.massTracker.getMassAMU( info.targetZA ) - PQUModule.PQU( PQUModule.pqu_float.surmiseSignificantDigits( info.level ),'eV/c**2').getValueAs('amu') info.massTracker.addMassAMU( info.targetZA, groundStateMass ) # overwrite excited state mass for ZA in info.massTracker.amuMasses : if( ZA in [ 1 ] ) : continue mass = info.massTracker.amuMasses[ZA] elementSymbol = chemicalElementModule.symbolFromZ[ZA/1000] A = str( ZA % 1000 ) name = isotopeModule.isotopeIDFromElementIDAndA( elementSymbol, A ) name = nucleusModule.levelNameFromIsotopeNameAndIndex( name, '0' ) mass = massModule.double( info.PoPsLabel, mass, quantityModule.stringToPhysicalUnit( 'amu' ) ) if( name not in reactionSuite.PoPs ) : toGNDMiscModule.getPoPsParticle( info, ZA, levelIndex = 0 ) particle = reactionSuite.PoPs[name] particle.mass.add( mass ) MF12BaseMTsAndRange = [ [ 50, 92 ], [ 600, 650 ], [ 650, 700 ], [ 700, 750 ], [ 750, 800 ], [ 800, 850 ] ] if( singleMTOnly is None ) : branchingData = None #if( len( info.MF12_LO2 ) > 0 ) : reactionSuite.gammaBranching = {} for MTLO2, MF12_LO2 in sorted(info.MF12_LO2.items()) : # The logic below assumes MTs are in ascending order per base MT. branchingBaseMT = None for MTBase, MTEnd in MF12BaseMTsAndRange : # Determine base MT for this MTLO2 if( MTBase < MTLO2 < MTEnd ) : branchingBaseMT = MTBase break if( branchingBaseMT is not None ) : residualZA = endf_endlModule.ENDF_MTZAEquation( info.projectileZA, info.targetZA, branchingBaseMT )[0][-1] residual = toGNDMiscModule.getTypeNameENDF( info, residualZA, None ) residualName = residual.id if( isinstance( residual, nuclearLevelModule.particle ) ) : residualName = residual.getAncestor( ).id level = MTLO2 - branchingBaseMT levelName, levelEnergy = '_e%d' % level, MF12_LO2[0]['ES'] fullName = residualName + levelName # compare this value to level energy from the particle list (from MF3 Q-value). particleLevelEnergy_eV = reactionSuite.PoPs[fullName].energy[0].value if( levelEnergy != particleLevelEnergy_eV ) : if( particleLevelEnergy_eV < 1e-12 ) : warningList.append( "MF12 parent level energy (%s) set to zero?" % particleLevelEnergy_eV ) info.doRaise.append( warningList[-1] ) elif( abs( levelEnergy - particleLevelEnergy_eV ) < 1e-4 * particleLevelEnergy_eV ) : MFLabel = '3' # Value with most precision wins. str1 = PQUModule.floatToShortestString( levelEnergy * 1e-20 ) # 1e-20 to insure e-form is returned. str2 = PQUModule.floatToShortestString( particleLevelEnergy_eV * 1e-20 ) # Want 1.23e-16 and not 12300 to differ if( len( str1 ) > len( str2 ) ) : # length from 1.2345e-16 and not 12345. reactionSuite.PoPs[fullName].energy[0].value = levelEnergy MFLabel = '12' warningList.append( "MT%d MF12 level energy %s differs from MF3 value %s. Setting to MF%s value." % ( MTLO2, levelEnergy, particleLevelEnergy_eV, MFLabel ) ) else : warningList.append( "MT%d MF12 parent level energy (%s) doesn't match known level" % ( MTLO2, particleLevelEnergy_eV ) ) info.doRaise.append( warningList[-1] ) for i1, MF12 in enumerate( MF12_LO2 ) : try : finalLevelEnergy = MF12['ESk'] if( finalLevelEnergy > 0. ) : # Find particle in the particleList with energy = finalLevelEnergy finalParticles = [ lev for lev in reactionSuite.getParticle( residualName ) if lev.energy.float('eV') == finalLevelEnergy ] if( len( finalParticles ) == 1 ) : finalParticle = finalParticles[0] else : # No exact match, look for levels within .01% of the exact value. idx = 0 while( True ) : idx += 1 finalParticleName = residualName+'_e%i'%idx if( not reactionSuite.hasParticle( finalParticleName ) ) : warningList.append( "MF12 final level energy (%s eV) doesn't match known level when decaying out of level %s " % \ ( finalLevelEnergy, MTLO2 ) ) info.doRaise.append( warningList[-1] ) thisLevelEnergy = reactionSuite.getParticle(finalParticleName).energy.pqu().getValueAs('eV') if( abs( thisLevelEnergy - finalLevelEnergy ) < 1e-4 * finalLevelEnergy ) : finalParticle = reactionSuite.getParticle(finalParticleName) break # found it else : finalParticle = reactionSuite.getParticle(residualName+'_e0') gammaTransition = 1. if( len( MF12['branching'] ) > 2 ) : gammaTransition = MF12['branching'][1] if( gammaTransition != 1 ) : raise Exception( 'Fix me' ) probability = probabilityModule.double( info.PoPsLabel, MF12['branching'][0] ) decayMode = decayDataModule.decayMode( str( i1 ), IDsPoPsModule.photon ) decayMode.probability.add( probability ) _decay = decayDataModule.decay( str( i1 ), decayDataModule.decayModesParticle) _decay.products.add( productModule.product( IDsPoPsModule.photon, IDsPoPsModule.photon ) ) _decay.products.add( productModule.product( finalParticle.id, finalParticle.id ) ) decayMode.decayPath.add( _decay ) reactionSuite.PoPs[fullName].nucleus.decayData.decayModes.add( decayMode ) except Exception, err : raise warningList.append( 'raise somewhere in "for MF12 in MF12_LO2" loop: MT%d, %s' % ( MT, str( err ) ) ) info.doRaise.append( warningList[-1] ) else : raise Exception( "Could not determine base MT for MF=12's MT=%s" % MTLO2 )