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

Making streamlit web app #20

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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
28 changes: 28 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
# A Docker image for hosting the cad_to_dagmc web app at https://www.xsplot.com

# build with
# docker build -t cad_to_dagmc .

# run with
# docker run --network host -t cad_to_dagmc

# maintained at https://github.com/fusion_energy/cad_to_dagmc.com/

FROM continuumio/miniconda3:4.12.0

RUN conda install -c conda-forge openmc

COPY src/*.py .
COPY pyproject.toml .

RUN pip install .[gui]

ENV PORT 8501

EXPOSE 8501


# solves bug of streamlit not running in container
# https://github.com/streamlit/streamlit/issues/4842
ENTRYPOINT [ "streamlit", "run" ]
CMD [ "app.py", "--server.headless", "true", "--server.fileWatcherType", "none", "--browser.gatherUsageStats", "false"]
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ mamba install -c fusion-energy -c cadquery -c conda-forge cad_to_dagmc
# Install (Conda + pip)

You will need to install some dependencies that are not available via PyPi.
This example uses mamba but conda could also be used.
```bash
conda install -c conda-forge mamba
mamba install -c conda-forge moab
mamba install -c conda-forge gmsh
mamba install -c conda-forge python-gmsh
mamba install -c cadquery -c conda-forge cadquery=master
```

Expand All @@ -62,6 +65,12 @@ Then you can install the cad_to_dagmc package with ```pip```
pip install cad_to_dagmc
```

To include the Graphical User Interface add the gui option to the install

```bash
pip install cad_to_dagmc[gui]
```

# Usage

To use the h5m geometry you will need a transport code with DAGMC enabled such as OpenMC.
Expand Down
6 changes: 6 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,16 @@ tests = [
"dagmc_h5m_file_inspector",
"openmc_data_downloader"
]
gui = [
"streamlit"
]

[project.urls]
"Homepage" = "https://github.com/fusion-energy/cad_to_dagmc"
"Bug Tracker" = "https://github.com/fusion-energy/cad_to_dagmc/issues"

[tool.setuptools]
package-dir = {"" = "src"}

[project.scripts]
cad_to_dagmc = "cad_to_dagmc.launch:main"
131 changes: 131 additions & 0 deletions src/cad_to_dagmc/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,131 @@
from pathlib import Path
from cadquery import importers
import streamlit as st
import cadquery as cq

from cad_to_dagmc import CadToDagmc


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 Geometry Plot",
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(
"""
# CAD to DAGMC

### ⚛ A geometry conversion tool.

🐍 Run this app locally with Python ```pip install cad_to_dagmc[gui]``` then run with ```cad_to_dagmc```

⚙ Produce DAGMC files in batch with the 🐍 [Python API](https://github.com/fusion-energy/cad_to_dagmc/tree/main/examples)

💾 Raise a feature request, report and issue or make a contribution on [GitHub](https://github.com/fusion-energy/cad_to_dagmc)

📧 Email feedback to mail@jshimwell.com

🔗 You might be interested in the related package [dagmc_geometry_slice_plotter](https://github.com/fusion-energy/dagmc_geometry_slice_plotter).
"""
)
st.write("<br>", unsafe_allow_html=True)


def main():

header()

st.write(
"""
👉 Create your CAD geometry, export to a STP file file and upload the STP file here.
"""
)
geometry_stp_file = st.file_uploader(
"Upload your CAD files (stp file format)", type=["stp", "step"]
)

if geometry_stp_file == None:
new_title = '<p style="font-family:sans-serif; color:Red; font-size: 30px;">Upload your STP file</p>'
st.markdown(new_title, unsafe_allow_html=True)

# TODO find a nice stp file and url
# st.markdown(
# 'Not got STP files handy? Download an example [](https://raw.githubusercontent.com/fusion-energy/openmc_plot/main/examples/tokamak/geometry.xml "download")'
# )

else:

save_uploadedfile(geometry_stp_file)

part = importers.importStep(geometry_stp_file.name).val()

if isinstance(part, cq.assembly.Assembly):
print("assembly found")
part = part.toCompound()

if isinstance(part, (cq.occ_impl.shapes.Compound, cq.occ_impl.shapes.Solid)):
iterable_solids = part.Solids()
else:
iterable_solids = part.val().Solids()

print(iterable_solids)
mat_tags = []
for i, solid in enumerate(iterable_solids):
mat_tag = st.text_input(
label=f"material tag for volume {i}",
key=f"mat_tags_{i}",
value=f"mat_{i}",
)
mat_tags.append(mat_tag)

print(mat_tags)

if st.button("Generate DAGMC h5m file"):

my_model = CadToDagmc()

for mat_tag, solid in zip(mat_tags, iterable_solids):
print(solid, mat_tag)
my_model.add_cadquery_object(solid, material_tags=[mat_tag])

my_model.export_dagmc_h5m_file()

with open("dagmc.h5m", "rb") as f:
st.download_button("Download DAGMC h5m file", f, file_name="dagmc.h5m")

# with open(geometry_stp_file.name, "rb") as file:

# my_model = CadToDagmc()
# the d and c from the word dagmc would be tagged with one material and the agm are tagged with another material
# my_model.add_cadquery_object(part, material_tags=mat_tags)
# my_model.export_dagmc_h5m_file()
# st.download_button(
# label="Download DAGMC h5m file",
# data=file,
# file_name="dagmc.h5m",
# mime=None,
# )


if __name__ == "__main__":
main()
32 changes: 24 additions & 8 deletions src/cad_to_dagmc/core.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
from tempfile import mkstemp

from typing import Iterable
import typing
from cadquery import importers
from cadquery import Assembly
from OCP.GCPnts import GCPnts_QuasiUniformDeflection
Expand All @@ -22,7 +22,10 @@ def __init__(self):
self.material_tags = []

def add_stp_file(
self, filename: str, material_tags: Iterable[str], scale_factor: float = 1.0
self,
filename: str,
material_tags: typing.Iterable[str],
scale_factor: float = 1.0,
):
"""Loads the parts from stp file into the model keeping track of the
parts and their material tags.
Expand All @@ -45,11 +48,24 @@ def add_stp_file(
scaled_part = part
else:
scaled_part = part.scale(scale_factor)
self.add_cadquery_object(scaled_part, material_tags)
self.add_cadquery_object(object=scaled_part, material_tags=material_tags)

def add_cadquery_object(self, object, material_tags):
def add_cadquery_object(
self,
object: typing.Union[
cq.assembly.Assembly, cq.occ_impl.shapes.Compound, cq.occ_impl.shapes.Solid
],
material_tags: typing.Iterable[str],
):
"""Loads the parts from CadQuery object into the model keeping track of
the parts and their material tags.

Args:
object: the cadquery object to convert
material_tags: the names of the DAGMC material tags to assign.
These will need to be in the same order as the volumes in the
STP file and match the material tags used in the neutronics
code (e.g. OpenMC).
"""

if isinstance(object, cq.assembly.Assembly):
Expand All @@ -71,10 +87,10 @@ def add_cadquery_object(self, object, material_tags):

def export_dagmc_h5m_file(
self,
filename="dagmc.h5m",
min_mesh_size=1,
max_mesh_size=10,
verbose=False,
filename: str = "dagmc.h5m",
min_mesh_size: float = 1,
max_mesh_size: float = 10,
verbose: bool = False,
):

volume_atol: float = 0.000001
Expand Down
16 changes: 16 additions & 0 deletions src/cad_to_dagmc/launch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import runpy
import sys
import cad_to_dagmc
from pathlib import Path


def main():

path_to_app = str(Path(cad_to_dagmc.__path__[0]) / "app.py")

sys.argv = ["streamlit", "run", path_to_app]
runpy.run_module("streamlit", run_name="__main__")


if __name__ == "__main__":
main()