From 99045cc4dcb584c3c84b337c87522d985e5f7288 Mon Sep 17 00:00:00 2001 From: Chun Shen Date: Thu, 20 Aug 2015 10:13:40 -0400 Subject: [PATCH 1/5] fixed a typo in the array index when compute the scaled parameter response --- applications/madai_compute_resolving_power | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/applications/madai_compute_resolving_power b/applications/madai_compute_resolving_power index e7bf767..a02d603 100755 --- a/applications/madai_compute_resolving_power +++ b/applications/madai_compute_resolving_power @@ -599,7 +599,7 @@ def build_data_tables(correlations, observable_names, parameter_names): row = [] for i, parameter in enumerate(parameter_names): row.append(parameter_response[k][i]) - row[i] *= correlations.observable_standard_deviation(i) + row[i] *= correlations.observable_standard_deviation(k) scaled_parameter_response.append(row) tables['scaled_parameter_response'] = DataTable(rows = observable_names, columns = parameter_names, \ row_type = 'observable', column_type = 'parameter', \ From f63e99f20c7f1b2ac58951fcb04f1b297142e4e9 Mon Sep 17 00:00:00 2001 From: Chun Shen Date: Mon, 24 Aug 2015 20:17:17 -0400 Subject: [PATCH 2/5] add a python script to build a GUI with the MADAI emulator --- applications/madai_emulator_GUI | 260 ++++++++++++++++++++++++++++++++ 1 file changed, 260 insertions(+) create mode 100644 applications/madai_emulator_GUI diff --git a/applications/madai_emulator_GUI b/applications/madai_emulator_GUI new file mode 100644 index 0000000..b77453f --- /dev/null +++ b/applications/madai_emulator_GUI @@ -0,0 +1,260 @@ +#!/usr/bin/env python2 + +""" + This is a simple GUI for the MADAI emulator. + It provides an easy interface between the users and the MADAI emulator + and clear visual information for the comparison between the emulator + results and the experimental data. + It calls the built in program madai_emulate to get results from the + emulator. +""" + +import subprocess +from Tkinter import * +import sys +from os import path + + +class HelloWorld: + def __init__(self, parent, stat_directory): + + # initialize the emulator + self.emulator = subprocess.Popen( + ["madai_emulate", stat_directory], stdin=subprocess.PIPE, + stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + self.parameters = {} # holds all the parameters + self.parameter_range = {} # holds the ranges of the parameters + self.parameter_name_list = [] # records the order of the parameters + self.observables_list = {} # holds all the observables + self.observable_name_list = [] # records the order of the observables + self.number_of_lines_for_covariance_matrix = 0 + self.result_list = [] + + # read the header + self.read_in_header() + + """Build the GUI""" + self.master = parent # store the parent + title_frame = Frame(parent) # frame for all class widgets + title_frame.pack(side='top') # pack frame in parent's window + + # create frame to hold the first widget row: + header_frame = Frame(title_frame) + # this frame (row) is packed from top to bottom: + header_frame.pack(side='top') + # create label in the frame: + font = 'times 48 bold' + title_text = 'GUI for MADAI emulator' + header_text = Label(header_frame, text=title_text, fg='blue', font=font) + header_text.pack(side='top', pady=20) + + middle_frame = Frame(title_frame) + middle_frame.pack(side='top', padx=2, pady=2) + + # place all the sliders in a left frame: + slider_frame = Frame(middle_frame) + slider_frame.pack(side='left', padx=2, pady=2) + + self.slider_widget_list = {} + for parameter_name in self.parameter_name_list: + parameter_min = self.parameter_range[parameter_name][0] + parameter_max = self.parameter_range[parameter_name][1] + parameter_default = (parameter_min + parameter_max)/2. + self.parameters[parameter_name] = DoubleVar() + self.parameters[parameter_name].set(parameter_default) + self.slider_widget_list[parameter_name] = self.slider( + slider_frame, self.parameters[parameter_name], parameter_min, + parameter_max, parameter_name) + + # place the textentry widgets and the buttons in a frame + # to the right of slider_frame: + text_entry_frame = Frame(middle_frame) + text_entry_frame.pack(side='left', anchor='n', padx=2, pady=2) + + # use a separate frame and the grid geometry manager to + # pack the labels and entries in a table fashion (enables + # nice alignment): + entry_frame = Frame(text_entry_frame) + entry_frame.pack(side='top', pady=22, padx=12) + self.row_counter = 0 + + self.text_entry_widget_list = {} + for parameter_name in self.parameter_name_list: + text_entry_widget = self.textentry( + entry_frame, self.parameters[parameter_name], parameter_name) + text_entry_widget.bind('', + lambda event: self.slider_widget_list[parameter_name].configure( + to=self.parameters[parameter_name].get()) + ) + self.text_entry_widget_list[parameter_name] = text_entry_widget + + # add some space (empty label): + Label(text_entry_frame, text='').pack(side='top', pady=5) + + # add compute button: + self.sim = Button(text_entry_frame, text='Compute', + width=8, command=self.compute) + self.sim.pack(side='top', pady=5) + + # put the results to the right of text entry widgets + results_frame = Frame(middle_frame) + results_frame.pack(side='left', anchor='n', padx=2, pady=2) + results_title_frame = Frame(results_frame) + results_title_frame.pack(side='top', anchor='n', padx=1, pady=1) + results_title_text = Label( + results_title_frame, text='results', fg='black', + font='times 30 bold') + results_title_text.pack(side='top', pady=5) + + # read in experimental observables + observables_file = open( + path.join(stat_directory, 'experimental_results.dat'), 'r') + for observable_line in observables_file: + temp_line = observable_line.split(' ') + observable_name = temp_line[0] + self.observable_name_list.append(observable_name) + observables_value = temp_line[1] + observables_value_error = temp_line[2] + self.observables_list[observable_name] = ( + observables_value, observables_value_error) + self.result_list.append(StringVar()) + self.compute() + + results_show_frame = Frame(results_frame) + results_show_frame.pack(side='top', anchor='n', padx=2, pady=2) + + # print observables names + results_name_frame = Frame(results_show_frame) + results_name_frame.pack(side='left', anchor='n', padx=2, pady=2) + font_format = 'times 20 bold' + observable_name = Label(results_name_frame, text='name', fg='black', + font=font_format) + observable_name.pack(side='top', pady=1) + for observable_name in self.observable_name_list: + observable_text = Label(results_name_frame, text=observable_name, + fg='red', font=font_format) + observable_text.pack(side='top', pady=1) + + # print theory results + results_theory_frame = Frame(results_show_frame) + results_theory_frame.pack(side='left', anchor='n', padx=2, pady=2) + font_format = 'times 20' + observable_name = Label(results_theory_frame, text='theory', fg='black', + font=(font_format + ' bold')) + observable_name.pack(side='top', pady=1) + for i in range(len(self.observable_name_list)): + observable_text = Label( + results_theory_frame, textvariable=self.result_list[i], + fg='black', font=font_format) + observable_text.bind('', self.compute()) + observable_text.pack(side='top', pady=1) + + # print experimental results + results_exp_frame = Frame(results_show_frame) + results_exp_frame.pack(side='left', anchor='n', padx=2, pady=2) + font_format = 'times 20' + observable_name = Label(results_exp_frame, text='exp.', fg='black', + font=(font_format + ' bold')) + observable_name.pack(side='top', pady=1) + for observable_name in self.observable_name_list: + observables_value = float(self.observables_list[observable_name][0]) + observables_value_error = float( + self.observables_list[observable_name][1]) + obs_min = observables_value - observables_value_error + obs_max = observables_value + observables_value_error + observable_text = Label( + results_exp_frame, text='(%g, %g)' % (obs_min, obs_max), + fg='black', font=font_format) + observable_text.pack(side='top', pady=1) + + def read_in_header(self, ): + """ + read in header information for the emulator and initialize the + parameter and observables dictionaries + """ + self.emulator.stdout.readline() # skip the line for version information + + # read in parameters information + number_of_parameters = int(self.emulator.stdout.readline().split()[1]) + for i in range(number_of_parameters): + line_list = self.emulator.stdout.readline().split() + parameter_name = line_list[0] + self.parameter_name_list.append(parameter_name) + parameter_min = float(line_list[2]) + parameter_max = float(line_list[3]) + self.parameter_range[parameter_name] = ( + parameter_min, parameter_max) + self.parameters[parameter_name] = (parameter_min + parameter_max)/2. + + # skip observables information + number_of_observables = int(self.emulator.stdout.readline().split()[1]) + for i in range(number_of_observables): + self.emulator.stdout.readline() + + # read in number of lines for covariance matrix + self.number_of_lines_for_covariance_matrix = int( + self.emulator.stdout.readline().split()[2]) + + self.emulator.stdout.readline() # skip the line "END_OF_HEADER" + + def compute(self,): + """ + This function call the MADAI emulator and return the results + """ + # prepare the input stream for the emulator + parameter_stream = '' + for parameter_name in self.parameter_name_list: + parameter_stream = ( + parameter_stream + ' ' + + str(self.parameters[parameter_name].get()) + '\n') + + # call the emulator + self.emulator.stdin.write(parameter_stream) + + # retrieve the results from stdout + for i in range(len(self.observable_name_list)): + line = self.emulator.stdout.readline() + self.result_list[i].set(str('%g' % float(line))) + + # skip the covariant matrix + for i in range(self.number_of_lines_for_covariance_matrix): + self.emulator.stdout.readline() + + def textentry(self, parent, variable, label): + """Make a textentry field tied to variable.""" + # pack a label and entry horizontally in a frame: + l = Label(parent, text=label) + l.grid(column=0, row=self.row_counter, sticky='w') + widget = Entry(parent, textvariable=variable, width=8) + widget.grid(column=1, row=self.row_counter) + #widget.grid(column=1, sticky='w') + self.row_counter += 1 + return widget + + def slider(self, parent, variable, low, high, label): + """Make a slider [low,high] tied to variable.""" + widget = Scale(parent, orient='horizontal', + from_=low, to=high, # range of slider + # tickmarks on the slider "axis": + tickinterval=(high-low), + # the steps of the counter above the slider: + resolution=(high-low)/5000.0, + label=label, # label printed above the slider + length=300, # length of slider in pixels + variable=variable) # slider value is tied to variable + widget.pack(side='top') + return widget + + +def create_GUI_for_emulator(directory_path): + root = Tk() # root (main) window + hello = HelloWorld(root, directory_path) + root.mainloop() + +if __name__ == '__main__': + if len(sys.argv) != 2: + print 'Usage: ' + sys.argv[0] + '/stats/directory/' + exit() + stat_directory = path.abspath(sys.argv[1]) + create_GUI_for_emulator(stat_directory) From 9c41cede7204dbe58fb5856b01c9e264448abdd8 Mon Sep 17 00:00:00 2001 From: Chun Shen Date: Mon, 24 Aug 2015 22:59:17 -0400 Subject: [PATCH 3/5] improved the GUI --- applications/madai_emulator_GUI | 133 ++++++++++++++------------------ 1 file changed, 57 insertions(+), 76 deletions(-) diff --git a/applications/madai_emulator_GUI b/applications/madai_emulator_GUI index b77453f..15aa0ac 100644 --- a/applications/madai_emulator_GUI +++ b/applications/madai_emulator_GUI @@ -7,6 +7,8 @@ results and the experimental data. It calls the built in program madai_emulate to get results from the emulator. + + written by Chun Shen (Aug. 2015) """ import subprocess @@ -15,9 +17,8 @@ import sys from os import path -class HelloWorld: +class EmulatorGUI: def __init__(self, parent, stat_directory): - # initialize the emulator self.emulator = subprocess.Popen( ["madai_emulate", stat_directory], stdin=subprocess.PIPE, @@ -34,6 +35,18 @@ class HelloWorld: # read the header self.read_in_header() + observables_file = open( + path.join(stat_directory, 'experimental_results.dat'), 'r') + for observable_line in observables_file: + temp_line = observable_line.split(' ') + observable_name = temp_line[0] + self.observable_name_list.append(observable_name) + observables_value = temp_line[1] + observables_value_error = temp_line[2] + self.observables_list[observable_name] = ( + observables_value, observables_value_error) + self.result_list.append(StringVar()) + """Build the GUI""" self.master = parent # store the parent title_frame = Frame(parent) # frame for all class widgets @@ -45,57 +58,46 @@ class HelloWorld: header_frame.pack(side='top') # create label in the frame: font = 'times 48 bold' - title_text = 'GUI for MADAI emulator' + title_text = 'A GUI for the MADAI emulator' header_text = Label(header_frame, text=title_text, fg='blue', font=font) header_text.pack(side='top', pady=20) middle_frame = Frame(title_frame) middle_frame.pack(side='top', padx=2, pady=2) - # place all the sliders in a left frame: - slider_frame = Frame(middle_frame) - slider_frame.pack(side='left', padx=2, pady=2) - - self.slider_widget_list = {} - for parameter_name in self.parameter_name_list: - parameter_min = self.parameter_range[parameter_name][0] - parameter_max = self.parameter_range[parameter_name][1] - parameter_default = (parameter_min + parameter_max)/2. - self.parameters[parameter_name] = DoubleVar() - self.parameters[parameter_name].set(parameter_default) - self.slider_widget_list[parameter_name] = self.slider( - slider_frame, self.parameters[parameter_name], parameter_min, - parameter_max, parameter_name) - # place the textentry widgets and the buttons in a frame # to the right of slider_frame: - text_entry_frame = Frame(middle_frame) - text_entry_frame.pack(side='left', anchor='n', padx=2, pady=2) + widget_frame = Frame(middle_frame) + widget_frame.pack(side='left', anchor='n', padx=2, pady=2) + + parameter_title_frame = Frame(widget_frame) + parameter_title_frame.pack(side='top', anchor='n', padx=1, pady=1) + parameter_title_text = Label( + parameter_title_frame, text='parameters', fg='black', + font='times 30 bold') + parameter_title_text.pack(side='top', pady=5) # use a separate frame and the grid geometry manager to # pack the labels and entries in a table fashion (enables # nice alignment): - entry_frame = Frame(text_entry_frame) - entry_frame.pack(side='top', pady=22, padx=12) + entry_frame = Frame(widget_frame) + entry_frame.pack(side='top', pady=20, padx=10) self.row_counter = 0 - self.text_entry_widget_list = {} + self.widget_list = {} + for parameter_name in self.parameter_name_list: + parameter_min = self.parameter_range[parameter_name][0] + parameter_max = self.parameter_range[parameter_name][1] + parameter_default = (parameter_min + parameter_max)/2. + self.parameters[parameter_name] = DoubleVar() + self.parameters[parameter_name].set(parameter_default) for parameter_name in self.parameter_name_list: - text_entry_widget = self.textentry( - entry_frame, self.parameters[parameter_name], parameter_name) - text_entry_widget.bind('', - lambda event: self.slider_widget_list[parameter_name].configure( - to=self.parameters[parameter_name].get()) - ) - self.text_entry_widget_list[parameter_name] = text_entry_widget - - # add some space (empty label): - Label(text_entry_frame, text='').pack(side='top', pady=5) - - # add compute button: - self.sim = Button(text_entry_frame, text='Compute', - width=8, command=self.compute) - self.sim.pack(side='top', pady=5) + parameter_min = self.parameter_range[parameter_name][0] + parameter_max = self.parameter_range[parameter_name][1] + widget = self.text_entry_and_slider_widget( + entry_frame, self.parameters[parameter_name], parameter_min, + parameter_max, parameter_name) + self.widget_list[parameter_name] = widget # put the results to the right of text entry widgets results_frame = Frame(middle_frame) @@ -108,21 +110,8 @@ class HelloWorld: results_title_text.pack(side='top', pady=5) # read in experimental observables - observables_file = open( - path.join(stat_directory, 'experimental_results.dat'), 'r') - for observable_line in observables_file: - temp_line = observable_line.split(' ') - observable_name = temp_line[0] - self.observable_name_list.append(observable_name) - observables_value = temp_line[1] - observables_value_error = temp_line[2] - self.observables_list[observable_name] = ( - observables_value, observables_value_error) - self.result_list.append(StringVar()) - self.compute() - results_show_frame = Frame(results_frame) - results_show_frame.pack(side='top', anchor='n', padx=2, pady=2) + results_show_frame.pack(side='top', anchor='n', padx=100, pady=20) # print observables names results_name_frame = Frame(results_show_frame) @@ -147,7 +136,7 @@ class HelloWorld: observable_text = Label( results_theory_frame, textvariable=self.result_list[i], fg='black', font=font_format) - observable_text.bind('', self.compute()) + observable_text.bind('', self.compute_update(1.0)) observable_text.pack(side='top', pady=1) # print experimental results @@ -168,7 +157,7 @@ class HelloWorld: fg='black', font=font_format) observable_text.pack(side='top', pady=1) - def read_in_header(self, ): + def read_in_header(self,): """ read in header information for the emulator and initialize the parameter and observables dictionaries @@ -198,7 +187,7 @@ class HelloWorld: self.emulator.stdout.readline() # skip the line "END_OF_HEADER" - def compute(self,): + def compute_update(self, input): """ This function call the MADAI emulator and return the results """ @@ -221,35 +210,27 @@ class HelloWorld: for i in range(self.number_of_lines_for_covariance_matrix): self.emulator.stdout.readline() - def textentry(self, parent, variable, label): + def text_entry_and_slider_widget(self, parent, variable, low, high, label): """Make a textentry field tied to variable.""" # pack a label and entry horizontally in a frame: - l = Label(parent, text=label) - l.grid(column=0, row=self.row_counter, sticky='w') + l = Label(parent, text=label, fg='red', font='times 20 bold') + l.grid(column=0, row=2*self.row_counter, sticky='w') widget = Entry(parent, textvariable=variable, width=8) - widget.grid(column=1, row=self.row_counter) - #widget.grid(column=1, sticky='w') + widget.grid(column=1, row=2*self.row_counter) + widget_slider = Scale( + parent, orient='horizontal', from_=low, to=high, + tickinterval=high-low, resolution=(high-low)/10000.0, + length=350, variable=variable, + command=self.compute_update) # slider value is tied to variable + widget_slider.grid(column=0, row=2*self.row_counter+1, columnspan=2) self.row_counter += 1 - return widget - - def slider(self, parent, variable, low, high, label): - """Make a slider [low,high] tied to variable.""" - widget = Scale(parent, orient='horizontal', - from_=low, to=high, # range of slider - # tickmarks on the slider "axis": - tickinterval=(high-low), - # the steps of the counter above the slider: - resolution=(high-low)/5000.0, - label=label, # label printed above the slider - length=300, # length of slider in pixels - variable=variable) # slider value is tied to variable - widget.pack(side='top') - return widget + return widget_slider def create_GUI_for_emulator(directory_path): root = Tk() # root (main) window - hello = HelloWorld(root, directory_path) + root.title("A GUI for the MADAI emulator (made by Chun Shen)") + my_gui = EmulatorGUI(root, directory_path) root.mainloop() if __name__ == '__main__': From 5b81bcacfe482c7825bd465a07bd27def56961da Mon Sep 17 00:00:00 2001 From: Chun Shen Date: Mon, 24 Aug 2015 23:03:04 -0400 Subject: [PATCH 4/5] improved read-in ability for the observables file --- applications/madai_emulator_GUI | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) mode change 100644 => 100755 applications/madai_emulator_GUI diff --git a/applications/madai_emulator_GUI b/applications/madai_emulator_GUI old mode 100644 new mode 100755 index 15aa0ac..6ed10c4 --- a/applications/madai_emulator_GUI +++ b/applications/madai_emulator_GUI @@ -38,7 +38,7 @@ class EmulatorGUI: observables_file = open( path.join(stat_directory, 'experimental_results.dat'), 'r') for observable_line in observables_file: - temp_line = observable_line.split(' ') + temp_line = observable_line.split() observable_name = temp_line[0] self.observable_name_list.append(observable_name) observables_value = temp_line[1] From c797fbcb6ca38c19858b7fbbc07ea1c2bc3d3e1a Mon Sep 17 00:00:00 2001 From: Chun Shen Date: Tue, 25 Aug 2015 10:15:59 -0400 Subject: [PATCH 5/5] some fine tuning for the GUI --- applications/madai_emulator_GUI | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/applications/madai_emulator_GUI b/applications/madai_emulator_GUI index 6ed10c4..5584cc7 100755 --- a/applications/madai_emulator_GUI +++ b/applications/madai_emulator_GUI @@ -35,6 +35,7 @@ class EmulatorGUI: # read the header self.read_in_header() + # initialize observables observables_file = open( path.join(stat_directory, 'experimental_results.dat'), 'r') for observable_line in observables_file: @@ -47,7 +48,7 @@ class EmulatorGUI: observables_value, observables_value_error) self.result_list.append(StringVar()) - """Build the GUI""" + # Build the GUI self.master = parent # store the parent title_frame = Frame(parent) # frame for all class widgets title_frame.pack(side='top') # pack frame in parent's window @@ -59,21 +60,22 @@ class EmulatorGUI: # create label in the frame: font = 'times 48 bold' title_text = 'A GUI for the MADAI emulator' - header_text = Label(header_frame, text=title_text, fg='blue', font=font) + header_text = Label(header_frame, text=title_text, + fg='blue', font=font) header_text.pack(side='top', pady=20) middle_frame = Frame(title_frame) middle_frame.pack(side='top', padx=2, pady=2) - # place the textentry widgets and the buttons in a frame - # to the right of slider_frame: + # place text entry and slider widgets on the left widget_frame = Frame(middle_frame) widget_frame.pack(side='left', anchor='n', padx=2, pady=2) + # title parameter_title_frame = Frame(widget_frame) parameter_title_frame.pack(side='top', anchor='n', padx=1, pady=1) parameter_title_text = Label( - parameter_title_frame, text='parameters', fg='black', + parameter_title_frame, text='Parameters', fg='black', font='times 30 bold') parameter_title_text.pack(side='top', pady=5) @@ -105,7 +107,7 @@ class EmulatorGUI: results_title_frame = Frame(results_frame) results_title_frame.pack(side='top', anchor='n', padx=1, pady=1) results_title_text = Label( - results_title_frame, text='results', fg='black', + results_title_frame, text='Observables', fg='black', font='times 30 bold') results_title_text.pack(side='top', pady=5) @@ -143,7 +145,7 @@ class EmulatorGUI: results_exp_frame = Frame(results_show_frame) results_exp_frame.pack(side='left', anchor='n', padx=2, pady=2) font_format = 'times 20' - observable_name = Label(results_exp_frame, text='exp.', fg='black', + observable_name = Label(results_exp_frame, text='experiment', fg='black', font=(font_format + ' bold')) observable_name.pack(side='top', pady=1) for observable_name in self.observable_name_list: