Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Hot fix - tud fng issue #290

Merged
merged 4 commits into from
Jun 5, 2024
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
182 changes: 86 additions & 96 deletions jade/expoutput.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
# You should have received a copy of the GNU General Public License
# along with JADE. If not, see <http://www.gnu.org/licenses/>.

from __future__ import annotations
import math
import os
import re
Expand Down Expand Up @@ -168,89 +169,84 @@ def build_atlas(self):
# Remove tmp images
shutil.rmtree(tmp_path)

def _extract_outputs(self):
def _extract_single_output(
self, results_path: os.PathLike, folder: str, lib: str
) -> tuple[pd.DataFrame, str]:
mfile, ofile = self._get_output_files(results_path)
# Parse output
output = MCNPoutput(mfile, ofile)

# need to extract the input in case of multi
if self.multiplerun:
pieces = folder.split("_")
input = pieces[-1]
if input not in self.inputs:
self.inputs.append(input)
self.outputs[input, lib] = output
# Get the meaningful results
self.results[input, lib] = self._processMCNPdata(output)
else:
# just treat it as a special case of multiple run
self.outputs[self.testname, lib] = output
# Get the meaningful results
self.results[self.testname, lib] = self._processMCNPdata(output)
input = self.testname

return output.tallydata, input

def _extract_outputs(self) -> None:
"""
Extract, organize and store the results coming from the MCNP runs
Extract, organize and store the results coming from the different codes
runs

Returns
-------
None.
"""
outputs = {}
results = {}
inputs = []
self.outputs = {}
self.results = {}

# Each output object is processing only one code at the time at the moment
if self.mcnp:
code_tag = "mcnp"
if self.openmc:
print("Experimental comparison not implemented for OpenMC")
return
if self.serpent:
print("Experimental comparison not implemented for Serpent")
return
if self.d1s:
code_tag = "d1s"

# only multiple runs have multiple inputs
if self.multiplerun:
self.inputs = []
else:
self.inputs = [self.testname]

# Iterate on the different libraries results except 'Exp'
for lib, test_path in self.test_path.items():
if lib != EXP_TAG:
if self.multiplerun:
# Results are organized by folder and lib
code_raw_data = {}
for folder in os.listdir(test_path):
# FIX MCNP HARD CODED PATH HERE
if self.mcnp:
results_path = os.path.join(test_path, folder, "mcnp")
pieces = folder.split("_")
# Get zaid
input = pieces[-1]
mfile, ofile = self._get_output_files(results_path)
# Parse output
output = MCNPoutput(mfile, ofile)
outputs[input, lib] = output
code_raw_data[input, lib] = output.tallydata
# self.raw_data[input, lib] = output.tallydata

# Get the meaningful results
results[input, lib] = self._processMCNPdata(output)
if input not in inputs:
inputs.append(input)
if self.openmc:
print(
"Experimental comparison not implemented \
for OpenMC"
)
break
if self.serpent:
print(
"Experimental comparison not implemented \
for Serpent"
)
break
if self.d1s:
results_path = os.path.join(test_path, folder, "d1s")
pieces = folder.split("_")
# Get zaid
input = pieces[-1]
mfile, ofile = self._get_output_files(results_path)
# Parse output
output = MCNPoutput(mfile, ofile)
outputs[input, lib] = output
code_raw_data[input, lib] = output.tallydata
# self.raw_data[input, lib] = output.tallydata

# Get the meaningful results
results[input, lib] = self._processMCNPdata(output)
if input not in inputs:
inputs.append(input)
if self.mcnp:
self.raw_data["mcnp"].update(code_raw_data)
if self.d1s:
self.raw_data["d1s"].update(code_raw_data)
results_path = os.path.join(test_path, folder, code_tag)
tallydata, input = self._extract_single_output(
results_path, folder, lib
)
code_raw_data[input, lib] = tallydata

