def __init__(self, resultMap): QDialog.__init__(self) self.setupUi(self) self.settings = RaseSettings() self.headerLabels = [ 'File', 'Tp', 'Fn', 'Fp', 'Precision', 'Recall', 'Fscore', 'IDs' ] self.NUM_COLS = len(self.headerLabels) self.session = Session() self.tblDetailedResults.setContextMenuPolicy(Qt.CustomContextMenu) self.tblDetailedResults.setColumnCount(self.NUM_COLS) self.tblDetailedResults.setHorizontalHeaderLabels(self.headerLabels) self.tblDetailedResults.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.tblDetailedResults.setRowCount(0) row = 0 for file in resultMap: results = resultMap[file] results.insert(0, file) self.tblDetailedResults.insertRow(row) for col in range(self.NUM_COLS): self.tblDetailedResults.setItem(row, col, QTableWidgetItem(results[col])) row = row + 1 results.pop(0) self.tblDetailedResults.resizeColumnsToContents() self.tblDetailedResults.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.buttonOK.clicked.connect(self.closeSelected) self.buttonExport.clicked.connect(self.handleExport)
def viewResults(r, scenIdall, detector): """ Opens Results table """ # need a correspondence table in order to display results! session = Session() settings = RaseSettings() default_corr_table = session.query(CorrespondenceTable).filter_by( is_default=True).one_or_none() if not default_corr_table: msgbox = QMessageBox( QMessageBox.Question, 'No Correspondence Table set!', 'No correspondence table set! Would you like to set a correspondence table now?' ) msgbox.addButton(QMessageBox.Yes) msgbox.addButton(QMessageBox.No) answer = msgbox.exec() if answer == QMessageBox.Yes: CorrespondenceTableDialog().exec_() settings.setIsAfterCorrespondenceTableCall(True) else: return selected_scenarios = scenIdall r.calculateScenarioStats(1, selected_scenarios, detector) ViewResultsDialog(r, selected_scenarios, detector).exec_()
def make_scenIdall(session, input_data): settings = RaseSettings() detector = session.query(Detector).filter_by( name=input_data['instrument']).first() repeat_scens = [] for bkgd_data in input_data['background']: bkgd = bkgd_data[0] repeat_scens = repeat_scens + session.query(Scenario).join( ScenarioMaterial).join(ScenarioBackgroundMaterial).filter( Scenario.acq_time == float(input_data['dwell_time'])).filter( ScenarioMaterial.fd_mode == input_data['source_fd'], ScenarioMaterial.material_name == input_data['source']).filter( ScenarioBackgroundMaterial.fd_mode == bkgd[0], ScenarioBackgroundMaterial.material_name == bkgd[1].name, ScenarioBackgroundMaterial.dose == bkgd[2]).all() common_scens = [ x for x in set(repeat_scens) if repeat_scens.count(x) == len(input_data['background']) ] scenIdall = [] for scen in common_scens: results_dir = get_results_dir(settings.getSampleDirectory(), detector, scen.id) if files_endswith_exists(results_dir, (".n42", ".res")): scenIdall.append(scen.id) return scenIdall
def __init__(self, parent): QDialog.__init__(self, parent) self.settings = RaseSettings() self.setupUi(self) self.txtDataDir.setReadOnly(True) self.txtDataDir.setText(self.settings.getDataDirectory()) self.dataDirectoryChanged = False self.algoDictionary = {} algoCount = 0 for name, data in inspect.getmembers(sampling_algos, predicate=inspect.isfunction): try: readable_name = data.__doc__.splitlines()[0].strip() if readable_name == '': raise Exception("") except: readable_name = name self.downSapmplingAlgoComboBox.addItem(readable_name) self.algoDictionary[algoCount] = data if data == self.settings.getSamplingAlgo(): self.downSapmplingAlgoComboBox.setCurrentIndex(algoCount) algoCount += 1 self.algorithmSelected = False self.downSapmplingAlgoComboBox.currentIndexChanged.connect( self.chooseSamplingAlgo)
def test_set_db_loc(self): """ Verifies that the database location can be set """ import os data_dir = os.getcwd() settings = RaseSettings() settings.setDataDirectory(data_dir) assert data_dir == settings.getDataDirectory()
def __init__(self, parent = None): QDialog.__init__(self) self.parent = parent self.session = Session() self.settings = RaseSettings() self.setupUi(self) self.setReplaysTable() self.deleteSelectedReplaysButton.clicked.connect(self.deleteSelectedReplays) self.btnOK.clicked.connect(self.oK) self.buttonExport.clicked.connect(self.handleExport) self.buttonImport.clicked.connect(self.handleImport) self.addNewReplayButton.clicked.connect(self.on_btnNewReplay_clicked)
def __init__(self): QDialog.__init__(self) self.setupUi(self) self.settings = RaseSettings() self.NUM_COLS = 3 self.tableEdited = False self.session = Session() # Query the entries in the current default table corTableRows = self.readCorrTableRows() if not corTableRows: self.NUM_ROWS = 0 else: self.NUM_ROWS = corTableRows.count() self.tblCCCLists.setItemDelegate( Delegate(self.tblCCCLists, isotopeCol=0)) self.tblCCCLists.setRowCount(self.NUM_ROWS) self.tblCCCLists.setColumnCount(self.NUM_COLS) self.columnLabels = ['Source', 'Correct ID', 'Allowed ID'] self.tblCCCLists.setHorizontalHeaderLabels(self.columnLabels) self.tblCCCLists.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.tblCCCLists.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) self.tblCCCLists.setContextMenuPolicy(Qt.CustomContextMenu) self.tblCCCLists.customContextMenuRequested.connect(self.openMenu) self.tblCCCLists.setSortingEnabled(False) if corTableRows: for row, line in enumerate(corTableRows): self.tblCCCLists.setItem(row, 0, QTableWidgetItem(line.isotope)) self.tblCCCLists.setItem(row, 1, QTableWidgetItem(line.corrList1)) self.tblCCCLists.setItem(row, 2, QTableWidgetItem(line.corrList2)) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.btnAddRow.clicked.connect(self.addRow) self.populateDefaultComboBox() self.setSaveAsTableName() self.buttonImport.clicked.connect(self.handleImport) self.buttonExport.clicked.connect(self.handleExport) self.buttonApplyDefaultSetting.clicked.connect(self.applySettings) self.btnDeleteSelected.clicked.connect(self.deleteSelected) self.btnClose.clicked.connect(self.closeSelected)
def __init__(self, parent): QDialog.__init__(self, parent) self.settings = RaseSettings() self.setupUi(self) self.txtRandomVal.setText(str(self.settings.getRandomSeed())) if self.settings.getRandomSeedFixed(): self.txtRandomVal.setEnabled(True) self.checkBox.setChecked(True) else: self.txtRandomVal.setDisabled(True) self.checkBox.setChecked(False) self.checkBox.stateChanged.connect(self.checkChanged) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject)
def check_edge_ids(session, replications, start_list, end_list, edge_ids, detector): """Check if there are results ready for values on the rising edge of the S-curve""" settings = RaseSettings() counter = [0] * 3 for i, ids_list in enumerate([edge_ids, start_list, end_list]): for id in ids_list: scen = session.query(Scenario).filter_by(id=id).first() results_dir = get_results_dir(settings.getSampleDirectory(), detector, id) if files_endswith_exists( results_dir, (".n42", ".res")) and scen.replication >= replications: counter[i] += 1 return counter[0], counter[1], counter[2]
def accept(self): """ Stores the selected values in the RaseSettings class """ selected = [cb.text().replace('&&', '&') for cb in self.cb_list if cb.isChecked()] RaseSettings().setResultsTableSettings(selected) return QDialog.accept(self)
def cleanup_scenarios(rangefind_rep, scenIds): """Remove scenarios from the database that were rangefinders, i.e.: low replication scenarios""" settings = RaseSettings() session = Session() scenarios = [] for scen in scenIds: scenarios.append(session.query(Scenario).filter_by(id=scen).first()) scens_to_delete = [] for scen in scenarios: if scen.replication == rangefind_rep: scens_to_delete.append(scen.id) delete_scenario(scens_to_delete, settings.getSampleDirectory()) session.commit()
def set_current_settings(self): """ Loads and apply the stored settings """ for cb in self.cb_list: if cb.text().replace('&&', '&') in RaseSettings().getResultsTableSettings(): cb.setChecked(True) else: cb.setChecked(False)
def handleExport(self): """ Exports Results Dataframe to CSV format """ path = QFileDialog.getSaveFileName(self, 'Save File', RaseSettings().getDataDirectory(), 'CSV (*.csv)') if path[0]: df = self.parent.scenario_stats_df.copy() df['Scen Desc'] = df['Scen Desc'].apply(lambda x: re.sub('<[^<]+?>', '', x)) df.to_csv(path[0])
def reboot_database(): """Delete and recreate the database between test classes""" settings = RaseSettings() if os.path.isdir(settings.getSampleDirectory()): shutil.rmtree(settings.getSampleDirectory()) if os.path.isfile(settings.getDatabaseFilepath()): os.remove(settings.getDatabaseFilepath()) initializeDatabase(settings.getDatabaseFilepath())
def reset_data(self, data): """ Reset and reformat the data. Should be called always after the data have been recomputed or columns selection changed :param data: the new input pandas dataframe from the identification results analysis """ self.layoutAboutToBeChanged.emit() self._data = data.copy() self.col_settings = RaseSettings().getResultsTableSettings() self._reformat_data() self.layoutChanged.emit()
def __init__(self, parent=None): QDialog.__init__(self) self.parent = parent self.session = Session() self.settings = RaseSettings() self.setupUi(self) self.setWeightsTable() self.check_usemweights.setChecked( self.settings.getUseMWeightsInCalcs()) self.check_useconfs.setChecked( self.settings.getUseConfidencesInCalcs()) self.btnDeleteSelectedMaterials.clicked.connect( self.deleteSelectedMaterials) self.buttonExport.clicked.connect(self.handleExport) self.buttonImport.clicked.connect(self.handleImport) self.btnAddNewMaterial.clicked.connect(self.on_btnNewMaterial_clicked) self.setWindowTitle('Modify Material Weights') self.materialsToDelete = []
def __init__(self, parent, replay=None, resultsTranslator=None): QDialog.__init__(self, parent) self.parent = parent self.setupUi(self) self.settings = RaseSettings() self.replay = replay self.resultsTranslator = resultsTranslator if replay: self.setWindowTitle('Edit Replay Software') self.txtName.setReadOnly(True) self.txtName.setText(replay.name) self.txtCmdLine.setText(replay.exe_path) self.txtSettings.setText(replay.settings) self.cbCmdLine.setChecked(bool(replay.is_cmd_line)) self.txtTemplatePath.setText(replay.n42_template_path) self.txtFilenameSuffix.setText(replay.input_filename_suffix) if resultsTranslator: self.txtResultsTranslator.setText(resultsTranslator.exe_path) self.txtSettings_3.setText(resultsTranslator.settings) self.cbCmdLine_3.setChecked(bool(resultsTranslator.is_cmd_line))
def __init__(self, parent=None, modify_flag=False): QDialog.__init__(self) self.parent = parent self.modify_flag = modify_flag self.session = Session() self.settings = RaseSettings() self.setupUi(self) self.setInfluencesTable() self.btnDeleteSelectedInfluences.clicked.connect( self.deleteSelectedInfluences) self.buttonExport.clicked.connect(self.handleExport) self.buttonImport.clicked.connect(self.handleImport) self.btnAddNewInfluence.clicked.connect( self.on_btnNewInfluence_clicked) if self.modify_flag: self.setWindowTitle('Modify Influences') else: self.setWindowTitle('Add Influences') self.influencesToDelete = []
def __init__(self, session): QDialog.__init__(self) self.setupUi(self) self.buttonBox.addButton("Create", QDialogButtonBox.AcceptRole) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) self.settings = RaseSettings() # TODO: Add a delegate to the flux column as well; doing so now via a simple copy and paste operation is # creating a SIGSEGV self.sourceTable.setItemDelegateForColumn(hh['dose'], PositiveDoubleDelegate()) self.sourceTable.setSelectionBehavior(QAbstractItemView.SelectRows) self.sourceTable.setColumnHidden( hh['folder'], True) # folder is hidden but shown as tooltip on filename cell self.txtVendorID.setValidator( QRegExpValidator(QRegExp('[a-zA-Z0-9]{0,4}'))) self.txtModelID.setValidator( QRegExpValidator(QRegExp('[a-zA-Z0-9]{0,3}'))) self.btnRemoveSrc.clicked.connect(self.delete_selected) self.sourceTable.itemChanged.connect(self.update_base_fname) self.txtVendorID.textChanged.connect(self.update_base_fname_all) self.txtModelID.textChanged.connect(self.update_base_fname_all) self.btnExport.clicked.connect(self.handleExport) self.btnImport.clicked.connect(self.handleImport) self.btnClearBkgSel.clicked.connect(self.clear_background_selection) self.sourceTable.itemSelectionChanged.connect( self.activate_SetAsBkg_button) self.backgroundFileName = None self.backgroundFileFolder = None self.unselectedBkgColor = None self.btnSetAsBkg.setEnabled(False)
def __init__(self, tblMat, materialCol, intensityCol=-1, unitsCol=2, selected_detname=None, editable=False, auto_s=False): QItemDelegate.__init__(self) self.tblMat = tblMat self.matCol = materialCol self.intensityCol = intensityCol self.unitsCol = unitsCol self.editable = editable self.selected_detname = selected_detname self.auto_s = auto_s self.settings = RaseSettings()
class RandomSeedDialog(ui_input_random_seed.Ui_InputRandomSeedDialog, QDialog): def __init__(self, parent): QDialog.__init__(self, parent) self.settings = RaseSettings() self.setupUi(self) self.txtRandomVal.setText(str(self.settings.getRandomSeed())) if self.settings.getRandomSeedFixed(): self.txtRandomVal.setEnabled(True) self.checkBox.setChecked(True) else: self.txtRandomVal.setDisabled(True) self.checkBox.setChecked(False) self.checkBox.stateChanged.connect(self.checkChanged) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) @pyqtSlot() def accept(self): randomText = self.txtRandomVal.text() if randomText and self.is_number(randomText) and float(randomText) >= 1 and float(randomText) <= pow(2,30): self.settings.setRandomSeed(int(float(randomText))) self.settings.setRandomSeedFixed(self.checkBox.isChecked()) super().accept() else: QMessageBox.information(self, 'Invalid Random Seed Value', 'seed value must be numeric between 1 and 1,073,741,824') super().accept() dialog = RandomSeedDialog(self) dialog.exec_() @pyqtSlot() def reject(self): super().accept() def checkChanged(self): """ enables txtRandomVal IFF the box is checked """ if self.checkBox.isChecked(): self.txtRandomVal.setEnabled(True) else: self.txtRandomVal.setDisabled(True) def is_number(self,s): """ returns True if string is a number. """ try: float(s) return True except ValueError: return False
def handleExport(self): """ Exports to CSV """ path = QFileDialog.getSaveFileName(self, 'Save File', RaseSettings().getDataDirectory(), 'CSV (*.csv)') if path[0]: with open(path[0], mode='w', newline='') as stream: writer = csv.writer(stream) writer.writerow(self.columnLabelList) for row in range(self.tblResults.rowCount()): rowdata = [] for column in range(self.tblResults.columnCount()): item = self.tblResults.item(row, column) if item is not None: rowdata.append(item.text()) else: rowdata.append('') writer.writerow(rowdata)
def __init__(self, parent): QDialog.__init__(self, parent) cols_list = ['Det/Replay', 'Scen Desc', 'Dose', 'Flux', 'Background Dose', 'Background Flux', 'Infl', 'AcqTime', 'Repl', 'PID', 'PID CI', 'C&C', 'C&C CI', 'TP', 'FP', 'FN', 'Precision', 'Recall', 'F_Score', 'wTP', 'wFP', 'wFN', 'wPrecision', 'wRecall', 'wF_Score'] # QT treats the ampersand symbol as a special character, so it needs special treatment self.cb_list = [QCheckBox(v.replace('&', '&&')) for v in cols_list] layout = QVBoxLayout() for cb in self.cb_list: # if not (cb.text() == self.not_fd_mode): layout.addWidget(cb) self.buttonBox = QDialogButtonBox(self) self.buttonBox.setStandardButtons(QDialogButtonBox.Cancel|QDialogButtonBox.Ok) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) layout.addWidget(self.buttonBox) self.setLayout(layout) if RaseSettings().getResultsTableSettings(): self.set_current_settings() else: self.set_default()
def __init__(self, parent, scenario, detector, selected, file_list=None): QDialog.__init__(self, parent) self.setupUi(self) self.scenario = scenario self.detector = detector self.selected = selected self.session = Session() self.json_file = os.path.join(get_bundle_dir(), "d3_resources", "spectrum.json") self.index = selected self.file_list = file_list if not self.file_list: sample_path = get_sample_dir(RaseSettings().getSampleDirectory(), self.detector, self.scenario.id) self.file_list = glob.glob(os.path.join(sample_path, "*.n42")) self.file_list.sort(key=natural_keys) self.browser = WebSpectraView(self) self.plot_spectrum() self.plot_layout = QVBoxLayout(self.widget) self.plot_layout.addWidget(self.browser) self.widget.setFocus()
def complete_tests(): """Make sure no sample spectra are left after the final test is run""" settings = RaseSettings() original_data_dir = settings.getDataDirectory() settings.setDataDirectory(os.path.join(os.getcwd(), '__temp_test_rase')) yield None # anything before this line will be run prior to the tests print('CLEANING UP') # run after the last test settings = RaseSettings() if os.path.isdir(settings.getSampleDirectory()): shutil.rmtree(settings.getSampleDirectory()) if os.path.isfile(settings.getDatabaseFilepath()): os.remove(settings.getDatabaseFilepath()) settings.setDataDirectory(original_data_dir) print('CLEANUP COMPLETE')
class ManageInfluencesDialog(ui_manage_influences_dialog.Ui_Dialog, QDialog): def __init__(self, parent=None, modify_flag=False): QDialog.__init__(self) self.parent = parent self.modify_flag = modify_flag self.session = Session() self.settings = RaseSettings() self.setupUi(self) self.setInfluencesTable() self.btnDeleteSelectedInfluences.clicked.connect( self.deleteSelectedInfluences) self.buttonExport.clicked.connect(self.handleExport) self.buttonImport.clicked.connect(self.handleImport) self.btnAddNewInfluence.clicked.connect( self.on_btnNewInfluence_clicked) if self.modify_flag: self.setWindowTitle('Modify Influences') else: self.setWindowTitle('Add Influences') self.influencesToDelete = [] def setInfluencesTable(self): influences = list(self.session.query(DetectorInfluence)) if self.tblInfluences: self.tblInfluences.clear() self.tblInfluences.setColumnCount(NUM_COL) self.tblInfluences.setRowCount(len(influences)) self.tblInfluences.setHorizontalHeaderLabels([ 'Name', 'Infl_0\n(offset)', 'Drift\n(Infl_0)', 'Infl_1\n(linear)', 'Drift\n(Infl_1)', 'Infl_2\n(quadratic)', 'Drift\n(Infl_2)', 'Fixed Smear\n(Eres, keV)', 'Drift\n(Fixed Smear)', 'Linear Smear\n(Eres, %)', 'Drift\n(Linear Smear)' ]) self.tblInfluences.setSelectionBehavior(QAbstractItemView.SelectRows) self.tblInfluences.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) row = 0 if self.modify_flag: union = Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled else: union = Qt.ItemIsSelectable | Qt.ItemIsEnabled for influence in influences: item = QTableWidgetItem(QTableWidgetItem(influence.influence_name)) item.setFlags(Qt.ItemIsSelectable | Qt.ItemIsEnabled) self.tblInfluences.setItem(row, NAME, item) for (col, infl) in zip(COLUMNS[1:], [ str(influence.infl_0), str(influence.degrade_infl0), str(influence.infl_1), str(influence.degrade_infl1), str(influence.infl_2), str(influence.degrade_infl2), str(influence.fixed_smear), str(influence.degrade_f_smear), str(influence.linear_smear), str(influence.degrade_l_smear) ]): item = QTableWidgetItem(infl) item.setFlags(union) self.tblInfluences.setItem(row, col, item) row += 1 self.tblInfluences.setColumnWidth(INFL_2, 80) self.tblInfluences.setColumnWidth(FIX_SMEAR, 90) self.tblInfluences.setColumnWidth(DEGRADE_FIX_SMEAR, 90) self.tblInfluences.setColumnWidth(LIN_SMEAR, 90) self.tblInfluences.setColumnWidth(DEGRADE_LIN_SMEAR, 90) def on_btnNewInfluence_clicked(self, checked): """ Adds new influence row that is fully editable """ row = self.tblInfluences.rowCount() self.tblInfluences.insertRow(row) union = Qt.ItemIsSelectable | Qt.ItemIsEditable | Qt.ItemIsEnabled for col in COLUMNS: item = QTableWidgetItem() item.setFlags(union) if col != NAME and col != INFL_1: item.setText('0.0') elif col == INFL_1: item.setText('1.0') self.tblInfluences.setItem(row, col, item) def handleExport(self): """ Exports to CSV """ path = QFileDialog.getSaveFileName(self, 'Save File', self.settings.getDataDirectory(), 'CSV (*.csv)') if path[0]: with open(path[0], mode='w', newline='') as stream: writer = csv.writer(stream) for row in range(self.tblInfluences.rowCount()): rowdata = [] for column in range(self.tblInfluences.columnCount()): item = self.tblInfluences.item(row, column) if item is not None: rowdata.append(item.text()) else: rowdata.append('') writer.writerow(rowdata) def handleImport(self): """ Imports from CSV """ path = QFileDialog.getOpenFileName(self, 'Open File', self.settings.getDataDirectory(), 'CSV(*.csv)') if path[0]: # FIXME: This doesn't check in any way that the format of the file is correct with open(path[0], mode='r') as stream: self.tblInfluences.setRowCount(0) self.tblInfluences.setColumnCount(0) for rowdata in csv.reader(stream): row = self.tblInfluences.rowCount() self.tblInfluences.insertRow(row) self.tblInfluences.setColumnCount(len(rowdata)) for column, data in enumerate(rowdata): item = QTableWidgetItem(data) self.tblInfluences.setItem(row, column, item) self.tblInfluences.setHorizontalHeaderLabels([ 'Name', 'Infl_0\n(offset)', 'Drift\n(Infl_0)', 'Infl_1\n(linear)', 'Drift\n(Infl_1)', 'Infl_2\n(quadratic)', 'Drift\n(Infl_2)', 'Fixed Smear\n(Eres, keV)', 'Drift\n(Fixed Smear)', 'Linear Smear\n(Eres, %)', 'Drift\n(Linear Smear)' ]) def deleteSelectedInfluences(self): """ Deletes Selected Influences """ rows = self.tblInfluences.selectionModel().selectedRows() indices = [] for r in rows: indices.append(r.row()) indices.sort(reverse=True) for index in indices: name = self.tblInfluences.item(index, NAME).text() self.tblInfluences.removeRow(index) influenceDelete = self.session.query(Influence).filter( Influence.name == name).first() if influenceDelete: self.influencesToDelete.append(influenceDelete) @pyqtSlot() def accept(self): """ Closes dialog """ names = [] for row in range(self.tblInfluences.rowCount()): try: for col in COLUMNS[1:]: float(self.tblInfluences.item(row, col).text()) except: return QMessageBox.critical( self, 'Invalid influence value', 'All specified influence values must be numbers') if not self.tblInfluences.item(row, NAME).text(): return QMessageBox.critical(self, 'Unnamed influence', 'Influence must have a name!') names.append(self.tblInfluences.item(row, NAME).text()) if not self.tblInfluences.item(row, INFL_1).text(): self.tblInfluences.item(row, INFL_1).setText('1') elif float(self.tblInfluences.item(row, INFL_1).text()) <= 0: return QMessageBox.critical( self, 'Linear influence factor error', 'Linear scaling factor must be greater than zero! For no linear scaling, set this value to 1.' ) if len(names) != len(set(names)): return QMessageBox.critical( self, 'Repeat influence', 'Influences must each have unique names!') for row in range(self.tblInfluences.rowCount()): influence_name = self.tblInfluences.item(row, NAME).text() influence = self.session.query(Influence).filter_by( name=influence_name).first() if not influence: influence = Influence() influence.name = influence_name self.session.add(influence) det_influence = self.session.query(DetectorInfluence).filter_by( influence_name=influence_name).first() if not det_influence: det_influence = DetectorInfluence() self.session.add(det_influence) det_influence.influence_name = influence_name for col in COLUMNS[INFL_0:]: if not self.tblInfluences.item(row, col).text(): if col == INFL_1: self.tblInfluences.item(row, col).setText('1') else: self.tblInfluences.item(row, col).setText('0') det_influence.infl_0 = float( self.tblInfluences.item(row, INFL_0).text()) det_influence.degrade_infl0 = float( self.tblInfluences.item(row, DEGRAGE_INFL_0).text()) det_influence.infl_1 = float( self.tblInfluences.item(row, INFL_1).text()) det_influence.degrade_infl1 = float( self.tblInfluences.item(row, DEGRAGE_INFL_1).text()) det_influence.infl_2 = float( self.tblInfluences.item(row, INFL_2).text()) det_influence.degrade_infl2 = float( self.tblInfluences.item(row, DEGRAGE_INFL_2).text()) det_influence.fixed_smear = float( self.tblInfluences.item(row, FIX_SMEAR).text()) det_influence.degrade_f_smear = float( self.tblInfluences.item(row, DEGRADE_FIX_SMEAR).text()) det_influence.linear_smear = float( self.tblInfluences.item(row, LIN_SMEAR).text()) det_influence.degrade_l_smear = float( self.tblInfluences.item(row, DEGRADE_LIN_SMEAR).text()) det_influence.influence = influence for influenceDelete in self.influencesToDelete: for scen in self.session.query(Scenario).filter( Scenario.influences.contains(influenceDelete)).all(): if influenceDelete.name in [i.name for i in scen.influences]: scen_hash = Scenario.scenario_hash( scen.acq_time, scen.scen_materials, scen.scen_bckg_materials, [ i for i in scen.influences if i.name != influenceDelete.name ]) if not self.session.query(Scenario).filter_by( id=scen_hash).first(): smats = [ ScenarioMaterial(dose=mat.dose, fd_mode=mat.fd_mode, material=mat.material) for mat in scen.scen_materials ] sback = [ ScenarioBackgroundMaterial(dose=mat.dose, fd_mode=mat.fd_mode, material=mat.material) for mat in scen.scen_bckg_materials ] Scenario(acq_time=scen.acq_time, replication=scen.replication, scen_materials=smats, scen_bckg_materials=sback, influences=[ i for i in scen.influences if i.name != influenceDelete.name ], scenario_groups=scen.scenario_groups) self.session.delete(scen) self.session.delete(influenceDelete) self.session.commit() if not self.modify_flag: for index in sorted( self.tblInfluences.selectionModel().selectedRows()): row = index.row() col = NAME if index.sibling(row, col).data() not in \ [self.parent.listInfluences.item(itemnum).text() for itemnum in range(self.parent.listInfluences.count())]: self.parent.listInfluences.addItem( index.sibling(row, col).data()) return QDialog.accept(self)
def __init__(self, rase_gui, id=None, duplicate=[], auto_s=False): QDialog.__init__(self) self.setupUi(self) self.rase_gui = rase_gui self.tblMaterial.setContextMenuPolicy(Qt.CustomContextMenu) self.tblBackground.setContextMenuPolicy(Qt.CustomContextMenu) self.id = id self.auto_s = auto_s self.settings = RaseSettings() self.scenarioHasChanged = False self.groupHasChanged = False self.duplicate = duplicate self.session = Session() self.txtAcqTime.setText('30') self.txtAcqTime.setToolTip( "Enter comma-separated values OR range as min-max:step OR range followed by comma-separated values" ) self.txtReplication_2.setText('100') int_validator = QIntValidator() self.txtAcqTime.setValidator(RegExpSetValidator()) self.txtReplication_2.setValidator(int_validator) self.tblMaterial.setHorizontalHeaderItem(INTENSITY, QTableWidgetItem('Intensity')) self.tblBackground.setHorizontalHeaderItem( INTENSITY, QTableWidgetItem('Intensity')) self.tblMaterial.customContextMenuRequested.connect( lambda x, table=self.tblMaterial: self.context_auto_range( x, self.tblMaterial)) self.tblBackground.customContextMenuRequested.connect( lambda x, table=self.tblBackground: self.context_auto_range( x, self.tblBackground)) # set material table self.tblMaterial.setItemDelegate( MaterialDoseDelegate(self.tblMaterial, unitsCol=UNITS, materialCol=MATERIAL, intensityCol=INTENSITY)) self.tblMaterial.setRowCount(10) for row in range(self.tblMaterial.rowCount()): self.tblMaterial.setItem(row, UNITS, QTableWidgetItem()) self.tblMaterial.setItem(row, INTENSITY, QTableWidgetItem()) self.tblMaterial.setItem(row, MATERIAL, QTableWidgetItem()) self.tblMaterial.item(row, INTENSITY).setToolTip( "Enter comma-separated values OR range as min-max:step OR range followed by comma-separated values" ) self.tblMaterial.setRowHeight(row, 22) # set background table self.tblBackground.setItemDelegate( MaterialDoseDelegate(self.tblBackground, unitsCol=UNITS, materialCol=MATERIAL, intensityCol=INTENSITY, auto_s=self.auto_s)) self.tblBackground.setRowCount(10) for row in range(self.tblBackground.rowCount()): self.tblBackground.setItem(row, UNITS, QTableWidgetItem()) self.tblBackground.setItem(row, INTENSITY, QTableWidgetItem()) self.tblBackground.setItem(row, MATERIAL, QTableWidgetItem()) self.tblBackground.item(row, INTENSITY).setToolTip( "Enter comma-separated values OR range as min-max:step OR range followed by comma-separated values" ) self.tblBackground.setRowHeight(row, 22) # fill influence list for influence in self.session.query(Influence): self.lstInfluences.addItem(QListWidgetItem(influence.name)) self.comboDetectorSelect.addItems( ["all detectors"] + [s.name for s in self.session.query(Detector).all()]) self.comboDetectorSelect.currentIndexChanged.connect( self.updateTableDelegate) # display a previous scenario if defined if self.id: if not self.duplicate: self.setWindowTitle("Scenario Edit") scenario = self.session.query(Scenario).get(id) materials = scenario.scen_materials bckg_materials = scenario.scen_bckg_materials influences = scenario.influences for table, mat_list in zip( (self.tblMaterial, self.tblBackground), (materials, bckg_materials)): for rowCount, mat in enumerate(mat_list): item = QTableWidgetItem(units_labels[mat.fd_mode]) item.setData(Qt.UserRole, mat.fd_mode) table.setItem(rowCount, 0, item) table.setItem(rowCount, 1, QTableWidgetItem(mat.material_name)) table.setItem(rowCount, 2, QTableWidgetItem(str(mat.dose))) self.txtAcqTime.setText(str(scenario.acq_time)) self.txtReplication_2.setText(str(scenario.replication)) for influence in influences: lst = self.lstInfluences.findItems(influence.name, Qt.MatchExactly)[0] lst.setSelected(True) self.groups = self.getGroups() else: self.setWindowTitle("Build Scenario from Other Scenario") scens = [ self.session.query(Scenario).filter_by(id=scen).first() for scen in self.duplicate ] scenario = scens[0] materials = scenario.scen_materials back_materials = scenario.scen_bckg_materials influences = scenario.influences mat_dict = {} back_dict = {} mat_fd = [] back_fd = [] for mat in materials: mat_fd.append((mat.material_name, mat.fd_mode)) mat_dict[mat.material_name] = set([mat.dose]) for back in back_materials: back_fd.append((back.material_name, back.fd_mode)) back_dict[back.material_name] = set([back.dose]) if len(scens) > 1: for scen in scens[1:]: mat_dict = self.make_matDict(scen.scen_materials, mat_dict) back_dict = self.make_matDict(scen.scen_bckg_materials, back_dict) if influences: influences.append[scen.influences] else: influences = scen.influences for table, material_dictionary, fd_list in \ zip((self.tblMaterial, self.tblBackground), (mat_dict, back_dict), (mat_fd, back_fd)): mat_list_tup = [(k, v) for k, v in material_dictionary.items()] for rowCount, (mat, fd_mode) in enumerate( zip(mat_list_tup, fd_list)): doses = [str(d) for d in sorted(mat[1])] item = QTableWidgetItem(units_labels[fd_mode[1]]) item.setData(Qt.UserRole, fd_mode[1]) table.setItem(rowCount, 0, item) table.setItem(rowCount, 1, QTableWidgetItem(str(mat[0]))) table.setItem(rowCount, 2, QTableWidgetItem(str(','.join(doses)))) self.txtAcqTime.setText(str(scenario.acq_time)) for influence in influences: lst = self.lstInfluences.findItems(influence.name, Qt.MatchExactly)[0] lst.setSelected(True) self.groups = self.getGroups() else: self.groups = [] if self.auto_s and self.rase_gui.static_background: for rowCount, mat in enumerate(self.rase_gui.static_background): mat = mat[0] item = QTableWidgetItem(units_labels[mat[0]]) item.setData(Qt.UserRole, mat[0]) self.tblBackground.setItem(rowCount, 0, item) self.tblBackground.setItem(rowCount, 1, QTableWidgetItem(mat[1].name)) self.tblBackground.setItem(rowCount, 2, QTableWidgetItem(str(mat[2]))) # signal/slot connections (this has to be done after_ the previous scenario is loaded) self.tblMaterial.cellChanged.connect(self.scenarioChanged) self.tblBackground.cellChanged.connect(self.scenarioChanged) self.tblMaterial.cellChanged.connect(self.updateScenariosList) self.tblBackground.cellChanged.connect(self.updateScenariosList) self.lstInfluences.itemSelectionChanged.connect(self.scenarioChanged) self.txtAcqTime.textChanged.connect(self.scenarioChanged) self.txtReplication_2.textChanged.connect(self.scenarioChanged) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject)
class CorrespondenceTableDialog(ui_correspondence_table_dialog.Ui_dlgCorrTable, QDialog): def __init__(self): QDialog.__init__(self) self.setupUi(self) self.settings = RaseSettings() self.NUM_COLS = 3 self.tableEdited = False self.session = Session() # self.corTable = None # Query the entries in the current default table corTableRows = self.readCorrTableRows() if not corTableRows: self.NUM_ROWS = 0 else: self.NUM_ROWS = corTableRows.count() self.tblCCCLists.setItemDelegate( Delegate(self.tblCCCLists, isotopeCol=0)) self.tblCCCLists.setRowCount(self.NUM_ROWS) self.tblCCCLists.setColumnCount(self.NUM_COLS) self.columnLabels = ['Source', 'Correct ID', 'Allowed ID'] self.tblCCCLists.setHorizontalHeaderLabels(self.columnLabels) self.tblCCCLists.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.tblCCCLists.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) self.tblCCCLists.setContextMenuPolicy(Qt.CustomContextMenu) self.tblCCCLists.customContextMenuRequested.connect(self.openMenu) self.tblCCCLists.setSortingEnabled(False) # for row in range(self.NUM_ROWS): # for col in range(self.NUM_COLS): # self.tblCCCLists.setItem(row, col, QTableWidgetItem()) if corTableRows: for row, line in enumerate(corTableRows): # if (row >= self.NUM_ROWS): # self.NUM_ROWS = self.NUM_ROWS + 1 # self.tblCCCLists.setRowCount(self.NUM_ROWS) # for col in range(self.NUM_COLS): # self.tblCCCLists.setItem(row, col, QTableWidgetItem()) self.tblCCCLists.setItem(row, 0, QTableWidgetItem(line.isotope)) self.tblCCCLists.setItem(row, 1, QTableWidgetItem(line.corrList1)) self.tblCCCLists.setItem(row, 2, QTableWidgetItem(line.corrList2)) self.buttonBox.accepted.connect(self.accept) self.buttonBox.rejected.connect(self.reject) # self.pushButton.clicked.connect(self.addLines) self.btnAddRow.clicked.connect(self.addRow) self.populateDefaultComboBox() self.setSaveAsTableName() self.buttonImport.clicked.connect(self.handleImport) self.buttonExport.clicked.connect(self.handleExport) self.buttonApplyDefaultSetting.clicked.connect(self.applySettings) self.btnDeleteSelected.clicked.connect(self.deleteSelected) self.btnClose.clicked.connect(self.closeSelected) def closeSelected(self): """ closes dialog """ super().accept() def deleteSelected(self): """ deletes selected rows """ rows = self.tblCCCLists.selectionModel().selectedRows() indices = [] for r in rows: indices.append(r.row()) indices.sort(reverse=True) for index in indices: self.tblCCCLists.removeRow(index) self.NUM_ROWS = self.NUM_ROWS - len(indices) def setDefaultCorrTable(self, tableName): """ Sets selected table as default """ corrTable = self.session.query(CorrespondenceTable).filter_by( name=tableName).first() corrTable.is_default = True self.session.commit() def applySettings(self): """ Sets selected table as default and loads it for edit """ self.setDefaultCorrTable(self.setDefaultComboBox.currentText()) self.tblCCCLists.setRowCount(0) if not self.readCorrTableRows(): return corTableRows = self.readCorrTableRows() row = 0 if corTableRows: for line in corTableRows: self.NUM_ROWS = row + 1 self.tblCCCLists.setRowCount(self.NUM_ROWS) for col in range(self.NUM_COLS): self.tblCCCLists.setItem(row, col, QTableWidgetItem()) self.tblCCCLists.setItem(row, 0, QTableWidgetItem(line.isotope)) self.tblCCCLists.setItem(row, 1, QTableWidgetItem(line.corrList1)) self.tblCCCLists.setItem(row, 2, QTableWidgetItem(line.corrList2)) row = row + 1 self.setSaveAsTableName() def populateDefaultComboBox(self): """ loads available correspondence tables into the selection box """ corrTables = list(self.session.query(CorrespondenceTable)) for i, table in enumerate(corrTables): self.setDefaultComboBox.addItem(table.name) if table.is_default: self.setDefaultComboBox.setCurrentIndex(i) def setSaveAsTableName(self): corrTable = self.session.query(CorrespondenceTable).filter_by( is_default=True).one_or_none() if corrTable is not None: self.txtCorrespondenceTable.setText(corrTable.name) self.txtCorrespondenceTable.repaint() def readCorrTableRows(self): """ Queries elements of the Default Correspondence Table :return: row elements of the correspondence table from DB """ corrTable = self.session.query(CorrespondenceTable).filter_by( is_default=True).one_or_none() if corrTable is None: return None else: return self.session.query(CorrespondenceTableElement).filter_by( corr_table_name=corrTable.name) def addRow(self): """ adds row to the table in the open dialog """ self.NUM_ROWS = self.NUM_ROWS + 1 self.tblCCCLists.setRowCount(self.NUM_ROWS) for col in range(self.NUM_COLS): self.tblCCCLists.setItem(self.NUM_ROWS - 1, col, QTableWidgetItem()) def accept(self): table_name = self.txtCorrespondenceTable.text() if table_name == "": QMessageBox.information(self, 'Correspondence Table Name Needed', 'Please Specify New Table Name') return corrTable = self.session.query(CorrespondenceTable).filter_by( name=table_name).one_or_none() if corrTable is not None: # table already exists, so delete first before overwriting self.session.query(CorrespondenceTableElement).filter_by( corr_table_name=self.txtCorrespondenceTable.text()).delete() self.session.delete(corrTable) self.session.commit() table = CorrespondenceTable(name=table_name, is_default=True) self.session.add(table) for row in range(self.NUM_ROWS): iso = self.tblCCCLists.item(row, 0).text() l1 = self.tblCCCLists.item(row, 1).text() l2 = self.tblCCCLists.item(row, 2).text() if iso != '': corrTsbleEntry = CorrespondenceTableElement(isotope=iso, corrList1=l1, corrList2=l2) table.corr_table_elements.append(corrTsbleEntry) else: break self.session.commit() super().accept() def handleExport(self): """ exports to CSV """ path = QFileDialog.getSaveFileName(self, 'Save File', self.settings.getDataDirectory(), 'CSV (*.csv)') if path[0]: with open(path[0], mode='w', newline='') as stream: writer = csv.writer(stream) writer.writerow(self.columnLabels) for row in range(self.tblCCCLists.rowCount()): rowdata = [] for column in range(self.tblCCCLists.columnCount()): item = self.tblCCCLists.item(row, column) if item is not None: rowdata.append(item.text()) else: rowdata.append('') writer.writerow(rowdata) def handleImport(self): """ imports from CSV """ path = QFileDialog.getOpenFileName(self, 'Open File', self.settings.getDataDirectory(), 'CSV(*.csv)') if path[0]: # FIXME: This doesn't check in any way that the format of the file is correct with open(path[0], mode='r') as stream: self.tblCCCLists.setRowCount(0) self.tblCCCLists.setColumnCount(0) for rowdata in csv.reader(stream): row = self.tblCCCLists.rowCount() if 'Correct ID' in str(rowdata): continue self.tblCCCLists.insertRow(row) self.tblCCCLists.setColumnCount(len(rowdata)) for column, data in enumerate(rowdata): item = QTableWidgetItem(data) self.tblCCCLists.setItem(row, column, item) self.tblCCCLists.setHorizontalHeaderLabels(self.columnLabels) self.tblCCCLists.horizontalHeader().setSectionResizeMode( 1, QHeaderView.Stretch) self.tblCCCLists.horizontalHeader().setSectionResizeMode( 2, QHeaderView.Stretch) self.NUM_ROWS = self.tblCCCLists.rowCount() @pyqtSlot(QTableWidgetItem) def on_tblCCCLists_itemChanged(self, item): """ Listener for changes to the table """ self.tableEdited = True def openMenu(self, point): """ Adds sorting to the table """ sortAction = QAction('Sort', self) menu = QMenu(self.tblCCCLists) menu.addAction(sortAction) action = menu.exec_(self.tblCCCLists.mapToGlobal(point)) if action == sortAction: sortingCol = self.tblCCCLists.currentColumn() sortingList = [] rowMap = {} for row in range(self.NUM_ROWS): if self.tblCCCLists.item(row, 0).text() == "": continue rowMapItem = {} for col in range(self.NUM_COLS): if col != sortingCol: rowMapItem[col] = self.tblCCCLists.item(row, col).text() rowMap[self.tblCCCLists.item(row, sortingCol).text()] = rowMapItem sortingList.append( self.tblCCCLists.item(row, sortingCol).text()) sortingList.sort() row = 0 for token in sortingList: rowMapItem = rowMap[token] for col in rowMapItem: self.tblCCCLists.setItem(row, col, QTableWidgetItem(rowMapItem[col])) self.tblCCCLists.setItem(row, sortingCol, QTableWidgetItem(token)) row = row + 1
def __init__(self, data): super(ResultsTableModel, self).__init__() self._data = data.copy() self.col_settings = RaseSettings().getResultsTableSettings() self._reformat_data()
class DetailedResultsDialog(ui_detailed_results_dialog.Ui_dlgDetailedResults, QDialog): def __init__(self, resultMap): QDialog.__init__(self) self.setupUi(self) self.settings = RaseSettings() self.headerLabels = [ 'File', 'Tp', 'Fn', 'Fp', 'Precision', 'Recall', 'Fscore', 'IDs' ] self.NUM_COLS = len(self.headerLabels) self.session = Session() self.tblDetailedResults.setContextMenuPolicy(Qt.CustomContextMenu) self.tblDetailedResults.setColumnCount(self.NUM_COLS) self.tblDetailedResults.setHorizontalHeaderLabels(self.headerLabels) self.tblDetailedResults.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.tblDetailedResults.setRowCount(0) row = 0 for file in resultMap: results = resultMap[file] results.insert(0, file) self.tblDetailedResults.insertRow(row) for col in range(self.NUM_COLS): self.tblDetailedResults.setItem(row, col, QTableWidgetItem(results[col])) row = row + 1 results.pop(0) self.tblDetailedResults.resizeColumnsToContents() self.tblDetailedResults.horizontalHeader().setSectionResizeMode( 0, QHeaderView.Stretch) self.buttonOK.clicked.connect(self.closeSelected) self.buttonExport.clicked.connect(self.handleExport) def handleExport(self): """ exports to CSV """ path = QFileDialog.getSaveFileName(self, 'Save File', self.settings.getDataDirectory(), 'CSV (*.csv)') if path[0]: with open(path[0], mode='w', newline='') as stream: writer = csv.writer(stream) writer.writerow(self.headerLabels) for row in range(self.tblDetailedResults.rowCount()): rowdata = [] for column in range(self.tblDetailedResults.columnCount()): item = self.tblDetailedResults.item(row, column) if item is not None: rowdata.append(item.text()) else: rowdata.append('') writer.writerow(rowdata) def get_selected_cells_as_text(self): """ Returns the selected cells of the table as plain text """ selected_rows = self.tblDetailedResults.selectedIndexes() text = "" # show the context menu only if on an a valid part of the table if selected_rows: cols = set(index.column() for index in self.tblDetailedResults.selectedIndexes()) for row in set( index.row() for index in self.tblDetailedResults.selectedIndexes()): text += "\t".join([ self.tblDetailedResults.item(row, col).text() for col in cols ]) text += '\n' return text def keyPressEvent(self, e): if e.key() == Qt.Key_Copy or e.key == QKeySequence( QKeySequence.Copy) or e.key() == 67: QApplication.clipboard().setText(self.get_selected_cells_as_text()) @pyqtSlot(QPoint) def on_tblDetailedResults_customContextMenuRequested(self, point): """ Handles "Copy" right click selections on the table """ copy_action = QAction('Copy', self) menu = QMenu(self.tblDetailedResults) menu.addAction(copy_action) action = menu.exec_(self.tblDetailedResults.mapToGlobal(point)) if action == copy_action: QApplication.clipboard().setText(self.get_selected_cells_as_text()) def closeSelected(self): """ Closes dialog """ super().accept()