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
1 change: 0 additions & 1 deletion openmc_plotter/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@

__version__ = '0.3.1'
18 changes: 8 additions & 10 deletions openmc_plotter/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
#!/usr/bin/env python

from argparse import ArgumentParser
from pathlib import Path
from threading import Thread
Expand All @@ -13,28 +11,28 @@
from . import __version__
from .main_window import MainWindow, _openmcReload


def main():
ap = ArgumentParser(description='OpenMC Plotter GUI')
version_str = f'OpenMC Plotter Version: {__version__}'
ap.add_argument('-v', '--version', action='version', version=version_str,
help='Display version info.')
ap.add_argument('-d', '--model-directory', default=os.curdir,
help='Location of model dir (default is current dir)')
ap.add_argument('-e','--ignore-settings', action='store_false',
help='Ignore plot_settings.pkl file if present.')
ap.add_argument('-s', '--threads', type=int, default=None,
help='If present, number of threads used to generate plots.')
ap.add_argument('model_path', nargs='?', default=os.curdir,
help='Location of model XML file or a directory containing '
'XML files (default is current dir)')

args = ap.parse_args()

os.chdir(args.model_directory)

run_app(args)


def run_app(user_args):
path_icon = str(Path(__file__).parent / 'assets/openmc_logo.png')
path_splash = str(Path(__file__).parent / 'assets/splash.png')
path_icon = str(Path(__file__).parent / 'assets' / 'openmc_logo.png')
path_splash = str(Path(__file__).parent / 'assets' / 'splash.png')

app = QApplication(sys.argv)
app.setOrganizationName("OpenMC")
Expand All @@ -53,7 +51,7 @@ def run_app(user_args):
QtCore.Qt.AlignHCenter | QtCore.Qt.AlignBottom)
app.processEvents()
# load OpenMC model on another thread
openmc_args = {'threads': user_args.threads}
openmc_args = {'threads': user_args.threads, 'model_path': user_args.model_path}
loader_thread = Thread(target=_openmcReload, kwargs=openmc_args)
loader_thread.start()
# while thread is working, process app events
Expand All @@ -67,7 +65,7 @@ def run_app(user_args):

font_metric = QtGui.QFontMetrics(app.font())
screen_size = app.primaryScreen().size()
mainWindow = MainWindow(font_metric, screen_size)
mainWindow = MainWindow(font_metric, screen_size, user_args.model_path)
# connect splashscreen to main window, close when main window opens
mainWindow.loadGui(use_settings_pkl=user_args.ignore_settings)
mainWindow.show()
Expand Down
4 changes: 2 additions & 2 deletions openmc_plotter/docks.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,9 +678,9 @@ def update(self):
self.tallySelector.addItem("None")
for idx, tally in enumerate(self.model.statepoint.tallies.values()):
if tally.name == "":
self.tallySelector.addItem('Tally {}'.format(tally.id), userData=tally.id)
self.tallySelector.addItem(f'Tally {tally.id}', userData=tally.id)
else:
self.tallySelector.addItem('Tally {} "{}"'.format(tally.id, tally.name), userData=tally.id)
self.tallySelector.addItem(f'Tally {tally.id} "{tally.name}"', userData=tally.id)
self.tally_map[idx] = tally
self.updateSelectedTally()
self.updateMinMax()
Expand Down
28 changes: 17 additions & 11 deletions openmc_plotter/main_window.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import copy
from functools import partial
import os
from pathlib import Path
import pickle
from threading import Thread

Expand All @@ -20,15 +20,14 @@
except ImportError:
_HAVE_VTK = False

from .plotmodel import PlotModel, DomainTableModel, hash_file
from .plotmodel import PlotModel, DomainTableModel, hash_model
from .plotgui import PlotImage, ColorDialog
from .docks import DomainDock, TallyDock
from .overlays import ShortcutsOverlay
from .tools import ExportDataDialog

_COORD_LEVELS = 0

def _openmcReload(threads=None):
def _openmcReload(threads=None, model_path='.'):
# reset OpenMC memory, instances
openmc.lib.reset()
openmc.lib.finalize()
Expand All @@ -37,18 +36,22 @@ def _openmcReload(threads=None):
args = ["-c"]
if threads is not None:
args += ["-s", str(threads)]
args.append(model_path)
openmc.lib.init(args)
openmc.lib.settings.verbosity = 1


class MainWindow(QMainWindow):
def __init__(self,
font=QtGui.QFontMetrics(QtGui.QFont()),
screen_size=QtCore.QSize()):
screen_size=QtCore.QSize(),
model_path='.'):
super().__init__()

