# <<BEGIN-copyright>>
# <<END-copyright>>
"""
This module contains miscellaneous functions.
"""
import math
from fudge.core.utilities import brb
import misc as miscModule
import endl_C
import endl_I
import endl_Z
import endl_y
[docs]def CInfo( w = 4 ) :
"""Prints a list of C and brief description for supported C-values."""
n = endl_C.endl_nCMax( )
l = endl_C.endl_CLabelMaxWidth( )
if( l < 4 ) : l = 4
Fmt = "%%4d %%%ds" % l
Cs = []
i = 1
while( i <= n ) :
s = endl_C.endl_CLabel( i )
if( s is None ) : s = "----"
Cs.append( Fmt % ( i, s ) )
i += 1
brb.tylist( Cs, w = w, sep = " |" )
[docs]def IInfo( ) :
"""Prints a list of I, number of columns and brief description for supported I-values."""
I = 0
print " I cols comment"
print "-----------------"
while( I < 100 ) :
s = endl_I.endl_ILabel( I )
if( s is not None ) :
print "%4d %5d %s" % ( I, endl_I.endl_IColumns( I ), s )
I += 1
[docs]def yInfo( ) :
"""Prints a list of y-id, symbol and name for supported projectiles."""
ls = endl_y.endl_yLabelMaxWidth( )
ll = endl_y.endl_yLongLabelMaxWidth( )
Fmt = " y %%%ds %%%ds" % ( ls, ll )
print Fmt % ( "Symbol", "Name" )
dashes = ( 6 + ls + ll ) * "-"
print dashes
Fmt = "%%4d %%%ds %%%ds" % ( ls, ll )
y = 1
while( 1 ) :
ls = endl_y.endl_yLabel( y )
if( ls is None ) : break
ll = endl_y.endl_yLongLabel( y )
print Fmt % ( y, ls, ll )
y += 1
[docs]def ZInfo( w = 2 ) :
"""Prints a list of Z, symbol and name for most elements."""
n = endl_Z.endl_nZs( )
Zs = []
Z = 0
while( Z < n ) :
Zs.append( "%4d %4s %15s" % ( Z, endl_Z.endl_ZSymbol( Z ), endl_Z.endl_ZLabel( Z ) ) )
Z += 1
brb.tylist( Zs, w = w, sep = " |" )
[docs]def ZAToYo( ZA ) :
"""Returns yo designator for ZA. This mapping is not one-to-one as example
ZA = 1001 could be yo = 2 or 12. The smaller yo values is returned."""
ZA_ = ZA
if( ZA_ > 10 ) and ( ZA_ < 20 ) : ZA_ -= 10
if ZA_ in [ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 1001, 1002, 1003, 2003, 2004 ] :
if ( ZA_ == 0 ) : return 7
if ( ZA_ < 1001 ) : return ZA_
if ( ZA_ == 1001 ) : return 2
if ( ZA_ == 1002 ) : return 3
if ( ZA_ == 1003 ) : return 4
if ( ZA_ == 2003 ) : return 5
if ( ZA_ == 2004 ) : return 6
raise Exception( "\nError in ZAToYo: unsupported ZA value = %s" % `ZA` )
[docs]def yoToZA( yo_i ) :
"""Returns ZA designator, or special code, from yo id. That is, ::
yo_i = 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16
is converted to
0, 1, 1001, 1002, 1003, 2003, 2004, 0, -8, -9, -10, 1, 1001, 1002, 1003, 2003, 2004
with the following meanings ::
none, n, p, d, t, He3, He, g, b+, b-, EC, n, p, d, t, He3, He.
yo_i must be a python integer."""
if ( yo_i < 0 ) or ( yo_i > 16 ) : raise Exception( "\nError in yoToZA: unsupported yo value = %s" % `yo_i` )
yo = yo_i
if ( yo > 10 ) : yo -= 10
return ( 0, 1, 1001, 1002, 1003, 2003, 2004, 0, -8, -9, -10 )[yo]
[docs]def yoToZA_forNuclei( yo ) :
"""Same as yoToZA except returns 0 if yo is in [ 7, 8, 9, 17, 18, 19 ] (i.e., is a gamma, positron or electron)."""
if( yo in [ 7, 8, 9, 17, 18, 19 ] ) : return( 0 )
return( yoToZA( yo ) )
[docs]def ZandAFromZA( ZA ) :
"""Returns the tuple ( Z, A ) from a ZA designator. ZA must be a python integer."""
import endlmisc
ZA_ = endlmisc.intZA( ZA )
Z = ZA_ / 1000
A = ZA_ - 1000 * Z
return ( Z, A )
[docs]def AFromZA( ZA ) :
"""Returns A from ZA designator ( ZA = 1000 * Z + A ). ZA must be a python integer."""
return ZandAFromZA( ZA )[1]
[docs]def ZFromZA( ZA ) :
"""ZFromZA( ZA )
Returns Z from ZA designator ( ZA = 1000 * Z + A ). ZA must be a python integer."""
return ZandAFromZA( ZA )[0]
[docs]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 )
[docs]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 ]
[docs]def reactionQ( yi, ZA, C, targetELevel = 0., X4 = 0, specialCases = 1, printQWarning = True, bdflsFile = None ) :
"""Returns the Q for reaction of type C involving incident particle yi and target ZA. Note,
the target is taken to be in its ground state."""
q = residualZA_yos_Q( yi, ZA, C, targetELevel = targetELevel, X4 = X4, specialCases = specialCases, printQWarning = printQWarning, bdflsFile = bdflsFile )
if ( q[0] is None ) : return None
return q[2]
[docs]def reactionThreshold( yi, ZA, C, targetELevel = 0., residualELevel = 0., Q = None, specialCases = 0, S = None, bdflsFile = None ) :
"""Returns the threshold for this reaction. targetELevel is the excited state of the target
and residualELevel is the excited state of the residual."""
if( bdflsFile is None ) :
import bdfls
bdflsFile = bdfls.getDefaultBdfls( )
QRequired = False
if( AFromZA( ZA ) == 0 ) : # User must enter Q
QRequired = True
elif( 99120 <= ZA <= 99200 ) : # User must enter Q
QRequired = True
elif( C == 1 ) :
raise Exception( 'Error from reactionThreshold: cannot calculate threshold for C = 1 reaction' )
elif( C == 5 ) :
raise Exception( 'Error from reactionThreshold: cannot calculate threshold for C = 5 reaction' )
elif( C == 15 ) : # User must enter Q
QRequired = True
elif( C >= 50 ) : # User must enter Q
QRequired = True
else :
C_ = C
if( S == 1 ) :
yos = endl_C.endl_C_yoInfo( C )
if( len( yos ) > 1 ) : # Attempt to handle breakup of residual properly (e.g., n + C12 --> n + (C12' -> 3a )).
yo = yos[:1]
CList = endl_C.endl_C_CList( )
for Cp in CList :
if( yo == endl_C.endl_C_yoInfo( Cp ) ) :
C_ = Cp
break
Q = reactionQ( yi, ZA, C_, specialCases = specialCases, bdflsFile = bdflsFile )
if( QRequired and ( Q is None ) ) : raise Exception( 'Error from reactionThreshold: user must supply Q for requested ZA = %s or C = %d' % ( `ZA`, C ) )
Threshold = -Q - targetELevel + residualELevel
if( Threshold < 0. ) : Threshold = 0.
r = 1. + bdflsFile.mass( yi ) / bdflsFile.mass( ZA )
Threshold *= r
return( Threshold )
[docs]def symbolForYoOrZA( yoOrZA, NameASeperator = "", ZAOnly = 0, AddNatural = 1, m_to_m1 = False, suffixSeperator = None ) :
"""If ZAOnly == 0 and yoOrZA is a yo type particle then the symbol for its yo is returned;
otherwise, the symbol for ZA is returned. If AddNatural is true, then natural ZAs (i.e.,
those with A = 000 like 12000) have the string 'natural' append to the symbol for the Z,
otherwise, natural targets only contain the symbol. If m_to_m1 is True then when Suffix = 'm'
it is changed to 'm1'."""
return symOrNameForYoOrZA( yoOrZA, 0, ASep = NameASeperator, ZAOnly = ZAOnly, AddNatural = AddNatural, m_to_m1 = m_to_m1, suffixSeperator = suffixSeperator )
[docs]def nameForYoOrZA( yoOrZA, NameASeperator = "", ZAOnly = 0, AddNatural = 1, m_to_m1 = False, suffixSeperator = None ) :
"""If ZAOnly == 0 and yoOrZA is a yo type particle then the name for its yo is returned;
otherwise, the name for ZA is returned. If AddNatural is true, then natural ZAs (i.e.,
those with A = 000 like 12000) have the string 'natural' append to the name for the Z,
otherwise, natural targets only contain the name. If m_to_m1 is True then when Suffix = 'm'
it is changed to 'm1'."""
return symOrNameForYoOrZA( yoOrZA, 1, ASep = NameASeperator, ZAOnly = ZAOnly, AddNatural = AddNatural, m_to_m1 = m_to_m1, suffixSeperator = suffixSeperator )
[docs]def symOrNameForYoOrZA( yoOrZA, wantName, ASep = "", ZAOnly = 0, AddNatural = 1, m_to_m1 = False, suffixSeperator = None ) :
"""For internal use only (see symbolForYoOrZA or nameForYoOrZA)."""
import endlmisc
if( yoOrZA == 1 ) : return 'n'
if( yoOrZA == 7 ) : return 'gamma'
if ( ZAOnly == 0 ) :
try :
ZAyo = ZAToYo( yoOrZA ) # Is ZA a valid yo.
except :
ZAOnly = 1
if ( ZAOnly == 0 ) :
if ( wantName == 0 ) : return endl_y.endl_yLabel( ZAyo )
return endl_y.endl_yLongLabel( ZAyo )
ZA, Suffix = endlmisc.intZASuffix( yoOrZA )
if( m_to_m1 and ( Suffix == 'm' ) ) : Suffix = 'm1'
if( ZA > 99000 ) and ( ZA <= 99200 ) : return "FissionProductENDL%d" % ZA
if( suffixSeperator is None ) : suffixSeperator = ASep
if( Suffix != "" ) : Suffix = suffixSeperator + Suffix
Z, A = ZandAFromZA( ZA )
if ( wantName == 0 ) :
ZStr = endl_Z.endl_ZSymbol( Z )
if ( ZStr is None ) : ZStr = "Unk"
else :
ZStr = endl_Z.endl_ZLabel( Z )
if ( ZStr is None ) : ZStr = "Unknown"
if( A == 0 ) :
if ( AddNatural ) : return ZStr + suffixSeperator + 'natural' + Suffix
return ZStr
return ZStr + ASep + `A` + Suffix
[docs]def endlToGNDSName( yoOrZA ) :
return( symbolForYoOrZA( yoOrZA, NameASeperator = '', ZAOnly = True, AddNatural = True, m_to_m1 = True, suffixSeperator = '_' ) )
[docs]def gndsNameToEndlZ_A_Suffix( name ) :
"""Returns the tuple (Z, A, suffix, ZA) for a gnds isotope name (e.g., gnds name = 'Am242_m1' returns ( 95, 242, 'm1', 95242 )."""
return( miscModule.getZ_A_suffix_andZAFromName( name ) )
[docs]def fileInfo( yi, ZA, fileName ) :
"""Obtains yo, C, I and S from fileName and calls reactionInfo."""
import endlmisc
( yo, C, I, S ) = endlmisc.intYoCIS( fileName )
return reactionInfo( yi, ZA, yo, C, I, S )
[docs]def reactionInfo( yi, ZA, yo, C, I, S, bdflsFile = None ) :
"""Returns a string of 5 lines. The first 3 lines are the item return by reactionEquations.
The fourth is "Elastic" if C = 10 else it is a blank line, and the last is "total cross section"
if I == 0 and C == 0, else it is the string return by endl_I.endl_ILabel."""
r = reactionEquations( yi, ZA, C, bdflsFile = bdflsFile )
s = r[0] + "\n" # Line 1 done
s += r[1] + "\n" # Line 2 done
s += r[2] + "\n" # Line 3 done
if ( C == 10 ) : s += "Elastic"
s += "\n" # Line 4 done
if ( I == 0 ) and ( C == 0 ) :
s += "total cross section"
else :
s += endl_I.endl_ILabel( I )
s += "\n" # Line 5 done
return s
[docs]def reactionQByZAs( incomingZAs, outgoingZAs, bdflsFile = None ) :
"""Returns the Q in MeV for the reaction, that is, the (sum of incoming masses) - (sum of outgoing mass) in MeV.
Returns None if at least one of the masses is unknown."""
if( bdflsFile is None ) :
import bdfls
bdflsFile = bdfls.getDefaultBdfls( )
ZAMultiplicities = {}
for ZA in incomingZAs :
if( ZA < 1000 ) : ZA = yoToZA_forNuclei( ZA )
if( ZA not in ZAMultiplicities ) : ZAMultiplicities[ZA] = 0
ZAMultiplicities[ZA] += 1
for ZA in outgoingZAs :
if( ZA < 1000 ) : ZA = yoToZA_forNuclei( ZA )
if( ZA not in ZAMultiplicities ) : ZAMultiplicities[ZA] = 0
ZAMultiplicities[ZA] -= 1
mass = 0.
ZAs = ZAMultiplicities.keys( )
ZAs.sort( )
for ZA in ZAs :
m = bdflsFile.mass( ZA )
if( m is None ) : return( None )
mass += m * ZAMultiplicities[ZA]
return( mass * bdflsFile.constant( 4 ) )
[docs]def reactionQByIsotopeNames( incomingNames, outgoingNames, bdflsFile = None ) :
"""Returns the Q in MeV for the reaction, that is, the (sum of incoming masses) - (sum of outgoing mass) in MeV.
Returns None if at least one of the masses is unknown. This routine only works for isotopes in the ground state as it
converts each name to it ZA and calls reactionQByZAs (see reactionQByZAs for more details). Example,
incomingNames = [ 'n', 'W186' ]
outgoingNames = [ 'H3', 'He4', 'Tm176' ]
Q = reactionQByIsotopeNames( incomingNames, outgoingNames )"""
incomingZAs = [ gndsNameToEndlZ_A_Suffix( name )[-1] for name in incomingNames ]
outgoingZAs = [ gndsNameToEndlZ_A_Suffix( name )[-1] for name in outgoingNames ]
return( reactionQByZAs( incomingZAs, outgoingZAs, bdflsFile ) )
[docs]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 )