From c41aa8fa25a6893f0e480b6c076641ad746ea625 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 8 Jan 2025 12:49:02 -0500 Subject: [PATCH 01/13] latex escapes in comments --- .../CoulombPlusNuclearElastic.py | 14 +++++----- .../RutherfordScattering.py | 28 +++++++++---------- .../chargedParticleElastic/misc.py | 2 +- .../nuclearAmplitudeExpansion.py | 8 +++--- .../nuclearPlusInterference.py | 20 ++++++------- 5 files changed, 36 insertions(+), 36 deletions(-) diff --git a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/CoulombPlusNuclearElastic.py b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/CoulombPlusNuclearElastic.py index b4f8739f..7a0cf2bb 100644 --- a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/CoulombPlusNuclearElastic.py +++ b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/CoulombPlusNuclearElastic.py @@ -118,14 +118,14 @@ def spin( self ) : @property def etaCoefficient( self ) : - """This function returns the parameter :math:`\eta \, \sqrt{E} = Z_1 \, Z_2 \, sqrt{\alpha^2 \mu m_1 / 2}`.""" + """This function returns the parameter :math:`\\eta \\, \\sqrt{E} = Z_1 \\, Z_2 \\, sqrt{\\alpha^2 \\mu m_1 / 2}`.""" self.initialize( ) return( self.__etaCoefficient ) @property def kCoefficient( self ) : - """This function returns the coefficient for the particle wave number (i.e., :math:`k(E) / \sqrt{E}`).""" + """This function returns the coefficient for the particle wave number (i.e., :math:`k(E) / \\sqrt{E}`).""" self.initialize( ) return( self.__kCoefficient ) @@ -220,15 +220,15 @@ def initialize( self ): def dSigma_dMu(self, energy, muCutoff, accuracy=1e-3, epsilon=1e-6, excludeRutherfordScattering=False, probability=False): """ - This function returns :math:`d\sigma / d\mu` at the specified incident energy if *probability* is False and :math:`P(\mu)` otherwise - if True.. The :math:`\mu` domain goes from muMin to *muCutoff*. For identical particles, muMin is set to -*muCutoff* otherwise it is -1. + This function returns :math:`d\\sigma / d\\mu` at the specified incident energy if *probability* is False and :math:`P(\mu)` otherwise + if True.. The :math:`\\mu` domain goes from muMin to *muCutoff*. For identical particles, muMin is set to -*muCutoff* otherwise it is -1. :param energy: Energy of the projectile. - :param muCutoff: The maximum (and maybe minimum) value of :math:`\mu` for the returned function. + :param muCutoff: The maximum (and maybe minimum) value of :math:`\\mu` for the returned function. :param accuracy: The accuracy of the returned function. :param epsilon: This variable is not used. :param excludeRutherfordScattering: If True, Rutherford scattering is not added to the returned function, otherwise it is. - :param probability: If True :math:`P(\mu)` is returned otherwise :math:`d\sigma / d\mu` is returned. + :param probability: If True :math:`P(\\mu)` is returned otherwise :math:`d\\sigma / d\\mu` is returned. :return: An instance of :py:class:`angularModule.XYs1d`. """ @@ -290,7 +290,7 @@ def calculateAverageProductData( self, style, indent = '', **kwargs ) : def processCoulombPlusNuclearMuCutoff( self, style, energyMin = None, accuracy = 1e-3, epsilon = 1e-6, excludeRutherfordScattering = False ) : """ - This function returns the cross section and angular distribution for :math:`\mu` from muMin to muMax. + This function returns the cross section and angular distribution for :math:`\\mu` from muMin to muMax. For identical particles, muMin is set to -muMax otherwise it is -1. The value of muMax is the *muCufoff* member of *style*. diff --git a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/RutherfordScattering.py b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/RutherfordScattering.py index 1e1f7f97..1cdc918b 100644 --- a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/RutherfordScattering.py +++ b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/RutherfordScattering.py @@ -52,7 +52,7 @@ def __init__(self, domainMin=None, domainMax=None, domainUnit=None ): @property def etaCoefficient( self ) : - r"""This method returns the parameter :math:`\eta \, \sqrt{E} = Z_1 \, Z_2 \, sqrt{\alpha^2 \mu m_1 / 2}`.""" + """This method returns the parameter :math:`\\eta \\, \\sqrt{E} = Z_1 \\, Z_2 \\, sqrt{\\alpha^2 \\mu m_1 / 2}`.""" return( self.ancestor.etaCoefficient ) @@ -64,7 +64,7 @@ def spin( self ) : @property def kCoefficient( self ) : - r"""This function returns the coefficient for the particle wave number (i.e., :math:`k(E) / \sqrt{E}`).""" + """This function returns the coefficient for the particle wave number (i.e., :math:`k(E) / \\sqrt{E}`).""" return( self.ancestor.kCoefficient ) @@ -89,11 +89,11 @@ def convertUnits( self, unitMap ): self.domainUnit = newUnit def crossSectionVersusEnergy(self, muMax, accuracy=1e-3, energyMin=None, energyMax=None): - r""" - Returns the partial Rutherford cross section by Integrating :math:`d\sigma / d\mu` from muMin to *muMax*. For identical particles, muMin + """ + Returns the partial Rutherford cross section by Integrating :math:`d\\sigma / d\\mu` from muMin to *muMax*. For identical particles, muMin is set to -*muMax* otherwise it is -1. - :param muMax: The upper limit for the :amth:`\mu` integration. + :param muMax: The upper limit for the :amth:`\\mu` integration. :param accuracy: The lin-lin interpolation accuracy of the returned cross section. :param energyMin: The minimum projectile energy for the returned cross section. :param energyMax: The maximum projectile energy for the returned cross section. @@ -130,10 +130,10 @@ def evaluateAtX(self, energy): def dSigma_dMuVersusEnergy(self, muMax, accuracy=1e-3, energyMin=None, energyMax=None): - r""" - Returns :math:`d\sigma(E) / d\mu`. + """ + Returns :math:`d\\sigma(E) / d\\mu`. - :param muMax: The upper limit for the :amth:`\mu` integration. + :param muMax: The upper limit for the :amth:`\\mu` integration. :param accuracy: The lin-lin interpolation accuracy of the returned cross section. :param energyMin: The minimum projectile energy for the returned cross section. :param energyMax: The maximum projectile energy for the returned cross section. @@ -159,13 +159,13 @@ def dSigma_dMuVersusEnergy(self, muMax, accuracy=1e-3, energyMin=None, energyMax return xys2d def dSigma_dMu(self, energy, accuracy=1e-3, muMax=0.999, probability=False): - r""" - Returns :math:`d\sigma / d\mu` at the specified projdctile energy if *probability* is False, otherwise :math:`P(mu)` is returned.. + """ + Returns :math:`d\\sigma / d\\mu` at the specified projdctile energy if *probability* is False, otherwise :math:`P(mu)` is returned.. :param energy: Energy of the projectile. :param accuracy: The lin-lin interpolation accuracy of the returned data. :param muMax: Slices the upper domain mu to this value. - :param probability: If True :math:`P(mu)` is returned instead of :math:`d\sigma / d\mu`. + :param probability: If True :math:`P(mu)` is returned instead of :math:`d\\sigma / d\\mu`. :return: A :py:class:`angularModule.XYs1d` instance. """ @@ -224,10 +224,10 @@ def energyDomain(self, energyMin=None, energyMax=None): return energyUnit, energyMin, energyMax def evaluate( self, energy, mu, phi = 0.0 ) : - r""" - Returns the :math:`d\sigma / d \Omega(energy,\mu,\phi) for Rutherford scattering. Note, Rutherford + """ + Returns the :math:`d\\sigma / d \\Omega(energy,\\mu,\\phi) for Rutherford scattering. Note, Rutherford scattering is independent of phi but phi is listed as an argument to be consistent with others - :math:`d\sigma / d\Omega` that may depend on phi. + :math:`d\\sigma / d\\Omega` that may depend on phi. :param energy: Projectile energy. :param mu: Scattering angle cosine. diff --git a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/misc.py b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/misc.py index 9266f7e0..8cdce6ef 100644 --- a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/misc.py +++ b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/misc.py @@ -149,7 +149,7 @@ def fixMuRange(data, epsilon=1e-6): """ This function ensures that the range of mu in *data* is [-1, 1] by adding 0.0's to the missing ranges. Note, *data* is modified. - :param data: A python list of :math:`P(\mu)`. + :param data: A python list of :math:`P(\\mu)`. :param epsilon: The relative amount to add a point below (above) the first (last) point in addition to the point at -1 (1). """ diff --git a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearAmplitudeExpansion.py b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearAmplitudeExpansion.py index a7983b09..faf4cb55 100644 --- a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearAmplitudeExpansion.py +++ b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearAmplitudeExpansion.py @@ -96,7 +96,7 @@ def __init__( self, nuclearTerm = None, realInterference = None, imaginaryInterf @property def etaCoefficient( self ) : - """This method returns the parameter :math:`\eta \, \sqrt{E} = Z_1 \, Z_2 \, sqrt{\alpha^2 \mu m_1 / 2}`.""" + """This method returns the parameter :math:`\\eta \\, \\sqrt{E} = Z_1 \\, Z_2 \\, sqrt{\\alpha^2 \\mu m_1 / 2}`.""" return( self.ancestor.etaCoefficient ) @@ -207,7 +207,7 @@ def convertUnits( self, unitMap ): def dSigma_dMu(self, energy, accuracy=1e-3, muMax=0.999, probability=False): """ - This function returns :math:`d\sigma / d\mu` at the specified incident energy. + This function returns :math:`d\\sigma / d\\mu` at the specified incident energy. :param energy: Energy of the projectile. :param accuracy: The accuracy of the returned *dSigma_dMu*. @@ -219,7 +219,7 @@ def dSigma_dMu(self, energy, accuracy=1e-3, muMax=0.999, probability=False): class Tester : """ - This class is used to added point to :math:`d\sigma / d\mu` until the desired lin-lin interpolation is met. + This class is used to added point to :math:`d\\sigma / d\\mu` until the desired lin-lin interpolation is met. This class is for internal use. """ @@ -238,7 +238,7 @@ def __init__( self, evaluate, energy, relativeTolerance, absoluteTolerance ) : def evaluateAtX( self, mu ) : """ - This function returns *self* evaluated at a projectile energy and outgoing :math:`\mu`. + This function returns *self* evaluated at a projectile energy and outgoing :math:`\\mu`. :param mu: The mu point to evaluate *self* at. """ diff --git a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearPlusInterference.py b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearPlusInterference.py index ed4c70ec..e779cd2d 100644 --- a/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearPlusInterference.py +++ b/fudge/reactionData/doubleDifferentialCrossSection/chargedParticleElastic/nuclearPlusInterference.py @@ -36,7 +36,7 @@ class CrossSection(miscModule.ChargedParticleElasticTerm): """ - This class represents the :math:`\sigma(E)` part of :math:`\sigma(E) \, P(\mu|E)` + This class represents the :math:`\\sigma(E)` part of :math:`\\sigma(E) \\, P(\\mu|E)` """ moniker = 'crossSection' @@ -45,7 +45,7 @@ class CrossSection(miscModule.ChargedParticleElasticTerm): class Distribution( miscModule.ChargedParticleElasticTerm): """ - This class represents the :math:`P(\mu|E)` part of :math:`\sigma(E) \, P(\mu|E)`. + This class represents the :math:`P(\\mu|E)` part of :math:`\\sigma(E) \\, P(\\mu|E)`. """ moniker = 'distribution' @@ -56,8 +56,8 @@ class Distribution( miscModule.ChargedParticleElasticTerm): class NuclearPlusInterference( ancestryModule.AncestryIO ): """ This class represents the nuclear + interference term of the elastic scattering of two nuclei and - stores the double differential cross section as the product :math:`\sigma(E) \, P(\mu|E)`. - In :math:`P(\mu|E)` the :math:`\mu` ranges from muMin to muCutoff where muCutoff is a member of this + stores the double differential cross section as the product :math:`\\sigma(E) \\, P(\\mu|E)`. + In :math:`P(\\mu|E)` the :math:`\\mu` ranges from muMin to muCutoff where muCutoff is a member of this class and muMin is -muCutoff for identical particles and -1 otherwise. The following table list the primary members of this class: @@ -65,7 +65,7 @@ class and muMin is -muCutoff for identical particles and -1 otherwise. +-------------------+-------------------------------------------------------------------------------+ | Member | Description | +===================+===============================================================================+ - | muCutoff | The maximum :math:`\mu` value the data represent. | + | muCutoff | The maximum :math:`\\mu` value the data represent. | +-------------------+-------------------------------------------------------------------------------+ | crossSection | The cross section part of the nuclear + interference term. | +-------------------+-------------------------------------------------------------------------------+ @@ -77,7 +77,7 @@ class and muMin is -muCutoff for identical particles and -1 otherwise. def __init__( self, muCutoff, crossSection = None, distribution = None ): """ - :param muCutoff: The maximum :math:`\mu` value the data represent. + :param muCutoff: The maximum :math:`\\mu` value the data represent. :param crossSection: The cross section part of the nuclear + interference term. :param distribution: The distribution part of the nuclear + interference term. """ @@ -175,7 +175,7 @@ def convertUnits( self, unitMap ): def dSigma_dMu(self, energy, accuracy=1e-3, muMax=None, probability=False): """ - Returns :math:`d\sigma / d\mu` at the specified projdctile energy. + Returns :math:`d\\sigma / d\\mu` at the specified projdctile energy. :param energy: Energy of the projectile. :param accuracy: This argument is not used. @@ -207,10 +207,10 @@ def dSigma_dMu(self, energy, accuracy=1e-3, muMax=None, probability=False): return _dSigma_dMu def evaluate( self, E, mu, phi = 0.0 ) : - r""" - Returns the :math:`d\sigma / d \Omega(energy,\mu,\phi) for Rutherford scattering. Note, Rutherford + """ + Returns the :math:`d\\sigma / d \\Omega(energy,\\mu,\\phi) for Rutherford scattering. Note, Rutherford scattering is independent of phi but phi is listed as an argument to be consistent with others - :math:`d\sigma / d\Omega` that may depend on phi. + :math:`d\\sigma / d\\Omega` that may depend on phi. :param energy: Projectile energy. :param mu: Scattering angle cosine. From 9cca874992c37b351c447a72666a8a9039f8eb96 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 8 Jan 2025 12:52:00 -0500 Subject: [PATCH 02/13] np.mat obsolute, use np.asmatrix --- fudge/covariances/mixed.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fudge/covariances/mixed.py b/fudge/covariances/mixed.py index 1de2fef5..9a07017c 100644 --- a/fudge/covariances/mixed.py +++ b/fudge/covariances/mixed.py @@ -221,11 +221,11 @@ def add_values(v1,v2): commonColAxis.values.values = add_values(commonColAxis.values, cc.matrix.axes[1].values) # Now sum up the components - commonMatrix = numpy.mat( firstCovMtx.group( ( commonRowAxis.values.values, commonColAxis.values.values ), + commonMatrix = numpy.asmatrix( firstCovMtx.group( ( commonRowAxis.values.values, commonColAxis.values.values ), ( commonRowAxis.unit, commonColAxis.unit ) ).matrix.array.constructArray() ) for c in summands[1:]: cc = make_common_type(c) - commonMatrix += numpy.mat( cc.group( ( commonRowAxis.values.values, commonColAxis.values.values ), + commonMatrix += numpy.asmatrix( cc.group( ( commonRowAxis.values.values, commonColAxis.values.values ), ( commonRowAxis.unit, commonColAxis.unit ) ).matrix.array.constructArray() ) # Now create the instance of the resulting CovarianceMatrix From c0729eca02f6a9d69c6541e360340c29737e528e Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 8 Jan 2025 13:16:57 -0500 Subject: [PATCH 03/13] port to newer x4i version --- brownies/BNL/plot_evaluation/__init__.py | 40 +++++++++--------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/brownies/BNL/plot_evaluation/__init__.py b/brownies/BNL/plot_evaluation/__init__.py index 875b8d0c..9c806f57 100644 --- a/brownies/BNL/plot_evaluation/__init__.py +++ b/brownies/BNL/plot_evaluation/__init__.py @@ -303,19 +303,13 @@ def generatePlot(observable, dataSets, xyData=None, xydyData=None, xdxydyData=No def getEXFORSets(sym, A, metastable, reaction=None, quantity="SIG", nox4evals=True, nox4legend=False, forceLegend=False, plotSyle=None, verbose=True): - exforData = [] +exforData = [] try: from x4i import exfor_manager, exfor_entry except ImportError: print('WARNING: x4i not successfully imported (check your PYTHONPATH?), so EXFOR data not plotted') return exforData - def barnsConverter(x): - if x == 'barns': - return 'b' - else: - return x - db = exfor_manager.X4DBManagerPlainFS() i = 0 M = "" @@ -357,30 +351,24 @@ def barnsConverter(x): legend = ds[d].legend() if verbose: print(' ', d, legend) - dat = [] - unc = [] - for line in ds[d].data: - if len(line) != 4: - continue - if line[0] is None or line[1] is None: - continue - dx = 0.0 - dy = 0.0 - if line[2] is not None: - dx = line[2] - if line[3] is not None: - dy = line[3] - dat.append([line[0], line[1]]) - unc.append([dx, dy]) - if None in unc[-1]: - unc[-1][unc[-1].index(None)] = 0.0 - if len(dat) > 0: + if 'Energy' in ds[d].data and 'Data' in ds[d].data: + dat = ds[d].data[['Energy', 'Data']].pint.dequantify().values.tolist() + try: + unc = ds[d].data[['d(Energy)', 'd(Data)']].pint.dequantify().values.tolist() + except KeyError as err: # There was a problem getting uncertainties, so skip it + unc = None + xUnit = str(ds[d].data['Energy'].pint.units) + yUnit = str(ds[d].data['Data'].pint.units) + if yUnit == 'b/sr': + yUnit='b' # newish strange choice in EXFOR management if e.startswith('V') or not suppressEXFORLegend: theLegend = legend + ' (' + str(d[0]) + '.' + str(d[1][-3:]) + ')' else: theLegend = '_noLegend_' exforData.append( - DataSet2d(data=dat, uncertainty=unc, xUnit=ds[d].units[0], yUnit=barnsConverter(ds[d].units[1]), + DataSet2d(data=dat, uncertainty=unc, + xUnit=xUnit, + yUnit=yUnit, legend=theLegend, lineStyle=' ', symbol=plotstyles.getPlotSymbol(i), color=plotstyles.getPlotColor(theLegend, False))) i += 1 From f52122aae8cde56ca2a71398c0b69341c83cc6de Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 8 Jan 2025 13:19:42 -0500 Subject: [PATCH 04/13] oops, indentation error --- brownies/BNL/plot_evaluation/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/brownies/BNL/plot_evaluation/__init__.py b/brownies/BNL/plot_evaluation/__init__.py index 9c806f57..0d63cd30 100644 --- a/brownies/BNL/plot_evaluation/__init__.py +++ b/brownies/BNL/plot_evaluation/__init__.py @@ -303,7 +303,7 @@ def generatePlot(observable, dataSets, xyData=None, xydyData=None, xdxydyData=No def getEXFORSets(sym, A, metastable, reaction=None, quantity="SIG", nox4evals=True, nox4legend=False, forceLegend=False, plotSyle=None, verbose=True): -exforData = [] + exforData = [] try: from x4i import exfor_manager, exfor_entry except ImportError: From 0c0caa746c629639d746b8794f6c443aa97b359b Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 8 Jan 2025 13:33:08 -0500 Subject: [PATCH 05/13] clip overly large uncertainties --- fudge/vis/matplotlib/plot2d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fudge/vis/matplotlib/plot2d.py b/fudge/vis/matplotlib/plot2d.py index f66dd5da..129aa609 100644 --- a/fudge/vis/matplotlib/plot2d.py +++ b/fudge/vis/matplotlib/plot2d.py @@ -664,7 +664,7 @@ def __makePlot2d(datasets, xAxisSettings=None, yAxisSettings=None, theTitle=None else: thePlot.set_xscale('linear') if yAxisSettings.isLog: - thePlot.set_yscale('log') + thePlot.set_yscale('log', nonposy="clip") else: thePlot.set_yscale('linear') if xAxisSettings.autoscale: From 6f7a06dc01f6ed7ae88658ad91f79a4112a60c29 Mon Sep 17 00:00:00 2001 From: David Brown Date: Wed, 8 Jan 2025 13:53:01 -0500 Subject: [PATCH 06/13] bad switch --- fudge/vis/matplotlib/plot2d.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fudge/vis/matplotlib/plot2d.py b/fudge/vis/matplotlib/plot2d.py index 129aa609..f66dd5da 100644 --- a/fudge/vis/matplotlib/plot2d.py +++ b/fudge/vis/matplotlib/plot2d.py @@ -664,7 +664,7 @@ def __makePlot2d(datasets, xAxisSettings=None, yAxisSettings=None, theTitle=None else: thePlot.set_xscale('linear') if yAxisSettings.isLog: - thePlot.set_yscale('log', nonposy="clip") + thePlot.set_yscale('log') else: thePlot.set_yscale('linear') if xAxisSettings.autoscale: From 81e5ddc2c7a6182b73a9e163151ff4a301d867dc Mon Sep 17 00:00:00 2001 From: Caleb Mattoon Date: Wed, 8 Jan 2025 12:34:16 -0800 Subject: [PATCH 07/13] FUDGE-6.8.0 release Changes include: - Adding support for incoherent photon scattering that produces both an electron vacancy and a scattered photon (not yet officially supported by GNDS) - Adding support for the 'targetInfo' section for storing TNSL target isotopic abundances, GNDS-2.1 - Various fixes to support compiling with numpy 2 with either 'make' or 'pip install' - Fixes for installing on Windows - ENDF translation and physics checking updates --- .github/workflows/makefile.yml | 4 +- .github/workflows/python-app.yml | 9 +- Merced/Makefile | 2 +- README.md | 28 +- bin/Makefile | 2 +- bin/buildMapFile.py | 2 +- bin/crossSections.py | 10 +- bin/cullProcessedData.py | 22 +- bin/energyBalance.py | 9 +- bin/peek.py | 19 +- bin/processProtare.py | 16 +- brownies/bin/endf2gnds.py | 4 +- brownies/bin/plot_covariance.py | 3 + .../converting/ENDFToGNDS/ENDF_ITYPE_0.py | 476 ++++++------ .../ENDFToGNDS/ENDF_ITYPE_0_Misc.py | 68 +- .../converting/ENDFToGNDS/ENDF_ITYPE_1.py | 97 +-- .../converting/ENDFToGNDS/ENDF_ITYPE_2.py | 63 +- .../ENDFToGNDS/ENDF_ITYPE_3_6_Misc.py | 16 +- .../converting/ENDFToGNDS/ENDF_ITYPE_4.py | 530 +++++++------- .../converting/ENDFToGNDS/ENDF_ITYPE_5.py | 94 +-- .../converting/ENDFToGNDS/ENDF_ITYPE_6.py | 96 +-- .../converting/ENDFToGNDS/metaStableData.py | 683 +++++++++--------- brownies/legacy/converting/endfFileToGNDS.py | 339 ++++----- brownies/legacy/converting/toGNDSMisc.py | 238 +++--- .../thermalNeutronScatteringLaw.py | 42 ++ .../productData/distributions/KalbachMann.py | 75 +- brownies/legacy/toENDF6/reactionSuite.py | 3 +- .../b60ba9b0c8bc58d29daa09756d15449b/gnds.xsd | 51 +- .../covariances.xsd | 2 +- doc/html/_modules/fudge/covariances/base.html | 15 +- .../fudge/covariances/covarianceMatrix.html | 393 +++++----- .../fudge/covariances/covarianceSection.html | 122 ++-- .../fudge/covariances/covarianceSuite.html | 152 ++-- .../fudge/covariances/distributions.html | 84 ++- .../_modules/fudge/covariances/mixed.html | 178 ++--- .../fudge/covariances/modelParameters.html | 76 +- .../shortRangeSelfScalingVariance.html | 68 +- .../_modules/fudge/covariances/summed.html | 140 ++-- doc/html/_modules/fudge/institution.html | 22 +- .../fissionEnergyRelease.html | 1 + .../fissionFragmentData.html | 9 +- .../deterministic/transferMatrices.html | 4 +- doc/html/_modules/fudge/product.html | 22 + .../distributions/photonScattering.html | 6 + .../distributions/uncorrelated.html | 2 + doc/html/_modules/fudge/reactionSuite.html | 99 ++- doc/html/_modules/fudge/reactions/base.html | 13 +- doc/html/_modules/fudge/styles.html | 64 +- doc/html/_modules/fudge/suites.html | 526 +++++++------- doc/html/_modules/fudge/warning.html | 10 + doc/html/fudge/fudge.covariances.html | 2 +- doc/html/fudge/fudge.html | 46 +- doc/html/fudge/fudge.outputChannelData.html | 5 + .../fudge/fudge.processing.deterministic.html | 2 +- .../fudge.productData.distributions.html | 17 + doc/html/genindex.html | 20 +- doc/html/index.html | 2 +- doc/html/objects.inv | Bin 27534 -> 27602 bytes doc/html/searchindex.js | 2 +- doc/html/tutorial/index.html | 2 +- fudge/GNDS_formatVersion.py | 3 +- fudge/covariances/base.py | 15 +- fudge/covariances/covarianceMatrix.py | 393 +++++----- fudge/covariances/covarianceSection.py | 122 ++-- fudge/covariances/covarianceSuite.py | 152 ++-- fudge/covariances/covariances.xsd | 2 +- fudge/covariances/distributions.py | 84 ++- fudge/covariances/enums.py | 2 +- fudge/covariances/mixed.py | 178 ++--- fudge/covariances/modelParameters.py | 76 +- .../shortRangeSelfScalingVariance.py | 68 +- fudge/covariances/summed.py | 140 ++-- fudge/covariances/test/rebuild_test_data.py | 32 +- fudge/covariances/test/test_base.py | 219 +++--- .../covariances/test/test_covarianceSuite.py | 58 +- fudge/covariances/test/test_mixed.py | 265 ++++--- fudge/covariances/test/test_summed.py | 79 +- .../test/test_toCovarianceMatrix.py | 17 +- fudge/fudgeVersion.py | 2 +- fudge/gnds.xsd | 51 +- fudge/institution.py | 20 + .../fissionEnergyRelease.py | 1 + .../fissionFragmentData.py | 9 +- .../deterministic/transferMatrices.py | 4 +- .../deterministic/upscatter/bin/Makefile | 2 +- fudge/processing/flux.py | 8 +- fudge/processing/resonances/setup.py | 18 +- fudge/product.py | 22 + .../productData/distributions/KalbachMann.py | 43 +- .../productData/distributions/distribution.py | 2 +- .../distributions/photonScattering.py | 6 + fudge/productData/distributions/reference.py | 6 +- .../productData/distributions/uncorrelated.py | 2 + fudge/protareProductInfo.py | 56 +- .../CoulombPlusNuclearElastic.py | 8 +- .../chargedParticleElastic/misc.py | 2 +- .../nuclearAmplitudeExpansion.py | 8 +- .../nuclearPlusInterference.py | 12 +- .../doubleDifferentialCrossSection.py | 3 +- .../photonScattering/incoherentDoppler.py | 231 ++++++ .../thermalNeutronScatteringLaw/base.py | 4 +- .../coherentElasticMisc.py | 6 +- .../incoherentInelastic.py | 76 +- fudge/reactionSuite.py | 93 ++- fudge/reactions/base.py | 13 +- fudge/ris.py | 79 +- fudge/styles.py | 64 +- fudge/suites.py | 2 +- fudge/targetInfo.py | 152 ++++ fudge/warning.py | 10 + getFudgeVersion.py | 2 +- .../ptwXY/Test/UnitTesting/Others/clip.c | 1 + .../ptwXY/Test/UnitTesting/Others/mod.c | 1 + .../UnitTesting/integrate/integrationXY.c | 1 + .../ptwXY/Test/UnitTesting/inverse/inverse.c | 1 + .../ptwXY/Test/UnitTesting/thinning/thin.c | 1 + .../toFunction/createFromFunction.c | 1 + 117 files changed, 4798 insertions(+), 3237 deletions(-) create mode 100644 fudge/reactionData/doubleDifferentialCrossSection/photonScattering/incoherentDoppler.py create mode 100644 fudge/targetInfo.py diff --git a/.github/workflows/makefile.yml b/.github/workflows/makefile.yml index 84fbd32b..ca099566 100644 --- a/.github/workflows/makefile.yml +++ b/.github/workflows/makefile.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.8", "3.12", "3.x"] + python-version: ["3.8", "3.12", "3.13"] steps: - uses: actions/checkout@v4 @@ -22,7 +22,7 @@ jobs: run: python -m pip install --upgrade pip setuptools wheel numpy h5py matplotlib - name: Build - run: make PYTHON=python + run: make PYTHON=python CC=gcc - name: Run check run: | diff --git a/.github/workflows/python-app.yml b/.github/workflows/python-app.yml index 736696f0..ee1262c3 100644 --- a/.github/workflows/python-app.yml +++ b/.github/workflows/python-app.yml @@ -9,7 +9,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] - python-version: ["3.8", "3.12", "3.x"] + python-version: ["3.8", "3.12", "3.13"] steps: - name: Set up Python ${{ matrix.python-version }} @@ -24,5 +24,10 @@ jobs: run: python -m pip install --upgrade pip setuptools wheel numpy h5py - name: Install FUDGE - run: python -m pip install git+https://github.com/LLNL/fudge.git@ci_dev + run: | + if [ "$RUNNER_OS" == "Windows" ]; then + export CC=gcc + fi + python -m pip install git+https://github.com/LLNL/fudge.git + shell: bash diff --git a/Merced/Makefile b/Merced/Makefile index 6a4702f9..3bd3fce3 100644 --- a/Merced/Makefile +++ b/Merced/Makefile @@ -5,7 +5,7 @@ # SPDX-License-Identifier: BSD-3-Clause # <> -subDirs = Doc Src TestSuite bin +subDirs = Doc MonteCarlo Src TestSuite bin .PHONY: default bin clean realclean check doc doSubDirs prefixDeploy diff --git a/README.md b/README.md index 2fb40044..a87d6bc2 100644 --- a/README.md +++ b/README.md @@ -44,22 +44,26 @@ Optional packages matplotlib and PyQT5 are also recommended to support plotting. - Install FUDGE: - pip install git+https://github.com/LLNL/fudge.git@6.7.1 + # Install latest available version: + pip install git+https://github.com/LLNL/fudge.git + + Or, + + # Install a tagged release: + pip install git+https://github.com/LLNL/fudge.git@fudge6.8.0 - Installation by cloning the git repository and building with the unix `make` command: This is the typical mode for active FUDGE maintenance and development. The following steps are recommended: - - Ensure that NumPy (version 1.15 or later) is installed + - Ensure that NumPy (version 1.15 or greater) is installed - Clone FUDGE in the current directory: - ``` git clone https://github.com/LLNL/fudge.git - # or using SSH (requires creating a github account and registering an ssh key): - git clone git@github.com:LLNL/fudge.git - ``` + # or using SSH (requires creating a github account and registering an ssh key): + git clone git@github.com:LLNL/fudge.git - Build FUDGE: @@ -82,6 +86,18 @@ Optional packages matplotlib and PyQT5 are also recommended to support plotting. - on Windows, the environment variable should be added to the registry (see for example ) +### Notes for Windows users: + +FUDGE installations are now regularly tested on Github CI using Windows with the MinGW environment. +Compiling C extensions on Windows may require an extra step: if command 'cc.exe' is not available, +locate a C compiler and set environment variable CC to that compiler. For example, +``` +set CC=gcc +pip install git+https://github.com/LLNL/fudge.git +``` + +Please let us know if you run into trouble installing or using FUDGE on Windows! + ### Differences between FUDGE installed via `pip install` vs. via `make`: When FUDGE is installed via `pip install`, several executable scripts are installed into diff --git a/bin/Makefile b/bin/Makefile index ddc7a4de..97e4f28e 100644 --- a/bin/Makefile +++ b/bin/Makefile @@ -14,7 +14,7 @@ merced: mv ../Merced/bin/merced . upscatter: - cd ../fudge/processing/deterministic/upscatter; $(MAKE) CC=gcc + cd ../fudge/processing/deterministic/upscatter; $(MAKE) mv ../fudge/processing/deterministic/upscatter/bin/calcUpscatterKernel . check: diff --git a/bin/buildMapFile.py b/bin/buildMapFile.py index 9787b203..14634bd5 100755 --- a/bin/buildMapFile.py +++ b/bin/buildMapFile.py @@ -201,7 +201,7 @@ def sortFiles(files): try : name, data = GNDS_fileModule.type(file) except : - if args.verbose > 2: print(' WARNING: Invalid file "%s".' % file) + print(' WARNING: Invalid file "%s".' % file) continue if( name == reactionSuiteModule.ReactionSuite.moniker ) : if data['interaction'] is None: diff --git a/bin/crossSections.py b/bin/crossSections.py index c3fa352d..5272603a 100755 --- a/bin/crossSections.py +++ b/bin/crossSections.py @@ -22,6 +22,7 @@ from fudge.reactionData import crossSection as crossSectionModule from fudge.reactionData.doubleDifferentialCrossSection.photonScattering import coherent as coherentModule from fudge.reactionData.doubleDifferentialCrossSection.photonScattering import incoherent as incoherentModule +from fudge.reactionData.doubleDifferentialCrossSection.photonScattering import incoherentDoppler as incoherentDopplerModule summaryDocString__FUDGE = '''Outputs the evaluated cross section for each reaction and total for a GNDS reactionSuite. The processed data are written to files if the "-o" and "--processed" options are used.''' @@ -171,7 +172,7 @@ def outputLabel(crossSection, MT, reactionStr, reactionIndex): crossSections = [] if args.verbose > 0: print(protare.sourcePath) -total = crossSectionModule.XYs1d(axes=protare.reactions[0].crossSection[-1].axes) +total = crossSectionModule.XYs1d(axes=crossSectionModule.defaultAxes(energyUnit=protare.domainUnit)) for reactionCounter, reaction in enumerate(protare.reactions): if args.verbose > 1: print(' %s' % reaction) crossSection = reaction.crossSection.toPointwise_withLinearXYs(lowerEps=1e-6, upperEps=1e-6) @@ -192,7 +193,8 @@ def outputLabel(crossSection, MT, reactionStr, reactionIndex): reactionCounterOffset = reactionCounter + 1 if len(protare.sums.crossSectionSums) > 0: - outputLog.write('\nData in crossSectionSums:\n') + if outputDir is not None: + outputLog.write('\nData in crossSectionSums:\n') for reactionCounter2, reaction in enumerate(protare.sums.crossSectionSums): reactionCounter = reactionCounterOffset + reactionCounter2 @@ -224,6 +226,10 @@ def outputLabel(crossSection, MT, reactionStr, reactionIndex): prefix = 'incoherentScatteringFactor' formClass = incoherentModule.Form dataName = 'scatteringFactor' + elif reaction.ENDF_MT >= 1534 and reaction.ENDF_MT <= 1572: + prefix = 'incoherentDoppler' + formClass = incoherentDopplerModule.Form + dataName = 'ComptonProfile' else: continue for form in reaction.doubleDifferentialCrossSection: diff --git a/bin/cullProcessedData.py b/bin/cullProcessedData.py index ca74624c..04fcfbde 100755 --- a/bin/cullProcessedData.py +++ b/bin/cullProcessedData.py @@ -15,23 +15,23 @@ summaryDocString__FUDGE = """This script removed all processed data (except resonance reconstructed data) for the specified GNDS protare file.""" -description = summaryDocString__FUDGE +description = summaryDocString__FUDGE + """ If option "--outputDir" is present, the directory is striped from the output path and replaced +with the specified path.""" parser = argparse.ArgumentParser(description=description, allow_abbrev=False) singleProtareArguments = argumentsForScriptsModule.SingleProtareArguments(parser) -parser.add_argument('output', nargs='?', default=None, help='Output file name.') +parser.add_argument('outputPath', default=None, type=pathlib.Path, help='Output file name.') +parser.add_argument('--outputDir', action='store', default=None, type=pathlib.Path, help='The output directory to write the output file to.') args = parser.parse_args() protare = singleProtareArguments.protare(args) +protare.cullProcessedData() -stylesToRemove = [] -preProcessingStyles = protare.styles.preProcessingStyles() -for style in protare.styles : - if not isinstance(style, preProcessingStyles): - stylesToRemove.append(style.label) -protare.removeStyles(stylesToRemove) +outputPath = args.outputPath +if outputPath is None: + outputPath = pathlib.Path(protare.sourcePath).with_suffix('.culled.xml') +if args.outputDir is not None: + outputPath = args.outputDir / outputPath.name -output = args.output -if output is None: output = pathlib.Path(protare.sourcePath).with_suffix('.culled.xml') -protare.saveToFile(output) +protare.saveToFile(outputPath) diff --git a/bin/energyBalance.py b/bin/energyBalance.py index d1ff5247..61eb4a83 100755 --- a/bin/energyBalance.py +++ b/bin/energyBalance.py @@ -131,6 +131,8 @@ def output(reactionOutputDir, fileName, curve, crossSection=None): priorEnergy = energy if priorEnergy is not None: # Add a point at the last zero cross section point. curve.setValue(priorEnergy, curve.evaluate(priorEnergy)) + elif fileName == 'Q.dat': + curve = curve * crossSection.domainSlice(domainMin=curve.domainMin) weighted = [] for index, (xValue, yValue) in enumerate(curve): @@ -216,14 +218,17 @@ def process(reaction, isReaction): crossSection = reaction.crossSection.toPointwise_withLinearXYs(lowerEps=1e-6) output(reactionOutputDir, 'crossSection.dat', crossSection) + outputChannel = reaction.outputChannel if isReaction: + Q = outputChannel.Q[0].toPointwise_withLinearXYs(accuracy=1e-5, lowerEps=1e-6) + output(reactionOutputDir, 'Q.dat', Q, crossSection) availableEnergy = reaction.availableEnergy[apdLabel] output(reactionOutputDir, 'availableEnergy.dat', availableEnergy, crossSection) - checkTwoBody(reactionOutputDir, crossSection, reaction.outputChannel) + checkTwoBody(reactionOutputDir, crossSection, outputChannel) productSums = {} - outputProductData(reactionOutputDir, crossSection, reaction.outputChannel, productSums, 0) + outputProductData(reactionOutputDir, crossSection, outputChannel, productSums, 0) totalProductEnergy = XYs1dModule.XYs1d(axes=averageProductEnergyAxes) for pid in productSums: diff --git a/bin/peek.py b/bin/peek.py index e8a14742..bf2f726a 100755 --- a/bin/peek.py +++ b/bin/peek.py @@ -18,6 +18,7 @@ from fudge import outputChannel as outputChannelModule from fudge import product as productModule from fudge import sums as sumsModule +from fudge import institution as institutionModule from fudge.reactionData import crossSection as crossSectionModule from fudge.productData import multiplicity as multiplicityModule from fudge.productData.distributions import unspecified as unspecifiedModule @@ -45,6 +46,7 @@ parser.add_argument('--doNotShowProducts', action='store_true', help='If present, no product data are displayed.') parser.add_argument('--skipProductions', action='store_true', help='If present, skips the "productions" node.') parser.add_argument('--skipIncompleteReactions', action='store_true', help='If present, skips the "incompleteReactions" node.') +parser.add_argument('--skipPhotoAtomicIncoherentDoppler', action='store_true', help='If present, skips the photo-atomic incoherent Doppler reactions.') parser.add_argument('--products', action='append', default=[], help='Only show reactions with these products in their list. If empty, all reactions are shown.') parser.add_argument('--MT', action='append', type=int, default=[], help='Only show reactions with these MTs. If empty, all reactions are shown.') parser.add_argument('--crossSectionSums', action='store_true', help='If present, also show crossSectionSum information.') @@ -176,8 +178,8 @@ def reactionPeek(self, prefix, index, indent, reactionIndex): QStr = 'Q_threshold = %11s' % self.outputChannel.Q[0].evaluate(self.domainMin) except: QStr = '"Q_threshold issue, please report to FUDGE developers"' - print('%s%-36s (%4d): %s domainMin = %11s domainMax = %10s %s%s' % - (indent, prefix % str(self), index, QStr, self.domainMin, self.domainMax, self.domainUnit, crossSectionStr)) + print('%s%-36s (%4d): %s domainMin = %11.6g domainMax = %10.6g %s MT = %s%s' % + (indent, prefix % str(self), index, QStr, self.domainMin, self.domainMax, self.domainUnit, self.ENDF_MT, crossSectionStr)) productPath = [str(index)] if not args.doNotShowProducts: self.outputChannel.__peek(indent + indentIncrement, [str(reactionIndex)]) @@ -202,12 +204,14 @@ def crossSectionSum(self, index, indent): print('%s%-32s (%4d): domainMin = %s, domainMax = %s %s%s' % (indent, str(self), index, crossSection.domainMin, crossSection.domainMax, crossSection.domainUnit, crossSectionStr)) -def showChildren(node, skip): +def showChildren(node, skip, label=None): if skip: return if len(node) > 0: - print('%s%s:' % (indent, node.moniker)) + if label is None: + label = node.moniker + print('%s%s:' % (indent, label)) for reactionIndex, reaction in enumerate(node): reaction.__peek('%s', reactionIndex, 2 * indentIncrement, reactionIndex) @@ -236,3 +240,10 @@ def showChildren(node, skip): print('%sCross section sums:' % indent) for crossSectionSumIndex, crossSectionSum in enumerate(protare.sums.crossSectionSums): crossSectionSum.__peek(crossSectionSumIndex, 2 * indentIncrement) + + try: + photoAtomicIncoherentDoppler = protare.applicationData[institutionModule.photoAtomicIncoherentDoppler] + showChildren(photoAtomicIncoherentDoppler.data[0], args.skipPhotoAtomicIncoherentDoppler, + label='Photo-atomic incoherent doppler reactions') + except: + pass diff --git a/bin/processProtare.py b/bin/processProtare.py index bfff98bc..557a21d0 100755 --- a/bin/processProtare.py +++ b/bin/processProtare.py @@ -218,21 +218,7 @@ def listFileProperties(_fileName): preProcessedStyles = reactionSuite.styles.preProcessingStyles() if args.cullProcessedData: - stylesToRemove = [] - for style in reactionSuite.styles: - if not isinstance(style, preProcessedStyles): - stylesToRemove.append(style.label) - reactionSuite.removeStyles(stylesToRemove) - - # applicationData requires special handling: - from fudge.processing.deterministic import tokens as deterministicTokensModule - from fudge.resonances import probabilityTables as probabilityTablesModule - for label in (deterministicTokensModule.multiGroupReactions, - deterministicTokensModule.multiGroupDelayedNeutrons, - deterministicTokensModule.multiGroupIncompleteProducts, - probabilityTablesModule.LLNLProbabilityTablesToken): - if label in reactionSuite.applicationData: - reactionSuite.applicationData.pop(label) + reactionSuite.cullProcessedData() for style in reactionSuite.styles: # Fail on detection of existing processed data. if not isinstance(style, preProcessedStyles): diff --git a/brownies/bin/endf2gnds.py b/brownies/bin/endf2gnds.py index 6a35c239..a851aa3e 100755 --- a/brownies/bin/endf2gnds.py +++ b/brownies/bin/endf2gnds.py @@ -90,9 +90,9 @@ def process_args( ) : if hasattr(topLevel, 'convertUnits') and args.energyUnit != 'eV': topLevel.convertUnits({'eV': args.energyUnit}) if hasattr(topLevel, 'saveAllToFile'): - topLevel.saveAllToFile(outFile) + topLevel.saveAllToFile(outFile, formatVersion=args.formatVersion) else: - topLevel.saveToFile(outFile) + topLevel.saveToFile(outFile, formatVersion=args.formatVersion) break except Exception as err: sys.stderr.write('WARNING: ENDF write error: %s\n' % err) diff --git a/brownies/bin/plot_covariance.py b/brownies/bin/plot_covariance.py index 4bce52ef..25870bc9 100755 --- a/brownies/bin/plot_covariance.py +++ b/brownies/bin/plot_covariance.py @@ -88,4 +88,7 @@ otherMT = args.crossMT elif c.columnData is None: otherMT = args.MT + else: + otherMT = args.MT + raise KeyError("(MF0,MT0)x(MF1,MT1) = (%s,%s)x(%s,%s) not found" % (args.MF, args.MT, args.MF, otherMT)) diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0.py index 5c99e550..a52cd6dd 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0.py @@ -52,8 +52,8 @@ from .. import toGNDSMisc as toGNDSMiscModule from .. import endf_endl as endf_endlModule -def deriveMT3MF3FromMT1_2(info, reactionSuite): +def deriveMT3MF3FromMT1_2(info, reactionSuite): totalCrossSection, elasticCrossSection = None, None for reaction in reactionSuite.sums.crossSectionSums: if reaction.ENDF_MT == 1: @@ -64,12 +64,12 @@ def deriveMT3MF3FromMT1_2(info, reactionSuite): if reaction.ENDF_MT == 2: elasticCrossSection = reaction.crossSection.evaluated break - if totalCrossSection is None: raise Exception( 'No total cross section for calculating non-elastic' ) - if elasticCrossSection is None: raise Exception( 'No elastic cross section for calculating non-elastic' ) + if totalCrossSection is None: raise Exception('No total cross section for calculating non-elastic') + if elasticCrossSection is None: raise Exception('No elastic cross section for calculating non-elastic') try: form = totalCrossSection - elasticCrossSection - except: + except Exception: totalCrossSection = totalCrossSection.toPointwise_withLinearXYs(accuracy=1e-3, lowerEps=1e-6) elasticCrossSection = elasticCrossSection.toPointwise_withLinearXYs(accuracy=1e-3, lowerEps=1e-6) form = totalCrossSection - elasticCrossSection @@ -77,8 +77,8 @@ def deriveMT3MF3FromMT1_2(info, reactionSuite): form.label = info.style return form -def checkProductList(outputChannel, productList): +def checkProductList(outputChannel, productList): if outputChannel is None: return for product in outputChannel: @@ -89,8 +89,9 @@ def checkProductList(outputChannel, productList): continue productList[product.pid] -= multiplicity -def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSectionOnly, doCovariances, verbose, reconstructResonances = True): +def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSectionOnly, doCovariances, verbose, + reconstructResonances=True): warningList = [] info.totalOrPromptFissionNeutrons = {} @@ -98,11 +99,13 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect info.PoPsOverrides = {} if 452 in MTDatas: - info.totalOrPromptFissionNeutrons[totalToken] = getTotalOrPromptFission(info, 452, MTDatas, totalToken, warningList) + info.totalOrPromptFissionNeutrons[totalToken] = getTotalOrPromptFission(info, 452, MTDatas, totalToken, + warningList) if 455 in MTDatas: info.delayedFissionDecayChannel = getDelayedFission(info, 455, MTDatas, warningList) if 456 in MTDatas: - info.totalOrPromptFissionNeutrons[promptToken] = getTotalOrPromptFission(info, 456, MTDatas, promptToken, warningList) + info.totalOrPromptFissionNeutrons[promptToken] = getTotalOrPromptFission(info, 456, MTDatas, promptToken, + warningList) if 458 in MTDatas: info.fissionEnergyReleaseData = MTDatas[458] sys.stdout.flush() @@ -153,10 +156,10 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect incompleteReactions = [] nonElastic = [] delayInsertingSummedReaction = [] - linksToCheck = [] # links that may need to be updated after reading resonances + linksToCheck = [] # links that may need to be updated after reading resonances SpecialLRProducts = [] - for MT in MTList : + for MT in MTList: crossSection = None if MT in MTs2Skip: continue if (singleMTOnly is not None) and (MT != singleMTOnly): continue @@ -167,8 +170,8 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect elif MT in range(102, 108): channelProcess = outputChannelModule.Processes.inclusive elif MT in continuumMTs: - for discreteMT in continuumMTs[MT]: - if discreteMT in MTList: channelProcess = outputChannelModule.Processes.continuum + for discreteMT in continuumMTs[MT]: + if discreteMT in MTList: channelProcess = outputChannelModule.Processes.continuum warningList = [] MTData = MTDatas[MT] @@ -179,17 +182,18 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect 21: enumsModule.FissionGenre.thirdChance, 38: enumsModule.FissionGenre.fourthChance}.get(MT, enumsModule.FissionGenre.none) - # Sometimes excited states are identified in MF8. Read this before reading distributions to make sure info is present. + # 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 + if doParseReaction: # normal reaction, with cross section and distributions try: crossSection, outputChannel, MFKeys, LRProducts = parseReaction( info, info.target, info.projectileZA, info.targetZA, MT, MTData, warningList, - parseCrossSectionOnly=parseCrossSectionOnly, channelProcess=channelProcess ) + parseCrossSectionOnly=parseCrossSectionOnly, channelProcess=channelProcess) except KeyboardInterrupt: raise except: @@ -215,22 +219,22 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect reaction = reactionModule.Reaction(None, outputChannel.genre, ENDF_MT=MT, fissionGenre=fissionGenre) endf_endlModule.setReactionsOutputChannelFromOutputChannel(info, reaction, outputChannel) if hasattr(info, 'dSigma_form'): - reaction.doubleDifferentialCrossSection.add( info.dSigma_form ) + reaction.doubleDifferentialCrossSection.add(info.dSigma_form) del info.dSigma_form crossSection = crossSectionModule.CoulombPlusNuclearElastic( - link = reaction.doubleDifferentialCrossSection.evaluated, - label = info.style, relative = True ) - reaction.crossSection.add( crossSection ) - if( MT == 5 ) : + link=reaction.doubleDifferentialCrossSection.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. chance fission but total is also present. - - fissionComponents.append( reaction ) - else : - if( MT in summedReactionsInfo ) : - delayInsertingSummedReaction.append( reaction ) - else : - reactions.append( [ MT, reaction ] ) + elif MT in fissionMTs and haveTotalFission: + # This is 1st, 2nd, etc. chance fission but total is also present. + fissionComponents.append(reaction) + else: + if MT in summedReactionsInfo: + delayInsertingSummedReaction.append(reaction) + else: + reactions.append([MT, reaction]) else: if 12 in MTData: # MF=12-15 is occasionally provided without corresponding MF=3, e.g. ENDF-VIII.1 g-069_Tm_169 @@ -245,75 +249,84 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect MFList = [] for MF in [4, 5, 6]: 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))) + 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. + 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 = reaction.crossSection.evaluated if MT in summedReactions: productionCrossSection = crossSection productionCrossSection = crossSectionModule.Reference(link=productionCrossSection, label=info.style) linksToCheck.append(productionCrossSection) - elif( LMF == 10 ) : # MF10 data is cross section. Product's multipliticy is 1. + elif LMF == 10: # MF10 data is cross-section. Product's multiplicity is 1. productionCrossSection = radioactiveData[4] - else : - raise Exception( "Unknown LMF=%d encountered in MF=8 for MT=%d" % ( LMF, MT ) ) + else: + raise Exception("Unknown LMF=%d encountered in MF=8 for MT=%d" % (LMF, MT)) ZAP = radioactiveData[0] ELFS = radioactiveData[1] LFS = radioactiveData[2] - if( LMF in [ 9, 10 ] ) : - Q = toGNDSMiscModule.returnConstantQ( info.style, radioactiveData[6], productionCrossSection ) + if LMF in [9, 10]: + Q = toGNDSMiscModule.returnConstantQ(info.style, radioactiveData[6], productionCrossSection) else: Q = outputChannel.Q[info.style] - if MT==18: + if MT == 18: outputChannel = outputChannelModule.OutputChannel(enumsModule.Genre.NBody) outputChannel.Q.add(Q) - icr = incompleteReactionModule.IncompleteReaction('fission', outputChannel.genre, MT, fissionGenre=enumsModule.FissionGenre.total) - endf_endlModule.setReactionsOutputChannelFromOutputChannel( info, icr, outputChannel ) - - icr.crossSection.add( productionCrossSection ) - incompleteReactions.append( icr ) + icr = incompleteReactionModule.IncompleteReaction('fission', outputChannel.genre, MT, + fissionGenre=enumsModule.FissionGenre.total) + endf_endlModule.setReactionsOutputChannelFromOutputChannel(info, icr, outputChannel) + + icr.crossSection.add(productionCrossSection) + incompleteReactions.append(icr) continue - if( LMF == 6 ) : # Product multiplicity is in MF6, so production channel multiplicity needs to refer to it: - residual = toGNDSMiscModule.getTypeNameGamma( info, ZAP, level = ELFS, levelIndex = LFS ) - residualID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(residual.id, info.specialNuclearParticleID) + if LMF == 6: # Product multiplicity is in MF6, so production channel multiplicity needs to refer to it: + residual = toGNDSMiscModule.getTypeNameGamma(info, ZAP, level=ELFS, levelIndex=LFS) + residualID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(residual.id, + info.specialNuclearParticleID) MF6prod = outputChannel.getProductsWithName(residualID) - if( len( MF6prod ) != 1 ) : # problem appears in JEFF-3.2 Y90 and Y91 - info.missingRadioactiveProduct.append('Unique MT%d radioactive product %s not found in product list!' % (MT, residualID)) + if len(MF6prod) != 1: # problem appears in JEFF-3.2 Y90 and Y91 + info.missingRadioactiveProduct.append( + 'Unique MT%d radioactive product %s not found in product list!' % (MT, residualID)) continue - multiplicity = multiplicityModule.Reference( label = info.style, link = MF6prod[0].multiplicity ) - else : + multiplicity = multiplicityModule.Reference(label=info.style, link=MF6prod[0].multiplicity) + else: multiplicity = radioactiveData[3] - try : + try: if crossSection is None: - crossSectionData = [[reactionSuite.styles[0].projectileEnergyDomain.min, 1.0], [reactionSuite.styles[0].projectileEnergyDomain.max, 1.0]] - crossSection = crossSectionModule.XYs1d(data=crossSectionData, axes=crossSectionModule.defaultAxes(reactionSuite.styles[0].projectileEnergyDomain.unit)) - residual = toGNDSMiscModule.newGNDSParticle( info, toGNDSMiscModule.getTypeNameGamma( info, ZAP, level = ELFS, levelIndex = LFS ), - crossSection, multiplicity = multiplicity ) - except : - info.logs.write( '\nMT = %s\n' % MT ) + crossSectionData = [[reactionSuite.styles[0].projectileEnergyDomain.min, 1.0], + [reactionSuite.styles[0].projectileEnergyDomain.max, 1.0]] + crossSection = crossSectionModule.XYs1d(data=crossSectionData, axes=crossSectionModule.defaultAxes( + reactionSuite.styles[0].projectileEnergyDomain.unit)) + residual = toGNDSMiscModule.newGNDSParticle( + info, toGNDSMiscModule.getTypeNameGamma(info, ZAP, level=ELFS, levelIndex=LFS), + crossSection, multiplicity=multiplicity) + except: + info.logs.write('\nMT = %s\n' % MT) raise productionOutputChannel = outputChannelModule.OutputChannel(enumsModule.Genre.production) - 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+',') ) + 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( None, productionOutputChannel.genre, ENDF_MT = MT ) - endf_endlModule.setReactionsOutputChannelFromOutputChannel( info, production, productionOutputChannel ) - production.crossSection.add( productionCrossSection ) - productions.append( production ) + production = productionModule.Production(None, productionOutputChannel.genre, ENDF_MT=MT) + endf_endlModule.setReactionsOutputChannelFromOutputChannel(info, production, productionOutputChannel) + production.crossSection.add(productionCrossSection) + productions.append(production) - if( verbose > 0 ) : - for warning in warningList : info.logs.write( " WARNING: %s\n" % warning, stderrWriting = True ) + if verbose > 0: + for warning in warningList: info.logs.write(" WARNING: %s\n" % warning, stderrWriting=True) for MT, reaction in reactions: if reaction.label in reactionSuite.reactions: @@ -331,84 +344,98 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect if multiplicity > 0: missingProduct.append(product) if len(missingProduct) > 0: - warningList.append('For MT=%s, product list does not match MT. Missing products are %s.' % (MT, ','.join(missingProduct))) + warningList.append('For MT=%s, product list does not match MT. Missing products are %s.' % ( + MT, ','.join(missingProduct))) print(' WARNING: %s' % warningList[-1]) - reactionSuite.reactions.add( reaction ) + reactionSuite.reactions.add(reaction) - for reaction in delayInsertingSummedReaction : - reactionSuite.reactions.add( reaction ) + for reaction in delayInsertingSummedReaction: + reactionSuite.reactions.add(reaction) - if( MT5Reaction is not None ) : - reactionSuite.reactions.add( MT5Reaction ) + 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)' } + # 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: if 2 in MTList: - summedReactionsInfo[1] = [ 2 ] + nonElastic + summedReactionsInfo[1] = [2] + nonElastic else: summedReactionsInfo[1] = nonElastic - summedReactionMTs = endfFileToGNDSMiscModule.niceSortOfMTs( list(summedReactions.keys( )), verbose = 0, 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 + summedReactionMTs = endfFileToGNDSMiscModule.niceSortOfMTs(list(summedReactions.keys()), verbose=0, + 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] omitWhenWritingENDF = False - if( ( MT == 3 ) and ( crossSection is None ) ) : - crossSection = deriveMT3MF3FromMT1_2( info, reactionSuite ) + if (MT == 3) and (crossSection is None): + crossSection = deriveMT3MF3FromMT1_2(info, reactionSuite) omitWhenWritingENDF = True - summedCrossSection = sumsModule.CrossSectionSum( label = channelIDs[MT], ENDF_MT = MT ) - for reaction in reactionSuite.reactions : - if( reaction.ENDF_MT in summedReactionsInfo[MT] ) : summedCrossSection.summands.append( sumsModule.Add( link = reaction.crossSection ) ) - summedCrossSection.Q.add( outputChannel.Q[info.style] ) - summedCrossSection.crossSection.add( crossSection ) - if( omitWhenWritingENDF ): - info.ENDFconversionFlags.add( summedCrossSection, "omit" ) - reactionSuite.sums.crossSectionSums.add( summedCrossSection ) + summedCrossSection = sumsModule.CrossSectionSum(label=channelIDs[MT], ENDF_MT=MT) + for reaction in reactionSuite.reactions: + if reaction.ENDF_MT in summedReactionsInfo[MT]: + summedCrossSection.summands.append(sumsModule.Add(link=reaction.crossSection)) + summedCrossSection.Q.add(outputChannel.Q[info.style]) + summedCrossSection.crossSection.add(crossSection) + if omitWhenWritingENDF: + info.ENDFconversionFlags.add(summedCrossSection, "omit") + reactionSuite.sums.crossSectionSums.add(summedCrossSection) gammas = [] - for product in outputChannel : + for product in outputChannel: particle = reactionSuite.PoPs[product.pid] - if( isinstance( particle, gaugeBosonModule.Particle ) ) : - gammas.append( product ) - else : - if( product.outputChannel is not None ) : - for product2 in product.outputChannel : + if isinstance(particle, gaugeBosonModule.Particle): + gammas.append(product) + else: + if product.outputChannel is not None: + for product2 in product.outputChannel: particle = reactionSuite.PoPs[product2.pid] - if( isinstance( particle, gaugeBosonModule.Particle ) ) : gammas.append( product2 ) - if( len( gammas ) > 0 ) : + if isinstance(particle, gaugeBosonModule.Particle): gammas.append(product2) + if len(gammas) > 0: productChannel = outputChannelModule.OutputChannel(enumsModule.Genre.NBody) - for QForm in outputChannel.Q : productChannel.Q.add( QForm ) - for gamma in gammas : productChannel.products.add( productChannel.products.uniqueLabel( gamma ) ) - productionReaction = orphanProductModule.OrphanProduct('Orphan product %s' % str(i1), productChannel.genre, ENDF_MT = MT ) - endf_endlModule.setReactionsOutputChannelFromOutputChannel( info, productionReaction, productChannel ) - 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( None, reaction.outputChannel.genre, reaction.ENDF_MT, fissionGenre = reaction.fissionGenre ) - endf_endlModule.setReactionsOutputChannelFromOutputChannel( info, fissionComponent, reaction.outputChannel ) - for crossSection in reaction.crossSection : fissionComponent.crossSection.add( crossSection ) - reactionSuite.fissionComponents.add( fissionComponent ) + for QForm in outputChannel.Q: productChannel.Q.add(QForm) + for gamma in gammas: productChannel.products.add(productChannel.products.uniqueLabel(gamma)) + productionReaction = orphanProductModule.OrphanProduct('Orphan product %s' % str(i1), productChannel.genre, + ENDF_MT=MT) + endf_endlModule.setReactionsOutputChannelFromOutputChannel(info, productionReaction, productChannel) + 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( + None, reaction.outputChannel.genre, reaction.ENDF_MT, fissionGenre=reaction.fissionGenre) + endf_endlModule.setReactionsOutputChannelFromOutputChannel(info, fissionComponent, reaction.outputChannel) + for crossSection in reaction.crossSection: fissionComponent.crossSection.add(crossSection) + reactionSuite.fissionComponents.add(fissionComponent) unprocessedMTs = [] for MT in extraMTs: - if MT in list(range(201,208)): + if MT in range(201, 208): outputChannel = outputChannelModule.OutputChannel(enumsModule.Genre.NBody) - label = 'Total %s production' % {201: 'neutron', 202: 'gamma', 203: 'proton', 204: 'deuteron', 205: 'triton', 206: 'helion', 207: 'alpha'}[MT] - productID = {201: IDsPoPsModule.neutron, 202: IDsPoPsModule.photon, 203: IDsPoPsModule.proton, 204: IDsPoPsModule.familiarDeuteron, - 205: IDsPoPsModule.familiarTriton, 206: IDsPoPsModule.familiarHelion, 207: IDsPoPsModule.familiarAlpha}[MT] + label = 'Total %s production' % \ + {201: 'neutron', 202: 'gamma', 203: 'proton', 204: 'deuteron', 205: 'triton', 206: 'helion', + 207: 'alpha'}[MT] + productID = {201: IDsPoPsModule.neutron, 202: IDsPoPsModule.photon, 203: IDsPoPsModule.proton, + 204: IDsPoPsModule.familiarDeuteron, + 205: IDsPoPsModule.familiarTriton, 206: IDsPoPsModule.familiarHelion, + 207: IDsPoPsModule.familiarAlpha}[MT] incompleteReaction = incompleteReactionModule.IncompleteReaction(label, outputChannel.genre, ENDF_MT=MT) - crossSection, outputChannel, MFKeys, LRProducts = parseReaction(info, info.target, info.projectileZA, info.targetZA, - MT, MTDatas[MT], warningList, parseCrossSectionOnly=parseCrossSectionOnly, channelProcess=channelProcess) + crossSection, outputChannel, MFKeys, LRProducts = parseReaction( + info, info.target, info.projectileZA, info.targetZA, MT, MTDatas[MT], warningList, + parseCrossSectionOnly=parseCrossSectionOnly, channelProcess=channelProcess) if len(outputChannel.products) == 0: - productID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(productID, specialNuclearParticleIDPoPsModule.Mode.nuclide) + productID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID( + productID, specialNuclearParticleIDPoPsModule.Mode.nuclide) product = toGNDSMiscModule.newGNDSParticle(info, productID, crossSection) product.distribution.add(unspecifiedModule.Form(info.style, xDataEnumsModule.Frame.lab)) outputChannel.products.add(product) @@ -421,74 +448,74 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect endf_endlModule.setReactionsOutputChannelFromOutputChannel(info, incompleteReaction, outputChannel) incompleteReactions.append(incompleteReaction) if verbose > 0: - print() # put messages for each extraMT on a separate line + print() # put messages for each extraMT on a separate line elif MT in range(851, 871): - continue # dealt with while parsing covariances + continue # dealt with while parsing covariances else: unprocessedMTs.append(MT) if len(unprocessedMTs) > 0: print('INFO: the following MTs were not converted: %s.' % unprocessedMTs) for production in productions: - reactionSuite.productions.add( production ) + reactionSuite.productions.add(production) for incompleteReaction in incompleteReactions: reactionSuite.incompleteReactions.add(incompleteReaction) - if hasattr( info, 'totalDelayedMultiplicity' ) : - fissionOutputchannel = reactionSuite.getReaction( 'fission' ).outputChannel + if hasattr(info, 'totalDelayedMultiplicity'): + fissionOutputchannel = reactionSuite.getReaction('fission').outputChannel - delayedNubar = sumsModule.MultiplicitySum( label = "delayed fission neutron multiplicity", ENDF_MT = 455 ) - for neutron in fissionOutputchannel.fissionFragmentData.delayedNeutrons : - delayedNubar.summands.append( sumsModule.Add( link = neutron.product.multiplicity ) ) - delayedNubar.multiplicity.add( info.totalDelayedMultiplicity ) - reactionSuite.sums.multiplicitySums.add( delayedNubar ) + delayedNubar = sumsModule.MultiplicitySum(label="delayed fission neutron multiplicity", ENDF_MT=455) + for neutron in fissionOutputchannel.fissionFragmentData.delayedNeutrons: + delayedNubar.summands.append(sumsModule.Add(link=neutron.product.multiplicity)) + delayedNubar.multiplicity.add(info.totalDelayedMultiplicity) + reactionSuite.sums.multiplicitySums.add(delayedNubar) - totalNubar = sumsModule.MultiplicitySum( label = "total fission neutron multiplicity", ENDF_MT = 452 ) + totalNubar = sumsModule.MultiplicitySum(label="total fission neutron multiplicity", ENDF_MT=452) for product in fissionOutputchannel.products: if product.pid == IDsPoPsModule.neutron: - totalNubar.summands.append( sumsModule.Add( product.multiplicity ) ) - totalNubar.summands.append( sumsModule.Add( delayedNubar.multiplicity ) ) - totalNubar.multiplicity.add( info.totalOrPromptFissionNeutrons[totalToken] ) - reactionSuite.sums.multiplicitySums.add( totalNubar ) + totalNubar.summands.append(sumsModule.Add(product.multiplicity)) + totalNubar.summands.append(sumsModule.Add(delayedNubar.multiplicity)) + totalNubar.multiplicity.add(info.totalOrPromptFissionNeutrons[totalToken]) + reactionSuite.sums.multiplicitySums.add(totalNubar) warningList = [] - try : # Parse resonance section. + 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 ) - if info.LRP == 2: # LRP was read in from first line of ENDF file + 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) + if info.LRP == 2: # LRP was read in from first line of ENDF file if resonances.resolved: resonances.resolved.evaluated.useForSelfShieldingOnly = True if resonances.unresolved: resonances.unresolved.evaluated.useForSelfShieldingOnly = True reactionSuite.resonances = 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.ENDF_MT == MT ) ] - MTChannels += [ r1 for r1 in reactionSuite.sums.crossSectionSums if( r1.ENDF_MT == MT ) ] - MTChannels += [ r1 for r1 in reactionSuite.fissionComponents if( r1.ENDF_MT == MT ) ] - if( len( MTChannels ) == 0 ) : - if( MT in ( 3, 18, 19 ) ) : + resonanceLink = crossSectionModule.ResonanceLink(link=resonances) + + for MT in resonanceMTs: + MTChannels = [r1 for r1 in reactionSuite.reactions if (r1.ENDF_MT == MT)] + MTChannels += [r1 for r1 in reactionSuite.sums.crossSectionSums if (r1.ENDF_MT == MT)] + MTChannels += [r1 for r1 in reactionSuite.fissionComponents if (r1.ENDF_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 ) : + else: + warningList.append('Unable to find channel corresponding to resonance data for MT%d' % MT) + elif len(MTChannels) == 1: crossSectionComponent = MTChannels[0].crossSection - if( isinstance( crossSectionComponent[info.style], crossSectionModule.CoulombPlusNuclearElastic ) ) : - continue # Don't make any changes to Coulomb elastic scattering. + if isinstance(crossSectionComponent[info.style], crossSectionModule.CoulombPlusNuclearElastic): + continue # Don't make any changes to Coulomb elastic scattering. # break background up into resolved, unresolved and fast regions: haveResolved = (resonances.resolved is not None and not - resonances.resolved.evaluated.useForSelfShieldingOnly) + resonances.resolved.evaluated.useForSelfShieldingOnly) haveUnresolved = (resonances.unresolved is not None and not - resonances.unresolved.evaluated.useForSelfShieldingOnly) + resonances.unresolved.evaluated.useForSelfShieldingOnly) if MT in (18, 19) and not haveUnresolved: # convert to resonancesWithBackground only if resolved region includes fission widths, @@ -497,10 +524,10 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect if isinstance(resolved, resonancesCommonModule.EnergyIntervals): resolved = resolved[-1].evaluated if hasattr(resolved, 'resonanceReactions'): - if not any( [r.isFission() for r in resolved.resonanceReactions]): + if not any([r.isFission() for r in resolved.resonanceReactions]): continue - else: # Breit-Wigner, must resort to looking at column names - if not any( ['fission' in c.name for c in resolved.resonanceParameters.table.columns] ): + else: # Breit-Wigner, must resort to looking at column names + if not any(['fission' in c.name for c in resolved.resonanceParameters.table.columns]): continue originalBackgroundForm = backgroundForm = crossSectionComponent[info.style] @@ -512,10 +539,12 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect if MT == 3 and backgroundForm.domainMin > resonances.scatteringRadius.evaluated.domainMin: # Address error appearing in several JEFF evaluations - warningList.append("MT3 background cross section does not span resonance region. Assuming background == 0") + warningList.append( + "MT3 background cross section does not span resonance region. Assuming background == 0") backgroundForm.prepend(crossSectionModule.XYs1d( axes=backgroundForm.axes, - data=[[resonances.scatteringRadius.evaluated.domainMin, 0], [backgroundForm.domainMin, 0]]) + data=[[resonances.scatteringRadius.evaluated.domainMin, 0], + [backgroundForm.domainMin, 0]]) ) if haveUnresolved: @@ -531,7 +560,8 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect backgroundBoundaries = [region.domainMax for region in backgroundForm[:-1]] missingBoundaries = {} - if haveResolved and (haveUnresolved or haveFast) and resonances.resolved.domainMax not in backgroundBoundaries: + if haveResolved and ( + haveUnresolved or haveFast) and resonances.resolved.domainMax not in backgroundBoundaries: missingBoundaries[resonances.resolved.domainMax] = ['mergeWithNextRegion'] if haveUnresolved and haveFast and resonances.unresolved.domainMax not in backgroundBoundaries: missingBoundaries[resonances.unresolved.domainMax] = ['mergeWithNextRegion'] @@ -545,16 +575,16 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect for boundary in sorted(missingBoundaries.keys()): if boundary not in backgroundForm.domainGrid: missingBoundaries[boundary].append('deletePoint') - bkForm2.append( backgroundForm.domainSlice(domainMin, boundary) ) + bkForm2.append(backgroundForm.domainSlice(domainMin, boundary)) domainMin = boundary - bkForm2.append( backgroundForm.domainSlice(domainMin, backgroundForm.domainMax) ) + bkForm2.append(backgroundForm.domainSlice(domainMin, backgroundForm.domainMax)) - else: # Regions1d + else: # Regions1d startIdx = 0 for boundary in sorted(missingBoundaries.keys()): for idx in range(startIdx, len(backgroundForm)): if backgroundForm[idx].domainMax > boundary: break - bkForm2.append( backgroundForm[idx] ) + bkForm2.append(backgroundForm[idx]) # add the missing boundary: if boundary not in backgroundForm[idx].domainGrid: missingBoundaries[boundary].append('deletePoint') @@ -562,7 +592,8 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect backgroundForm[idx].domainSlice(domainMin, boundary)) domainMin = boundary startIdx = idx - bkForm2.append( backgroundForm[idx].domainSlice(domainMin, backgroundForm[idx].domainMax) ) + bkForm2.append( + backgroundForm[idx].domainSlice(domainMin, backgroundForm[idx].domainMax)) for region in backgroundForm[idx + 1:]: bkForm2.append(region) @@ -583,11 +614,12 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect RRBack.index = None else: RRBack = crossSectionModule.Regions1d(axes=backgroundForm.axes) - for jdx in range(idx+1): + for jdx in range(idx + 1): RRBack.append(backgroundForm[jdx]) - RRBack = crossSectionModule.ResolvedRegion( RRBack ) + RRBack = crossSectionModule.ResolvedRegion(RRBack) if resonances.resolved.domainMax in missingBoundaries: - info.ENDFconversionFlags.add( RRBack, ",".join(missingBoundaries[resonances.resolved.domainMax]) ) + info.ENDFconversionFlags.add(RRBack, + ",".join(missingBoundaries[resonances.resolved.domainMax])) idx += 1 startIdx = idx @@ -597,49 +629,51 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect if backgroundForm[idx].domainMax != resonances.unresolved.domainMax: warningList.append("Domain mismatch between unresolved resonances and background") info.doRaise.append(warningList[-1]) - if idx==startIdx: + if idx == startIdx: URRBack = backgroundForm[idx] URRBack.index = None else: URRBack = crossSectionModule.Regions1d(axes=backgroundForm.axes) - for jdx in range(startIdx,idx+1): + for jdx in range(startIdx, idx + 1): URRBack.append(backgroundForm[jdx]) - URRBack = crossSectionModule.UnresolvedRegion( URRBack ) + URRBack = crossSectionModule.UnresolvedRegion(URRBack) if resonances.unresolved.domainMax in missingBoundaries: - info.ENDFconversionFlags.add( URRBack, ",".join(missingBoundaries[resonances.unresolved.domainMax]) ) + info.ENDFconversionFlags.add(URRBack, ",".join( + missingBoundaries[resonances.unresolved.domainMax])) idx += 1 startIdx = idx if startIdx < len(backgroundForm): - if startIdx == len(backgroundForm)-1: + if startIdx == len(backgroundForm) - 1: fastBack = backgroundForm[startIdx] fastBack.index = None else: fastBack = crossSectionModule.Regions1d(axes=backgroundForm.axes) for jdx in range(startIdx, len(backgroundForm)): fastBack.append(backgroundForm[jdx]) - fastBack = crossSectionModule.FastRegion( fastBack ) + fastBack = crossSectionModule.FastRegion(fastBack) - background_ = crossSectionModule.Background( RRBack, URRBack, fastBack ) + background_ = crossSectionModule.Background(RRBack, URRBack, fastBack) crossSectionComponent.pop(info.style) - crossSectionComponent.add( crossSectionModule.ResonancesWithBackground( - info.style, resonanceLink, background_, backgroundForm.uncertainty ) ) + crossSectionComponent.add(crossSectionModule.ResonancesWithBackground( + info.style, resonanceLink, background_, backgroundForm.uncertainty)) for link in linksToCheck: if link.link is originalBackgroundForm: - link.link = crossSectionComponent[ info.style ] - else : + link.link = crossSectionComponent[info.style] + else: raise NotImplementedError("Multiple reactions match resonance MT%d" % MT) except BadResonances as e: - warningList.append( ' ERROR: unable to parse resonances! Error message: %s' % e ) - info.doRaise.append( warningList[-1] ) + warningList.append(' ERROR: unable to parse resonances! Error message: %s' % e) + info.doRaise.append(warningList[-1]) - MF12BaseMTsAndRange = [[50, 92], [600, 650], [650, 700], [700, 750], [750, 800], [800, 850], [900, 1000] ] + MF12BaseMTsAndRange = [[50, 92], [600, 650], [650, 700], [700, 750], [750, 800], [800, 850], [900, 1000]] if singleMTOnly is None: - for MTLO2, MF12_LO2 in sorted(info.MF12_LO2.items()): # The logic below assumes MTs are in ascending order per base MT. + 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 + for MTBase, MTEnd in MF12BaseMTsAndRange: # Determine base MT for this MTLO2 if MTBase < MTLO2 < MTEnd: branchingBaseMT = MTBase break @@ -684,22 +718,26 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect finalParticle = toGNDSMiscModule.getPoPsParticle(info, residualZA, levelIndex=level, level=levelEnergy, levelUnit='eV') - particleLevelEnergy_eV = reactionSuite.PoPs[fullName].energy[0].value # Compare this value to level energy from the particle list (from MF3 Q-value). + particleLevelEnergy_eV = reactionSuite.PoPs[fullName].energy[0].value + # Compare this value to level energy from the particle list (from MF3 Q-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: + 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. + # 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' if str1 != str2: - warningList.append("MT%d MF12 level energy %s differs from MF3 value %s. Setting to MF%s value." % - (MTLO2, levelEnergy, particleLevelEnergy_eV, MFLabel)) + 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)) @@ -707,7 +745,7 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect for i1, MF12 in enumerate(MF12_LO2): try: finalLevelEnergy = MF12['ESk'] - if finalLevelEnergy > 0.: # Find particle in the particleList with energy = finalLevelEnergy + if finalLevelEnergy > 0.: # Find particle in the particleList with energy = finalLevelEnergy finalParticles = [lev for lev in reactionSuite.PoPs[residualName].ancestor if lev.energy.float('eV') == finalLevelEnergy] if len(finalParticles) == 1: @@ -717,10 +755,12 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect idx = 0 while True: idx += 1 - finalParticleName = chemicalElementMiscModule.nuclideIDFromIsotopeSymbolAndIndex(residualName, idx) + finalParticleName = chemicalElementMiscModule.nuclideIDFromIsotopeSymbolAndIndex( + residualName, 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)) + 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]) try: thisLevelEnergy = reactionSuite.PoPs[finalParticleName].energy.float('eV') @@ -731,7 +771,7 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect raise if abs(thisLevelEnergy - finalLevelEnergy) < 1e-4 * finalLevelEnergy: finalParticle = reactionSuite.PoPs[finalParticleName] - break # found it + break # found it else: finalParticle = reactionSuite.PoPs[residualName] gammaTransition = 1. @@ -746,21 +786,22 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect _decay.products.add(productModule.Product(IDsPoPsModule.photon, IDsPoPsModule.photon)) _decay.products.add(productModule.Product(finalParticle.id, finalParticle.id)) decayMode.decayPath.add(_decay) - if MF12['LG'] == 2: # internal conversion competes with gamma emission + if MF12['LG'] == 2: # internal conversion competes with gamma emission from PoPs.decays import spectrum as spectrumModule - Pgamma = spectrumModule.Shell(MF12['branching'][1], label=spectrumModule.Shell.total, unit='') + Pgamma = spectrumModule.Shell(MF12['branching'][1], label=spectrumModule.Shell.total, + unit='') decayMode.photonEmissionProbabilities.add(Pgamma) reactionSuite.PoPs[fullName].decayData.decayModes.add(decayMode) except Exception as err: warningList.append('raise somewhere in "for MF12 in MF12_LO2" loop: MT%d, %s' % (MT, err)) info.doRaise.append(warningList[-1]) - else : + else: raise Exception("Could not determine base MT for MF=12's MT=%s" % MTLO2) if doCovariances: - covarianceMFs = sorted(set([mf for mt in MTDatas.values() for mf in mt.keys() if mf>30])) + 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))) + 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 """ @@ -786,7 +827,7 @@ def ITYPE_0(MTDatas, info, reactionSuite, singleMTOnly, MTs2Skip, parseCrossSect evaluated = info.evaluatedStyle.copy() evaluated.documentation.endfCompatible.body = None covarianceSuite.styles.add(evaluated) - #covarianceSuite.removeExtraZeros() # disable for easier comparison to ENDF + # covarianceSuite.removeExtraZeros() # disable for easier comparison to ENDF else: covarianceSuite = None except Exception as e: @@ -862,13 +903,13 @@ def overridePoPsIfNecessary(AWRI, spinParity=None): 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') + 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 # neutron already handled as special case mass = info.massTracker.amuMasses[ZA] - elementSymbol = chemicalElementMiscModule.symbolFromZ[ZA//1000] + elementSymbol = chemicalElementMiscModule.symbolFromZ[ZA // 1000] name = chemicalElementMiscModule.isotopeSymbolFromChemicalElementIDAndA(elementSymbol, ZA % 1000) name = chemicalElementMiscModule.nuclideIDFromIsotopeSymbolAndIndex(name, 0) mass = massModule.Double(info.PoPsLabel, mass, quantityModule.stringToPhysicalUnit('amu')) @@ -891,17 +932,17 @@ def overridePoPsIfNecessary(AWRI, spinParity=None): if particleID == reactionSuite.target: particleID = targetID if particleID == 'target': particle = reactionSuite.PoPs[targetID] - else : + else: particle = reactionSuite.PoPs[particleID] if isinstance(particle, nuclideModule.Particle): particle = particle.nucleus - if len(particle.spin) == 0: particle.spin.add( spin ) + if len(particle.spin) == 0: particle.spin.add(spin) if spinParity[1]: parity = spinParity[1].value particle.parity.add(parityModule.Integer(info.PoPsLabel, parity, parityModule.baseUnit)) - for reaction in reactionSuite.reactions: # For two-body reactions, this sections decays an excited state + for reaction in reactionSuite.reactions: # For two-body reactions, this sections decays an excited state if reaction.ENDF_MT == 2: continue if reaction.outputChannel.genre == enumsModule.Genre.twoBody: @@ -910,7 +951,7 @@ def overridePoPsIfNecessary(AWRI, spinParity=None): particle = info.PoPs[residual.pid] if isinstance(particle, nuclideModule.Particle): addGroundState = particle.nucleus.index != 0 - if addGroundState: # gamma data should be in orphanProducts. + if addGroundState: # gamma data should be in orphanProducts. groundState = particle.isotope.nuclides[0] ZA = chemicalElementMiscModule.ZA(groundState) multiplicity = residual.multiplicity[0].copy() @@ -929,7 +970,8 @@ def overridePoPsIfNecessary(AWRI, spinParity=None): if reconstructResonances and reactionSuite.resonances is not None and reactionSuite.resonances.reconstructCrossSection: info.logs.write(' Reconstructing resonances\n') try: - reactionSuite.reconstructResonances(info.reconstructedStyle, info.reconstructedAccuracy, verbose=verbose, thin=True) + reactionSuite.reconstructResonances(info.reconstructedStyle, info.reconstructedAccuracy, verbose=verbose, + thin=True) except Exception as ex: warningList.append("Resonance reconstruction failed: %s" % ex) info.resonanceReconstructionFailed = str(ex) @@ -939,7 +981,7 @@ def adjustMF13Multiplicity2(multiplicity, crossSection): energyMultiplicity = [] if multiplicity.domainMax > crossSection.domainMax: - multiplicity = multiplicity.domainSlice(domainMax = crossSection.domainMax) + multiplicity = multiplicity.domainSlice(domainMax=crossSection.domainMax) for energyIn, multiplicityValue in multiplicity: crossSectionAtEnergy = crossSection.evaluate(energyIn) if crossSectionAtEnergy != 0: multiplicityValue /= crossSectionAtEnergy @@ -986,7 +1028,7 @@ def adjustMF13Gammas(reaction): gammaProduction = gammaProduction[0] summands = [sumsModule.Add(link=r.multiplicity) for r in gammaProduction.outputChannel.getProductsWithName(IDsPoPsModule.photon)] - if len(summands)==0: + if len(summands) == 0: for _product in gammaProduction.outputChannel: if _product.outputChannel is not None: summands += [sumsModule.Add(link=r.multiplicity) for r in @@ -997,7 +1039,7 @@ def adjustMF13Gammas(reaction): name = gammaProduction.outputChannel.toString(MT=MT) multiplicitySum = sumsModule.MultiplicitySum(label=name + " total gamma multiplicity", ENDF_MT=MT) - for summand in summands : multiplicitySum.summands.append(summand) + for summand in summands: multiplicitySum.summands.append(summand) multiplicitySum.multiplicity.add(multiplicity) reactionSuite.sums.multiplicitySums.add(multiplicitySum) diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0_Misc.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0_Misc.py index 36c454c7..2feae1ba 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0_Misc.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_0_Misc.py @@ -1954,7 +1954,8 @@ def readMF6(MT, info, MF6Data, productList, warningList, undefinedLevelInfo, isT NA = int(KalbachMannData['Lists'][0]['L2']) dataPerPoint = NA + 2 - fData = energyModule.XYs2d(axes=KalbachMann_f_Axes, interpolation=interpolation, interpolationQualifier=interpolationQualifier) + fData = [energyModule.XYs2d(axes=KalbachMann_f_Axes, interpolation=interpolation, + interpolationQualifier=interpolationQualifier)] ra_interpolationQualifier = { xDataEnumsModule.InterpolationQualifier.none: xDataEnumsModule.InterpolationQualifier.none, @@ -1962,11 +1963,13 @@ def readMF6(MT, info, MF6Data, productList, warningList, undefinedLevelInfo, isT xDataEnumsModule.InterpolationQualifier.correspondingPoints: xDataEnumsModule.InterpolationQualifier.correspondingPoints }[interpolationQualifier] - rData = KalbachMannModule.XYs2d(axes=KalbachMann_r_Axes, interpolation=interpolation, interpolationQualifier=ra_interpolationQualifier) + rData = [KalbachMannModule.XYs2d(axes=KalbachMann_r_Axes, interpolation=interpolation, + interpolationQualifier=ra_interpolationQualifier)] aData = None if NA == 2: - aData = KalbachMannModule.XYs2d(axes=KalbachMann_a_Axes, interpolation=interpolation, interpolationQualifier=ra_interpolationQualifier) + aData = [KalbachMannModule.XYs2d(axes=KalbachMann_a_Axes, interpolation=interpolation, + interpolationQualifier=ra_interpolationQualifier)] priorE, priorEp_f_r_ = -1, [-1, -1, -1] for i1, data in enumerate(KalbachMannData['Lists']): @@ -1977,32 +1980,48 @@ def readMF6(MT, info, MF6Data, productList, warningList, undefinedLevelInfo, isT priorEp_f_r__ = [Ep_, f_, r_] if value == priorE: if i1 == 1: - fData.pop(0) - rData.pop(0) + fData[-1].pop(0) + rData[-1].pop(0) if aData is not None: - aData.pop(0) + aData[-1].pop(0) else: if priorEp_f_r_ == priorEp_f_r__: continue # For TENDL files with duplicate data. - print('\nMT=%d' % MT) - print(value, priorEp_f_r_) - print(priorE, priorEp_f_r__) - raise NotImplementedError('hell - need to support regions') + + # Discontinuous data, need to split into regions + fData.append(KalbachMannModule.XYs2d(axes=KalbachMann_f_Axes, interpolation=interpolation, + interpolationQualifier=interpolationQualifier)) + rData.append(KalbachMannModule.XYs2d(axes=KalbachMann_r_Axes, interpolation=interpolation, + interpolationQualifier=ra_interpolationQualifier)) + if aData is not None: + aData.append( + KalbachMannModule.XYs2d(axes=KalbachMann_a_Axes, interpolation=interpolation, + interpolationQualifier=ra_interpolationQualifier)) + priorE, priorEp_f_r_ = value, priorEp_f_r__ if Ep_[-2] == Ep_[-1]: Ep_[-1] *= 1.00000001 - fData.append(energyModule.XYs1d(data=(Ep_, f_), dataForm='xsandys', axes=KalbachMann_f_Axes, + fData[-1].append(energyModule.XYs1d(data=(Ep_, f_), dataForm='xsandys', axes=KalbachMann_f_Axes, outerDomainValue=value, interpolation=interpolationLEP)) - rData.append(XYs1dModule.XYs1d(data=(Ep_, r_), dataForm= 'xsandys', axes=KalbachMann_r_Axes, + rData[-1].append(XYs1dModule.XYs1d(data=(Ep_, r_), dataForm= 'xsandys', axes=KalbachMann_r_Axes, outerDomainValue=value, interpolation=interpolationLEP)) if aData is not None: a_ = data['data'][3::dataPerPoint] - aData.append(XYs1dModule.XYs1d(data=(Ep_, a_), dataForm='xsandys', axes=KalbachMann_a_Axes, + aData[-1].append(XYs1dModule.XYs1d(data=(Ep_, a_), dataForm='xsandys', axes=KalbachMann_a_Axes, outerDomainValue=value, interpolation=interpolationLEP)) - fSubform = KalbachMannModule.FSubform(fData) - rSubform = KalbachMannModule.RSubform(rData) - aSubform = KalbachMannModule.ASubform(aData) + def toRegionsIfNeeded(section): + if section is None: return + if len(section) == 1: return section[0] # XYs2d + regions_ = KalbachMannModule.Regions2d() + for subsection in section: + regions_.append(subsection) + regions_.axes = regions_[0].axes + return regions_ + + fSubform = KalbachMannModule.FSubform(toRegionsIfNeeded(fData)) + rSubform = KalbachMannModule.RSubform(toRegionsIfNeeded(rData)) + aSubform = KalbachMannModule.ASubform(toRegionsIfNeeded(aData)) form = KalbachMannModule.Form(info.style, frame, fSubform, rSubform, aSubform) elif( LANG in [ 11, 12, 13, 14, 15 ] ) : # P(E',mu|E) @@ -3146,7 +3165,7 @@ def read_LCOMP2_correlation(NNN, NM, NDIGIT, dat): row -= 1 col -= 1 if row >= NNN or col >= row: - raise BadCovariance("Matrix indices out of range for MF32 LCOMP=2 matrix") + raise BadCovariance("Matrix indices out of range for MF32 LCOMP=2 matrix: (%d,%d) vs. %d" % (row,col,NNN)) matrix[row, col:col+len(vals)] = vals for idx in range(NNN): # symmetrize matrix[idx, idx:] = matrix[idx:, idx] @@ -3642,6 +3661,7 @@ def makeURRcovariance(uncert, energyBounds, conversionFlag=None): # find URR section corresponding to each row in the matrix: matrixSections = [] + urr_warnings = [] for L, J, averageParams in LJs: conversionFlag = [] for key in sorted(averageParams): @@ -3651,16 +3671,26 @@ def makeURRcovariance(uncert, energyBounds, conversionFlag=None): lsections = [lsec for lsec in URR.Ls if lsec.L == L] if len(lsections) == 0: - raise BadCovariance("No match in MF2 for MF32 URR section with L=%d" % L) + urr_warnings.append("No match in MF2 for MF32 URR section with L=%d" % L) + continue lsection, = lsections jsections = [jsec for jsec in lsection.Js if jsec.J == J] if len(jsections) == 0: - raise BadCovariance("No match in MF2 for MF32 URR section with L=%d, J=%d" % (L, J)) + urr_warnings.append("No match in MF2 for MF32 URR section with L=%d, J=%d" % (L, J)) + continue jsection, = jsections matrixSections.append([lsection.L, jsection.J, jsection.levelSpacing, conversionFlag]) for idx in range(MPAR-1): matrixSections.append([lsection.L, jsection.J, jsection.widths[idx], conversionFlag]) + if urr_warnings: + print("Errors encountered in MF=32 URR covariance section:") + for warning in urr_warnings: + print(" " + warning) + warningList += urr_warnings + info.doRaise.append("Encountered malformed MF=32 URR data") + continue + assert len(matrixSections) == len(matrix) crossTermCounter = 0 diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_1.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_1.py index 6535a0b8..f274ea6c 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_1.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_1.py @@ -32,81 +32,86 @@ energyUnit = 'eV' -def parseMF454_459( info, fissionFragmentData, MT, MTDatas ) : +def parseMF454_459(info, fissionFragmentData, MT, MTDatas): MFData = MTDatas[MT] MF8Data = MFData[8] - ZA, AWR, LE_plus1 = endfFileToGNDSMiscModule.sixFunkyFloatStringsToIntsAndFloats( MF8Data[0], intIndices = [ 0, 2 ], logFile = info.logs )[0:3] + ZA, AWR, LE_plus1 = endfFileToGNDSMiscModule.sixFunkyFloatStringsToIntsAndFloats( + MF8Data[0], intIndices=[0, 2], logFile=info.logs)[0:3] info.ZA_massLineInfo.add(ZA, AWR, MT, 8, 0) line = 1 - if( MT == 454 ) : - elapsedTime = elapsedTimeModule.ElapsedTime( 'initial' ) - elapsedTime.time.add( timeModule.Double( 'initial', 0.0, 's' ) ) - else : - elapsedTime = elapsedTimeModule.ElapsedTime( 'unspecified' ) - elapsedTime.time.add( timeModule.String( 'unspecified', 'unspecified', 's' ) ) + if MT == 454: + elapsedTime = elapsedTimeModule.ElapsedTime('initial') + elapsedTime.time.add(timeModule.Double('initial', 0.0, 's')) + else: + elapsedTime = elapsedTimeModule.ElapsedTime('unspecified') + elapsedTime.time.add(timeModule.String('unspecified', 'unspecified', 's')) - for iLE in range( LE_plus1 ) : - line, ENDFList = endfFileToGNDSMiscModule.getList( line, MF8Data, logFile = info.logs ) + for iLE in range(LE_plus1): + line, ENDFList = endfFileToGNDSMiscModule.getList(line, MF8Data, logFile=info.logs) NFP = ENDFList['N2'] data = ENDFList['data'] - interpolation = ENDFList['L1'] # Currently ignored. + interpolation = ENDFList['L1'] # Currently ignored. fissionProducts = [] yields = [] uncertainties = [] - for iFP in range( NFP ): - ZAFP = int( data[iFP*4] ) - FPS = int( data[iFP*4+1] ) - FPID = chemicalElementMiscPoPsModule.idFromZA( ZAFP ) - if( FPS > 0 ) : FPID = aliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex(FPID, FPS) - if( FPID in fissionProducts ) : raise Exception( 'FPID = %s already in fissionProducts' % FPID ) - fissionProducts.append( FPID ) - - yields.append( data[iFP*4+2] ) - uncertainties.append( data[iFP*4+3] ) - - if( ( MT == 454 ) and ( iLE == 0 ) ) : - productYield = productYieldModule.ProductYield( info.style ) - fissionFragmentData.productYields.add( productYield ) - else : + for iFP in range(NFP): + ZAFP = int(data[iFP * 4]) + FPS = int(data[iFP * 4 + 1]) + FPID = chemicalElementMiscPoPsModule.idFromZA(ZAFP) + if FPS > 0: FPID = aliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex(FPID, FPS) + if FPID in fissionProducts: raise Exception('FPID = %s already in fissionProducts' % FPID) + fissionProducts.append(FPID) + + yields.append(data[iFP * 4 + 2]) + uncertainties.append(data[iFP * 4 + 3]) + + if (MT == 454) and (iLE == 0): + productYield = productYieldModule.ProductYield(info.style) + fissionFragmentData.productYields.add(productYield) + else: productYield = fissionFragmentData.productYields[0] - incidentEnergy = incidentEnergyModule.IncidentEnergy( str( iLE ) ) - incidentEnergy.energy.add( incidentEnergyModule.Double( str( iLE ), ENDFList[ 'C1' ], energyUnit ) ) + incidentEnergy = incidentEnergyModule.IncidentEnergy(str(iLE)) + incidentEnergy.energy.add(incidentEnergyModule.Double(str(iLE), ENDFList['C1'], energyUnit)) incidentEnergy.yields.nuclides = nuclidesModule.Nuclides(fissionProducts) - incidentEnergy.yields.values = yieldsModule.Values( yields ) + incidentEnergy.yields.values = yieldsModule.Values(yields) - variances = [u**2 for u in uncertainties] - diagonal = arrayModule.Diagonal( shape = ( len( variances ), len( variances ) ), data = variances ) - covariance = yieldsModule.Covariance( diagonal ) - incidentEnergy.yields.uncertainty = yieldsModule.Uncertainty( covariance ) + variances = [u ** 2 for u in uncertainties] + diagonal = arrayModule.Diagonal(shape=(len(variances), len(variances)), data=variances) + covariance = yieldsModule.Covariance(diagonal) + incidentEnergy.yields.uncertainty = yieldsModule.Uncertainty(covariance) - elapsedTime.incidentEnergies.add( incidentEnergy ) + elapsedTime.incidentEnergies.add(incidentEnergy) - productYield.elapsedTimes.add( elapsedTime ) + productYield.elapsedTimes.add(elapsedTime) -def ITYPE_1( MTDatas, info, verbose = 0 ) : + +def ITYPE_1(MTDatas, info, verbose=0): """Parses ENDF NFY data.""" errors = [] - info.PoPs.documentation.endfCompatible.body = '\n'.join( MTDatas[451][1][4:-info.NXC] ) # Add ENDF documentation + info.PoPs.documentation.endfCompatible.body = '\n'.join(MTDatas[451][1][4:-info.NXC]) # Add ENDF documentation endfFileToGNDSMiscModule.completeDocumentation(info, info.PoPs.documentation) - parentAtom = toGNDSMiscModule.getPoPsParticle( info, info.targetZA, name = None, levelIndex = info.levelIndex, level = info.level, levelUnit = energyUnit ) - if( len( parentAtom.mass ) == 0 ) : - parentAtom.mass.add( massModule.Double( info.PoPsLabel, info.massTracker.neutronMass * info.targetMass, quantityModule.stringToPhysicalUnit( 'amu' ) ) ) - if( len( parentAtom.nucleus.halflife ) == 0 ) : - parentAtom.nucleus.halflife.add( halflifeModule.String( info.PoPsLabel, halflifeModule.UNSTABLE, halflifeModule.baseUnit ) ) + parentAtom = toGNDSMiscModule.getPoPsParticle(info, info.targetZA, name=None, levelIndex=info.levelIndex, + level=info.level, levelUnit=energyUnit) + if len(parentAtom.mass) == 0: + parentAtom.mass.add(massModule.Double(info.PoPsLabel, info.massTracker.neutronMass * info.targetMass, + quantityModule.stringToPhysicalUnit('amu'))) + if len(parentAtom.nucleus.halflife) == 0: + parentAtom.nucleus.halflife.add( + halflifeModule.String(info.PoPsLabel, halflifeModule.UNSTABLE, halflifeModule.baseUnit)) - fissionFragmentData = fissionFragmentDataModule.FissionFragmentData( ) + fissionFragmentData = fissionFragmentDataModule.FissionFragmentData() - if( 454 in MTDatas ) : parseMF454_459( info, fissionFragmentData, 454, MTDatas ) - if( 459 in MTDatas ) : parseMF454_459( info, fissionFragmentData, 459, MTDatas ) + if 454 in MTDatas: parseMF454_459(info, fissionFragmentData, 454, MTDatas) + if 459 in MTDatas: parseMF454_459(info, fissionFragmentData, 459, MTDatas) # check if all elapsed times / incident energies use same list of nuclides nuclides = fissionFragmentData.productYields[info.style].elapsedTimes[0].incidentEnergies[0].yields.nuclides @@ -128,4 +133,4 @@ def ITYPE_1( MTDatas, info, verbose = 0 ) : fissionFragmentData.productYields.add(newProductYield) - return { 'fissionFragmentData' : fissionFragmentData, 'PoPs' : info.PoPs, 'errors' : errors, 'info' : info } + return {'fissionFragmentData': fissionFragmentData, 'PoPs': info.PoPs, 'errors': errors, 'info': info} diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_2.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_2.py index 4493c29a..de8b1cd6 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_2.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_2.py @@ -28,8 +28,9 @@ from PoPs.quantities import quantity as quantityModule from PoPs.quantities import mass as massModule from PoPs.families import unorthodox as unorthodoxModule +from PoPs.chemicalElements import chemicalElement as chemicalElementModule -from fudge import enums as enumsModule +from fudge import enums as enumsModule, targetInfo from fudge import physicalQuantity as physicalQuantityModule from fudge import styles as stylesModule from fudge import reactionSuite as reactionSuiteModule @@ -182,6 +183,13 @@ def ITYPE_2(fileName, MAT, MTDatas, info, evaluation, verbose): # Unfortunately libraries use different conventions for TNSL MAT numbers, and ZSYMAM can only be 11 chars raise Exception("Cannot determine TNSL target ZA or id from filename %s" % fileName) + targetInfo_ = None + info.boundAtomCrossSections = [] + if 7 in MTDatas[451]: + # ENDF-6 now (as of 2023) supports listing isotopic abundances within TNSL. Parse those into 'targetInfo' + dat = MTDatas[451][7] + targetInfo_, info.boundAtomCrossSections = readMF7_info(info, dat) + target = toGNDSMiscModule.getTypeNameGamma(info, ZA) if targetID is None: targetID = "tnsl-" + target.id tnsl_target = unorthodoxModule.Particle(targetID) @@ -193,6 +201,10 @@ def ITYPE_2(fileName, MAT, MTDatas, info, evaluation, verbose): interaction = enumsModule.Interaction.TNSL info.principalScattererPid = target.id + if len(info.boundAtomCrossSections) > 1: + # switch principal scattering atom to chemical element: + popsParticle = info.PoPs[target.id] + info.principalScattererPid = popsParticle.chemicalElementSymbol info.scatterers = scatterers evaluatedStyle.documentation.endfCompatible.body = info.documentation endfFileToGNDSMisc.completeDocumentation(info, evaluatedStyle.documentation) @@ -222,6 +234,8 @@ def ITYPE_2(fileName, MAT, MTDatas, info, evaluation, verbose): reactionSuite = reactionSuiteModule.ReactionSuite(info.projectile, targetID, evaluation, style=evaluatedStyle, interaction=interaction, formatVersion=info.formatVersion, MAT=MAT, PoPs=info.PoPs) + if targetInfo_ is not None: + reactionSuite.styles.getEvaluatedStyle().targetInfo = targetInfo_ for reaction in reactions: reactionSuite.reactions.add(reaction) @@ -345,18 +359,25 @@ def readMF7(info, MT, MF7): boundAtomCrossSection = incoherentInelasticModule.BoundAtomCrossSection( freeAtomCrossSection * ((massAMU + neutronMassAMU) / massAMU) ** 2, 'b') + boundAtomCrossSectionByNuclide = None + if hasattr(info, 'boundAtomCrossSections'): + boundAtomCrossSectionByNuclide = incoherentInelasticModule.BoundAtomCrossSectionByNuclide() + for bac in info.boundAtomCrossSections: + boundAtomCrossSectionByNuclide.add(bac) + principalAtom = { 'pid': pid, 'numberPerMolecule': numberPerMolecule, 'mass': incoherentInelasticModule.Mass(massAMU, 'amu'), 'e_max': incoherentInelasticModule.E_max(b_n[3], 'eV'), 'boundAtomCrossSection': boundAtomCrossSection, + 'boundAtomCrossSectionByNuclide': boundAtomCrossSectionByNuclide, 'selfScatteringKernel': None, # principal scattering kernel is read after all scattering atoms 'primaryScatterer': True, 'e_critical': incoherentInelasticModule.E_critical(b_n[1], 'eV') } - if len(info.PoPs[pid].mass) == 0: + if pid in info.PoPs and len(info.PoPs[pid].mass) == 0: mass = massModule.Double(info.PoPsLabel, massAMU, quantityModule.stringToPhysicalUnit('amu')) info.PoPs[pid].mass.add(mass) @@ -512,3 +533,41 @@ def readMF7(info, MT, MF7): if line != len(MF7): raise ValueError("Trailing data left in MT%i MF7!" % MT) return forms + + +def readMF7_info(info, dat): + ZA, AWR, NA, dum, dum, dum = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(dat[0], range(2, 6)) + neutronMassAMU = info.PoPs[IDsPoPsModule.neutron].mass.float('amu') + + targetInfo_ = targetInfo.TargetInfo() + boundAtomCrossSections = [] + line = 1 + for element_idx in range(NA): + dum, dum, NAS, dum, tmp, NI = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(dat[line], range(2, 6)) + assert tmp == NI * 6, f"Malformed line #{line} in MF=7 MT=451" + line += 1 + + element = None + for nuclide_index in range(NI): + ZAI, LISI, AFI, AWRI, SFI, dum = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(dat[line]) + if LISI != 0: + raise NotImplementedError("Isomeric state in MF=7 MT=451") + pops_nuclide = toGNDSMiscModule.getTypeNameGamma(info, int(ZAI)) + info.PoPs.add(pops_nuclide) + massAMU = AWRI * neutronMassAMU + mass = massModule.Double(info.PoPsLabel, massAMU, quantityModule.stringToPhysicalUnit('amu')) + info.PoPs[pops_nuclide.id].mass.add(mass) + + boundAtomCrossSections.append(incoherentInelasticModule.BoundAtomCrossSection( + SFI * ((massAMU + neutronMassAMU) / massAMU) ** 2, 'b', label=pops_nuclide.id)) + nuclide = targetInfo.Nuclide(pops_nuclide.id, AFI) + + if element is None: + symbol = pops_nuclide.findClassInAncestry(chemicalElementModule.ChemicalElement).symbol + element = targetInfo.ChemicalElement(symbol) + element.nuclides.add(nuclide) + line += 1 + + targetInfo_.isotopicAbundances.chemicalElements.add(element) + + return targetInfo_, boundAtomCrossSections diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_3_6_Misc.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_3_6_Misc.py index 66482074..b926917d 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_3_6_Misc.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_3_6_Misc.py @@ -10,14 +10,14 @@ """ MT_AtomicConfigurations = { - 534 : '1s1/2', 535 : '2s1/2', 536 : '2p1/2', 537 : '2p3/2', 538 : '3s1/2', - 539 : '3p1/2', 540 : '3p3/2', 541 : '3d3/2', 542 : '3d5/2', 543 : '4s1/2', - 544 : '4p1/2', 545 : '4p3/2', 546 : '4d3/2', 547 : '4d5/2', 548 : '4f5/2', - 549 : '4f7/2', 550 : '5s1/2', 551 : '5p1/2', 552 : '5p3/2', 553 : '5d3/2', - 554 : '5d5/2', 555 : '5f5/2', 556 : '5f7/2', 557 : '5g7/2', 558 : '5g9/2', - 559 : '6s1/2', 560 : '6p1/2', 561 : '6p3/2', 562 : '6d3/2', 563 : '6d5/2', - 564 : '6f5/2', 565 : '6f7/2', 566 : '6g7/2', 567 : '6g9/2', 568 : '6h9/2', - 569 : '6h11/2', 570 : '7s1/2', 571 : '7p1/2', 572 : '7p3/2' } + 534: '1s1/2', 535: '2s1/2', 536: '2p1/2', 537: '2p3/2', 538: '3s1/2', + 539: '3p1/2', 540: '3p3/2', 541: '3d3/2', 542: '3d5/2', 543: '4s1/2', + 544: '4p1/2', 545: '4p3/2', 546: '4d3/2', 547: '4d5/2', 548: '4f5/2', + 549: '4f7/2', 550: '5s1/2', 551: '5p1/2', 552: '5p3/2', 553: '5d3/2', + 554: '5d5/2', 555: '5f5/2', 556: '5f7/2', 557: '5g7/2', 558: '5g9/2', + 559: '6s1/2', 560: '6p1/2', 561: '6p3/2', 562: '6d3/2', 563: '6d5/2', + 564: '6f5/2', 565: '6f7/2', 566: '6g7/2', 567: '6g9/2', 568: '6h9/2', + 569: '6h11/2', 570: '7s1/2', 571: '7p1/2', 572: '7p3/2'} # also create reverse lookup for translating back to ENDF-6: AtomicConfigurations_MT = {} diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_4.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_4.py index 101d9cb4..8bddad9f 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_4.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_4.py @@ -33,236 +33,245 @@ from brownies.legacy.converting import toGNDSMisc energyUnit = 'eV' -alphaID = chemicalElementMiscPoPsModule.nucleusIDFromZAndA( 2, 4 ) - -decayType = { 0 : 'gamma', - 1 : 'beta-', - 2 : 'beta+ or e.c.', # or electron capture... - 3 : 'IT', - 4 : 'alpha', - 5 : IDsPoPsModule.neutron, - 6 : 'SF', - 7 : IDsPoPsModule.proton, - 8 : 'e-', - 9 : 'xray', - 10 : 'unknown' } - -decayParticles = { 0 : IDsPoPsModule.photon, - 1 : IDsPoPsModule.electron, - 2 : IDsPoPsModule.positron, - 3 : None, - 4 : alphaID, - 5 : IDsPoPsModule.neutron, - 6 : None, - 7 : IDsPoPsModule.proton, - 8 : IDsPoPsModule.electron, - 9 : IDsPoPsModule.photon, - 10 : IDsPoPsModule.electronAntiNeutrino, - 11 : IDsPoPsModule.electronNeutrino } - -STYPProduct = { 0 : spectrumModule.gammaProduct, - 1 : spectrumModule.betaMinusProduct, - 2 : spectrumModule.betaPlusOrElectronCaptureProduct, - 4 : spectrumModule.alphaProduct, - 5 : spectrumModule.neutronProduct, - 6 : spectrumModule.SFProduct, - 7 : spectrumModule.protonProduct, - 8 : spectrumModule.discreteElectronProduct, - 9 : spectrumModule.xRayProduct, - 10 : spectrumModule.antiNeutrinoProduct, - 11 : spectrumModule.neutrinoProduct } - -def addProductToDecayMode( info, decayMode, decayParticleID, RFS = 0, lastDecayMode = False ) : - - if( lastDecayMode and ( RFS != 0 ) ) : - isotopeNuclideID = chemicalElementMiscPoPsModule.nuclideIDFromIsotopeSymbolAndIndex( decayParticleID, RFS ) - metaStableID = PoPsAliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex(isotopeNuclideID, RFS) +alphaID = chemicalElementMiscPoPsModule.nucleusIDFromZAndA(2, 4) + +decayType = {0: 'gamma', + 1: 'beta-', + 2: 'beta+ or e.c.', # or electron capture... + 3: 'IT', + 4: 'alpha', + 5: IDsPoPsModule.neutron, + 6: 'SF', + 7: IDsPoPsModule.proton, + 8: 'e-', + 9: 'xray', + 10: 'unknown'} + +decayParticles = {0: IDsPoPsModule.photon, + 1: IDsPoPsModule.electron, + 2: IDsPoPsModule.positron, + 3: None, + 4: alphaID, + 5: IDsPoPsModule.neutron, + 6: None, + 7: IDsPoPsModule.proton, + 8: IDsPoPsModule.electron, + 9: IDsPoPsModule.photon, + 10: IDsPoPsModule.electronAntiNeutrino, + 11: IDsPoPsModule.electronNeutrino} + +STYPProduct = {0: spectrumModule.gammaProduct, + 1: spectrumModule.betaMinusProduct, + 2: spectrumModule.betaPlusOrElectronCaptureProduct, + 4: spectrumModule.alphaProduct, + 5: spectrumModule.neutronProduct, + 6: spectrumModule.SFProduct, + 7: spectrumModule.protonProduct, + 8: spectrumModule.discreteElectronProduct, + 9: spectrumModule.xRayProduct, + 10: spectrumModule.antiNeutrinoProduct, + 11: spectrumModule.neutrinoProduct} + + +def addProductToDecayMode(info, decayMode, decayParticleID, RFS=0, lastDecayMode=False): + if lastDecayMode and (RFS != 0): + isotopeNuclideID = chemicalElementMiscPoPsModule.nuclideIDFromIsotopeSymbolAndIndex(decayParticleID, RFS) + metaStableID = PoPsAliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex( + isotopeNuclideID, RFS) info.PoPs.add(PoPsAliasModule.MetaStable(metaStableID, isotopeNuclideID, RFS)) decayParticleID = metaStableID - decayMode.products.add( decayMode.products.uniqueLabel( productModule.Product( decayParticleID, decayParticleID ) ) ) + decayMode.products.add(decayMode.products.uniqueLabel(productModule.Product(decayParticleID, decayParticleID))) -def addDecayMode( info, decayMode, decayParticleIndex, parentZA, RFS, lastDecayMode ) : +def addDecayMode(info, decayMode, decayParticleIndex, parentZA, RFS, lastDecayMode): decayParticleID = decayParticles[decayParticleIndex] decayModeType = decayDataModule.decayModesParticle - if( decayParticleID is None ) : - if( decayParticleIndex == 3 ) : + if decayParticleID is None: + if decayParticleIndex == 3: decayModeType = decayDataModule.decayModesIT - elif( decayParticleIndex == 6 ) : + elif decayParticleIndex == 6: decayModeType = decayDataModule.decayModesSF - else : - print( ' Oops', decayParticleIndex ) + else: + print(' Oops', decayParticleIndex) return - complete = decayParticleIndex not in [ 2, 6 ] - _decay = decayDataModule.Decay( str( len( decayMode.decayPath ) ), decayModeType, complete = complete ) + complete = decayParticleIndex not in [2, 6] + _decay = decayDataModule.Decay(str(len(decayMode.decayPath)), decayModeType, complete=complete) decayParticleZ = 0 decayParticleA = 0 - if( decayParticleID is not None ) : - if( decayParticleID != IDsPoPsModule.positron ) : addProductToDecayMode( info, _decay, decayParticleID ) + if decayParticleID is not None: + if decayParticleID != IDsPoPsModule.positron: addProductToDecayMode(info, _decay, decayParticleID) - if( decayParticleID == IDsPoPsModule.electron ) : + if decayParticleID == IDsPoPsModule.electron: decayParticleZ = -1 - addProductToDecayMode( info, _decay, IDsPoPsModule.electronAntiNeutrino ) - elif( decayParticleID == IDsPoPsModule.positron ) : + addProductToDecayMode(info, _decay, IDsPoPsModule.electronAntiNeutrino) + elif decayParticleID == IDsPoPsModule.positron: decayParticleZ = +1 - elif( decayParticleID == IDsPoPsModule.photon ) : + elif decayParticleID == IDsPoPsModule.photon: pass - elif( decayParticleID == IDsPoPsModule.neutron ) : + elif decayParticleID == IDsPoPsModule.neutron: decayParticleZ, decayParticleA = 0, 1 - elif( decayParticleID == IDsPoPsModule.proton ) : + elif decayParticleID == IDsPoPsModule.proton: decayParticleZ, decayParticleA = 1, 1 - else : + else: decayParticleZ, decayParticleA = 2, 4 - residialProductZA = parentZA - ( 1000 * decayParticleZ + decayParticleA ) - if( residialProductZA == 1 ) : + residialProductZA = parentZA - (1000 * decayParticleZ + decayParticleA) + if residialProductZA == 1: residialProductID = IDsPoPsModule.neutron - else : - residialProductID = chemicalElementMiscPoPsModule.idFromZAndA( residialProductZA // 1000, residialProductZA % 1000 ) - if( decayParticleIndex != 6 ) : addProductToDecayMode( info, _decay, residialProductID, RFS, lastDecayMode ) + else: + residialProductID = chemicalElementMiscPoPsModule.idFromZAndA(residialProductZA // 1000, + residialProductZA % 1000) + if decayParticleIndex != 6: addProductToDecayMode(info, _decay, residialProductID, RFS, lastDecayMode) - decayMode.decayPath.add( _decay ) - return( residialProductZA ) + decayMode.decayPath.add(_decay) + return residialProductZA -def getRTYP( line, offset = 0 ) : - RTYP = line[offset:offset+11] - RTYP = RTYP.split( '+' )[0] - RTYP = RTYP.split( 'e' )[0] - RTYP = RTYP.split( 'E' )[0] - RTYP = RTYP.strip( '0' ) - initialDecay, otherDecays = RTYP.split( '.' ) - initialDecay = int( initialDecay ) - otherDecays = [ int( digit ) for digit in otherDecays ] +def getRTYP(line, offset=0): + RTYP = line[offset:offset + 11] + RTYP = RTYP.split('+')[0] + RTYP = RTYP.split('e')[0] + RTYP = RTYP.split('E')[0] + RTYP = RTYP.strip('0') + initialDecay, otherDecays = RTYP.split('.') + initialDecay = int(initialDecay) + otherDecays = [int(digit) for digit in otherDecays] - RTYP_key = "%d.%s" % ( initialDecay, ''.join( [ "%s" % other for other in otherDecays ] ) ) + RTYP_key = "%d.%s" % (initialDecay, ''.join(["%s" % other for other in otherDecays])) - return( initialDecay, otherDecays, RTYP_key ) + return initialDecay, otherDecays, RTYP_key -def addDiscreteSpectra( decayModes, RTYP_key, decayParticleIndex, discreteSpectra ) : - def addInternalConversionCoefficients( discrete, RIC, dRIC, label ) : +def addDiscreteSpectra(decayModes, RTYP_key, decayParticleIndex, discreteSpectra): + def addInternalConversionCoefficients(discrete, RIC, dRIC, label): internalConversionCoefficients = spectrumModule.Shell(RIC, label=label, unit='') - addUncertainty( internalConversionCoefficients, dRIC ) - discrete.internalConversionCoefficients.add( internalConversionCoefficients ) + addUncertainty(internalConversionCoefficients, dRIC) + discrete.internalConversionCoefficients.add(internalConversionCoefficients) decayParticleID = decayParticles[decayParticleIndex] - if( decayParticleID is None ) : raise Exception( 'decayParticleID is None, what is to be done?' ) + if decayParticleID is None: raise Exception('decayParticleID is None, what is to be done?') decayParticleLabel = STYPProduct[decayParticleIndex] spectra = decayModes[RTYP_key].spectra - if( decayParticleLabel not in spectra ) : - spectrum = spectrumModule.Spectrum( decayParticleLabel, decayParticleID ) - spectra.add( spectrum ) - else : + if decayParticleLabel not in spectra: + spectrum = spectrumModule.Spectrum(decayParticleLabel, decayParticleID) + spectra.add(spectrum) + else: spectrum = spectra[decayParticleLabel] RTYP, TYPE, RI, dRI, RIS, dRIS = discreteSpectra['RTYP_plus'] - if( RIS != 0 ) : print( "STYP, RIS =", decayParticleIndex, RIS ) + if RIS != 0: print("STYP, RIS =", decayParticleIndex, RIS) - if( TYPE == 1.0 ) : + if TYPE == 1.0: type = spectrumModule.TransitionType.allowed - elif( TYPE == 2.0 ) : + elif TYPE == 2.0: type = spectrumModule.TransitionType.firstForbidden - elif( TYPE == 3.0 ) : + elif TYPE == 3.0: type = spectrumModule.TransitionType.secondForbidden - else : + else: type = spectrumModule.TransitionType.none - intensity = spectrumModule.Intensity( RI ) - addUncertainty( intensity, dRI ) + intensity = spectrumModule.Intensity(RI) + addUncertainty(intensity, dRI) - energy = spectrumModule.Energy( discreteSpectra['ER'], energyUnit ) - addUncertainty( energy, discreteSpectra['dER'] ) + energy = spectrumModule.Energy(discreteSpectra['ER'], energyUnit) + addUncertainty(energy, discreteSpectra['dER']) positronIntensity = None - if( decayParticleIndex == 0 and RIS != 0 ) : - RIS = spectrumModule.InternalPairFormationCoefficient( RIS ) - elif( decayParticleIndex == 2 and RIS != 0 ) : # STYP=2 means interpret RIS differently - positronIntensity = spectrumModule.PositronEmissionIntensity( RIS ) - addUncertainty( positronIntensity, dRIS ) + if decayParticleIndex == 0 and RIS != 0: + RIS = spectrumModule.InternalPairFormationCoefficient(RIS) + elif (decayParticleIndex == 2) and (RIS != 0): # STYP=2 means interpret RIS differently + positronIntensity = spectrumModule.PositronEmissionIntensity(RIS) + addUncertainty(positronIntensity, dRIS) RIS = None - else : + else: RIS = None - discrete = spectrumModule.Discrete( intensity, energy, type = type, _internalPairFormationCoefficient = RIS, - _positronEmissionIntensity = positronIntensity ) - if( 'RICC' in discreteSpectra ) : - addInternalConversionCoefficients( discrete, discreteSpectra['RICC'], discreteSpectra['dRICC'], spectrumModule.Shell.total ) - if( 'RICK' in discreteSpectra ) : - addInternalConversionCoefficients( discrete, discreteSpectra['RICK'], discreteSpectra['dRICK'], spectrumModule.Shell.KShell ) - if( 'RICL' in discreteSpectra ) : - addInternalConversionCoefficients( discrete, discreteSpectra['RICL'], discreteSpectra['dRICL'], spectrumModule.Shell.LShell ) - spectrum.append( discrete ) - -def addContinuumSpectrum( decayModes, RTYP_key, decayParticleIndex, regions, covariance ) : - + discrete = spectrumModule.Discrete(intensity, energy, type=type, _internalPairFormationCoefficient=RIS, + _positronEmissionIntensity=positronIntensity) + if 'RICC' in discreteSpectra: + addInternalConversionCoefficients(discrete, discreteSpectra['RICC'], discreteSpectra['dRICC'], + spectrumModule.Shell.total) + if 'RICK' in discreteSpectra: + addInternalConversionCoefficients(discrete, discreteSpectra['RICK'], discreteSpectra['dRICK'], + spectrumModule.Shell.KShell) + if 'RICL' in discreteSpectra: + addInternalConversionCoefficients(discrete, discreteSpectra['RICL'], discreteSpectra['dRICL'], + spectrumModule.Shell.LShell) + spectrum.append(discrete) + + +def addContinuumSpectrum(decayModes, RTYP_key, decayParticleIndex, regions, covariance): decayParticleID = decayParticles[decayParticleIndex] - if( decayParticleID is None ) : raise TypeError( 'decayParticleID is None, what is to be done?' ) + if decayParticleID is None: raise TypeError('decayParticleID is None, what is to be done?') decayParticleLabel = STYPProduct[decayParticleIndex] - if RTYP_key not in decayModes: raise KeyError( "RTYP %s not found is list of decay modes, RTYP's in this evaluation are %s"%(RTYP_key,str(decayModes.keys())) ) + if RTYP_key not in decayModes: raise KeyError( + "RTYP %s not found is list of decay modes, RTYP's in this evaluation are %s" % ( + RTYP_key, str(decayModes.keys()))) spectra = decayModes[RTYP_key].spectra - if( decayParticleLabel not in spectra ) : - spectrum = spectrumModule.Spectrum( decayParticleLabel, decayParticleID ) - spectra.add( spectrum ) - else : + if decayParticleLabel not in spectra: + spectrum = spectrumModule.Spectrum(decayParticleLabel, decayParticleID) + spectra.add(spectrum) + else: spectrum = spectra[decayParticleLabel] - if( len( regions ) == 1 ) : + if len(regions) == 1: data = regions[0] data.axes = spectrumModule.Continuum.defaultAxes(energyUnit) - else : - print( "len( regions ) > 1" ) + else: + print("len( regions ) > 1") raise NotImplementedError("Continuum spectrum with multiple interpolation regions") - continuum = spectrumModule.Continuum( data ) - spectrum.append( continuum ) + continuum = spectrumModule.Continuum(data) + spectrum.append(continuum) -def addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, cls ) : - if( len( aveDecayEnergies ) > 0 ) : - if( aveDecayEnergies[0] >= 0 ) : - averageEnergy = cls( aveDecayEnergies[0], energyUnit ) - addUncertainty( averageEnergy, aveDecayEnergies[1] ) - decayData.averageEnergies.add( averageEnergy ) +def addAverageDecayEnergyIfPresent(decayData, aveDecayEnergies, cls): + if len(aveDecayEnergies) > 0: + if aveDecayEnergies[0] >= 0: + averageEnergy = cls(aveDecayEnergies[0], energyUnit) + addUncertainty(averageEnergy, aveDecayEnergies[1]) + decayData.averageEnergies.add(averageEnergy) aveDecayEnergies = aveDecayEnergies[2:] - return( aveDecayEnergies ) + return aveDecayEnergies + -def addUncertainty( quantity, value ) : +def addUncertainty(quantity, value): + if value == 0: return + quantity.uncertainty = uncertaintyModule.Uncertainty(standardModule.Standard(uncertaintyModule.Double(value))) - if( value == 0 ) : return - quantity.uncertainty = uncertaintyModule.Uncertainty( standardModule.Standard( uncertaintyModule.Double( value ) ) ) -def printInfo( verbose, dataIndex, MT457MF8Data ) : +def printInfo(verbose, dataIndex, MT457MF8Data): + if verbose > 4: print(' dataIndex = ', dataIndex, MT457MF8Data[dataIndex], verbose) + return 1 - if( verbose > 4 ) : print( ' dataIndex = ', dataIndex, MT457MF8Data[dataIndex], verbose ) - return( 1 ) -def ITYPE_4( MTDatas, info, verbose = 0 ) : +def ITYPE_4(MTDatas, info, verbose=0): """Convert ENDF ITYPE 4 data (decay data) into PoPs.""" errors = [] - evalStyle = stylesPoPsModule.Evaluated( 'eval', '', info.library, info.libraryVersion, info.Date ) - evalStyle.documentation.endfCompatible.body = '\n'.join( MTDatas[451][1][4:-info.NXC] ) # Add ENDF documentation + evalStyle = stylesPoPsModule.Evaluated('eval', '', info.library, info.libraryVersion, info.Date) + evalStyle.documentation.endfCompatible.body = '\n'.join(MTDatas[451][1][4:-info.NXC]) # Add ENDF documentation endfFileToGNDSMisc.completeDocumentation(info, evalStyle.documentation) - info.PoPs.styles.add( evalStyle ) + info.PoPs.styles.add(evalStyle) # The atom containing the parent nucleus - parentAtom = toGNDSMisc.getPoPsParticle(info, info.targetZA, name = None, levelIndex = info.levelIndex, level = info.level, - levelUnit = energyUnit) + parentAtom = toGNDSMisc.getPoPsParticle(info, info.targetZA, name=None, levelIndex=info.levelIndex, + level=info.level, + levelUnit=energyUnit) parentAtom.mass.add( - massModule.Double( info.style, info.massTracker.amuMasses[info.targetZA], 'amu' ) + massModule.Double(info.style, info.massTracker.amuMasses[info.targetZA], 'amu') ) decayParticle = parentAtom - if(chemicalElementMiscPoPsModule.hasNucleus( parentAtom)) : decayParticle = parentAtom.nucleus + if chemicalElementMiscPoPsModule.hasNucleus(parentAtom): decayParticle = parentAtom.nucleus - if( 457 in MTDatas ) : + if 457 in MTDatas: dataIndex = 0 MT457MF8Data = MTDatas[457][8] @@ -270,137 +279,162 @@ def ITYPE_4( MTDatas, info, verbose = 0 ) : # Read parent info block AWR_lineNumber = dataIndex - ZA, AWR, LIS, LISO, NST, NSP = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MT457MF8Data[dataIndex], intIndices = [2, 3, 4, 5]) + ZA, AWR, LIS, LISO, NST, NSP = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MT457MF8Data[dataIndex], intIndices=[2, 3, 4, 5]) info.ZA_massLineInfo.add(ZA, AWR, 457, 8, AWR_lineNumber, LIS=LIS) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) - if( LIS != 0 ) : - aliasID = "%s_m%s" % ( parentAtom.isotope.symbol, LISO ) + if LIS != 0: + aliasID = "%s_m%s" % (parentAtom.isotope.symbol, LISO) info.PoPs.add(PoPsAliasModule.MetaStable(aliasID, parentAtom.id, LISO)) - HL, dHL, dummy, dummy, NC2, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MT457MF8Data[dataIndex], intIndices=[4]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) + HL, dHL, dummy, dummy, NC2, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MT457MF8Data[dataIndex], intIndices=[4]) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) - NC = NC2 // 2 # NC: number of decay energies - if( NC not in [ 3, 17 ] ) : raise ValueError( "Number of decay energies must be 3 or 17, found %d" % NC ) - nlines = ( NC2 + 5 ) // 6 + NC = NC2 // 2 # NC: number of decay energies + if NC not in [3, 17]: raise ValueError("Number of decay energies must be 3 or 17, found %d" % NC) + nlines = (NC2 + 5) // 6 aveDecayEnergies = [] - for index in range( nlines ) : + for index in range(nlines): aveDecayEnergies.extend(endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(MT457MF8Data[dataIndex])) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) - - if( len( [ aveDecayEnergy for aveDecayEnergy in aveDecayEnergies if( aveDecayEnergy != 0 ) ] ) > 0 ) : - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.LightParticles ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.ElectroMagneticRadiation ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.HeavyParticles ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.BetaMinus ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.BetaPlus ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.AugerElectron ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.ConversionElectron ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.Gamma ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.XRay ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.InternalBremsstrahlung ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.Annihilation ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.Alpha ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.Recoil ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.SpontaneousFission ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.FissionNeutrons ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.Proton ) - aveDecayEnergies = addAverageDecayEnergyIfPresent( decayData, aveDecayEnergies, averageEnergyModule.Neutrino ) - - SPI, PAR, dum, dum, NDK6, NDK = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MT457MF8Data[dataIndex], intIndices = [1, 2, 3, 4, 5]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) - if( -77.8 < SPI < -77.7 ) : SPI = None # see page 180 of ENDF manual # FIXME: Need "UNKNOWN" markup + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) + + if len([aveDecayEnergy for aveDecayEnergy in aveDecayEnergies if (aveDecayEnergy != 0)]) > 0: + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.LightParticles) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.ElectroMagneticRadiation) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.HeavyParticles) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.BetaMinus) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.BetaPlus) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.AugerElectron) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.ConversionElectron) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.Gamma) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.XRay) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.InternalBremsstrahlung) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.Annihilation) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.Alpha) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.Recoil) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.SpontaneousFission) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.FissionNeutrons) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.Proton) + aveDecayEnergies = addAverageDecayEnergyIfPresent( + decayData, aveDecayEnergies, averageEnergyModule.Neutrino) + + SPI, PAR, dum, dum, NDK6, NDK = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MT457MF8Data[dataIndex], intIndices=[1, 2, 3, 4, 5]) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) + if -77.8 < SPI < -77.7: SPI = None # see page 180 of ENDF manual # FIXME: Need "UNKNOWN" markup halflifeValue = None - if( NST == 1 ) : halflifeValue = 'stable' - if( PAR == 0 ) : PAR = None # BRB, Happens for dec-013_Al_040.endf - toGNDSMisc.addParticleData(decayParticle, info, massValue = None, spinValue = SPI, parityValue = PAR, - chargeValue = None, halflifeValue = halflifeValue) + if NST == 1: halflifeValue = 'stable' + if PAR == 0: PAR = None # BRB, Happens for dec-013_Al_040.endf + toGNDSMisc.addParticleData(decayParticle, info, massValue=None, spinValue=SPI, parityValue=PAR, + chargeValue=None, halflifeValue=halflifeValue) - if( NST == 1 ) : # Nucleus is stable, nothing to do + if NST == 1: # Nucleus is stable, nothing to do pass - elif( NST == 0 ) : # Nucleus is unstable - halflife = halflifeModule.Double( info.PoPsLabel, HL, halflifeModule.baseUnit ) - addUncertainty( halflife, dHL ) - decayParticle.halflife.add( halflife ) + elif NST == 0: # Nucleus is unstable + halflife = halflifeModule.Double(info.PoPsLabel, HL, halflifeModule.baseUnit) + addUncertainty(halflife, dHL) + decayParticle.halflife.add(halflife) # Iterate over decay chains decayModes = {} - for i1 in range( NDK ) : # iterate over decay modes - initialDecay, otherDecays, RTYP_key = getRTYP( MT457MF8Data[dataIndex] ) + for i1 in range(NDK): # iterate over decay modes + initialDecay, otherDecays, RTYP_key = getRTYP(MT457MF8Data[dataIndex]) RTYP, RFS, Q, dQ, BR, dBR = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(MT457MF8Data[dataIndex]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) - if( verbose > 3 ) : print( 'RTYP = ', RTYP ) - RFS = int( RFS ) # BRB, Isometic state of daughter + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) + if verbose > 3: print('RTYP = ', RTYP) + RFS = int(RFS) # BRB, Isometic state of daughter - allDecays = [ initialDecay ] + otherDecays - decayMode = decayDataModule.DecayMode( str( i1 ), ','.join( [ decayType[r_id] for r_id in allDecays ] ) ) + allDecays = [initialDecay] + otherDecays + decayMode = decayDataModule.DecayMode(str(i1), ','.join([decayType[r_id] for r_id in allDecays])) decayModes[RTYP_key] = decayMode - Q = QModule.Double( info.PoPsLabel, Q, energyUnit ) - addUncertainty( Q, dQ ) - decayMode.Q.add( Q ) - - probability = probabilityModule.Double( "BR", BR, '' ) - addUncertainty( probability, dBR ) - decayMode.probability.add( probability ) - # FIXME: what should we do for really small probabilities, so small ENDF gives 0, like spontaneous fission? - n1 = len( otherDecays ) - 1 - residualZA = addDecayMode( info, decayMode, initialDecay, info.targetZA, RFS, -1 == n1 ) - for i2, otherDecay in enumerate( otherDecays ) : - residualZA = addDecayMode( info, decayMode, otherDecay, residualZA, RFS, i2 == n1 ) - decayData.decayModes.add( decayMode ) - - # LCON determines whether continuum spectra given: LCON 0: discrete only, 1: continuous only, 2: both - for i1 in range( NSP ) : # Iterate over spectra - zero, STYP, LCON, LCOV, six, NER = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MT457MF8Data[dataIndex], intIndices = [2, 3, 4, 5]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) + Q = QModule.Double(info.PoPsLabel, Q, energyUnit) + addUncertainty(Q, dQ) + decayMode.Q.add(Q) + + probability = probabilityModule.Double("BR", BR, '') + addUncertainty(probability, dBR) + decayMode.probability.add(probability) + # FIXME: what should we do for really small probabilities, so small ENDF gives 0, like spontaneous fission? + n1 = len(otherDecays) - 1 + residualZA = addDecayMode(info, decayMode, initialDecay, info.targetZA, RFS, -1 == n1) + for i2, otherDecay in enumerate(otherDecays): + residualZA = addDecayMode(info, decayMode, otherDecay, residualZA, RFS, i2 == n1) + decayData.decayModes.add(decayMode) + + # LCON determines whether continuum spectra given: LCON 0: discrete only, 1: continuous only, 2: both + for i1 in range(NSP): # Iterate over spectra + zero, STYP, LCON, LCOV, six, NER = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MT457MF8Data[dataIndex], intIndices=[2, 3, 4, 5]) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) if zero != 0 or six != 6: print(" WARNING: unexpected value for spectrum header on line %d of MF8 MT457" % dataIndex) # FIXME following values are unused. Could check against spectra and warn if they aren't consistent? - FD, dFD, ERave, dERave, FC, dFC = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(MT457MF8Data[dataIndex]) # FD: discrete normalization, FC: continuum norm., ERave: average decay energy - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) - - if( LCON != 1 ) : # Discrete spectra given. - for i2 in range( NER ) : - ER, dER, dum, dum, NT, dum = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MT457MF8Data[dataIndex], intIndices = [2, 3, 4, 5]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) - discreteSpectra = { 'ER': ER, 'dER': dER } - if( LCON != 1 ) : - if( NT not in ( 6, 8, 12 ) ) : raise ValueError( "Unexpected NT=%d encountered!" % NT ) - initialDecay, otherDecays, RTYP_key = getRTYP( MT457MF8Data[dataIndex] ) - discreteSpectra['RTYP_plus'] = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(MT457MF8Data[dataIndex]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) - if( verbose > 3 ) : print( 'STYP, RTYP = ', STYP, RTYP_key ) - if( NT > 6 ) : - RICC, dRICC, RICK, dRICK, RICL, dRICL = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(MT457MF8Data[dataIndex]) - dataIndex += printInfo( verbose, dataIndex, MT457MF8Data ) + FD, dFD, ERave, dERave, FC, dFC = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(MT457MF8Data[ + dataIndex]) # FD: discrete normalization, FC: continuum norm., ERave: average decay energy + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) + + if LCON != 1: # Discrete spectra given. + for i2 in range(NER): + ER, dER, dum, dum, NT, dum = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MT457MF8Data[dataIndex], intIndices=[2, 3, 4, 5]) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) + discreteSpectra = {'ER': ER, 'dER': dER} + if LCON != 1: + if NT not in (6, 8, 12): raise ValueError("Unexpected NT=%d encountered!" % NT) + initialDecay, otherDecays, RTYP_key = getRTYP(MT457MF8Data[dataIndex]) + discreteSpectra['RTYP_plus'] = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats( + MT457MF8Data[dataIndex]) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) + if verbose > 3: print('STYP, RTYP = ', STYP, RTYP_key) + if NT > 6: + RICC, dRICC, RICK, dRICK, RICL, dRICL = endfFileToGNDSMisc.sixFunkyFloatStringsToFloats( + MT457MF8Data[dataIndex]) + dataIndex += printInfo(verbose, dataIndex, MT457MF8Data) discreteSpectra['RICC'], discreteSpectra['dRICC'] = RICC, dRICC - if( NT > 8 ) : + if NT > 8: discreteSpectra['RICK'], discreteSpectra['dRICK'] = RICK, dRICK discreteSpectra['RICL'], discreteSpectra['dRICL'] = RICL, dRICL - addDiscreteSpectra( decayModes, RTYP_key, STYP, discreteSpectra ) + addDiscreteSpectra(decayModes, RTYP_key, STYP, discreteSpectra) - if( LCON != 0 ) : # Continuum spectra given. - initialDecay, otherDecays, RTYP_key = getRTYP( MT457MF8Data[dataIndex] ) + if LCON != 0: # Continuum spectra given. + initialDecay, otherDecays, RTYP_key = getRTYP(MT457MF8Data[dataIndex]) try: dataIndex, TAB1, regions = endfFileToGNDSMisc.getTAB1Regions(dataIndex, MT457MF8Data) RTYP = TAB1['C1'] - if( verbose > 3 ) : print( 'STYP, RTYP = ', STYP, RTYP ) - LCOV = int( TAB1['L2'] ) - if( len( regions ) != 1 ) : raise IndexError( 'len( regions ) = %s' % len( regions ) ) + if verbose > 3: print('STYP, RTYP = ', STYP, RTYP) + LCOV = int(TAB1['L2']) + if len(regions) != 1: raise IndexError('len( regions ) = %s' % len(regions)) covariance = None - if( LCOV != 0 ) : - print( " LCOV != 0" ) + if LCOV != 0: + print(" LCOV != 0") dataIndex, covariance = endfFileToGNDSMisc.getList(dataIndex, MT457MF8Data) - addContinuumSpectrum( decayModes, RTYP_key, STYP, regions, covariance ) + addContinuumSpectrum(decayModes, RTYP_key, STYP, regions, covariance) except Exception as err: import sys - print('ERROR: '+str(err),file=sys.stderr) - else : - raise ValueError( "In decay data (MT=457,MF=8), NST should be 0 or 1. Found %d" % NST ) + print('ERROR: ' + str(err), file=sys.stderr) + else: + raise ValueError("In decay data (MT=457,MF=8), NST should be 0 or 1. Found %d" % NST) - return( { 'PoPs' : info.PoPs, 'errors' : errors, 'info' : info } ) + return {'PoPs': info.PoPs, 'errors': errors, 'info': info} diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_5.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_5.py index a18aab60..1d3a46aa 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_5.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_5.py @@ -28,76 +28,82 @@ energyUnit = 'eV' -def parseMF454_459( info, fissionFragmentData, MT, MTDatas ) : +def parseMF454_459(info, fissionFragmentData, MT, MTDatas): MFData = MTDatas[MT] MF8Data = MFData[8] - ZA, AWR, LE_plus1 = endfFileToGNDSMiscModule.sixFunkyFloatStringsToIntsAndFloats( MF8Data[0], intIndices = [ 0, 2 ], logFile = info.logs )[0:3] + ZA, AWR, LE_plus1 = endfFileToGNDSMiscModule.sixFunkyFloatStringsToIntsAndFloats( + MF8Data[0], intIndices=[0, 2], logFile=info.logs)[0:3] info.ZA_massLineInfo.add(ZA, AWR, MT, 8, 0) - if( LE_plus1 != 1 ) : raise Exception( 'This is not spontaneous fission yield data.' ) + if LE_plus1 != 1: raise Exception('This is not spontaneous fission yield data.') line = 1 fissionProducts = [] - line, ENDFList = endfFileToGNDSMiscModule.getList( line, MF8Data, logFile = info.logs ) - NFP = ENDFList ['N2'] + line, ENDFList = endfFileToGNDSMiscModule.getList(line, MF8Data, logFile=info.logs) + NFP = ENDFList['N2'] data = ENDFList['data'] yields = [] uncertainties = [] - for iFP in range( NFP ): - ZAFP = int( data[iFP*4] ) - FPS = int( data[iFP*4+1] ) - FPID = chemicalElementMiscPoPsModule.idFromZA( ZAFP ) - if( FPS > 0 ) : FPID = aliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex(FPID, FPS) - if( FPID in fissionProducts ) : raise Exception( 'FPID = "%s" already in fissionProducts.' % FPID ) - fissionProducts.append( FPID ) - - yields.append( data[iFP*4+2] ) - uncertainties.append( data[iFP*4+3] ) - - if( len( fissionFragmentData.productYields ) == 0 ) : - fissionFragmentData.productYields.add( productYieldModule.ProductYield( info.style, fissionProducts ) ) - else : - if( fissionFragmentData.productYields[0].nuclides != fissionProducts ) : - raise Exception( 'Fission products differ between independent and cumulative.' ) - - if( MT == 454 ) : + for iFP in range(NFP): + ZAFP = int(data[iFP * 4]) + FPS = int(data[iFP * 4 + 1]) + FPID = chemicalElementMiscPoPsModule.idFromZA(ZAFP) + if FPS > 0: FPID = aliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex(FPID, FPS) + if FPID in fissionProducts: raise Exception('FPID = "%s" already in fissionProducts.' % FPID) + fissionProducts.append(FPID) + + yields.append(data[iFP * 4 + 2]) + uncertainties.append(data[iFP * 4 + 3]) + + if len(fissionFragmentData.productYields) == 0: + fissionFragmentData.productYields.add(productYieldModule.ProductYield(info.style, fissionProducts)) + else: + if fissionFragmentData.productYields[0].nuclides != fissionProducts: + raise Exception('Fission products differ between independent and cumulative.') + + if MT == 454: elapsedTime = elapsedTimeModule.ElapsedTime('initial') - elapsedTime.time.add( timeModule.Double( info.style, 0.0, 's' ) ) - else : + elapsedTime.time.add(timeModule.Double(info.style, 0.0, 's')) + else: elapsedTime = elapsedTimeModule.ElapsedTime('unspecified') - elapsedTime.time.add( timeModule.String( info.style, 'unspecified', 's' ) ) + elapsedTime.time.add(timeModule.String(info.style, 'unspecified', 's')) - elapsedTime.yields.nuclides = yieldsModule.NuclidesLink(fissionFragmentData.productYields[0].nuclides, relative=True) - elapsedTime.yields.values = yieldsModule.Values( yields ) + elapsedTime.yields.nuclides = yieldsModule.NuclidesLink(fissionFragmentData.productYields[0].nuclides, + relative=True) + elapsedTime.yields.values = yieldsModule.Values(yields) - variances = [u**2 for u in uncertainties] - diagonal = arrayModule.Diagonal( shape = ( len( variances ), len( variances ) ), data = variances ) - covariance = yieldsModule.Covariance( diagonal ) - uncertainty = yieldsModule.Uncertainty( covariance ) + variances = [u ** 2 for u in uncertainties] + diagonal = arrayModule.Diagonal(shape=(len(variances), len(variances)), data=variances) + covariance = yieldsModule.Covariance(diagonal) + uncertainty = yieldsModule.Uncertainty(covariance) elapsedTime.yields.uncertainty = uncertainty - fissionFragmentData.productYields[0].elapsedTimes.add( elapsedTime ) + fissionFragmentData.productYields[0].elapsedTimes.add(elapsedTime) -def ITYPE_5( MTDatas, info, verbose = 0 ) : + +def ITYPE_5(MTDatas, info, verbose=0): """Parses ENDF SFY data.""" errors = [] - evalStyle = stylesPoPsModule.Evaluated( 'eval', '', info.library, info.libraryVersion, info.Date ) - evalStyle.documentation.endfCompatible.body = '\n'.join( MTDatas[451][1][4:-info.NXC] ) # Add ENDF documentation + evalStyle = stylesPoPsModule.Evaluated('eval', '', info.library, info.libraryVersion, info.Date) + evalStyle.documentation.endfCompatible.body = '\n'.join(MTDatas[451][1][4:-info.NXC]) # Add ENDF documentation endfFileToGNDSMiscModule.completeDocumentation(info, evalStyle.documentation) info.PoPs.styles.add(evalStyle) - parentAtom = toGNDSMiscModule.getPoPsParticle( info, info.targetZA, name = None, levelIndex = info.levelIndex, level = info.level, levelUnit = energyUnit ) - if( len( parentAtom.mass ) == 0 ) : - parentAtom.mass.add( massModule.Double( info.PoPsLabel, info.massTracker.neutronMass * info.targetMass, quantityModule.stringToPhysicalUnit( 'amu' ) ) ) - if( len( parentAtom.nucleus.halflife ) == 0 ) : - parentAtom.nucleus.halflife.add( halflifeModule.String( info.PoPsLabel, halflifeModule.UNSTABLE, halflifeModule.baseUnit ) ) + parentAtom = toGNDSMiscModule.getPoPsParticle(info, info.targetZA, name=None, levelIndex=info.levelIndex, + level=info.level, levelUnit=energyUnit) + if len(parentAtom.mass) == 0: + parentAtom.mass.add(massModule.Double(info.PoPsLabel, info.massTracker.neutronMass * info.targetMass, + quantityModule.stringToPhysicalUnit('amu'))) + if len(parentAtom.nucleus.halflife) == 0: + parentAtom.nucleus.halflife.add( + halflifeModule.String(info.PoPsLabel, halflifeModule.UNSTABLE, halflifeModule.baseUnit)) fissionFragmentData = parentAtom.fissionFragmentData - if( 454 in MTDatas ) : parseMF454_459( info, fissionFragmentData, 454, MTDatas ) - if( 459 in MTDatas ) : parseMF454_459( info, fissionFragmentData, 459, MTDatas ) + if 454 in MTDatas: parseMF454_459(info, fissionFragmentData, 454, MTDatas) + if 459 in MTDatas: parseMF454_459(info, fissionFragmentData, 459, MTDatas) - return { 'PoPs' : info.PoPs, 'errors' : errors, 'info' : info } + return {'PoPs': info.PoPs, 'errors': errors, 'info': info} diff --git a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_6.py b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_6.py index 6736ffe0..82a00712 100644 --- a/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_6.py +++ b/brownies/legacy/converting/ENDFToGNDS/ENDF_ITYPE_6.py @@ -24,78 +24,86 @@ from . import endfFileToGNDSMisc from .ENDF_ITYPE_3_6_Misc import MT_AtomicConfigurations -def ITYPE_6( Z, MTDatas, info, verbose = 0 ) : + +def ITYPE_6(Z, MTDatas, info, verbose=0): """Parses ENDF atomic relaxation data.""" MT = 533 errors = [] elementSymbol = chemicalElementMiscModule.symbolFromZ[Z] - MTs = sorted( MTDatas.keys( ) ) - if( 451 in MTs ) : MTs.remove( 451 ) - if( MTs != [ MT ] ) : raise Exception( 'Only allowed MT is %s (and 451): %s' % ( MT, MTs ) ) + MTs = sorted(MTDatas.keys()) + if 451 in MTs: MTs.remove(451) + if MTs != [MT]: raise Exception('Only allowed MT is %s (and 451): %s' % (MT, MTs)) warningList = [] MFData = MTDatas[MT] - info.logs.write( ' %3d %s' % ( MT, sorted( MFData.keys( ) ) ) ) + info.logs.write(' %3d %s' % (MT, sorted(MFData.keys()))) - if( list( MFData.keys( ) ) != [ 28 ] ) : - raise Exception( 'For MT %s data, only allowed MF is 28: %s' % ( MT, list( MFData.keys( ) ) ) ) + if list(MFData.keys()) != [28]: + raise Exception('For MT %s data, only allowed MF is 28: %s' % (MT, list(MFData.keys()))) MF28 = MFData[28] - PoPs = databasePoPsModule.Database( "ENDF atomic relaxation for Z = %s" % Z, '1.0', formatVersion = info.formatVersion ) - evalStyle = stylesPoPsModule.Evaluated( 'eval', '', info.library, info.libraryVersion, info.Date ) + PoPs = databasePoPsModule.Database("ENDF atomic relaxation for Z = %s" % Z, '1.0', formatVersion=info.formatVersion) + evalStyle = stylesPoPsModule.Evaluated('eval', '', info.library, info.libraryVersion, info.Date) evalStyle.documentation.endfCompatible.body = info.documentation endfFileToGNDSMisc.completeDocumentation(info, evalStyle.documentation) - PoPs.styles.add( evalStyle ) - chemicalElement = chemicalElementModule.ChemicalElement( elementSymbol, Z, chemicalElementMiscModule.nameFromZ[Z] ) - PoPs.add( chemicalElement ) + PoPs.styles.add(evalStyle) + chemicalElement = chemicalElementModule.ChemicalElement(elementSymbol, Z, chemicalElementMiscModule.nameFromZ[Z]) + PoPs.add(chemicalElement) - atomicData = atomicModule.Atomic( ) + atomicData = atomicModule.Atomic() chemicalElement.atomicData = atomicData offset = 0 - ZA, AWP, dummy, dummy, NSS, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MF28[offset], intIndices = [4], logFile = info.logs) + ZA, AWP, dummy, dummy, NSS, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MF28[offset], intIndices=[4], logFile=info.logs) info.ZA_massLineInfo.add(ZA, AWP, MT, 28, offset) offset += 1 - for subshell in range( NSS ) : - SUBI, dummy, dummy, dummy, dummy, NTR = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MF28[offset], intIndices = [0, 5], logFile = info.logs) + for subshell in range(NSS): + SUBI, dummy, dummy, dummy, dummy, NTR = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MF28[offset], intIndices=[0, 5], logFile=info.logs) offset += 1 - EBI, ELN, dummy, dummy, dummy, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MF28[offset], intIndices = [ ], logFile = info.logs) + EBI, ELN, dummy, dummy, dummy, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MF28[offset], intIndices=[], logFile=info.logs) offset += 1 - configuration = configurationModule.Configuration( MT_AtomicConfigurations[534+SUBI-1], ELN ) - atomicData.configurations.add( configuration ) - configuration.bindingEnergy.add( bindingEnergyModule.Double( 'eval', EBI, 'eV' ) ) + configuration = configurationModule.Configuration(MT_AtomicConfigurations[534 + SUBI - 1], ELN) + atomicData.configurations.add(configuration) + configuration.bindingEnergy.add(bindingEnergyModule.Double('eval', EBI, 'eV')) decayData = configuration.decayData probabilitySum = 0. - info.logs.write( ' : %s' % MT_AtomicConfigurations[534+SUBI-1] ) - for i1 in range( NTR ) : - SUBJ, SUBK, ETR, FTF, dummy, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats(MF28[offset], intIndices = [0, 1], logFile = info.logs) + info.logs.write(' : %s' % MT_AtomicConfigurations[534 + SUBI - 1]) + for i1 in range(NTR): + SUBJ, SUBK, ETR, FTF, dummy, dummy = endfFileToGNDSMisc.sixFunkyFloatStringsToIntsAndFloats( + MF28[offset], intIndices=[0, 1], logFile=info.logs) offset += 1 - decayMode = decayDataModule.DecayMode( str( i1 ), 'atomicRelaxation' ) - decayMode.probability.add( probabilityModule.Double( "BR", FTF, '' ) ) - decay = decayDataModule.Decay( str( 0 ), decayDataModule.decayModesParticle ) - - if( SUBK == 0 ) : - decay.products.add( productModule.Product( IDsPoPsModule.photon, IDsPoPsModule.photon ) ) - elementID = '%s{%s}' % ( elementSymbol, MT_AtomicConfigurations[534+SUBJ-1] ) - else : - decay.products.add( productModule.Product( IDsPoPsModule.electron, IDsPoPsModule.electron ) ) - elementID = '%s{%s,%s}' % ( elementSymbol, MT_AtomicConfigurations[534+SUBJ-1], MT_AtomicConfigurations[534+SUBK-1] ) - decay.products.add( productModule.Product( elementID, elementID ) ) + decayMode = decayDataModule.DecayMode(str(i1), 'atomicRelaxation') + decayMode.probability.add(probabilityModule.Double("BR", FTF, '')) + decay = decayDataModule.Decay(str(0), decayDataModule.decayModesParticle) + + if SUBK == 0: + decay.products.add(productModule.Product(IDsPoPsModule.photon, IDsPoPsModule.photon)) + elementID = '%s{%s}' % (elementSymbol, MT_AtomicConfigurations[534 + SUBJ - 1]) + else: + decay.products.add(productModule.Product(IDsPoPsModule.electron, IDsPoPsModule.electron)) + elementID = '%s{%s,%s}' % ( + elementSymbol, MT_AtomicConfigurations[534 + SUBJ - 1], MT_AtomicConfigurations[534 + SUBK - 1]) + decay.products.add(productModule.Product(elementID, elementID)) probabilitySum += FTF - decayMode.decayPath.add( decay ) - decayData.decayModes.add( decayMode ) - if( NTR > 0 ) : - if( abs( 1 - probabilitySum ) > 1e-4 ) : warningList.append( 'decay probabilities sum to %.6f not 1.' % probabilitySum ) - - if( offset != len( MF28 ) ) : raise Exception( 'Not allow lines of MF 28 data processed: offset = %d, len( MF28 ) = %d' % ( offset, len( MF28 ) ) ) - info.logs.write( '\n' ) - for warning in warningList : info.logs.write( " WARNING: %s\n" % warning, stderrWriting = True ) - - return( { 'PoPs' : PoPs, 'errors' : errors } ) + decayMode.decayPath.add(decay) + decayData.decayModes.add(decayMode) + if NTR > 0: + if abs(1 - probabilitySum) > 1e-4: + warningList.append('decay probabilities sum to %.6f not 1.' % probabilitySum) + + if offset != len(MF28): + raise Exception('Not allow lines of MF 28 data processed: offset = %d, len( MF28 ) = %d' % (offset, len(MF28))) + info.logs.write('\n') + for warning in warningList: info.logs.write(" WARNING: %s\n" % warning, stderrWriting=True) + + return {'PoPs': PoPs, 'errors': errors} diff --git a/brownies/legacy/converting/ENDFToGNDS/metaStableData.py b/brownies/legacy/converting/ENDFToGNDS/metaStableData.py index dca06d4e..d1b8242e 100644 --- a/brownies/legacy/converting/ENDFToGNDS/metaStableData.py +++ b/brownies/legacy/converting/ENDFToGNDS/metaStableData.py @@ -10,7 +10,7 @@ Data for some meta-stables are bogus as values could were not in ENSDF. """ -# Meta-stable energies in eV. Data as ( levelIndex, levelEnergy ) +# Meta-stable energies in eV. Data stored as (levelIndex, levelEnergy) unknownMetaStableEnergy = 100.0 metaStableData = { "Ag94_m1": (1, 344200.), @@ -72,12 +72,12 @@ "In130_m1": (1, 50000.), "In131_m1": (1, 302000.), "In133_m1": (1, 330000.), - "Rh91_m1": ( 1, 172900. ), - "Rh92_m1": ( 1, 100. ), - "Rh94_m1": ( 1, 100. ), - "Rh95_m1": ( 1, 543300. ), - "Rh96_m1": ( 1, 51980. ), - "Rh97_m1": ( 1, 258760. ), + "Rh91_m1": (1, 172900.), + "Rh92_m1": (1, 100.), + "Rh94_m1": (1, 100.), + "Rh95_m1": (1, 543300.), + "Rh96_m1": (1, 51980.), + "Rh97_m1": (1, 258760.), "Rh98_m1": (2, 56300.), "Rh99_m1": (1, 64400.), "Rh100_m1": (4, 107590.), @@ -157,13 +157,13 @@ "La136_m1": (9, 259500.), "La146_m1": (1, unknownMetaStableEnergy), "Ta156_m1": (1, 100000.), - "Ta159_m1": ( 1, 64000. ), - "Ta160_m1": ( 1, unknownMetaStableEnergy ), - "Ta161_m1": ( 3, 110300. ), - "Ta178_m1": ( 1, 1467820. ), - "Ta182_m2": ( 29, 519577. ), - "Ta182_m1": ( 1, 16273. ), - "Ta180_m1": ( 2, 77200. ), + "Ta159_m1": (1, 64000.), + "Ta160_m1": (1, unknownMetaStableEnergy), + "Ta161_m1": (3, 110300.), + "Ta178_m1": (1, 1467820.), + "Ta182_m2": (29, 519577.), + "Ta182_m1": (1, 16273.), + "Ta180_m1": (2, 77200.), "Ce127_m1": (1, 7300.), "Ce131_m1": (1, 63090.), "Ce133_m1": (1, unknownMetaStableEnergy), @@ -202,8 +202,8 @@ "Pm138_m1": (1, unknownMetaStableEnergy), "Pm139_m1": (1, 188700.), "Pm140_m1": (1, unknownMetaStableEnergy), - "Pm148_m1": ( 3, 137900. ), - "Pm154_m1": ( 1, unknownMetaStableEnergy ), + "Pm148_m1": (3, 137900.), + "Pm154_m1": (1, unknownMetaStableEnergy), "Gd139_m1": (1, unknownMetaStableEnergy), "Gd141_m1": (4, 377760.), "Gd143_m1": (1, 152600.), @@ -216,10 +216,10 @@ "Eu140_m1": (1, unknownMetaStableEnergy), "Eu141_m1": (1, 96450), "Eu142_m1": (1, unknownMetaStableEnergy), - "Eu150_m1": ( 1, 41700. ), - "Eu152_m1": ( 1, unknownMetaStableEnergy ), - "Eu152_m2": ( 2, 2 * unknownMetaStableEnergy ), - "Eu154_m1": ( 1, unknownMetaStableEnergy ), + "Eu150_m1": (1, 41700.), + "Eu152_m1": (1, unknownMetaStableEnergy), + "Eu152_m2": (2, 2 * unknownMetaStableEnergy), + "Eu154_m1": (1, unknownMetaStableEnergy), "Tb141_m1": (1, unknownMetaStableEnergy), "Tb142_m1": (3, 279700.), "Tb143_m1": (1, unknownMetaStableEnergy), @@ -227,333 +227,336 @@ "Tb146_m1": (1, unknownMetaStableEnergy), "Tb147_m1": (1, 50600.), "Tb148_m1": (1, 90100.), - "Tb149_m1": ( 1, 35780. ), - "Tb150_m1": ( 2, 461000. ), - "Tb151_m1": ( 3, 99530. ), - "Tb152_m1": ( 6, 501740. ), - "Tb154_m1": ( 1, unknownMetaStableEnergy ), - "Tb156_m1": ( 2, 49630. ), - "Tb156_m2": ( 4, 88400 ), - "Tb158_m1": ( 3, 110300. ), + "Tb149_m1": (1, 35780.), + "Tb150_m1": (2, 461000.), + "Tb151_m1": (3, 99530.), + "Tb152_m1": (6, 501740.), + "Tb154_m1": (1, unknownMetaStableEnergy), + "Tb156_m1": (2, 49630.), + "Tb156_m2": (4, 88400), + "Tb158_m1": (3, 110300.), "Dy143_m1": (3, 310700.), "Dy146_m1": (11, 2934500.), "Dy147_m1": (2, 750500.), - "Dy165_m1": ( 2, 108155.2 ), + "Dy165_m1": (2, 108155.2), "Ho148_m1": (1, unknownMetaStableEnergy), "Ho149_m1": (1, 48800.), "Ho150_m1": (1, unknownMetaStableEnergy), - "Ho151_m1": ( 3, 41000. ), - "Ho152_m1": ( 3, 160000. ), - "Ho153_m1": ( 1, 68700. ), - "Ho154_m1": ( 1, unknownMetaStableEnergy ), - "Ho156_m1": ( 1, 52370. ), - "Ho158_m1": ( 1, 67200. ), - "Ho158_m2": ( 9, 180000. ), - "Ho159_m1": ( 3, 205910 ), - "Ho160_m2": ( 6, 169560. ), - "Ho160_m1": ( 1, 59980. ), - "Ho161_m1": ( 2, 211150. ), - "Ho162_m1": ( 3, 105870. ), - "Ho163_m1": ( 3, 297880. ), - "Ho164_m1": ( 3, 139780. ), - "Ho166_m1": ( 1, 5969 ), - "Ho168_m1": ( 1, 59000 ), - "Ho170_m1": ( 1, 120000 ), + "Ho151_m1": (3, 41000.), + "Ho152_m1": (3, 160000.), + "Ho153_m1": (1, 68700.), + "Ho154_m1": (1, unknownMetaStableEnergy), + "Ho156_m1": (1, 52370.), + "Ho158_m1": (1, 67200.), + "Ho158_m2": (9, 180000.), + "Ho159_m1": (3, 205910), + "Ho160_m2": (6, 169560.), + "Ho160_m1": (1, 59980.), + "Ho161_m1": (2, 211150.), + "Ho162_m1": (3, 105870.), + "Ho163_m1": (3, 297880.), + "Ho164_m1": (3, 139780.), + "Ho166_m1": (1, 5969), + "Ho168_m1": (1, 59000), + "Ho170_m1": (1, 120000), "Tm151_m1": (1, unknownMetaStableEnergy), "Tm152_m1": (1, unknownMetaStableEnergy), - "Tm153_m1": ( 1, 43000. ), - "Tm154_m1": ( 3, unknownMetaStableEnergy ), - "Tm155_m1": ( 1, 41000. ), - "Tm158_m1": ( 1, unknownMetaStableEnergy ), - "Tm160_m1": ( 2, 80000. ), - "Tm162_m1": ( 1, unknownMetaStableEnergy ), - "Tm164_m1": ( 1, unknownMetaStableEnergy ), - "Tm166_m1": ( 6, 109338. ), + "Tm153_m1": (1, 43000.), + "Tm154_m1": (3, unknownMetaStableEnergy), + "Tm155_m1": (1, 41000.), + "Tm158_m1": (1, unknownMetaStableEnergy), + "Tm160_m1": (2, 80000.), + "Tm162_m1": (1, unknownMetaStableEnergy), + "Tm164_m1": (1, unknownMetaStableEnergy), + "Tm166_m1": (6, 109338.), "Yb151_m1": (1, unknownMetaStableEnergy), - "Yb169_m1": ( 1, 24199.9 ), - "Yb177_m1": ( 6, 331500. ), - "Yb176_m1": ( 5, 1049800. ), + "Yb169_m1": (1, 24199.9), + "Yb177_m1": (6, 331500.), + "Yb176_m1": (5, 1049800.), "Lu154_m1": (1, unknownMetaStableEnergy), - "Lu155_m1": ( 3, 20000. ), - "Lu156_m1": ( 1, unknownMetaStableEnergy ), - "Lu157_m1": ( 1, 20900. ), - "Lu160_m1": ( 1, unknownMetaStableEnergy ), - "Lu166_m2": ( 2, 43000. ), - "Lu166_m1": ( 1, 34370. ), - "Lu167_m1": ( 1, unknownMetaStableEnergy ), - "Lu168_m1": ( 6, 109338. ), - "Lu169_m1": ( 1, 29000. ), - "Lu170_m1": ( 8, 92910. ), - "Lu171_m1": ( 2, 71130. ), - "Lu172_m1": ( 1, 41860. ), - "Lu174_m1": ( 4, 170830. ), - "Lu178_m1": ( 3, 123800. ), - "Lu177_m1": ( 29, 970175.7 ), - "Lu176_m1": ( 1, 122845. ), - "Er167_m1": ( 3, 207801. ), - "Hf171_m1": ( 2, 21930. ), - "Hf178_m1": ( 5, 1147416. ), - "Hf180_m1": ( 6, 1141552. ), - "Hf179_m1": ( 5, 375035.2 ), - "Hf182_m1": ( 9, 1172870. ), - "Fr202_m1": ( 1, unknownMetaStableEnergy ), - "Fr204_m1": ( 1, 41000. ), - "Fr206_m1": ( 1, unknownMetaStableEnergy ), - "Rn201_m1": ( 1, unknownMetaStableEnergy ), - "Rn199_m1": ( 1, 180000. ), - "Rn203_m1": ( 1, 362000. ), - "At194_m1": ( 1, unknownMetaStableEnergy ), - "At195_m1": ( 1, 33000. ), - "At197_m1": ( 1, 52000. ), - "At198_m1": ( 1, 102000. ), - "At200_m1": ( 1, 112000. ), - "At202_m1": ( 1, unknownMetaStableEnergy ), - "At204_m1": ( 1, 587300. ), - "At212_m1": ( 2, 222900. ), - "Po193_m1": ( 1, 100. ), - "Po199_m1": ( 2, 310000. ), - "Po201_m1": ( 3, 424100. ), - "Po203_m1": ( 5, 641640. ), - "Po207_m1": ( 14, 1383160. ), - "Po211_m1": ( 15, 1462000. ), - "Ra205_m1": ( 1, 263000. ), - "Fm250_m1": ( 1, unknownMetaStableEnergy ), - "Fm247_m1": ( 1, 45000. ), - "Es256_m1": ( 1, 100. ), - "Es250_m1": ( 1, 100. ), - "Bk248_m1": ( 1, 100. ), - "Am246_m1": ( 1, 100. ), - "Am244_m1": ( 1, 89500. ), - "Am242_m1": ( 2, 48600. ), - "Am236_m1": ( 1, 100. ), - "Pu237_m1": ( 3, 145543. ), - "Np242_m1": ( 1, 100.0 ), - "Np240_m1": ( 1, 100.0 ), - "Np236_m1": ( 1, 57.0 ), - "U235_m1": ( 1, 76.0 ), - "Ru93_m1": ( 1, 734400. ), - "As82_m1": ( 1, 131600. ), - "Ge73_m1": ( 2, 66725. ), - "Ge75_m1": ( 2, 139690. ), - "Ge77_m1": ( 2, 159710. ), - "Ge79_m1": ( 1, 185950. ), - "Ge81_m1": ( 1, 679140. ), - "Zn61_m1": ( 1, 88550. ), # There does not seem to be a reasonable meta-stable in the ENSDF data so I am take the first one. - "Zn61_m2": ( 2, 123840. ), # There does not seem to be a reasonable meta-stable in the ENSDF data so I am take the second one. - "Zn61_m3": ( 3, 418800. ), # What is going on with JENDL-5? - "Zn69_m1": ( 1, 438636. ), - "Zn71_m1": ( 1, 157700. ), - "Zn77_m1": ( 2, 772440. ), - "Cu68_m1": ( 3, 721260. ), - "Cu70_m1": ( 1, 101000. ), - "Cu76_m1": ( 1, 100. ), - "Co54_m1": ( 1, 197100. ), - "Co58_m1": ( 1, 24950. ), - "Co60_m1": ( 1, 58590. ), - "Co62_m1": ( 1, 22000. ), - "Co68_m1": ( 1, 100. ), - "Co70_m1": ( 1, 100. ), - "V44_m1": ( 1, 100. ), - "V60_m1": ( 1, 100. ), - "Fe53_m1": ( 22, 3040000. ), - "Ti48_m1": ( 1, 983531. ), # There does not seem to be a reasonable meta-stable in the ENSDF data so I am take the first one. - "K38_m1": ( 1, 130220. ), - "Al24_m1": ( 1, 425800. ), - "Al26_m1" : ( 1, 228305. ), - "Cl34_m1" : ( 1, 146360. ), - "Cl38_m1": ( 1, 671365. ), - "W179_m1" : ( 2, 221926. ), - "W183_m1" : ( 7, 309493. ), - "W185_m1" : ( 6, 197383. ), - "Re163_m1": ( 1, 115000. ), - "Re165_m1": ( 1, 48000. ), - "Re169_m1": ( 1, unknownMetaStableEnergy ), - "Re172_m1": ( 1, unknownMetaStableEnergy ), - "Re182_m1" : ( 1, 1000. ), - "Re184_m1" : ( 5, 188010. ), - "Re186_m1" : ( 4, 149000. ), - "Re188_m1" : ( 7, 172069. ), - "Re190_m1" : ( 3, 210000. ), - "Os181_m1" : ( 1, 49200. ), - "Os183_m1" : ( 2, 170710. ), - "Os189_m1" : ( 1, 30812. ), - "Os190_m1": ( 32, 1705700. ), - "Os191_m1" : ( 1, 74382. ), - "Ir168_m1": ( 1, unknownMetaStableEnergy ), - "Ir169_m1": ( 1, 153000. ), - "Ir170_m1": ( 1, unknownMetaStableEnergy ), - "Ir171_m1": ( 1, unknownMetaStableEnergy ), - "Ir173_m1": ( 3, 226000. ), - "Ir174_m1": ( 1, 193000. ), - "Ir186_m1" : ( 1, 1000. ), - "Ir190_m1" : ( 2, 26100. ), - "Ir190_m2" : ( 37, 376400. ), - "Ir191_m1" : ( 3, 171240. ), - "Ir192_m1" : ( 3, 56720. ), - "Ir192_m2" : ( 16, 168140. ), - "Ir193_m1" : ( 2, 80239. ), - "Ir194_m1" : ( 7, 147072. ), - "Ir195_m1" : ( 2, 1e5 ), - "Ir196_m1" : ( 4, 410000. ), - "Ir197_m1" : ( 2, 115000. ), - "Pt183_m1" : ( 1, 34500. ), - "Pt185_m1" : ( 2, 103410. ), - "Pt193_m1" : ( 5, 149780. ), - "Pt195_m1" : ( 7, 259300. ), - "Pt197_m1" : ( 9, 399590. ), - "Pt199_m1" : ( 8, 424000. ), - "Au175_m1": ( 1, unknownMetaStableEnergy ), - "Au176_m1": ( 1, unknownMetaStableEnergy ), - "Au177_m1": ( 2, 182700. ), - "Au184_m1": ( 3, 68460. ), - "Au185_m1" : ( 1, 1000. ), - "Au187_m1" : ( 2, 120510. ), - "Au189_m1" : ( 3, 247230. ), - "Au190_m1": ( 1, unknownMetaStableEnergy ), - "Au191_m1": ( 4, 266200. ), - "Au192_m1": ( 4, 135410. ), - "Au194_m1": ( 3, 107400. ), - "Au194_m2": ( 8, 475700. ), - "Au193_m1" : ( 4, 290190. ), - "Au195_m1" : ( 4, 318580. ), - "Au196_m1" : ( 3, 84656. ), - "Au197_m1" : ( 4, 409150. ), - "Au200_m1" : ( 11, 962000. ), - "Hg185_m1" : ( 4, 99300. ), - "Hg187_m1" : ( 1, 1000. ), - "Hg189_m1" : ( 2, 1000. ), - "Hg191_m1" : ( 1, 1000. ), - "Hg193_m1" : ( 3, 140760. ), - "Hg195_m1" : ( 3, 176070. ), - "Hg197_m1" : ( 4, 298930. ), - "Hg199_m1" : ( 7, 532480. ), - "Tl185_m1": ( 3, 454800. ), - "Tl186_m1" : ( 1, 1000. ), - "Tl187_m1" : ( 2, 335009. ), - "Tl188_m1" : ( 1, 1000. ), - "Tl189_m1" : ( 1, 257600. ), - "Tl190_m1" : ( 1, 1000. ), - "Tl191_m1" : ( 1, 1000. ), - "Tl192_m1" : ( 1, 156000. ), - "Tl193_m1" : ( 1, 1000. ), - "Tl194_m1" : ( 1, 1000. ), - "Tl195_m1" : ( 2, 482630. ), - "Tl196_m1" : ( 6, 394200. ), - "Tl197_m1": ( 2, 608220. ), - "Tl198_m1" : ( 7, 543500. ), - "Tl207_m1": ( 1, 1348180. ), - "Pb183_m1": ( 1, 97000. ), - "Pb185_m1": ( 1, unknownMetaStableEnergy ), - "Pb187_m1" : ( 1, 81000. ), - "Pb189_m1": ( 1, 40000. ), - "Pb191_m1" : ( 1, 138000. ), - "Pb193_m1" : ( 1, 1000. ), - "Pb195_m1" : ( 2, 202900. ), - "Pb197_m1" : ( 2, 319310. ), - "Pb199_m1" : ( 1, 1000. ), - "Pb201_m1" : ( 4, 629100. ), - "Pb202_m1" : ( 13, 2169830. ), - "Pb203_m1" : ( 6, 825200. ), - "Pb204_m1": ( 21, 2185880. ), - "Pb207_m1": ( 3, 1633356. ), - "Sc42_m1" : ( 2, 616300. ), - "Sc44_m1" : ( 1, 271240. ), - "Sc45_m1": ( 1, 12400. ), - "Sc46_m1" : ( 1, 142528. ), - "Sc50_m1": ( 1, 256895. ), - "Mn50_m1" : ( 1, 225280. ), - "Mn52_m1" : ( 1, 377749. ), - "Mn58_m1": ( 1, 71770. ), - "Mn60_m1": ( 1, 271800. ), - "Se73_m1" : ( 1, 25710. ), - "Se77_m1" : ( 1, 161922.3 ), - "Se79_m1" : ( 1, 95770. ), - "Se81_m1" : ( 1, 103000. ), - "Se83_m1": ( 1, 228920. ), - "Br70_m1": ( 6, 2292300. ), - "Br72_m1": ( 1, 100760. ), - "Br74_m1" : ( 1, 13580. ), - "Br76_m1" : ( 1, 102580. ), - "Br77_m1" : ( 1, 105860. ), - "Br79_m1" : ( 1, 207610. ), - "Br80_m1" : ( 1, 85843. ), - "Br82_m1" : ( 1, 45949.2 ), - "Br84_m1" : ( 1, 320000. ), - "Kr79_m1" : ( 1, 129770. ), - "Kr81_m1" : ( 1, 190640. ), - "Kr83_m1" : ( 1, 41557.5 ), - "Kr85_m1" : ( 1, 304871. ), - "Rb78_m1": ( 3, 111190. ), - "Rb81_m1" : ( 1, 86317.1 ), - "Rb82_m1" : ( 1, 69000. ), - "Rb84_m1" : ( 1, 463591. ), - "Rb86_m1" : ( 1, 556051. ), - "Rb90_m1" : ( 1, 106901. ), - "Sr83_m1" : ( 1, 259151. ), - "Sr85_m1" : ( 1, 238791. ), - "Sr87_m1" : ( 1, 388533. ), - "Y80_m1": ( 1, 111190. ), - "Y83_m1" : ( 1, 62047.1 ), - "Y84_m1": ( 2, 67000. ), - "Y85_m1" : ( 1, 196800. ), - "Y86_m1" : ( 1, 218211. ), - "Y87_m1" : ( 1, 380821. ), - "Y89_m1" : ( 1, 908971. ), - "Y90_m1" : ( 1, 681671. ), - "Y91_m1" : ( 1, 555580. ), - "Y93_m1": ( 2, 758719. ), - "Y97_m1": ( 1, 667520. ), - "Y98_m1": ( 6, 465700. ), - "Y100_m1": ( 4, 145000. ), - "Zr85_m1" : ( 1, 292281. ), - "Zr87_m1" : ( 1, 335841. ), - "Zr89_m1" : ( 1, 587821. ), - "Zr90_m1": ( 3, 2319000. ), - "Nb86_m1": ( 2, 100. ), - "Nb87_m1": ( 1, 3900. ), - "Nb88_m1": ( 1, 100. ), - "Nb89_m1": ( 1, 35000. ), - "Nb90_m1" : ( 1, 124670. ), - "Nb91_m1" : ( 1, 104601. ), - "Nb92_m1" : ( 1, 135501. ), - "Nb93_m1" : ( 1, 30770.1 ), - "Nb94_m1": ( 1, 40892. ), - "Nb95_m1": ( 1, 235690. ), - "Nb97_m1": ( 1, 743350. ), - "Nb98_m1": ( 1, 84000. ), - "Nb99_m1": ( 1, 365270. ), - "Nb100_m1": ( 4, 314230. ), - "Nb102_m1": ( 1, 100. ), - "Mo89_m1": ( 2, 387500. ), - "Mo91_m1" : ( 1, 653011. ), - "Mo93_m1": ( 16, 2424950. ), - "Tc88_m1": ( 1, 100. ), - "Tc89_m1": ( 1, 62600. ), - "Tc90_m1" : ( 1, 100000. ), - "Tc90_m2": ( 2, 144100. ), - "Tc91_m1" : ( 1, 139300. ), - "Tc93_m1" : ( 1, 391840. ), - "Tc94_m1" : ( 1, 76000. ), - "Tc95_m1" : ( 1, 38900. ), - "Tc96_m1" : ( 1, 34230. ), - "Tc97_m1": ( 1, 96570. ), - "Tc99_m1": ( 2, 142683.6 ), - "Tc102_m1": ( 1, 100. ), - "Bi188_m1": ( 4, unknownMetaStableEnergy ), - "Bi190_m1": ( 4, 191000. ), - "Bi192_m1" : ( 1, 147000. ), - "Bi193_m1" : ( 1, 308000. ), - "Bi194_m1" : ( 1, 109000. ), - "Bi194_m2" : ( 2, 200000. ), - "Bi195_m1" : ( 1, 401000. ), - "Bi196_m1" : ( 1, 271000. ), - "Bi197_m1" : ( 1, 500000. ), - "Bi198_m1" : ( 1, 100000. ), - "Bi198_m2" : ( 2, 248500. ), - "Bi199_m1" : ( 1, 667000. ), - "Bi200_m1": ( 1, 200000. ), - "Bi200_m2": ( 3, 428200. ), - "Bi201_m1" : ( 1, 846350. ), - "Bi203_m1": ( 6, 1098210. ), - "Bi210_m1": ( 2, 271310. ), - "Bi216_m1": ( 1, 100. ) } + "Lu155_m1": (3, 20000.), + "Lu156_m1": (1, unknownMetaStableEnergy), + "Lu157_m1": (1, 20900.), + "Lu160_m1": (1, unknownMetaStableEnergy), + "Lu166_m2": (2, 43000.), + "Lu166_m1": (1, 34370.), + "Lu167_m1": (1, unknownMetaStableEnergy), + "Lu168_m1": (6, 109338.), + "Lu169_m1": (1, 29000.), + "Lu170_m1": (8, 92910.), + "Lu171_m1": (2, 71130.), + "Lu172_m1": (1, 41860.), + "Lu174_m1": (4, 170830.), + "Lu178_m1": (3, 123800.), + "Lu177_m1": (29, 970175.7), + "Lu176_m1": (1, 122845.), + "Er167_m1": (3, 207801.), + "Hf171_m1": (2, 21930.), + "Hf178_m1": (5, 1147416.), + "Hf180_m1": (6, 1141552.), + "Hf179_m1": (5, 375035.2), + "Hf182_m1": (9, 1172870.), + "Fr202_m1": (1, unknownMetaStableEnergy), + "Fr204_m1": (1, 41000.), + "Fr206_m1": (1, unknownMetaStableEnergy), + "Rn201_m1": (1, unknownMetaStableEnergy), + "Rn199_m1": (1, 180000.), + "Rn203_m1": (1, 362000.), + "At194_m1": (1, unknownMetaStableEnergy), + "At195_m1": (1, 33000.), + "At197_m1": (1, 52000.), + "At198_m1": (1, 102000.), + "At200_m1": (1, 112000.), + "At202_m1": (1, unknownMetaStableEnergy), + "At204_m1": (1, 587300.), + "At212_m1": (2, 222900.), + "Po193_m1": (1, 100.), + "Po199_m1": (2, 310000.), + "Po201_m1": (3, 424100.), + "Po203_m1": (5, 641640.), + "Po207_m1": (14, 1383160.), + "Po211_m1": (15, 1462000.), + "Ra205_m1": (1, 263000.), + "Fm250_m1": (1, unknownMetaStableEnergy), + "Fm247_m1": (1, 45000.), + "Es256_m1": (1, 100.), + "Es250_m1": (1, 100.), + "Bk248_m1": (1, 100.), + "Am246_m1": (1, 100.), + "Am244_m1": (1, 89500.), + "Am242_m1": (2, 48600.), + "Am236_m1": (1, 100.), + "Pu237_m1": (3, 145543.), + "Np242_m1": (1, 100.0), + "Np240_m1": (1, 100.0), + "Np236_m1": (1, 57.0), + "U235_m1": (1, 76.0), + "Ru93_m1": (1, 734400.), + "As82_m1": (1, 131600.), + "Ge73_m1": (2, 66725.), + "Ge75_m1": (2, 139690.), + "Ge77_m1": (2, 159710.), + "Ge79_m1": (1, 185950.), + "Ge81_m1": (1, 679140.), + "Zn61_m1": (1, 88550.), + # There does not seem to be a reasonable meta-stable in the ENSDF data, so I take the first one. + "Zn61_m2": (2, 123840.), + # There does not seem to be a reasonable meta-stable in the ENSDF data, so I take the second one. + "Zn61_m3": (3, 418800.), # What is going on with JENDL-5? + "Zn69_m1": (1, 438636.), + "Zn71_m1": (1, 157700.), + "Zn77_m1": (2, 772440.), + "Cu68_m1": (3, 721260.), + "Cu70_m1": (1, 101000.), + "Cu76_m1": (1, 100.), + "Co54_m1": (1, 197100.), + "Co58_m1": (1, 24950.), + "Co60_m1": (1, 58590.), + "Co62_m1": (1, 22000.), + "Co68_m1": (1, 100.), + "Co70_m1": (1, 100.), + "V44_m1": (1, 100.), + "V60_m1": (1, 100.), + "Fe53_m1": (22, 3040000.), + "Ti48_m1": (1, 983531.), + # There does not seem to be a reasonable meta-stable in the ENSDF data, so I take the first one. + "K38_m1": (1, 130220.), + "Al24_m1": (1, 425800.), + "Al26_m1": (1, 228305.), + "Cl34_m1": (1, 146360.), + "Cl38_m1": (1, 671365.), + "W179_m1": (2, 221926.), + "W183_m1": (7, 309493.), + "W185_m1": (6, 197383.), + "Re163_m1": (1, 115000.), + "Re165_m1": (1, 48000.), + "Re169_m1": (1, unknownMetaStableEnergy), + "Re172_m1": (1, unknownMetaStableEnergy), + "Re182_m1": (1, 1000.), + "Re184_m1": (5, 188010.), + "Re186_m1": (4, 149000.), + "Re188_m1": (7, 172069.), + "Re190_m1": (3, 210000.), + "Os181_m1": (1, 49200.), + "Os183_m1": (2, 170710.), + "Os189_m1": (1, 30812.), + "Os190_m1": (32, 1705700.), + "Os191_m1": (1, 74382.), + "Ir168_m1": (1, unknownMetaStableEnergy), + "Ir169_m1": (1, 153000.), + "Ir170_m1": (1, unknownMetaStableEnergy), + "Ir171_m1": (1, unknownMetaStableEnergy), + "Ir173_m1": (3, 226000.), + "Ir174_m1": (1, 193000.), + "Ir186_m1": (1, 1000.), + "Ir190_m1": (2, 26100.), + "Ir190_m2": (37, 376400.), + "Ir191_m1": (3, 171240.), + "Ir192_m1": (3, 56720.), + "Ir192_m2": (16, 168140.), + "Ir193_m1": (2, 80239.), + "Ir194_m1": (7, 147072.), + "Ir195_m1": (2, 1e5), + "Ir196_m1": (4, 410000.), + "Ir197_m1": (2, 115000.), + "Pt183_m1": (1, 34500.), + "Pt185_m1": (2, 103410.), + "Pt193_m1": (5, 149780.), + "Pt195_m1": (7, 259300.), + "Pt197_m1": (9, 399590.), + "Pt199_m1": (8, 424000.), + "Au175_m1": (1, unknownMetaStableEnergy), + "Au176_m1": (1, unknownMetaStableEnergy), + "Au177_m1": (2, 182700.), + "Au184_m1": (3, 68460.), + "Au185_m1": (1, 1000.), + "Au187_m1": (2, 120510.), + "Au189_m1": (3, 247230.), + "Au190_m1": (1, unknownMetaStableEnergy), + "Au191_m1": (4, 266200.), + "Au192_m1": (4, 135410.), + "Au194_m1": (3, 107400.), + "Au194_m2": (8, 475700.), + "Au193_m1": (4, 290190.), + "Au195_m1": (4, 318580.), + "Au196_m1": (3, 84656.), + "Au197_m1": (4, 409150.), + "Au200_m1": (11, 962000.), + "Hg185_m1": (4, 99300.), + "Hg187_m1": (1, 1000.), + "Hg189_m1": (2, 1000.), + "Hg191_m1": (1, 1000.), + "Hg193_m1": (3, 140760.), + "Hg195_m1": (3, 176070.), + "Hg197_m1": (4, 298930.), + "Hg199_m1": (7, 532480.), + "Tl185_m1": (3, 454800.), + "Tl186_m1": (1, 1000.), + "Tl187_m1": (2, 335009.), + "Tl188_m1": (1, 1000.), + "Tl189_m1": (1, 257600.), + "Tl190_m1": (1, 1000.), + "Tl191_m1": (1, 1000.), + "Tl192_m1": (1, 156000.), + "Tl193_m1": (1, 1000.), + "Tl194_m1": (1, 1000.), + "Tl195_m1": (2, 482630.), + "Tl196_m1": (6, 394200.), + "Tl197_m1": (2, 608220.), + "Tl198_m1": (7, 543500.), + "Tl207_m1": (1, 1348180.), + "Pb183_m1": (1, 97000.), + "Pb185_m1": (1, unknownMetaStableEnergy), + "Pb187_m1": (1, 81000.), + "Pb189_m1": (1, 40000.), + "Pb191_m1": (1, 138000.), + "Pb193_m1": (1, 1000.), + "Pb195_m1": (2, 202900.), + "Pb197_m1": (2, 319310.), + "Pb199_m1": (1, 1000.), + "Pb201_m1": (4, 629100.), + "Pb202_m1": (13, 2169830.), + "Pb203_m1": (6, 825200.), + "Pb204_m1": (21, 2185880.), + "Pb207_m1": (3, 1633356.), + "Sc42_m1": (2, 616300.), + "Sc44_m1": (1, 271240.), + "Sc45_m1": (1, 12400.), + "Sc46_m1": (1, 142528.), + "Sc50_m1": (1, 256895.), + "Mn50_m1": (1, 225280.), + "Mn52_m1": (1, 377749.), + "Mn58_m1": (1, 71770.), + "Mn60_m1": (1, 271800.), + "Se73_m1": (1, 25710.), + "Se77_m1": (1, 161922.3), + "Se79_m1": (1, 95770.), + "Se81_m1": (1, 103000.), + "Se83_m1": (1, 228920.), + "Br70_m1": (6, 2292300.), + "Br72_m1": (1, 100760.), + "Br74_m1": (1, 13580.), + "Br76_m1": (1, 102580.), + "Br77_m1": (1, 105860.), + "Br79_m1": (1, 207610.), + "Br80_m1": (1, 85843.), + "Br82_m1": (1, 45949.2), + "Br84_m1": (1, 320000.), + "Kr79_m1": (1, 129770.), + "Kr81_m1": (1, 190640.), + "Kr83_m1": (1, 41557.5), + "Kr85_m1": (1, 304871.), + "Rb78_m1": (3, 111190.), + "Rb81_m1": (1, 86317.1), + "Rb82_m1": (1, 69000.), + "Rb84_m1": (1, 463591.), + "Rb86_m1": (1, 556051.), + "Rb90_m1": (1, 106901.), + "Sr83_m1": (1, 259151.), + "Sr85_m1": (1, 238791.), + "Sr87_m1": (1, 388533.), + "Y80_m1": (1, 111190.), + "Y83_m1": (1, 62047.1), + "Y84_m1": (2, 67000.), + "Y85_m1": (1, 196800.), + "Y86_m1": (1, 218211.), + "Y87_m1": (1, 380821.), + "Y89_m1": (1, 908971.), + "Y90_m1": (1, 681671.), + "Y91_m1": (1, 555580.), + "Y93_m1": (2, 758719.), + "Y97_m1": (1, 667520.), + "Y98_m1": (6, 465700.), + "Y100_m1": (4, 145000.), + "Zr85_m1": (1, 292281.), + "Zr87_m1": (1, 335841.), + "Zr89_m1": (1, 587821.), + "Zr90_m1": (3, 2319000.), + "Nb86_m1": (2, 100.), + "Nb87_m1": (1, 3900.), + "Nb88_m1": (1, 100.), + "Nb89_m1": (1, 35000.), + "Nb90_m1": (1, 124670.), + "Nb91_m1": (1, 104601.), + "Nb92_m1": (1, 135501.), + "Nb93_m1": (1, 30770.1), + "Nb94_m1": (1, 40892.), + "Nb95_m1": (1, 235690.), + "Nb97_m1": (1, 743350.), + "Nb98_m1": (1, 84000.), + "Nb99_m1": (1, 365270.), + "Nb100_m1": (4, 314230.), + "Nb102_m1": (1, 100.), + "Mo89_m1": (2, 387500.), + "Mo91_m1": (1, 653011.), + "Mo93_m1": (16, 2424950.), + "Tc88_m1": (1, 100.), + "Tc89_m1": (1, 62600.), + "Tc90_m1": (1, 100000.), + "Tc90_m2": (2, 144100.), + "Tc91_m1": (1, 139300.), + "Tc93_m1": (1, 391840.), + "Tc94_m1": (1, 76000.), + "Tc95_m1": (1, 38900.), + "Tc96_m1": (1, 34230.), + "Tc97_m1": (1, 96570.), + "Tc99_m1": (2, 142683.6), + "Tc102_m1": (1, 100.), + "Bi188_m1": (4, unknownMetaStableEnergy), + "Bi190_m1": (4, 191000.), + "Bi192_m1": (1, 147000.), + "Bi193_m1": (1, 308000.), + "Bi194_m1": (1, 109000.), + "Bi194_m2": (2, 200000.), + "Bi195_m1": (1, 401000.), + "Bi196_m1": (1, 271000.), + "Bi197_m1": (1, 500000.), + "Bi198_m1": (1, 100000.), + "Bi198_m2": (2, 248500.), + "Bi199_m1": (1, 667000.), + "Bi200_m1": (1, 200000.), + "Bi200_m2": (3, 428200.), + "Bi201_m1": (1, 846350.), + "Bi203_m1": (6, 1098210.), + "Bi210_m1": (2, 271310.), + "Bi216_m1": (1, 100.)} diff --git a/brownies/legacy/converting/endfFileToGNDS.py b/brownies/legacy/converting/endfFileToGNDS.py index 7f4ff9e4..7eb4fb00 100644 --- a/brownies/legacy/converting/endfFileToGNDS.py +++ b/brownies/legacy/converting/endfFileToGNDS.py @@ -40,38 +40,39 @@ from brownies.legacy.toENDF6 import ENDFconversionFlags as ENDFconversionFlagsModule -class LogFiles : - def __init__( self, toStdOut = False, toStdErr = False, logFile = None, defaultIsStderrWriting = True ) : +class LogFiles: - def addIfDifferent( newOutput ) : + def __init__(self, toStdOut=False, toStdErr=False, logFile=None, defaultIsStderrWriting=True): - if( newOutput.isatty( ) ) : - for output in self.outputs : - if( output.isatty( ) ) : return( False ) - return( True ) + def addIfDifferent(newOutput): + + if newOutput.isatty(): + for output in self.outputs: + if output.isatty(): return False + return True self.defaultIsStderrWriting = defaultIsStderrWriting self.outputs = [] - if( toStdOut ) : self.outputs.append( sys.stdout ) - if( toStdErr and addIfDifferent( sys.stderr ) ) : self.outputs.append( sys.stderr ) - if( logFile ) : - if( type( logFile ) == type( '' ) ) : - logFile = open( logFile, 'w' ) - elif( type( logFile ) != type( sys.stdout ) ) : - raise Exception( 'logFile type = %s is no supported' % ( type( logFile ) ) ) - if( addIfDifferent( logFile ) ) : self.outputs.append( logFile ) - - def write( self, msg, stderrWriting = None ) : + if toStdOut: self.outputs.append(sys.stdout) + if toStdErr and addIfDifferent(sys.stderr): self.outputs.append(sys.stderr) + if logFile: + if isinstance(logFile, str): + logFile = open(logFile, 'w') + elif type(logFile) != type(sys.stdout): + raise Exception('logFile type = %s is no supported' % (type(logFile))) + if addIfDifferent(logFile): self.outputs.append(logFile) - if( stderrWriting is None ) : stderrWriting = self.defaultIsStderrWriting - for output in self.outputs : - if( ( output == sys.stderr ) and ( not( stderrWriting ) ) ) : continue - output.write( msg ) + def write(self, msg, stderrWriting=None): + if stderrWriting is None: stderrWriting = self.defaultIsStderrWriting + for output in self.outputs: + if (output == sys.stderr) and not stderrWriting: continue + output.write(msg) -def readMF1MT451(_MAT, _MTDatas, formatVersion, specialNuclearParticleID, styleName='eval', logFile=None, verboseWarnings=False, **kwargs): +def readMF1MT451(_MAT, _MTDatas, formatVersion, specialNuclearParticleID, styleName='eval', logFile=None, + verboseWarnings=False, **kwargs): # We're going to save everything in the info instance info = toGNDSMisc.Infos(formatVersion, styleName) info.doRaise = [] @@ -84,24 +85,25 @@ def readMF1MT451(_MAT, _MTDatas, formatVersion, specialNuclearParticleID, styleN targetZA, targetMass, LRP, LFI, NLIB, NMOD = \ endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(_MTDatas[451][1][0], logFile=logFile) targetZA = int(targetZA) # Target's ZA - LRP = int(LRP) # Resonance parameter data info - LFI = int(LFI) # Is fission present - NLIB = int(NLIB) # What library (e.g., 0 = ENDF/B - NMOD = int(NMOD) # Version modification flag + LRP = int(LRP) # Resonance parameter data info + LFI = int(LFI) # Is fission present + NLIB = int(NLIB) # What library (e.g., 0 = ENDF/B + NMOD = int(NMOD) # Version modification flag isNaturalTarget = (targetZA % 1000) == 0 # Line #2 targetExcitationEnergy, STA, LIS, LISO, dummy, NFOR = \ endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(_MTDatas[451][1][1], logFile=logFile) - STA = int(STA) # Is nucleus unstable - LIS = int(LIS) # Excitation number - LISO = int(LISO) # Isomeric state number - if( ( targetExcitationEnergy != 0 ) or ( LIS != 0 ) or ( LISO != 0 ) ) : - if( ( targetExcitationEnergy == 0 ) or ( LIS == 0 ) or ( LISO == 0 ) ) : - print( " WARNING: target excitation energy = %s, LIS = %s and LISO = %s are not consistent." % ( targetExcitationEnergy, LIS, LISO ) ) - NFOR = int(NFOR) # Must be 6 for ENDF-6 format - if (NFOR != 6): - print (" WARNING: endfFileToGNDS only supports ENDF-6 format. This file has unsupported NFOR=%d" % NFOR) + STA = int(STA) # Is nucleus unstable + LIS = int(LIS) # Excitation number + LISO = int(LISO) # Isomeric state number + if (targetExcitationEnergy != 0) or (LIS != 0) or (LISO != 0): + if (targetExcitationEnergy == 0) or (LIS == 0) or (LISO == 0): + print(" WARNING: target excitation energy = %s, LIS = %s and LISO = %s are not consistent." % ( + targetExcitationEnergy, LIS, LISO)) + NFOR = int(NFOR) # Must be 6 for ENDF-6 format + if NFOR != 6: + print(" WARNING: endfFileToGNDS only supports ENDF-6 format. This file has unsupported NFOR=%d" % NFOR) info.ZA_massLineInfo.targetZA = targetZA info.ZA_massLineInfo.targetLIS = LIS @@ -112,19 +114,21 @@ def readMF1MT451(_MAT, _MTDatas, formatVersion, specialNuclearParticleID, styleN NSUB = int(NSUB) # 10 * ZA + iType for projectile NVER = int(NVER) # Evaluation version number LREL = int(LREL) # Evaluation sub-version number - IPART, ITYPE = divmod( NSUB, 10 ) + IPART, ITYPE = divmod(NSUB, 10) projectileZA = IPART - if (projectileZA == 11): projectileZA = 9 + if projectileZA == 11: projectileZA = 9 info.ZA_massLineInfo.add(projectileZA, projectileMass, 451, 1, 2) # Line #4 targetTemperature, dummy, LDRZ, dummy, NWD, NXC = \ endfFileToGNDSMisc.sixFunkyFloatStringsToFloats(_MTDatas[451][1][3], logFile=logFile) LDRZ = int(LDRZ) # Primary or special evaluation of this material - NWD = int(NWD) # - NXC = int(NXC) # + NWD = int(NWD) # + NXC = int(NXC) # + + info.convertJENDL_stylePrimarygammas = kwargs.get('JENDL_stylePrimarygammas', NLIB == 6) + # If True, treats MF=6 primary gamma energies as binding energy, otherwise as gamma energy. - info.convertJENDL_stylePrimarygammas = kwargs.get('JENDL_stylePrimarygammas', NLIB == 6) # If True, treats MF=6 primary gamma energies as binding energy, otherwise as gamma energy. # Save the library name and version info.library = endf_endlModule.NLIBs.get(NLIB, 'Unknown') info.evaluation = info.library # why do I need this? @@ -141,28 +145,28 @@ def readMF1MT451(_MAT, _MTDatas, formatVersion, specialNuclearParticleID, styleN # Save general information info.author = _MTDatas[451][1][4][33:66] - info.documentation = '\n'.join( _MTDatas[451][1][4:4+NWD] ) - info.MAT = _MAT + info.documentation = '\n'.join(_MTDatas[451][1][4:4 + NWD]) + info.MAT = _MAT info.LISO = LISO - info.LIS = LIS + info.LIS = LIS info.EMAX = EMAX info.levelIndex = LIS info.NSUB = NSUB - info.LFI = LFI - info.STA = STA + info.LFI = LFI + info.STA = STA info.targetTemperature = targetTemperature info.materialName = _MTDatas[451][1][4][:11].strip() info.targetMass = targetMass info.isNaturalTarget = isNaturalTarget - info.LRP = LRP + info.LRP = LRP info.NLIB = NLIB info.NMOD = NMOD info.NVER = NVER info.LREL = LREL - info.NXC = NXC - info.NWD = NWD + info.NXC = NXC + info.NWD = NWD info.LDRZ = LDRZ - info.ITYPE= ITYPE + info.ITYPE = ITYPE # All evaluations need a particle database and we fill in a lot of that information from MF1MT451 info.PoPsLabel = styleName @@ -175,33 +179,34 @@ def readMF1MT451(_MAT, _MTDatas, formatVersion, specialNuclearParticleID, styleN info.addMassAWR(info.targetZA, targetMass) # If there is a projectile, tell info about it too - if ITYPE in [4,5]: - info.projectile=None - info.projectileZA=None + if ITYPE in [4, 5]: + info.projectile = None + info.projectileZA = None else: - name = {0: 'g', 1: IDsPoPsModule.neutron, 11: 'e-', 1001: 'H1', 1002: 'H2', 1003: 'H3', 2003: 'He3', 2004: 'He4'}[IPART] + name = {0: 'g', 1: IDsPoPsModule.neutron, 11: 'e-', + 1001: 'H1', 1002: 'H2', 1003: 'H3', 2003: 'He3', 2004: 'He4'}[IPART] info.projectile = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(name, specialNuclearParticleID) info.projectileZA = projectileZA info.addMassAWR(projectileZA, projectileMass, asTarget=False) return info -def printMassHistoryAndReturn(printMassHistory, info, stuffToReturn): +def printMassHistoryAndReturn(printMassHistory, info, stuffToReturn): if printMassHistory: info.massTracker.printHistory() info.ZA_massLineInfo.printInfo() return stuffToReturn -def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation=None, - MTs2Skip=None, parseCrossSectionOnly=False, formatVersion=GNDS_formatVersionModule.default, - toStdOut=True, toStdErr=True, logFile=None, skipBadData=False, doCovariances=True, - verboseWarnings=False, verbose=1, reconstructResonances=True, - specialNuclearParticleID=specialNuclearParticleIDPoPsModule.Mode.nuclide, **kwargs): - logs = LogFiles( toStdOut = toStdOut, toStdErr = toStdErr, logFile = logFile, defaultIsStderrWriting = False ) - header, MAT, MTDatas = endfFileToGNDSMisc.parseENDFByMT_MF(fileName, logFile = logs) +def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation=None, + MTs2Skip=None, parseCrossSectionOnly=False, formatVersion=GNDS_formatVersionModule.default, + toStdOut=True, toStdErr=True, logFile=None, skipBadData=False, doCovariances=True, + verboseWarnings=False, verbose=1, reconstructResonances=True, + specialNuclearParticleID=specialNuclearParticleIDPoPsModule.Mode.nuclide, **kwargs): + logs = LogFiles(toStdOut=toStdOut, toStdErr=toStdErr, logFile=logFile, defaultIsStderrWriting=False) + header, MAT, MTDatas = endfFileToGNDSMisc.parseENDFByMT_MF(fileName, logFile=logs) styleName = 'eval' reconstructedStyleName = 'recon' @@ -209,79 +214,86 @@ def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation if MTs2Skip is None: MTs2Skip = [] # Parse the ENDF documentation section - info = readMF1MT451(MAT, MTDatas, formatVersion, specialNuclearParticleID, styleName=styleName, logFile=logs, verboseWarnings=verboseWarnings, **kwargs) + info = readMF1MT451(MAT, MTDatas, formatVersion, specialNuclearParticleID, styleName=styleName, logFile=logs, + verboseWarnings=verboseWarnings, **kwargs) info.missingRadioactiveProduct = [] info.printBadNK14 = True info.continuumSpectraFix = False info.acceptBadMF10FissionZAP = False - options = ['printBadNK14', 'continuumSpectraFix', 'ignoreBadDate', 'acceptBadMF10FissionZAP', 'JENDL_stylePrimarygammas', 'printMassHistory'] + options = ['printBadNK14', 'continuumSpectraFix', 'ignoreBadDate', 'acceptBadMF10FissionZAP', + 'JENDL_stylePrimarygammas', 'printMassHistory'] for option in kwargs: if option not in options: raise DeprecationWarning('invalid or deprecated option "%s"' % option) setattr(info, option, kwargs[option]) printMassHistory = kwargs.get('printMassHistory', False) - if info.ITYPE == 1: # NFY - return printMassHistoryAndReturn(printMassHistory, info, ENDF_ITYPE_1Module.ITYPE_1(MTDatas, info, verbose = verbose)) - elif info.ITYPE == 2: # Thermal scattering law data - return printMassHistoryAndReturn(printMassHistory, info, ENDF_ITYPE_2.ITYPE_2(fileName, MAT, MTDatas, info, evaluation, verbose = verbose)) - elif info.ITYPE == 4: # Decay data - return printMassHistoryAndReturn(printMassHistory, info, ENDF_ITYPE_4.ITYPE_4(MTDatas, info, verbose = verbose)) - elif info.ITYPE == 5: # SFY - return printMassHistoryAndReturn(printMassHistory, info, ENDF_ITYPE_5Module.ITYPE_5(MTDatas, info, verbose = verbose)) - elif info.ITYPE == 6: # Atomic relaxation data + if info.ITYPE == 1: # NFY + return printMassHistoryAndReturn(printMassHistory, info, + ENDF_ITYPE_1Module.ITYPE_1(MTDatas, info, verbose=verbose)) + elif info.ITYPE == 2: # Thermal scattering law data + return printMassHistoryAndReturn(printMassHistory, info, + ENDF_ITYPE_2.ITYPE_2(fileName, MAT, MTDatas, info, evaluation, + verbose=verbose)) + elif info.ITYPE == 4: # Decay data + return printMassHistoryAndReturn(printMassHistory, info, ENDF_ITYPE_4.ITYPE_4(MTDatas, info, verbose=verbose)) + elif info.ITYPE == 5: # SFY + return printMassHistoryAndReturn(printMassHistory, info, + ENDF_ITYPE_5Module.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 printMassHistoryAndReturn(printMassHistory, info, ENDF_ITYPE_6.ITYPE_6(info.targetZA // 1000, MTDatas, info, verbose = verbose)) + return printMassHistoryAndReturn( + printMassHistory, info, 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 = toGNDSMisc.getTypeNameGamma(info, info.targetZA, level = info.level, levelIndex = info.levelIndex) + 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 = toGNDSMisc.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 ) + if info.STA != 0: + halflife = halflifeModule.String(info.PoPsLabel, halflifeModule.UNSTABLE, halflifeModule.baseUnit) target = info.PoPs[targetID] - if( isinstance( target, nuclideModule.Particle ) ) : target = target.nucleus - if( len( target.halflife ) == 0 ) : target.halflife.add( halflife ) - elif( info.ITYPE == 3 ) : # Atomic transport data (e, x) + if isinstance(target, nuclideModule.Particle): target = target.nucleus + if len(target.halflife) == 0: target.halflife.add(halflife) + elif info.ITYPE == 3: # Atomic transport data (e, x) targetZ = info.targetZA // 1000 targetID = chemicalElementMiscModule.symbolFromZ[targetZ] targetName = chemicalElementMiscModule.nameFromZ[targetZ] - info.PoPs.add( chemicalElementModule.ChemicalElement( targetID, targetZ, targetName ) ) - else : - raise ValueError( "Unsupported ITYPE = %s" % info.ITYPE ) + info.PoPs.add(chemicalElementModule.ChemicalElement(targetID, targetZ, targetName)) + else: + raise ValueError("Unsupported ITYPE = %s" % info.ITYPE) unrecognizedMAT = False try: - ZA2, MAT2 = endf_endlModule.ZAAndMATFromParticleName( targetID ) + 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 MAT2 != info.MAT: + info.logs.write(" WARNING: ENDF MAT = %s not as expected (i.e., %s).\n" % (info.MAT, MAT2), + stderrWriting=True) unrecognizedMAT = True except KeyError: - info.logs.write( " WARNING: could not compute MAT for particle %s.\n" % targetID ) + info.logs.write(" WARNING: could not compute MAT for particle %s.\n" % targetID) unrecognizedMAT = True info.targetID = targetID info.targetAliasID = targetID # Add alias if needed for metastable target - if( info.LISO != 0 ) : + if info.LISO != 0: aliasName = PoPsAliasModule.MetaStable.metaStableNameFromNuclearLevelNameAndMetaStableIndex(targetID, info.LISO) info.PoPs.add(PoPsAliasModule.MetaStable(aliasName, targetID, info.LISO)) info.targetAliasID = aliasName # Compute the reconstructed and evaluated Styles - projectileDomain = stylesModule.ProjectileEnergyDomain( 1e-5, 2e+7, 'eV' ) # will be overwritten after parsing all reactions - evaluatedStyle = stylesModule.Evaluated(styleName, '', - physicalQuantityModule.Temperature( - PQUModule.PQU_float.surmiseSignificantDigits(info.targetTemperature), - 'K'), - projectileDomain, 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") + projectileDomain = stylesModule.ProjectileEnergyDomain( + 1e-5, 2e+7, 'eV') # will be overwritten after parsing all reactions + evaluatedStyle = stylesModule.Evaluated( + styleName, '', physicalQuantityModule.Temperature( + PQUModule.PQU_float.surmiseSignificantDigits(info.targetTemperature), 'K'), + projectileDomain, 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 evaluatedStyle.documentation.endfCompatible.body = info.documentation @@ -296,14 +308,17 @@ def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation projectile = toGNDSMisc.getTypeNameGamma(info, info.projectileZA) projectileID = projectile.id if projectile.id != IDsPoPsModule.photon: - projectileID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(projectile.id, specialNuclearParticleID) + projectileID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID( + projectile.id, specialNuclearParticleID) # Set up the reactionSuite interaction = enumsModule.Interaction.nuclear - if( info.ITYPE == 3 ) : interaction = enumsModule.Interaction.atomic - reactionSuite = reactionSuiteModule.ReactionSuite(projectileID, info.targetAliasID, evaluation, interaction=interaction, - style=info.evaluatedStyle, MAT=MAT, PoPs=info.PoPs, formatVersion=info.formatVersion) - MTDatas[451][1] = MTDatas[451][1][:4+info.NWD] + if info.ITYPE == 3: interaction = enumsModule.Interaction.atomic + reactionSuite = reactionSuiteModule.ReactionSuite(projectileID, info.targetAliasID, evaluation, + interaction=interaction, + style=info.evaluatedStyle, MAT=MAT, PoPs=info.PoPs, + formatVersion=info.formatVersion) + MTDatas[451][1] = MTDatas[451][1][:4 + info.NWD] info.reactionSuite = reactionSuite info.PoPs = reactionSuite.PoPs info.target = reactionSuite.target @@ -312,44 +327,44 @@ def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation # Set up the covarianceSuite, if needed, and do other ITYPE-specific calculations covarianceSuite = None - if( info.ITYPE in [ 0, 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 ) ) + if info.ITYPE in [0, 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 ] ) : - 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) + elif info.ITYPE in [3]: + 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) # Fix incident energy domain limits: reactionList = reactionSuite.reactions if len(reactionList) == 0: reactionList = list(reactionSuite) - if( reactionList[0].ENDF_MT == 2 ) : - nonThresholdList = [ reactionList[0] ] - else : + if reactionList[0].ENDF_MT == 2: + nonThresholdList = [reactionList[0]] + else: nonThresholdList = [] for reac in reactionList: - if hasattr(reac,'outputChannal'): + if hasattr(reac, 'outputChannel'): if reac.outputChannel.Q.getConstant() >= 0: - nonThresholdList.append( reac ) - elif hasattr(reac,'Q'): + nonThresholdList.append(reac) + elif hasattr(reac, 'Q'): print(type(reac.Q)) print(len(reac.Q)) print(type(reac.Q[0])) if reac.Q.getConstant() >= 0: - nonThresholdList.append( reac ) + nonThresholdList.append(reac) else: - pass # print warning? + pass # print warning? if len(nonThresholdList) > 0: - domainMin = max( [reac.crossSection.domainMin for reac in nonThresholdList] ) + domainMin = max([reac.crossSection.domainMin for reac in nonThresholdList]) else: - domainMin = min( [reac.crossSection.domainMin for reac in reactionList] ) - domainMax = min( [reac.crossSection.domainMax for reac in reactionList] ) + domainMin = min([reac.crossSection.domainMin for reac in reactionList]) + domainMax = min([reac.crossSection.domainMax for reac in reactionList]) info.evaluatedStyle.projectileEnergyDomain.min = domainMin info.evaluatedStyle.projectileEnergyDomain.max = domainMax @@ -361,27 +376,27 @@ def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation reactionSuite._loadedCovariances = [covarianceSuite] # Fill up the reactionSuite - for reaction in reactionSuite.reactions : addUnspecifiedDistributions( info, reaction.outputChannel ) - for production in reactionSuite.productions : addUnspecifiedDistributions( info, production.outputChannel ) + for reaction in reactionSuite.reactions: addUnspecifiedDistributions(info, reaction.outputChannel) + for production in reactionSuite.productions: addUnspecifiedDistributions(info, production.outputChannel) if len(info.ENDFconversionFlags.flags) > 0: flagsToPurge = [] for conversion in info.ENDFconversionFlags.flags: if conversion.link.rootAncestor is covarianceSuite: - conversion.root = '$covariances' # FIXME need better way of handling this + conversion.root = '$covariances' # FIXME need better way of handling this elif conversion.link.rootAncestor is not reactionSuite: - flagsToPurge.append( conversion ) # flag doesn't point to any GNDS node + flagsToPurge.append(conversion) # flag doesn't point to any GNDS node for flag in flagsToPurge: - info.ENDFconversionFlags.flags.remove( flag ) - info.ENDFconversionFlags.flags.sort(key = lambda val: val.flags) + info.ENDFconversionFlags.flags.remove(flag) + info.ENDFconversionFlags.flags.sort(key=lambda val: val.flags) LLNLdata = institutionModule.Institution("LLNL") LLNLdata.append(info.ENDFconversionFlags) - reactionSuite.applicationData.add( LLNLdata ) + reactionSuite.applicationData.add(LLNLdata) PoPs = reactionSuite.PoPs - lightMasses = { # atomic masses in amu, taken from AME2012 (http://www.nndc.bnl.gov/masses/mass.mas12) - IDsPoPsModule.neutron: 1.00866491585, + lightMasses = { # atomic masses in amu, taken from AME2012 (http://www.nndc.bnl.gov/masses/mass.mas12) + IDsPoPsModule.neutron: 1.00866491585, 'H1': 1.00782503223, 'H2': 2.01410177812, 'H3': 3.01604927791, @@ -392,32 +407,33 @@ def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation if pid in info.PoPs: if len(info.PoPs[pid].mass) == 0: info.PoPs[pid].mass.add( - massModule.Double( info.PoPsLabel, lightMasses[pid], quantityModule.stringToPhysicalUnit('amu') ) + massModule.Double(info.PoPsLabel, lightMasses[pid], quantityModule.stringToPhysicalUnit('amu')) ) - for product1ID in info.missingTwoBodyMasses : - if len(info.PoPs[product1ID].mass) != 0: # mass was added to PoPs, likely in previous block + for product1ID in info.missingTwoBodyMasses: + if len(info.PoPs[product1ID].mass) != 0: # mass was added to PoPs, likely in previous block product1Mass = info.PoPs[product1ID].getMass("amu") else: raise ValueError("Missing mass for 2-body reaction product %s" % product1ID) - massPTmP1 = PoPs[reactionSuite.projectile].getMass( 'amu' ) + PoPs[targetID].getMass( 'amu' ) - \ + massPTmP1 = PoPs[reactionSuite.projectile].getMass('amu') + PoPs[targetID].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' ) ) + 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 ) + if len(residual.mass) == 0: residual.mass.add(mass) # Did we have trouble? - if( ( len( info.MF4ForNonNeutrons ) > 0 ) and ( verbose > 0 ) ) : - print(' WARNING: MF=4 data for non-neutron product: MTs = %s' % sorted( info.MF4ForNonNeutrons )) + if len(info.MF4ForNonNeutrons) > 0 and verbose > 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', True ) - raise Exception( 'len( info.doRaise ) > 0' ) + 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', True) + raise Exception('len( info.doRaise ) > 0') if info.resonanceReconstructionFailed != '': print('ERROR: Resonance reconstruction failed: "%s".' % info.resonanceReconstructionFailed) @@ -431,25 +447,26 @@ def endfFileToGNDS(fileName, useFilesQAlways=True, singleMTOnly=None, evaluation info.massTracker.printHistory() info.ZA_massLineInfo.printInfo() - return( { 'reactionSuite' : reactionSuite, 'covarianceSuite' : covarianceSuite, 'errors' : info.doRaise, 'info':info } ) + return {'reactionSuite': reactionSuite, 'covarianceSuite': covarianceSuite, 'errors': info.doRaise, 'info': info} + -def addUnspecifiedDistributions( info, outputChannel ) : +def addUnspecifiedDistributions(info, outputChannel): + if outputChannel is None: return + for product in outputChannel: + if len(product.distribution) == 0: + product.distribution.add(unspecifiedModule.Form(info.style, productFrame=xDataEnumsModule.Frame.lab)) + info.ENDFconversionFlags.add(product, 'implicitProduct') + addUnspecifiedDistributions(info, product.outputChannel) - if( outputChannel is None ) : return - for product in outputChannel : - if( len( product.distribution ) == 0 ) : - product.distribution.add(unspecifiedModule.Form(info.style, productFrame = xDataEnumsModule.Frame.lab)) - info.ENDFconversionFlags.add( product, 'implicitProduct' ) - addUnspecifiedDistributions( info, product.outputChannel ) -if( __name__ == '__main__' ) : +if __name__ == '__main__': - rce = endfFileToGNDS( fileName = sys.argv[1]) + rce = endfFileToGNDS(fileName=sys.argv[1]) x, c = rce['reactionSuite'], rce['covarianceSuite'] - f = open( 'test.xml', 'w' ) - f.write( '\n'.join( x.toXML_strList( ) + [ '' ] ) ) - f.close( ) - if( c is not None ) : # covariances - f = open( 'test-covar.xml', 'w' ) - f.write( '\n'.join( c.toXML_strList( ) + [ '' ] ) ) + f = open('test.xml', 'w') + f.write('\n'.join(x.toXML_strList() + [''])) + f.close() + if c is not None: # covariances + f = open('test-covar.xml', 'w') + f.write('\n'.join(c.toXML_strList() + [''])) f.close() diff --git a/brownies/legacy/converting/toGNDSMisc.py b/brownies/legacy/converting/toGNDSMisc.py index 2bec4515..04c3e96a 100644 --- a/brownies/legacy/converting/toGNDSMisc.py +++ b/brownies/legacy/converting/toGNDSMisc.py @@ -41,125 +41,128 @@ from . import massTracker as massTrackerModule -def ZAToName( ZA ) : - if( ZA == 99120 ) : return( 'FissionProductENDL99120' ) - if( ZA == 99125 ) : return( 'FissionProductENDL99125' ) - return( chemicalElementMiscPoPsModule.isotopeSymbolFromChemicalElementIDAndA( chemicalElementMiscPoPsModule.symbolFromZ[ZA//1000], ZA % 1000 ) ) +def ZAToName(ZA): + if ZA == 99120: return 'FissionProductENDL99120' + if ZA == 99125: return 'FissionProductENDL99125' + return chemicalElementMiscPoPsModule.isotopeSymbolFromChemicalElementIDAndA( + chemicalElementMiscPoPsModule.symbolFromZ[ZA // 1000], ZA % 1000) -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 ) +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 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 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 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 ) + 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 addNucleusInfoForLightNuclei( ZA, nucleus, info ) : +def addNucleusInfoForLightNuclei(ZA, nucleus, info): spinValue, parityValue, halflifeValue = None, None, None - if( ZA == 1001 ) : + if ZA == 1001: massValue, spinValue, parityValue, chargeValue, halflifeValue = 1.00727646662, '1/2', 1, 1, 'stable' - elif( ZA == 1002 ) : + elif ZA == 1002: massValue, spinValue, parityValue, chargeValue, halflifeValue = 2.01355321275, '1', 1, 1, 'stable' - elif( ZA == 1003 ) : + elif ZA == 1003: massValue, spinValue, parityValue, chargeValue, halflifeValue = 3.01550071621, '1/2', 1, 1, 3.88789e+8 - elif( ZA == 2003 ) : + elif ZA == 2003: massValue, spinValue, parityValue, chargeValue, halflifeValue = 3.01493224717, '1/2', 1, 2, 'stable' - elif( ZA == 2004 ) : + elif ZA == 2004: massValue, spinValue, parityValue, chargeValue, halflifeValue = 4.0015061791, '0', 1, 2, 'stable' - else : + else: return - addParticleData( nucleus, info, massValue, spinValue, parityValue, chargeValue, halflifeValue ) + addParticleData(nucleus, info, massValue, spinValue, parityValue, chargeValue, halflifeValue) -def getPoPsParticle( info, ZA, name = None, levelIndex = None, level = 0., levelUnit = 'MeV' ) : - if( levelIndex is not None ) : - levelIndex = int( levelIndex ) - if( levelIndex < 0 ) : raise Exception( 'levelIndex = %d must be >= 0' % levelIndex ) +def getPoPsParticle(info, ZA, name=None, levelIndex=None, level=0., levelUnit='MeV'): + if levelIndex is not 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 ) : + if ZA in [0, 17]: ZA = 7 + if name is not None: pass - elif( ZA == 1 ) : + elif ZA == 1: particle = baryonModule.Particle(IDsPoPsModule.neutron) - addParticleData( particle, info, 1.00866491574, "1/2", 1, 0, 881.5 ) + 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 ) + 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-_anti', generation = leptonModule.Generation.electronic ) - addParticleData( particle, info, 5.485799090e-4, "1/2", -1, 1, halflifeModule.STABLE ) + elif ZA == 8: + particle = leptonModule.Particle('e-_anti', generation=leptonModule.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 = leptonModule.Generation.electronic ) - addParticleData( particle, info, 5.485799090e-4, "1/2", 1, -1, halflifeModule.STABLE ) + elif ZA == 9: + particle = leptonModule.Particle('e-', generation=leptonModule.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 ) - charge = chargeModule.Integer( info.PoPsLabel, 46, chargeModule.baseUnit ) - particle.charge.add( charge ) - else : - name = ZAToName( ZA ) - if( levelIndex is None ) : + 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) + charge = chargeModule.Integer(info.PoPsLabel, 46, chargeModule.baseUnit) + particle.charge.add(charge) + 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 ) - level = PQUModule.PQU( PQUModule.PQU_float.surmiseSignificantDigits( level ), levelUnit ) - name = chemicalElementMiscPoPsModule.nuclideIDFromIsotopeSymbolAndIndex( name, levelIndex ) + if level < 0.: raise Exception('Negative value = %s for continuum is not allowed' % level) + level = PQUModule.PQU(PQUModule.PQU_float.surmiseSignificantDigits(level), levelUnit) + name = chemicalElementMiscPoPsModule.nuclideIDFromIsotopeSymbolAndIndex(name, levelIndex) - if( ( particle is None ) and ( name not in info.PoPs ) ) : + if (particle is None) and (name not in info.PoPs): - if( level is not None ) : # Add a nuclide. - baseName = name.split('_')[0] # Always need to add ground state before excited level. - if( 'FissionProduct' in name ) : baseName = name.split('_')[0] + if level is not None: # Add a nuclide. + baseName = name.split('_')[0] # Always need to add ground state before excited level. + if 'FissionProduct' in name: baseName = name.split('_')[0] - particle = nuclideModule.Particle( name ) - charge = chargeModule.Integer( info.PoPsLabel, 0, chargeModule.baseUnit ) - particle.charge.add( charge ) + particle = nuclideModule.Particle(name) + charge = chargeModule.Integer(info.PoPsLabel, 0, chargeModule.baseUnit) + particle.charge.add(charge) - energy = nuclearEnergyLevelModule.Double( info.PoPsLabel, float( level ), level.unit ) - particle.nucleus.energy.add( energy ) + energy = nuclearEnergyLevelModule.Double(info.PoPsLabel, float(level), level.unit) + particle.nucleus.energy.add(energy) - charge = chargeModule.Integer( info.PoPsLabel, ZA // 1000, chargeModule.baseUnit ) - particle.nucleus.charge.add( charge ) - addNucleusInfoForLightNuclei( ZA, particle.nucleus, info ) - else : - if( particle is None ) : raise Exception( 'FIX ME' ) - else : - if( particle is None ) : particle = info.PoPs[name] + charge = chargeModule.Integer(info.PoPsLabel, ZA // 1000, chargeModule.baseUnit) + particle.nucleus.charge.add(charge) + addNucleusInfoForLightNuclei(ZA, particle.nucleus, info) + else: + if particle is None: raise Exception('FIX ME') + else: + if particle is None: particle = info.PoPs[name] if name not in info.PoPs: info.PoPs.add(particle) if name != IDsPoPsModule.photon: - familiarID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(name, specialNuclearParticleIDPoPsModule.Mode.familiar) + familiarID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID( + name, specialNuclearParticleIDPoPsModule.Mode.familiar) if familiarID != name: - nucleusID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID(name, specialNuclearParticleIDPoPsModule.Mode.nucleus) + nucleusID = specialNuclearParticleIDPoPsModule.specialNuclearParticleID( + name, specialNuclearParticleIDPoPsModule.Mode.nucleus) if familiarID not in info.PoPs: if familiarID == IDsPoPsModule.proton: proton = baryonModule.Particle(IDsPoPsModule.proton) @@ -170,13 +173,15 @@ def getPoPsParticle( info, ZA, name = None, levelIndex = None, level = 0., level return particle -def getTypeName( info, ZA, name = None, levelIndex = None, level = 0., levelUnit = 'MeV' ) : + +def getTypeName(info, ZA, name=None, levelIndex=None, level=0., levelUnit='MeV'): """ Returns the name for this ZA and level if present. Returned name is of the form Am242, Am242_m1, Am242_e2. levelIndex must be None or an integer > 0. """ - return( getPoPsParticle( info, ZA, name, levelIndex, level, levelUnit ) ) + return getPoPsParticle(info, ZA, name, levelIndex, level, levelUnit) + def newGNDSParticle(info, particle, crossSection, multiplicity=1, outputChannel=None): """ @@ -197,49 +202,51 @@ def newGNDSParticle(info, particle, crossSection, multiplicity=1, outputChannel= if multiplicity.rangeMin == multiplicity.rangeMax == 1.0: multiplicity = multiplicity.rangeMin if isinstance(multiplicity, (int, float)): - axes = multiplicityModule.defaultAxes( crossSection.domainUnit ) - multiplicity = multiplicityModule.Constant1d(multiplicity, crossSection.domainMin, crossSection.domainMax, axes=axes, label=info.style) + axes = multiplicityModule.defaultAxes(crossSection.domainUnit) + multiplicity = multiplicityModule.Constant1d(multiplicity, crossSection.domainMin, crossSection.domainMax, + axes=axes, label=info.style) product.multiplicity.add(multiplicity) return product -def getTypeNameGamma( info, ZA, level = None, levelIndex = None ) : - if( level is not None ) : - if( fudgemath.isNumber( level ) ) : - if( level < 0 ) : - if( ( level > -100 ) and ( levelIndex == 0 ) ) : +def getTypeNameGamma(info, ZA, level=None, levelIndex=None): + if level is not None: + if fudgemath.isNumber(level): + if level < 0: + if (level > -100) and (levelIndex == 0): level = 0 - else : - message = 'Negative excitation level = %s for ZA = %s and levelIndex = %s is not allowed' % ( level, ZA, levelIndex ) - sys.stderr.write( message+'\n' ) - info.doRaise.append( message ) + else: + message = 'Negative excitation level = %s for ZA = %s and levelIndex = %s is not allowed' % ( + level, ZA, levelIndex) + sys.stderr.write(message + '\n') + info.doRaise.append(message) level = 0 - elif( type( level ) != type( '' ) ) : - raise Exception( 'for ZA %d, level (type ="%s") must be a number or a string' % ( ZA, brb.getType( level ) ) ) - if( ZA == 0 ) : ZA = 7 # Special case for gammas which are yo = 7 for ENDL. - p = getTypeName( info, ZA, level = level, levelIndex = levelIndex, levelUnit = 'eV' ) - return( p ) + elif not isinstance(level, str): + raise Exception('for ZA %d, level (type ="%s") must be a number or a string' % (ZA, brb.getType(level))) + if ZA == 0: ZA = 7 # Special case for gammas which are yo = 7 for ENDL. + p = getTypeName(info, ZA, level=level, levelIndex=levelIndex, levelUnit='eV') + return p -def getTypeNameENDF( info, ZA, undefinedLevelInfo ) : +def getTypeNameENDF(info, ZA, undefinedLevelInfo): levelIndex, level = None, 0. - if( undefinedLevelInfo is not None ) : - if( undefinedLevelInfo['ZA'] == ZA ) : - if undefinedLevelInfo['level'] > 0. and ZA in [ 1001, 1002, 1003, 2003, 2004 ] : + if undefinedLevelInfo is not None: + if undefinedLevelInfo['ZA'] == ZA: + if undefinedLevelInfo['level'] > 0. and ZA in [1001, 1002, 1003, 2003, 2004]: info.logs.write(" Excited state of ZA %d encountered" % ZA) undefinedLevelInfo['count'] += 1 - if( undefinedLevelInfo['count'] > 1 ) : - if( undefinedLevelInfo['level'] > 0. ) : + if undefinedLevelInfo['count'] > 1: + if undefinedLevelInfo['level'] > 0.: raise Exception("undefinedLevelInfo['count'] > 1 for ZA = %s: %s" % (ZA, undefinedLevelInfo)) else: levelIndex, level = undefinedLevelInfo['levelIndex'], undefinedLevelInfo['level'] - return( getTypeNameGamma( info, ZA, level = level, levelIndex = levelIndex ) ) + return getTypeNameGamma(info, ZA, level=level, levelIndex=levelIndex) -class Infos: - def __init__( self, formatVersion, style ) : +class Infos: + def __init__(self, formatVersion, style): self.formatVersion = formatVersion self.style = style self.massTracker = massTrackerModule.MassTracker() @@ -253,16 +260,17 @@ def logs(self): return self.__logs @logs.setter def logs(self, logs): self.__logs = logs - def addMassAWR( self, ZA, AWR, asTarget=True ): - warning = self.massTracker.addMassAWR( ZA, AWR, asTarget=asTarget ) - if warning: self.logs.write( warning ) + def addMassAWR(self, ZA, AWR, asTarget=True): + warning = self.massTracker.addMassAWR(ZA, AWR, asTarget=asTarget) + if warning: self.logs.write(warning) + -def returnConstantQ( style, Q, crossSection ) : +def returnConstantQ(style, Q, crossSection): + axes = QModule.defaultAxes(crossSection.domainUnit) + return QModule.Constant1d(Q, crossSection.domainMin, crossSection.domainMax, axes=axes, label=style) - axes = QModule.defaultAxes( crossSection.domainUnit ) - return( QModule.Constant1d( Q, crossSection.domainMin, crossSection.domainMax, axes = axes, label = style ) ) -def addUnspecifiedDistributions(info, outputChannel, frame=xDataEnumsModule.Frame.none) : +def addUnspecifiedDistributions(info, outputChannel, frame=xDataEnumsModule.Frame.none): """ For products with no distribution, assign an unspecified distribution. Interim products before breakup get an 'implicitProduct' conversion flag (so they aren't written back to ENDF-6), @@ -277,8 +285,8 @@ def addUnspecifiedDistributions(info, outputChannel, frame=xDataEnumsModule.Fram if len(product.distribution) == 0: product.distribution.add(unspecifiedModule.Form(info.style, productFrame=frame)) if product.outputChannel or firstProductId == IDsPoPsModule.neutron: - info.ENDFconversionFlags.add( product, 'implicitProduct' ) - else : + info.ENDFconversionFlags.add(product, 'implicitProduct') + else: if frame == xDataEnumsModule.Frame.none: frame = product.distribution[info.style].productFrame addUnspecifiedDistributions(info, product.outputChannel, frame=xDataEnumsModule.Frame.lab) diff --git a/brownies/legacy/toENDF6/differentialCrossSection/thermalNeutronScatteringLaw.py b/brownies/legacy/toENDF6/differentialCrossSection/thermalNeutronScatteringLaw.py index 1daa1196..3fcd4fa9 100644 --- a/brownies/legacy/toENDF6/differentialCrossSection/thermalNeutronScatteringLaw.py +++ b/brownies/legacy/toENDF6/differentialCrossSection/thermalNeutronScatteringLaw.py @@ -192,6 +192,48 @@ def toENDF6( self, endfMFList, flags, targetInfo, verbosityIndent = '' ): if atom.T_effective is not None: endf += atom.T_effective.toENDF6( flags, targetInfo, verbosityIndent = '' ) endfMFList[7][4] = endf + [99999] + + targetInfo_ = self.rootAncestor.styles.getEvaluatedStyle().targetInfo + if targetInfo_ is not None: + # write general information section: + NA = len(targetInfo_.isotopicAbundances.chemicalElements) + endf = [endfFormatsModule.endfHeadLine(ZAM, AWT, NA, 0, 0, 0)] + pops = self.rootAncestor.PoPs + numberPerMolecule = {} + for atom in self.scatteringAtoms: + try: + popsParticle = pops[atom.pid] + except: + print(f"Can't look up particle {atom.pid}. Assuming 1 scattering atom per molecule.") + continue + + if hasattr(popsParticle, 'symbol'): + symbol = popsParticle.symbol + elif hasattr(popsParticle, 'chemicalElementSymbol'): + symbol = popsParticle.chemicalElementSymbol + else: + raise TypeError("Can't determine chemical element for particle %s" % atom.pid) + numberPerMolecule[symbol] = atom.numberPerMolecule + for chemicalElement in targetInfo_.isotopicAbundances.chemicalElements: + NAS = numberPerMolecule.get(chemicalElement.symbol, 1) + NI = len(chemicalElement.nuclides) + endf.append(endfFormatsModule.endfContLine(0, 0, NAS, 0, 6*NI, NI)) + for nuclide in chemicalElement.nuclides: + popsParticle = pops[nuclide.pid] + ZAI = 1000 * popsParticle.Z + popsParticle.A + AFI = nuclide.atomFraction + mass_amu = popsParticle.mass.float('amu') + AWRI = mass_amu / neutronMass + + boundAtomCrossSection, = [bac for bac in self.scatteringAtoms[0].boundAtomCrossSectionByNuclide + if bac.label == nuclide.pid] + freeAtomCrossSection = boundAtomCrossSection.value * ( + mass_amu / (mass_amu + neutronMass)) ** 2 + endf.append(endfFormatsModule.endfDataLine([ZAI, 0, AFI, AWRI, freeAtomCrossSection, 0])) + + endf.append(endfFormatsModule.endfSENDLineNumber()) + endfMFList[7][451] = endf + thermalScatteringModule.incoherentInelastic.Form.toENDF6 = toENDF6 # diff --git a/brownies/legacy/toENDF6/productData/distributions/KalbachMann.py b/brownies/legacy/toENDF6/productData/distributions/KalbachMann.py index 9c2fbc9d..793a0e2c 100644 --- a/brownies/legacy/toENDF6/productData/distributions/KalbachMann.py +++ b/brownies/legacy/toENDF6/productData/distributions/KalbachMann.py @@ -9,51 +9,74 @@ from xData import enums as xDataEnumsModule from xData import XYs1d as XYs1dModule +from xData import regions as regionsModule from fudge.productData.distributions import KalbachMann as KalbachMannModule from ... import endfFormats as endfFormatsModule from ... import gndsToENDF6 as gndsToENDF6Module + # # KalbachMann # -def toENDF6( self, MT, endfMFList, flags, targetInfo ) : +def toENDF6(self, MT, endfMFList, flags, targetInfo): fSubform = self.fSubform.data rSubform = self.rSubform.data aSubform = self.aSubform - if( not( aSubform.isEmptyASubform( ) ) ) : raise 'hell - FIXME' + if not aSubform.isEmptyASubform(): raise 'hell - FIXME' + + def getFlatListOfInterpolations(functional2d): + if isinstance(functional2d, regionsModule.Regions2d): + return [xys1d.interpolation for xys2d in functional2d for xys1d in xys2d] + else: + return [xys1d.interpolation for xys1d in functional2d] - outgoingInterpolation = set( [val.interpolation for val in fSubform] + [val.interpolation for val in rSubform] ) + outgoingInterpolation = set(getFlatListOfInterpolations(fSubform) + getFlatListOfInterpolations(rSubform)) if len(outgoingInterpolation) != 1: raise NotImplementedError("Only one outgoing interpolation supported when writing Kalbach-Mann to ENDF-6") - LEP = {xDataEnumsModule.Interpolation.flat: 1, xDataEnumsModule.Interpolation.linlin: 2 }[outgoingInterpolation.pop()] - ENDFDataList = [ endfFormatsModule.endfContLine( 0, 0, 2, LEP, 1, len( fSubform ) ) ] - interpolation = gndsToENDF6Module.gndsToENDF2PlusDInterpolationFlag(fSubform.interpolation, fSubform.interpolationQualifier) - ENDFDataList += endfFormatsModule.endfInterpolationList( [ len( fSubform ), interpolation ] ) EInUnit = fSubform.axes[2].unit EpUnit = fSubform.axes[1].unit fUnit = fSubform.axes[0].unit - EInFactor = PQUModule.PQU( 1, EInUnit ).getValueAs( 'eV' ) - EpFactor = PQUModule.PQU( 1, EpUnit ).getValueAs( 'eV' ) - fFactor = PQUModule.PQU( 1, fUnit ).getValueAs( '1/eV' ) - for i1, fAtEnergy in enumerate( fSubform ) : - rAtEnergy = rSubform[i1] - if( not( isinstance( fAtEnergy, XYs1dModule.XYs1d ) ) ) : raise 'hell - FIXME' - if( not( isinstance( rAtEnergy, XYs1dModule.XYs1d ) ) ) : raise 'hell - FIXME' - value = fAtEnergy.outerDomainValue - if( value != rAtEnergy.outerDomainValue ) : raise 'hell - FIXME' - value *= EInFactor - coefficients = [] - for i1, ( Ep1, f1 ) in enumerate( fAtEnergy ) : - Ep2, r1 = rAtEnergy[i1] - if( Ep1 != Ep2 ) : raise 'hell - FIXME' - coefficients += [ EpFactor * Ep1, fFactor * f1, r1 ] - length = len( coefficients ) - ENDFDataList += [ endfFormatsModule.endfContLine( 0, value, 0, 1, length, length / 3 ) ] - ENDFDataList += endfFormatsModule.endfDataList( coefficients ) - gndsToENDF6Module.toENDF6_MF6( MT, endfMFList, flags, targetInfo, 1, self.productFrame, ENDFDataList ) + EInFactor = PQUModule.PQU(1, EInUnit).getValueAs('eV') + EpFactor = PQUModule.PQU(1, EpUnit).getValueAs('eV') + fFactor = PQUModule.PQU(1, fUnit).getValueAs('1/eV') + + LEP = {xDataEnumsModule.Interpolation.flat: 1, + xDataEnumsModule.Interpolation.linlin: 2}[outgoingInterpolation.pop()] + if isinstance(fSubform, regionsModule.Regions2d): + N1 = len(fSubform) + NE = sum([len(xys2d) for xys2d in fSubform]) + interp = fSubform[0].interpolation + qualifier = fSubform[0].interpolationQualifier + else: + N1 = 1 + NE = len(fSubform) + interp = fSubform.interpolation + qualifier = fSubform.interpolationQualifier + fSubform = [fSubform] + rSubform = [rSubform] + ENDFDataList = [endfFormatsModule.endfContLine(0, 0, 2, LEP, N1, NE)] + interpolation = gndsToENDF6Module.gndsToENDF2PlusDInterpolationFlag(interp, qualifier) + ENDFDataList += endfFormatsModule.endfInterpolationList([NE, interpolation]) + for f_region, r_region in zip(fSubform, rSubform): + for i1, fAtEnergy in enumerate(f_region): + rAtEnergy = r_region[i1] + if not isinstance(fAtEnergy, XYs1dModule.XYs1d): raise 'hell - FIXME' + if not isinstance(rAtEnergy, XYs1dModule.XYs1d): raise 'hell - FIXME' + value = fAtEnergy.outerDomainValue + if value != rAtEnergy.outerDomainValue: raise 'hell - FIXME' + value *= EInFactor + coefficients = [] + for i1, (Ep1, f1) in enumerate(fAtEnergy): + Ep2, r1 = rAtEnergy[i1] + if Ep1 != Ep2: raise 'hell - FIXME' + coefficients += [EpFactor * Ep1, fFactor * f1, r1] + length = len(coefficients) + ENDFDataList += [endfFormatsModule.endfContLine(0, value, 0, 1, length, length / 3)] + ENDFDataList += endfFormatsModule.endfDataList(coefficients) + gndsToENDF6Module.toENDF6_MF6(MT, endfMFList, flags, targetInfo, 1, self.productFrame, ENDFDataList) KalbachMannModule.Form.toENDF6 = toENDF6 diff --git a/brownies/legacy/toENDF6/reactionSuite.py b/brownies/legacy/toENDF6/reactionSuite.py index fade4e6c..fac7304e 100644 --- a/brownies/legacy/toENDF6/reactionSuite.py +++ b/brownies/legacy/toENDF6/reactionSuite.py @@ -144,7 +144,8 @@ def toENDF6(self, styleLabel, flags, verbosityIndent='', covarianceSuite=None, u targetInfo['LIS'] = levelIndex targetInfo['metastables'] = {} targetInfo['LISO'] = 0 - if levelIndex > 0: targetInfo['LISO'] = 1 + if levelIndex > 0: + targetInfo['LISO'] = self.PoPs[self.target].metaStableIndex # BRBBRB for alias in self.PoPs.aliases: if hasattr(alias, 'metaStableIndex'): diff --git a/doc/html/_downloads/b60ba9b0c8bc58d29daa09756d15449b/gnds.xsd b/doc/html/_downloads/b60ba9b0c8bc58d29daa09756d15449b/gnds.xsd index e4d19ac1..2198448c 100644 --- a/doc/html/_downloads/b60ba9b0c8bc58d29daa09756d15449b/gnds.xsd +++ b/doc/html/_downloads/b60ba9b0c8bc58d29daa09756d15449b/gnds.xsd @@ -59,7 +59,7 @@ - + @@ -97,6 +97,7 @@ + @@ -149,6 +150,44 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -631,7 +670,7 @@ - + @@ -1351,6 +1390,7 @@ + @@ -1854,10 +1894,17 @@ + + + + + + + diff --git a/doc/html/_downloads/fa01c2168c9265e8fca8812f1987898f/covariances.xsd b/doc/html/_downloads/fa01c2168c9265e8fca8812f1987898f/covariances.xsd index 7c0e497b..a4aa5c1d 100644 --- a/doc/html/_downloads/fa01c2168c9265e8fca8812f1987898f/covariances.xsd +++ b/doc/html/_downloads/fa01c2168c9265e8fca8812f1987898f/covariances.xsd @@ -34,7 +34,7 @@ - + diff --git a/doc/html/_modules/fudge/covariances/base.html b/doc/html/_modules/fudge/covariances/base.html index 39d1f1fe..d36ba533 100644 --- a/doc/html/_modules/fudge/covariances/base.html +++ b/doc/html/_modules/fudge/covariances/base.html @@ -52,31 +52,32 @@

Source code for fudge.covariances.base

 
 import abc
 
+
 
[docs]class Covariance(abc.ABC): @property @abc.abstractmethod - def label( self ): pass + def label(self): pass
[docs] @abc.abstractmethod - def rowBounds( self, unit=None ): pass
+ def rowBounds(self, unit=None): pass
[docs] @abc.abstractmethod - def columnBounds( self, unit=None ): pass
+ def columnBounds(self, unit=None): pass
@property @abc.abstractmethod - def domainUnit( self ): pass + def domainUnit(self): pass @property @abc.abstractmethod - def isSymmetric( self ): pass + def isSymmetric(self): pass
[docs] @abc.abstractmethod - def toCovarianceMatrix( self, domain=None ): pass
+ def toCovarianceMatrix(self, domain=None): pass
[docs] @abc.abstractmethod - def getUncertaintyVector( self, theData=None, relative=True ): pass
+ def getUncertaintyVector(self, theData=None, relative=True): pass
diff --git a/doc/html/_modules/fudge/covariances/covarianceMatrix.html b/doc/html/_modules/fudge/covariances/covarianceMatrix.html index f3a89396..58d472ba 100644 --- a/doc/html/_modules/fudge/covariances/covarianceMatrix.html +++ b/doc/html/_modules/fudge/covariances/covarianceMatrix.html @@ -65,6 +65,7 @@

Source code for fudge.covariances.covarianceMatrix

lowerEps = 1e-8 upperEps = 1e-8 +
[docs]class CovarianceMatrix(ancestryModule.AncestryIO, base.Covariance): """ Simplest form of covariance. covarianceMatrix contains a label, a covariance 'type' which might be 'absolute', @@ -75,7 +76,7 @@

Source code for fudge.covariances.covarianceMatrix

moniker = 'covarianceMatrix' keyName = 'label' - def __init__( self, label, type=covarianceEnumsModule.Type.absolute, matrix=None, productFrame=None ): + def __init__(self, label, type=covarianceEnumsModule.Type.absolute, matrix=None, productFrame=None): """ :param label: refers either to a style (i.e., 'eval'), or to the index inside a 'mixed' covariance @@ -88,30 +89,30 @@

Source code for fudge.covariances.covarianceMatrix

:rtype: CovarianceMatrix """ - ancestryModule.AncestryIO.__init__( self ) + ancestryModule.AncestryIO.__init__(self) self.__label = label self.__type = covarianceEnumsModule.Type.checkEnumOrString(type) self.productFrame = productFrame - self.matrix = matrix #: a :py:class:`xData.gridded.Gridded2d` instance containing the matrix - self.matrix.setAncestor( self ) + self.matrix = matrix #: a :py:class:`xData.gridded.Gridded2d` instance containing the matrix + self.matrix.setAncestor(self) @property - def label( self ): + def label(self): return self.__label @label.setter - def label( self, value ) : + def label(self, value): - if( value is not None ) : - if( not( isinstance( value, str ) ) ) : raise TypeError( 'label must be a string' ) + if (value is not None): + if (not (isinstance(value, str))): raise TypeError('label must be a string') self.__label = value @property - def domainUnit( self ): + def domainUnit(self): return self.matrix.axes[-1].unit @property - def productFrame( self ): + def productFrame(self): return self.__productFrame @productFrame.setter @@ -123,16 +124,16 @@

Source code for fudge.covariances.covarianceMatrix

self.__productFrame = xDataEnumsModule.Frame.checkEnumOrString(value) @property - def type( self ): + def type(self): return self.__type -
[docs] def getValue( self, x, y ): - ix = self.matrix.axes[2].getIndexOfValue(x) - if isinstance(self.matrix.axes[1].values, linkModule.Link): - iy = self.matrix.axes[2].getIndexOfValue(y) - else: - iy = self.matrix.axes[1].getIndexOfValue(y) - return self.matrix.array.constructArray()[ix, iy]
+
[docs] def getValue(self, x, y): + ix = self.matrix.axes[2].getIndexOfValue(x) + if isinstance(self.matrix.axes[1].values, linkModule.Link): + iy = self.matrix.axes[2].getIndexOfValue(y) + else: + iy = self.matrix.axes[1].getIndexOfValue(y) + return self.matrix.array.constructArray()[ix, iy]
[docs] def rowBounds( self, unit=None ): """Get the bounds of the row. If unit is specified, return the bounds in that unit.""" @@ -141,7 +142,7 @@

Source code for fudge.covariances.covarianceMatrix

factor = PQU.PQU(1, self.matrix.axes[-1].unit).getValueAs(unit) return (self.matrix.axes[-1].values[0] * factor, self.matrix.axes[-1].values[-1] * factor)
-
[docs] def columnBounds( self, unit=None ): +
[docs] def columnBounds(self, unit=None): """Get the bounds of the column. If unit is specified, return the bounds in that unit.""" if isinstance(self.matrix.axes[-2].values, linkModule.Link): return self.rowBounds(unit) factor = 1 @@ -155,35 +156,35 @@

Source code for fudge.covariances.covarianceMatrix

:return: boolean """ - if ( self.matrix.array.compression == arrayModule.Diagonal.moniker or - self.matrix.array.symmetry in (arrayModule.Symmetry.lower, arrayModule.Symmetry.upper) ): + if (self.matrix.array.compression == arrayModule.Diagonal.moniker or + self.matrix.array.symmetry in (arrayModule.Symmetry.lower, arrayModule.Symmetry.upper)): return True # could still be symmetric even if it doesn't use compression arr = self.matrix.array.constructArray() - return numpy.all( arr==arr.T )
+ return numpy.all(arr == arr.T)
-
[docs] def convertAxesToUnits( self, units ): +
[docs] def convertAxesToUnits(self, units): """ Converts all the axes' units. The parameter ``units`` should be a list of units with the same length as self.axes """ - if not type( units ) in [ list, tuple ]: + if not type(units) in [list, tuple]: raise TypeError("units argument must be a list or tuple of strings") - if len( units ) != len( self.matrix.axes ): + if len(units) != len(self.matrix.axes): raise ValueError("requested units list has a different length than the number of axes") - for i,a in enumerate( self.matrix.axes ): - if isinstance(a,axesModule.Grid): - a.convertToUnit( units[i] ) - elif isinstance(a,axesModule.Axis): - a.unit=units[i] + for i, a in enumerate(self.matrix.axes): + if isinstance(a, axesModule.Grid): + a.convertToUnit(units[i]) + elif isinstance(a, axesModule.Axis): + a.unit = units[i] else: raise TypeError()
-
[docs] def convertUnits( self, unitMap ): +
[docs] def convertUnits(self, unitMap): self.matrix.convertUnits(unitMap)
-
[docs] def domainSlice( self, rowDomainBounds, columnDomainBounds=None, label="" ): +
[docs] def domainSlice(self, rowDomainBounds, columnDomainBounds=None, label=""): """ Return copy with a revised domain for rows and columns. If requested domain extends beyond limits of self, add rows/columns of zeros to the new matrix. @@ -209,17 +210,17 @@

Source code for fudge.covariances.covarianceMatrix

indices = [] for index, boundary in enumerate(rowDomainBounds): if boundary in bins: - indices.append( bins.index(boundary) ) - matrixIndices.append( bins.index(boundary) ) + indices.append(bins.index(boundary)) + matrixIndices.append(bins.index(boundary)) elif boundary > bins[-1]: - matrixIndices.append(len(bins)-1) - indices.append( bisect.bisect(bins, boundary) ) + matrixIndices.append(len(bins) - 1) + indices.append(bisect.bisect(bins, boundary)) else: if index == 0: - matrixIndices.append( max(bisect.bisect(bins, boundary)-1, 0) ) + matrixIndices.append(max(bisect.bisect(bins, boundary) - 1, 0)) else: - matrixIndices.append( bisect.bisect(bins, boundary) ) - indices.append( bisect.bisect(bins, boundary) ) + matrixIndices.append(bisect.bisect(bins, boundary)) + indices.append(bisect.bisect(bins, boundary)) new_bins = bins[slice(*indices)] slice1 = slice(*matrixIndices) @@ -230,8 +231,8 @@

Source code for fudge.covariances.covarianceMatrix

if new_bins[-1] != rowDomainBounds[1]: new_bins.append(rowDomainBounds[1]) - indices2 = [0, matrixIndices[1]-matrixIndices[0]] - if rowDomainBounds[0] < bins[0]: # pad start of matrix with extra zeros + indices2 = [0, matrixIndices[1] - matrixIndices[0]] + if rowDomainBounds[0] < bins[0]: # pad start of matrix with extra zeros indices2[0] += 1 indices2[1] += 1 slice2 = slice(*indices2) @@ -240,10 +241,11 @@

Source code for fudge.covariances.covarianceMatrix

newAxes = self.matrix.axes.copy() - row_ebounds = list( self.matrix.axes[-1].values ) - s1, s1a, new_row_ebounds = getNewBinBoundaries( row_ebounds, rowDomainBounds ) + row_ebounds = list(self.matrix.axes[-1].values) + s1, s1a, new_row_ebounds = getNewBinBoundaries(row_ebounds, rowDomainBounds) newAxes[2] = axesModule.Grid(newAxes[2].label, newAxes[2].index, newAxes[2].unit, - style=xDataEnumsModule.GridStyle.boundaries, values=valuesModule.Values(new_row_ebounds)) + style=xDataEnumsModule.GridStyle.boundaries, + values=valuesModule.Values(new_row_ebounds)) if (isinstance(self.matrix.axes[-2].values, linkModule.Link) and self.matrix.axes[-2].values.link is self.matrix.axes[-1].values): @@ -251,23 +253,25 @@

Source code for fudge.covariances.covarianceMatrix

s2 = s1 s2a = s1a newAxes[1] = axesModule.Grid(newAxes[1].label, newAxes[1].index, newAxes[1].unit, - style=newAxes[1].style, values=linkModule.Link(link=newAxes[2].values, relative=True)) + style=newAxes[1].style, + values=linkModule.Link(link=newAxes[2].values, relative=True)) else: - col_ebounds = list( self.matrix.axes[-2].values ) - s2, s2a, new_col_ebounds = getNewBinBoundaries( col_ebounds, columnDomainBounds ) + col_ebounds = list(self.matrix.axes[-2].values) + s2, s2a, new_col_ebounds = getNewBinBoundaries(col_ebounds, columnDomainBounds) newAxes[1] = axesModule.Grid(newAxes[1].label, newAxes[1].index, newAxes[1].unit, - style=xDataEnumsModule.GridStyle.boundaries, values=valuesModule.Values(new_col_ebounds)) + style=xDataEnumsModule.GridStyle.boundaries, + values=valuesModule.Values(new_col_ebounds)) - rawMatrix = numpy.zeros(shape=(len(new_row_ebounds)-1, len(new_col_ebounds)-1)) - rawMatrix[s1a,s2a] = self.matrix.array.constructArray()[s1, s2] + rawMatrix = numpy.zeros(shape=(len(new_row_ebounds) - 1, len(new_col_ebounds) - 1)) + rawMatrix[s1a, s2a] = self.matrix.array.constructArray()[s1, s2] # Pack result inside a covarianceMatrix/gridded2d - gridded = griddedModule.Gridded2d( axes=newAxes, - array=arrayModule.Full(rawMatrix.shape, data=rawMatrix.flatten()) ) + gridded = griddedModule.Gridded2d(axes=newAxes, + array=arrayModule.Full(rawMatrix.shape, data=rawMatrix.flatten())) return CovarianceMatrix(label, type=self.type, matrix=gridded, productFrame=self.productFrame)
-
[docs] def toCovarianceMatrix( self ): +
[docs] def toCovarianceMatrix(self): """ Return copy of self (for consistency with toCovarianceMatrix behavior in summed.py / mixed.py) :return: @@ -276,7 +280,7 @@

Source code for fudge.covariances.covarianceMatrix

cm.setAncestor(self.ancestor) return cm
-
[docs] def getCorrelationMatrix( self ): +
[docs] def getCorrelationMatrix(self): """ Returns the correlation matrix generated from self's covariance matrix. This is essentially a copy of self, but renormalized by the uncertainty: @@ -292,27 +296,27 @@

Source code for fudge.covariances.covarianceMatrix

""" # Check if is full, square covariance matrix if not self.isSymmetric(): - raise TypeError( "Can only extract correlation matrices from symmetric covariance matrices" ) - + raise TypeError("Can only extract correlation matrices from symmetric covariance matrices") + # Rescale result matrix theCorrelationMatrix = self.matrix.array.constructArray() - theUncertainty = copy.copy( numpy.diag( theCorrelationMatrix ) ) - theUncertainty[ theUncertainty < 0.0 ] = 0.0 - theUncertainty = numpy.sqrt( theUncertainty ) - for i1 in range( theCorrelationMatrix.shape[0] ): - for i2 in range( theCorrelationMatrix.shape[1] ): - theCorrelationMatrix[i1,i2] /= ( theUncertainty[i1] * theUncertainty[i2] ) + theUncertainty = copy.copy(numpy.diag(theCorrelationMatrix)) + theUncertainty[theUncertainty < 0.0] = 0.0 + theUncertainty = numpy.sqrt(theUncertainty) + for i1 in range(theCorrelationMatrix.shape[0]): + for i2 in range(theCorrelationMatrix.shape[1]): + theCorrelationMatrix[i1, i2] /= (theUncertainty[i1] * theUncertainty[i2]) # Return the result tridata = theCorrelationMatrix[numpy.tri(theCorrelationMatrix.shape[0], dtype=bool)].tolist() correlation = griddedModule.Gridded2d( - axes=self.matrix.axes.copy(),#FIXME: unresolvedLinks still unresolved! - array=arrayModule.Full(shape=theCorrelationMatrix.shape, data=tridata, - symmetry=arrayModule.Symmetry.lower) ) + axes=self.matrix.axes.copy(), # FIXME: unresolvedLinks still unresolved! + array=arrayModule.Full(shape=theCorrelationMatrix.shape, data=tridata, + symmetry=arrayModule.Symmetry.lower)) correlation.axes[0].unit = '' return correlation
-
[docs] def toAbsolute( self, rowData=None, colData=None ): +
[docs] def toAbsolute(self, rowData=None, colData=None): """ Rescales self (if it is a relative covariance) using XYs1d rowData and colData to convert self into an absolute covariance matrix. @@ -336,23 +340,23 @@

Source code for fudge.covariances.covarianceMatrix

# Make sure we have usable row data to rescale with if rowData is None: - rowData=self.findAttributeInAncestry('rowData').link.toPointwise_withLinearXYs(lowerEps=lowerEps, - upperEps=upperEps) - if not isinstance( rowData, XYs1dModule.XYs1d ): - raise TypeError( 'rowData must be of type XYs1d, found %s' % type(rowData) ) - gRowData = rowData.group( self.matrix.axes[2].values, norm='dx' ) + rowData = self.findAttributeInAncestry('rowData').link.toPointwise_withLinearXYs(lowerEps=lowerEps, + upperEps=upperEps) + if not isinstance(rowData, XYs1dModule.XYs1d): + raise TypeError('rowData must be of type XYs1d, found %s' % type(rowData)) + gRowData = rowData.group(self.matrix.axes[2].values, norm='dx') # Only generate the column rescaling if we need to if not isinstance(self.matrix.axes[1].values, linkModule.Link): if colData is None: colData = self.findAttributeInAncestry('columnData').link.toPointwise_withLinearXYs(lowerEps=lowerEps, upperEps=upperEps) - if not isinstance( colData, XYs1dModule.XYs1d ): - raise TypeError( 'colData must be of type XYs1d, found %s' % type(colData) ) - gColData = colData.group( self.matrix.axes[1].values, norm='dx' ) + if not isinstance(colData, XYs1dModule.XYs1d): + raise TypeError('colData must be of type XYs1d, found %s' % type(colData)) + gColData = colData.group(self.matrix.axes[1].values, norm='dx') else: - colData=rowData - gColData=gRowData + colData = rowData + gColData = gRowData from numpy import outer new_data = self.matrix.array.constructArray() * outer(gRowData, gColData) @@ -378,15 +382,15 @@

Source code for fudge.covariances.covarianceMatrix

else: newGridded2d.axes[0].unit = rowData.axes[0].unit + '*' + colData.axes[0].unit - result = CovarianceMatrix( label="toAbsolute", type=covarianceEnumsModule.Type.absolute, - matrix = newGridded2d, productFrame=self.productFrame ) + result = CovarianceMatrix(label="toAbsolute", type=covarianceEnumsModule.Type.absolute, + matrix=newGridded2d, productFrame=self.productFrame) result.setAncestor(self.ancestor) result._relative = self return result
-
[docs] def toRelative( self, rowData=None, colData=None ): +
[docs] def toRelative(self, rowData=None, colData=None): """ Rescales self (if it is a absolute covariance) using XYs1d rowData and colData to convert self into a relative covariance matrix. @@ -409,21 +413,21 @@

Source code for fudge.covariances.covarianceMatrix

return self._relative # Make sure we have usable row data to rescale with - if rowData is None: + if rowData is None: rowData = self.findAttributeInAncestry('rowData').link.toPointwise_withLinearXYs(lowerEps=lowerEps, upperEps=upperEps) - if not isinstance( rowData, XYs1dModule.XYs1d ): - raise TypeError( 'rowData must be of type XYs1d, found %s' % type(rowData) ) - gRowData = rowData.group( self.matrix.axes[2].values, norm='dx' ) + if not isinstance(rowData, XYs1dModule.XYs1d): + raise TypeError('rowData must be of type XYs1d, found %s' % type(rowData)) + gRowData = rowData.group(self.matrix.axes[2].values, norm='dx') # Only generate the column rescaling if we need to if not isinstance(self.matrix.axes[1].values, linkModule.Link): - if colData is None: + if colData is None: colData = self.findAttributeInAncestry('columnData').link.toPointwise_withLinearXYs(lowerEps=lowerEps, upperEps=upperEps) - if not isinstance( colData, XYs1dModule.XYs1d ): - raise TypeError( 'colData must be of type XYs1d, found %s' % type(colData) ) - gColData = colData.group( self.matrix.axes[1].values, norm='dx' ) + if not isinstance(colData, XYs1dModule.XYs1d): + raise TypeError('colData must be of type XYs1d, found %s' % type(colData)) + gColData = colData.group(self.matrix.axes[1].values, norm='dx') else: gColData = gRowData @@ -448,17 +452,17 @@

Source code for fudge.covariances.covarianceMatrix

# Set the final units newGridded2d.axes[0].unit = '' - result = CovarianceMatrix( label="toRelative", type=covarianceEnumsModule.Type.relative, - matrix = newGridded2d, productFrame=self.productFrame ) + result = CovarianceMatrix(label="toRelative", type=covarianceEnumsModule.Type.relative, + matrix=newGridded2d, productFrame=self.productFrame) result.setAncestor(self.ancestor) result._absolute = self return result
-
[docs] def copy( self ): +
[docs] def copy(self): - return CovarianceMatrix( self.label, self.type, self.matrix.copy(), self.productFrame )
+ return CovarianceMatrix(self.label, self.type, self.matrix.copy(), self.productFrame)
[docs] def check(self, info): """Check if relative uncertainty is in the bounds passed into the checker, @@ -523,7 +527,7 @@

Source code for fudge.covariances.covarianceMatrix

return warnings
-
[docs] def fix( self, **kw ): +
[docs] def fix(self, **kw): """Fix uncertainty using the bounds passed into the fixer. Requires specification of the data ("theData") if the covariance is not relative. I was not creative when I coded this, so it will fail when theData.getValue( x ) @@ -531,25 +535,25 @@

Source code for fudge.covariances.covarianceMatrix

warnings = [] if self.isSymmetric() and kw['fixUncLimits']: - A = numpy.array( self.matrix.data ) + A = numpy.array(self.matrix.data) relative = self.type == covarianceEnumsModule.Type.relative - for idx in range( A.shape[0] ): + for idx in range(A.shape[0]): eMin = self.axes[2].grid[idx] - eMax = self.axes[2].grid[idx+1] + eMax = self.axes[2].grid[idx + 1] if relative: uncMin = kw['minRelUnc'] uncMax = kw['maxRelUnc'] else: - uncMin = kw['theData'].getValue( 0.5*(eMax+eMin) ) - uncMax = kw['theData'].getValue( 0.5*(eMax+eMin) ) - uncMin2 = uncMin*uncMin - uncMax2 = uncMax*uncMax - #eThresh = threshold.getValueAs( component.axes[0].units ) + uncMin = kw['theData'].getValue(0.5 * (eMax + eMin)) + uncMax = kw['theData'].getValue(0.5 * (eMax + eMin)) + uncMin2 = uncMin * uncMin + uncMax2 = uncMax * uncMax + # eThresh = threshold.getValueAs( component.axes[0].units ) if uncMin2 <= A[idx, idx] <= uncMax2: pass # unc is where it should be - elif uncMin2 >= A[idx,idx]: - if idx+1 < A.shape[0] and A[idx+1, idx+1] >= uncMin2: - A[idx, idx] = A[idx+1, idx+1] + elif uncMin2 >= A[idx, idx]: + if idx + 1 < A.shape[0] and A[idx + 1, idx + 1] >= uncMin2: + A[idx, idx] = A[idx + 1, idx + 1] else: A[idx, idx] = uncMin2 # else: # above threshold and uncertainty out of bounds @@ -573,9 +577,9 @@

Source code for fudge.covariances.covarianceMatrix

# A[jdx,idx] = A[idx,jdx] # A[idx,idx] = uncMax2 self.data = A.tolist() - return warnings + self.matrix.fix( **kw )
- -
[docs] def group( self, groupBoundaries = ( None, None ), groupUnit = ( None, None ) ): + return warnings + self.matrix.fix(**kw)
+ +
[docs] def group(self, groupBoundaries=(None, None), groupUnit=(None, None)): r""" Group the matrix in self @@ -668,33 +672,35 @@

Source code for fudge.covariances.covarianceMatrix

axis1index = 2 else: axis1index = 1 - + # setup the old axes in a form we can (ab)use in the XYs1d class - axes2_ = axesModule.Axes(2, labelsUnits={1:( self.matrix.axes[2].label, self.matrix.axes[2].unit ),0:( 'dummy', '' )}) - axes1_ = axesModule.Axes(2, labelsUnits={1:( self.matrix.axes[axis1index].label, self.matrix.axes[axis1index].unit ),0:( 'dummy', '' )}) - + axes2_ = axesModule.Axes(2, labelsUnits={1: (self.matrix.axes[2].label, self.matrix.axes[2].unit), + 0: ('dummy', '')}) + axes1_ = axesModule.Axes(2, labelsUnits={ + 1: (self.matrix.axes[axis1index].label, self.matrix.axes[axis1index].unit), 0: ('dummy', '')}) + # define basis functions for the rows and columns basis2 = XYs1dModule.XYs1d(axes=axes2_, - data=[(x, 0.0) for x in self.matrix.axes[2].values], interpolation='flat') + data=[(x, 0.0) for x in self.matrix.axes[2].values], interpolation='flat') basis1 = XYs1dModule.XYs1d(axes=axes1_, - data=[(x, 0.0) for x in self.matrix.axes[axis1index].values], interpolation='flat') - basis2 = basis2.convertAxisToUnit( 1, groupUnit[0] ) - basis1 = basis1.convertAxisToUnit( 1, groupUnit[1] ) + data=[(x, 0.0) for x in self.matrix.axes[axis1index].values], interpolation='flat') + basis2 = basis2.convertAxisToUnit(1, groupUnit[0]) + basis1 = basis1.convertAxisToUnit(1, groupUnit[1]) # build the regrouping matrices for the two bases w0 = [] - for idx in range( self.matrix.array.shape[0] ): - basis2[idx] = ( basis2[idx][0], 1.0 ) - w0.append( basis2.groupOneFunction( groupBoundaries[0], norm = 'dx' ) ) - basis2[idx] = ( basis2[idx][0], 0.0 ) - w0 = numpy.array( w0 ) + for idx in range(self.matrix.array.shape[0]): + basis2[idx] = (basis2[idx][0], 1.0) + w0.append(basis2.groupOneFunction(groupBoundaries[0], norm='dx')) + basis2[idx] = (basis2[idx][0], 0.0) + w0 = numpy.array(w0) w1 = [] - for j in range( self.matrix.array.shape[1] ): - basis1[j] = ( basis1[j][0], 1.0 ) - w1.append( basis1.groupOneFunction( groupBoundaries[1], norm = 'dx' ) ) - basis1[j] = ( basis1[j][0], 0.0 ) - w1 = numpy.array( w1 ) - + for j in range(self.matrix.array.shape[1]): + basis1[j] = (basis1[j][0], 1.0) + w1.append(basis1.groupOneFunction(groupBoundaries[1], norm='dx')) + basis1[j] = (basis1[j][0], 0.0) + w1 = numpy.array(w1) + # set up the regrouped covariance matrix grouped = self.copy() grouped.matrix.axes[2].data = groupBoundaries[0] @@ -705,7 +711,7 @@

Source code for fudge.covariances.covarianceMatrix

gdata = numpy.dot(w0.T, numpy.dot(odata, w1)) trigdata = gdata[numpy.tril_indices(gdata.shape[0])] grouped.matrix.array = arrayModule.Full(shape=gdata.shape, data=trigdata, - symmetry=arrayModule.Symmetry.lower) + symmetry=arrayModule.Symmetry.lower) return grouped
[docs] def removeExtraZeros(self, verbose=False): @@ -714,37 +720,37 @@

Source code for fudge.covariances.covarianceMatrix

:return: """ theMatrix = self.matrix.array.constructArray() - rowStart, colStart = 0,0 + rowStart, colStart = 0, 0 rowEnd, colEnd = theMatrix.shape - if verbose: print('before',theMatrix) + if verbose: print('before', theMatrix) # Figure out which end rows/columns are full of zeros. We can remove those - while numpy.all(theMatrix[rowStart,:]==0): rowStart += 1 - while numpy.all(theMatrix[:,colStart]==0): colStart += 1 - while numpy.all(theMatrix[rowEnd-1,:]==0): rowEnd -= 1 - while numpy.all(theMatrix[:,colEnd-1]==0): colEnd -= 1 + while numpy.all(theMatrix[rowStart, :] == 0): rowStart += 1 + while numpy.all(theMatrix[:, colStart] == 0): colStart += 1 + while numpy.all(theMatrix[rowEnd - 1, :] == 0): rowEnd -= 1 + while numpy.all(theMatrix[:, colEnd - 1] == 0): colEnd -= 1 theMatrix = theMatrix[rowStart:rowEnd, colStart:colEnd] - if verbose: print('after',theMatrix) + if verbose: print('after', theMatrix) - if verbose: print('before',self.matrix.axes[-1].toXML(), self.matrix.axes[-2].toXML()) + if verbose: print('before', self.matrix.axes[-1].toXML(), self.matrix.axes[-2].toXML()) if isinstance(self.matrix.axes[-2].values, linkModule.Link): - assert (rowStart,rowEnd) == (colStart,colEnd) - self.matrix.axes[-1].values.values = self.matrix.axes[-1].values[rowStart:rowEnd+1] + assert (rowStart, rowEnd) == (colStart, colEnd) + self.matrix.axes[-1].values.values = self.matrix.axes[-1].values[rowStart:rowEnd + 1] else: - self.matrix.axes[-1].values.values = self.matrix.axes[-1].values[rowStart:rowEnd+1] - self.matrix.axes[-2].values.values = self.matrix.axes[-2].values[colStart:colEnd+1] + self.matrix.axes[-1].values.values = self.matrix.axes[-1].values[rowStart:rowEnd + 1] + self.matrix.axes[-2].values.values = self.matrix.axes[-2].values[colStart:colEnd + 1] - if verbose: print('after',self.matrix.axes[-1].toXML(), self.matrix.axes[-2].toXML()) + if verbose: print('after', self.matrix.axes[-1].toXML(), self.matrix.axes[-2].toXML()) self.matrix.array = arrayModule.Full(shape=theMatrix.shape, - data=theMatrix[numpy.tri(theMatrix.shape[0])==1.0].tolist(), + data=theMatrix[numpy.tri(theMatrix.shape[0]) == 1.0].tolist(), symmetry=arrayModule.Symmetry.lower)
-
[docs] def getUncertaintyVector( self, theData=None, relative=True ): +
[docs] def getUncertaintyVector(self, theData=None, relative=True): """ Get an XYs1d object containing uncertainty for this matrix. Convert relative/absolute if requested (if so, must also pass central values as theData) @@ -762,37 +768,39 @@

Source code for fudge.covariances.covarianceMatrix

""" if not self.isSymmetric(): raise ValueError("getUncertaintyVector only applies to symmetric matrices!") - energies = list( self.matrix.axes[-1].values ) - diag = numpy.diagonal( self.matrix.array.constructArray() ).copy() - diag[ diag < 0.0 ] = 0.0 - diag = list( numpy.sqrt( diag ) ) - diag.append( diag[-1] ) # point corresponding to final energy bin + energies = list(self.matrix.axes[-1].values) + diag = numpy.diagonal(self.matrix.array.constructArray()).copy() + diag[diag < 0.0] = 0.0 + diag = list(numpy.sqrt(diag)) + diag.append(diag[-1]) # point corresponding to final energy bin yunit = self.matrix.axes[0].unit - if yunit != '': # get square root of the unit - yunit = PQU.PQU(1,yunit).sqrt().getUnitSymbol() - axes_ = axesModule.Axes(2, labelsUnits={1:('energy_in',self.matrix.axes[2].unit), 0:('uncertainty',yunit)} ) - uncert = XYs1dModule.XYs1d( list( zip( energies, copy.deepcopy( diag ) ) ), axes = axes_, interpolation = 'flat' ) - uncert = uncert.changeInterpolation(xDataEnumsModule.Interpolation.linlin,accuracy=1e-3,lowerEps=1e-8,upperEps=1e-8) + if yunit != '': # get square root of the unit + yunit = PQU.PQU(1, yunit).sqrt().getUnitSymbol() + axes_ = axesModule.Axes(2, labelsUnits={1: ('energy_in', self.matrix.axes[2].unit), 0: ('uncertainty', yunit)}) + uncert = XYs1dModule.XYs1d(list(zip(energies, copy.deepcopy(diag))), axes=axes_, interpolation='flat') + uncert = uncert.changeInterpolation(xDataEnumsModule.Interpolation.linlin, accuracy=1e-3, lowerEps=1e-8, + upperEps=1e-8) # do we need to convert absolute->relative or vice versa? - if (relative and self.type == covarianceEnumsModule.Type.absolute) or (not relative and self.type == covarianceEnumsModule.Type.relative): + if (relative and self.type == covarianceEnumsModule.Type.absolute) or ( + not relative and self.type == covarianceEnumsModule.Type.relative): if theData is None: - theData = self.findAttributeInAncestry('rowData').link.toPointwise_withLinearXYs(lowerEps = 1e-8, - upperEps = 1e-8) + theData = self.findAttributeInAncestry('rowData').link.toPointwise_withLinearXYs(lowerEps=1e-8, + upperEps=1e-8) try: - theData = theData.toPointwise_withLinearXYs( lowerEps = 1e-8, upperEps = 1e-8 ) + theData = theData.toPointwise_withLinearXYs(lowerEps=1e-8, upperEps=1e-8) uncert, theData = uncert.mutualify(1e-8, 1e-8, False, theData, 1e-8, 1e-8, False) - if relative: #convert absolute to relative + if relative: # convert absolute to relative uncert /= theData - else: #relative to absolute + else: # relative to absolute uncert *= theData except Exception as err: - print(len( uncert ), uncert.copyDataToXYs()[0], uncert.copyDataToXYs()[-1]) - print(len( theData ), theData.copyDataToXYs()[0], theData.copyDataToXYs()[-1]) - raise Exception( err.message ) + print(len(uncert), uncert.copyDataToXYs()[0], uncert.copyDataToXYs()[-1]) + print(len(theData), theData.copyDataToXYs()[0], theData.copyDataToXYs()[-1]) + raise Exception(err.message) return uncert
- -
[docs] def plot( self, title = None, scalelabel = None, xlim=None, ylim=None, xlog=False, ylog=False ): + +
[docs] def plot(self, title=None, scalelabel=None, xlim=None, ylim=None, xlog=False, ylog=False): """ :param title: @@ -815,52 +823,52 @@

Source code for fudge.covariances.covarianceMatrix

x = self.matrix.axes[2].values y = self.matrix.axes[axis1index].values - X, Y = np.meshgrid( x, y ) - XY = np.hstack((X.ravel()[:,np.newaxis], Y.ravel()[:,np.newaxis])) + X, Y = np.meshgrid(x, y) + XY = np.hstack((X.ravel()[:, np.newaxis], Y.ravel()[:, np.newaxis])) Z = (self.matrix.array.constructArray()).ravel() - - ax = plt.subplot(1,1,1) - if title is None: title = str( self.toXLink() ) + + ax = plt.subplot(1, 1, 1) + if title is None: title = str(self.toXLink()) plt.suptitle(title) qc = QuadMesh( - meshWidth=len(x)-1, - meshHeight=len(y)-1, - coordinates=XY, -# showedges=True, - antialiased=True, + meshWidth=len(x) - 1, + meshHeight=len(y) - 1, + coordinates=XY, + # showedges=True, + antialiased=True, shading='flat', transOffset=ax.transData) - - qc.set_array(Z) - ax.add_collection(qc,autolim=True) + + qc.set_array(Z) + ax.add_collection(qc, autolim=True) if xlim is None: - ax.set_xlim( x[0], x[-1] ) + ax.set_xlim(x[0], x[-1]) else: - ax.set_xlim( xlim[0], xlim[1] ) + ax.set_xlim(xlim[0], xlim[1]) if ylim is None: - ax.set_ylim( y[0], y[-1] ) + ax.set_ylim(y[0], y[-1]) else: - ax.set_ylim( ylim[0], ylim[1] ) + ax.set_ylim(ylim[0], ylim[1]) if xlog: - ax.set_xscale( 'log' ) + ax.set_xscale('log') if ylog: - ax.set_yscale( 'log' ) + ax.set_yscale('log') - xlabel = self.matrix.axes[2].label + ' (' + self.matrix.axes[2].unit +')' - ylabel = self.matrix.axes[axis1index].label + ' (' + self.matrix.axes[axis1index].unit +')' + xlabel = self.matrix.axes[2].label + ' (' + self.matrix.axes[2].unit + ')' + ylabel = self.matrix.axes[axis1index].label + ' (' + self.matrix.axes[axis1index].unit + ')' - ax.set_xlabel( xlabel ) - ax.set_ylabel( ylabel ) + ax.set_xlabel(xlabel) + ax.set_ylabel(ylabel) cbar = plt.colorbar(qc) if scalelabel is not None: cbar.set_label(scalelabel) else: - cbar.set_label(str(self.type)+' covariance ('+str(self.matrix.axes[0].unit)+')') + cbar.set_label(str(self.type) + ' covariance (' + str(self.matrix.axes[0].unit) + ')') plt.show()
-
[docs] def toXML_strList( self, indent = '', **kwargs ) : +
[docs] def toXML_strList(self, indent='', **kwargs): """ :param indent: @@ -868,15 +876,15 @@

Source code for fudge.covariances.covarianceMatrix

:return: """ - indent2 = indent + kwargs.get( 'incrementalIndent', ' ' ) + indent2 = indent + kwargs.get('incrementalIndent', ' ') - xmlString = [ '%s<%s' % ( indent, self.moniker ) ] + xmlString = ['%s<%s' % (indent, self.moniker)] if self.label is not None: xmlString[0] += ' label="%s"' % self.label xmlString[0] += ' type="%s"' % self.type if self.productFrame is not None: xmlString[0] += ' productFrame="%s"' % self.productFrame xmlString[0] += '>' - xmlString += self.matrix.toXML_strList( indent2, **kwargs ) + xmlString += self.matrix.toXML_strList(indent2, **kwargs) xmlString[-1] += '</%s>' % self.moniker return xmlString
@@ -884,10 +892,11 @@

Source code for fudge.covariances.covarianceMatrix

def parseNodeUsingClass(cls, element, xPath, linkData, **kwargs): """Translate <covarianceMatrix> element from xml into python class.""" - xPath.append( element.tag ) + xPath.append(element.tag) matrix_ = griddedModule.Gridded2d.parseNodeUsingClass(element[0], xPath, linkData, **kwargs) - CM = cls(label=element.get('label'), type=element.get('type'), matrix=matrix_, productFrame=element.get('productFrame')) + CM = cls(label=element.get('label'), type=element.get('type'), matrix=matrix_, + productFrame=element.get('productFrame')) xPath.pop() diff --git a/doc/html/_modules/fudge/covariances/covarianceSection.html b/doc/html/_modules/fudge/covariances/covarianceSection.html index 14afbbe8..8a30d41b 100644 --- a/doc/html/_modules/fudge/covariances/covarianceSection.html +++ b/doc/html/_modules/fudge/covariances/covarianceSection.html @@ -62,6 +62,7 @@

Source code for fudge.covariances.covarianceSection

from .mixed import MixedForm from .summed import SummedCovariance +
[docs]class CovarianceSection(suitesModule.Suite): """ A covarianceSuite contains sections, where each section represents either a self-covariance for one quantity, @@ -91,7 +92,7 @@

Source code for fudge.covariances.covarianceSection

:param columnData: xData.link.link pointing to data corresponding to columns of the covariance matrix """ - suitesModule.Suite.__init__( self, [Covariance] ) + suitesModule.Suite.__init__(self, [Covariance]) self.label = label self.rowData = rowData @@ -121,51 +122,55 @@

Source code for fudge.covariances.covarianceSection

except IndexError: return self[0] -
[docs] def check( self, info ): +
[docs] def check(self, info): """ check each section """ from fudge import warning warnings = [] for form in self: - formWarnings = form.check( info ) + formWarnings = form.check(info) if formWarnings: - warnings.append( warning.Context( "Form '%s':" % form.label, formWarnings ) ) + warnings.append(warning.Context("Form '%s':" % form.label, formWarnings)) return warnings
-
[docs] def findInstancesOfClassInChildren(self, cls, level = 9999): +
[docs] def findInstancesOfClassInChildren(self, cls, level=9999): foundInstances = ancestryModule.Ancestry.findInstancesOfClassInChildren(self, cls, level) foundInstances += suitesModule.Suite.findInstancesOfClassInChildren(self, cls, level) return foundInstances
- -
[docs] def fix( self, **kw ): + +
[docs] def fix(self, **kw): """assemble some useful info, to be handed down to children's check() functions""" info = {} warnings = [] - if self.rowData is None: info['rowENDF_MFMT'] = None - else: info['rowENDF_MFMT'] = self.rowData['ENDF_MFMT'] - if self.columnData is None: info['columnENDF_MFMT'] = None - else: info['columnENDF_MFMT'] = self.columnData['ENDF_MFMT'] - info.update( kw ) - for form in self: warnings += form.fix( **info ) + if self.rowData is None: + info['rowENDF_MFMT'] = None + else: + info['rowENDF_MFMT'] = self.rowData['ENDF_MFMT'] + if self.columnData is None: + info['columnENDF_MFMT'] = None + else: + info['columnENDF_MFMT'] = self.columnData['ENDF_MFMT'] + info.update(kw) + for form in self: warnings += form.fix(**info) return warnings
-
[docs] def toXML_strList( self, indent = '', **kwargs ) : +
[docs] def toXML_strList(self, indent='', **kwargs): - indent2 = indent + kwargs.get( 'incrementalIndent', ' ' ) + indent2 = indent + kwargs.get('incrementalIndent', ' ') formatVersion = kwargs.get('formatVersion', GNDS_formatVersionModule.default) moniker = self.monikerByFormat.get(formatVersion, self.moniker) - xmlString = [indent+'<%s label="%s"' % (moniker, self.label)] + xmlString = [indent + '<%s label="%s"' % (moniker, self.label)] if self.crossTerm: xmlString[0] += ' crossTerm="true"' xmlString[0] += '>' - for dataPointer in ('rowData','columnData'): + for dataPointer in ('rowData', 'columnData'): if getattr(self, dataPointer) is not None: - xmlString.append( getattr(self, dataPointer).toXML( indent2, **kwargs ) ) + xmlString.append(getattr(self, dataPointer).toXML(indent2, **kwargs)) for form in self: - xmlString += form.toXML_strList( indent2, **kwargs ) + xmlString += form.toXML_strList(indent2, **kwargs) xmlString[-1] += '</%s>' % moniker return xmlString
@@ -173,22 +178,22 @@

Source code for fudge.covariances.covarianceSection

def parseNodeUsingClass(cls, element, xPath, linkData, **kwargs): """Translate <section> element from xml.""" - xPath.append( '%s[@label="%s"]' % (element.tag, element.get('label') ) ) + xPath.append('%s[@label="%s"]' % (element.tag, element.get('label'))) - linkData['typeConversion'] = {'domainMin':float, 'domainMax':float} + linkData['typeConversion'] = {'domainMin': float, 'domainMax': float} rowData_ = RowData.parseNodeUsingClass(element[0], xPath, linkData, **kwargs) columnData_ = None - if element[1].tag=="columnData": + if element[1].tag == "columnData": columnData_ = ColumnData.parseNodeUsingClass(element[1], xPath, linkData, **kwargs) del linkData['typeConversion'] - section_ = cls( element.get('label'), rowData_, columnData_ ) + section_ = cls(element.get('label'), rowData_, columnData_) start = 2 if (columnData_ is not None) else 1 for form in element[start:]: formClass = { - CovarianceMatrix.moniker: CovarianceMatrix, - MixedForm.moniker: MixedForm, - SummedCovariance.moniker: SummedCovariance, - }.get( form.tag ) + CovarianceMatrix.moniker: CovarianceMatrix, + MixedForm.moniker: MixedForm, + SummedCovariance.moniker: SummedCovariance, + }.get(form.tag) if formClass is None: raise Exception("encountered unknown covariance matrix form '%s'" % form.tag) section_.add(formClass.parseNodeUsingClass(form, xPath, linkData, **kwargs)) @@ -197,12 +202,13 @@

Source code for fudge.covariances.covarianceSection

return section_
-