def val_changed(self, val_str): # Backup form state old_ma_unit, old_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, use_old_value=False) old_prevalence = self.current_prevalence new_text = self._get_txt_from_val_str(val_str) no_errors, display_scale_val = self._text_box_value_is_between_bounds(val_str, new_text) if no_errors is False: # There are errors self.restore_ma_unit_and_table(old_ma_unit,old_table, old_prevalence) calc_fncs.block_signals(self.entry_widgets, True) if val_str == "est": self.effect_txt_box.setFocus() elif val_str == "lower": self.low_txt_box.setFocus() elif val_str == "upper": self.high_txt_box.setFocus() elif val_str == "prevalence": self.prevalence_txt_box.setFocus() calc_fncs.block_signals(self.entry_widgets, False) return # If we got to this point it means everything is ok so far try: if display_scale_val not in EMPTY_VALS: display_scale_val = float(display_scale_val) else: display_scale_val = None except ValueError: # a number wasn't entered; ignore # should probably clear out the box here, too. print "fail." return None calc_scale_val = meta_py_r.diagnostic_convert_scale(display_scale_val, self.cur_effect, convert_to="calc.scale") if val_str == "est": self.ma_unit.set_effect(self.cur_effect, self.group_str, calc_scale_val) elif val_str == "lower": self.ma_unit.set_lower(self.cur_effect, self.group_str, calc_scale_val) elif val_str == "upper": self.ma_unit.set_upper(self.cur_effect, self.group_str, calc_scale_val) elif val_str == "prevalence": pass new_ma_unit, new_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, use_old_value=False) new_prevalence = self._get_prevalence_str() restore_old_f = lambda: self.restore_ma_unit_and_table(old_ma_unit, old_table, old_prevalence) restore_new_f = lambda: self.restore_ma_unit_and_table(new_ma_unit, new_table, new_prevalence) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command) self.current_prevalence = new_prevalence
def clear_form(self): # For undo/redo old_ma_unit, old_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, use_old_value=False) old_prevalence = self._get_prevalence_str() keys = ["c11", "c12", "r1sum", "c21", "c22", "r2sum", "c1sum", "c2sum", "total"] blank_vals = dict( zip(keys, [""]*len(keys)) ) self._set_vals(blank_vals) self._update_ma_unit() # clear out effects stuff for metric in DIAGNOSTIC_METRICS: self.ma_unit.set_effect_and_ci(metric, self.group_str, None, None, None, mult=self.mult) # clear line edits self.set_current_effect() self.prevalence_txt_box.blockSignals(True) self.prevalence_txt_box.setText("") self.prevalence_txt_box.blockSignals(False) calc_fncs.reset_table_item_flags(self.two_by_two_table) #self.enable_txt_box_input() new_ma_unit, new_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, use_old_value=False) new_prevalence = self._get_prevalence_str() restore_old_f = lambda: self.restore_ma_unit_and_table(old_ma_unit, old_table, old_prevalence) restore_new_f = lambda: self.restore_ma_unit_and_table(new_ma_unit, new_table, new_prevalence) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def clear_form(self): # For undo/redo old_ma_unit, old_table = self._save_ma_unit_and_table_state( table=self.raw_data_table, ma_unit=self.ma_unit, use_old_value=False) blank_vals = { "c11": "", "c12": "", "r1sum": "", "c21": "", "c22": "", "r2sum": "", "c1sum": "", "c2sum": "", "total": "" } self._set_vals(blank_vals) self._update_ma_unit() # clear out effects stuff for metric in BINARY_ONE_ARM_METRICS + BINARY_TWO_ARM_METRICS: if ((self.cur_effect in BINARY_TWO_ARM_METRICS and metric in BINARY_TWO_ARM_METRICS) or (self.cur_effect in BINARY_ONE_ARM_METRICS and metric in BINARY_ONE_ARM_METRICS)): self.ma_unit.set_effect_and_ci(metric, self.group_str, None, None, None, mult=self.mult) else: # TODO: Do nothing for now..... treat the case where we have to switch group strings down the line pass # clear line edits self.set_current_effect() calc_fncs.reset_table_item_flags(self.raw_data_table) ####self.enable_txt_box_input() new_ma_unit, new_table = self._save_ma_unit_and_table_state( table=self.raw_data_table, ma_unit=self.ma_unit, use_old_value=False) restore_old_f = lambda: self.restore_ma_unit_and_table( old_ma_unit, old_table) restore_new_f = lambda: self.restore_ma_unit_and_table( new_ma_unit, new_table) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def cell_changed(self, row, col): # tries to make sense of user input before passing # on to the R routine old_ma_unit, old_table = self._save_ma_unit_and_table_state( table=self.raw_data_table, ma_unit=self.ma_unit, old_value=self.current_item_data, row=row, col=col, use_old_value=True) try: # Test if entered data is valid (a number) warning_msg = self._cell_data_not_valid( self.raw_data_table.item(row, col).text()) if warning_msg: raise Exception("Invalid Cell Data") self._update_data_table( ) # calculate rest of table (provisionally) based on new entry warning_msg = self.check_table_consistency.run() if warning_msg: raise Exception("Table no longer consistent.") except Exception as e: msg = e.args[0] QMessageBox.warning(self.parent(), "whoops", msg) # popup warning self.restore_ma_unit_and_table( old_ma_unit, old_table) # brings things back to the way they were return # and leave self._update_ma_unit() # table widget --> ma_unit self.try_to_update_cur_outcome( ) # update metric in ma_unit and in table new_ma_unit, new_table = self._save_ma_unit_and_table_state( table=self.raw_data_table, ma_unit=self.ma_unit, row=row, col=col, use_old_value=False) #restore_f = self.restore_ma_unit_and_table #command = calc_fncs.CommandFieldChanged(old_ma_unit, new_ma_unit, old_table, new_table, restore_f=restore_f, parent=self) restore_old_f = lambda: self.restore_ma_unit_and_table( old_ma_unit, old_table) restore_new_f = lambda: self.restore_ma_unit_and_table( new_ma_unit, new_table) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def _cell_changed(self, row, col): old_ma_unit, old_tables_data = self._save_ma_unit_and_table_states( tables=self.tables, ma_unit=self.ma_unit, table=self.simple_table, row=row, col=col, old_value=self.current_item_data[self.simple_table], use_old_value=True) old_correlation = self._get_correlation_str() # Just for simple_table for now column_headers = self.get_column_header_strs() try: warning_msg = self._cell_data_not_valid( self.simple_table.item(row, col).text(), column_headers[col]) if warning_msg: raise Exception("Invalid Cell Data") self.impute_data() except Exception as e: msg = e.args[0] QMessageBox.warning(self.parent(), "whoops", msg) self.restore_ma_unit_and_tables(old_ma_unit, old_tables_data, old_correlation) return self._copy_raw_data_from_table_to_ma_unit() # table --> ma_unit self.try_to_update_cur_outcome() new_ma_unit, new_tables_data = self._save_ma_unit_and_table_states( tables=self.tables, ma_unit=self.ma_unit, table=self.simple_table, row=row, col=col, use_old_value=False) new_correlation = self._get_correlation_str() restore_old_f = lambda: self.restore_ma_unit_and_tables( old_ma_unit, old_tables_data, old_correlation) restore_new_f = lambda: self.restore_ma_unit_and_tables( new_ma_unit, new_tables_data, new_correlation) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def cell_changed(self, row, col): old_ma_unit, old_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, old_value = self.current_item_data, row = row, col = col, use_old_value=True) old_prevalence = self._get_prevalence_str() try: # Test if entered data is valid (a number) warning_msg = self.cell_data_invalid(self.two_by_two_table.item(row, col).text()) if warning_msg: raise Exception("Invalid Cell Data") self._update_data_table() # calculate rest of table (provisionally) based on new entry warning_msg = self.check_table_consistency.run() if warning_msg: raise Exception("Table no longer consistent.") except Exception as e: msg = e.args[0] QMessageBox.warning(self.parent(), "whoops", msg) #popup warning self.restore_ma_unit_and_table(old_ma_unit,old_table, old_prevalence) # brings things back to the way they were return # and leave # if we got here, everything seems ok self._update_ma_unit() # 2x2 table --> ma_unit self.impute_effects_in_ma_unit() # effects --> ma_unit self.set_current_effect() # ma_unit --> effects new_ma_unit, new_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, row = row, col = col, use_old_value = False) new_prevalence = self._get_prevalence_str() restore_old_f = lambda: self.restore_ma_unit_and_table(old_ma_unit, old_table, old_prevalence) restore_new_f = lambda: self.restore_ma_unit_and_table(new_ma_unit, new_table, new_prevalence) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def enable_back_calculation_btn(self, engage = False): # For undo/redo old_ma_unit, old_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, use_old_value=False) old_prevalence = self._get_prevalence_str() def build_dict(): d = {} for effect in BACK_CALCULATABLE_DIAGNOSTIC_EFFECTS: est,lower,upper = self.ma_unit.get_effect_and_ci(effect, self.group_str, self.mult) conv_to_disp_scale = lambda x: meta_py_r.diagnostic_convert_scale(x, effect, convert_to="display.scale") d_est,d_lower,d_upper = [conv_to_disp_scale(x) for x in [est,lower,upper]] for i,Rsubkey in enumerate(["",".lb",".ub"]): try: d["%s%s" % (effect.lower(), Rsubkey)] = float([d_est,d_lower,d_upper][i]) except: pass x = self.getTotalSubjects() d["total"] = float(x) if is_a_float(x) else None x = self.prevalence_txt_box.text() d["prev"] = float(x) if is_a_float(x) else None d["conf.level"] = self.global_conf_level # now grab the raw data, if available d.update(self.get_raw_diag_data()) return d def new_data(diag_data, imputed): new_data = (imputed["TP"], imputed["FP"], imputed["FN"], imputed["TN"]) old_data = (self._get_int(0,0), self._get_int(0,1), self._get_int(1,0), self._get_int(1,1), ) isBlank = lambda x: x in EMPTY_VALS new_item_available = lambda old, new: isBlank(old) and not isBlank(new) comparison = [new_item_available(old_data[i], new_data[i]) for i in range(len(new_data))] print("Comparison:", comparison) if any(comparison): changed = True else: changed = False return changed diag_data = build_dict() print("Diagnostic Data for back-calculation: ", diag_data) #if diag_data is not None: imputed = meta_py_r.impute_diag_data(diag_data) print "imputed data: %s" % imputed # Leave if nothing was imputed if not (imputed["TP"] or imputed["TN"] or imputed["FP"] or imputed["FN"]): print("Nothing could be imputed") self.back_calc_Btn.setEnabled(False) return None if new_data(diag_data, imputed): self.back_calc_Btn.setEnabled(True) else: self.back_calc_Btn.setEnabled(False) #self.set_clear_btn_color() if not engage: return None ######################################################################## # Actually do stuff with imputed data here if we are 'engaged' ######################################################################## self.update_2x2_table(imputed) self._update_data_table() self._update_ma_unit() #self.set_clear_btn_color() # For undo/redo new_ma_unit, new_table = self._save_ma_unit_and_table_state( table = self.two_by_two_table, ma_unit = self.ma_unit, use_old_value=False) new_prevalence = self._get_prevalence_str() restore_old_f = lambda: self.restore_ma_unit_and_table(old_ma_unit, old_table, old_prevalence) restore_new_f = lambda: self.restore_ma_unit_and_table(new_ma_unit, new_table, new_prevalence) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def enable_back_calculation_btn(self, engage=False): # For undo/redo old_ma_unit, old_table = self._save_ma_unit_and_table_state( table=self.raw_data_table, ma_unit=self.ma_unit, use_old_value=False) def build_back_calc_args_dict(): d = {} d["metric"] = str(self.cur_effect) est, lower, upper = self.ma_unit.get_effect_and_ci( self.cur_effect, self.group_str, self.mult) conv_to_disp_scale = lambda x: meta_py_r.binary_convert_scale( x, self.cur_effect, convert_to="display.scale") d_est, d_lower, d_upper = [ conv_to_disp_scale(x) for x in [est, lower, upper] ] for i, R_key in enumerate(["estimate", "lower", "upper"]): try: d["%s" % R_key] = float([d_est, d_lower, d_upper][i]) except: d["%s" % R_key] = None d["conf.level"] = self.global_conf_level d["Ev_A"] = float(self._get_int( 0, 0)) if not self._is_empty(0, 0) else None d["N_A"] = float(self._get_int( 0, 2)) if not self._is_empty(0, 2) else None d["Ev_B"] = float(self._get_int( 1, 0)) if not self._is_empty(1, 0) else None d["N_B"] = float(self._get_int( 1, 2)) if not self._is_empty(1, 2) else None return d def new_data(bin_data, imputed): changed = False old_data = (bin_data["Ev_A"], bin_data["N_A"], bin_data["Ev_B"], bin_data["N_B"]) new_data = [] new_data.append(( int(round(imputed["op1"]["a"])), int(round(imputed["op1"]["b"])), int(round(imputed["op1"]["c"])), int(round(imputed["op1"]["d"])), )) if "op2" in imputed: new_data.append(( int(round(imputed["op2"]["a"])), int(round(imputed["op2"]["b"])), int(round(imputed["op2"]["c"])), int(round(imputed["op2"]["d"])), )) def new_item_available(old, new): isBlank = lambda x: x in EMPTY_VALS no_longer_blank = isBlank(old) and not isBlank(new) return no_longer_blank comparison0 = [ new_item_available(old_data[i], new_data[0][i]) for i in range(len(old_data)) ] new_data_in_op1 = any(comparison0) print("Comparison0:", comparison0) if new_data_in_op1: changed = True if "op2" in imputed: comparison1 = [ new_item_available(old_data[i], new_data[1][i]) for i in range(len(old_data)) ] print("Comparison1:", comparison1) new_data_in_op2 = any(comparison1) if not new_data_in_op2: changed = False else: changed = False return changed ### end of new_data() definition #### # Makes no sense to show the button on a form where the back # calculation is not implemented if not self.cur_effect in ["OR", "RR", "RD"]: self.back_calc_btn.setVisible(False) return None else: self.back_calc_btn.setVisible(True) bin_data = build_back_calc_args_dict() print("Binary data for back-calculation:", bin_data) imputed = meta_py_r.impute_bin_data(bin_data.copy()) print("Imputed data: %s", imputed) # Leave if nothing was imputed if "FAIL" in imputed: print("Fail to impute") self.back_calc_btn.setEnabled(False) return None if new_data(bin_data, imputed): self.back_calc_btn.setEnabled(True) else: self.back_calc_btn.setEnabled(False) #self.set_clear_btn_color() if not engage: return None ######################################################################## # Actually do stuff with imputed data here if we are 'engaged' ######################################################################## for x in range(3): self.clear_column(x) # clear out the table if len(imputed.keys()) > 1: dialog = ChooseBackCalcResultForm(imputed, parent=self) if dialog.exec_(): choice = dialog.getChoice() else: # don't do anything if cancelled return None else: # only one option choice = "op1" # set values in table & save in ma_unit self.raw_data_table.blockSignals(True) self._set_val(0, 0, int(round(imputed[choice]["a"]))) self._set_val(0, 2, int(round(imputed[choice]["b"]))) self._set_val(1, 0, int(round(imputed[choice]["c"]))) self._set_val(1, 2, int(round(imputed[choice]["d"]))) self.raw_data_table.blockSignals(False) self._update_data_table() self._update_ma_unit() # save in ma_unit #self.set_clear_btn_color() # for undo/redo new_ma_unit, new_table = self._save_ma_unit_and_table_state( table=self.raw_data_table, ma_unit=self.ma_unit, use_old_value=False) restore_old_f = lambda: self.restore_ma_unit_and_table( old_ma_unit, old_table) restore_new_f = lambda: self.restore_ma_unit_and_table( new_ma_unit, new_table) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def enable_back_calculation_btn(self, engage=False): # For undo/redo old_ma_unit, old_tables_data = self._save_ma_unit_and_table_states( tables=[ self.simple_table, self.g1_pre_post_table, self.g2_pre_post_table ], ma_unit=self.ma_unit, use_old_value=False) old_correlation = self._get_correlation_str() # Choose metric parameter if not already chosen if (self.metric_parameter is None) and self.cur_effect in [ "MD", "SMD" ]: print("need to choose metric parameter because it is %s" % str(self.metric_parameter)) if self.cur_effect == "MD": info = "In order to perform back-calculation most accurately, we need to know something about the assumptions about the two population standard deviations.\n*Are we assuming that both of the population standard deviations are the same (as in most parametric data analysis techniques)" option0_txt = "yes (default)." option1_txt = "no" dialog = ChooseBackCalcResultForm(info, option0_txt, option1_txt) dialog.setWindowTitle("Population SD Assumptions") if dialog.exec_(): self.metric_parameter = True if dialog.getChoice( ) == 0 else False elif self.cur_effect == "SMD": info = "In order to perform back-calculation most accurately, we need to know if the the bias in the SMD been corrected i.e. should we use Hedge's g or Cohen's d when performing the back calculation?" option0_txt = "Hedges' g (default)" option1_txt = "Cohen's d" dialog = ChooseBackCalcResultForm(info, option0_txt, option1_txt) dialog.setWindowTitle("SMD bias correction") if dialog.exec_(): self.metric_parameter = True if dialog.getChoice( ) == 0 else False print("metric_parameter is now %s" % str(self.metric_parameter)) def build_data_dicts(): var_names = self.get_column_header_strs() tmp = [] for row_index in range(2): value = lambda x: self._get_float(row_index, x) tmp.append([(var_name, value(i)) for i, var_name in enumerate(var_names) if value(i) is not None]) group1_data = dict(tmp[0]) group2_data = dict(tmp[1]) tmp = self.ma_unit.get_effect_and_ci(self.cur_effect, self.group_str, self.mult) effect_data = { "est": tmp[0], "low": tmp[1], "high": tmp[2], "metric": self.cur_effect, "met.param": self.metric_parameter } #print("Group 1 Data: ", group1_data) #print("Group 2 Data: ", group2_data) #print("Effect Data: ", effect_data) return (group1_data, group2_data, effect_data) def new_data(g1_data, g2_data, imputed): changed = False new_data = (imputed["n1"], imputed["sd1"], imputed["mean1"], imputed["n2"], imputed["sd2"], imputed["mean2"]) old_data = ( g1_data["n"] if "n" in g1_data else None, g1_data["sd"] if "sd" in g1_data else None, g1_data["mean"] if "mean" in g1_data else None, g2_data["n"] if "n" in g2_data else None, g2_data["sd"] if "sd" in g2_data else None, g2_data["mean"] if "mean" in g2_data else None, ) new_item_available = lambda old, new: (old is None) and (new is not None) comparison = [ new_item_available(old_data[i], new_data[i]) for i in range(len(new_data)) ] print("Comparison:", comparison) if any(comparison): changed = True else: changed = False return changed if self.cur_effect not in ["MD", "SMD"]: self.back_calc_btn.setVisible(False) return None else: self.back_calc_btn.setVisible(True) (group1_data, group2_data, effect_data) = build_data_dicts() imputed = meta_py_r.back_calc_cont_data(group1_data, group2_data, effect_data, self.conf_level) print("Imputed data: ", imputed) # Leave if there was a failure if "FAIL" in imputed: print("Failure to impute") self.back_calc_btn.setEnabled(False) return None if new_data(group1_data, group2_data, imputed): self.back_calc_btn.setEnabled(True) else: self.back_calc_btn.setEnabled(False) self.set_clear_btn_color() if not engage: return None ######################################################################## # Actually do stuff with imputed data here if we are 'engaged' ######################################################################## # Choose one of the values if multiple ones were returned in the output keys_to_names = { "n1": "group 1 sample size", "n2": "group 2 sample size", "sd1": "group 1 standard deviation", "sd2": "group 2 standard deviation", "mean1": "group 1 mean", "mean2": "group 2 mean" } for key, value in imputed.iteritems(): # TODO: (maybe).....: The R code which generates results can # POTENTIALLY yield a maximum of 4 numbers for n1 and n2. However, # empirical testing has shown that this doesn't really happen. # However, for completeness in the future the number of # ChooseBackCalcResultForm options should be generated dynamically if is_list(value): info = ( "The back calculation has resulted in multiple results for " + keys_to_names[key] + "\n\nPlease choose one of the following:") option0_txt = keys_to_names[key] + " = " + str(value[0]) option1_txt = keys_to_names[key] + " = " + str(value[1]) print("Options (0,1)", value[0], value[1]) dialog = ChooseBackCalcResultForm(info, option0_txt, option1_txt) if dialog.exec_(): imputed[key] = value[0] if dialog.getChoice( ) == 0 else value[1] else: # pressed cancel return None # do nothing and leave # Write the data to the table var_names = self.get_column_header_strs() group1_data = { "n": imputed["n1"], "sd": imputed["sd1"], "mean": imputed["mean1"] } group2_data = { "n": imputed["n2"], "sd": imputed["sd2"], "mean": imputed["mean2"] } for row in range(len(self.cur_groups)): for var_index, var_name in enumerate(var_names): if var_name not in ["n", "sd", "mean"]: continue val = group1_data[var_name] if row == 0 else group2_data[ var_name] if var_name == 'n' and val not in EMPTY_VALS: val = int(round(val)) # convert float to integer self._set_val(row, var_index, val, self.simple_table) self.impute_data() self._copy_raw_data_from_table_to_ma_unit() #self.set_clear_btn_color() # For undo/redo self.enable_back_calculation_btn() new_ma_unit, new_tables_data = self._save_ma_unit_and_table_states( tables=[ self.simple_table, self.g1_pre_post_table, self.g2_pre_post_table ], ma_unit=self.ma_unit, use_old_value=False) new_correlation = self._get_correlation_str() restore_old_f = lambda: self.restore_ma_unit_and_tables( old_ma_unit, old_tables_data, old_correlation) restore_new_f = lambda: self.restore_ma_unit_and_tables( new_ma_unit, new_tables_data, new_correlation) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def impute_pre_post_data(self, table, group_index, row=None, col=None): ''' The row index corresponds to the group that will be affected by the data edits. E.g., a row index of 0 will result in the data for the first group (row 0 in the simple_table) being modified. ''' if not (row, col) == ( None, None ): # means this was called through user interaction, not programmatically old_ma_unit, old_tables_data = self._save_ma_unit_and_table_states( tables=self.tables, ma_unit=self.ma_unit, table=table, row=row, col=col, old_value=self.current_item_data[table], use_old_value=True) old_correlation = self._get_correlation_str() group_name = self.cur_groups[group_index] var_names = self.get_column_header_strs_pre_post() params_dict = {} # A, B correspond to pre, post for a_b_index, a_b_name in enumerate(["A", "B"]): # assemble the fields in a dictionary; pass off to meta_py_r for var_index, var_name in enumerate(var_names): var_value = self._get_float(a_b_index, var_index, table) if var_value is not None: params_dict["%s.%s" % (var_name, a_b_name)] = var_value params_dict['metric'] = ("'%s'" % self.cur_effect) # now pass off what we have for this study to the # imputation routine results_from_r = meta_py_r.impute_pre_post_cont_data( params_dict, float(self.correlation_pre_post.text()), self.conf_level_to_alpha()) print "imputation results from R: %s" % results_from_r if not results_from_r["succeeded"]: return None print("Prepost-imputation succeeded") ### # first update the simple table computed_vals = results_from_r["output"] for var_index, var_name in enumerate(self.get_column_header_strs()): val = computed_vals[var_name] self._set_val(group_index, var_index, val) # update the raw data for N, mean and SD fields (this is all that is actually stored) if var_index < 3: self.ma_unit.get_raw_data_for_group( group_name)[var_index] = computed_vals[var_name] # self.try_to_update_cur_outcome() ### # also update the pre/post tables pre_vals = results_from_r["pre"] post_vals = results_from_r["post"] for var_index, var_name in enumerate(var_names): pre_val = pre_vals[var_name] post_val = post_vals[var_name] self._set_val(0, var_index, pre_val, table) self._set_val(1, var_index, post_val, table) self._copy_raw_data_from_table_to_ma_unit() self.set_clear_btn_color() # function was invoked as a result of user interaction, not # programmatically if not (row, col) == (None, None): new_ma_unit, new_tables_data = self._save_ma_unit_and_table_states( tables=self.tables, ma_unit=self.ma_unit, table=table, row=row, col=col, use_old_value=False) new_correlation = self._get_correlation_str() restore_old_f = lambda: self.restore_ma_unit_and_tables( old_ma_unit, old_tables_data, old_correlation) restore_new_f = lambda: self.restore_ma_unit_and_tables( new_ma_unit, new_tables_data, new_correlation) command = calc_fncs.CommandFieldChanged( restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)
def val_changed(self, val_str): # Backup form state old_ma_unit, old_tables_data = self._save_ma_unit_and_table_states( tables=[ self.simple_table, self.g1_pre_post_table, self.g2_pre_post_table ], ma_unit=self.ma_unit, use_old_value=False) old_correlation = self.current_correlation new_text = self._get_txt_from_val_str(val_str) no_errors, display_scale_val = self._text_box_value_is_between_bounds( val_str, new_text) if no_errors is False: print("There was an error while in val_changed") self.restore_ma_unit_and_tables(old_ma_unit, old_tables_data, old_correlation) calc_fncs.block_signals(self.entry_widgets, True) if val_str == "est": self.effect_txt_box.setFocus() elif val_str == "lower": self.low_txt_box.setFocus() elif val_str == "upper": self.high_txt_box.setFocus() elif val_str == "correlation_pre_post": self.correlation_pre_post.setFocus() calc_fncs.block_signals(self.entry_widgets, False) return # If we got to this point it means everything is ok so far try: if display_scale_val not in EMPTY_VALS: display_scale_val = float(display_scale_val) else: display_scale_val = None except ValueError: # a number wasn't entered; ignore # should probably clear out the box here, too. print "fail." return None calc_scale_val = meta_py_r.continuous_convert_scale( display_scale_val, self.cur_effect, convert_to="calc.scale") if val_str == "est": self.ma_unit.set_effect(self.cur_effect, self.group_str, calc_scale_val) elif val_str == "lower": self.ma_unit.set_lower(self.cur_effect, self.group_str, calc_scale_val) elif val_str == "upper": self.ma_unit.set_upper(self.cur_effect, self.group_str, calc_scale_val) elif val_str == "correlation_pre_post": print "ok -- correlation set to %s" % self.correlation_pre_post.text( ) # Recompute the estimates self.impute_pre_post_data(self.g1_pre_post_table, 0) self.impute_pre_post_data(self.g2_pre_post_table, 1) self.impute_data() #### experimental new_ma_unit, new_tables_data = self._save_ma_unit_and_table_states( tables=[ self.simple_table, self.g1_pre_post_table, self.g2_pre_post_table ], ma_unit=self.ma_unit, use_old_value=False) new_correlation = self._get_correlation_str() restore_old_f = lambda: self.restore_ma_unit_and_tables( old_ma_unit, old_tables_data, old_correlation) restore_new_f = lambda: self.restore_ma_unit_and_tables( new_ma_unit, new_tables_data, new_correlation) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command) self.current_correlation = new_correlation
def clear_form(self): # For undo/redo old_ma_unit, old_tables_data = self._save_ma_unit_and_table_states( tables=[ self.simple_table, self.g1_pre_post_table, self.g2_pre_post_table ], ma_unit=self.ma_unit, use_old_value=False) old_correlation = self._get_correlation_str() self.metric_parameter = None # } these two should go together self.enable_txt_box_input() # } calc_fncs.block_signals(self.entry_widgets, True) # reset tables for table in self.tables: for row_index in range(len(self.cur_groups)): for var_index in range(table.columnCount()): self._set_val(row_index, var_index, "", table=table) calc_fncs.block_signals(self.entry_widgets, False) self._copy_raw_data_from_table_to_ma_unit() # clear out effects stuff for metric in CONTINUOUS_ONE_ARM_METRICS + CONTINUOUS_TWO_ARM_METRICS: if ((self.cur_effect in CONTINUOUS_TWO_ARM_METRICS and metric in CONTINUOUS_TWO_ARM_METRICS) or (self.cur_effect in CONTINUOUS_ONE_ARM_METRICS and metric in CONTINUOUS_ONE_ARM_METRICS)): self.ma_unit.set_effect_and_ci(metric, self.group_str, None, None, None, mult=self.mult) else: # TODO: Do nothing for now..... treat the case where we have to switch group strings down the line pass # clear line edits self.set_current_effect() calc_fncs.block_signals(self.entry_widgets, True) self.correlation_pre_post.setText("0.0") calc_fncs.block_signals(self.entry_widgets, False) # For undo/redo self.enable_back_calculation_btn() new_ma_unit, new_tables_data = self._save_ma_unit_and_table_states( tables=[ self.simple_table, self.g1_pre_post_table, self.g2_pre_post_table ], ma_unit=self.ma_unit, use_old_value=False) new_correlation = self._get_correlation_str() restore_old_f = lambda: self.restore_ma_unit_and_tables( old_ma_unit, old_tables_data, old_correlation) restore_new_f = lambda: self.restore_ma_unit_and_tables( new_ma_unit, new_tables_data, new_correlation) command = calc_fncs.CommandFieldChanged(restore_new_f=restore_new_f, restore_old_f=restore_old_f, parent=self) self.undoStack.push(command)