Skip to content
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
31 changes: 30 additions & 1 deletion openmc_plotter/main_window.py
Original file line number Diff line number Diff line change
Expand Up @@ -378,6 +378,16 @@ def createMenuBar(self):
self.overlapAct.toggled.connect(overlap_connector)
self.editMenu.addAction(self.overlapAct)

self.undefinedAct = QAction('Enable Undefined Region Coloring', self)
self.undefinedAct.setShortcut('Ctrl+I')
self.undefinedAct.setCheckable(True)
self.undefinedAct.setToolTip('Toggle undefined regions')
self.undefinedAct.setStatusTip('Toggle display of undefined '
'(not found) regions when enabled')
undefined_connector = partial(self.toggleUndefined, apply=True)
self.undefinedAct.toggled.connect(undefined_connector)
self.editMenu.addAction(self.undefinedAct)

self.outlineAct = QAction('Enable Domain Outlines', self)
self.outlineAct.setShortcut('Ctrl+U')
self.outlineAct.setCheckable(True)
Expand Down Expand Up @@ -438,14 +448,15 @@ def updateEditMenu(self):
self.restoreAction.setDisabled(not changed)

toggle_actions = (self.maskingAction, self.highlightingAct,
self.outlineAct, self.overlapAct)
self.outlineAct, self.overlapAct, self.undefinedAct)
# Temporarily block signals to avoid triggering plot update
for action in toggle_actions:
action.blockSignals(True)
self.maskingAction.setChecked(self.model.currentView.masking)
self.highlightingAct.setChecked(self.model.currentView.highlighting)
self.outlineAct.setChecked(self.model.currentView.outlinesCell)
self.overlapAct.setChecked(self.model.currentView.color_overlaps)
self.undefinedAct.setChecked(self.model.currentView.color_undefined)
for action in toggle_actions:
action.blockSignals(False)

Expand Down Expand Up @@ -742,6 +753,12 @@ def toggleOverlaps(self, state, apply=False):
if apply:
self.applyChanges()

def toggleUndefined(self, state, apply=False):
self.model.activeView.color_undefined = bool(state)
self.colorDialog.updateUndefined()
if apply:
self.applyChanges()

def editColorMap(self, colormap_name, property_type, apply=False):
self.model.activeView.colormaps[property_type] = colormap_name
self.plotIm.updateColorMap(colormap_name, property_type)
Expand Down Expand Up @@ -935,6 +952,18 @@ def editOverlapColor(self, apply=False):
if apply:
self.applyChanges()

def editUndefinedColor(self, apply=False):
current_color = self.model.activeView.undefined_color
dlg = QColorDialog(self)
dlg.setCurrentColor(QtGui.QColor.fromRgb(*current_color))
if dlg.exec():
new_color = dlg.currentColor().getRgb()[:3]
self.model.activeView.undefined_color = new_color
self.colorDialog.updateUndefinedColor()

if apply:
self.applyChanges()

def editBackgroundColor(self, apply=False):
current_color = self.model.activeView.domainBackground
dlg = QColorDialog(self)
Expand Down
1 change: 1 addition & 0 deletions openmc_plotter/overlays.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class ShortcutsOverlay(QWidget):
("Toggle Masking", c_key + "+M"),
("Toggle Highlighting", c_key + "+L"),
("Toggle Overlap Coloring", c_key + "+P"),
("Toggle Undefined Coloring", c_key + "+I"),
("Toggle Domain Outlines", c_key + "+U"),
("Set XY Basis", "Alt+X"),
("Set YZ Basis", "Alt+Y"),
Expand Down
58 changes: 56 additions & 2 deletions openmc_plotter/plotgui.py
Original file line number Diff line number Diff line change
Expand Up @@ -361,6 +361,22 @@ def _overlapInfo(self, id):
label2 = self._cellLabel(cell2)
return f"OVERLAP: Universe {universe}, Cells {label1} and {label2}"

