Skip to content

Commit

Permalink
Merge pull request #7 from fusion-energy/adding_gu
Browse files Browse the repository at this point in the history
Adding a gui
  • Loading branch information
shimwell authored Mar 27, 2023
2 parents 983fd23 + b05cfe9 commit d860ae0
Show file tree
Hide file tree
Showing 10 changed files with 329 additions and 28 deletions.
10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,14 @@ openmc_cylindrical_mesh_plotter is available on PyPi
pip install openmc_cylindrical_mesh_plotter
```

## Usage
## API Usage

See the [examples](https://github.com/fusion-energy/openmc_cylindrical_mesh_plotter/tree/main/examples) folder for example scripts

## Graphical User Interface Usage

```bash
openmc_cylindrical_mesh_plotter
```

![openmc cylinder mesh plot GUI](https://user-images.githubusercontent.com/8583900/228016577-d5d9f541-1b4d-4d9b-a207-f3f1d08e27a8.gif)
2 changes: 1 addition & 1 deletion examples/plot_phir_slice_point_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
theta, r, values = mesh.slice_of_data(
dataset=my_tally_result.mean.flatten(),
slice_index=slice_index,
axis="PhiR",
view_direction="PhiR",
volume_normalization=False,
)

Expand Down
2 changes: 1 addition & 1 deletion examples/plot_phir_slice_ring_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@
theta, r, values = mesh.slice_of_data(
dataset=my_tally_result.mean.flatten(),
slice_index=slice_index,
axis="PhiR",
view_direction="PhiR",
volume_normalization=False,
)

Expand Down
2 changes: 1 addition & 1 deletion examples/plot_rz_slices_point_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
for slice_index in range(1, len(mesh.phi_grid)):
data = mesh.slice_of_data(
dataset=my_tally_result.mean.flatten(),
axis="RZ",
view_direction="RZ",
# dataset=np.array(2*19*49*[1]), flat data for testing
slice_index=slice_index,
volume_normalization=False,
Expand Down
2 changes: 1 addition & 1 deletion examples/plot_rz_slices_ring_source.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@
for slice_index in range(1, len(mesh.phi_grid)):
data = mesh.slice_of_data(
dataset=my_tally_result.mean.flatten(),
axis="RZ",
view_direction="RZ",
# dataset=np.array(2*19*49*[1]), flat data for testing
slice_index=slice_index,
volume_normalization=False,
Expand Down
2 changes: 2 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ dynamic = ["version"]
[tool.setuptools_scm]
write_to = "src/openmc_cylindrical_mesh_plotter/_version.py"

[project.scripts]
openmc_cylindrical_mesh_plotter = "openmc_cylindrical_mesh_plotter.launch:main"

[project.optional-dependencies]
tests = [
Expand Down
218 changes: 218 additions & 0 deletions src/openmc_cylindrical_mesh_plotter/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,218 @@
import openmc
import streamlit as st
from matplotlib.colors import LogNorm
import openmc_cylindrical_mesh_plotter as cmp
import matplotlib.pyplot as plt


def save_uploadedfile(uploadedfile):
with open(uploadedfile.name, "wb") as f:
f.write(uploadedfile.getbuffer())
return st.success(f"Saved File to {uploadedfile.name}")


def header():
"""This section writes out the page header common to all tabs"""

st.set_page_config(
page_title="OpenMC Cylindrical Mesh Plotter",
page_icon="⚛",
layout="wide",
)

hide_streamlit_style = """
<style>
#MainMenu {visibility: hidden;}
footer {
visibility: hidden;
}
</style>
"""
st.markdown(hide_streamlit_style, unsafe_allow_html=True)

st.write(
"""
# OpenMC Cylindrical Mesh Plotter
### ⚛ A plotting user interface for cylindrical meshes.
🐍 Run this app locally with Python ```pip install openmc_cylindrical_mesh_plotter``` then run with ```openmc_cylindrical_mesh_plotter```
⚙ Produce MatPlotLib plots in batch with the 🐍 [Python API](https://github.com/fusion-energy/openmc_cylindrical_mesh_plotter/tree/master/examples)
💾 Raise a feature request, report and issue or make a contribution on [GitHub](https://github.com/fusion-energy/openmc_cylindrical_mesh_plotter)
📧 Email feedback to [email protected]
🔗 This package forms part of a more [comprehensive openmc plot](https://github.com/fusion-energy/openmc_plot) package where geometry, tallies, slices, etc can be plotted and is hosted on [xsplot.com](https://www.xsplot.com/) .
"""
)

st.write("<br>", unsafe_allow_html=True)


def main():
st.write(
"""
👉 Carry out an OpenMC simulation to generate a ```statepoint.h5``` file.
"""
# Not got a h5 file handy, right mouse 🖱️ click and save these links
# [ example 1 ](https://fusion-energy.github.io/openmc_cylindrical_mesh_plotter/examples/csg_tokamak/geometry.xml),
# [ example 2 ](https://fusion-energy.github.io/openmc_cylindrical_mesh_plotter/examples/csg_cylinder_box/geometry.xml)
)

statepoint_file = st.file_uploader("Select your statepoint h5 file", type=["h5"])

if statepoint_file is None:
new_title = '<center><p style="font-family:sans-serif; color:Red; font-size: 30px;">Select your depletion results h5 file</p></center>'
st.markdown(new_title, unsafe_allow_html=True)

else:
save_uploadedfile(statepoint_file)
statepoint = openmc.StatePoint(statepoint_file.name)

tally_description = cmp.get_cylindricalmesh_tallies_and_scores(statepoint)
tally_description_str = [
f"ID={td['id']} score={td['score']} name={td['name']}"
for td in tally_description
]

tally_description_to_plot = st.sidebar.selectbox(
label="Tally to plot", options=tally_description_str, index=0
)
tally_id_to_plot = tally_description_to_plot.split(" ")[0][3:]
tally_score_to_plot = tally_description_to_plot.split(" ")[1][6:]

view_direction = st.sidebar.selectbox(
label="view direction",
options=("PhiR", "RZ"),
index=0,
key="axis",
help="",
)

tally_or_std = st.sidebar.radio(
"Tally mean or std dev", options=["mean", "std_dev"]
)

volume_normalization = st.sidebar.radio(
"Divide value by mesh voxel volume", options=[True, False]
)

value_multiple = st.sidebar.number_input(
"Multiplier value",
value=1.0,
help="Input a number that will be used to scale the mesh values. For example a input of 2 would double all the values.",
)

my_tally = statepoint.get_tally(id=int(tally_id_to_plot))
score = my_tally.get_values(
scores=[tally_score_to_plot], value=tally_or_std
).flatten()
mesh = my_tally.find_filter(filter_type=openmc.MeshFilter).mesh
extent = mesh.get_mpl_plot_extent(view_direction=view_direction)

slice_index = st.sidebar.slider(
label="slice index",
min_value=1,
value=1,
max_value=mesh.get_number_of_slices(view_direction=view_direction),
)

contour_levels_str = st.sidebar.text_input(
"Contour levels",
help="Optionally add some comma deliminated contour values",
)

if contour_levels_str:
contour_levels = sorted(
[float(v) for v in contour_levels_str.strip().split(",")]
)
else:
contour_levels = None

if tally_or_std == "mean":
cbar_label = tally_score_to_plot
else: # 'std dev'
cbar_label = f"standard deviation {tally_score_to_plot}"

title = st.sidebar.text_input(
"Colorbar title",
help="Optionally set your own colorbar label for the plot",
value=cbar_label,
)

log_lin_scale = st.sidebar.radio("Scale", options=["log", "linear"])
if log_lin_scale == "linear":
norm = None
else:
norm = LogNorm()

xlabel, ylabel = mesh.get_axis_labels(view_direction=view_direction)

if view_direction == "RZ":
image_slice = mesh.slice_of_data(
dataset=score, # ,
view_direction=view_direction,
slice_index=slice_index,
volume_normalization=volume_normalization,
)
image_slice = image_slice * value_multiple

axes = plt.subplot(1, 1, 1)
(xlabel, ylabel) = mesh.get_axis_labels(view_direction=view_direction)

axes.set_xlabel(xlabel)
axes.set_ylabel(ylabel)
im = axes.imshow(X=image_slice, extent=extent, norm=norm)

if contour_levels_str:
axes.contour(
image_slice,
levels=contour_levels,
colors="black",
linewidths=1,
extent=extent,
)
else:
extent = None # not yet figured out
theta, r, values = mesh.slice_of_data(
dataset=score, # ,
view_direction=view_direction,
slice_index=slice_index,
volume_normalization=volume_normalization,
)
values = values * value_multiple
fig, axes = plt.subplots(subplot_kw=dict(projection="polar"))
im = axes.contourf(
theta, r, values, extent=extent, norm=norm
) # , locator=ticker.LogLocator())

if contour_levels_str:
axes.contour(
theta,
r,
values,
levels=contour_levels,
colors="darkgrey",
linewidths=1,
extent=extent,
)

plt.colorbar(im, label=title, ax=axes)

plt.savefig("openmc_plot_cylindricalmesh_image.png")
with open("openmc_plot_cylindricalmesh_image.png", "rb") as file:
st.download_button(
label="Download image",
data=file,
file_name="openmc_plot_cylindricalmesh_image.png",
mime="image/png",
)
st.pyplot(plt)


if __name__ == "__main__":
header()
main()
Loading

0 comments on commit d860ae0

Please sign in to comment.