def render_measurement(self): self.measurement.clear() option = self.test_measurement.currentText() if option == 'gradient': self.signal, self.grad_from, self.grad_to = self.measurement.addWidgets([ DropDown('Gradient of:', data_manager.get_growth_variables()), TextEntry('Between:', placeholder='Y = '), TextEntry('And:', placeholder='Y = ')]) elif option == 'time to': self.signal, self.time_to = self.measurement.addWidgets([ DropDown('Time for:', data_manager.get_growth_variables()), TextEntry('To reach:', placeholder='Y = ')]) elif option == 'fit parameter': model = get_model(config.fit_options[0]) self.fit, self.signal, self.param, self.fit_from, self.fit_to = self.measurement.addWidgets([ DropDown('Fit:', config.fit_options, change_action=self.update_param_list), DropDown('Of:', data_manager.get_growth_variables()), DropDown('Parameter:', model.params), TextEntry('From:', placeholder=config.xvar), TextEntry('To:', placeholder=config.xvar)]) else: self.measurement.hide() return self.measurement.show() return
def initUI(self): self.line_style, self.line_colour, self.marker_style, _ = self.window.addWidgets( [ DropDown('Line style:', config.line_style_options), TextEntry('Line colour:'), DropDown('Marker style:', list(config.marker_style_options.keys())), Button("Apply", clicked=self.apply_changes) ])
def initUI(self): # Dropdown list of available file types file_types = config.replicate_types if self.row == -1: file_types = config.file_types self.file_type = self.window.addWidget( DropDown('File type:', file_types, change_action=self.update_options)) # Button for selecting files to import self.window.addWidget( Button("Select data file(s)", clicked=self.select_data)) # List of files to import self.file_list = self.window.addWidget(List()) self.file_list.setSpacing(-5 * config.wr) self.file_list.setStyleSheet(styles.default_font) # Button and list for Algem conditions files self.select_conditions_button = self.window.addWidget( Button("Select conditions file(s)", clicked=self.select_conditions)) self.select_conditions_button.hide() self.conditions_file_list = self.window.addWidget( List(spacing=-5 * config.wr, style=styles.default_font)) self.conditions_file_list.hide() # Button and list for HT24 details file self.select_details_button = self.window.addWidget( Button("Select details file", clicked=self.select_details)) self.select_details_button.hide() self.details_file_list = self.window.addWidget( List(spacing=-5 * config.wr, style=styles.default_font)) self.details_file_list.hide() # Option to downsample conditions data self.downsample = self.window.addWidget( TextEntry('Downsample conditions:', default=config.downsample, tooltip='Only read in every X data points')) self.downsample.hide() # Checkbox for merging replicates in HT24 data self.merge_replicates = self.window.addWidget( CheckBox('Merge replicates')) self.merge_replicates.hide() # Button to load the data self.window.addWidget(Button("Load", clicked=self.load)) self.update_options()
def initUI(self): fit_config = LayoutWidget(QVBoxLayout) # List of row options self.curve_option, self.fit_option, self.fit_from, self.fit_to, self.set_bounds, _ = fit_config.addWidgets( [ DropDown('Data:', data_manager.get_growth_data_labels()), DropDown('Fit:', config.fit_options), TextEntry('From:', default=config.fit_from), TextEntry('To:', default=config.fit_to), CheckBox('Set parameter bounds', change_action=self.render_bounds), Button("Fit", clicked=self.fit) ]) self.window.addWidget(fit_config.widget) self.bound_input = LayoutWidget(QVBoxLayout) self.param_bounds = self.bound_input.addWidget(ParameterBounds("p")) self.window.addWidget(self.bound_input.widget) self.bound_input.hide()
def __init__(self, text, parent=None): self.item = QListWidgetItem() self.type = text # Horizontal box layout layout = LayoutWidget(QHBoxLayout) spacer = layout.addWidget(QWidget()) spacer.setFixedWidth(10 * config.wr) # Add a delete button layout.addWidget(DeleteButton(clicked=parent.remove_item)) # Add a label with row type if (text == 'profile'): layout.addWidget(RoundLabel('Profile')) if (text == 'reactor'): layout.addWidget(RoundLabel('Reactor')) # Add other options based on type # Gradient needs a start and end measurement point in Y if (text == 'gradient'): self.data, self.grad_from, self.grad_to = layout.addWidgets([ DropDown('Gradient of:', data_manager.get_growth_variables()), TextEntry('Between:', default=-1, placeholder='Y = '), TextEntry('And:', default=-1, placeholder='Y = ') ]) # Time to needs a Y point to reach if (text == 'time to'): self.data, self.time_to = layout.addWidgets([ DropDown('Time for:', data_manager.get_growth_variables()), TextEntry('To reach:', default=-1, placeholder='Y = ') ]) # Average of a condition needs condition and start and end time if (text == 'average of condition'): self.condition, self.start_t, self.end_t = layout.addWidgets([ DropDown('Average of:', data_manager.get_condition_variables()), TextEntry('Between:', default=-1, placeholder=config.xvar), TextEntry('And:', default=-1, placeholder=config.xvar) ]) # Condition at time needs condition and time if (text == 'condition at time'): self.condition, self.time = layout.addWidgets([ DropDown('Value of:', data_manager.get_condition_variables()), TextEntry('At:', default=-1, placeholder=config.xvar) ]) # Value of fit parameter needs fit and parameter if (text == 'fit parameter'): model = get_model(config.fit_options[0], '', '') self.fit, self.data, self.param, self.fit_from, self.fit_to, self.show_error = layout.addWidgets( [ DropDown('Fit:', config.fit_options, change_action=self.update_param_list), DropDown('Data:', data_manager.get_growth_variables()), DropDown('Parameter:', model.params), TextEntry('From:', default=-1, placeholder=config.xvar), TextEntry('To:', default=-1, placeholder=config.xvar), CheckBox("Show error") ]) # Pad out the row layout.layout.addStretch() layout.layout.setSpacing(5) layout.layout.setContentsMargins(10, 10, 50, 5) self.widget = layout.widget self.item.setSizeHint(self.widget.sizeHint())
def initUI(self): self.setGeometry(self.left, self.top, self.width, self.height) # Configuration tab corr_config = LayoutWidget(QVBoxLayout, margin=5, spacing=0) # X axis selection = condition variable # Dropdown of condition variables OR take from main plot self.condition = corr_config.addWidget( DropDown('X-axis: Average of', data_manager.get_condition_variables())) # Y axis selection = growth related measurement # Dropdown of y variables (OD/CD) OR take from main plot self.data = corr_config.addWidget( DropDown('Y-axis:', data_manager.get_growth_variables())) # Choice of fit and fit parameter fit_option = LayoutWidget(QHBoxLayout) model = get_model(config.fit_options[0]) self.fit, self.param = fit_option.addWidgets([ DropDown('Fit:', config.fit_options, change_action=self.update_param_list), DropDown('Parameter:', model.params) ]) corr_config.addWidget(fit_option.widget) range_option = LayoutWidget(QHBoxLayout) self.start_t, self.end_t = range_option.addWidgets([ TextEntry('Between:', default=-1, placeholder=config.xvar), TextEntry('And:', default=-1, placeholder=config.xvar) ]) corr_config.addWidget(range_option.widget) self.figure_title = corr_config.addWidget(TextEntry('Figure title:')) title_option = LayoutWidget(QHBoxLayout) self.x_title, self.y_title = title_option.addWidgets( [TextEntry('X-axis title:'), TextEntry('Y-axis title:')]) corr_config.addWidget(title_option.widget) options = LayoutWidget(QHBoxLayout) self.label, self.calc_correlation = options.addWidgets( [CheckBox('Label'), CheckBox('Calculate correlation')]) corr_config.addWidget(options.widget) # Plot button corr_config.addWidget(Button('Plot', clicked=self.update_plot)) self.tabs.addTab(corr_config.widget, 'Configuration') # Plot tab plot_view = LayoutWidget(QGridLayout, margin=5, spacing=10) # Plot self.plot = plot_view.addWidget( CorrelationCanvas(self, width=10 * config.wr, height=4 * config.hr, dpi=100 * config.wr), 0, 0, 4, 4) shadow = QGraphicsDropShadowEffect(blurRadius=10 * config.wr, xOffset=3 * config.wr, yOffset=3 * config.hr) self.plot.setGraphicsEffect(shadow) self.plot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) # Save button plot_view.addWidget(Button('Save', clicked=self.save_plot), 4, 0, 1, 4) self.tabs.addTab(plot_view.widget, 'Plot')
def initUI(self): self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) wr = config.wr hr = config.wr tabs = QTabWidget() tabs.setStyleSheet(styles.tab_style) # --------------------------------------------------------------------- # PLOTTING TAB # --------------------------------------------------------------------- # Main plotting window splitter = QSplitter() plot_view = LayoutWidget(QGridLayout, margin=5, spacing=10) # Main plot window (row, column, row extent, column extent) self.plot = plot_view.addWidget( PlotCanvas(self, width=10 * wr, height=4 * hr, dpi=100 * wr), 0, 1, 5, 5) shadow = QGraphicsDropShadowEffect(blurRadius=10 * wr, xOffset=3 * wr, yOffset=3 * hr) self.plot.setGraphicsEffect(shadow) self.plot.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding) toolbar = plot_view.addWidget(QToolBar("Tools", self), 0, 0, 5, 1) toolbar.setOrientation(Qt.Vertical) toolbar.setStyleSheet(styles.toolbar_style) toolbar_icons = [ ":measure.svg", ":fit.svg", ":table.svg", ":correlations.svg", ":template.svg", ":normal.svg" ] toolbar_labels = [ '&Measure', '&Fit', '&To Table', '&Correlations', '&Download Template', '&Statisitical Tests' ] toolbar_actions = [ self.toggle_cursor, self.fit_curve, self.create_table, self.open_correlation, self.download_template, self.open_tests ] for i, icon in enumerate(toolbar_icons): toolbar_action = QAction(QIcon(icon), toolbar_labels[i], self) toolbar_action.triggered.connect(toolbar_actions[i]) toolbar.addAction(toolbar_action) splitter.addWidget(plot_view.widget) data_entry = LayoutWidget(QVBoxLayout, margin=5, spacing=10) self.data_button, self.data_list, _, self.condition_data_list, _, self.calibration_file, _ = data_entry.addWidgets( [ Button('Add Data', tooltip='Import data for plotting', clicked=self.open_data_files), List(scroll=True), TopLabel('Condition Data:'), List(scroll=True), Button('Add Calibration Curve', tooltip='Set OD to CD conversion from file', clicked=self.open_calibration_file), DelLabel('', clicked=self.remove_calibration_file), BigButton('Plot!', tooltip='Plot the data!', clicked=self.update_plot) ]) self.data_button.setContextMenuPolicy(Qt.CustomContextMenu) self.data_button.customContextMenuRequested.connect( self.on_context_menu) self.clear_menu = QMenu(self) self.clear_action = QAction('Clear all', self) self.clear_menu.addAction(self.clear_action) self.calibration_file.setFixedHeight(40 * hr) splitter.addWidget(data_entry.widget) tabs.addTab(splitter, 'Plotting') # --------------------------------------------------------------------- # OPTIONS TABS # --------------------------------------------------------------------- # --------------- AXIS CONFIGURATION # Axis configuration axis_options = LayoutWidget(QVBoxLayout, style=styles.white_background) axis_h = LayoutWidget(QHBoxLayout) self.figure_title = axis_options.addWidget(TextEntry('Figure title:')) x_options = LayoutWidget(QVBoxLayout) x_options.addWidget(TopLabel('X (time):')) # X axis config x_form = Form() self.xaxis_dropdown, self.xaxis_name, self.xaxis_unit, self.xaxis_min, self.xaxis_max, self.xaxis_log = x_form.addRows( [ DropDown('Variable:', config.xaxis_units, index=2), TextEntry('Label:'), TextEntry('Unit name:', tooltip='Enter "none" for no units'), TextEntry('Range min:', default=config.xmin), TextEntry('Range max:', default=config.xmax), CheckBox('Log scale') ], padding=[False, False, False, False, False, True]) x_options.addWidget(x_form.widget) axis_h.addWidget(x_options.widget) y_options = LayoutWidget(QVBoxLayout) y_options.addWidget(TopLabel('Y (growth):')) # Y axis config y_form = Form() self.yaxis_dropdown, self.yaxis_name, self.yaxis_unit, self.yaxis_min, self.yaxis_max = y_form.addRows( [ DropDown('Variable:', []), TextEntry('Label:'), TextEntry('Unit name:', tooltip='Enter "none" for no units'), TextEntry('Range min:', default=config.ymin), TextEntry('Range max:', default=config.ymax) ]) # Y axis log scale ylog_hbox = LayoutWidget(QHBoxLayout) ylog_hbox.layout.setSpacing(15 * wr) ylog_hbox.layout.setContentsMargins(0, 0, 1 * wr, 1 * hr) self.yaxis_log, self.yaxis_normlog = ylog_hbox.addWidgets( [CheckBox('Log scale'), CheckBox('ln(Y/Y0)')]) y_form.addRow(ylog_hbox.widget, pad=True) y_options.addWidget(y_form.widget) axis_h.addWidget(Spacer()) axis_h.addWidget(y_options.widget) z_options = LayoutWidget(QVBoxLayout) z_options.addWidget(TopLabel('Y2 (conditions):')) # Condition Y axis drop down menu z_form = Form() self.condition_yaxis_dropdown, self.condition_yaxis_name, self.condition_yaxis_unit, self.condition_yaxis_min, self.condition_yaxis_max, self.condition_yaxis_log = z_form.addRows( [ DropDown('Variable:', []), TextEntry('Label:'), TextEntry('Unit name:', tooltip='Enter "none" for no units'), TextEntry('Range min:', default=config.condition_ymin), TextEntry('Range max:', default=config.condition_ymax), CheckBox('Log scale') ], padding=[False, False, False, False, False, True]) z_options.addWidget(z_form.widget) axis_h.addWidget(Spacer()) axis_h.addWidget(z_options.widget) axis_options.addWidget(axis_h.widget) axis_options.addWidget(Spacer()) tabs.addTab(axis_options.widget, 'Axes') # --------------- DATA CONFIGURATION # Data configuration options data_options = LayoutWidget(QHBoxLayout, style=styles.white_background) data_form = Form() self.smooth_data, self.align_data, self.y_alignment, self.initial_y, self.growth_average, self.condition_average, self.show_events = data_form.addRows( [ CheckBox('Data smoothing off/on', tooltip='Apply Savitzky-Golay to noisy data'), CheckBox('Alignment at time = 0 on/off', tooltip='Start growth curves at 0 time'), TextEntry('Align at Y:', default=config.y_alignment, tooltip='Align all growth curves at given Y value'), TextEntry('Set initial Y:', default=config.initial_y, tooltip='Start growth curves at a given Y value'), TextEntry('Growth data time average:', default=config.growth_average, tooltip='Average over a given time window'), TextEntry('Condition data time average:', default=config.condition_average, tooltip='Average over a given time window'), CheckBox('Show events off/on') ], padding=[True, True, False, False, False, False, True]) data_options.addWidget(data_form.widget) # Remove any obvious outliers from the growth data outlier_options = LayoutWidget(QVBoxLayout) outlier_options.addWidget(TopLabel('Data outliers:')) outlier_form = Form() self.auto_remove, self.remove_above, self.remove_below = outlier_form.addRows( [ CheckBox('Auto-remove outliers off/on'), TextEntry('Remove above:', default=config.remove_above), TextEntry('Remove below:', default=config.remove_below) ], padding=[True, False, False]) outlier_options.addWidget(outlier_form.widget) outlier_options.addWidget(Spacer()) data_options.addWidget(outlier_options.widget) data_options.addWidget(Spacer()) tabs.addTab(data_options.widget, 'Data') # --------------- LEGEND CONFIGURATION # Legend configuration options legend_options = LayoutWidget(QHBoxLayout, style=styles.white_background) # Legend on/off checkbox growth_options = LayoutWidget(QVBoxLayout) growth_options.addWidget(TopLabel('Growth Legend:')) growth_form = Form() self.legend_toggle, self.legend_names, self.legend_title, self.extra_info, self.only_extra = growth_form.addRows( [ CheckBox('Legend on'), DropDown( 'Labels:', [], tooltip='Edit names by changing text and pressing return', edit=True), TextEntry( 'Heading:', tooltip='Show extra information from the file in the legend' ), DropDown('Extra text:', config.info_options), CheckBox('Remove labels') ], padding=[True, False, False, False, True]) growth_options.addWidget(growth_form.widget) growth_options.addWidget(Spacer()) legend_options.addWidget(growth_options.widget) # Condition legend configuration condition_options = LayoutWidget(QVBoxLayout) condition_options.addWidget(TopLabel('Condition legend:')) condition_form = Form() self.condition_legend_toggle, self.condition_legend_names, self.condition_legend_title, self.condition_extra_info, self.condition_only_extra = condition_form.addRows( [ CheckBox('Legend on'), DropDown( 'Labels:', [], tooltip='Edit names by changing text and pressing return', edit=True), TextEntry('Heading:'), DropDown( 'Extra text:', config.info_options, tooltip='Show extra information from the file in the legend' ), CheckBox('Remove labels') ], padding=[True, False, False, False, True]) condition_options.addWidget(condition_form.widget) condition_options.addWidget(Spacer()) legend_options.addWidget(condition_options.widget) legend_options.addWidget(Spacer()) tabs.addTab(legend_options.widget, 'Legend') # --------------- STYLE CONFIGURATION # Style configuration style_options = LayoutWidget(QHBoxLayout, style=styles.white_background) # Plot style dropdown menu style_form = Form(align=True) self.style_dropdown, self.font_dropdown, self.axis_colour, self.grid_toggle = style_form.addRows( [ DropDown('Style:', config.style_options), DropDown('Font style:', config.font_options), TextEntry('Condition axis color:'), CheckBox('Grid on/off') ], padding=[False, False, False, True]) style_options.addWidget(style_form.widget) # Sized style_numeric_form = Form(align=True) self.title_size, self.legend_size, self.label_size, self.line_width, self.marker_size, self.capsize, self.save_dpi = style_numeric_form.addRows( [ SpinBox('Title font size:', start=config.title_size, min_val=0, max_val=100), SpinBox('Legend font size:', start=config.legend_size, min_val=0, max_val=100), SpinBox('Label font size:', start=config.label_size, min_val=0, max_val=100), SpinBox('Line width:', start=config.line_width, min_val=0, max_val=20), SpinBox('Marker size:', start=config.marker_size, min_val=0, max_val=20), SpinBox('Error cap size:', start=config.capsize, min_val=0, max_val=20), SpinBox('Saved figure DPI:', start=config.save_dpi, min_val=10, max_val=2000) ]) style_options.addWidget(style_numeric_form.widget) tabs.addTab(style_options.widget, 'Style') # --------------- STATS CONFIGURATION # Stats configuration stats_form = Form(align=True, style=styles.white_background) self.std_err, self.sig_figs, self.show_fit_text, self.show_fit_result, self.show_fit_errors = stats_form.addRows( [ RadioButton( 'Standard deviation', 'Standard error', tooltip= 'Show standard deviation or the standard error on the mean in plots and measurements' ), SpinBox('Significant figures:', start=config.sig_figs, min_val=0, max_val=20), CheckBox( 'Show fit model text', tooltip='Checked = display equation for fitted model\n' 'Unchecked = don' 't display equation'), CheckBox( 'Show fit parameters', tooltip='Checked = show fitted values of model parameters\n' 'Unchecked = don' 't show fit parameters'), CheckBox( 'Show fit errors', tooltip='Checked = show uncertainties on fit parameters\n' 'Unchecked = don' 't show uncertainties') ], padding=[True, False, True, True, True]) tabs.addTab(stats_form.widget, 'Stats') # --------------- ADVANCED CONFIGURATION # Advanced configuration advanced_options = LayoutWidget(QHBoxLayout, style=styles.white_background) sg_form = Form(align=True, style=styles.white_background) _, self.sg_window_size, self.sg_order, self.sg_deriv, self.sg_rate = sg_form.addRows( [ TopLabel('Savitsky-Golay smoothing:'), TextEntry('Window size', default=config.sg_window_size), TextEntry('Order of polynomial', default=config.sg_order), TextEntry('Order of derivative', default=config.sg_deriv), TextEntry('Sample spacing', default=config.sg_rate) ]) adv_outlier_form = Form(align=True, style=styles.white_background) self.outlier_threshold = adv_outlier_form.addRow( TextEntry('Auto outlier threshold', default=config.outlier_threshold)) advanced_options.addWidget(sg_form.widget) advanced_options.addWidget(adv_outlier_form.widget) tabs.addTab(advanced_options.widget, 'Advanced') # ---------------------------------- self.setCentralWidget(tabs) self.show()