Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/makefile.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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: |
Expand Down
9 changes: 7 additions & 2 deletions .github/workflows/python-app.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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 }}
Expand All @@ -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

2 changes: 1 addition & 1 deletion Merced/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
# SPDX-License-Identifier: BSD-3-Clause
# <<END-copyright>>

subDirs = Doc Src TestSuite bin
subDirs = Doc MonteCarlo Src TestSuite bin

.PHONY: default bin clean realclean check doc doSubDirs prefixDeploy

Expand Down
28 changes: 22 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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:

Expand All @@ -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 <http://www.support.tabs3.com/main/R10463.htm>)

### 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
Expand Down
2 changes: 1 addition & 1 deletion bin/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
2 changes: 1 addition & 1 deletion bin/buildMapFile.py
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
10 changes: 8 additions & 2 deletions bin/crossSections.py
Original file line number Diff line number Diff line change
Expand Up @@ -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.'''

Expand Down Expand Up @@ -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)
Expand All @@ -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
Expand Down Expand Up @@ -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:
Expand Down
22 changes: 11 additions & 11 deletions bin/cullProcessedData.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 7 additions & 2 deletions bin/energyBalance.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down Expand Up @@ -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:
Expand Down
19 changes: 15 additions & 4 deletions bin/peek.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.')
Expand Down Expand Up @@ -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)])
Expand All @@ -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)

Expand Down Expand Up @@ -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
16 changes: 1 addition & 15 deletions bin/processProtare.py
Original file line number Diff line number Diff line change
Expand Up @@ -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):
Expand Down
42 changes: 15 additions & 27 deletions brownies/BNL/plot_evaluation/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -310,12 +310,6 @@ def getEXFORSets(sym, A, metastable, reaction=None, quantity="SIG", nox4evals=Tr
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 = ""
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -1298,8 +1286,8 @@ def makeAngDistMubarPlot(gndsMap={}, xyData={}, xydyData={}, xdxydyData={},
xdxydyData=xdxydyData,
plotStyle=plotStyle,
suggestTitle=getSuggestTitle(target, projectile, reactionName, mt),
suggestXLog=(mt in [1, 2, 18, 102] + range(501, 574)),
suggestYLog=(mt in [1, 2, 18, 102] + range(501, 574)),
suggestXLog=(mt in [1, 2, 18, 102] + list(range(501, 574))),
suggestYLog=(mt in [1, 2, 18, 102] + list(range(501, 574))),
suggestFrame=suggestFrame,
figsize=figsize,
useBokeh=useBokeh)
Expand Down
2 changes: 1 addition & 1 deletion brownies/BNL/restools/resonance_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ def getFakeResonanceSet(
:param L: orbital angular momentum
:param J: total angular momentum
:param levelDensity: dictionary containing L/J-specific energy-dependent level densities
:param aveWidthFuncs': dictionary containing L/J-specific energy-dependent widths
:param aveWidthFuncs: dictionary containing L/J-specific energy-dependent widths
:param DOFs: Chi-square degrees of freedom for each reaction channel, used for drawing resonance widths.
:param widthKeys: column headers for resulting Table
:param domainMin: lower bound for generating resonances, usually equal to lower bound for level densities / widths
Expand Down
4 changes: 2 additions & 2 deletions brownies/bin/endf2gnds.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
3 changes: 3 additions & 0 deletions brownies/bin/plot_covariance.py
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Loading
Loading