diff --git a/openmc_plotter/main_window.py b/openmc_plotter/main_window.py index e4579a9..03555f9 100755 --- a/openmc_plotter/main_window.py +++ b/openmc_plotter/main_window.py @@ -190,8 +190,13 @@ def createMenuBar(self): self.openStatePointAction.setToolTip('Open statepoint file') self.openStatePointAction.triggered.connect(self.openStatePoint) + self.importPropertiesAction = QAction("&Import properties...", self) + self.importPropertiesAction.setToolTip("Import properties") + self.importPropertiesAction.triggered.connect(self.importProperties) + self.dataMenu = self.mainMenu.addMenu('D&ata') self.dataMenu.addAction(self.openStatePointAction) + self.dataMenu.addAction(self.importPropertiesAction) self.updateDataMenu() # Edit Menu @@ -531,6 +536,28 @@ def openStatePoint(self): self.updateDataMenu() self.tallyDock.update() + def importProperties(self): + filename, ext = QFileDialog.getOpenFileName(self, "Import properties", + ".", "*.h5") + if not filename: + return + + try: + openmc.lib.import_properties(filename) + message = 'Imported properties: {}' + except (FileNotFoundError, OSError, openmc.lib.exc.OpenMCError) as e: + message = 'Error opening properties file: {}' + msg_box = QMessageBox() + msg_box.setText(f"Error opening properties file: \n\n {e} \n") + msg_box.setIcon(QMessageBox.Warning) + msg_box.setStandardButtons(QMessageBox.Ok) + msg_box.exec_() + finally: + self.statusBar().showMessage(message.format(filename), 5000) + + if self.model.activeView.colorby == 'temperature': + self.applyChanges() + def closeStatePoint(self): # remove the statepoint object and update the data menu filename = self.model.statepoint.filename diff --git a/openmc_plotter/plotgui.py b/openmc_plotter/plotgui.py index d735880..c0dbc5e 100644 --- a/openmc_plotter/plotgui.py +++ b/openmc_plotter/plotgui.py @@ -183,11 +183,13 @@ def getIDinfo(self, event): # check that the position is in the axes view if 0 <= yPos < self.model.currentView.v_res \ and 0 <= xPos and xPos < self.model.currentView.h_res: - id = self.model.ids[yPos][xPos] - temp = "{:g}".format(self.model.properties[yPos][xPos][0]) - density = "{:g}".format(self.model.properties[yPos][xPos][1]) + id = self.model.ids[yPos, xPos] + instance = self.model.instances[yPos, xPos] + temp = "{:g}".format(self.model.properties[yPos, xPos, 0]) + density = "{:g}".format(self.model.properties[yPos, xPos, 1]) else: id = _NOT_FOUND + instance = _NOT_FOUND density = str(_NOT_FOUND) temp = str(_NOT_FOUND) @@ -207,7 +209,7 @@ def getIDinfo(self, event): properties = {'density': density, 'temperature': temp} - return id, properties, domain, domain_kind + return id, instance, properties, domain, domain_kind def mouseDoubleClickEvent(self, event): xCenter, yCenter = self.getPlotCoords(event.pos()) @@ -219,7 +221,7 @@ def mouseMoveEvent(self, event): xPlotPos, yPlotPos = self.getPlotCoords(event.pos()) # Show Cell/Material ID, Name in status bar - id, properties, domain, domain_kind = self.getIDinfo(event) + id, instance, properties, domain, domain_kind = self.getIDinfo(event) domainInfo = "" tallyInfo = "" @@ -235,21 +237,29 @@ def mouseMoveEvent(self, event): temperature = properties['temperature'] density = properties['density'] + if instance != _NOT_FOUND and domain_kind == 'Cell': + instanceInfo = f" ({instance})" + else: + instanceInfo = "" if id == _VOID_REGION: domainInfo = ("VOID") elif id == _OVERLAP: domainInfo = ("OVERLAP") elif id != _NOT_FOUND and domain[id].name: - domainInfo = ("{} {}: \"{}\"\t Density: {} g/cc\t" - "Temperature: {} K".format(domain_kind, - id, - domain[id].name, - density, - temperature)) + domainInfo = ("{} {}{}: \"{}\"\t Density: {} g/cc\t" + "Temperature: {} K".format( + domain_kind, + id, + instanceInfo, + domain[id].name, + density, + temperature + )) elif id != _NOT_FOUND: - domainInfo = ("{} {}\t Density: {} g/cc\t" + domainInfo = ("{} {}{}\t Density: {} g/cc\t" "Temperature: {} K".format(domain_kind, id, + instanceInfo, density, temperature)) else: @@ -328,7 +338,7 @@ def contextMenuEvent(self, event): self.main_window.undoAction.setText('&Undo ({})'.format(len(self.model.previousViews))) self.main_window.redoAction.setText('&Redo ({})'.format(len(self.model.subsequentViews))) - id, properties, domain, domain_kind = self.getIDinfo(event) + id, instance, properties, domain, domain_kind = self.getIDinfo(event) cv = self.model.currentView diff --git a/openmc_plotter/plotmodel.py b/openmc_plotter/plotmodel.py index 11e2e19..f9f5cc7 100644 --- a/openmc_plotter/plotmodel.py +++ b/openmc_plotter/plotmodel.py @@ -100,6 +100,7 @@ def __init__(self): # Cell/Material ID by coordinates self.ids = None + self.instances = None self.version = __VERSION__ @@ -198,7 +199,8 @@ def makePlot(self): props = openmc.lib.property_map(cv) self.cell_ids = ids[:, :, 0] - self.mat_ids = ids[:, :, 1] + self.instances = ids[:, :, 1] + self.mat_ids = ids[:, :, 2] # set model ids based on domain if cv.colorby == 'cell': diff --git a/setup.py b/setup.py index 654c047..6e04f8d 100644 --- a/setup.py +++ b/setup.py @@ -35,9 +35,9 @@ ], # Dependencies - 'python_requires': '>=3.5', + 'python_requires': '>=3.6', 'install_requires': [ - 'openmc>0.12.0', 'numpy', 'matplotlib', 'PySide2' + 'openmc>0.12.2', 'numpy', 'matplotlib', 'PySide2' ], 'extras_require': { 'test' : ['pytest', 'pytest-qt'],