def UpdateSheet(self):
        self.tableClinicalStatistic.clear()
        self.tableClinicalStatistic.setSortingEnabled(False)
        if self.comboSheet.currentText() == TRAIN:
            df = self.sheet_dict[TRAIN]
        elif self.comboSheet.currentText() == CV_VAL:
            df = self.sheet_dict[CV_VAL]
        elif self.comboSheet.currentText() == TEST:
            df = self.sheet_dict[TEST]
        else:
            mylog.error('Wrong key in the result table, or may click clear')
            return

        df.sort_index(inplace=True)
        self.tableClinicalStatistic.setRowCount(df.shape[0])
        self.tableClinicalStatistic.setColumnCount(df.shape[1] + 1)

        headerlabels = df.columns.tolist()
        headerlabels.insert(0, 'Models Name')
        self.tableClinicalStatistic.setHorizontalHeaderLabels(headerlabels)

        for row_index in range(df.shape[0]):
            for col_index in range(df.shape[1] + 1):
                if col_index == 0:
                    self.tableClinicalStatistic.setItem(
                        row_index, col_index,
                        QTableWidgetItem(df.index[row_index]))
                else:
                    self.tableClinicalStatistic.setItem(
                        row_index, col_index,
                        QTableWidgetItem(str(df.iloc[row_index,
                                                     col_index - 1])))

        self.tableClinicalStatistic.setSortingEnabled(True)
    def ShowOneResult(self):
        if not self.tableClinicalStatistic.selectedIndexes():
            return None
        index = self.tableClinicalStatistic.selectedIndexes()[0]
        row = index.row()
        one_item = self.tableClinicalStatistic.item(row, 0)
        pipeline_name = str(one_item.text())
        normalizer, dr, fs, fn, fitter = pipeline_name.split('_')

        fitter_folder = os.path.join(self._root_folder, normalizer, dr,
                                     fs + '_' + fn, fitter)
        self._current_fitter.Load(fitter_folder)
        self.textEditModelDescription.setText(self._current_fitter.Summary())

        try:
            if CheckTextInCombo(pipeline_name, self.comboSurvivalModel):
                self.comboSurvivalModel.setCurrentText(pipeline_name)
                self.UpdateSurvivalCurve()

            part_name = self._FullName2PartName(pipeline_name)
            if CheckTextInCombo(part_name, self.comboCindexModel):
                self.comboCindexModel.setCurrentText(part_name)
                self.UpdateFeature()

            if CheckTextInCombo(pipeline_name, self.comboModelContribution):
                self.comboModelContribution.setCurrentText(pipeline_name)
                self.UpdateFeature()

        except Exception as e:
            mylog.error(e)
    def SaveFigure(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            store_folder = dlg.selectedFiles()[0]
            try:
                self.canvasSurvival.getFigure().savefig(os.path.join(
                    store_folder, 'SurvivalCurve.eps'),
                                                        dpi=1200)
                self.canvasSurvival.getFigure().savefig(os.path.join(
                    store_folder, 'SurvivalCurve.jpg'),
                                                        dpi=300)
            except Exception as e:
                mylog.error('Saving Survival Curve {}'.format(e.__str__()))
                QMessageBox.about(
                    self, 'Save Figure Failed',
                    'There is no SurvivalCurve figure.\n' + e.__str__())

            try:
                self.canvasFeature.getFigure().savefig(os.path.join(
                    store_folder, 'Feature Contribution.eps'),
                                                       dpi=1200)
                self.canvasFeature.getFigure().savefig(os.path.join(
                    store_folder, 'Feature Contribution.jpg'),
                                                       dpi=300)
            except Exception as e:
                mylog.error('Saving Feature Contribution {}'.format(
                    e.__str__()))
                QMessageBox.about(
                    self, 'Save Figure Failed',
                    'There is no Feature Contribution figure.\n' + e.__str__())
Exemple #4
0
 def LoadReducer(self, store_folder):
     with open(os.path.join(store_folder, '{}.csv'.format(TRANSFORM_TYPE_SUB_FEATURES)),
               'r', newline='') as file:
         reader = csv.reader(file)
         for row in reader:
             if row[0] == TRANSFORM_TYPE:
                 assert(row [1] == TRANSFORM_TYPE_SUB)
             elif row[0] == TRANSFORM_TYPE_SUB_FEATURES:
                 self.info = row[1:]
             else:
                 mylog.error('The first work of the dimension reducer file is not correct.')
                 raise ValueError
Exemple #5
0
    def Transform(self, dc: DataContainer, store_folder=None, store_key=None):
        for sub_feature in self.sub_features:
            if sub_feature not in dc.feature_name:
                mylog.error('DataContainer does not have the sub feature')
                raise KeyError

        new_dc = FeatureSelector().SelectByName(dc, self.sub_features)

        if store_folder is not None and store_key is not None:
            new_dc.Save(os.path.join(store_folder, '{}_reduced_features.csv'.format(store_key)))

        return new_dc
    def LoadResult(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            self._root_folder = dlg.selectedFiles()[0]

            if not os.path.exists(self._root_folder):
                return
            try:
                if self.sae.LoadResult(self._root_folder):
                    self.lineEditResultPath.setText(self._root_folder)
                    self.SetResultDescription()
                    self.SetResultTable()
                    self.InitialUi()

                    self.buttonSaveFigure.setEnabled(True)
                    self.UpdateFeature()
                    self.buttonClearResult.setEnabled(True)
                    self.buttonLoadResult.setEnabled(False)
                    # self.buttonGenerateDescription.setEnabled(True)

                    self.radioSurvivalSplitDataset.setEnabled(True)
                    self.radioSurvivalSplitFeature.setEnabled(True)
                    self.radioContribution.setEnabled(True)
                    self.radioVariance.setEnabled(True)
                    self.checkSurvivalKM.setEnabled(True)

                    self.radioSurvivalSplitDataset.setChecked(True)
                    self.radioContribution.setChecked(True)

                    self.UpdateFeature()
                    self.UpdateSurvival()

                    self._is_loading = True

                else:
                    QMessageBox().about(
                        self, "Load Failed",
                        "The results were built by SAE with the previous version and can not be "
                        "loaded.")
            except Exception as ex:
                QMessageBox.about(self, "Load Error", ex.__str__())
                mylog.error('Load Error, The reason is ' +
                            traceback.format_exception(ex))
                self.ClearAll()
                raise ex
Exemple #7
0
    def MakePipelines(self):
        self.__normalizers = []
        if self.checkNormalizeNone.isChecked():
            self.__normalizers.append(NormalizerNone)
        if self.checkNormalizeMinMax.isChecked():
            self.__normalizers.append(NormalizerMinMax)
        if self.checkNormalizeZscore.isChecked():
            self.__normalizers.append(NormalizerZscore)
        if self.checkNormalizeMean.isChecked():
            self.__normalizers.append(NormalizerMean)

        self.__dimension_reducers = []
        if self.checkDimensionReduceNone.isChecked():
            self.__dimension_reducers.append(DimensionReducerNone())
        if self.checkDimensionReducePCC.isChecked():
            self.__dimension_reducers.append(DimensionReducerPcc())

        self.__feature_selectors = []
        if self.checkFeatureSelectorNone.isChecked():
            self.__feature_selectors.append(FeatureSelectorAll)
        if self.checkFeatureSelectorCluster.isChecked():
            self.__feature_selectors.append(FeatureSelectorCluster)

        self.__feature_numbers = np.arange(self.spinBoxMinFeatureNumber.value(),
                                           self.spinBoxMaxFeatureNumber.value() + 1).tolist()

        self.__fitters = []
        if self.checkCoxPH.isChecked():
            self.__fitters.append(CoxPH())
        # if self.checkAalen.isChecked():
        #     self.__fitters.append(AalenAdditive())
        if len(self.__fitters) == 0:
            mylog.error('Process classifier list length is zero.')
            return False

        cv = CrossValidation(k=int(self.spinCvFold.value()))

        self.pipeline_manager.SetCV(cv)
        self.pipeline_manager.SetNormalizers(self.__normalizers)
        self.pipeline_manager.SetReducers(self.__dimension_reducers)
        self.pipeline_manager.SetFeatureNumbers(self.__feature_numbers)
        self.pipeline_manager.SetFeatureSelectors(self.__feature_selectors)
        self.pipeline_manager.SetFitters(self.__fitters)

        return True
Exemple #8
0
    def Run(self):
        if self.train_dc.IsEmpty():
            QMessageBox.about(self, '', 'Training data is empty.')
            mylog.warning('Training data is empty.')
            return

        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.DirectoryOnly)
        dlg.setOption(QFileDialog.ShowDirsOnly)

        if dlg.exec_():
            store_folder = dlg.selectedFiles()[0]
            if len(os.listdir(store_folder)) > 0:
                reply = QMessageBox.question(self, 'Continue?',
                                             'The folder is not empty, if you click Yes, '
                                             'the data would be clear in this folder',
                                             QMessageBox.Yes, QMessageBox.No)
                if reply == QMessageBox.Yes:
                    try:
                        for file in os.listdir(store_folder):
                            if os.path.isdir(os.path.join(store_folder, file)):
                                shutil.rmtree(os.path.join(store_folder, file))
                            else:
                                os.remove(os.path.join(store_folder, file))
                    except PermissionError:
                        mylog.error('Permission Error: {}'.format(store_folder))
                        QMessageBox().about(self, 'Warning', 'Is there any opened files?')
                        return
                    except OSError:
                        mylog.error('Permission Error: {}'.format(store_folder))
                        QMessageBox().about(self, 'Warning', 'Is there any opened files?')
                        return
                else:
                    return

            if self.MakePipelines():
                self.thread.moveToThread(QThread())
                self.thread.SetProcessForm(self, store_folder)

                self.thread.signal.connect(self.textEditVerbose.setPlainText)
                self.thread.start()
                self.SetLoadState(False)
                self.SetRunState(False)
            else:
                mylog.error('Make pipeline failed. Pipeline must include Fitter and CV method.')
                QMessageBox.about(self, 'Pipeline Error', 'Pipeline must include Fitter and CV method')
Exemple #9
0
    def run(self):
        self._process_form.pipeline_manager.SaveInfo(self.store_folder)

        try:
            for total, num, group in self._process_form.pipeline_manager.RunCV(
                    self._process_form.train_dc,
                    self.store_folder):
                text = "Cross Validation:\nGroup {}: {} / {}".format(int(group), num, total)
                self.signal.emit(text)
        except Exception as e:
            print(traceback.format_exc())
            mylog.error('Thread RunCV Failed: ', e.__str__())

        try:
            for total, num in self._process_form.pipeline_manager.EstimateCV(
                    self.store_folder,
                    self._process_form.train_dc.event_name,
                    self._process_form.train_dc.duration_name):
                text = "Cross Validation:\nDone.\n\n" \
                       "Merging CV Results:\n{} / {}".format(num, total)
                self.signal.emit(text)
        except Exception as e:
            mylog.error('Thread MergeCV Result Failed: ', e.__str__())

        try:
            for total, num in self._process_form.pipeline_manager.RunWithoutCV(self._process_form.train_dc,
                                                                               self._process_form.test_dc,
                                                                               self.store_folder):
                text = "Corss Validation Done.\n\nCV Result Merge Done\n\n" \
                       "Model Developing:\n{} / {}".format(num, total)
                self.signal.emit(text)
        except Exception:
            mylog.error("Thread RunWithoutCV Failed: ", e.__str__())

        text = "Model Developing:\nDone.\n\nCross Validation:\nDone.\n\nMerging CV Results:\nDone.\n"
        self.signal.emit(text)
        self._process_form.SetLoadState(True)
        self._process_form.SetRunState(True)
Exemple #10
0
    def LoadData(self):
        if self.lineEditTrainingData.text():
            try:
                self.train_dc.Load(self.lineEditTrainingData.text(),
                                   self.event_name, self.duration_name)
                mylog.info('Open CSV file ' + self.lineEditTrainingData.text() + ' succeed.')
                self.spinBoxMaxFeatureNumber.setValue(len(self.train_dc.feature_name))
            except OSError as reason:
                message = 'Open SCV file Error, The reason is ' + str(reason)
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return
            except ValueError:
                message = 'Open SCV file ' + self.lineEditTrainingData.text() + ' Failed. because of value error.'
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return
            except Exception as e:
                message = 'Unexpected Error: {}'.format(e.__str__())
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return

        if self.lineEditTestingData.text():
            try:
                self.test_dc.Load(self.lineEditTestingData.text(),
                                   self.event_name, self.duration_name)
                mylog.info('Open CSV file ' + self.lineEditTestingData.text() + ' succeed.')
            except OSError as reason:
                message = 'Open SCV file Error, The reason is ' + str(reason)
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return
            except ValueError:
                message = 'Open SCV file ' + self.lineEditTrainingData.text() + ' Failed. because of value error.'
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return
            except KeyError:
                message = 'The event key {} and duration key {} do not exist in testing data set.'.format(
                    self.comboEvent.currentText(), self.comboDuration.currentText()
                )
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return
            except Exception as e:
                message = 'Unexpected Error: {}'.format(e.__str__())
                mylog.error(message)
                QMessageBox.information(self, 'Error', message)
                return
        else:
            self.test_dc = DataContainer()

        self.SetRunState(True)

        self.spinCvFold.setMaximum(len(self.train_dc.case_name))
        self.spinCvFold.setValue(5)
        self.UpdateDataDescription()