diff --git a/src/utils/plot_mesh_tally.py b/src/utils/plot_mesh_tally.py new file mode 100644 index 000000000..625304105 --- /dev/null +++ b/src/utils/plot_mesh_tally.py @@ -0,0 +1,296 @@ +'''Python script to plot tally data generated by OpenMC.''' + +#!/usr/bin/env python + +import sys +from statepoint import * + +# Color intensity dependent on individual score? + +from PyQt4.QtCore import * +from PyQt4.QtGui import * +import matplotlib.pyplot as plt +from matplotlib.figure import Figure +from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas +from matplotlib.backends.backend_qt4agg import NavigationToolbar2QTAgg as NavigationToolbar +import numpy as np + +class AppForm(QMainWindow): + def __init__(self, parent=None): + QMainWindow.__init__(self, parent) + + # Read data from source or leakage fraction file + self.get_file_data() + self.main_frame = QWidget() + self.setCentralWidget(self.main_frame) + + # Create the Figure, Canvas, and Axes + self.dpi = 100 + self.fig = Figure((5.0, 15.0), dpi=self.dpi) + self.canvas = FigureCanvas(self.fig) + self.canvas.setParent(self.main_frame) + self.axes = self.fig.add_subplot(111) + + # Create the navigation toolbar, tied to the canvas + self.mpl_toolbar = NavigationToolbar(self.canvas, self.main_frame) + + # Grid layout at bottom + self.grid = QGridLayout() + + # Overall layout + self.vbox = QVBoxLayout() + self.vbox.addWidget(self.canvas) + self.vbox.addWidget(self.mpl_toolbar) + self.vbox.addLayout(self.grid) + self.main_frame.setLayout(self.vbox) + + # Tally selections + label_tally = QLabel("Tally:") + self.tally = QComboBox() + self.tally.addItems([(str(i + 1)) for i in range(self.n_tallies)]) + self.connect(self.tally, SIGNAL('activated(int)'), + self._update) + self.connect(self.tally, SIGNAL('activated(int)'), + self.populate_boxes) + self.connect(self.tally, SIGNAL('activated(int)'), + self.on_draw) + + # Planar basis + label_basis = QLabel("Basis:") + self.basis = QComboBox() + self.basis.addItems(['xy', 'yz', 'xz']) + + # Update window when 'Basis' selection is changed + self.connect(self.basis, SIGNAL('activated(int)'), + self._update) + self.connect(self.basis, SIGNAL('activated(int)'), + self.populate_boxes) + self.connect(self.basis, SIGNAL('activated(int)'), + self.on_draw) + + # Axial level within selected basis + label_axial_level = QLabel("Axial Level:") + self.axial_level = QComboBox() + self.connect(self.axial_level, SIGNAL('activated(int)'), + self.on_draw) + + self.label_filters = QLabel("Filter options:") + + # Labels for all possible filters + self.labels = {'cell': 'Cell: ', 'cellborn': 'Cell born: ', + 'surface': 'Surface: ', 'material': 'Material', + 'universe': 'Universe: ', 'energyin': 'Energy in: ', + 'energyout': 'Energy out: '} + + # Empty reusable labels + self.qlabels = {} + for j in range(8): + self.nextLabel = QLabel + self.qlabels[j] = self.nextLabel + + # Reusable comboboxes labelled with filter names + self.boxes = {} + for key in self.labels.keys(): + self.nextBox = QComboBox() + self.connect(self.nextBox, SIGNAL('activated(int)'), + self.on_draw) + self.boxes[key] = self.nextBox + + # Combobox to select among scores + self.score_label = QLabel("Score:") + self.scoreBox = QComboBox() + for item in self.tally_scores[0]: + self.scoreBox.addItems(str(item)) + self.connect(self.scoreBox, SIGNAL('activated(int)'), + self.on_draw) + + # Fill layout + self.grid.addWidget(label_tally, 0, 0) + self.grid.addWidget(self.tally, 0, 1) + self.grid.addWidget(label_basis, 1, 0) + self.grid.addWidget(self.basis, 1, 1) + self.grid.addWidget(label_axial_level, 2, 0) + self.grid.addWidget(self.axial_level, 2, 1) + self.grid.addWidget(self.label_filters, 3, 0) + + self._update() + self.populate_boxes() + self.on_draw() + + def get_file_data(self): + # Get data file name from "open file" browser + filename = QFileDialog.getOpenFileName(self, 'Select statepoint file', '.') + + # Create StatePoint object and read in data + self.datafile = StatePoint(filename) + self.datafile.read_results() + self.datafile.generate_stdev() + + self.setWindowTitle('Core Map Tool : ' + str(self.datafile.path)) + + # Set maximum colorbar value by maximum tally data value + self.maxvalue = self.datafile.tallies[0].results.max() + + self.labelList = [] + + # Read mesh dimensions +# for mesh in self.datafile.meshes: +# self.nx, self.ny, self.nz = mesh.dimension + + # Read filter types from statepoint file + self.n_tallies = len(self.datafile.tallies) + self.tally_list = [] + for tally in self.datafile.tallies: + self.filter_types = [] + for f in tally.filters: + self.filter_types.append(f) + self.tally_list.append(self.filter_types) + + # Read score types from statepoint file + self.tally_scores = [] + for tally in self.datafile.tallies: + self.score_types = [] + for s in tally.scores: + self.score_types.append(s) + self.tally_scores.append(self.score_types) + print 'self.tally_scores = ', self.tally_scores + + def on_draw(self): + """ Redraws the figure + """ + + print 'Calling on_draw...' + # Get selected basis, axial_level and stage + basis = self.basis.currentIndex() + 1 + axial_level = self.axial_level.currentIndex() + 1 + + # Create spec_list + spec_list = [] + for tally in self.datafile.tallies[self.tally.currentIndex()].filters.values(): + if tally.type == 'mesh': + continue + index = self.boxes[tally.type].currentIndex() + spec_list.append((tally.type, index)) + + if self.basis.currentText() == 'xy': + matrix = np.zeros((self.nx, self.ny)) + for i in range(self.nx): + for j in range(self.ny): + matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (i, j, axial_level))], self.scoreBox.currentIndex())[0] + + elif self.basis.currentText() == 'yz': + matrix = np.zeros((self.ny, self.nz)) + for i in range(self.ny): + for j in range(self.nz): + matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (axial_level, i, j))], self.scoreBox.currentIndex())[0] + + else: + matrix = np.zeros((self.nx, self.nz)) + for i in range(self.nx): + for j in range(self.nz): + matrix[i,j] = self.datafile.get_value(self.tally.currentIndex(), spec_list + [('mesh', (i, axial_level, j))], self.scoreBox.currentIndex())[0] + + print spec_list + + # Clear the figure + self.fig.clear() + + # Make figure, set up color bar + self.axes = self.fig.add_subplot(111) + cax = self.axes.imshow(matrix, vmin=0.0, vmax=matrix.max(), interpolation="nearest") + self.fig.colorbar(cax) + + self.axes.set_xticks([]) + self.axes.set_yticks([]) + self.axes.set_aspect('equal') + + # Draw canvas + self.canvas.draw() + + def _update(self): + '''Updates widget to display new relevant comboboxes and figure data + ''' + print 'Calling _update...' + + self.mesh = self.datafile.meshes[self.datafile.tallies[self.tally.currentIndex()].filters['mesh'].bins[0] - 1] + + self.nx, self.ny, self.nz = self.mesh.dimension + + # Clear axial level combobox + self.axial_level.clear() + + # Repopulate axial level combobox based on current basis selection + if (self.basis.currentText() == 'xy'): + self.axial_level.addItems([str(i+1) for i in range(self.nz)]) + elif (self.basis.currentText() == 'yz'): + self.axial_level.addItems([str(i+1) for i in range(self.nx)]) + else: + self.axial_level.addItems([str(i+1) for i in range(self.ny)]) + + # Determine maximum value from current tally data set + self.maxvalue = self.datafile.tallies[self.tally.currentIndex()].results.max() + print self.maxvalue + + # Clear and hide old filter labels + for item in self.labelList: + item.clear() + + # Clear and hide old filter boxes + for j in self.labels: + self.boxes[j].clear() + self.boxes[j].setParent(None) + + self.update() + + def populate_boxes(self): + print 'Calling populate_boxes...' + + n = 4 + labels = {'cell': 'Cell : ', + 'cellborn': 'Cell born: ', + 'surface': 'Surface: ', + 'material': 'Material: ', + 'universe': 'Universe: '} + + # For each filter in newly-selected tally, name a label and fill the + # relevant combobox with options + for element in self.tally_list[self.tally.currentIndex()]: + nextFilter = self.datafile.tallies[self.tally.currentIndex()].filters[element] + if element == 'mesh': + continue + + label = QLabel(self.labels[element]) + self.labelList.append(label) + combobox = self.boxes[element] + self.grid.addWidget(label, n, 0) + self.grid.addWidget(combobox, n, 1) + n += 1 + + print element + if element in ['cell', 'cellborn', 'surface', 'material', 'universe']: + combobox.addItems([str(i) for i in nextFilter.bins]) + for i in nextFilter.bins: + print i + + elif element == 'energyin' or element == 'energyout': + for i in range(nextFilter.length): + text = str(nextFilter.bins[i]) + ' to ' + str(nextFilter.bins[i+1]) + combobox.addItem(text) + + self.scoreBox.clear() + for item in self.tally_scores[self.tally.currentIndex()]: + self.scoreBox.addItem(str(item)) + self.grid.addWidget(self.score_label, n, 0) + self.grid.addWidget(self.scoreBox, n, 1) + + + +def main(): + app = QApplication(sys.argv) + form = AppForm() + form.show() + app.exec_() + + +if __name__ == "__main__": + main()