def _isUndefinedInternal(self, event):
"""Whether the pixel under the event is an internal undefined region."""
if self.model.undefined_internal is None:
return False
xPos, yPos = self.getDataIndices(event)
cv = self.model.currentView
if not (0 <= yPos < cv.v_res and 0 <= xPos < cv.h_res):
return False
return bool(self.model.undefined_internal[yPos, xPos])

def _undefinedInfo(self, event):
"""Status-bar text for an undefined (not-found) pixel, if classified."""
if self._isUndefinedInternal(event):
return "WARNING: undefined internal region"
return ""

def mouseDoubleClickEvent(self, event):
xCenter, yCenter = self.getPlotCoords(event.pos())
self.main_window.editPlotOrigin(xCenter, yCenter, apply=True)
Expand Down Expand Up @@ -414,7 +430,7 @@ def mouseMoveEvent(self, event):
density,
temperature))
else:
domainInfo = ""
domainInfo = self._undefinedInfo(event)

if self.model.tally_data is not None:
tid, value = self.getTallyInfo(event)
Expand Down Expand Up @@ -568,7 +584,16 @@ def contextMenuEvent(self, event):

if cv.colorby not in _MODEL_PROPERTIES:
self.menu.addSeparator()
if int(id) == _NOT_FOUND:
if int(id) == _NOT_FOUND and self._isUndefinedInternal(event):
undefColorAction = self.menu.addAction(
'Edit Undefined Color...')
undefColorAction.setToolTip('Edit undefined color')
undefColorAction.setStatusTip(
'Edit plot undefined region color')
connector = partial(self.main_window.editUndefinedColor,
apply=True)
undefColorAction.triggered.connect(connector)
elif int(id) == _NOT_FOUND:
bgColorAction = self.menu.addAction(
'Edit Background Color...')
bgColorAction.setToolTip('Edit background color')
Expand Down Expand Up @@ -598,6 +623,7 @@ def contextMenuEvent(self, event):
self.menu.addAction(self.main_window.maskingAction)
self.menu.addAction(self.main_window.highlightingAct)
self.menu.addAction(self.main_window.overlapAct)
self.menu.addAction(self.main_window.undefinedAct)
self.menu.addSeparator()
self.menu.addAction(self.main_window.dockAction)

Expand Down Expand Up @@ -1125,6 +1151,17 @@ def createGeneralTab(self):
self.overlapColorButton.setFixedHeight(self.font_metric.height() * 1.5)
self.overlapColorButton.clicked.connect(main_window.editOverlapColor)

# Undefined (not-found) region plotting
self.undefinedCheck = QCheckBox('', self)
undefined_connector = partial(main_window.toggleUndefined)
self.undefinedCheck.stateChanged.connect(undefined_connector)

self.undefinedColorButton = QPushButton()
self.undefinedColorButton.setCursor(QtCore.Qt.PointingHandCursor)
self.undefinedColorButton.setFixedWidth(button_width)
self.undefinedColorButton.setFixedHeight(self.font_metric.height() * 1.5)
self.undefinedColorButton.clicked.connect(main_window.editUndefinedColor)

self.colorResetButton = QPushButton("&Reset Colors")
self.colorResetButton.setCursor(QtCore.Qt.PointingHandCursor)
self.colorResetButton.clicked.connect(main_window.resetColors)
Expand All @@ -1147,6 +1184,9 @@ def createGeneralTab(self):
formLayout.addRow('Show Overlaps:', self.overlapCheck)
formLayout.addRow('Overlap Color:', self.overlapColorButton)
formLayout.addRow(HorizontalLine())
formLayout.addRow('Show Undefined:', self.undefinedCheck)
formLayout.addRow('Undefined Color:', self.undefinedColorButton)
formLayout.addRow(HorizontalLine())
formLayout.addRow('Color Plot By:', self.colorbyBox)
formLayout.addRow('Universe Level:', self.universeLevelBox)
formLayout.addRow(self.colorResetButton, None)
Expand Down Expand Up @@ -1314,6 +1354,8 @@ def updateDialogValues(self):
self.updateDomainTabs()
self.updateOverlap()
self.updateOverlapColor()
self.updateUndefined()
self.updateUndefinedColor()