# Results are organized just by lib
else:
mfile, ofile = self._get_output_files(test_path)
# Parse output
output = MCNPoutput(mfile, ofile)
outputs[self.testname, lib] = output
# Adjourn raw Data
self.raw_data[self.testname, lib] = output.tallydata
# Get the meaningful results
results[self.testname, lib] = self._processMCNPdata(output)

self.outputs = outputs
self.results = results
if inputs:
self.inputs = inputs
else:
self.inputs = [self.testname]
results_path = os.path.join(test_path, code_tag)
tallydata, input = self._extract_single_output(
results_path, None, lib
)
code_raw_data = {(self.testname, lib): tallydata}

# Adjourn raw Data
self.raw_data[code_tag].update(code_raw_data)

def _read_exp_results(self):
"""
Expand Down Expand Up @@ -483,9 +479,7 @@ def _pp_excel_comparison(self):
Responsible for producing excel outputs
"""
# Dump the global C/E table
ex_outpath = os.path.join(
self.excel_path, self.testname + "_CE_tables.xlsx"
)
ex_outpath = os.path.join(self.excel_path, self.testname + "_CE_tables.xlsx")
# Create a Pandas Excel writer using XlsxWriter as the engine.
with pd.ExcelWriter(ex_outpath, engine="xlsxwriter") as writer:
# --- build and dump the C/E table ---
Expand Down Expand Up @@ -673,7 +667,7 @@ def _read_exp_file(self, filepath):
filepath : str
string containing the path to the experimental file to be read
for comparison

"""
return pd.read_csv(filepath, sep=";")

Expand All @@ -684,7 +678,7 @@ def _build_atlas(self, tmp_path, atlas):
"""
Fill the atlas with the customized plots. Creation and saving of the
atlas are handled elsewhere.

Parameters
----------
tmp_path : str
Expand Down Expand Up @@ -753,7 +747,7 @@ def _get_tally_info(self, tally):
tallynum (int): Tally number of the tally being plotted
particle (str): Type of quantity being plotted on the X axis
quant + unit (str): Unit of quantity being plotted on the X axis

"""
tallynum = tally.tallyNumber
particle = tally.particleList[np.where(tally.tallyParticles == 1)[0][0]]
Expand Down Expand Up @@ -786,7 +780,7 @@ def _define_title(self, input, quantity_CE):

def _dump_ce_table(self):
"""
Generates the C/E table and dumps them as an .xlsx file
Generates the C/E table and dumps them as an .xlsx file
"""
final_table = pd.concat(self.tables)
skipcol_global = 0
Expand Down Expand Up @@ -998,7 +992,7 @@ def _parse_data_df(self, data, output, x_axis, tallynum):
x_axis : str
X axis title
tallynum : int
Tally number, used to determine behaviour for protons and
Tally number, used to determine behaviour for protons and
neutrons

Returns
Expand Down Expand Up @@ -1172,7 +1166,7 @@ def _exp_comp_case_check(self, indexes):

def _get_conv_df(self, df):
"""
Adds extra columns to the dataframe containing the maximum and
Adds extra columns to the dataframe containing the maximum and
average errors of the tallies

Parameters
Expand All @@ -1184,9 +1178,9 @@ def _get_conv_df(self, df):
Returns
-------
conv_df: Dataframe
Same as previous dataframe, but with two extra columns containing
Same as previous dataframe, but with two extra columns containing
maximum and average errors