self.screen = screen_size
self.font_metric = font
self.setWindowTitle('OpenMC Plot Explorer')
self.model_path = Path(model_path)

def loadGui(self, use_settings_pkl=True):

Expand Down Expand Up @@ -451,7 +454,7 @@ def loadModel(self, reload=False, use_settings_pkl=True):
if reload:
self.resetModels()
else:
self.model = PlotModel(use_settings_pkl)
self.model = PlotModel(use_settings_pkl, self.model_path)

# update plot and model settings
self.updateRelativeBases()
Expand Down Expand Up @@ -1151,11 +1154,10 @@ def closeEvent(self, event):

def saveSettings(self):
if self.model.statepoint:
self.model.statepoint.close()
self.model.statepoint.close()

# get hashes for geometry.xml and material.xml at close
mat_xml_hash = hash_file('materials.xml')
geom_xml_hash = hash_file('geometry.xml')
# get hashes for material.xml and geometry.xml at close
mat_xml_hash, geom_xml_hash = hash_model(self.model_path)

pickle_data = {
'version': self.model.version,
Expand All @@ -1164,7 +1166,11 @@ def saveSettings(self):
'mat_xml_hash': mat_xml_hash,
'geom_xml_hash': geom_xml_hash
}
with open('plot_settings.pkl', 'wb') as file:
if self.model_path.is_file():
settings_pkl = self.model_path.with_name('plot_settings.pkl')
else:
settings_pkl = self.model_path / 'plot_settings.pkl'
with settings_pkl.open('wb') as file:
pickle.dump(pickle_data, file)

def exportTallyData(self):
Expand Down
125 changes: 73 additions & 52 deletions openmc_plotter/plotmodel.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
from ast import literal_eval
from collections import defaultdict
import copy
import hashlib
import itertools
import threading
import os
from pathlib import Path
import pickle
import hashlib
import threading

from PySide2.QtWidgets import QItemDelegate, QColorDialog, QLineEdit, QMessageBox
from PySide2.QtCore import QAbstractTableModel, QModelIndex, Qt, QSize, QEvent
Expand All @@ -18,7 +19,7 @@
from .statepointmodel import StatePointModel
from .plot_colors import random_rgb, reset_seed

ID, NAME, COLOR, COLORLABEL, MASK, HIGHLIGHT = tuple(range(0, 6))
ID, NAME, COLOR, COLORLABEL, MASK, HIGHLIGHT = range(6)

_VOID_REGION = -1
_NOT_FOUND = -2
Expand All @@ -28,7 +29,6 @@
_PROPERTY_INDICES = {'temperature': 0, 'density': 1}

_REACTION_UNITS = 'Reactions per Source Particle'
_FLUX_UNITS = 'Particle-cm per Source Particle'
_PRODUCTION_UNITS = 'Particles Produced per Source Particle'
_ENERGY_UNITS = 'eV per Source Particle'

Expand Down Expand Up @@ -60,10 +60,11 @@
'Std. Dev.': 'std_dev',
'Rel. Error': 'rel_err'}

def hash_file(filename):

def hash_file(path):
# return the md5 hash of a file
h = hashlib.md5()
with open(filename,'rb') as file:
with path.open('rb') as file:
chunk = 0
while chunk != b'':
# read 32768 bytes at a time
Expand All @@ -72,50 +73,66 @@ def hash_file(filename):
return h.hexdigest()