def updateMasking(self):
masking = self.model.activeView.masking
Expand Down Expand Up @@ -1383,10 +1425,22 @@ def updateOverlap(self):
if colorby in ('cell', 'material'):
self.overlapCheck.setChecked(overlap_val)

def updateUndefinedColor(self):
color = self.model.activeView.undefined_color
self.undefinedColorButton.setStyleSheet("border-radius: 8px;"
"background-color: rgb%s" % (str(color)))

def updateUndefined(self):
colorby = self.model.activeView.colorby
undefined_val = self.model.activeView.color_undefined
if colorby in ('cell', 'material'):
self.undefinedCheck.setChecked(undefined_val)

def updateColorBy(self):
colorby = self.model.activeView.colorby
self.colorbyBox.setCurrentText(colorby)
self.overlapCheck.setEnabled(colorby in ("cell", "material"))
self.undefinedCheck.setEnabled(colorby in ("cell", "material"))
self.universeLevelBox.setEnabled(colorby == 'cell')

def updateUniverseLevel(self):
Expand Down
31 changes: 31 additions & 0 deletions openmc_plotter/plotmodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,12 @@ def __init__(self, use_settings_pkl, model_path, default_res):
# Map to be populated by overlap functions
self.overlap_info = None

# Boolean mask of internal undefined (not-found) regions, populated by
# makePlot when undefined-region coloring is enabled. Internal regions
# are enclosed by defined geometry (potentially unsafe); external
# (boundary-connected) undefined regions are intentionally ignored.
self.undefined_internal = None

self.version = __version__

# default statepoint value
Expand Down Expand Up @@ -585,6 +591,18 @@ def makePlot(self, view: Optional["PlotView"] = None,
if dom.highlight:
image[self.ids == int(id)] = cv.highlightBackground

# Classify and color undefined (not-found) regions. Only internal
# regions (holes enclosed by defined geometry) are flagged as a
# warning; external regions connect to the slice boundary and are
# left untouched.
self.undefined_internal = None
if cv.color_undefined:
_, _, internal = \
openmc.Model._classify_undefined_regions(self.cell_ids)
if internal is not None:
self.undefined_internal = internal
image[internal] = cv.undefined_color

# set model image
self.image = image

Expand Down Expand Up @@ -1228,6 +1246,11 @@ class PlotViewIndependent:
RGB color to apply to plot background
overlap_color : 3-tuple of int
RGB color to apply for cell overlap regions
color_undefined : bool
Indicator of whether or not internal undefined (not-found) regions
will be shown
undefined_color : 3-tuple of int
RGB color to apply for internal (enclosed) undefined regions
domainAlpha : float between 0 and 1
Alpha value of the geometry plot
plotVisibile : bool
Expand Down Expand Up @@ -1277,6 +1300,9 @@ def __init__(self):
self.highlightSeed = 1
self.domainBackground = (50, 50, 50)
self.overlap_color = (255, 0, 0)
# Undefined (not-found) region coloring (internal regions only)
self.color_undefined = False
self.undefined_color = (255, 165, 0)
self.domainAlpha = 1.0
self.domainVisible = True
self.outlinesCell = False
Expand Down Expand Up @@ -1314,6 +1340,11 @@ def __setstate__(self, state):
self.outlinesCell = False
if not hasattr(self, 'outlinesMat'):
self.outlinesMat = False
# Undefined region coloring (added in a later version)
if not hasattr(self, 'color_undefined'):
self.color_undefined = False
if not hasattr(self, 'undefined_color'):
self.undefined_color = (255, 165, 0)
# Migrate old boolean attributes to new tallyDataMinMaxType
if not hasattr(self, 'tallyDataMinMaxType'):
if getattr(self, 'tallyDataUserMinMax', False):
Expand Down
Loading