"""
conv_df = pd.DataFrame()
for library in df.index.unique(level="Library").tolist():
Expand All @@ -1203,7 +1197,7 @@ class TiaraFCOutput(TiaraOutput):

def _pp_excel_comparison(self):
"""
Builds dataframe from computational output comparable to experimental
Builds dataframe from computational output comparable to experimental
data and generates the excel comparison
"""

Expand Down Expand Up @@ -1247,9 +1241,7 @@ def _pp_excel_comparison(self):
self._exp_comp_case_check(indexes=indexes)
self.case_tree_df.sort_values(indexes, axis=0, inplace=True)
# Build ExcelWriter object
filepath = os.path.join(
self.excel_path, "Tiara_Fission_Cells_CE_tables.xlsx"
)
filepath = os.path.join(self.excel_path, "Tiara_Fission_Cells_CE_tables.xlsx")
with pd.ExcelWriter(filepath, engine="xlsxwriter") as writer:

# Create 1 worksheet for each energy/material combination
Expand Down Expand Up @@ -1391,7 +1383,7 @@ def _build_atlas(self, tmp_path, atlas):
"""
Fill the atlas with the customized plots. Creation and saving of the
atlas are handled elsewhere.

Parameters
----------
tmp_path : str
Expand Down Expand Up @@ -1549,9 +1541,7 @@ def _pp_excel_comparison(self):
indexes = ["Library", "Shield Material", "Energy", "Shield Thickness"]
self._exp_comp_case_check(indexes=indexes)
# Create ExcelWriter object
filepath = os.path.join(
self.excel_path, "Tiara_Bonner_Spheres_CE_tables.xlsx"
)
filepath = os.path.join(self.excel_path, "Tiara_Bonner_Spheres_CE_tables.xlsx")
with pd.ExcelWriter(filepath, engine="xlsxwriter") as writer:
# Loop over shield material/energy combinations
mat_list = self.case_tree_df.index.unique(level="Shield Material").tolist()
Expand Down Expand Up @@ -1662,7 +1652,7 @@ def _build_atlas(self, tmp_path, atlas):
"""
Fill the atlas with the customized plots. Creation and saving of the
atlas are handled elsewhere.

Parameters
----------
tmp_path : str
Expand Down Expand Up @@ -1822,7 +1812,7 @@ def _build_atlas(self, tmp_path, atlas):
"""
Fill the atlas with the customized plots. Creation and saving of the
atlas are handled elsewhere.

Parameters
----------
tmp_path : str
Expand Down Expand Up @@ -1922,7 +1912,7 @@ def _build_atlas(self, tmp_path, atlas):
"""
Fill the atlas with the customized plots. Creation and saving of the
atlas are handled elsewhere.

Parameters
----------
tmp_path : str
Expand All @@ -1944,14 +1934,14 @@ def _build_atlas(self, tmp_path, atlas):
return atlas

def _plot_tally_group(self, group, tmp_path, atlas):
"""
Plots tallies for a given group of outputs and add to Atlas object
"""
Plots tallies for a given group of outputs and add to Atlas object

Parameters
----------
group : list
list of groups in the experimental benchmark object, outputs are
grouped by material, several tallies for each material/group
list of groups in the experimental benchmark object, outputs are
grouped by material, several tallies for each material/group
tmp_path : str
path to temporary atlas plot folder
atlas : JADE Atlas
Expand All @@ -1960,7 +1950,7 @@ def _plot_tally_group(self, group, tmp_path, atlas):
Returns
-------
atlas : JADE Atlas
adjusted Atlas object
adjusted Atlas object
"""
# Extract 'Tally' and 'Input' values for the current 'Group'
group_data = self.groups.xs(group, level="Group", drop_level=False)
Expand Down
6 changes: 6 additions & 0 deletions jade/output.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,8 +329,14 @@ def single_postprocess(self):
except KeyError:
# this means that the column is only one and we have
# two distinct DFs for values and errors
# depending on pandas version, these may be series or
# directly arrays
values = vals_df["Value"]
error = err_df["Error"]
if isinstance(values, pd.Series) or isinstance(values, pd.DataFrame):
values = values.values
if isinstance(error, pd.Series) or isinstance(error, pd.DataFrame):
error = error.values

lib_name = self.session.conf.get_lib_name(self.lib)
lib = {"x": x, "y": values, "err": error, "ylabel": lib_name}
Expand Down