Source code for fudge.legacy.endl.endlFile

# <<BEGIN-copyright>>
# <<END-copyright>>

"""
This module contains the class endlFile. See class endlFile for usage.
"""

import os
import time
from fudge.core.utilities import fudgeExceptions
import bdfls
import endl2
import endlIClasses
import endlmisc

checkQThreshold = True

[docs]class endlFile : """This class holds data that is contained in an ENDL file. (In general, this class should only be instantiated indirectly via methods in endlZA.) An ENDL data file can contains one or more related data sets, each specified by a unique set of X1, X2, X3, X4 values, for a specific set of yo, C, I and S values. As example, for the cross section, I = 0, for inelastic scattering of a neutron, C = 11, the target may be left in different excited states. In ENDL ths cross sections to specific excited state, S = 1, are stored in a file named "yo00c11i000s001", and the data for different excited states are distinguished by different excitation levels, X1-value, for the target. When the read method for this class gets the data from this file it creates a new endlI0 object for each data set and addes it to the levels member of this class. The number of data sets (i.e., length of levels) is return by the len method for the endlFile object. No data is read in when the object is instantiated; instead, the read method must be explicitly called. Useful Members:: name The file's name. path The full path, include name, of this file. ZA The ENDL ZA-value for this file. ZA = 1000 * Z + A. yi The ENDL yi-value for this file. That is, the projectile for this file. yo The ENDL yo-value for this file. That is, the outgoing particle for this file. C The ENDL C-value for this file. I The ENDL I-value for this file. S The ENDL S-value for this file. levels A list of endlI* objects for each data sets in file. This is empty until the method read is called. """ def __init__( self, designerFile, name, path, ZA, yi, halflife = None, bdflsFile = None ) : """In general, this routine should be used indirectly via endlZA.read( ) or endlZA.addFile( ) and not called directly, unless you know what you are doing.""" if( bdflsFile is None ) : bdflsFile = bdfls.getDefaultBdfls( ) self.bdflsFile = bdflsFile self.designerFile = designerFile self.name = name self.path = path self.ZA = ZA self.yiTags = endlmisc.incidentParticleTags( yi ) self.yi = self.yiTags[0] self.yo = int( name[2:4] ) self.C = int( name[5:7] ) self.I = int( name[8:11] ) self.S = int( name[12:15] ) self.mode = endlmisc.getmodestring_( self.I, "endlFile.__init__" ) self.halflife = halflife # Added so uses can input for natural ZA because the halflife is not in the bdfls file. self.levels = [] def __len__( self ) : """Returns the number of levels for self.""" return len( self.levels ) def __getitem__( self, index ) : """Returns the (i-1)^th item from self.levels.""" if( self.levels == [] ) : raise Exception( "File not read in." ) return( self.levels[index] ) def __repr__( self ) : """Returns the string 'R# filename' where R is 'r' if the data has been read in and is '-' if it has not been, '#' is the number of columns of data and file name is the name of the file (e.g. 'r2 yo00c01i000s000').""" r = "r" if( self.levels == [] ) : r = "-" return r + self.mode + " " + self.name
[docs] def check( self, targetParameters, dQ_MeV = 10e-3, dThreshold_MeV = 10e-3, allowZeroE = False, xCloseEps = None, normTolerance = 1e-5, maxAbsFloatValue = None ) : """Checks self's data if it as been read in. This is, it goes through the list levels, calling the appropriate routines to check data.""" suffix = os.path.basename(self.path.rstrip(self.name).rstrip(os.sep))[8:] ErrMsgs = [] X1 = X2 = X3 = X4 = None for l in self.levels : if( ( ( self.C == 1 ) and ( self.I == 0 ) ) or ( self.C == 5 ) ) : Threshold = 0. Q = 0. elif( self.C == 6 ) : Threshold = 0. Q = 0. elif( ( endl2.AFromZA( l.ZA ) == 0 ) or ( 99120 <= l.ZA <= 99200 ) or ( self.C == 15 ) or ( self.C >= 50 ) ) : Q = l.getQ( ) else : Q = endl2.reactionQ( l.yi, l.ZA, l.C, targetELevel = l.getELevel( ), X4 = l.getX4( ), specialCases = 1, bdflsFile = self.bdflsFile ) if( l.S in [ 1 ] ) : residualELevel = l.getX1( ) else : residualELevel = l.getX4( ) Threshold = endl2.reactionThreshold( l.yi, l.ZA, l.C, targetELevel = l.getELevel( ), residualELevel = residualELevel, Q = l.getQ( ), S = self.S, bdflsFile = self.bdflsFile ) r = 1. + self.bdflsFile.mass( self.yi ) / self.bdflsFile.mass( self.ZA ) QThreshold = ( -l.getQ( ) ) * r if( QThreshold <= 0. ) : QThreshold = 0. if( targetParameters['T'] is None ) : targetParameters['T'] = l.Temperature targetParameters['ELevel'] = l.ELevel targetParameters['halflife'] = l.Halflife if( ( targetParameters['T'] != l.Temperature ) or ( targetParameters['ELevel'] != l.ELevel ) or ( targetParameters['halflife'] != l.Halflife ) ) : ErrMsgs.append( endlmisc.endlCheckerObject( suffix = suffix, data = l, message = 'target parameters differ' ) ) elif( X1 is not None ) : if( ( X1 == l.X1 ) and ( X2 == l.X2 ) and ( X3 == l.X3 ) and ( X4 == l.X4 ) ) : ErrMsgs.append( endlmisc.endlCheckerObject( suffix = suffix, data = l, message = 'duplicate data' ) ) X1 = l.X1; X2 = l.X2; X3 = l.X3; X4 = l.X4 if( abs( l.getQ( ) - Q ) > dQ_MeV ) : ErrMsgs.append( endlmisc.endlCheckerObject( suffix = suffix, data = l, message = 'bad Q: should be %.4e' % Q ) ) if( ( self.C != 6 ) and( hasattr( l, "getThresholdsForChecker" ) ) ) : thresholds = l.getThresholdsForChecker( ) iT = 0 _dThreshold_MeV = dThreshold_MeV for t in thresholds : # Currently, thresholds is the first min( n, 2 ) Energy points in the data where n is the length of the data. if( checkQThreshold ) : if( t + _dThreshold_MeV < QThreshold ) : ErrMsgs.append( endlmisc.endlCheckerObject( suffix = suffix, data = l, \ message = 'bad QThreshold: should be %.8e at index = %d instead of %.8e' % ( QThreshold, iT, t ) ) ) else : if( t + _dThreshold_MeV < Threshold ) : ErrMsgs.append( endlmisc.endlCheckerObject( suffix = suffix, data = l, \ message = 'bad threshold: should be %.8e at index = %d instead of %.8e' % ( Threshold, iT, t ) ) ) if( l.I != 4 ) : _dThreshold_MeV = 0. # The second point must be higher than the threshold else ndfgen may fail. iT += 1 ErrMsgs += l.check( printWarning = False, printErrors = False, allowZeroE = allowZeroE, xCloseEps = xCloseEps, normTolerance = normTolerance, \ maxAbsFloatValue = maxAbsFloatValue ) return( ErrMsgs )
[docs] def setYiZAYoCISs( self, yi = None, ZA = None, yo = None, C = None, I = None, S = None ) : """Fixes the headers in all of file's levels to match yo, C, I and S. For input parameters that are None, self's values are used. Also sets self's yi and ZA to inputted values if they are other than None.""" if( yi is None ) : yi = self.yi if( ZA is None ) : ZA = self.ZA if( yo is None ) : yo = self.yo if( C is None ) : C = self.C if( I is None ) : I = self.I if( S is None ) : S = self.S self.yi = yi self.ZA = ZA self.yo = yo self.C = C self.I = I self.S = S self.name = 'yo%.2dc%.2di%.3ds%.3d' % ( yo, C, I, S ) for l in self.levels : l.setYiZAYoCIS( yi = yi, ZA = ZA, yo = yo, C = C, I = I, S = S )
[docs] def IsyoCIS( self, yo = None, C = None, I = None, S = None ) : """Returns 1 if self matches yo, C, I and S, and 0 otherwise. yo may be a single integer or a list of integers and the same for C, I and S. For example self has yo = 7 and C = 3 then self.IsyoCIS( yo = (5, 6, 7), C=(3,4) ) will return a true.""" if( yo is not None ) : if( ( type( yo ) == type( [] ) ) or ( type( yo ) == type( () ) ) ) : yo2 = yo yo = [] for y in yo2 : yo.append( endlmisc.outgoingParticleTags( y )[0] ) else : yo = endlmisc.outgoingParticleTags( yo )[0] if ( ( type( yo ) != type( [] ) ) and ( type( yo ) != type( () ) ) ) : yo = ( yo, ) if ( ( type( C ) != type( [] ) ) and ( type( C ) != type( () ) ) ) : C = ( C, ) if ( ( type( I ) != type( [] ) ) and ( type( I ) != type( () ) ) ) : I = ( I, ) if ( ( type( S ) != type( [] ) ) and ( type( S ) != type( () ) ) ) : S = ( S, ) if ( ( self.yo in yo ) or ( yo == ( None, ) ) ) and \ ( ( self.C in C ) or ( C == ( None, ) ) ) and \ ( ( self.I in I ) or ( I == ( None, ) ) ) and \ ( ( self.S in S ) or ( S == ( None, ) ) ) : return 1 return 0
[docs] def unreadData( self, X1 = None, X2 = None, X3 = None, X4 = None, Q = None ) : """Removes self's reference to data matching X1, X2, X3, X4 and Q. Note, the data may still be in the work directory if the file is not saved.""" i = len( self.levels ) while( i > 0 ) : i -= 1 l = self.levels[i] if ( ( l.X1 == X1 ) or ( X1 is None ) ) and ( ( l.X2 == X2 ) or ( X2 is None ) ) and \ ( ( l.X3 == X3 ) or ( X3 is None ) ) and ( ( l.X4 == X4 ) or ( X4 is None ) ) and \ ( ( l.Q == Q ) or ( Q is None ) ) : del self.levels[i]
[docs] def addData( self, data = [], date = None, interpolation = 0, eLevel = 0., temperature = 2.586e-8, Q = None, X1 = 0., X2 = 0., X3 = 0., X4 = 0., mass = None, halflife = None ) : """Adds data to self with the header information provided.""" i = 0 for l in self.levels : c = l.compareQXs( Q, X1, X2, X3, X4 ) if( c == 0 ) : raise Exception( "\nError in endlFile.addData: data already exist for X1 = %e, X2 = %e, X3 = %e, X4 = %e, Q = %e" % ( X1, X2, X3, X4, l.Q ) ) elif ( c > 0 ) : break i += 1 if( Q is None ) : Q = 0. if ( len( self.levels ) > 0 ) : Q = self.levels[0].Q if( date is None ) : date = time.localtime( time.time( ) ) date = 10000 * ( date[0] - 2000 ) + 100 * date[1] + date[2] if( type( date ) == type( 1 ) ) : date = "%.6d" % date if( mass is None ) : mass = self.bdflsFile.mass( self.ZA ) if( mass is None ) : raise Exception( "\nError in endlFile.addData: bdfls file does not have mass for ZA = %d" % self.ZA ) mass = endlmisc.headerFunkyDouble2String( mass ) if( halflife is None ) : halflife = self.bdflsFile.halflife( self.ZA ) if( halflife is None ) : halflife = self.halflife if( halflife is None ) : raise Exception( "\nError in endlFile.addData: bdfls file does not have halflife for ZA = %d" % self.ZA ) halflife = endlmisc.headerFunkyDouble2String( halflife ) h = [ "%6d %2d %2d %s %6s%1d12 %s %s %s\n" % ( self.ZA, self.yi, self.yo, mass, date, interpolation, endlmisc.headerFunkyDouble2String( eLevel ), halflife, endlmisc.headerFunkyDouble2String( temperature ) ), "%2d%3d%3d %s %s %s %s %s\n" % ( self.C, self.I, self.S, endlmisc.headerFunkyDouble2String( Q ), endlmisc.headerFunkyDouble2String( X1), endlmisc.headerFunkyDouble2String( X2), endlmisc.headerFunkyDouble2String( X3), endlmisc.headerFunkyDouble2String( X4 ) ) ] # # ???? Need to check that data is proper type of data. # d = endlIClasses.endlAddIObject( None, self.yo, self.C, self.I, self.S, h, data, bdflsFile = self.bdflsFile ) self.levels.insert( i, d ) return self.levels[i]
[docs] def addEndlData( self, endlData, overWrite = 0 ) : """Adds the data in the endl object endlData to self. enldData must be of an endlI* class that must match self's I class. For example, if self is I = 11 data then endlData be must an endlI11 object. Currently, overWrite is not implemented.""" # THIS NEEDS WORKD???? if( ( endlData.I != self.I ) or ( endlData.S != self.S ) or ( endlData.C != self.C ) or ( endlData.yo != self.yo ) ) : raise Exception( "( endlData.I != self.I ) or ( endlData.S != self.S ) or ( endlData.C != self.C ) or ( endlData.yo != self.yo )" ) i = 0 for l in self.levels : c = l.compareQXs( endlData.Q, endlData.X1, endlData.X2, endlData.X3, endlData.X4 ) if( c == 0 ) : raise Exception( "Data already exist for X1 = %e, X2 = %e, X3 = %e, X4 = %e, Q = %e for yo = %d C = %d, I = %d and S =%d" % ( l.X1, l.X2, l.X3, l.X4, l.Q, self.yo, self.C, self.I, self.S ) ) elif( c > 0 ) : break i += 1 points = endlData.copyData( ) o = endlIClasses.endlAddIObject( None, endlData.yo, endlData.C, endlData.I, endlData.S, endlData.h, points, bdflsFile = self.bdflsFile ) self.levels.insert( i, o ) return o
[docs] def columns( self ) : """Returns the number of data columns for self's data. For example, for 3d data a 3 is returned.""" return endlmisc.getNumberOfColumns_( self.I, "endlFile.columns" )
[docs] def info( self ) : """Prints information about each level in self (i.e., call info for each element of self.levels.""" for i in range( len( self.levels ) ) : print "levels[%d]" % i self.levels[i].info( ) print
[docs] def ls( self ) : """Prints file name, and level information for self.""" print self.name s = "" for i in range( len( self.levels ) ) : s = s + ( " levels[%d] %s" % ( i, `self.levels[i]` ) ) print s
[docs] def read( self ) : """Reads in the data from self's file.""" if ( not os.path.isfile( self.path ) ) : raise Exception( "\nError in endlFile.read: no such file %s" % self.path ) f = open( self.path ) level = 1 while 1 : d = endlIClasses.endlAddIObject( f, self.yo, self.C, self.I, self.S, None, [], bdflsFile = self.bdflsFile ) if ( d.h[0] == "" ) : break slevel = None if( ( self.C == 11 ) and ( self.S == 1 ) ) : slevel = level d.label = endl2.reactionEquations( self.yi, self.ZA, self.C, level = slevel, printQWarning = False )[1] self.levels.append( d ) level += 1 f.close( )
[docs] def save( self, f ) : """Saves data to file f where f is a python file type (e.g., sys.stdout).""" for l in self.levels : l.save( f )