def nuclides(Z, A, data): symbol = chemicalElementMiscModule.symbolFromZ[Z] isotopeID = chemicalElementMiscModule.isotopeSymbolFromChemicalElementIDAndA( symbol, A) keys = random.sample([key for key in data], len(data)) for index in keys: name = chemicalElementMiscModule.nuclideIDFromIsotopeSymbolAndIndex( isotopeID, index) nameLower = name[:1].lower() + name[1:] level = nuclideModule.particle(name) nucleus = level.nucleus atomicMass, nuclearMass, energy, charge, halflife, spin, parity = data[ index] energy = nuclearEnergyLevelModule.double( 'base', energy, quantityModule.stringToPhysicalUnit('keV')) level.energy.add(energy) if (atomicMass is not None): mass = massModule.double( 'base', atomicMass, quantityModule.stringToPhysicalUnit('amu')) level.mass.add(mass) if (nuclearMass is not None): mass = massModule.double( 'base', nuclearMass, quantityModule.stringToPhysicalUnit('amu')) nucleus.mass.add(mass) if (charge is not None): charge = chargeModule.integer( 'base', charge, quantityModule.stringToPhysicalUnit('e')) nucleus.charge.add(charge) if (halflife is not None): if (halflife == 'stable'): halflife = halflifeModule.string( 'base', halflife, quantityModule.stringToPhysicalUnit('s')) else: time, unit = halflife.split() halflife = halflifeModule.double( 'base', float(time), quantityModule.stringToPhysicalUnit(unit)) nucleus.halflife.add(halflife) if (spin is not None): spin = spinModule.fraction( 'base', spinModule.fraction.toValueType(spin), quantityModule.stringToPhysicalUnit('hbar')) nucleus.spin.add(spin) if (parity is not None): parity = parityModule.integer( 'base', parity, quantityModule.stringToPhysicalUnit('')) nucleus.parity.add(parity) database.add(level)
def addParticleData(particle, info, massValue, spinValue, parityValue, chargeValue, halflifeValue): if (massValue is not None): mass = massModule.double(info.PoPsLabel, massValue, quantityModule.stringToPhysicalUnit('amu')) particle.mass.add(mass) if (spinValue is not None): spin = spinModule.fraction(info.PoPsLabel, fractions.Fraction(spinValue), spinModule.baseUnit) particle.spin.add(spin) if (parityValue is not None): parity = parityModule.integer(info.PoPsLabel, parityValue, parityModule.baseUnit) particle.parity.add(parity) if (chargeValue is not None): charge = chargeModule.integer(info.PoPsLabel, chargeValue, chargeModule.baseUnit) particle.charge.add(charge) if (halflifeValue is not None): if (isinstance(halflifeValue, str)): halflife = halflifeModule.string(info.PoPsLabel, halflifeValue, halflifeModule.baseUnit) else: halflife = halflifeModule.double(info.PoPsLabel, halflifeValue, halflifeModule.baseUnit) particle.halflife.add(halflife)
def nuclearLevel(Z, A, data): symbol = chemicalElementModule.symbolFromZ[Z] isotopeID = isotopeModule.isotopeIDFromElementIDAndA(symbol, A) keys = random.sample([key for key in data], len(data)) for index in keys: mass, energy, charge, halflife, spin, parity = data[index] name = nucleusModule.nucleusNameFromNucleusNameAndIndex( isotopeID, index) nucleus = nucleusModule.particle(name, index) energy = nuclearEnergyLevelModule.double( 'base', energy, quantityModule.stringToPhysicalUnit('keV')) nucleus.energy.add(energy) name = nucleusModule.levelNameFromIsotopeNameAndIndex(isotopeID, index) level = nuclearLevelModule.particle(name, nucleus) if (mass is not None): mass = massModule.double( 'base', mass, quantityModule.stringToPhysicalUnit('amu')) level.mass.add(mass) if (charge is not None): charge = chargeModule.integer( 'base', charge, quantityModule.stringToPhysicalUnit('e')) level.charge.add(charge) if (halflife is not None): time, unit = halflife.split() halflife = halflifeModule.double( 'base', float(time), quantityModule.stringToPhysicalUnit(unit)) level.halflife.add(halflife) if (spin is not None): spin = spinModule.fraction( 'base', spinModule.fraction.toValueType(spin), quantityModule.stringToPhysicalUnit('hbar')) level.spin.add(spin) if (parity is not None): parity = parityModule.integer( 'base', parity, quantityModule.stringToPhysicalUnit('')) level.parity.add(parity) database.add(level)
from PoPs.groups import isotope as isotopeModule A = '16' isotopeID = isotopeModule.isotopeIDFromElementIDAndA('O', A) isotope = isotopeModule.suite(isotopeID, A) data = [['0', 15.99491461956, 0, None, None, None, None], ['1', None, 6049400, None, None, None, None], ['2', None, 6129893, None, None, None, None], ['3', None, 6917100, None, None, None, None]] for index, mass, energy, charge, halflife, spin, parity in data: name = nucleusModule.nucleusNameFromNucleusNameAndIndex(isotopeID, index) nucleus = nucleusModule.particle(name, index) energy = nuclearEnergyLevelModule.double( 'base', energy, quantityModule.stringToPhysicalUnit('eV')) nucleus.energy.add(energy) name = nucleusModule.levelNameFromIsotopeNameAndIndex(isotopeID, index) level = nuclearLevelModule.particle(name, nucleus) if (mass is not None): mass = massModule.double('base', mass, quantityModule.stringToPhysicalUnit('amu')) level.mass.add(mass) if (charge is not None): charge = chargeModule.integer('base', charge, quantityModule.stringToPhysicalUnit('e')) level.charge.add(charge)
from PoPs.quantities import quantity as quantityModule from PoPs.quantities import mass as massModule from PoPs.quantities import spin as spinModule from PoPs.quantities import parity as parityModule from PoPs.quantities import charge as chargeModule from PoPs.quantities import halflife as halflifeModule from PoPs.quantities import nuclearEnergyLevel as nuclearEnergyLevelModule from PoPs.families import nucleus as nucleusModule from PoPs.families import nuclearLevel as nuclearLevelModule index = '3' name = nucleusModule.levelNameFromIsotopeNameAndIndex( 'o16', index ) nucleus = nucleusModule.particle( name, index ) energy = nuclearEnergyLevelModule.double( 'base', 6917100, quantityModule.stringToPhysicalUnit( 'eV' ) ) nucleus.energy.add( energy ) name = nucleusModule.levelNameFromIsotopeNameAndIndex( 'O16', index ) level = nuclearLevelModule.particle( name, nucleus ) mass = massModule.double( 'base', 15.99491461956, quantityModule.stringToPhysicalUnit( 'amu' ) ) level.mass.add( mass ) charge = chargeModule.integer( 'base', 0, quantityModule.stringToPhysicalUnit( 'e' ) ) level.charge.add( charge ) halflife = halflifeModule.double( 'base', 1e100, quantityModule.stringToPhysicalUnit( 's' ) ) level.halflife.add( halflife ) spin = spinModule.fraction( 'base', spinModule.fraction.toValueType( '5/2' ), quantityModule.stringToPhysicalUnit( 'hbar' ) )
# herein do not necessarily state or reflect those of the United States Government or # Lawrence Livermore National Security, LLC, and shall not be used for advertising or # product endorsement purposes. # # <<END-copyright>> from PoPs.quantities import quantity as quantityModule from PoPs.quantities import mass as massModule from PoPs.quantities import spin as spinModule from PoPs.quantities import parity as parityModule from PoPs.quantities import charge as chargeModule from PoPs.quantities import halflife as halflifeModule print '============== MASS ==============' m1 = massModule.double('atomic', 2.12, quantityModule.stringToPhysicalUnit('amu')) xmlm1 = m1.toXML() print xmlm1 m2 = massModule.double.parseXMLStringAsClass(xmlm1) if (xmlm1 != m2.toXML()): raise Exception('Fix me.') print suite = massModule.suite() suite.add(m1) m2 = massModule.double('nuclear', 2, quantityModule.stringToPhysicalUnit('amu')) suite.add(m2) print suite.toXML()
# product endorsement purposes. # # <<END-copyright>> from PoPs.quantities import quantity as quantityModule from PoPs.quantities import mass as massModule from PoPs.quantities import spin as spinModule from PoPs.quantities import parity as parityModule from PoPs.quantities import charge as chargeModule from PoPs.quantities import halflife as halflifeModule from PoPs.families import gaugeBoson as gaugeBosonModule photon = gaugeBosonModule.particle('photon') mass = massModule.double('base', 0, quantityModule.stringToPhysicalUnit('amu')) photon.mass.add(mass) charge = chargeModule.integer('base', 0, quantityModule.stringToPhysicalUnit('e')) photon.charge.add(charge) halflife = halflifeModule.double('base', 1e100, quantityModule.stringToPhysicalUnit('s')) photon.halflife.add(halflife) spin = spinModule.fraction('base', spinModule.fraction.toValueType('1'), quantityModule.stringToPhysicalUnit('hbar')) photon.spin.add(spin) parity = parityModule.integer('base', 1,
from PoPs.quantities import mass as massModule from PoPs.quantities import spin as spinModule from PoPs.quantities import parity as parityModule from PoPs.quantities import charge as chargeModule from PoPs.quantities import halflife as halflifeModule from PoPs.quantities import nuclearEnergyLevel as nuclearEnergyLevelModule from PoPs.families import nuclide as nuclideModule index = 3 name = chemicalElementMiscModule.nuclideIDFromIsotopeSymbolAndIndex( 'O16', index) level = nuclideModule.particle(name) energy = nuclearEnergyLevelModule.double( 'base', 6917100, quantityModule.stringToPhysicalUnit('eV')) level.nucleus.energy.add(energy) mass = massModule.double('base', 15.99491461956, quantityModule.stringToPhysicalUnit('amu')) level.mass.add(mass) charge = chargeModule.integer('base', 0, quantityModule.stringToPhysicalUnit('e')) level.charge.add(charge) halflife = halflifeModule.double('base', 1e100, quantityModule.stringToPhysicalUnit('s')) level.halflife.add(halflife) spin = spinModule.fraction('base', spinModule.fraction.toValueType('5/2'),
'2': [None, 6129893, None, None, None, None], '3': [None, 6917100, None, None, None, None] } symbol = chemicalElementModule.symbolFromZ[8] for A, data in [['17', O16Data], ['16', O16Data]]: isotopeID = isotopeModule.isotopeIDFromElementIDAndA(symbol, A) keys = random.sample([key for key in data], len(data)) for index in keys: mass, energy, charge, halflife, spin, parity = data[index] name = nucleusModule.nucleusNameFromNucleusNameAndIndex( isotopeID, index) nucleus = nucleusModule.particle(name, index) energy = nuclearEnergyLevelModule.double( 'base', energy, quantityModule.stringToPhysicalUnit('keV')) nucleus.energy.add(energy) name = nucleusModule.levelNameFromIsotopeNameAndIndex(isotopeID, index) level = nuclearLevelModule.particle(name, nucleus) if (mass is not None): mass = massModule.double( 'base', mass, quantityModule.stringToPhysicalUnit('amu')) level.mass.add(mass) if (charge is not None): charge = chargeModule.integer( 'base', charge, quantityModule.stringToPhysicalUnit('e')) level.charge.add(charge)
def endfFileToGND(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation=None, MTs2Skip=None, parseCrossSectionOnly=False, toStdOut=True, toStdErr=True, logFile=None, skipBadData=False, doCovariances=True, verboseWarnings=False, verbose=1, reconstructResonances=True, **kwargs): logs = logFiles(toStdOut=toStdOut, toStdErr=toStdErr, logFile=logFile, defaultIsStderrWriting=False) header, MAT, MTDatas = endfFileToGNDMisc.parseENDFByMT_MF(fileName, logFile=logs) styleName = 'eval' reconstructedStyleName = 'recon' if MTs2Skip is None: MTs2Skip = [] # Parse the ENDF documentation section info = readMF1MT451(MAT, MTDatas, styleName=styleName, logFile=logs, verboseWarnings=verboseWarnings, **kwargs) # OK, now decide what to do # First batch of ITYPE's are the special cases if (info.ITYPE == 2): # Thermal scattering law data return (ENDF_ITYPE_2.ITYPE_2(MTDatas, info, verbose=verbose)) elif (info.ITYPE == 4): # Decay data, including SFPY return (ENDF_ITYPE_4.ITYPE_4(MTDatas, info, verbose=verbose)) elif (info.ITYPE == 5): # Decay data, including SFPY return (ENDF_ITYPE_5.ITYPE_5(MTDatas, info, verbose=verbose)) elif (info.ITYPE == 6): # Atomic relaxation data if (info.NSUB not in [6]): raise ValueError('For ITYPE = %d, invalid NSUB = %s' % (info.ITYPE, info.NSUB)) return (ENDF_ITYPE_6.ITYPE_6(info.targetZA / 1000, MTDatas, info, verbose=verbose)) # Second batch of ITYPE's are general transport data if (info.LIS != 0): levelIndex = info.LIS if (info.ITYPE in [ 0, 1, 9 ]): # Nuclear transport data (g, n, p, d, t, h, a), including FPY target = toGNDMisc.getTypeNameGamma(info, info.targetZA, level=info.level, levelIndex=info.levelIndex) targetID = target.id if ((info.STA != 0)): halflife = halflifeModule.string(info.PoPsLabel, halflifeModule.UNSTABLE, halflifeModule.baseUnit) target = info.PoPs[targetID] if (isinstance(target, nuclearLevelModule.particle)): target = target.nucleus if (isinstance(target, isotopeModule.suite)): target = target[0].nucleus if (len(target.halflife) == 0): target.halflife.add(halflife) elif (info.ITYPE == 3): # Atomic transport data (e, x) targetZ = info.targetZA / 1000 targetID = chemicalElementModule.symbolFromZ[targetZ] targetName = chemicalElementModule.nameFromZ[targetZ] info.PoPs.add( chemicalElementModule.suite(targetID, targetZ, targetName)) else: raise ValueError("Unsupported ITYPE = %s" % info.ITYPE) # Add alias if needed for metastable target ZA2, MAT2 = endf_endlModule.ZAAndMATFromParticleName(targetID) MAT2 += info.LISO if (MAT2 != info.MAT): info.logs.write( " WARNING: ENDF MAT = %s not as expected (i.e., %s).\n" % (info.MAT, MAT2), stderrWriting=True) if (info.LISO != 0): targetBaseName = targetID.split('_')[0] aliasName = alias.aliases.nuclearMetaStableName( targetBaseName, info.LISO) info.PoPs.add( PoPsAliasModule.metaStable(aliasName, targetID, info.LISO)) # Compute the reconstructed and evaluated Styles evaluatedStyle = fudge.gnd.styles.evaluated( styleName, '', physicalQuantityModule.temperature( PQUModule.pqu_float.surmiseSignificantDigits( info.targetTemperature), 'K'), info.library, info.libraryVersion, date=info.Date) if (evaluation is None): evaluation = "%s-%d.%d" % (info.library, info.NVER, info.LREL) info.reconstructedStyle = stylesModule.crossSectionReconstructed( reconstructedStyleName, derivedFrom=evaluatedStyle.label, date="2016-11-06") # Stuff for handling transport data info.printBadNK14 = True info.continuumSpectraFix = False info.ignoreMF10Fission = False options = [ 'printBadNK14', 'continuumSpectraFix', 'ignoreBadDate', 'ignoreMF10Fission' ] for option in kwargs: if (option not in options): raise DeprecationWarning('invalid deprecated option "%s"' % option) setattr(info, option, kwargs[option]) info.evaluatedStyle = evaluatedStyle info.reconstructedAccuracy = 0.001 info.MF12_LO2 = {} info.AWR_mode = None info.particleSpins = {} info.missingTwoBodyMasses = {} info.MF4ForNonNeutrons = [] projectile = toGNDMisc.getTypeNameGamma(info, info.projectileZA) # Set up the reactionSuite reactionSuite = reactionSuiteModule.reactionSuite( projectile.id, targetID, evaluation, style=info.evaluatedStyle, documentation=info.documentation, MAT=MAT, PoPs=info.PoPs) MTDatas[451][1] = MTDatas[451][1][:4 + info.NWD] info.reactionSuite = reactionSuite info.PoPs = reactionSuite.PoPs info.target = reactionSuite.target # Set up the covarianceSuite, if needed, and do other ITYPE-specific calculations covarianceSuite = None if ((info.ITYPE == 0) or (info.ITYPE == 9)): doRaise = info.NSUB not in { 0: [0, 10, 10010, 10020, 10030, 20030, 20040], 9: [19] }[info.ITYPE] if (doRaise): raise ValueError('For ITYPE = %d, invalid NSUB = %s' % (info.ITYPE, info.NSUB)) covarianceSuite = ENDF_ITYPE_0.ITYPE_0( MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSectionOnly, doCovariances, verbose, reconstructResonances=reconstructResonances) elif (info.ITYPE in [3, 1]): if (info.NSUB not in [3, 11, 113]): raise ValueError('For ITYPE = %d, invalid NSUB = %s' % (info.ITYPE, info.NSUB)) ENDF_ITYPE_3.ITYPE_3(MTDatas, info, reactionSuite, singleMTOnly, parseCrossSectionOnly, verbose=verbose) # Fill up the reactionSuite for reaction in reactionSuite.reactions: addUnspecifiedDistributions(info, reaction.outputChannel) for production in reactionSuite.productions: addUnspecifiedDistributions(info, production.outputChannel) PoPs = reactionSuite.PoPs lightMasses = { # atomic masses in amu, taken from AME2012 (http://www.nndc.bnl.gov/masses/mass.mas12) 'n': 1.00866491585, 'H1': 1.00782503223, 'H2': 2.01410177812, 'H3': 3.01604927791, 'He3': 3.01602932008, 'He4': 4.00260325413, } for product1ID in info.missingTwoBodyMasses: try: product1Mass = PoPs[product1ID].getMass('amu') except Exception as exc: # FIXME currently getMass raises Exception, should probably be KeyError instead if product1ID in lightMasses: product1Mass = lightMasses[product1ID] PoPs[product1ID].mass.add( massModule.double( info.PoPsLabel, product1Mass, quantityModule.stringToPhysicalUnit('amu'))) else: raise exc massPTmP1 = PoPs[reactionSuite.projectile].getMass( 'amu' ) + PoPs[reactionSuite.target].getMass( 'amu' ) - \ product1Mass summedQM = 0 for product2ID, QM in info.missingTwoBodyMasses[product1ID]: summedQM += QM mass = massPTmP1 - PQUModule.PQU( summedQM / len(info.missingTwoBodyMasses[product1ID]), 'eV/c**2').getValueAs('amu') mass = massModule.double(info.PoPsLabel, mass, quantityModule.stringToPhysicalUnit('amu')) residual = reactionSuite.PoPs[info.missingTwoBodyMasses[product1ID][0] [0]] if (len(residual.mass) == 0): residual.mass.add(mass) # Did we have trouble? if (len(info.MF4ForNonNeutrons) > 0): print ' WARNING: MF=4 data for non-neutron product: MTs = %s' % sorted( info.MF4ForNonNeutrons) if (len(info.doRaise) > 0 and not skipBadData): info.logs.write('\nRaising due to following errors:\n') for err in info.doRaise: info.logs.write(err + '\n') raise Exception('len( info.doRaise ) > 0') return ({ 'reactionSuite': reactionSuite, 'covarianceSuite': covarianceSuite, 'errors': info.doRaise, 'info': info })
def getPoPsParticle(info, ZA, name=None, levelIndex=None, level=0., levelUnit='MeV'): if (levelIndex not in ['c', 's', None]): levelIndex = int(levelIndex) if (levelIndex < 0): raise Exception('levelIndex = %d must be >= 0' % levelIndex) particle = None if (ZA in [0, 17]): ZA = 7 if (name is not None): pass elif (ZA == 1): particle = baryonModule.particle('n') addParticleData(particle, info, 1.00866491574, "1/2", 1, 0, 881.5) name = particle.id elif (ZA == 7): particle = gaugeBosonModule.particle(IDsPoPsModule.photon) addParticleData(particle, info, 0.0, "1", 1, 0, halflifeModule.STABLE) name = particle.id elif (ZA == 8): particle = leptonModule.particle('e+', generation='electronic') # BRB need to make it 'e-_anti' and alias to 'e+'. # particle = leptonModule.particle( 'e-_anti', generation = 'electronic' ) addParticleData(particle, info, 5.485799090e-4, "1/2", -1, 1, halflifeModule.STABLE) name = particle.id elif (ZA == 9): particle = leptonModule.particle('e-', generation='electronic') addParticleData(particle, info, 5.485799090e-4, "1/2", 1, -1, halflifeModule.STABLE) name = particle.id elif (ZA in [99120, 99125]): name = ZAToName(ZA) particle = unorthodoxModule.particle(name) mass = massModule.double(info.PoPsLabel, 117.5, quantityModule.stringToPhysicalUnit('amu')) particle.mass.add(mass) else: name = ZAToName(ZA) if (levelIndex is None): levelIndex = 0 level = 0. if (level < 0.): raise Exception( 'Negative value = %s for continuum is not allowed' % level) if (levelIndex in ['c', 's']): # to continuum or sum of all levels. level = PQUModule.PQU( PQUModule.pqu_float.surmiseSignificantDigits(level), levelUnit) name += "_%s" % levelIndex else: level = PQUModule.PQU( PQUModule.pqu_float.surmiseSignificantDigits(level), levelUnit) name += '_e%d' % levelIndex nucleus = None if ((particle is None) and (name not in info.PoPs)): if (level is not None): # Add a nuclearLevel/isotope. baseName = name.split('_')[ 0] # Always need to add ground state before excited level. if ('natural' in name): baseName = '_'.join(name.split('_')[:2]) elif ('FissionProduct' in name): baseName = name.split('_')[0] index = levelIndex if (level.getValueAs('MeV') == 0.): index = 0 particle = nuclearLevelModule.particle(name) charge = chargeModule.integer(info.PoPsLabel, 0, chargeModule.baseUnit) particle.charge.add(charge) nucleusName = name[0].lower() + name[1:] nucleus = nucleusModule.particle(nucleusName, str(levelIndex)) energy = nuclearEnergyLevelModule.double(info.PoPsLabel, float(level), level.unit) nucleus.energy.add(energy) charge = chargeModule.integer(info.PoPsLabel, ZA / 1000, chargeModule.baseUnit) nucleus.charge.add(charge) particle.nucleus = nucleus addNucleusInfoForLightNuclei(ZA, nucleus, info) else: if (particle is None): if ('FissionProduct' in name): particleOrLevel = gnd.xParticle.FissionProduct( name, mass=massUnit, attributes=particleQualifiers) elif ('TNSL' in name): particleOrLevel = gnd.xParticle.thermalNeutronScatteringLawIsotope( name, mass=massUnit, attributes=particleQualifiers) else: particleOrLevel = gnd.xParticle.isotope( name, mass=massUnit, attributes=particleQualifiers) else: if (particle is None): particle = info.PoPs[name] if (name not in info.PoPs): info.PoPs.add(particle) if (isinstance(particle, nuclearLevelModule.particle)): if (particle.intIndex == 0): particle = particle.getAncestor() return (particle)
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 )
[ '2', None, 6129893, None, None, None, None ], [ '3', None, 6917100, None, None, None, None ] ] Z = 8 symbol = 'O' chemicalElement = chemicalElementModule.suite( symbol, Z, 'Oxygen' ) for A in [ '14', '15', '16', '17', '18' ] : isotopeID = isotopeModule.isotopeIDFromElementIDAndA( symbol, A ) isotope = isotopeModule.suite( isotopeID, A ) if( A == '16' ) : for index, mass, energy, charge, halflife, spin, parity in O16Data : name = nucleusModule.nucleusNameFromNucleusNameAndIndex( isotopeID, index ) nucleus = nucleusModule.particle( name, index ) energy = nuclearEnergyLevelModule.double( 'base', energy, quantityModule.stringToPhysicalUnit( 'eV' ) ) nucleus.energy.add( energy ) name = nucleusModule.levelNameFromIsotopeNameAndIndex( isotopeID, index ) level = nuclearLevelModule.particle( name, nucleus ) if( mass is not None ) : mass = massModule.double( 'base', mass, quantityModule.stringToPhysicalUnit( 'amu' ) ) level.mass.add( mass ) if( charge is not None ) : charge = chargeModule.integer( 'base', charge, quantityModule.stringToPhysicalUnit( 'e' ) ) level.charge.add( charge ) if( halflife is not None ) :