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 == 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 setYi( self, yi ) : """Sets self's yi value and self's header yi value to yi. yi must be an integer or a string convertible to an integer.""" iyi = endlmisc.incidentParticleTags( yi )[0] if( ( iyi < 1 ) or ( iyi > 10 ) ) : raise Exception( "\nError in setYi: yi must be in the range [1, 10]" ) self.checkHeader( 1 ) self.yi = iyi syi = "%3d" % iyi self.h[0] = self.h[0][:6] + syi + self.h[0][9:]
def possibleReactions( projectile, target, energy_MeV, maxProducts = 4, bdflsFile = None ) : """This function returns a list of all reactions for the projectile with kinetic energy energy_MeV hitting the stationary target that are allowed by the amount of energy_MeV available in the center-of-mass and a reaction's Q. Reactions considered will only contain products of n_1, H_1, H_2, H_3, He_3, He_4 and a residual. The reactions considered are also limited to the number of outgoing products, not including the residual, being no greater than maxProducts.""" if( bdflsFile is None ) : import bdfls bdflsFile = bdfls.getDefaultBdfls( ) import endlmisc projectile_ = endlmisc.incidentParticleTags( projectile ) projectiles = [ [ 1, 0 ], [ 1001, 0 ], [ 1002, 0 ], [ 1003, 0 ], [ 2003, 0 ], [ 2004, 0 ] ] nProjectiles = len( projectiles ) if( not ( 0 < projectile_[0] <= nProjectiles ) and projectile != 7 ) : raise Exception( '%s is an unsupported projectile' % projectile ) projectileZA = yoToZA( projectile_[0] ) incidentZA = projectileZA + target if projectile != 7: for p in projectiles : p[1] = bdflsFile.mass( p[0] ) if( p[0] == projectileZA ) : projectileMass = p[1] else: projectileMass = 0.0 targetMass = bdflsFile.mass( target ) incidentMass = projectileMass + targetMass kineticMass = energy_MeV / bdflsFile.constant( 4 ) if( kineticMass < 1e-6 * projectileMass ) : # Use non-relativity incidentMass += targetMass * kineticMass / incidentMass else : # Need relativity incidentMass = math.sqrt( incidentMass * incidentMass + 2. * kineticMass * targetMass ) reactions = [] def possibleReactions2( currentZA, products, productMass, level ) : if( level > maxProducts ) : return for ZA, mass in projectiles : residualZA = currentZA - ZA if( residualZA < ZA ) : break Z, A = ZandAFromZA( residualZA ) if( A < Z ) : continue newProducts = products + [ ZA ] newProductMass = productMass + mass if( not( 1 < residualZA < 1001 ) ) : residualMass = bdflsFile.mass( residualZA ) if( residualMass is not None ) : if( incidentMass >= ( residualMass + newProductMass ) ) : reactions.append( newProducts + [ residualZA ] ) possibleReactions2( residualZA, newProducts, newProductMass, level + 1 ) possibleReactions2( incidentZA, [], 0., 1 ) return( reactions )
def reactionEquations( yi_, ZA_, C, level = None, specialCases = 1, printQWarning = True, NameASeperator = "", bdflsFile = None ) : """Given the incident particle yi, target ZA and reaction type C, this routine returns a list of three string for the reaction's equation. The first string is of the form 'yi + ZA -> products + residual + Q' and the second is of the form ZA(yi,products)residual. The third string is of the form (yi,products). For example, reactionEquations( 1, 94239, 13 ) returns the list [ 'n + Pu239n -> 3n + Pu237 + -12.64503 MeV', 'Pu239(n,3n)Pu237', '(n,3n)' ]. If level is not None, """ import endlmisc yi = endlmisc.incidentParticleTags( yi_ )[0] ZA, Suffix = endlmisc.intZASuffix( ZA_ ) Z, A = ZandAFromZA( ZA ) s1 = endl_y.endl_yLabel( ZAToYo( yi ) ) + " + " + symbolForYoOrZA( ZA_, ZAOnly = 1, AddNatural = 0, NameASeperator = NameASeperator ) + " ->" s2 = symbolForYoOrZA( ZA_, ZAOnly = 1, AddNatural = 0, NameASeperator = NameASeperator ) + "(" + endl_y.endl_yLabel( ZAToYo( yi ) ) + "," ZAr, yos, q = residualZA_yos_Q( yi, ZA, C, specialCases = specialCases, printQWarning = printQWarning, bdflsFile = bdflsFile ) if ( ( len( yos ) > 0 ) and ( yos[0] < 0 ) ) : if ( yos[0] == -1 ) : # yo is unknown s1 += " ?" s2 += "?)?" elif ( yos[0] == -2 ) : # yo = yi s1 += " %s + %s" % ( endl_y.endl_yLabel( ZAToYo( yi ) ), symbolForYoOrZA( ZA_, ZAOnly = 1, AddNatural = 0, NameASeperator = NameASeperator ) ) s2 += "%s)%s" % ( endl_y.endl_yLabel( ZAToYo( yi ) ), symbolForYoOrZA( ZA_, ZAOnly = 1, AddNatural = 0, NameASeperator = NameASeperator ) ) elif ( yos[0] == -3 ) : # fission s1 += " fission + ?" s2 += "fission)?" elif ( yos[0] == -4 ) : # Xyo s1 += " X%s + ?" % endl_y.endl_yLabel( ZAToYo( yos[1] ) ) s2 += "X%s)?" % endl_y.endl_yLabel( ZAToYo( yos[1] ) ) else : raise Exception( "\nError in reactionName: invalid yos[0] = %s" % `yos[0]` ) else : n = 1 yo_ = None syo = "" for yo in yos : if ( yo_ is None ) : yo_ = yo elif ( yo != yo_ ) : syo += " + " if ( n > 1 ) : syo += `n` s2 += `n` syo += symbolForYoOrZA( yo_, NameASeperator = NameASeperator ) s2 += symbolForYoOrZA( yo_, NameASeperator = NameASeperator ) + " " n = 1 yo_ = yo else : n += 1 if ( yo_ is not None ) : syo += " + " if ( n > 1 ) : syo += `n` s2 += `n` syo += endl_y.endl_yLabel( ZAToYo( yo_ ) ) s2 += endl_y.endl_yLabel( ZAToYo( yo_ ) ) + " " if ( ( yi == 1 ) and ( C == 11 ) ) or ( ( yi == 2 ) and ( C == 40 ) ) or ( ( yi == 3 ) and ( C == 41 ) ) or \ ( ( yi == 4 ) and ( C == 42 ) ) or ( ( yi == 5 ) and ( C == 44 ) ) or ( ( yi == 6 ) and ( C == 45 ) ) : syo += "'" s2 = s2[:-1] + "'" syo = syo[2:] # remove first " +" if ( q is None ) : qStr = "?" else : qStr = "%.8g MeV" % q if( ZA > 99000 ) and ( ZA <= 99200 ) or ( ZAr is None ) : ZArStr = "?" else : ZArStr = symbolForYoOrZA( ZAr, ZAOnly = 1, AddNatural = 0, NameASeperator = NameASeperator ) if( level is not None ) : ZArStr += '[' + str( level ) + ']' s1 += syo + " + " + ZArStr + " + " + qStr if ( s2[-1] == " " ) : s2 = s2[:-1] s2 += ")" + ZArStr s3 = "" if ( s2.find( "(" ) != -1 ) : s3 = "(" + s2.split( "(" )[1].split( ")" )[0] + ")" return [ s1, s2, s3 ]
def residualZA_yos_Q( yi_, ZA_, C, targetELevel = 0., X4 = 0, specialCases = 1, printQWarning = True, bdflsFile = None ) : """Returns a tuple containing the residual ZA', yos and Q for reaction of type C involving incident particle yi and target ZA. yos is a list. For example, the reation, ZA + yi -> ZA' + yo_1 + yo_2 + ... + yo_n + Q, would return ( ZA', [ yo_1, yo_2, ..., yo_n ], Q ).""" if( bdflsFile is None ) : import bdfls bdflsFile = bdfls.getDefaultBdfls( ) import endlmisc ZA, Suffix = endlmisc.intZASuffix( ZA_ ) if( ( ( ZA % 1000 ) / 100 ) > 7 ) : ZA = ZA % 100 + 1000 * ( ZA / 1000 ) yi = endlmisc.incidentParticleTags( yi_ )[0] if( ( ( yi == 3 ) and ( ZA == 1003 ) and ( C == 30 ) ) or # Added kludge to handle t(d,g n)He reaction. ( ( yi == 4 ) and ( ZA == 1002 ) and ( C == 30 ) ) ) : yos = [ 7, 1 ] else : yos = endl_C.endl_C_yoInfo( C ) if ( yos is None ) or ( yos == () ) : return (None, ( ), None) # No such C-value or C-value does is not a reaction (e.g., C=1). if ( yos[0] == -1 ) : return ( ZA, ( yi, ), None ) # yo unknown. if ( yos[0] == -2 ) : return ( ZA, ( yi, ), 0. ) # yo = yi. if ( yos[0] == -3 ) : return ( None, ( -3, ), None ) # Fission if ( yos[0] == -4 ) : return ( None, ( -4, yos[1] ), None ) # Xyo if ( ZA >= 99000 ) and ( ZA <= 99200 ) : return( None, yos, None ) Zr, Ar = ZandAFromZA( ZA ) Z_A = ZandAFromZA( yoToZA_forNuclei( ZAToYo( yi ) ) ) # yi's Z and A. Zr += Z_A[0] if( Ar != 0 ) : Ar += Z_A[1] ZAr = ZA + yoToZA_forNuclei( ZAToYo( yi ) ) # Add yi's ZA to ZAr. for yo in yos : # Subtract yos' Z, A and ZA from ZAr. if( yo in [ 7, 8, 9 ] ) : continue yo_ = yo if ( yo < 1001 ) : yo_ = yoToZA_forNuclei( yo ) Z_A = ZandAFromZA( yo_ ) Zr -= Z_A[0] if( Ar != 0 ) : Ar -= Z_A[1] ZAr -= yo_ if( Zr < 0 ) : # Check all ok. raise Exception( "\nError in residualZA_yos_Q: bad C-value = %d for ZA = %d and yi = %d" % ( C, ZA, yi ) ) if( specialCases and ( ZAr == 4008 ) ) : # Special case for Be8 -> 2 He (e.g., n + Be9 -> 2 n + (Be8 -> 2 He)). yos = yos + ( 2004, ) Zr, Ar, ZAr = 2, 4, 2004 if( Ar < 0 ) : Ar = 0 if( Ar == 0 ) : return( 1000 * Zr, yos, None ) Remove_yi = True yos_ = [] for yo in yos : # To make math better, do not add and then subtract when yo = yi. try : yo_ = ZAToYo( yo ) except : yo_ = yo if( Remove_yi and ( yo_ == yi ) ) : Remove_yi = False else : if ( yo != 0 ) : yos_.append( yo ) if ( ZAr == ZA ) : ZAyos = 0 for yo in yos : if( yo < 1000 ) : ZAyos += yoToZA_forNuclei( yo ) else : ZAyos += yo q = bdflsFile.mass( yi ) for yo in yos : q -= bdflsFile.mass( yo ) if ( len( yos_ ) == 0 ) or ( ZAyos == yoToZA_forNuclei( yi ) ) : q = ( bdflsFile.constant( 4 ) * q ) q += targetELevel - X4 return ( ZAr, yos, q ) endlmisc.printWarning( "Printing yo list") for yo in yos_ : endlmisc.printWarning( `yo` ) endlmisc.printWarning( "\n" ) raise Exception( "Error in residualZA_yos_Q: ZAr == ZA, but yo list not empty" ) q = 0. if( Remove_yi ) : q += bdflsFile.mass( yi ) for yo in yos_ : q -= bdflsFile.mass( yo ) ZAm = bdflsFile.mass( ZA ) if ( ZAm is None ) : if( printQWarning ) : endlmisc.printWarning( "Warning in residualZA_yos_Q: target ZA = %d not in bdfls file (yi = %d, ZA = %d, C = %d)" % \ ( ZA, yi, ZA, C ) ) q = None else : m = bdflsFile.mass( ZAr ) # Mass of residual. if ( m is None ) : if( printQWarning ) : endlmisc.printWarning( "Warning in residualZA_yos_Q: could not calculate Q as residual ZA = %d" % ZAr + " not in bdfls file (yi = %d, ZA = %d, C = %d)" % ( yi, ZA, C ) ) q = None else : q += bdflsFile.mass( ZA ) - m q *= bdflsFile.constant( 4 ) # Convert AMU to MeVs. if q is not None : q += targetELevel - X4 return ( ZAr, yos, q )
def __init__(self, database=None, projectile=None, yi=None, workDir=None, delWorkDirWhenDone=0, readOnly=0, release='current', bdflsFile=None, cleanWorkDirOfZAs=False): """Creates a new endlProject with database as the default database to use when reading ZAs. If bdflsFile is not None, then it is the bdfls class instance associated with self.""" if (yi != None): endlmisc.printWarning( 'Argument "yi" for Constructor of endlProject is deprecated, please use argument "projectile" instead.' ) if (projectile != None): raise Exception( 'Both "yi" and "projectile" argument specified, only use "projectile".' ) projectile = yi if (database == None): database = fudgeDefaults.ENDL_DEFAULT_DATABASE if (bdflsFile == None): bdflsFileName = None if (os.path.exists('bdfls')): bdflsFileName = './bdfls' # Else logic handled below. else: bdflsFileName = bdflsFile.Source self.readOnly = readOnly or fudgeParameters.ReadOnly self.delWorkDirWhenDone = delWorkDirWhenDone dbInDatabaseName, yiInDatabaseName = os.path.split(database) if (yiInDatabaseName in [ "yi01", "yi02", "yi03", "yi04", "yi05", "yi06", "yi07", "yi09" ]): database = dbInDatabaseName if ((projectile != None) and (yiInDatabaseName != endlmisc.incidentParticleTags(projectile)[1])): raise Exception( "\nError in endlProject.__init__: yi in database name and yi differ" ) projectile = endlmisc.incidentParticleTags(yiInDatabaseName)[5] else: if (projectile == None): projectile = 'n' self.yiTags = endlmisc.incidentParticleTags(projectile) self.name = self.yiTags[5] (self.database, Status) = endlmisc.getFullPath(os.path.join(database, 'ascii'), fudgeDefaults.ENDL_DATABASE_DIR) if (Status == 0): (self.database, Status) = endlmisc.getFullPath(database, fudgeDefaults.ENDL_DATABASE_DIR) if (Status == 0): ( self.database, Status ) = endlmisc.getFullPath( os.path.join( database, 'ascii' ), \ os.path.join( fudgeDefaults.TRANSLATED_DATABASE_DIR, release ) ) if (Status == 0): # File or directory does not exist if (self.yiTags[0] not in [1, 2, 3, 4, 5, 6, 7, 9]): raise Exception( "\nError in endlProject.__init__: invalid projectile = %s" % self.name) self.database = None self.yi = self.yiTags[0] if (fudgeParameters.VerboseMode > 0): print self.yiTags[1] elif (Status == 1): raise Exception( "\nError in endlProject.__init__: database is not a directory") else: self.database = os.path.join(self.database, self.yiTags[1]) if (not os.path.exists(self.database)): self.database = None else: if (bdflsFileName == None): bdflsFileName = os.path.join( os.path.dirname(self.database).split('/ascii')[0], 'bdfls') if (not os.path.exists(bdflsFileName)): bdflsFileName = None self.yi = self.yiTags[0] self.bdflsFile = bdflsFile if (bdflsFile == None): self.bdflsFile = bdfls.getBdflsFile( name=bdflsFileName ) # endlProject relies on bdfls class to search BDFLSPATH self.bdflsFileName = endlmisc.getAbsPath_withDefaultDBCheck( self.bdflsFile.Source)[ 0] # and "/usr/gapps/data/nuclear/bdfls", in that order, self.mass = 0 # for the bdfls file. yoZA = endl2.yoToZA(self.yiTags[0]) if (self.yiTags[0] != 7): self.mass = self.bdflsFile.mass(abs(yoZA)) if (yoZA < 0): yoZA = 0 self.Z, self.A = endl2.ZandAFromZA(yoZA) if (fudgeParameters.VerboseMode > 0): print 'Using bdfls', self.bdflsFileName print self.database gappsDir = os.path.realpath('/usr/gapps/data/nuclear') if self.readOnly: self.workDir = None else: if (workDir == ''): workDir = self.database if (workDir == None): self.workDir = tempfile.mkdtemp() else: self.workDir = workDir if (gappsDir == os.path.realpath(self.workDir)[:len(gappsDir)]): if ('development' not in os.path.realpath(self.workDir)): raise Exception( 'cannot make workDir point to /usr/gapps/data/nuclear, except in a development sub-directory' ) if (not os.path.isdir(self.workDir)): os.makedirs(self.workDir) self.workDir = endlmisc.appendyiDirIfNeeded( self.workDir, self.yiTags[0]) if (not os.path.isdir(self.workDir)): os.makedirs(self.workDir) if (not (self.workDir is None) and cleanWorkDirOfZAs): os.system('rm -rf %s/za[0-9][0-9][0-9][0-9][0-9][0-9]*' % self.workDir) self.zas = [] self.documentation = None if (self.database != None): documentationFileName = os.path.join(self.database, 'documentation.txt') if (os.path.exists(documentationFileName)): self.documentation = fudgeDocumentationFile.fudgeDocumentationFile( documentationFileName) endlProjectList.append(self)