def ENDF_MTZAEquation(projectileZA, targetZA, MT): """ This function returns a python list of length 2. The first element is a list of all outgoing particle ZA's (including the residual) for the reaction of projectileZA + targetZA with ENDF's reaction identifier MT. The second element is a reaction equation for this projectileZA, targetZA and MT. For example ENDF_MTZAEquation( 1, 95242, 22 ) returns ([1, 2004, 93238], 'n + Am242 -> n + He4 + Np238') That is, for a neutron ( projectileZA = 1 ) hitting Am242 ( targetZA = 95242 ) with MT = 22 - ENDF (z,na) reaction - the outgoing particle ZA's are [1, 2004, 93238] and the reaction equation is 'n + Am242 -> n + He4 + Np238'. """ if ((MT < 0) or (MT > 999) or (MT in [1, 3, 5, 10, 18, 19, 20, 21, 27, 38, 101, 151] or (200 < MT < 600) or (850 < MT < 875))): raise Exception('MT = %s is no supported' % MT) elif (MT == 2): productCounts = {nuclear.nucleusNameFromZA(projectileZA): 1} level = None elif (MT == 4): productCounts = {nuclear.nucleusNameFromZA(projectileZA): 1} level = None else: productCounts = endfMTtoC_ProductLists[MT].productCounts level = endfMTtoC_ProductLists[MT].residualLevel compoundZA = projectileZA + targetZA residualZA = compoundZA productCountList = [] adder, equationZA, equation = '', [], '%s + %s ->' % ( nuclear.nucleusNameFromZA(projectileZA), nuclear.nucleusNameFromZA(targetZA)) for product in productCounts: if (product == IDsPoPsModule.photon): productZA = 0 else: productZA = nuclear.getZ_A_suffix_andZAFromName(product)[-1] if (productCounts[product] > 0): productCountList.append( [productZA, product, productCounts[product]]) productCountList.sort() for productZA, token, count in productCountList: residualZA -= count * productZA for idx in xrange(count): equation += ' %s%s' % (adder, token) equationZA.append(productZA) adder = '+ ' levelStr = '' if (not (level is None)): if (type(level) == type(0)): if (level > 0): levelStr = "_e%s" % level elif (type(level) == type('')): if (level == 'c'): levelStr = '_c' else: raise Exception('Unknown level specifier = %s' % level) else: raise Exception('Unknown level specifier = %s' % level) equation += ' %s%s%s' % (adder, nuclear.nucleusNameFromZA(residualZA), levelStr) equationZA.append(residualZA) return (equationZA, equation)
def getParticleNameFromMAT(MAT): Z, MATstuff = divmod(MAT, 100) nStable, nIsomer = divmod((MATstuff - 25), 3) A = endfMATBases[Z] + nStable name = nuclear.nucleusNameFromZA(1000 * Z + A) if nIsomer: name += '_m%i' % nIsomer return name
def __init__(self, isotope, database=None): try: self.ZA = int(isotope) self.isotope = nuclear.nucleusNameFromZA(self.ZA) except: self.isotope = isotope self.ZA = nuclear.getZ_A_suffix_andZAFromName(self.isotope)[3] self.xensl = XENSL(self.ZA, database=database) self.levels = self.xensl.levels self.metastables = {} # example {'m1':'e2'} self.levelMetastables = {} # i.e., { 'e2' : 'm1' } try: self.getMetastables() except AttributeError: self.defineMetastables(isomerMinimumHalflife)
def calculate_a( self, energy_in, energy_out_cmMin, energy_out_cmMax, accuracy = 1e-6 ) : from fudge.core.math import fudgemath from fudge.particles import nuclear def getParticleData( particle ) : Z, A, suffix, ZA = particle.getZ_A_SuffixAndZA( ) return( particle.name, Z, max( 0, A - Z ), A, particle.getMass( 'MeV/c**2' ) ) energyFactor = PQU.PQU( 1, 'MeV' ).getValueAs( self.fSubform.data.axes[-1].unit ) projectile = self.findAttributeInAncestry( 'projectile' ) target = self.findAttributeInAncestry( 'target' ) product = self.findClassInAncestry( fudge.gnd.product.product ).particle name_a, Z_a, N_a, A_a, AWRa = getParticleData( projectile ) name_A, Z_A, N_A, A_A, AWRA = getParticleData( target ) name_b, Z_b, N_b, A_b, AWRb = getParticleData( product ) Z_C, N_C = Z_a + Z_A, N_a + N_A if( N_A == 0 ) : N_C = 0 Z_B, N_B = Z_C - Z_b, max( 0, N_C - N_b ) A_B = Z_B + N_B if( N_B == 0 ) : A_B = 0 particles = self.findClassInAncestry( fudge.gnd.reactionSuite.reactionSuite ).particles residual = particles.getParticle( nuclear.nucleusNameFromZA( 1000 * Z_B + A_B ) ) AWRB = residual.getMass( 'MeV/c**2' ) Ma, Ia = self.KalbachMann_a_parameters[name_a]['M'], self.KalbachMann_a_parameters[name_a]['I'] mb, Ib = self.KalbachMann_a_parameters[name_b]['m'], self.KalbachMann_a_parameters[name_b]['I'] Sa, Sb = energyFactor * self.calculate_S_ab_MeV( Z_A, N_A, Z_C, N_C, Ia ), energyFactor * self.calculate_S_ab_MeV( Z_B, N_B, Z_C, N_C, Ib ) C1, C2, C3 = 0.04 / energyFactor, 1.8e-6 / energyFactor**3, 6.7e-7 / energyFactor**4 ea = energy_in * AWRA / ( AWRa + AWRA ) + Sa R1, R3 = 130 * energyFactor, 41 * energyFactor # MeV to self's energy units. if( ea < R1 ) : R1 = ea if( ea < R3 ) : R3 = ea def calculate_a2( energy_out_cm ) : eb = energy_out_cm * ( AWRb + AWRB ) / AWRB + Sb X1, X3 = R1 * eb / ea, R3 * eb / ea return( X1 * ( C1 + C2 * X1 * X1 ) + C3 * Ma * mb * X3**4 ) class thicken_a : def __init__( self, calculate_a2, relativeTolerance, absoluteTolerance ) : self.calculate_a2 = calculate_a2 self.relativeTolerance = relativeTolerance self.absoluteTolerance = absoluteTolerance def evaluateAtX( self, x ) : return( self.calculate_a2( x ) ) a = [ [ energy_out_cmMin, calculate_a2( energy_out_cmMin ) ], [ energy_out_cmMax, calculate_a2( energy_out_cmMax ) ] ] a = fudgemath.thickenXYList( a, thicken_a( calculate_a2, accuracy, 1e-10 ) ) axes = axesModule.axes( ) axes[0] = axesModule.axis( 'a', 0, '' ) axes[1] = self.fSubform.data.axes[1].copy( ) return( XYsModule.XYs1d( data = a, axes = axes, accuracy = accuracy ) )
def toENDF6( self, style, flags, verbosityIndent = '', covarianceSuite = None ) : evaluatedStyle = self.styles.getEvaluatedStyle( ) if( evaluatedStyle is None ) : raise ValueError( 'no evaluation style found' ) if( flags['verbosity'] >= 10 ) : print '%s%s' % ( verbosityIndent, self.inputParticlesToReactionString( suffix = " -->" ) ) verbosityIndent2 = verbosityIndent + ' ' * ( len( self.inputParticlesToReactionString( suffix = " -->" ) ) + 1 ) projectile, target = self.projectile, self.target projectileZA = projectile.getZ_A_SuffixAndZA( )[-1] IPART = projectileZA if( projectile.name == 'e-' ) : IPART = 11 targetZA, MAT = endf_endl.ZAAndMATFromParticleName( target.name ) targetZ, targetA = divmod( targetZA, 1000 ) targetInfo = processingInfoModule.tempInfo( ) targetInfo['style'] = style targetInfo['reactionSuite'] = self targetInfo['ZA'] = targetZA if( self.particles.hasID( 'n' ) ) : # Need neutron mass in eV/c**2, but it may not be in the particle list. targetInfo['neutronMass'] = self.getParticle( 'n' ).getMass( 'eV/c**2' ) else : neutronAmu = masses.getMassFromZA( 1 ) targetInfo['neutronMass'] = PQU.PQU( neutronAmu, 'amu' ).getValueAs('eV/c**2') if( isinstance( target, fudge.gnd.xParticle.element ) ) : targetInfo['mass'] = elementalMass[targetZA] else : targetInfo['mass'] = target.getMass( 'eV/c**2' ) / targetInfo['neutronMass'] try : targetInfo['LIS'] = target['levelIndex'] except : targetInfo['LIS'] = 0 targetInfo['metastables'] = [] targetInfo['LISO'] = 0 for key, alias in self.aliases.items( ) : if( alias.hasAttribute( 'nuclearMetaStable' ) ) : targetInfo['metastables'].append( alias.getValue() ) if( alias.getValue() == target.name ) : targetInfo['LISO'] = int( alias.getAttribute( 'nuclearMetaStable' ) ) MAT += targetInfo['LISO'] if( self.MAT is not None ) : MAT = self.MAT ITYPE = 0 # Other ITYPE sublibraries not yet supported. BRB is this still true for reaction in self.reactions : if( 500 <= reaction.ENDF_MT < 573 ) : ITYPE = 3 targetInfo['crossSectionMF'] = { 0 : 3, 3 : 23 }[ITYPE] targetInfo['delayedRates'] = [] targetInfo['totalDelayedNubar'] = None targetInfo['MTs'], targetInfo['MF8'], targetInfo['LRs'] = {}, {}, {} endfMFList = { 1 : { 451 : [] }, 2 : {}, 3 : {}, 4 : {}, 5 : {}, 6 : {}, 8 : {}, 9 : {}, 10 : {}, 12 : {}, 13 : {}, 14 : {}, 15 : {}, 23 : {}, 26 : {}, 27 : {}, 31 : {}, 32 : {}, 33 : {}, 34 : {}, 35 : {}, 40 : {} } if( self.resonances is not None ) : # Add resonances, independent of reaction channels self.resonances.toENDF6( endfMFList, flags, targetInfo, verbosityIndent=verbosityIndent2 ) targetInfo['production_gammas'] = {} for reaction in self : reaction.toENDF6( endfMFList, flags, targetInfo, verbosityIndent = verbosityIndent2 ) gndToENDF6Module.upDateENDFMF8Data( endfMFList, targetInfo ) for MT, production_gammas in targetInfo['production_gammas'].items( ) : MF, production_gammas = production_gammas[0], production_gammas[1:] for productionReaction in production_gammas : gammas = [ gamma for gamma in productionReaction.outputChannel ] targetInfo['crossSection'] = productionReaction.crossSection[targetInfo['style']] gndToENDF6Module.gammasToENDF6_MF12_13( MT, MF, endfMFList, flags, targetInfo, gammas ) for particle in self.particles : # gamma decay data. if( isinstance( particle, fudge.gnd.xParticle.isotope ) ) : for level in particle : if( level.gammas ) : # non-empty gamma information for baseMT in [ 50, 600, 650, 700, 750, 800 ] : residualZA = endf_endl.ENDF_MTZAEquation( projectileZA, targetZA, baseMT )[0][-1] if( nuclear.nucleusNameFromZA( residualZA ) == particle.name ) : break level.toENDF6( baseMT, endfMFList, flags, targetInfo ) MFs = sorted( endfMFList.keys( ) ) endfList = [] totalNubar = None totalDelayedNubar = targetInfo['totalDelayedNubar'] if( 455 in endfMFList[5] ) : MF5MT455s = endfMFList[5][455] endfMFList[1][455] = [ endfFormatsModule.endfHeadLine( targetZA, targetInfo['mass'], 0, 2, 0, 0 ) ] # Currently, only LDG = 0, LNU = 2 is supported. endfMFList[1][455] += [ endfFormatsModule.endfHeadLine( 0, 0, 0, 0, len( targetInfo['delayedRates'] ), 0 ) ] endfMFList[1][455] += endfFormatsModule.endfDataList( targetInfo['delayedRates'] ) multiplicityModule.fissionNeutronsToENDF6( 455, totalDelayedNubar, endfMFList, flags, targetInfo ) MF5MT455List = [ endfFormatsModule.endfHeadLine( targetZA, targetInfo['mass'], 0, 0, len( MF5MT455s ), 0 ) ] for MF5MT455 in MF5MT455s : MF5MT455List += MF5MT455 if( len( MF5MT455s ) == 0 ) : del endfMFList[5][455] else : endfMFList[5][455] = MF5MT455List + [ endfFormatsModule.endfSENDLineNumber( ) ] if( 'promptNubar' in targetInfo.dict ) : promptNubar = targetInfo['promptNubar'] multiplicityModule.fissionNeutronsToENDF6( 456, promptNubar, endfMFList, flags, targetInfo ) totalNubar = promptNubar try : if( not( totalDelayedNubar is None ) ) : totalNubar = totalNubar + totalDelayedNubar except : # The following is a kludge for some "bad" data. if( ( totalNubar.domainMax( unitTo = 'MeV' ) == 30. ) and ( totalDelayedNubar.domainMax( unitTo = 'MeV' ) == 20. ) ) : totalDelayedNubar[-1] = [ totalNubar.domainMax( ), totalDelayedNubar.getValue( totalDelayedNubar.domainMax( ) ) ] totalNubar = totalNubar + totalDelayedNubar elif( 'totalNubar' in targetInfo.dict ) : totalNubar = targetInfo['totalNubar'] if( totalNubar is not None ) : multiplicityModule.fissionNeutronsToENDF6( 452, totalNubar, endfMFList, flags, targetInfo ) if( covarianceSuite ) : covarianceSuite.toENDF6( endfMFList, flags, targetInfo ) endfDoc = self.documentation.get( 'endfDoc' ) if( endfDoc is None ) : docHeader2 = [ ' %2d-%-2s-%3d LLNL EVAL-OCT03 Unknown' % ( targetZ, fudge.particles.nuclear.elementSymbolFromZ( targetZ ), targetA ), ' DIST-DEC99 19990101 ', '----ENDL MATERIAL %4d' % MAT, '-----INCIDENT %s DATA' % { 1 : 'NEUTRON', 1001 : 'PROTON', 1002 : 'DEUTERON', 1003 : 'TRITON', 2003 : 'HELION', 2004 : 'ALPHA' }[projectileZA], '------ENDF-6 FORMAT' ] endfDoc = [ 'LLNL ENDL file translated to ENDF6 by FUDGE.', '' ' ************************ C O N T E N T S ***********************' ] else : docHeader2 = [] endfDoc = endfDoc.getLines( ) # update the documentation, including metadata on first 4 lines: try : self.getReaction( 'fission' ) LFI = True except KeyError : LFI = False LRP = -1 if( self.resonances is not None ) : if( self.resonances.scatteringRadius ) : LRP = 0 elif( self.resonances.reconstructCrossSection ) : LRP = 1 elif( self.resonances.unresolved and not( self.resonances.resolved ) and self.resonances.unresolved.tabulatedWidths.forSelfShieldingOnly ) : LRP = 1 else : LRP = 2 EMAX = max( [ reaction.crossSection.domainMax( unitTo = 'eV' ) for reaction in self.reactions ] ) temperature = self.styles[style].temperature.getValueAs( 'K' ) library = evaluatedStyle.library version = evaluatedStyle.version if( library == 'ENDL' ) : # Additional ENDF meta-data. If the library is unknown, use NLIB = -1 NVER, LREL, NMOD = 1, 1, 1 NLIB = -1 else : NVER, LREL, NMOD = map( int, version.split( '.' ) ) # Version stored as '7.2.1' NLIB = { "ENDF/B" : 0, "ENDF/A" : 1, "JEFF" : 2, "EFF" : 3, "ENDF/B (HE)" : 4, "CENDL" : 5, "JENDL" : 6, "SG-23" : 21, "INDL/V" : 31, "INDL/A" : 32, "FENDL" : 33, "IRDF" : 34, "BROND (IAEA version)" : 35, "INGDB-90" : 36, "FENDL/A" : 37, "BROND" : 41 }.get( library, -1 ) NFOR = 6 # ENDF-6 format NSUB = 10 * IPART + ITYPE LDRV = 0 STA = 0 if( isinstance( self.target, fudge.gnd.xParticle.nuclearLevel ) or self.target.attributes.get( 'unstable' ) ) : STA = 1 if( targetInfo['LISO'] ) : STA = 1 levelIndex, level_eV = 0, 0. if( hasattr( self.target, 'getLevelIndex' ) ) : levelIndex, level_eV = self.target.getLevelIndex( ), self.target.getLevelAsFloat( 'eV' ) docHeader = [ endfFormatsModule.endfHeadLine( targetZA, targetInfo['mass'], LRP, LFI, NLIB, NMOD ), endfFormatsModule.endfHeadLine( level_eV, STA, levelIndex, targetInfo['LISO'], 0, NFOR ), endfFormatsModule.endfHeadLine( self.projectile.getMass( 'eV/c**2' ) / targetInfo['neutronMass'], EMAX, LREL, 0, NSUB, NVER ), endfFormatsModule.endfHeadLine( temperature, 0, LDRV, 0, len( endfDoc ), -1 ) ] new_doc = fudge.gnd.documentation.documentation( 'endf', '\n'.join( docHeader + docHeader2 + endfDoc ) ) endfMFList[1][451] += endfFormatsModule.toEndfStringList( new_doc ) return( endfFormatsModule.endfMFListToFinalFile( endfMFList, MAT, lineNumbers = True ) )
def toENDF6(self, style, flags, verbosityIndent='', covarianceSuite=None, useRedsFloatFormat=False, lineNumbers=True, **kwargs): _useRedsFloatFormat = endfFormatsModule.useRedsFloatFormat endfFormatsModule.useRedsFloatFormat = useRedsFloatFormat evaluatedStyle = self.styles.getEvaluatedStyle() if (evaluatedStyle is None): raise ValueError('no evaluation style found') if (flags['verbosity'] >= 10): print '%s%s' % (verbosityIndent, self.inputParticlesToReactionString(suffix=" -->")) verbosityIndent2 = verbosityIndent + ' ' * ( len(self.inputParticlesToReactionString(suffix=" -->")) + 1) projectileZA = miscPoPsModule.ZA(self.PoPs[self.projectile]) IPART = projectileZA if (self.projectile == 'e-'): IPART = 11 targetZA, MAT = endf_endlModule.ZAAndMATFromParticleName(self.target) targetZ, targetA = divmod(targetZA, 1000) targetInfo = {} targetInfo['massTracker'] = massTrackerModule.massTracker() for particle in self.PoPs: if (isinstance(particle, (gaugeBosonPoPsModule.particle, leptonPoPsModule.particle, isotopePoPsModule.suite))): ZA = miscPoPsModule.ZA(particle) if (isinstance(particle, isotopePoPsModule.suite)): if (particle[0].intIndex != 0): continue if (len(particle.mass) > 0): targetInfo['massTracker'].addMassAMU(ZA, particle.getMass('amu')) elif (isinstance(particle, chemicalElementPoPsModule.suite)): ZA = 1000 * particle.Z targetInfo['massTracker'].addMassAMU( ZA, targetInfo['massTracker'].getElementalMassAMU(ZA)) targetInfo['style'] = style targetInfo['reactionSuite'] = self targetInfo['ZA'] = targetZA target = self.PoPs[self.target] levelIndex = 0 levelEnergy_eV = 0 if (isinstance(target, nuclearLevelPoPsModule.particle)): # isomer target levelIndex = target.intIndex levelEnergy_eV = target.energy[0].float('eV') targetInfo['mass'] = targetInfo['massTracker'].getMassAWR( targetZA, levelEnergyInEv=levelEnergy_eV) targetInfo['LIS'] = levelIndex targetInfo['metastables'] = {} targetInfo['LISO'] = 0 if (levelIndex > 0): targetInfo['LISO'] = 1 # BRBBRB for alias in self.PoPs.aliases: if (hasattr(alias, 'metaStableIndex')): targetInfo['metastables'][alias.pid] = alias MAT += targetInfo['LISO'] if (self.MAT is not None): MAT = self.MAT ITYPE = 0 for reaction in self.reactions: if (500 <= reaction.ENDF_MT < 573): ITYPE = 3 targetInfo['crossSectionMF'] = {0: 3, 3: 23}[ITYPE] targetInfo['delayedRates'] = [] targetInfo['MTs'], targetInfo['MF8'], targetInfo['LRs'] = {}, {}, {} endfMFList = { 1: { 451: [] }, 2: {}, 3: {}, 4: {}, 5: {}, 6: {}, 8: {}, 9: {}, 10: {}, 12: {}, 13: {}, 14: {}, 15: {}, 23: {}, 26: {}, 27: {}, 31: {}, 32: {}, 33: {}, 34: {}, 35: {}, 40: {} } if (self.resonances is not None): # Add resonances, independent of reaction channels self.resonances.toENDF6(endfMFList, flags, targetInfo, verbosityIndent=verbosityIndent2) targetInfo['production_gammas'] = {} for multiplicitySum in self.sums.multiplicities: if multiplicitySum.ENDF_MT == 452: targetInfo['totalNubar'] = multiplicitySum.multiplicity.evaluated elif multiplicitySum.ENDF_MT == 455: targetInfo[ 'totalDelayedNubar'] = multiplicitySum.multiplicity.evaluated for reaction in self: reaction.toENDF6(endfMFList, flags, targetInfo, verbosityIndent=verbosityIndent2) gndToENDF6Module.upDateENDFMF8Data(endfMFList, targetInfo) for MT, production_gammas in targetInfo['production_gammas'].items(): MF, production_gammas = production_gammas[0], production_gammas[1:] for productionReaction in production_gammas: gammas = [gamma for gamma in productionReaction.outputChannel] targetInfo['crossSection'] = productionReaction.crossSection[ targetInfo['style']] gndToENDF6Module.gammasToENDF6_MF12_13(MT, MF, endfMFList, flags, targetInfo, gammas) for particle in self.PoPs: if (isinstance(particle, nucleusPoPsModule.particle)): if (len(particle.decayData.decayModes) > 0): for baseMT in [50, 600, 650, 700, 750, 800]: residualZA = endf_endlModule.ENDF_MTZAEquation( projectileZA, targetZA, baseMT)[0][-1] atomID = particle.findClassInAncestry( isotopePoPsModule.suite).id if (nuclearModule.nucleusNameFromZA(residualZA) == atomID): break addDecayGamma(self.PoPs, particle, baseMT, endfMFList, flags, targetInfo) if 'totalNubar' in targetInfo: multiplicityModule.fissionNeutronsToENDF6(452, targetInfo['totalNubar'], endfMFList, flags, targetInfo) if 'promptNubar' in targetInfo: multiplicityModule.fissionNeutronsToENDF6(456, targetInfo['promptNubar'], endfMFList, flags, targetInfo) if 'totalDelayedNubar' in targetInfo: MF5MT455s = endfMFList[5][455] endfMFList[1][455] = [ endfFormatsModule.endfHeadLine(targetZA, targetInfo['mass'], 0, 2, 0, 0) ] # Currently, only LDG = 0, LNU = 2 is supported. endfMFList[1][455] += [ endfFormatsModule.endfHeadLine(0, 0, 0, 0, len(targetInfo['delayedRates']), 0) ] endfMFList[1][455] += endfFormatsModule.endfDataList( targetInfo['delayedRates']) multiplicityModule.fissionNeutronsToENDF6( 455, targetInfo['totalDelayedNubar'], endfMFList, flags, targetInfo) MF5MT455List = [ endfFormatsModule.endfHeadLine(targetZA, targetInfo['mass'], 0, 0, len(MF5MT455s), 0) ] for MF5MT455 in MF5MT455s: MF5MT455List += MF5MT455 if (len(MF5MT455s) == 0): del endfMFList[5][455] else: endfMFList[5][455] = MF5MT455List + [ endfFormatsModule.endfSENDLineNumber() ] if (covarianceSuite): covarianceSuite.toENDF6(endfMFList, flags, targetInfo) endfDoc = self.documentation.get('endfDoc') if (endfDoc is None): docHeader2 = [ ' %2d-%-2s-%3d LLNL EVAL-OCT03 Unknown' % (targetZ, nuclearModule.elementSymbolFromZ(targetZ), targetA), ' DIST-DEC99 19990101 ', '----ENDL MATERIAL %4d' % MAT, '-----INCIDENT %s DATA' % { 1: 'NEUTRON', 1001: 'PROTON', 1002: 'DEUTERON', 1003: 'TRITON', 2003: 'HELION', 2004: 'ALPHA' }[projectileZA], '------ENDF-6 FORMAT' ] endfDoc = [ 'LLNL ENDL file translated to ENDF6 by FUDGE.', '' ' ************************ C O N T E N T S ***********************' ] endlDoc = self.documentation.get('ENDL').getLines() endlDoc2 = [] if endlDoc != None: for line in endlDoc: if 'endep' in line: # remove text from the line before the ones containing 'endep' del endlDoc2[-1] break newline = textwrap.wrap(line, width=66, drop_whitespace=False, subsequent_indent=' ') if len(newline) == 0: newline = [' ' ] # do not let blank lines disappear altogether endlDoc2 += newline endfDoc = endlDoc2 + endfDoc else: docHeader2 = [] endfDoc = endfDoc.getLines() # update the documentation, including metadata on first 4 lines: if self.getReaction('fission') is not None: LFI = True else: LFI = False LRP = -1 if (self.resonances is not None): if (self.resonances.scatteringRadius): LRP = 0 elif (self.resonances.reconstructCrossSection): LRP = 1 elif (self.resonances.unresolved and not self.resonances.resolved): # self-shielding only LRP = 1 else: LRP = 2 crossSectionScale = self.reactions[0].domainUnitConversionFactor('eV') EMAX = max([ crossSectionScale * reaction.crossSection.domainMax for reaction in self.reactions ]) temperature = self.styles[style].temperature.getValueAs('K') library = evaluatedStyle.library version = evaluatedStyle.version if ( library == 'ENDL' ): # Additional ENDF meta-data. If the library is unknown, use NLIB = -1 NVER, LREL, NMOD = 1, 1, 1 NLIB = -1 else: NVER, LREL, NMOD = map(int, version.split('.')) # Version stored as '7.2.1' NLIB = { "ENDF/B": 0, "ENDF/A": 1, "JEFF": 2, "EFF": 3, "ENDF/B (HE)": 4, "CENDL": 5, "JENDL": 6, "SG-23": 21, "INDL/V": 31, "INDL/A": 32, "FENDL": 33, "IRDF": 34, "BROND (IAEA version)": 35, "INGDB-90": 36, "FENDL/A": 37, "BROND": 41 }.get(library, -1) NFOR = 6 # ENDF-6 format NSUB = 10 * IPART + ITYPE LDRV = 0 NLIB = kwargs.get('NLIB', NLIB) STA = 0 target = self.PoPs[self.target] if (isinstance(target, isotopePoPsModule.suite)): target = target[0] if (len(target.nucleus.halflife) > 0): if (target.nucleus.halflife[0].value == halflifePoPsModule.UNSTABLE ): STA = 1 if (levelIndex > 0): STA = 1 projectileMass = targetInfo['massTracker'].getMassAWR(projectileZA, asTarget=False) docHeader = [ endfFormatsModule.endfHeadLine(targetZA, targetInfo['mass'], LRP, LFI, NLIB, NMOD), endfFormatsModule.endfHeadLine(levelEnergy_eV, STA, levelIndex, targetInfo['LISO'], 0, NFOR), endfFormatsModule.endfHeadLine(projectileMass, EMAX, LREL, 0, NSUB, NVER), endfFormatsModule.endfHeadLine(temperature, 0, LDRV, 0, len(docHeader2 + endfDoc), -1) ] new_doc = documentationModule.documentation( 'endf', '\n'.join(docHeader + docHeader2 + endfDoc)) endfMFList[1][451] += endfFormatsModule.toEndfStringList(new_doc) endfFormatsModule.useRedsFloatFormat = _useRedsFloatFormat return (endfFormatsModule.endfMFListToFinalFile(endfMFList, MAT, lineNumbers=lineNumbers))