class PlotModel():
""" Geometry and plot settings for OpenMC Plot Explorer model
def hash_model(model_path):
"""Get hash values for materials.xml and geometry.xml (or model.xml)"""
if model_path.is_file():
mat_xml_hash = hash_file(model_path)
geom_xml_hash = ""
elif (model_path / 'model.xml').exists():
mat_xml_hash = hash_file(model_path / 'model.xml')
geom_xml_hash = ""
else:
mat_xml_hash = hash_file(model_path / 'materials.xml')
geom_xml_hash = hash_file(model_path / 'geometry.xml')
return mat_xml_hash, geom_xml_hash

Parameters
----------
use_settings_pkl : bool
If True, use plot_settings.pkl file to reload settings

Attributes
----------
geom : openmc.Geometry instance
OpenMC Geometry of the model
modelCells : collections.OrderedDict
Dictionary mapping cell IDs to openmc.Cell instances
modelMaterials : collections.OrderedDict
Dictionary mapping material IDs to openmc.Material instances
ids : NumPy int array (v_res, h_res, 1)
Mapping of plot coordinates to cell/material ID by pixel
ids_map : NumPy int32 array (v_res, h_res, 3)
Mapping of cell and material ids
properties : Numpy float array (v_res, h_res, 3)
Mapping of cell temperatures and material densities
image : NumPy int array (v_res, h_res, 3)
The current RGB image data
statepoint : StatePointModel
Simulation data model used to display tally results
applied_filters : tuple of ints
IDs of the applied filters for the displayed tally
previousViews : list of PlotView instances
List of previously created plot view settings used to undo
changes made in plot explorer
subsequentViews : list of PlotView instances
List of undone plot view settings used to redo changes made
in plot explorer
defaultView : PlotView instance
Default settings for given geometry
currentView : PlotView instance
Currently displayed plot settings in plot explorer
activeView : PlotView instance
Active state of settings in plot explorer, which may or may not
have unapplied changes
class PlotModel:
"""Geometry and plot settings for OpenMC Plot Explorer model

Parameters
----------
use_settings_pkl : bool
If True, use plot_settings.pkl file to reload settings
model_path : pathlib.Path
Path to model XML file or directory

Attributes
----------
geom : openmc.Geometry
OpenMC Geometry of the model
modelCells : collections.OrderedDict
Dictionary mapping cell IDs to openmc.Cell instances
modelMaterials : collections.OrderedDict
Dictionary mapping material IDs to openmc.Material instances
ids : NumPy int array (v_res, h_res, 1)
Mapping of plot coordinates to cell/material ID by pixel
ids_map : NumPy int32 array (v_res, h_res, 3)
Mapping of cell and material ids
properties : Numpy float array (v_res, h_res, 3)
Mapping of cell temperatures and material densities
image : NumPy int array (v_res, h_res, 3)
The current RGB image data
statepoint : StatePointModel
Simulation data model used to display tally results
applied_filters : tuple of ints
IDs of the applied filters for the displayed tally
previousViews : list of PlotView instances
List of previously created plot view settings used to undo
changes made in plot explorer
subsequentViews : list of PlotView instances
List of undone plot view settings used to redo changes made
in plot explorer
defaultView : PlotView
Default settings for given geometry
currentView : PlotView
Currently displayed plot settings in plot explorer
activeView : PlotView
Active state of settings in plot explorer, which may or may not
have unapplied changes
"""

def __init__(self, use_settings_pkl):
def __init__(self, use_settings_pkl, model_path):
""" Initialize PlotModel class attributes """

# Retrieve OpenMC Cells/Materials
Expand Down Expand Up @@ -147,8 +164,13 @@ def __init__(self, use_settings_pkl):

self.defaultView = self.getDefaultView()

if use_settings_pkl and os.path.isfile('plot_settings.pkl'):
with open('plot_settings.pkl', 'rb') as file:
if model_path.is_file():
settings_pkl = model_path.with_name('plot_settings.pkl')
else:
settings_pkl = model_path / 'plot_settings.pkl'

if use_settings_pkl and settings_pkl.is_file():
with settings_pkl.open('rb') as file:
try:
data = pickle.load(file)
except AttributeError:
Expand Down Expand Up @@ -176,8 +198,7 @@ def __init__(self, use_settings_pkl):

# get materials.xml and geometry.xml hashes to
# restore additional settings if possible
mat_xml_hash = hash_file('materials.xml')
geom_xml_hash = hash_file('geometry.xml')
mat_xml_hash, geom_xml_hash = hash_model(model_path)
if mat_xml_hash == data['mat_xml_hash'] and \
geom_xml_hash == data['geom_xml_hash']:
restore_domains = True
Expand Down Expand Up @@ -1071,8 +1092,8 @@ def adopt_plotbase(self, view):
self.basis = view.basis


class DomainView():
""" Represents view settings for OpenMC cell or material.
class DomainView:
"""Represents view settings for OpenMC cell or material.

Parameters
----------
Expand Down
4 changes: 2 additions & 2 deletions openmc_plotter/tools.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import copy
from time import sleep

import numpy as np
import openmc
from PySide2 import QtCore, QtGui, QtWidgets
from PySide2 import QtCore, QtWidgets

from .custom_widgets import HorizontalLine
from .scientific_spin_box import ScientificDoubleSpinBox


class ExportDataDialog(QtWidgets.QDialog):
"""
A dialog to facilitate generation of VTK files for
Expand Down