Esempio n. 1
0
    def __init__(self):
        super(MainWindow, self).__init__()
        mw = MatplotlibWidget()
        subplot = mw.getFigure().add_subplot(111)
        mw.draw()
        # print(dir(mw))
        # layout=QHBoxLayout()
        # mylabel=QLabel('Hi')
        # layout.addWidget(mylabel)
        # layout.addWidget(mw)
        # self.setLayout(layout)

        layout = QFormLayout()
        self.btn = QPushButton("Choose from list")
        self.btn.clicked.connect(self.getItem)

        self.le = QLineEdit()
        layout.addRow(self.btn, self.le)
        self.btn1 = QPushButton("get name")
        self.btn1.clicked.connect(self.gettext)

        self.le1 = QLineEdit()
        layout.addRow(self.btn1, self.le1)
        self.btn2 = QPushButton("Enter an integer")
        self.btn2.clicked.connect(self.getint)

        self.le2 = QLineEdit()
        layout.addRow(self.btn2, self.le2)
        self.setLayout(layout)
        self.setWindowTitle("Input Dialog demo")

        layout.addRow(mw)
Esempio n. 2
0
class StopWatchWindows(QtGui.QWidget):
    def __init__(self, args):
        super().__init__()

        self.main_layout = main_layout = QtGui.QVBoxLayout()
        self.setLayout(main_layout)

        self.startstop_button = QtGui.QPushButton('Start', self)
        self.save_button = QtGui.QPushButton('Save', self)
        self.label = QtGui.QLabel(self)
        self.display_time(0)

        self.plot_widget = MatplotlibWidget()

        main_layout.addWidget(self.startstop_button)
        main_layout.addWidget(self.label)
        main_layout.addWidget(self.plot_widget)
        main_layout.addWidget(self.save_button)

        self.startstop_button.clicked.connect(self.on_startstop_clicked)
        self.save_button.clicked.connect(self.save_to_file)

    def on_startstop_clicked(self):
        if self.startstop_button.text() == 'Start':
            self.thread = MyThread(self.display_time)
            self.thread.start()
            self.thread_scope = MyThread(self.update_graph, delay=0.2)
            self.thread_scope.start()

            self.startstop_button.setText('Stop')
        else:
            self.startstop_button.setText('Start')
            self.thread.want_to_terminate = True
            self.thread_scope.want_to_terminate = True

    def display_time(self, val):
        dec = val % 1
        int_part = int(val - dec)
        seconds = int_part % 60
        minutes = int_part // 60
        val = f"{minutes:02d}:{seconds:02d}:{int(100*dec):02d}"
        self.label.setText(val)

    def update_graph(self, val):
        fig = self.plot_widget.getFigure()
        fig.clf()
        ax = fig.subplots(1, 1)
        x, y = scope.get_waveform()
        ax.plot(x, y)
        self.data = np.array([x, y]).T
        fig.canvas.draw()

    def save_to_file(self):
        file_name, _ = QtGui.QFileDialog.getSaveFileName(
            self.save_button, 'Save file', "", "Data file (*.txt)")
        np.savetxt(file_name, self.data)
Esempio n. 3
0
class StopWatchWindows(QtGui.QWidget):
    def __init__(self, args):
        self.app = QtGui.QApplication([])
        QtGui.QWidget.__init__(self)

        self.main_layout = main_layout = QtGui.QVBoxLayout()
        self.setLayout(main_layout)

        self.btn = QtGui.QPushButton('Start', self)
        main_layout.addWidget(self.btn)

        self.label = QtGui.QLabel(self)
        self.label.setText('Bonjour')
        main_layout.addWidget(self.label)

        self.btn.clicked.connect(self.on_btn_clicked)

        self.w_plot = MatplotlibWidget()
        main_layout.addWidget(self.w_plot)
        self.plot_data([1, 2, 1, 5])

        instr = vxi11.Instrument('134.157.91.150')
        self.scope = TektronixScope(instr)

        self.display_time(0)

    def display_time(self, t):
        self.label.setText('{:.2f}'.format(t))
        self.plot_data(self.scope.get_waveform(1))

    def on_btn_clicked(self):
        print('Hello')
        if self.btn.text() == "Start":
            self.thread = MyThread(self.display_time)
            self.thread.start()
            self.btn.setText('Stop')
        elif self.btn.text() == "Stop":
            self.thread.want_to_terminate = True
            self.thread.join()
            self.btn.setText('Start')

    def plot_data(self, data):
        fig = self.w_plot.getFigure()
        fig.clf()
        ax = fig.subplots(1, 1)
        ax.plot(data)
        fig.canvas.draw()
Esempio n. 4
0
    def _create_expected_answered_ease_heatmap(self):
        chosen_ease = ['1', '2', '3', '4']
        expected_ease = ['1', '2', '3']

        answers = [[t.expected_ease, t.chosen_ease]
                   for t in RevisionAnswer.select(RevisionAnswer.expected_ease,
                                                  RevisionAnswer.chosen_ease)]
        df = pandas.DataFrame(answers,
                              columns=['expected_ease',
                                       'chosen_ease']).groupby([
                                           'expected_ease', 'chosen_ease'
                                       ]).size().unstack(fill_value=0)
        mat = df.to_numpy()
        print(mat)

        mw = MatplotlibWidget()
        fig = mw.getFigure()
        ax = fig.add_subplot()
        im = ax.imshow(df)

        ax.set_xticks(numpy.arange(len(chosen_ease)))
        ax.set_yticks(numpy.arange(len(expected_ease)))

        ax.set_xticklabels(chosen_ease)
        ax.set_yticklabels(expected_ease)

        ax.set_xlabel("Chosen ease")
        ax.set_ylabel("Expected ease")

        pyplot.setp(ax.get_xticklabels(),
                    rotation=45,
                    ha="right",
                    rotation_mode="anchor")

        for i in range(len(chosen_ease)):
            for j in range(len(expected_ease)):
                text = ax.text(i,
                               j,
                               mat[j, i],
                               ha="center",
                               va="center",
                               color="w")

        fig.tight_layout()
        mw.draw()
        self.layout.addWidget(mw)
Esempio n. 5
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.createActions()
        self.createMenus()
        self.setGeometry(100, 100, 600, 900)

        self.centralWidget = QWidget()
        # GrphicsWidget()
        layout = QHBoxLayout(self.centralWidget)
        self.scrollArea = QScrollArea(self)
        self.mw = MatplotlibWidget(size=(3.0, 40.0), dpi=100)
        lplot = self.mw.getFigure().add_subplot(121)
        self.ax = self.mw.getFigure().gca()
        l, b, w, h = self.ax.get_position().bounds
        # print(l, b, w, h)
        # self.ax.invert_yaxis()
        self.ax.set_position([0.125, 0.05, 0.5, 0.94])

        # l, b, w, h = self.ax.get_position().bounds
        # print(l, b, w, h)
        self.mw.draw()
        # self.plotlayout.addWidget(self.mw)

        self.scrollArea.setWidget(self.mw)

        layout.addWidget(self.scrollArea)

        self.setCentralWidget(self.centralWidget)
        self.lastree = LasTree()
        self.logtree = LasTree()
        self.wellLoad()
        self.logtree.set_files(['GR', 'BS'])
        self.logtree.buildTreeWidget()
        self.logtree.tree.itemSelectionChanged.connect(self.logPlot)

        self.createDockWindows()

        # self.logFileList.itemSelectionChanged.connect(self.lasLoad)
        # if not self.las_just_selected:
        # self.logList.itemSelectionChanged.connect(self.logPlot)

        self.setWindowTitle("Loggy")

        # self.newLetter()
    def wellLoad(self):
        self.wellFolder = well_folder

        self.files = []
        for f in np.array(os.listdir(self.wellFolder)[:]):
            if f[-4:].lower() in ['.las', 'dlis']:
                self.files.append(f)
        self.files = np.array(self.files)
        files_w_path = [self.wellFolder + f for f in self.files]

        cols = []

        # self.files=np.array(os.listdir(self.wellFolder)[:])

        self.lastree.set_files(self.files)
        self.lastree.buildTreeWidget()
        self.lasfiletree = self.lastree.treeview_dict.copy()
        self.lastree.tree.itemSelectionChanged.connect(self.lasLoad)

        self.lasLoadThread = LasLoadThread(files=files_w_path)

    # def lasBackgroundLoad():

    def lasLoad(self):
        las_name = self.lastree.tree.selectedItems()[0].text(
            0)  #self.logFileList.selectedItems()[0].text()
        if las_name in ['TVD', 'MD', 'LWD', 'WireLine']:
            return

        findex = np.where(self.files == las_name)[0][0]
        # print(findex)
        Loaded = False
        while (not Loaded):
            if (findex < len(self.lasLoadThread.Lases)):
                self.las = self.lasLoadThread.Lases[findex]
                Loaded = True
                self.logtree.tree.clear()
                # print('hi')
            else:
                # print('hello')

                # self.logtree.addItems(['Loading....'])
                time.sleep(1)

        if len(self.logtree.tree.selectedItems()) > 0:
            item = self.logtree.tree.selectedItems()[0]
            # print(dir(item))
            item.setSelected = False
        if not (len(self.las.keys()) < 1):
            # self.logtree = LasTree(self.las.keys())
            self.logtree.set_files(self.las.keys())
            self.logtree.buildTreeWidget()

            dcol = self.las.keys()[find_depth_indx(self.las)]
            self.depth_col = str_array2floats(self.las[dcol])
        # else:

        # self.las_just_selected = True

    def logPlot(self):

        # print(self.mw.getFigure().)
        # pass
        # if not self.las_just_selected:
        if len(self.logtree.tree.selectedItems()) > 0:
            keycol = self.logtree.tree.selectedItems()[0].text(0)
            try:
                self.log_col = str_array2floats(self.las[keycol])
                self.ax = LogPlot.basicPlot(self.ax,
                                            self.depth_col,
                                            self.log_col,
                                            lcolor='#800000')
                self.ax.set_ylim(500, 3000)
                self.ax.invert_yaxis()
            except:
                print('Unable to convert log to floats')
        self.mw.draw()

    def set_category(self):
        # qt_app = QApplication(sys.argv)
        # mnomonicsfile=mnomonicsfile
        # print(self.logtree.treeview_dict)
        # set_category_app = Categorize(self.logtree.treeview_dict,mnomonicsfile)
        print('*************************************************')
        print(self.logtree.treeview_dict)
        category_window = Categorize(self)
        category_window.set_params(self.logtree, mnomonicsfile)
        category_window.show()

        # self.logtree.tree.clear()
        # self.logtree.buildTreeWidget()
        # set_category_app.run()
        # self.logtree.buildTreeWidget()

    def createDockWindows(self):

        dock = QDockWidget("Log Files", self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        dock.setWidget(self.lastree.tree)
        #
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        self.set_category_button = QPushButton('Set Category', self)
        self.slect_files_button = QPushButton(
            'Select files for further process', self)

        # self.layout.addWidget(self.logtree.tree)
        dock = QDockWidget("Set", self)
        btn_w = QWidget()
        self.btn_layout = QVBoxLayout()
        btn_w.setLayout(self.btn_layout)
        dock.setWidget(btn_w)

        self.btn_layout.addWidget(self.set_category_button)
        self.btn_layout.addWidget(self.slect_files_button)

        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        dock = QDockWidget("Logs", self)

        dock.setWidget(self.logtree.tree)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)

        self.set_category_button.clicked.connect(self.set_category)
        self.slect_files_button.clicked.connect(self.retain4FurtherAnalysis)

    def createActions(self):
        self.exitAct = QAction("E&xit",
                               self,
                               shortcut="Ctrl+Q",
                               triggered=self.close)
        self.openFileAct = QAction("&Open",
                                   self,
                                   shortcut="Ctrl+O",
                                   triggered=self.file_open)
        self.aboutAct = QAction("&About", self, triggered=self.about)

    def retain4FurtherAnalysis(self):
        # print(self.lastree.treeview_dict)

        print(self.lasfiletree)
        lasfilemodtree = {}
        lc = LogCategorize(mnomonicsfile)
        self.files_4_further_analysis = []
        self.allfiles = {'fname': [], 'drange': [], 'curve_names': []}
        if len(self.lasLoadThread.Lases) == len(self.files):
            print('Loaded all files...')
            for las, lf in zip(self.lasLoadThread.Lases, self.files):
                lc.set_las(las)
                lc.lasCategorize()
                # print(lc.treeview_dict)
                # print(lc.get_catePresent())
                # print( lc.get_lasdepthrange())
                # print( lc.get_curverange('CAL'))
                lcates = lc.get_catePresent()
                # if len(lcates)>3:
                self.allfiles['fname'].append(lf)
                self.allfiles['drange'].append(lc.get_lasdepthrange())
                self.allfiles['curve_names'].append(lc.get_catePresent())
            # print(self.allfiles)
            topdepts = np.array(
                [np.float(d[0]) for d in self.allfiles['drange']])
            ncurves = np.array([len(d) for d in self.allfiles['curve_names']])

            self.allfiles['topdepts'] = topdepts
            self.allfiles['ncurves'] = ncurves
            self.allfiles['fname'] = np.array(self.allfiles['fname'])
            print(np.column_stack((topdepts, ncurves)))
            for k in self.lasfiletree:
                lasfilemodtree[k] = {}
                for l in self.lasfiletree[k]:
                    lasfilemodtree[k][l] = {}
                    if (len(self.lasfiletree[k][l]) > 0):
                        branch_files = np.array(self.lasfiletree[k][l])
                        print('*****************************************')
                        print(branch_files)
                        branch_files = self.sort_per_depthNcurves(branch_files)
                        print(branch_files)
                        for m in branch_files:
                            indx = np.where(self.allfiles['fname'] == m)[0][0]
                            print(m, self.allfiles['fname'], indx)
                            lasfilemodtree[k][l][m] = [
                                '{} - {}'.format(
                                    *self.allfiles['drange'][indx]),
                                str(len(self.allfiles['curve_names'][indx])),
                                ','.join(self.allfiles['curve_names'][indx])
                            ]
        else:
            print('Not loaded all files...')
        print(lasfilemodtree)
        self.retain_tree = Pytree(self)
        self.retain_tree.set_tree(lasfilemodtree)
        self.retain_tree.select_btn.clicked.connect(self.return_selected_items)
        self.retain_tree.buildTree()
        self.retain_tree.show()

        # sys.exit(app.exec_())
    def return_selected_items(self):
        iterator = QTreeWidgetItemIterator(self.retain_tree.tree)
        value = iterator.value()
        self.retain_files = []
        self.retain_files_ranges = []
        while value:
            if value.checkState(0) == Qt.Checked:
                # print('yes')
                print(value.text(0))
                self.retain_files.append(value.text(0))
                self.retain_files_ranges.append(value.text(1))
            # if hasattr(value, 'saveValue'):
            #     value.saveValue()
            iterator += 1
            value = iterator.value()
        # print(self.retain_files)
        # print(self.retain_files_ranges)
        self.retain_tree.close()
        self.show_lateralCorrections()

    def show_lateralCorrections(self):

        self.lateralCorr_buttons = []
        for i, rf in enumerate(zip(self.retain_files,
                                   self.retain_files_ranges)):
            lcw = QWidget()
            self.harlayout = QHBoxLayout()
            self.lateralCorr_buttons.append(
                QPushButton('Do Lateral Depth Match-' + str(i), self))
            self.harlayout.addWidget(QLabel(rf[1]))
            self.harlayout.addWidget(self.lateralCorr_buttons[-1])
            print(rf[0])
            self.lateralCorr_buttons[-1].clicked.connect(
                lambda state, x=rf[0]: self.doLateralCorr(x))
            lcw.setLayout(self.harlayout)
            self.btn_layout.addWidget(lcw)

    def doLateralCorr(self, lfilename):
        self.selected_lases = []
        findex = np.where(self.files == lfilename)[0][0]
        print(lfilename, findex)
        self.selected_lases.append(self.lasLoadThread.Lases[findex])
        lateralWin = LateralCorr(self)
        lateralWin.buildLogTree(self.selected_lases)
        lateralWin.logCorrelations()
        lateralWin.show()

    def sort_per_depthNcurves(self, branch_files):
        indxs = []

        for m in branch_files:
            indxs.append(np.where(self.allfiles['fname'] == m)[0][0])
        ncurves = self.allfiles['ncurves'][indxs]

        sort_dpt_indx = np.argsort(self.allfiles['topdepts'][indxs])

        ncurves_rule = ncurves[sort_dpt_indx] > 2
        branch_files = branch_files[sort_dpt_indx]

        # sort_dpt_indx=sort_dpt_indx[::-1]

        return np.append(branch_files[ncurves_rule],
                         branch_files[~ncurves_rule])

    def createMenus(self):
        self.fileMenu = QMenu("&File", self)
        # self.fileMenu.addAction(self.openAct)
        # self.fileMenu.addAction(self.printAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.openFileAct)
        self.fileMenu.addAction(self.exitAct)

        self.helpMenu = QMenu("&Help", self)
        self.helpMenu.addAction(self.aboutAct)
        # self.helpMenu.addAction(self.aboutQtAct)

        self.menuBar().addMenu(self.fileMenu)
        # self.menuBar().addMenu(self.viewMenu)
        # self.menuBar().addMenu(self.digitizeMenu)
        self.menuBar().addMenu(self.helpMenu)

        self.file_toolbar = QToolBar("File")
        self.file_toolbar.setIconSize(QSize(24, 24))
        self.addToolBar(self.file_toolbar)

    def about(self):
        QMessageBox.about(
            self, "About Log splicer",
            "<p>The <b>Image Viewer</b> example shows how to combine "
            "(QScrollArea.widgetResizable), can be used to implement "
            "zooming and scaling features.</p>"
            "<p>In addition the example shows how to use QPainter to "
            "print an image.</p>")

    def file_open(self):
        print('Not yet set')
Esempio n. 6
0
class VerticalCorr(QMainWindow):
    def __init__(self, parent=None):
        super(VerticalCorr, self).__init__(parent)
        from loggy_settings import well_folder, lwdVSwirelineFile, mnomonicsfile
        # projectFolder=r'D:\Ameyem Office\Projects\Cairn\W1\\'

        self.log_bundle = np.load(well_folder + '..\proc_logs_bundle.npy')
        self.flt_logs = {}

        for logname in self.log_bundle[0]['keys']:
            print(logname)
            self.flt_logs[logname] = [[] for i in range(len(self.log_bundle))]

        print('Starting main window...')

        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.setWindowTitle('Vertical Correlations')
        self.setGeometry(100, 100, 900, 400)
        layout = QVBoxLayout(self.centralWidget)

        self.logscrollArea = QScrollArea(self)
        layout.addWidget(self.logscrollArea)

        fw = QWidget()
        # fw.setMaximumWidth(120)
        # self.formLayout=QFormLayout()
        self.formLayout = QHBoxLayout()
        fw.setLayout(self.formLayout)
        layout.addWidget(fw)

        self.filtscrollArea = QScrollArea(self)
        layout.addWidget(self.filtscrollArea)
        self.getFormLayerFilled()

        self.setCentralWidget(self.centralWidget)

        self.createDockWindows()

        self.run_mass_filter()

    def getFormLayerFilled(self):
        self.learray = []
        # self.formLayout.addRow(QLabel(' '))
        # self.formLayout.addRow(QLabel('Calculated delays'))
        # self.formLayout.addRow(QLabel(' '))
        # for i,l in enumerate(self.delays.keys()):
        #     self.learray.append( QLineEdit('%.2f'%self.delays[l])) #
        #     self.formLayout.addRow(QLabel(l),self.learray[-1])
        self.n_patches2retain_le = QLineEdit('1')
        self.n_hist_segments_le = QLineEdit('100')
        self.histFilter_btn = QPushButton("Remove Spikes")
        self.histForm = QFormLayout()

        self.histForm.addRow(QLabel('Retainpatches: '),
                             self.n_patches2retain_le)
        self.histForm.addRow(QLabel('HistSegments: '), self.n_hist_segments_le)

        hfw = QWidget()
        hfw.setMaximumWidth(200)
        hfw.setLayout(self.histForm)
        # hfw.setMinimumWidth(120)

        self.formLayout.addWidget(hfw)
        self.formLayout.addWidget(self.histFilter_btn)
        self.histFilter_btn.clicked.connect(self.histFilter)
        # self.formLayout.addRow(QLabel('   '))

        # self.recal_btn = QPushButton("Recalculate")
        # self.formLayout.addRow(self.recal_btn)
        # self.recal_btn.clicked.connect(self.recalculateDelay)

    #     self.formLayout.addRow(QLabel(' '))
    #     self.save_btn = QPushButton("Save Curves")
    #     self.formLayout.addRow(self.save_btn)
    #     self.save_btn.clicked.connect(self.saveCorrCurves)

    # def applyDelayChange(self):
    #     for le,key in zip(self.learray,self.delays.keys()):
    #         self.delays[key]=np.float(le.text())
    #         print(le.text())
    #     self.log_correlations_plot()
    # def recalculateDelay(self):

    #     self.logCorrelations()

    # def saveCorrCurves(self):
    #     print('Saving logs...')
    #     proc_logs={}
    #     for logname in self.delays.keys():
    #         if self.delays[logname] !=0:
    #             shift_depth=self.depth_col+self.delays[logname]
    #             shift_depth.shape=len(shift_depth),1
    #             # np.save('now.npy',(shift_depth,self.las[logname]))
    #             # print(shift_depth,self.las[logname])
    #             XY=np.append(shift_depth,self.las[logname].reshape(len(shift_depth),1),axis=1)
    #             XY.shape=len(shift_depth),2
    #             # print(XY)
    #             flexlog=FlexLog(XY)
    #             resamLog=flexlog.resampleY(self.depth_col)
    #         else:
    #             resamLog=self.las[logname]
    #         key=self.interestedKeynames[self.interestedLognames==logname][0]
    #         proc_logs[key]=resamLog
    #     proc_logs['GR']=self.las[self.grlogname]
    #     proc_logs['DEPTH']=self.depth_col
    #     proc_logs['vlues_size']=np.size(self.las.values())
    #     proc_logs['keys']=self.interestedKeynames
    #     # proc_logs['test']='yes'
    #     bundle_file=self.wellFolder+'../proc_logs_bundle.npy'
    #     repeated=False
    #     if os.path.isfile(bundle_file):
    #         logbundle=np.load(bundle_file)
    #         for i,lb in enumerate(logbundle):
    #             if lb['vlues_size']==proc_logs['vlues_size']:
    #                 repeated=True
    #                 print('It is repeated so updated but not created...')
    #                 logbundle[i]=proc_logs
    #     else:
    #         logbundle=[]
    #     if not repeated:
    #         logbundle=np.append(logbundle,proc_logs)
    #     np.save(bundle_file,logbundle)
    #     print('Processed logs saved.. you can move on to next set...')
    #     time.sleep(2)
    #     self.close()
    def histFilter(self):
        depthcol_name = 'DEPTH'
        self.filtw = MatplotlibWidget(size=(22.0, 4), dpi=100)
        self.filtscrollArea.setWidget(self.filtw)
        ax = self.filtw.getFigure().add_subplot(1, 1, 1)

        hist_bins = np.int(self.n_hist_segments_le.text())
        n_big_patches = np.int(self.n_patches2retain_le.text())
        self.flt_logs[self.logname] = []
        for i, lb in enumerate(self.log_bundle):
            self.flt_logs[self.logname][i] = hist_filter(
                lb[self.logname].copy(),
                n_big_patches=n_big_patches,
                hist_bins=hist_bins)
            ax.plot(lb[depthcol_name], self.flt_logs[self.logname][i])
        # print(flt_arrs)

    def run_mass_filter(self):
        hist_bins = np.int(self.n_hist_segments_le.text())
        n_big_patches = np.int(self.n_patches2retain_le.text())

        for i, lb in enumerate(self.log_bundle):
            for logname in lb['keys']:
                self.flt_logs[logname][i] = hist_filter(
                    lb[logname].copy(),
                    n_big_patches=n_big_patches,
                    hist_bins=hist_bins)

    def logPlotPanel(self):
        print('Initiating plot widget...')
        self.logname = self.lastree.tree.selectedItems()[0].text(0)

        depthcol_name = 'DEPTH'
        # firstlog
        logdata = []
        depthdata = []
        self.mw = MatplotlibWidget(size=(22.0, 4), dpi=100)
        self.logscrollArea.setWidget(self.mw)
        self.ax = self.mw.getFigure().add_subplot(1, 1, 1)

        self.filtw = MatplotlibWidget(size=(22.0, 4), dpi=100)
        self.filtscrollArea.setWidget(self.filtw)
        ax2 = self.filtw.getFigure().add_subplot(1, 1, 1)

        for i, lb in enumerate(self.log_bundle):
            # print(lb[self.logname],lb[depthcol_name])
            self.ax.plot(lb[depthcol_name], lb[self.logname])
            ax2.plot(lb[depthcol_name], self.flt_logs[self.logname][i])

            # logdata=np.append([logdata],[lb[logname]],axis=0  )
            # depthdata=np.append([depthdata],[lb[depthcol_name] ],axis=0  )
        # print(logdata)
        # self.depth_col=self.las[dcol]
        # dt=self.depth_col[1]-self.depth_col[0]
        # print('Spacing = ',dt)
        # gammacol=self.las[self.grlogname]
        # gammacol[np.isnan(gammacol)]=0
        # self.norm_gamma=mean_norm(gammacol)#[0:800]

        # l, b, w, h = self.ax.get_position().bounds
        # self.ax.set_position([0.27,b+0.1,0.7,h])

        # self.lag_corrs={}
        # self.delays={}
        # self.normlogs={}
        # print('Calculating correlations...')
        # for logname in self.interestedLognames:
        #     if logname != self.grlogname:
        #         self.log_col=self.las[logname]
        #         self.log_col[np.isnan(self.log_col)]=0
        #         norm_blog=mean_norm(self.log_col)#[0:800]
        #         self.normlogs[logname]=norm_blog
        #         dist2look=100
        #         delay_estimation,lag_corr= get_delay(self.norm_gamma,norm_blog,dt,corrtype='abs',dist2look=dist2look)
        #         self.delays[logname]=-delay_estimation
        #         lagcor_range=np.arange(round(len(lag_corr[0])/2)-4*dist2look,round(len(lag_corr[0])/2)+4*dist2look)
        #         self.lag_corrs[logname]=(lag_corr[0][lagcor_range],lag_corr[1][lagcor_range])
        # self.log_correlations_plot()
        # self.getFormLayerFilled()
    def log_correlations_plot(self):
        self.mw = MatplotlibWidget(size=(22.0,
                                         len(self.interestedLognames) * 1.6),
                                   dpi=100)
        self.logscrollArea.setWidget(self.mw)
        print('Plotting...')
        self.ax = []
        for i, logname in enumerate(self.normlogs.keys()):
            self.ax.append(self.mw.getFigure().add_subplot(
                len(self.normlogs), 1, i + 1))
            l, b, w, h = self.ax[-1].get_position().bounds
            self.ax[-1].set_position([0.27, b + 0.1, 0.7, h])
            # self.log_col=self.las[logname]
            # self.log_col[np.isnan(self.log_col)]=0
            # norm_blog=mean_norm(self.log_col)#[0:800]
            depthb_shift = self.depth_col + self.delays[logname]
            self.ax[-1].plot(self.depth_col, self.normlogs[logname], 'b')
            self.ax[-1].plot(self.depth_col, self.norm_gamma, 'r')
            self.ax[-1].plot(depthb_shift, self.normlogs[logname], 'magenta')
            self.ax[-1].text(self.depth_col[0] - 50, 0.02, logname)

        lenax = len(self.ax)
        for i, logname in enumerate(self.lag_corrs.keys()):
            self.ax.append(self.mw.getFigure().add_subplot(
                len(self.normlogs), 2, lenax + i + 1))
            l, b, w, h = self.ax[i].get_position().bounds
            self.ax[-1].set_position([0.03, b, 0.21, h])
            self.ax[-1].plot(self.lag_corrs[logname][0],
                             self.lag_corrs[logname][1], 'b')
            self.ax[-1].text(self.delays[logname],
                             min(self.lag_corrs[logname][1]),
                             'Delay = %.2f' % self.delays[logname])
            line = self.ax[-1].axvline(x=self.delays[logname],
                                       ymin=-1,
                                       ymax=+1,
                                       linewidth=1.5,
                                       color='c')
            self.ax[-1].text(self.lag_corrs[logname][0][0], 0.4, logname)

        self.mw.draw()
        print('Complete...')

    def buildLogTree(self):
        self.lastree = LasTree()
        self.lastree.tree.headerItem().setText(0, "Categories")
        for lb in self.log_bundle:
            # logkeys=np.append(['GR'],lb['keys'])
            # print(logkeys)
            self.lastree.set_files(lb['keys'], make_tree_dict=False)
            mind, maxd = min(lb['DEPTH']), max(lb['DEPTH'])
            self.lastree.tree = treeWidgetFrmArray(
                self.lastree.tree, '({0:4.1f} to {1:4.1f})'.format(mind, maxd),
                lb['keys'])
        self.lastree.tree.itemSelectionChanged.connect(self.logPlotPanel)
        self.dock.setWidget(self.lastree.tree)
        print(dir(self.lastree.tree))
        print(help(self.lastree.tree.itemAt))
        print(self.lastree.tree.itemAt(1, 0).text(0))

    def createDockWindows(self):
        self.dock = QDockWidget("Log Files", self)
        self.dock.setAllowedAreas(Qt.LeftDockWidgetArea
                                  | Qt.RightDockWidgetArea)
        # dock.setWidget(self.lastree.tree)
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock)
Esempio n. 7
0
class mainWindow(QtGui.QMainWindow):
    """
    main Window, parent to GL Viewport and UI
    """
    def __init__(self, load=None, loadsnapshot=None, options={}, **kwargs):
        super(mainWindow, self).__init__()
        self._setupUI()
        if load is not None:
            self.loaddata_gadget(load)
        if loadsnapshot is not None:
            self.loadsnapshot_gadget(loadsnapshot, basic=options.basic)        
        

    def _setupUI(self):
        area = DockArea()
        self.setCentralWidget(area)
        self.resize(1000,800)
        self.setWindowTitle('Gadget Visualization')

        self._setupMenu()

        ## Create docks, place them into the window one at a time.
        ## Note that size arguments are only a suggestion; docks will still have to
        ## fill the entire dock area and obey the limits of their internal widgets.
        self.dock1 = Dock("Main Window", size=(800, 800))
        self.dock2 = Dock("Console", size=(800,200))
        self.dock3 = Dock("View", size=(200,800))
        self.dock4 = Dock("Options", size=(200,800))
        self.dock1.hideTitleBar()
        self.dock2.hideTitleBar()
#        dock3.hideTitleBar()

        area.addDock(self.dock1, 'left')
        area.addDock(self.dock3, 'right', self.dock1)
        area.addDock(self.dock4, 'top', self.dock3)
        area.addDock(self.dock2, 'bottom', self.dock1)
        area.moveDock(self.dock3, 'above', self.dock4)

        ## Add widgets into each dock
    #    self.sn = None
        self.filePath = '.'
        self.sn = snapshot()
        self.vis = sphvis()

        ## add GL Viewport
        self.ViewWidget = myGLViewWidget()
        self.ViewWidget.addItem(self.vis)
        self.dock1.addWidget(self.ViewWidget)

        ## setup embedded IPython terminal
        self._setupIpythonWidget()

        ## setup control widget
        self._setupControls()

    def _setupIpythonWidget(self):
        namespace={'pg': pg, 'np': np, 'vis': self.vis, 'sn': self.sn, 'vw': self.ViewWidget, 'main': self }
        #w2 = pg.console.ConsoleWidget(namespace=namespace)
        
        self.ipythonWidget = QIPythonWidget()
        self.ipythonWidget.pushVariables(namespace)
        self.dock2.addWidget(self.ipythonWidget)
        self.ipythonWidget.execute("%pylab", True, False)
        welcomeText = "\nPySPHViewer v%s\n" % (VERSION) \
            + "The data of the currently visible Snapshot can be accessed with the 'sn' object\n" \
            + "import numpy as np, pyqtgraph as pg\n" \
            + "\n"
        self.ipythonWidget.printText(welcomeText)

    def _setupControls(self):
        w3 = pg.LayoutWidget()
        self.dock3.addWidget(w3)

        label =  QtGui.QLabel("") 
        w3.addWidget(label)
        w3.nextRow()
        ##buttons
        buttons = [('Reset', self.ViewWidget.reset, 'r', -1),
                   ('Save Rotation', self.saveCurrentView, None, -1),
                   ('X-Z', self.ViewWidget.rotateXZ, 'c', None),
                   ('X-Y', self.ViewWidget.rotateXY, 'v', None),
                   ('Y-Z', self.ViewWidget.rotateYZ, 'b', 1),
                   ]
        for text, action, shortcut, cs in buttons:
            btn = QtGui.QPushButton(text)
            btn.setMinimumWidth(15)
            if cs:
                w3.addWidget(btn, colspan=cs)
                w3.nextRow()
            else:
                w3.addWidget(btn)
            if shortcut:
                btn.setShortcut(shortcut)
            btn.clicked.connect(action)
            
        w4 = pg.LayoutWidget()
        self.dock3.addWidget(w4)

        ## Checkboxes to select particle types to be displayed
        for t in range(self.vis.ntypes):
            cb = QtGui.QCheckBox(self.vis.typenames[t])
            cb.toggle()
            cb.stateChanged.connect(partial(self.vis.changeDrawTypes, ptype=t))
            w4.addWidget(cb)
            w4.nextRow()

        sliders = [
            ("Pointsize", np.sqrt(self.vis.mastersize)*25, self.vis.sizeChange, (0,100)),
            ("Alpha", self.vis.lum * 100, self.vis.alphaChange, (0,100)), 
            ("Step", self.vis.step, self.vis.stepChange, (1,100)),
            ]
        for text, val, slot, srange in sliders:
            label = QtGui.QLabel("%16s" % text)
            w4.addWidget(label)
            sl = QtGui.QSlider(QtCore.Qt.Horizontal)
            sl.setRange(*srange)
            sl.setValue(val)
            w4.addWidget(sl)
            w4.nextRow()
            sl.valueChanged.connect(slot)
        label =  QtGui.QLabel("") 
        w4.addWidget(label)

    def initpopup(self):
        self.popupPlot = popupPlot()
        vbox = QtGui.QVBoxLayout()
        self.popupPlot.setLayout(vbox)
        self.popupPlot.show()     
        self.mw = MatplotlibWidget()
        vbox.addWidget(self.mw)
        self.subplot = self.mw.getFigure().add_subplot(111)
        self.subplot.plot(np.arange(10))
        self.mw.draw()

    def _setupMenu(self):
        openFile = QtGui.QAction('&Open File', self)        
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new Gadget File')
        openFile.triggered.connect(self.openGadget)

        popupAction = QtGui.QAction('&PlotPopup', self)        
        popupAction.setStatusTip('Exit application')
        popupAction.triggered.connect(self.initpopup)

        exitAction = QtGui.QAction('&Exit', self)        
        exitAction.setShortcut('Esc')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(QtGui.qApp.quit)

        self.statusBar()

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(openFile)
        fileMenu.addAction(exitAction)

        self.toolbar = self.addToolBar('Exit')
        self.toolbar.addAction(openFile)
        self.toolbar.addAction(popupAction)
        self.toolbar.addAction(exitAction)

    def fileSelect(self):
        fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file', self.filePath)
        if fname:
            self.filePath =  QtCore.QFileInfo(fname).path()
            return fname

    def openGadget(self):
        fname = self.fileSelect()
        if fname:
            self.loadsnapshot_gadget(fname)

    def saveCurrentView(self):
        fname = self.fileSelect()
        with (open(fname, 'w')) as f:
            self.ViewWidget.currentView().transpose().astype(np.float64).tofile(f)

    def loadsnapshot_gadget(self, fname, **kwargs):
        self.sn.readgadget(fname, **kwargs)
        self.loaddata_gadget(self.sn)

    def loaddata_gadget(self, *args):
        self.vis.loaddata_gadget(*args)
        self.statusBar().showMessage('Snapshot loaded')
Esempio n. 8
0
class LateralCorr(QMainWindow):
    def __init__(self,parent=None):
        super(LateralCorr, self).__init__(parent)
        # self.wellFolder=well_folder
        print('Starting main window...')
        self.centralWidget = QWidget()
        self.setCentralWidget(self.centralWidget)
        self.setWindowTitle('Lateral Correlations')
        self.setGeometry(100,100, 900,400)

        layout = QHBoxLayout(self.centralWidget)
        self.formLayout=QFormLayout()
        fw=QWidget()
        fw.setMaximumWidth(120)
        # fw.setMinimumHeight(400)
        fw.setLayout(self.formLayout)

        self.logscrollArea = QScrollArea(self)
        # self.corrscrollArea = QScrollArea(self)

        # layout.addWidget(self.corrscrollArea)
        layout.addWidget(fw)
        layout.addWidget(self.logscrollArea)
        self.setCentralWidget(self.centralWidget)

        # self.create_plotWindow()        
        self.createDockWindows()

        
    def getFormLayerFilled(self):
        self.learray=[]
        self.formLayout.addRow(QLabel(' '))
        self.formLayout.addRow(QLabel('Calculated delays'))
        self.formLayout.addRow(QLabel(' '))
        for i,l in enumerate(self.delays.keys()):            
            self.learray.append( QLineEdit('%.2f'%self.delays[l])) #
            self.formLayout.addRow(QLabel(l),self.learray[-1])
        self.delaysubmit_btn = QPushButton("Apply")
        self.formLayout.addRow(self.delaysubmit_btn)
        self.delaysubmit_btn.clicked.connect(self.applyDelayChange)
        self.formLayout.addRow(QLabel('   '))
        self.recal_btn = QPushButton("Recalculate")
        self.formLayout.addRow(self.recal_btn)
        self.recal_btn.clicked.connect(self.recalculateDelay)
        self.formLayout.addRow(QLabel(' '))
        self.save_btn = QPushButton("Save Curves")
        self.formLayout.addRow(self.save_btn)
        self.save_btn.clicked.connect(self.saveCorrCurves)

        
    def applyDelayChange(self):
        for le,key in zip(self.learray,self.delays.keys()):
            self.delays[key]=np.float(le.text())            
            print(le.text())
        self.log_correlations_plot()
    def recalculateDelay(self):
                
        self.logCorrelations()

    def saveCorrCurves(self):
        print('Saving logs...')
        proc_logs={}
        for logname in self.delays.keys():
            if self.delays[logname] !=0:
                shift_depth=self.depth_col+self.delays[logname]
                shift_depth.shape=len(shift_depth),1
                # np.save('now.npy',(shift_depth,self.las[logname]))
                # print(shift_depth,self.las[logname])
                XY=np.append(shift_depth,self.las[logname].reshape(len(shift_depth),1),axis=1)
                XY.shape=len(shift_depth),2
                # print(XY)
                flexlog=FlexLog(XY)
                resamLog=flexlog.resampleY(self.depth_col)
            else:
                resamLog=self.las[logname]
            key=self.interestedKeynames[self.interestedLognames==logname][0]
            proc_logs[key]=resamLog            
        proc_logs['GR']=self.las[self.grlogname]
        proc_logs['DEPTH']=self.depth_col
        proc_logs['vlues_size']=np.size(self.las.values())
        proc_logs['keys']=self.interestedKeynames
        # proc_logs['test']='yes'
        bundle_file=proc_logs_bundle_file
        repeated=False
        if os.path.isfile(bundle_file):
            logbundle=np.load(bundle_file)
            print('______________________^^^^__________________________')
            print(len(logbundle))
            for i,lb in enumerate(logbundle):
                if lb['vlues_size']==proc_logs['vlues_size']:
                    repeated=True
                    print('________________________________________________')
                    print('It is repeated so updated but not created...')
                    logbundle[i]=proc_logs
                    break
                # else:
                #     print('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^')
                #     print('It is not repeated so  created...')
                
        else:
            logbundle=[]
        if not repeated:
            if (len(logbundle)>0):
                if proc_logs['DEPTH'][0]>logbundle[-1]['DEPTH'][0]:
                    logbundle=np.append(logbundle,proc_logs)
                else:
                    logbundle=np.append(proc_logs,logbundle)
            else:
                logbundle=np.append(proc_logs,logbundle)
                
        np.save(bundle_file,logbundle)
        print('Processed logs saved.. you can move on to next set...')
        time.sleep(2)
        self.close()
        
            

    def logCorrelations(self):
        print('Initiating plot widget...')
        self.interestedLognames=np.array([self.treeview_dict['Log'][key][0] for key in self.treeview_dict['Log']])

        # self.interestedLognames=np.array(self.interestedLognames)
        # print('self.interestedLognames : ',self.interestedLognames)
        self.interestedKeynames=np.array([k for k in self.treeview_dict['Log'].keys()])
        self.grlogname=self.treeview_dict['Log']['GR'][0]          
        
        dcol=self.las.keys()[find_depth_indx(self.las)]
        self.depth_col=self.las[dcol]
        dt=self.depth_col[1]-self.depth_col[0]
        print('Spacing = ',dt)
        gammacol=self.las[self.grlogname]
        gammacol[np.isnan(gammacol)]=0
        self.norm_gamma=mean_norm(gammacol)#[0:800]

        self.lag_corrs={}
        self.delays={}
        self.normlogs={}
        print('Calculating correlations...')
        for logname in self.interestedLognames:
            if logname != self.grlogname:
                self.log_col=self.las[logname]  
                self.log_col[np.isnan(self.log_col)]=0            
                norm_blog=mean_norm(self.log_col)#[0:800]
                self.normlogs[logname]=norm_blog
                dist2look=100
                delay_estimation,lag_corr= get_delay(self.norm_gamma,norm_blog,dt,corrtype='abs',dist2look=dist2look)
                self.delays[logname]=-delay_estimation
                lagcor_range=np.arange(round(len(lag_corr[0])/2)-4*dist2look,round(len(lag_corr[0])/2)+4*dist2look)
                self.lag_corrs[logname]=(lag_corr[0][lagcor_range],lag_corr[1][lagcor_range])
        self.log_correlations_plot()
        self.getFormLayerFilled()
    def log_correlations_plot(self):
        self.mw = MatplotlibWidget(size=(22.0, len(self.interestedLognames)*1.6), dpi=100)   
        self.logscrollArea.setWidget(self.mw)
        print('Plotting...')
        self.ax=[]
        for i,logname in enumerate(self.normlogs.keys()):
            self.ax.append(self.mw.getFigure().add_subplot(len(self.normlogs),1,i+1) )
            l, b, w, h = self.ax[-1].get_position().bounds 
            self.ax[-1].set_position([0.27,b+0.1,0.7,h])
            # self.log_col=self.las[logname]  
            # self.log_col[np.isnan(self.log_col)]=0            
            # norm_blog=mean_norm(self.log_col)#[0:800]
            depthb_shift=self.depth_col+self.delays[logname]
            self.ax[-1].plot(self.depth_col,self.normlogs[logname],'b')
            self.ax[-1].plot(self.depth_col,self.norm_gamma,'r')
            self.ax[-1].plot(depthb_shift,self.normlogs[logname],'magenta')
            self.ax[-1].text(self.depth_col[0]-50,0.02,logname)

        lenax=len(self.ax)
        for i,logname in enumerate(self.lag_corrs.keys()):
            self.ax.append(self.mw.getFigure().add_subplot(len(self.normlogs),2,lenax+i+1) )
            l, b, w, h = self.ax[i].get_position().bounds
            self.ax[-1].set_position([0.03,b,0.21,h])
            self.ax[-1].plot(self.lag_corrs[logname][0],self.lag_corrs[logname][1],'b')
            self.ax[-1].text(self.delays[logname],min(self.lag_corrs[logname][1]),'Delay = %.2f'%self.delays[logname])
            line = self.ax[-1].axvline(x=self.delays[logname], ymin=-1, ymax = +1, linewidth=1.5, color='c')
            self.ax[-1].text(self.lag_corrs[logname][0][0],0.4,logname)
                
        self.mw.draw()
        print('Complete...')

    def buildLogTree(self,lases):
        w = LasTree()
        # self.lasLoadThread = LasLoadThread(files=files_w_path)

        self.lases=lases
        if (len(self.lases)>0):
            if (len(self.lases[0].keys())>0):
                self.las=self.lases[0]      
                w.set_files(self.las.keys())
                del w.treeview_dict['Log']['NA']
                self.treeview_dict=w.treeview_dict
                
                w.buildTreeWidget()          

        self.dock.setWidget(w.tree)         
        
    def createDockWindows(self):        
        self.dock = QDockWidget("Log Files", self)
        self.dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        # dock.setWidget(self.lastree.tree)        
        self.addDockWidget(Qt.LeftDockWidgetArea, self.dock)
Esempio n. 9
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        self.axs = {}
        
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(1024, 768)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(MainWindow.sizePolicy().hasHeightForWidth())
        MainWindow.setSizePolicy(sizePolicy)
        icon = QtGui.QIcon()
        icon.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/logo48.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        MainWindow.setWindowIcon(icon)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.splitter1 = QtGui.QSplitter(QtCore.Qt.Horizontal)       
        #self.splitter1.setOpaqueResize(False)
        self.splitter1.setChildrenCollapsible(False)
        
        
        self.verticalLayout = QtGui.QVBoxLayout(self.centralwidget)
        self.verticalLayout.setObjectName(_fromUtf8("verticalLayout"))

        

        self.progressBar = QtGui.QProgressBar(self.centralwidget)
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName(_fromUtf8("progressBar"))
        self.progressBar.hide()

        self.progressBar_batch = QtGui.QProgressBar(self.centralwidget)
        self.progressBar_batch.setProperty("value", 24)
        self.progressBar_batch.setObjectName(_fromUtf8("progressBar_batch"))
        #self.progressBar_batch.hide()        
        #self.verticalLayout.addWidget(self.progressBar)
        MainWindow.setCentralWidget(self.centralwidget)
        
# Menu bar        
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 574, 36))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        
        self.menuFile = QtGui.QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuExport = QtGui.QMenu(self.menuFile)
        self.menuExport.setObjectName(_fromUtf8("menuExport"))
        
        self.menuView = QtGui.QMenu(self.menubar)
        self.menuView.setObjectName(_fromUtf8("menuView")) 
        
        MainWindow.setMenuBar(self.menubar)
        
# Status bar        
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.statusbar.addPermanentWidget(self.progressBar)
        self.statusbar.addPermanentWidget(self.progressBar_batch)        
        
                        
# Tool bar
        
        self.toolBar = QtGui.QToolBar(MainWindow)
        self.toolBar.setObjectName(_fromUtf8("toolBar"))
        self.toolBar.setIconSize(QtCore.QSize(64, 64))
        #self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)        
        MainWindow.addToolBar(QtCore.Qt.LeftToolBarArea, self.toolBar)        
        

# Dockable filelist
# http://www.tutorialspoint.com/pyqt/pyqt_qdockwidget.htm
# Is it necessary to use dockWidgetContent and layout?
        
        self.dockWidget_file_list = QtGui.QDockWidget("Annotations", MainWindow)
        self.dockWidget_file_list.setObjectName(_fromUtf8("dockWidget_file_list"))
        MainWindow.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.dockWidget_file_list)          
        
        self.tableWidget_file_list = QtGui.QTableWidget(0, 2)
        self.tableWidget_file_list.setHorizontalHeaderLabels(['File','Fraction(%)']) 
        self.tableWidget_file_list.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.tableWidget_file_list.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)          
        self.tableWidget_file_list.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)        

        self.dockWidget_file_list.setWidget(self.tableWidget_file_list)        
        
        header = self.tableWidget_file_list.horizontalHeader()
        header.setStretchLastSection(True)
        #header.setResizeMode(QtGui.QHeaderView.Stretch)


    
# Dockable hist
    
        self.splitter_lcd = QtGui.QSplitter(QtCore.Qt.Vertical)       
        #self.splitter1.setOpaqueResize(False)
        self.splitter_lcd.setChildrenCollapsible(False)        
        
        self.mw_hist = MatplotlibWidget()
        self.axs['hist_viewer'] = self.mw_hist.getFigure().add_subplot(111)  
        self.splitter_lcd.addWidget(self.mw_hist) 

        
        self.lcdNumber = QtGui.QLCDNumber(self.centralwidget)
        self.lcdNumber.setProperty("value", 12.34)
        self.lcdNumber.setObjectName(_fromUtf8("lcdNumber"))
        #self.lcdNumber.setSegmentStyle(QtGui.QLCDNumber.Flat)
        self.splitter_lcd.addWidget(self.lcdNumber)   
        self.lcdNumber.setMinimumHeight(40)
#        self.splitter_lcd.setStretchFactor(0, 7);
#        self.splitter_lcd.setStretchFactor(1, 1);        
#        self.splitter_lcd.setSizes([100,1])
#http://stackoverflow.com/questions/14478574/changing-the-digit-color-of-qlcd-number        
        palette = self.lcdNumber.palette() 
        # foreground color
        palette.setColor(palette.WindowText, QtCore.Qt.red)
        # background color
        palette.setColor(palette.Background, QtGui.QColor(255, 0, 0))
#        # "light" border
#        palette.setColor(palette.Light, QtGui.QColor(255, 0, 0))
#        # "dark" border
#        palette.setColor(palette.Dark, QtGui.QColor(0, 255, 0))
        # set the palette
        self.lcdNumber.setPalette(palette)    
    
        self.dockWidget_hist = QtGui.QDockWidget("Distribution", MainWindow)
        self.dockWidget_hist.setObjectName(_fromUtf8("dockWidget_hist"))
        self.dockWidget_hist.setWidget(self.splitter_lcd)        
        
        MainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockWidget_hist) 

# Dockable responses
        self.dockWidget_responses = QtGui.QDockWidget("Responses", MainWindow)
        self.dockWidget_responses.setObjectName(_fromUtf8("dockWidget_responses"))
        MainWindow.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.dockWidget_responses)         
        self.mw_response = MatplotlibWidget()
        self.axs['response_viewer'] = self.mw_response.getFigure().add_subplot(221)         
        self.axs['segment_viewer'] = self.mw_response.getFigure().add_subplot(222)   
        self.axs['raw_response_viewer'] = self.mw_response.getFigure().add_subplot(223)   
        self.axs['exemplar_viewer'] = self.mw_response.getFigure().add_subplot(224) 
        
            
        self.dockWidget_responses.setWidget(self.mw_response)        

                #self.splitter1.addWidget(self.splitter_lcd)
    
# Actions        
        self.actionOpen = QtGui.QAction(MainWindow)
        icon1 = QtGui.QIcon()
        icon1.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/add_image.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionOpen.setIcon(icon1)
        self.actionOpen.setObjectName(_fromUtf8("actionOpen"))
        
        self.actionOpen_folder = QtGui.QAction(MainWindow)
        icon2 = QtGui.QIcon()
        icon2.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/add_folder.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionOpen_folder.setIcon(icon2)
        self.actionOpen_folder.setObjectName(_fromUtf8("actionOpen_folder"))
        
        self.actionExportAsCSV = QtGui.QAction(MainWindow)
        self.actionOpen_folder.setObjectName(_fromUtf8("actionExportAsCSV"))        
        
        
        
        self.actionDetect = QtGui.QAction(MainWindow)
        icon3 = QtGui.QIcon()
        icon3.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/detection.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionDetect.setIcon(icon3)
        self.actionDetect.setObjectName(_fromUtf8("actionDetect")) 
        
        self.actionEstimate = QtGui.QAction(MainWindow)
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/recognition.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEstimate.setIcon(icon4)
        self.actionEstimate.setObjectName(_fromUtf8("actionEstimate"))

        self.actionRunOne = QtGui.QAction(MainWindow)
        icon5 = QtGui.QIcon()
        icon5.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/run_one.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionRunOne.setIcon(icon5)
        self.actionRunOne.setObjectName(_fromUtf8("actionRunOne"))         

        self.actionRunAll = QtGui.QAction(MainWindow)
        icon6 = QtGui.QIcon()
        icon6.addPixmap(QtGui.QPixmap(_fromUtf8("./resources/icons/run_all.png")), QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionRunAll.setIcon(icon6)
        self.actionRunAll.setObjectName(_fromUtf8("actionRunAll"))   



# Add actions to menu and toolbar       
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionOpen_folder)
        self.menuFile.addAction(self.menuExport.menuAction())
        self.menuExport.addAction(self.actionExportAsCSV)        
        self.menuFile.addAction(self.actionDetect)        
        
        self.menubar.addAction(self.menuFile.menuAction())
        self.toolBar.addAction(self.actionOpen)
        self.toolBar.addAction(self.actionOpen_folder)      
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionDetect) 
        self.toolBar.addAction(self.actionEstimate) 
        self.toolBar.addAction(self.actionRunOne) 
        self.toolBar.addAction(self.actionRunAll) 
        
        self.actionOpen.triggered.connect(self.load_image)
        self.actionOpen_folder.triggered.connect(self.load_dir)
        self.actionExportAsCSV.triggered.connect(self.export_as_csv)        
        self.actionDetect.triggered.connect(self.detect_blackboard_at_present)
        self.actionEstimate.triggered.connect(self.estimate_coverage_at_present)   
        self.actionRunOne.triggered.connect(self.run_one_at_present)
        self.actionRunAll.triggered.connect(self.run_all)        
        self.tableWidget_file_list.currentItemChanged.connect(self.file_list_selChanged)
##########################################
# Matplotlib Image Viewer

        
        self.mw_image = MatplotlibWidget()
        self.axs['image_viewer'] = self.mw_image.getFigure().add_subplot(111)
        self.axs['image_viewer'].set_frame_on(False)

        #self.splitter_lcd.addWidget(self.lcdNumber)        
        #self.toolBar.addWidget(self.lcdNumber)  
        
        self.splitter1.addWidget(self.mw_image)
        #self.splitter1.addWidget(self.splitter_lcd)

        self.splitter1.setStretchFactor(0, 10);
        #self.splitter1.setStretchFactor(1, 3);       
        self.verticalLayout.addWidget(self.splitter1)
        
        subplot = self.mw_image.getFigure().add_subplot(111)
        x = np.array(range(100))
        y = np.array(range(100))
        subplot.plot(x,y)
        self.mw_image.draw()
        
        self.retranslateUi(MainWindow)
        #QtCore.QObject.connect(self.horizontalSlider, QtCore.SIGNAL(_fromUtf8("valueChanged(int)")), self.progressBar.setValue)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

        self.window = MainWindow
        
        self.veg_data = veg_data()      
        
        self.veg_data.img_orig = None
        self.veg_data.bbox = []        
        
    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MO-VE: Missouri Vegetation Measurement Tool", None))
        #self.label.setText(_translate("MainWindow", "Output:", None))
        self.menuFile.setTitle(_translate("MainWindow", "File", None))
        self.menuExport.setTitle(_translate("MainWindow", "Export", None))
        self.menuView.setTitle(_translate("MainWindow", "View", None))        
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar", None))
        self.actionOpen.setText(_translate("MainWindow", "Load an image", None))
        self.actionOpen_folder.setText(_translate("MainWindow", "Load a folder", None))
        self.actionExportAsCSV.setText(_translate("MainWindow", "Export as CSV", None))
        
        
        self.actionDetect.setText(_translate("MainWindow", "Detect blackboard", None))     
        self.actionEstimate.setText(_translate("MainWindow", "Estimate coverage rate", None))
        self.actionRunOne.setText(_translate("MainWindow", "Run on current image", None))
        self.actionRunAll.setText(_translate("MainWindow", "Run on all images", None))        

             
    
    def load_image(self):
        fileName = QtGui.QFileDialog.getOpenFileName(None, 'OpenFile')
        fileName = unicode(fileName)
        if fileName == '' or self.load_image_by_name(fileName):
            return
        if not self.load_image_by_name(fileName):
            return
        dir_name, picture_name = os.path.split(fileName)
        self.veg_data.dir = dir_name                    
        self.veg_data.picture_list = [picture_name]
        self.veg_data.fraction_list = ['-']
        self.tableWidget_file_list.clearContents()
        self.tableWidget_file_list.setRowCount(1)
        
        self.tableWidget_file_list.setItem(0,0, QtGui.QTableWidgetItem(picture_name))  
        self.tableWidget_file_list.setItem(0,1, QtGui.QTableWidgetItem("-"))              
        

  
    def load_image_by_name(self, fileName):
        if fileName == '':
            return
            
         
        print fileName
        t0 = time.time()   
        img = cv2.imread(fileName)
        t1 = time.time()
        print 'cv2.imread',  t1 - t0        
        
        if img is None:
            msg = QtGui.QMessageBox()
            msg.setIcon(QtGui.QMessageBox.Warning)
        
            msg.setText("Unable to open " + fileName + '.')
            msg.setInformativeText("Unrecognized image format.")
            msg.setWindowTitle("MessageBox demo")
            #msg.setDetailedText("The details are as follows:")
            msg.setStandardButtons(QtGui.QMessageBox.Ok)
        	
            retval = msg.exec_()
            return False

        else:
            b,g,r = cv2.split(img)
            img2 = cv2.merge([r,g,b])
            
            t0 = time.time()  
            self.axs['image_viewer'].cla()
            self.axs['image_viewer'].imshow(img2)
            #self.axs['image_viewer'].set_title(os.path.basename(fileName))
            self.mw_image.draw()
            t1 = time.time()
            print 'plt.imshow',  t1 - t0  
            #plt.show()
            self.veg_data.img_orig = img
            self.veg_data.bbox = []
            return True

            
            
            
    def load_dir(self):
        supported_formats = ['.jpg', '.jpeg', '.png']
        dir_name = unicode(QtGui.QFileDialog.getExistingDirectory(self.window, "Select Directory"))
        if dir_name == '':
            return
        file_list = os.listdir(dir_name)
        picture_list = [f for f in file_list if os.path.splitext(f)[1].lower() in supported_formats]
        
        
        
        
        if not picture_list:
            return
        
        
        
        self.tableWidget_file_list.clearContents()
        self.tableWidget_file_list.setRowCount(len(picture_list))
        
  
        for i, p in enumerate(picture_list): 
            self.tableWidget_file_list.setItem(i,0, QtGui.QTableWidgetItem(p))  
            self.tableWidget_file_list.setItem(i,1, QtGui.QTableWidgetItem("-"))  

        self.veg_data.dir = dir_name                    
        self.veg_data.picture_list = picture_list
        self.veg_data.fraction_list = ['-'] * len(picture_list)         
        
        
        
#http://stackoverflow.com/questions/14803315/connecting-qtableview-selectionchanged-signal-produces-segfault-with-pyqt            
    def file_list_selChanged(self, item0, item1):

        if item0 is None:
            return
        if item1 is not None and item0.row() == item1.row():
            return
        print 'Selection changed.', item0.row(), unicode(item0.text())
        

        self.load_image_by_name(os.path.join(self.veg_data.dir, self.veg_data.picture_list[item0.row()]))
        
        self.veg_data.current_item_idx = item0.row()
        
        # Read cache

        file_name = self.veg_data.picture_list[self.veg_data.current_item_idx]
        file_name = os.path.basename(file_name)
        file_name = os.path.splitext(file_name)[0]
        segments = cv2.imread(os.path.join(self.veg_data.cache_dir, file_name + '_segments.tiff'))
        hist = None
        fraction = 0.0
        if segments is not None:        
            segments = np.bool_(segments)
            #print 'segments.shape == ', segments.shape
            hist = np.float32(segments[:,:,0]).mean(1)
            self.veg_data.fraction = float(hist.mean())

        #print os.path.join(self.veg_data.cache_dir, file_name + '_segments.tiff')
#        print segments.shape
        self.update_segment_viewer(segments)
        self.update_hist_viewer(hist)
        
#        print self.veg_data.fraction
#        print type(self.veg_data.fraction), type(self.veg_data.fraction * 1.0)
        self.lcdNumber.display(self.veg_data.fraction * 100.0)

        
    def export_as_csv(self):

#### non-native way:
#        dialog = QtGui.QFileDialog()
#        dialog.setFilter(dialog.filter() | QtCore.QDir.Hidden)
#        dialog.setDefaultSuffix('json')
#        dialog.setAcceptMode(QtGui.QFileDialog.AcceptSave)
#        dialog.setNameFilters(['JSON (*.json)'])
#        if dialog.exec_() == QtGui.QDialog.Accepted:
#            print(dialog.selectedFiles())
#        else:
#            print('Cancelled')        
####        
        
        fileName = QtGui.QFileDialog.getSaveFileName(None, 'Export as CSV', './untitled.csv', 'Comma-Separated Values files (*.csv)')
        fileName = unicode(fileName)
            
        if fileName:
#            if os.path.splitext(fileName)[1] != '.csv':
#                fileName += '.csv'
            with open(fileName, 'wb') as csvfile:
                csv_writer = csv.writer(csvfile, delimiter=',',
                                        quotechar='"', quoting=csv.QUOTE_MINIMAL)
                for file_name, cov_rate in zip(self.veg_data.picture_list, self.veg_data.fraction_list):                        
                    csv_writer.writerow([file_name, cov_rate])

        
        print fileName
        
        
    def detect_blackboard(self, img):

        height = img.shape[0]
        width = img.shape[1]    
        
        # Get the bounding box of blackboard
        img_HSV = cv2.cvtColor(img, cv2.cv.CV_BGR2HSV)
        x0, y0, x1, y1 = detectBlackboard(img_HSV)
        x0 *= width
        x1 *= width
        y0 *= height
        y1 = (x1-x0) * 1.5 + y0
        print  x0, y0, x1, y1
        bbox = [x0, y0, x1, y1]

        return bbox         
        
    def detect_blackboard_at_present(self):
        img = self.veg_data.img_orig
        if img is None:
            return
        self.veg_data.bbox = self.detect_blackboard(img)
        # Visulization 
        self.draw_bbox(self.veg_data.bbox)
       
    def estimate_coverage_at_present(self):
        img = self.veg_data.img_orig
        if img is None:
            return
            
        bbox = self.veg_data.bbox
        #print 'bbox', bbox
        if not bbox:
            return
        fraction, segments, hist, response, raw_response = \
                self.estimate_coverage(img, bbox, fast_mode=self.veg_data.fast_mode)
        
        # update list
        self.veg_data.fraction_list[self.veg_data.current_item_idx] = fraction
        self.veg_data.fraction = fraction
        self.tableWidget_file_list.item(self.veg_data.current_item_idx, 1).setText(str(fraction * 100))     
        
        # save cache
        file_name = self.veg_data.picture_list[self.veg_data.current_item_idx]
        file_name = os.path.basename(file_name)
        file_name = os.path.splitext(file_name)[0]
        cv2.imwrite(os.path.join(self.veg_data.cache_dir, file_name + '_segments.tiff'), np.uint8(segments))  
        cv2.imwrite(os.path.join(self.veg_data.cache_dir, file_name + '_segments.pbm'), np.uint8(segments))          
        # Visulization                
        self.lcdNumber.display(float(fraction) * 100.0)            
        self.progressBar.setValue(90)
        QtGui.QApplication.processEvents() 
        self.update_segment_viewer(segments)             
        self.update_response_viewer(response)
        self.update_raw_response_viewer(raw_response)
        self.update_hist_viewer(hist)
        self.update_exemplar_viewer(raw_response > THRES_RAW)
     
        self.progressBar.setValue(100)
        QtGui.QApplication.processEvents() 
        self.progressBar.hide()                
                        
        # Reactivate the file list tablewidget            
        self.tableWidget_file_list.setEnabled(True)    
       
    def estimate_coverage(self, img, bbox, fast_mode=False):

        self.progressBar.show()
        self.progressBar.setValue(10)
        QtGui.QApplication.processEvents()
        x0 = bbox[0]
        y0 = bbox[1]
        x1 = bbox[2]
        y1 = bbox[3]
            
        img_bboard = img[int(y0):int(y1), int(x0):int(x1), :]
            
            
        response, raw_response, exemplar_colors = \
            classify(img_bboard, THRES_RAW, fast_mode=fast_mode)
        self.progressBar.setValue(65)
        QtGui.QApplication.processEvents()
        fraction = 0.0
                      
        if response is not None:

            segments = (response > THRES_KMS)
            fraction = np.mean(segments)             
            hist = np.float32(segments).mean(1)

        else:
            hist = None
            
        return fraction, segments, hist, response, raw_response       

        # Make blackboard red

#            r1 = r[int(y0):int(y1), int(x0):int(x1)]
#            r1 = np.uint8(np.multiply(r1, coverage) 
#                    + np.multiply(r1, ~coverage) * 0.4 + ~coverage * (255*0.6))  
#            r[int(y0):int(y1), int(x0):int(x1)] = r1   
#            img2 = cv2.merge([r,g,b]) 
        
        
    def run_all(self):
        if len(self.veg_data.picture_list) > 0:
            self.progressBar_batch.setMaximum(len(self.veg_data.picture_list))
            
#        # Disable items first to prevent user's interacting
#        # http://stackoverflow.com/questions/21001144/disable-user-to-click-over-qtablewidget
#        for i, p in enumerate(self.veg_data.picture_list): 
#            item = self.tableWidget_file_list.item(i,0)
#            item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEnabled)
#            item = self.tableWidget_file_list.item(i,1)
#            item.setFlags(item.flags() & ~QtCore.Qt.ItemIsEnabled)       
        self.tableWidget_file_list.setEnabled(False)   
        
        for i in range(len(self.veg_data.picture_list)):
            self.tableWidget_file_list.selectRow(i) # This line need to be reimplemented,
                                                    # Different image shouldn't be selected though GUI
            self.run_one(fast_mode=True)
            self.progressBar_batch.setValue(i+1)
            QtGui.QApplication.processEvents() 
            
        self.tableWidget_file_list.setEnabled(True)     
         
#        # Resume user's interacting    
#        for i, p in enumerate(self.veg_data.picture_list): 
#            item = self.tableWidget_file_list.item(i,0)
#            item.setFlags(item.flags() | QtCore.Qt.ItemIsEnabled)
#            item = self.tableWidget_file_list.item(i,1)
#            item.setFlags(item.flags() | QtCore.Qt.ItemIsEnabled)       
                 

    def run_one_at_present(self):
        self.tableWidget_file_list.setEnabled(False)
        self.detect_blackboard_at_present()
        self.estimate_coverage_at_present()
        self.tableWidget_file_list.setEnabled(True) 
        
        
    def run_one(self,fast_mode=True):
        # Disactive the file list tablewidget 
        self.tableWidget_file_list.setEnabled(False)
        img = self.veg_data.img_orig
        bbox = self.detect_blackboard(img)
        
        # Visulization 
        self.draw_bbox(bbox)
        
        fraction, segments, hist, response, raw_response = \
                        self.estimate_coverage(img, bbox, fast_mode=fast_mode)
        
        # update list
        self.veg_data.fraction_list[self.veg_data.current_item_idx] = fraction
        self.veg_data.fraction = fraction
        self.tableWidget_file_list.item(self.veg_data.current_item_idx, 1).setText(str(fraction * 100))     
        
        # Visulization                
        self.lcdNumber.display(float(fraction) * 100.0)            
        self.progressBar.setValue(90)
        QtGui.QApplication.processEvents() 
        self.update_segment_viewer(segments)             
        self.update_response_viewer(response)
        self.update_raw_response_viewer(raw_response)
        self.update_hist_viewer(hist)
        self.update_exemplar_viewer(raw_response > THRES_RAW)
     
        self.progressBar.setValue(100)
        QtGui.QApplication.processEvents() 
        self.progressBar.hide()                
                        
        # Reactivate the file list tablewidget            
        self.tableWidget_file_list.setEnabled(True)      
        
       
    def draw_bbox(self, bbox):
        x0 = bbox[0]
        y0 = bbox[1]
        x1 = bbox[2]
        y1 = bbox[3]
        self.axs['image_viewer'].add_patch(
            plt.Rectangle((x0, y0),
                          (x1 - x0), 
                          (y1 - y0),
                          fill=False,
                          edgecolor='red', linewidth=2.0)
            )
        self.axs['image_viewer'].text(x0, y0 - 30,
            "blackboard",
        bbox=dict(facecolor='red', alpha=0.5),
        fontsize=12, color='white')                
        self.mw_image.draw()   
       
       
    def update_segment_viewer(self, segments):
        self.axs['segment_viewer'].cla()  
        if segments is None:
            self.mw_response.draw()
            return
        
        self.axs['segment_viewer'].imshow(segments, cmap='gray', interpolation='nearest')
        self.axs['segment_viewer'].set_title('Predicted vegetation')
        self.mw_response.draw()        
        
       
    def update_raw_response_viewer(self, raw_response):
        self.axs['raw_response_viewer'].cla()        
        if raw_response is None:
            self.mw_response.draw()
            return
        self.axs['raw_response_viewer'].imshow(-raw_response, interpolation='nearest')
        self.axs['raw_response_viewer'].set_title('LBP+SVM response map')    
        self.mw_response.draw()        


    def update_exemplar_viewer(self, exemplar):
        self.axs['exemplar_viewer'].cla()
        if exemplar is None:
            self.mw_response.draw()
            return
        self.axs['exemplar_viewer'].imshow(exemplar, cmap='gray', interpolation='nearest')
        self.axs['exemplar_viewer'].set_title('BBoard exemplar regions')
        self.mw_response.draw()


    def update_response_viewer(self, response):
        self.axs['response_viewer'].cla()
        if response is None:
            self.mw_response.draw()
            return
        self.axs['response_viewer'].imshow(np.log(response))
        self.axs['response_viewer'].set_title('KMeans loss map')
        self.mw_response.draw()  
          
        
    def update_hist_viewer(self, hist):
        
        self.axs['hist_viewer'].cla() 
#        print "hist is None:", hist is None
#        print hist.shape
        if hist is None or hist.shape[0] == 0:
            self.axs['hist_viewer'].text(0.1, 0,
                    "Unknown",
                    fontsize=15, weight='bold', color='red')
            self.mw_hist.draw()
            return
        
#        print hist.shape
        heights = range(hist.shape[0])
        heights.reverse()        
        self.axs['hist_viewer'].fill_betweenx(heights, hist, x2=0.0, color='#76b900', linewidth=1.0)
                
        self.axs['hist_viewer'].set_xlim([0.0, 1.0])
        self.axs['hist_viewer'].set_ylim([0.0, hist.shape[0]])
        self.axs['hist_viewer'].set_xlabel('coverage rate')
        self.axs['hist_viewer'].set_ylabel('height (/px)')        
        self.axs['hist_viewer'].set_title('Coverage rate vs. Height ')
        self.axs['hist_viewer'].set_axis_bgcolor('#444444')
        self.axs['hist_viewer'].grid(True, color='white')
        self.axs['hist_viewer'].text(0.1, 0,
            "overall\ncoverage:\n{0:.1f}%".format(np.mean(hist) * 100),
            fontsize=15, weight='bold', color='white')

        #self.mw_hist.getFigure().tight_layout()   # Failed when too narrow
        self.mw_hist.getFigure().subplots_adjust(left=0.4, right=0.9)        
        self.mw_hist.getFigure().subplots_adjust(left=0.4, right=0.9)
        self.mw_hist.draw()
Esempio n. 10
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setGeometry(100, 100, 600, 900)

        self.centralWidget = QWidget()
        # GrphicsWidget()
        layout = QHBoxLayout(self.centralWidget)
        self.scrollArea = QScrollArea(self)

        # gwidget=GrphicsWidget()

        self.mw = MatplotlibWidget(size=(3.0, 40.0), dpi=100)
        lplot = self.mw.getFigure().add_subplot(121)
        # print(dir(self.mw.getFigure()))

        # self.mw.getFigure().set_axes([0.85, 0.1, 0.075, 0.8])
        self.ax = self.mw.getFigure().gca()
        self.ax.set_position([0.1, 0.05, 0.8, 0.94])
        self.ax.invert_yaxis()
        # l, b, w, h = self.ax.get_position().bounds
        # print(l, b, w, h)
        self.mw.draw()
        # self.plotlayout.addWidget(self.mw)

        self.scrollArea.setWidget(self.mw)

        layout.addWidget(self.scrollArea)

        self.setCentralWidget(self.centralWidget)
        self.lastree = LasTree()
        self.logtree = LasTree()
        self.wellLoad()
        self.logtree.set_files(['GR', 'BS'])
        self.logtree.buildTreeWidget()
        self.logtree.tree.itemSelectionChanged.connect(self.logPlot)

        self.createDockWindows()

        # self.logFileList.itemSelectionChanged.connect(self.lasLoad)
        # if not self.las_just_selected:
        # self.logList.itemSelectionChanged.connect(self.logPlot)

        self.setWindowTitle("Loggy")

        # self.newLetter()
    def wellLoad(self):
        self.wellFolder = r'D:\Ameyem Office\Projects\Cairn\W1\LAS\\'

        self.files = np.array(os.listdir(self.wellFolder)[:])
        files_w_path = [self.wellFolder + f for f in self.files]

        cols = []

        self.files = np.array(os.listdir(self.wellFolder)[:])

        self.lastree.set_files(self.files)
        self.lastree.buildTreeWidget()
        self.lastree.tree.itemSelectionChanged.connect(self.lasLoad)

        self.lasLoadThread = LasLoadThread(files=files_w_path)

    # def lasBackgroundLoad():

    def lasLoad(self):
        las_name = self.lastree.tree.selectedItems()[0].text(
            0)  #self.logFileList.selectedItems()[0].text()
        if las_name in ['TVD', 'MD', 'LWD', 'WireLine']:
            return

        findex = np.where(self.files == las_name)[0][0]
        # print(findex)
        Loaded = False
        while (not Loaded):
            if (findex < len(self.lasLoadThread.Lases)):
                self.las = self.lasLoadThread.Lases[findex]
                Loaded = True
                self.logtree.tree.clear()
                # print('hi')
            else:
                # print('hello')

                # self.logtree.addItems(['Loading....'])
                time.sleep(1)

        if len(self.logtree.tree.selectedItems()) > 0:
            item = self.logtree.tree.selectedItems()[0]
            # print(dir(item))
            item.setSelected = False
        if not (len(self.las.keys()) < 1):
            # self.logtree = LasTree(self.las.keys())
            self.logtree.set_files(self.las.keys())
            self.logtree.buildTreeWidget()

            dcol = self.las.keys()[find_depth_indx(self.las)]
            self.depth_col = str_array2floats(self.las[dcol])
        # else:

        # self.las_just_selected = True

    def logPlot(self):

        # print(self.mw.getFigure().)
        # pass
        # if not self.las_just_selected:
        if len(self.logtree.tree.selectedItems()) > 0:
            keycol = self.logtree.tree.selectedItems()[0].text(0)
            try:
                self.log_col = str_array2floats(self.las[keycol])
                self.ax = LogPlot.basicPlot(self.ax,
                                            self.depth_col,
                                            self.log_col,
                                            lcolor='#800000')
            except:
                print('Unable to convert log to floats')
        self.mw.draw()

    def set_category(self):
        # qt_app = QApplication(sys.argv)
        mnomonicsfile = self.wellFolder + '../../mnemonics.txt'
        # print(self.logtree.treeview_dict)
        # set_category_app = Categorize(self.logtree.treeview_dict,mnomonicsfile)
        print('*************************************************')
        print(self.logtree.treeview_dict)
        category_window = Categorize(self)
        category_window.set_params(self.logtree, mnomonicsfile)
        category_window.show()

        # self.logtree.tree.clear()
        # self.logtree.buildTreeWidget()
        # set_category_app.run()
        # self.logtree.buildTreeWidget()

    def createDockWindows(self):

        dock = QDockWidget("Log Files", self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        dock.setWidget(self.lastree.tree)
        #
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        self.set_category_button = QPushButton('Set Category', self)

        # self.layout.addWidget(self.logtree.tree)
        dock = QDockWidget("Set", self)
        dock.setWidget(self.set_category_button)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        dock = QDockWidget("Logs", self)

        dock.setWidget(self.logtree.tree)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)

        self.set_category_button.clicked.connect(self.set_category)
Esempio n. 11
0
class ScopeWindows(QtGui.QWidget):
    def __init__(self, args):
        super().__init__()
        self.setObjectName('I')

        self.main_layout = main_layout = QtGui.QVBoxLayout()
        self.setLayout(main_layout)

        self.plot_widget = MatplotlibWidget()

        btn_layout = QtGui.QHBoxLayout()

        self.startstop = QtGui.QPushButton(self)
        self.startstop.setText('Start')
        self.label = QtGui.QLabel(self)
        self.display_label(0)
        self.save_btn = QtGui.QPushButton('Save', self)

        btn_layout.addWidget(self.startstop)
        btn_layout.addWidget(self.save_btn)
        btn_layout.addWidget(self.label)

        main_layout.addWidget(self.plot_widget)
        main_layout.addLayout(btn_layout)

        self.startstop.clicked.connect(self.on_startstop_clicked)
        self.save_btn.clicked.connect(self.save_to_file)

        print('INIT')

    @QtCore.pyqtSlot()
    def on_startstop_clicked(self):
        if self.startstop.text() == 'Start':
            self.startstop.setText('Stop')
            self.thread = MyThread(self.display_label)
            self.thread.start()
        elif self.startstop.text() == 'Stop':
            self.startstop.setText('Start')
            self.thread.running = False

    @QtCore.pyqtSlot()
    def save_to_file(self):
        # See https://doc.qt.io/qtforpython/PySide2/QtWidgets/QFileDialog.html#PySide2.QtWidgets.PySide2.QtWidgets.QFileDialog.getSaveFileName
        file_name = QtGui.QFileDialog.getSaveFileName(self.save_btn,
                                                      'Save file', "",
                                                      "Data file (*.txt)")
        print(file_name)

    def plot(self, param=0):
        fig = self.plot_widget.getFigure()
        fig.clf()
        x = np.linspace(0, 1, 1001)
        y = np.sin(2 * np.pi * x * param)
        ax = fig.subplots()
        ax.plot(x, y)
        ax.set_ylim(-1, 1)
        fig.canvas.draw()

    def display_label(self, val):
        self.plot(val)
        dec = val % 1
        int_part = int(val - dec)
        seconde = int_part % 60
        minutes = int_part // 60
        self.label.setText('{:02d}:{:02d}:{:02d}'.format(
            minutes, seconde, int(100 * dec)))
class SplatalogueAssignmentWindow(QDialog):
    FACE_COLOR = "#626262"
    EXPERIMENT_EDGE_COLOR = 'black'

    def __init__(self, experiment, chemical, selection_widget):
        super(SplatalogueAssignmentWindow, self).__init__()
        self.setWindowIcon(QIcon(QPixmap(images.LOGO_ICON)))
        self.setAttribute(Qt.WA_DeleteOnClose)
        self.setWindowTitle("Splatalogue Assignment Window")
        self.resize(1500, 750)

        ''' Data '''
        self.experiment = experiment
        self.chemical = chemical

        ''' Widgets '''
        self.info_widget = SplatalogueInfoWidget(chemical)
        self.table_widget = QTableWidget()
        self.matplot_widget = MatplotlibWidget()
        self.selection_widget = selection_widget

        '''Colors'''
        self.color___experiment_edge = SplatalogueAssignmentWindow.EXPERIMENT_EDGE_COLOR
        self.color___face_color = SplatalogueAssignmentWindow.FACE_COLOR

        self.__setup__()

    def validate(self):
        # Validate all lines for now
        for line in self.chemical.lines:
            line.validated = True
        match = self.chemical.validate_chemical(self.experiment)
        self.selection_widget.add_row(match)

        self.close()
        self.setResult(1)

    def __setup__(self):
        self.setStyleSheet(
            "background-color: rgb(48, 48, 48);\ngridline-color: rgb(195, 195, 195);\ncolor: rgb(255, 255, 255);\n")
        self.matplot_widget.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.__setup_layout()
        self.__populate_graph()
        self.__populate_table()

    def __setup_layout(self):
        outer_layout = QVBoxLayout()

        ''' Inner Grid Layout '''
        layout = QGridLayout()
        left_layout = QVBoxLayout()
        left_layout.addWidget(self.info_widget)
        left_layout.addWidget(self.table_widget)
        layout.addLayout(left_layout, 0, 0)
        layout.addWidget(self.matplot_widget, 0, 1)

        ''' Bottom Frame '''
        bottom_frame = QFrame()
        frame_layout = QHBoxLayout()
        # --- Widgets --- #
        validate_btn = QPushButton(QIcon(images.VALIDATE_ICON), "Validate")
        cancel_btn = QPushButton("Cancel")
        # -- Settings -- #
        bottom_frame.setFrameShadow(QFrame.Raised)
        bottom_frame.setFrameShape(QFrame.StyledPanel)
        # -- Add Widgets -- #
        frame_layout.addSpacerItem(QSpacerItem(20, 40, QSizePolicy.Expanding, QSizePolicy.Minimum))
        frame_layout.addWidget(validate_btn)
        frame_layout.addWidget(cancel_btn)
        bottom_frame.setLayout(frame_layout)
        # -- Button Connections -- #
        validate_btn.clicked.connect(self.validate)
        cancel_btn.clicked.connect(self.close)

        ''' Add '''
        outer_layout.addLayout(layout)
        outer_layout.addWidget(bottom_frame)

        self.setLayout(outer_layout)

    def __populate_graph(self):
        """

        :return:
        """

        figure = self.matplot_widget.getFigure()
        figure.set_facecolor(self.color___face_color)

        ''' Experiment Subplot '''
        frequencies, intensities = self.experiment.get_experiment_frequencies_intensities_list()
        max_freq = max(frequencies)
        min_freq = min(frequencies)

        self.subplot_1 = figure.add_subplot(311,
                                            axisbg='white',
                                            title='Experiment: ' + self.experiment.name + ' Peaks')

        self.subplot_1.bar(frequencies, intensities, width=0.02, edgecolor=self.color___experiment_edge)

        ''' Matches Subplot '''
        self.subplot_2 = figure.add_subplot(312,
                                            axisbg='white',
                                            sharex=self.subplot_1)

        for l in self.chemical.lines:
            # if l.intensity <= 0:
            self.subplot_2.bar(l.frequency, 1, width=0.02, edgecolor='blue')
            # else:
            #     self.subplot_2.bar(l.frequency, l.intensity, width=0.02, edgecolor='blue')

        ''' Chemical Subplot '''
        self.subplot_3 = figure.add_subplot(313,
                                            axisbg='white',
                                            sharex=self.subplot_1)

        lines = self.chemical.get_all_lines(min_freq, max_freq)
        for l in lines:
            if l.intensity is None:  # or l.intensity <= 1:
                self.subplot_3.bar(l.frequency, 1, width=0.02, edgecolor='black')
            else:
                self.subplot_3.bar(l.frequency, l.intensity, width=0.02, edgecolor='blue')

        ''' Adjustments '''
        # self.matplot_widget.getFigure().subplots_adjust(top=0.95,
        #                                              bottom = 0.07,
        #                                              left = 0.05,
        #                                              right = 0.97,
        #                                              hspace=0.35,)
        self.matplot_widget.draw()

    def __populate_table(self):
        """

        :return:
        """

        row_count = self.chemical.N
        column_count = 5

        # Format Table
        self.table_widget.setRowCount(row_count)
        self.table_widget.setColumnCount(column_count)
        self.table_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)
        self.table_widget.setSortingEnabled(True)

        # Set Header Label
        self.table_widget.setHorizontalHeaderLabels(["EXP-Frequency", "Frequency", "Intensity", \
                                                     "Units", "Linelist", ])

        for i in range(0, row_count):
            # Get Row Data
            # exp_freq = self.chemical.matched_lines[i]
            exp_freq = get_frequency(conn, self.chemical.matched_lines[i])
            frequency = self.chemical.lines[i].frequency
            intensity = self.chemical.lines[i].intensity
            line_list = self.chemical.lines[i].line_list
            units = self.chemical.lines[i].units

            # Convert Data to QTableWidgetItem
            exp_freq_item = QTableWidgetItem(str(exp_freq))
            frequency_item = QTableWidgetItem(str(frequency))
            intensity_item = QTableWidgetItem(str(intensity))
            line_list_item = QTableWidgetItem(str(line_list))
            units_item = QTableWidgetItem(str(units))

            self.table_widget.setItem(i, 0, exp_freq_item)
            self.table_widget.setItem(i, 1, frequency_item)
            self.table_widget.setItem(i, 2, intensity_item)
            self.table_widget.setItem(i, 3, units_item)
            self.table_widget.setItem(i, 4, line_list_item)

        # --- Set Size Policy --- #
        self.table_widget.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.MinimumExpanding)
        self.table_widget.setMaximumWidth(600)
        self.table_widget.setFixedWidth(500)
        self.table_widget.resizeColumnsToContents()
        self.table_widget.resizeRowsToContents()

        # -- Additional Options -- #
        self.table_widget.setEditTriggers(QTableWidget.NoEditTriggers)  # disallow in-table editing
Esempio n. 13
0
class VESViewer(QMainWindow):
    curve = []
    Image = []
    listitem = []
    imfolder = r"D:\Ameyem Office\Geoservices\Digitizer\\"
    zoom_fact = 1
    fileName = ''
    pick_type = 'digitize'
    depth_pix_lims = []
    prop_pix_lims = []
    init_thicks = [1, 10, 15, 175]
    init_res = [20, 4, 60, 200, 2000]
    proj_path = r'D:/Ameyem Office/Projects/Electric surveys/Easwar files/Mahoba/mohaba.resp/'

    def __init__(self):
        super(VESViewer, self).__init__()

        self.createActions()
        self.createMenus()
        win = QWidget()
        self.setCentralWidget(win)
        self.plotlayout = QHBoxLayout(self)
        self.init_m = np.append(self.init_res, self.init_thicks)
        self.datapath = self.proj_path + 'VESData/'
        # creates plot
        # self.plot = pg.PlotWidget()
        self.mw = MatplotlibWidget()
        self.subplot1 = self.mw.getFigure().add_subplot(121)
        self.subplot2 = self.mw.getFigure().add_subplot(122)
        self.mw.draw()
        self.plotlayout.addWidget(self.mw)
        # mltoolbar=self.mw.get_ToolBar()

        layout = BorderLayout()

        layout.add(self.plotlayout, BorderLayout.Center)

        self.list_w = QListWidget()
        # self.listitem.append(QListWidgetItem('Welcome to ResLayer!!!'))
        self.list_w.setFrameStyle(QFrame.Box | QFrame.Raised)
        layout.add(QWidgetItem(self.list_w), BorderLayout.West)
        win.setLayout(layout)
        # self.list_w.addItem(self.listitem[0])
        # self.list_w.itemClicked.connect(self.OnSingleClick)
        self.list_w.itemSelectionChanged.connect(self.OnSingleClick)

        self.setWindowTitle("Border Layout")

        mypen = pg.mkPen('y', width=1)
        # self.curve = self.plot.plot(x=[], y=[], pen=mypen)
        # self.plot.addItem(self.curve)

        files = os.listdir(self.datapath)
        for f in files:
            self.listitem.append(QListWidgetItem(f[:-4]))
            self.list_w.addItem(self.listitem[-1])

        self.vdf = pd.read_csv(self.datapath + files[0], header=None)
        self.plotVES()

    def onMouseMoved(self, point):
        # print(point)
        p = self.plot.plotItem.vb.mapSceneToView(point)
        self.statusBar().showMessage("{}-{}".format(p.x(), p.y()))

    def about(self):
        QMessageBox.about(
            self, "About Image Viewer",
            "<p>The <b>Image Viewer</b> example shows how to combine "
            "(QScrollArea.widgetResizable), can be used to implement "
            "zooming and scaling features.</p>"
            "<p>In addition the example shows how to use QPainter to "
            "print an image.</p>")

    def dialog_critical(self, s):
        dlg = QMessageBox(self)
        dlg.setText(s)
        dlg.setIcon(QMessageBox.Critical)
        dlg.show()

    def file_open(self):
        # path, _ = QFileDialog.getOpenFileName(self, "Open file", "", "CSV documents (*.dat);All files (*.*)")
        path = r'D:/Ameyem Office/Projects/Electric surveys/Easwar files/Mahoba/VES_data/112.dat'
        try:
            self.vdf = pd.read_csv(path, header=None)

        except Exception as e:
            self.dialog_critical(str(e))

        else:
            self.path = path
            self.plotVES(self.vdf)

    def createActions(self):
        self.exitAct = QAction("E&xit",
                               self,
                               shortcut="Ctrl+Q",
                               triggered=self.close)
        self.openFileAct = QAction("&Open",
                                   self,
                                   shortcut="Ctrl+O",
                                   triggered=self.file_open)
        self.aboutAct = QAction("&About", self, triggered=self.about)

        self.do_inversion_action = QAction(QIcon(
            os.path.join('ves_imgs', 'invert-tool.png')),
                                           "&Invert",
                                           self,
                                           shortcut="Ctrl+I",
                                           triggered=self.doVESinv)
        self.do_inversion_action.setStatusTip("Run inversion")
        # self.do_inversion_action.triggered.connect(self.doVESinv)

        # openFileAct = QAction(QIcon(os.path.join('images', 'blue-folder-open-document.png')), "Open file...", self)
        # open_file_action.setStatusTip("Open file")
        # open_file_action.triggered.connect(self.file_open)
        # file_menu.addAction(open_file_action)
        # file_toolbar.addAction(open_file_action)
    def createMenus(self):
        self.fileMenu = QMenu("&File", self)
        # self.fileMenu.addAction(self.openAct)
        # self.fileMenu.addAction(self.printAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.openFileAct)
        self.fileMenu.addAction(self.exitAct)

        self.helpMenu = QMenu("&Help", self)
        self.helpMenu.addAction(self.aboutAct)
        # self.helpMenu.addAction(self.aboutQtAct)

        self.menuBar().addMenu(self.fileMenu)
        # self.menuBar().addMenu(self.viewMenu)
        # self.menuBar().addMenu(self.digitizeMenu)
        self.menuBar().addMenu(self.helpMenu)

        self.file_toolbar = QToolBar("File")
        self.file_toolbar.setIconSize(QSize(24, 24))
        self.addToolBar(self.file_toolbar)

        self.fileMenu.addAction(self.do_inversion_action)
        self.file_toolbar.addAction(self.do_inversion_action)

    def OnSingleClick(self):
        print('\nItems selected...', end=' ')
        # self.curve=self.plot.plot(x=[0.9 ,300], y=[1, 10000], size=1, pen=pg.mkPen(None),clear=True)
        # self.plot2.plot(x=[0.9 ,300], y=[1, 10000], size=1, pen=pg.mkPen(None),clear=True)
        for item in self.list_w.selectedItems():
            vespoint_name = item.text()
            print(vespoint_name, end=' ')
            self.vdf = pd.read_csv(self.datapath + vespoint_name + '.dat',
                                   header=None)

            # # self.plot.close()
            # # self.plot = pg.PlotWidget()
            self.plotVES()
        # self.plotLocationPanel(locations4panel)
    def plotVES(self):
        # self.curve=
        self.subplot1.cla()
        self.subplot1.loglog(self.vdf[0], self.vdf[1], '*', basex=10)
        # self.subplot1.grid(True)
        self.subplot1.grid(b=True, which='major', color='grey', linestyle='-')
        self.subplot1.grid(b=True, which='minor')
        self.subplot1.set_title('Apparent resisitivity log ')
        self.subplot1.set_xlabel('Distance (m)')
        self.subplot1.set_ylabel('Apparent Resistivity (ohm-m)')
        self.subplot1.set_xlim(1, 1000)
        self.subplot1.set_ylim(1, 10000)

        self.subplot2.cla()
        # self.subplot2.loglog(self.vdf[0],self.vdf[1],'*', basex=10)
        # self.subplot1.grid(True)
        lr = int(1 + len(self.init_m) / 2)
        lt = int(len(self.init_m) / 2)
        r = np.append(self.init_m[:lr], np.nan)
        t = np.append(np.append(0.01, self.init_m[-lt:]), 1000)

        self.subplot2.grid(b=True, which='major', color='grey', linestyle='-')
        self.subplot2.grid(b=True, which='minor')
        self.subplot2.set_title('Layer model')
        self.subplot2.set_xlabel('Resistivity (ohm-m)')
        self.subplot2.set_ylabel('Depth (m)')
        # self.subplot2.invert_yaxis()
        self.subplot2.set_xlim(1, 6000)
        self.subplot2.set_ylim(0.1, 500)

        self.subplot2.step(r,
                           np.cumsum(t),
                           'k',
                           dashes=[5, 5, 5, 5],
                           linewidth=2)

        self.subplot2.set_xscale('log')
        self.subplot2.set_yscale('log')
        self.subplot2.invert_yaxis()
        self.mw.draw()

    def VESInvplot(self, x, roa, roaf, m, mf):
        lr = int(1 + len(mf) / 2)
        lt = int(len(mf) / 2)
        rf = np.append(mf[:lr], np.nan)
        tf = np.append(np.append(0.01, mf[-lt:]), 1000)
        self.subplot1.loglog(x, roaf, '-r', basex=10)
        self.subplot2.step(rf, np.cumsum(tf), 'r')

        self.mw.draw()

    def doVESinv(self):
        method = 'ghosh'
        x = self.vdf[0].values
        roa = self.vdf[1].values
        # ri= [100, 30, 20., 4.];
        # ti =[9, 61 ,50];
        m = np.append(self.init_res, self.init_thicks)
        mf, roaf = VES1dInv(m, x, roa, method=method, maxiteration=100)
        # VESplot(self.mw,x,roa,roaf,m,mf)
        self.VESInvplot(x, roa, roaf, m, mf)
Esempio n. 14
0
class PlotWidget(QWidget):
    """
    This class inherited from pyqtgraphs Plotwidget and MatplotlibWidget and adds additional compononets like:
        1) Cross-hair to view X, Y coordinates
        2) Changing plot-styles interactively
    """
    def __init__(self,parent=None,matplotlib=False):
        QWidget.__init__(self,parent)
        self.matplotlib=matplotlib
        self.mplPlotData={}
        self.mplErrorData={}
        self.xLabelFontSize=10
        self.yLabelFontSize=10
        self.titleFontSize=12
        self.xLabel='x'
        self.yLabel='y'
        self.title='Plot'            
        self.createPlotWidget()
        self.data={}
        self.dataErrPos={}
        self.dataErrNeg={}
        self.dataErr={}
        self.err={}
        self.data_num=0
        self.yerr={}
        self.fit={}
        
       
    def createPlotWidget(self):
        """
        Creates the plotWidget
        """
        self.vbLayout=QVBoxLayout(self)
        self.plotLayout=pg.LayoutWidget()
        self.vbLayout.addWidget(self.plotLayout)
        
        row=0
        col=0
        lineWidthLabel=QLabel('Line width')
        self.lineWidthLineEdit=QLineEdit('2')
        self.lineWidthLineEdit.returnPressed.connect(self.updatePlot)
        pointSizeLabel=QLabel('Point size')
        self.pointSizeLineEdit=QLineEdit('5')
        self.pointSizeLineEdit.returnPressed.connect(self.updatePlot)
        self.bgCheckBox=QCheckBox('White BG')
        self.bgCheckBox.stateChanged.connect(self.bgCheckBoxChanged)
        self.errorbarCheckBox=QCheckBox('Errorbar')
        self.errorbarCheckBox.stateChanged.connect(self.errorbarChanged)
        self.plotLayout.addWidget(lineWidthLabel,row=row,col=col)
        col+=1
        self.plotLayout.addWidget(self.lineWidthLineEdit,row=row,col=col)
        col+=1
        self.plotLayout.addWidget(pointSizeLabel,row=row,col=col)
        col+=1
        self.plotLayout.addWidget(self.pointSizeLineEdit,row=row,col=col)
        col+=1
        self.plotLayout.addWidget(self.bgCheckBox,row=row,col=col)
        col+=1
        self.plotLayout.addWidget(self.errorbarCheckBox,row=row,col=col)
        col=0
        row+=1
        if self.matplotlib:
            self.plotWidget=MatplotlibWidget()
            self.subplot=self.plotWidget.getFigure().add_subplot(111)
            self.plotWidget.fig.set_tight_layout(True)
            self.plotWidget.draw()
        else:
            self.plotWidget=pg.PlotWidget()
            self.plotWidget.getPlotItem().vb.scene().sigMouseMoved.connect(self.mouseMoved)
            self.legendItem=pg.LegendItem(offset=(0.0,1.0))
            self.legendItem.setParentItem(self.plotWidget.getPlotItem())
            
        self.plotLayout.addWidget(self.plotWidget,row=row,col=col,colspan=6)
        row+=1
        col=0 
        self.crosshairLabel=QLabel(u'X={: .5f} , y={: .5f}'.format(0.0,0.0))                                 
        self.xLogCheckBox=QCheckBox('LogX')
        self.xLogCheckBox.setTristate(False)
        self.xLogCheckBox.stateChanged.connect(self.updatePlot)
        self.yLogCheckBox=QCheckBox('LogY')
        self.yLogCheckBox.setTristate(False)
        self.yLogCheckBox.stateChanged.connect(self.updatePlot)
        if not self.matplotlib:
            self.plotLayout.addWidget(self.crosshairLabel,row=row,col=col,colspan=4)
        self.plotLayout.addWidget(self.xLogCheckBox,row=row,col=4)
        self.plotLayout.addWidget(self.yLogCheckBox,row=row,col=5)
        
        
        
    def bgCheckBoxChanged(self):
        if self.bgCheckBox.isChecked():
            self.plotWidget.setBackground('w')
            self.plotWidget.getAxis('left').setPen('k')
            self.plotWidget.getAxis('left').setTextPen('k')
            self.plotWidget.getAxis('bottom').setPen('k')
            self.plotWidget.getAxis('bottom').setTextPen('k')
        else:
            self.plotWidget.setBackground('k')
            self.plotWidget.getAxis('left').setPen('w')
            self.plotWidget.getAxis('left').setTextPen('w')
            self.plotWidget.getAxis('bottom').setPen('w')
            self.plotWidget.getAxis('bottom').setTextPen('w')


    def mouseMoved(self,pos):
        try:
            pointer=self.plotWidget.getPlotItem().vb.mapSceneToView(pos)
            x,y=pointer.x(),pointer.y()
            if self.plotWidget.getPlotItem().ctrl.logXCheck.isChecked():
                x=10**x
            if self.plotWidget.getPlotItem().ctrl.logYCheck.isChecked():
                y=10**y
            self.crosshairLabel.setText('X={: 10.5f}, Y={: 10.5e}'.format(x,y))
            # if x>1e-3 and y>1e-3:
            #     self.crosshairLabel.setText(u'X={: .5f} , Y={: .5f}'.format(x,y))
            # if x<1e-3 and y>1e-3:
            #     self.crosshairLabel.setText(u'X={: .3e} , Y={: .5f}'.format(x,y))
            # if x>1e-3 and y<1e-3:
            #     self.crosshairLabel.setText(u'X={: .5f} , Y={: .3e}'.format(x,y))
            # if x<1e-3 and y<1e-3:
            #     self.crosshairLabel.setText(u'X={: .3e} , Y={: .3e}'.format(x,y))
        except:
            pass
                
        #self.crosshairLabel.setText(u'X=%+0.5f, Y=%+0.5e'%(x,y))
        
        
    def add_data(self,x,y,yerr=None,name=None,fit=False,color=None):
        """
        Adds data into the plot where:
        x=Array of x-values
        y=Array of y-values
        yerr=Array of yerr-values. If None yerr will be set to sqrt(y)
        name=any string to be used for the key to put the data
        fit= True if the data corresponds to a fit
        """
        if not (isinstance(yerr,list) or isinstance(yerr,np.ndarray)):
            yerr=np.ones_like(y)
        x=np.array(x)
        y=np.array(y)
        if len(x)==len(y) and len(y)==len(yerr):
            if name is None:
                dname=str(self.data_num)
            else:
                dname=name
            if np.all(yerr==1):
                self.yerr[dname]=False
            else:
                self.yerr[dname]=True
            self.fit[dname]=fit
            if dname in self.data.keys():
                if color is None:
                    color=self.data[dname].opts['symbolPen'].color()
                pen=pg.mkPen(color=color,width=float(self.lineWidthLineEdit.text()))
                symbol='o'
                if self.fit[dname]:
                    symbol=None
                self.data[dname].setData(x,y,pen=pen,symbol=symbol,symbolSize=float(self.pointSizeLineEdit.text()),symbolPen=pg.mkPen(color=color),symbolBrush=pg.mkBrush(color=color))
                #self.data[dname].setPen(pg.mkPen(color=pg.intColor(np.random.choice(range(0,210),1)[0]),width=int(self.lineWidthLineEdit.text())))
                #if self.errorbarCheckBox.isChecked():
                # self.dataErrPos[dname].setData(x,np.where(y+yerr/2.0>0,y+yerr/2.0,y))
                # self.dataErrNeg[dname].setData(x,np.where(y-yerr/2.0>0,y-yerr/2.0,y))
                self.err[dname]= yerr
                self.dataErr[dname].setData(x=x, y=y, top=self.err[dname], bottom=self.err[dname], pen='w')# beam=min(np.abs(x))*0.01*float(self.pointSizeLineEdit.text()),pen='w')
            #self.dataErr[dname].setCurves(self.dataErrPos[dname],self.dataErrNeg[dname])
            else:
                if color is None:
                    color=pg.intColor(np.random.choice(range(0,210),1)[0])
                #color=self.data[dname].opts['pen'].color()
                pen=pg.mkPen(color=color,width=float(self.lineWidthLineEdit.text()))
                symbol='o'
                if self.fit[dname]:
                    symbol=None
                self.data[dname]=pg.PlotDataItem(x,y,pen=pen,symbol=symbol,symbolSize=float(self.pointSizeLineEdit.text()),symbolPen=pg.mkPen(color=color),symbolBrush=pg.mkBrush(color=color))
                self.dataErr[dname] = pg.ErrorBarItem()
                self.err[dname]=yerr
                self.dataErr[dname].setData(x=x,y=y,top=self.err[dname],bottom=self.err[dname], pen='w')# beam=min(np.abs(x))*0.01*float(self.pointSizeLineEdit.text()),pen='w')
                self.data[dname].curve.setClickable(True,width=10)
                self.data[dname].sigClicked.connect(self.colorChanged)
                #if self.errorbarCheckBox.isChecked():
                # self.dataErrPos[dname]=pg.PlotDataItem(x,np.where(y+yerr/2.0>0,y+yerr/2.0,y))
                # self.dataErrNeg[dname]=pg.PlotDataItem(x,np.where(y-yerr/2.0>0,y-yerr/2.0,y))
                #self.dataErr[dname]=pg.FillBetweenItem(curve1=self.dataErrPos[dname],curve2=self.dataErrNeg[dname],brush=pg.mkBrush(color=pg.hsvColor(1.0,sat=0.0,alpha=0.2)))
                self.data_num+=1
                #if len(x)>1:
                self.Plot([dname])
            return True
        else:
            QMessageBox.warning(self,'Data error','The dimensions of x, y or yerr are not matching',QMessageBox.Ok)
            return False
            
    def colorChanged(self,item):
        """
        Color of the item changed
        """
        color=item.opts['symbolPen'].color()
        newcolor=QColorDialog.getColor(initial=color)
        if newcolor.isValid():
            #if self.lineWidthLineEdit.text()!='0':
            item.setPen(pg.mkPen(color=newcolor,width=int(self.lineWidthLineEdit.text())))
            if self.pointSizeLineEdit.text()!='0':
                item.setSymbolBrush(pg.mkBrush(color=newcolor))
                item.setSymbolPen(pg.mkPen(color=newcolor))
    
    def errorbarChanged(self):
        """
        Updates the plot checking the Errorbar is checked or not
        """
        try:
            self.Plot(self.selDataNames)
        except:
            pass
            
        
    def Plot(self,datanames):
        """
        Plots all the data in the memory with errorbars where:
            datanames is the list of datanames
        """
        self.selDataNames=datanames
        if self.matplotlib: #Plotting with matplotlib
            names=list(self.mplPlotData.keys())
            for name in names:
                if name not in self.selDataNames:
                    self.mplPlotData[name].remove()
                    del self.mplPlotData[name]
                    try:
                        self.mplErrorData[name].remove()
                        del self.mplErrorData[name]
                    except:
                        pass
            self.xLabel=self.subplot.get_xlabel()
            self.yLabel=self.subplot.get_ylabel()
            self.title=self.subplot.get_title()
            #self.subplot.axes.cla()
            for dname in self.selDataNames:
                if self.fit[dname]:
                    plot_type = '-'
                else:
                    plot_type = '.-'
                if self.errorbarCheckBox.checkState()==Qt.Checked:
                    try:
                        self.mplPlotData[dname].set_xdata(self.data[dname].xData)
                        self.mplPlotData[dname].set_ydata(self.data[dname].yData)
                        self.mplPlotData[dname].set_markersize(int(self.pointSizeLineEdit.text()))
                        self.mplPlotData[dname].set_linewidth(int(self.lineWidthLineEdit.text()))

                        self.mplErrorData[dname].set_segments(np.array([[x,yt],[x,yb]]) for x,yt,yb in zip(self.data[dname].xData,self.dataErrPos[dname].yData,self.dataErrNeg[dname].yData))
                        self.mplErrorData[dname].set_linewidth(2)
                    except:
                        ln,err,bar =self.subplot.errorbar(self.data[dname].xData,self.data[dname].yData,xerr=None,yerr=self.dataErr[dname].opts['top']*2,fmt=plot_type,markersize=int(self.pointSizeLineEdit.text()),linewidth=int(self.lineWidthLineEdit.text()),label=dname)
                        self.mplPlotData[dname]=ln
                        self.mplErrorData[dname],=bar
                else:
                    try:
                        self.mplPlotData[dname].set_xdata(self.data[dname].xData)
                        self.mplPlotData[dname].set_ydata(self.data[dname].yData)
                        self.mplPlotData[dname].set_markersize(int(self.pointSizeLineEdit.text()))
                        self.mplPlotData[dname].set_linewidth(int(self.lineWidthLineEdit.text()))
                    except:
                        self.mplPlotData[dname], =self.subplot.plot(self.data[dname].xData,self.data[dname].yData,plot_type,markersize=int(self.pointSizeLineEdit.text()),linewidth=int(self.lineWidthLineEdit.text()),label=dname)
            if self.xLogCheckBox.checkState()==Qt.Checked:
                self.subplot.set_xscale('log')
            else:
                self.subplot.set_xscale('linear')
            if self.yLogCheckBox.checkState()==Qt.Checked:
                self.subplot.set_yscale('log')
            else:
                self.subplot.set_yscale('linear')
            self.subplot.set_xlabel(self.xLabel,fontsize=self.xLabelFontSize)
            self.subplot.set_ylabel(self.yLabel,fontsize=self.yLabelFontSize)
            self.subplot.set_title(self.title,fontsize=self.titleFontSize)
#            try:
#                self.leg.draggable()
#            except:
            self.leg=self.subplot.legend()
            self.leg.set_draggable(True)
            self.plotWidget.fig.set_tight_layout(True)
            self.plotWidget.draw()
                
        else:
            self.plotWidget.plotItem.setLogMode(x=False,y=False)
            self.plotWidget.clear()
            for names in self.data.keys():
                self.legendItem.removeItem(names)
            xlog_res=True
            ylog_res=True
            for dname in self.selDataNames:
                if np.all(self.data[dname].yData==0) and self.yLogCheckBox.checkState()==Qt.Checked: #This step is necessary for checking the zero values
                    QMessageBox.warning(self,'Zero error','All the yData are zeros. So Cannot plot Logarithm of yData for %s'%dname,QMessageBox.Ok)
                    ylog_res=ylog_res and False
                    if not ylog_res:
                        self.yLogCheckBox.stateChanged.disconnect(self.updatePlot)
                        self.yLogCheckBox.setCheckState(Qt.Unchecked)
                        self.yLogCheckBox.stateChanged.connect(self.updatePlot)
                if np.all(self.data[dname].xData==0) and self.xLogCheckBox.checkState()==Qt.Checked:
                    QMessageBox.warning(self,'Zero error','All the xData are zeros. So Cannot plot Logarithm of xData for %s'%dname,QMessageBox.Ok)
                    xlog_res=xlog_res and False
                    if not xlog_res:
                        self.xLogCheckBox.stateChanged.disconnect(self.updatePlot)
                        self.xLogCheckBox.setCheckState(Qt.Unchecked)
                        self.xLogCheckBox.stateChanged.connect(self.updatePlot)
                self.plotWidget.addItem(self.data[dname])
                if self.errorbarCheckBox.isChecked() and self.yerr[dname]:
                    x=self.data[dname].xData
                    y=self.data[dname].yData
                    top=copy.copy(self.err[dname])
                    bottom= copy.copy(self.err[dname])
                    if self.xLogCheckBox.checkState() == Qt.Checked:
                         x=np.log10(x)
                    if self.yLogCheckBox.checkState() == Qt.Checked:
                        top=np.log10(1+top/y)
                        bottom=np.log10(y/(y-bottom))
                        y = np.log10(y)
                    self.dataErr[dname].setData(x=x,y=y,top=top,bottom=bottom,pen='w')#beam=min(np.abs(x))*0.01*float(self.pointSizeLineEdit.text()),pen='w')
                    self.plotWidget.addItem(self.dataErr[dname])
                    # self.plotWidget.addItem(self.dataErrPos[dname])
                    # self.plotWidget.addItem(self.dataErrNeg[dname])
                    #self.plotWidget.addItem(self.dataErr[dname])
                    #self.dataErr[dname].setCurves(self.dataErrPos[dname],self.dataErrNeg[dname])
                self.legendItem.addItem(self.data[dname],dname)
            if self.xLogCheckBox.checkState()==Qt.Checked:
                self.plotWidget.plotItem.setLogMode(x=True)
            else:
                self.plotWidget.plotItem.setLogMode(x=False)
            if self.yLogCheckBox.checkState()==Qt.Checked:
                self.plotWidget.plotItem.setLogMode(y=True)
            else:
                self.plotWidget.plotItem.setLogMode(y=False)

                
    def remove_data(self,datanames):
        for dname in datanames:
            if self.matplotlib:
                self.mplPlotData[dname].remove()
                del self.mplPlotData[dname]
                if self.errorbarCheckBox.isChecked() and self.yerr[dname]:
                    self.mplErrorData[dname].remove()
                    del self.mplErrorData[dname]
            else:
                self.plotWidget.removeItem(self.data[dname])
                self.legendItem.removeItem(dname)
                if self.errorbarCheckBox.isChecked() and self.yerr[dname]:
                    self.plotWidget.removeItem(self.dataErr[dname])
                    # self.plotWidget.removeItem(self.dataErrPos[dname])
                    # self.plotWidget.removeItem(self.dataErrNeg[dname])
            del self.data[dname]
            del self.dataErr[dname]
            # del self.dataErrPos[dname]
            # del self.dataErrNeg[dname]
            
            
    def updatePlot(self):
        try:
            for dname in self.selDataNames:
                if self.lineWidthLineEdit.text()=='0' and not self.fit[dname]:
                    self.data[dname].opts['pen']=None
                    self.data[dname].updateItems()
                else:
                    #try:
                    self.data[dname].setPen(self.data[dname].opts['symbolPen']) #setting the same color as the symbol
                    color=self.data[dname].opts['pen'].color()
                    self.data[dname].setPen(pg.mkPen(color=color,width=float(self.lineWidthLineEdit.text())))
                    #except:
                    #    self.data[dname].setPen(pg.mkPen(color='b',width=float(self.lineWidthLineEdit.text())))
                self.data[dname].opts['symbol']='o'
                if self.fit[dname]:
                    self.data[dname].setSymbolSize(0)
                else:
                    self.data[dname].setSymbolSize(float(self.pointSizeLineEdit.text()))
            self.Plot(self.selDataNames)
        except:
            QMessageBox.warning(self,'Data Error','No data to plot',QMessageBox.Ok)
            
    def setXLabel(self,label,fontsize=4):
        """
        sets the X-label of the plot
        """
        self.xLabel=label
        self.xLabelFontSize=fontsize
        if self.matplotlib:
            self.subplot.set_xlabel(label,fontsize=fontsize)
            self.plotWidget.draw()
        else:
            self.plotWidget.getPlotItem().setLabel('bottom','<font size='+str(fontsize)+'>'+label+'</font>')
            
    def setYLabel(self,label,fontsize=4):
        """
        sets the y-label of the plot
        """
        self.yLabel=label
        self.yLabelFontSize=fontsize
        if self.matplotlib:
            self.subplot.set_ylabel(label,fontsize=fontsize)
            self.plotWidget.draw()
        else:
            self.plotWidget.getPlotItem().setLabel('left','<font size='+str(fontsize)+'>'+label+'</font>')        
            
            
    def setTitle(self,title,fontsize=6):
        """
        Sets the y-label of the plot
        """
        self.title=title
        self.titleFontSize=fontsize
        if self.matplotlib:
            self.subplot.set_title(title,fontsize=fontsize)
            self.plotWidget.draw()
        else:
            self.plotWidget.getPlotItem().setTitle(title='<font size='+str(fontsize)+'>'+title+'</font>')

    def addROI(self,values=(0,1),orientation='horizontal',movable=True, minmax_widget=None, min_widget=None, max_widget=None):
        if orientation=='vertical':
            self.roi=pg.LinearRegionItem(values=values,orientation=pg.LinearRegionItem.Vertical,movable=movable)
        else:
            self.roi = pg.LinearRegionItem(values=values, orientation=pg.LinearRegionItem.Horizontal,movable=movable)
        self.plotWidget.addItem(self.roi)
        return self.roi
Esempio n. 15
0
class AitoffDock(Dock):
    """
    Aitoff plot for displaying locations.
    """
    def __init__(self, *args, **kwargs):
        log.info('')
        super().__init__(*args, **kwargs)

        self.points = None
        self._axis_aitoff_text_labels = []

        self.mw = MatplotlibWidget()
        self.mw.toolbar.hide()
        self.subplot = self.mw.getFigure().add_subplot(111,
                                                       projection="aitoff")
        self.subplot.grid('on')

        #
        #  Add some dummy points
        #
        self.mw.draw()
        self.subplot_background = self.subplot.get_figure(
        ).canvas.copy_from_bbox(self.subplot.bbox)

        self.addWidget(self.mw)

    def clear_points(self):
        #
        #  Delete the points
        #
        log.info('')

        if self.points is not None:
            self.points.remove()
            self.points = None
            self.mw.draw()

        #
        #  Delete the text labels
        #

        for t in self._axis_aitoff_text_labels:
            t.remove()
        self._axis_aitoff_text_labels = []

    def add_points(self, points, color='b'):
        log.info('')

        self.clear_points()

        converted_points = [self.convert_ra_dec(*radec) for radec in points]

        #
        # Display the points on the Aitoff projection
        #

        xs = np.array([x[0] for x in converted_points])
        ys = np.array([x[1] for x in converted_points])
        self.points = self.subplot.scatter(xs, ys, c='b')

        #
        # Now label the numbers on the plot to correspond to the
        # similar images.
        #

        converted_points = np.array(converted_points)
        d = distance_matrix(converted_points, converted_points)

        rows = set(range(converted_points.shape[0]))
        groups = {}

        while len(rows) > 0:
            row = rows.pop()
            close = np.nonzero(d[row] < 0.01)[0]
            rows = rows - set(list(close))
            groups[row] = close

        for k, v in groups.items():
            tt = self.subplot.text(converted_points[k][0] + 0.05,
                                   converted_points[k][1] + 0.05,
                                   ','.join([str(x + 1) for x in v]))
            self._axis_aitoff_text_labels.append(tt)
            self.subplot.draw_artist(tt)

        self.mw.draw()

    def convert_ra_dec(self, ra, dec):
        log.info('')

        if ra is not None and dec is not None:
            coords = SkyCoord(ra=ra, dec=dec, unit='degree')
            ra = coords.ra.wrap_at(180 * u.deg).radian
            dec = coords.dec.radian
        else:
            ra, dec = None, None
        return ra, dec
Esempio n. 16
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.setGeometry(100, 100, 600, 900)

        self.centralWidget = QWidget()
        # GrphicsWidget()
        layout = QHBoxLayout(self.centralWidget)
        self.scrollArea = QScrollArea(self)

        # gwidget=GrphicsWidget()

        self.mw = MatplotlibWidget(size=(3.0, 40.0), dpi=100)
        lplot = self.mw.getFigure().add_subplot(121)
        # print(dir(self.mw.getFigure()))

        # self.mw.getFigure().set_axes([0.85, 0.1, 0.075, 0.8])
        self.ax = self.mw.getFigure().gca()
        self.ax.set_position([0.1, 0.05, 0.8, 0.94])
        self.ax.invert_yaxis()
        # l, b, w, h = self.ax.get_position().bounds
        # print(l, b, w, h)
        self.mw.draw()
        # self.plotlayout.addWidget(self.mw)

        self.scrollArea.setWidget(self.mw)

        layout.addWidget(self.scrollArea)

        self.setCentralWidget(self.centralWidget)
        self.wellLoad()
        self.logtree = LasTree(['GR', 'NPHI'])
        self.logtree.buildTreeWidget()
        self.logtree.tree.itemSelectionChanged.connect(self.logPlot)

        self.createDockWindows()

        # self.logFileList.itemSelectionChanged.connect(self.lasLoad)
        # if not self.las_just_selected:
        # self.logList.itemSelectionChanged.connect(self.logPlot)

        self.setWindowTitle("Loggy")

        # self.newLetter()
    def wellLoad(self):
        self.wellFolder = r'E:\Data\W1\LAS\\'

        self.files = np.array(os.listdir(self.wellFolder)[:])
        files_w_path = [self.wellFolder + f for f in self.files]
        # print(files_w_path)
        # self.logFileList.addItems(self.files)

        # folder=r'D:\Ameyem Office\Projects\Cairn\W1\LAS\\'
        cols = []
        # las=[]
        # log.df().sort_values([log.keys()[dindx]])
        # log.keys()
        self.files = np.array(os.listdir(self.wellFolder)[:])
        self.lastree = LasTree(self.files)
        self.lastree.buildTreeWidget()
        self.lastree.tree.itemSelectionChanged.connect(self.lasLoad)

        self.lasLoadThread = LasLoadThread(files=files_w_path)

    # def lasBackgroundLoad():

    def lasLoad(self):
        las_name = self.lastree.tree.selectedItems()[0].text(
            0)  #self.logFileList.selectedItems()[0].text()
        if las_name in ['TVD', 'MD', 'LWD', 'WireLine']:
            return

        findex = np.where(self.files == las_name)[0][0]
        # print(findex)
        Loaded = False
        while (not Loaded):
            if (findex < len(self.lasLoadThread.Lases)):
                self.las = self.lasLoadThread.Lases[findex]
                Loaded = True
            else:
                self.logtree.clear()
                # self.logtree.addItems(['Loading....'])
                time.sleep(1)

        if len(self.logtree.selectedItems()) > 0:
            item = self.logtree.selectedItems()[0]
            # print(dir(item))
            item.setSelected = False
        # self.logList.clear()
        # self.logList.addItems(self.las.keys() )
        if not (len(self.las.keys()) < 1):
            self.logtree = LasTree(self.las.keys())
            self.logtree.buildTreeWidget()
            # self.logtree.tree.itemSelectionChanged.connect(self.logPlot)

            dcol = self.las.keys()[find_depth_indx(self.las)]
            self.depth_col = str_array2floats(self.las[dcol])
        # else:

        # self.las_just_selected = True

    def logPlot(self):

        # print(self.mw.getFigure().)
        # pass
        # if not self.las_just_selected:
        if len(self.logtree.selectedItems()) > 0:
            keycol = self.logtree.selectedItems()[0].text(0)
            try:
                self.log_col = str_array2floats(self.las[keycol])
                self.ax = LogPlot.basicPlot(self.ax,
                                            self.depth_col,
                                            self.log_col,
                                            lcolor='#800000')
            except:
                print('Unable to convert log to floats')
        # else:
        #     self.las_just_selected=False

        # fig.subplots_adjust(top=0.75,wspace=0.1)

        # ax.invert_yaxis()
        # ax.plot([1,2,3],[2,1,4],'*')
        self.mw.draw()
        # self.subplot1 = self.mw.getFigure().add_subplot(121)

    def createDockWindows(self):

        dock = QDockWidget("Log Files", self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)

        # self.logFileList = self.lastree.tree #QListWidget(dock)
        # self.customerList.addItems(('Hello','How are you'))
        dock.setWidget(self.lastree.tree)
        #
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        # self.viewMenu.addAction(dock.toggleViewAction())

        dock = QDockWidget("Logs", self)

        # self.logList = QListWidget(dock)
        # self.logList.addItems(('Good morning','Hope you are doing well'))

        dock.setWidget(self.logtree.tree)

        # self.logList = QListWidget(dock)
        # self.logList.addItems(('Good morning','Hope you are doing well'))
        # dock.setWidget(self.logList)

        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
class mainApp(qt.QMainWindow):
    def __init__(self, parent=None):
        super(mainApp, self).__init__(parent)
        self.setMinimumWidth(1040 / 2)
        self.setMinimumHeight(1392 / 2)
        self.layout = qt.QGridLayout()
        self.widget = qt.QWidget()
        self.widget.setLayout(self.layout)
        self.setCentralWidget(self.widget)
        args = parser.parse_args()
        self.currentDirectory = os.path.abspath(args.directory)
        self.selectedDir = None

        self.table = qt.QListWidget()
        self.table.setMinimumWidth(200)
        self.table.setMaximumWidth(250)
        self.textedit = qt.QTextEdit()
        self.textedit.setMaximumHeight(150)
        self.textedit.setMinimumWidth(200)
        self.textedit.setMaximumWidth(250)
        self.update_directory_list()
        self.mw = MatplotlibWidget()
        self.mw.setMinimumWidth(1400)
        self.layout.addWidget(self.table, 0, 0, 1, 1)
        self.layout.addWidget(self.textedit, 1, 0, 1, 1)
        self.layout.addWidget(self.mw, 0, 1, 2, 3)

        # self.timer = qt.QTimer()
        # self.timer.timeout.connect(self.update_directory_list)
        # self.timer.start(10000)
        self.table.itemClicked.connect(self.analyse_image)
        self.table.itemDoubleClicked.connect(self.change_directory)

        # sys.stdout = OutLog( self.textedit, sys.stdout)
        # sys.stderr = OutLog( self.textedit, sys.stderr, qt.QColor(255,0,0) )

    def analyse_image(self, item):
        dir = self.currentDirectory + '/' + str(item.text())
        self.selectedDir = str(item.text())
        if not dir == '.' and not dir == '..':
            self.mw.getFigure().clear()
            # ''' initialise an instance of the stripPlot Widget '''
            analyse_image(self.mw, dir)
            self.mw.draw()

    def update_directory_list(self):
        index = None
        self.table.clear()
        start = time.time()
        # print (os.listdir(self.currentDirectory))
        dirs = [
            os.path.abspath(self.currentDirectory + '/' + a)
            for a in os.listdir(self.currentDirectory)
            if os.path.isdir(self.currentDirectory + '/' + a)
        ]
        print('read dirs in ', time.time() - start)
        if os.path.isfile(self.currentDirectory +
                          '/best_solutions_running.csv'):
            solutions = []
            with open(self.currentDirectory + '/best_solutions_running.csv',
                      'rt') as csvfile:
                spamreader = csv.reader(csvfile, csv.QUOTE_NONE, delimiter=',')
                for row in spamreader:
                    solutions.append([float(a) for a in row])
            # solutions = np.array(sorted([s for s in solutions if s[-3] < 12 and s[-4] < 2], key=lambda a: a[-1]))
            solutions = np.array(sorted(solutions, key=lambda a: a[-1]))
            # print (solutions)
            iterdirs = [
                self.currentDirectory + '/iteration_' + str(int(a[-2]))
                for a in solutions
                if os.path.isdir(self.currentDirectory + '/iteration_' +
                                 str(int(a[-2])))
            ]
            basedirs = [a for a in dirs if 'basefiles_' in a]
            vbcdirs = [a for a in dirs if 'vbc_' in a]
            setdirs = [a for a in dirs if 'set' in a]
            dirs = iterdirs  # + setdirs + vbcdirs + basedirs
            # print 'sorted dirs in ', time.time() - start
        else:
            dirs.sort(key=os.path.getmtime, reverse=True)
        self.table.addItem('.')
        self.table.addItem('..')
        for i, d in enumerate(dirs[:100]):
            d = d.replace(self.currentDirectory + '/',
                          '').replace(self.currentDirectory + '\\', '')
            item = self.table.addItem(d)
            if d == self.selectedDir:
                # print 'found dir = ', d, self.selectedDir
                index = i + 2
        if self.selectedDir is not None and index is not None:
            # try:
            self.table.itemClicked.disconnect(self.analyse_image)
            self.table.setCurrentRow(index)
            self.table.itemClicked.connect(self.analyse_image)
        # except:
        #     self.table.setCurrentRow(index)

    def change_directory(self, item):
        dir = str(item.text())
        print('changing directory! = ',
              os.path.abspath(self.currentDirectory + '/' + dir + '/'))
        self.currentDirectory = os.path.abspath(self.currentDirectory + '/' +
                                                dir + '/')
        self.update_directory_list()
Esempio n. 18
0
class MainWindow(QtGui.QMainWindow):

    def __init__(self, parent=None):
    
        QtGui.QMainWindow.__init__(self, parent) 
        self.loadIcons()   
        self.setupUserInterface() 
        self.setupSignals()    
        self.__version__ = __version__
        
        # Initialise variables
        self.imageFiles = {}
        self.timeData   = None
        self.plotWin    = None
        self.imageWin   = None
        self.BMDchange  = None
        self.roiNames   = None  
        
    def loadIcons(self):
        """ Load icons """
        self.icons = dict([
            ('BMDanalyseIcon', QtGui.QIcon(os.path.join(absDirPath,"icons","logo.png"))),
            ('imageAddIcon',   QtGui.QIcon(os.path.join(absDirPath,"icons","file_add.png"))),
            ('imageRemIcon',   QtGui.QIcon(os.path.join(absDirPath,"icons","file_delete2.png"))),
            ('imageDownIcon',  QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-up-2.png"))),
            ('imageUpIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-down-2.png"))),
            ('imagePrevIcon',  QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-left.png"))),
            ('imageNextIcon',  QtGui.QIcon(os.path.join(absDirPath,"icons","arrow-right.png"))),          
            ('roiAddIcon',     QtGui.QIcon(os.path.join(absDirPath,"icons","green-add3.png"))),
            ('roiRectIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","rectangularIcon.png"))),
            ('roiPolyIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","polygonIcon.png"))),
            ('roiRemIcon',     QtGui.QIcon(os.path.join(absDirPath,"icons","red_delete.png"))),
            ('roiSaveIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","filesave.png"))),
            ('roiCopyIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","file_copy.png"))),
            ('roiLoadIcon',    QtGui.QIcon(os.path.join(absDirPath,"icons","opened-folder.png")))])
        
    def setupUserInterface(self):
        """ Initialise the User Interface """

        # Left frame
        leftFrame = QtGui.QFrame()
        leftFrameLayout = QtGui.QHBoxLayout() 
        leftFrame.setLayout(leftFrameLayout)
        leftFrame.setLineWidth(0)
        leftFrame.setFrameStyle(QtGui.QFrame.Panel)
        leftFrameLayout.setContentsMargins(0,0,5,0)

        # Left frame contents     
        self.viewMain = GraphicsLayoutWidget()  # A GraphicsLayout within a GraphicsView 
        leftFrameLayout.addWidget(self.viewMain)
        self.viewMain.setMinimumSize(200,200)
        self.vb = MultiRoiViewBox(lockAspect=True,enableMenu=True)
        self.viewMain.addItem(self.vb)
        self.vb.disableAutoRange()
    
        # Right frame
        self.sidePanel = SidePanel(self) 
     
        # UI window (containing left and right frames)
        UIwindow         = QtGui.QWidget(self)
        UIwindowLayout   = QtGui.QHBoxLayout()
        UIwindowSplitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
        UIwindowLayout.addWidget(UIwindowSplitter)
        UIwindow.setLayout(UIwindowLayout)
        self.setCentralWidget(UIwindow)
        UIwindowSplitter.addWidget(leftFrame)
        UIwindowSplitter.addWidget(self.sidePanel)  
 
        # Application window
        self.setWindowTitle('BMDanalyse')
        self.setWindowIcon(self.icons['BMDanalyseIcon'])
        self.setMinimumSize(600,500)
        self.resize(self.minimumSize())
       
        # Window menus       
        self.createMenus()     
        self.createActions() 

    def createMenus(self):
        
        # Menus 
        menubar          = self.menuBar()
        self.fileMenu    = menubar.addMenu('&File')
        self.roiMenu     = menubar.addMenu('&ROIs')
        self.submenu     = self.roiMenu.addMenu(self.icons['roiAddIcon'],"Add ROI")
        self.analyseMenu = menubar.addMenu('&Analyse')
        self.aboutMenu   = menubar.addMenu('A&bout')
        
    def createActions(self):    
   
        # Actions for File menu
        self.loadImageAct   = QtGui.QAction(self.icons['imageAddIcon'], "&Load image(s)",        self, shortcut="Ctrl+L")
        self.removeImageAct = QtGui.QAction(self.icons['imageRemIcon'], "&Remove current image", self, shortcut="Ctrl+X") 
        self.exitAct        = QtGui.QAction("&Quit", self, shortcut="Ctrl+Q",statusTip="Exit the application")
        fileMenuActions  = [self.loadImageAct,self.removeImageAct,self.exitAct]
        fileMenuActFuncs = [self.loadImages,self.removeImage,self.close]
        for i in xrange(len(fileMenuActions)):
            action   = fileMenuActions[i]
            function = fileMenuActFuncs[i]
            action.triggered[()].connect(function)
        self.fileMenu.addAction(self.loadImageAct)
        self.fileMenu.addAction(self.removeImageAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)        
       
        # Actions for ROI menu
        # Submenu to add ROIs
     
        #self.addROIRectAct = QActionCustom("Rectangular",self.submenu)
        #self.addROIPolyAct = QActionCustom("Polygon",self.submenu)
        self.addROIRectAct = QtGui.QAction("Rectangular",self.submenu)
        self.addROIPolyAct = QtGui.QAction("Polygon",self.submenu)
        
        #self.addROIRectAct.clickEvent.connect(self.vb.addROI)
        #self.addROIPolyAct.clickEvent.connect(self.vb.addPolyRoiRequest) 
        self.addROIRectAct.triggered[()].connect(self.vb.addROI)
        self.addROIPolyAct.triggered[()].connect(self.vb.addPolyRoiRequest) 
        
        self.submenu.addAction(self.addROIRectAct)
        self.submenu.addAction(self.addROIPolyAct)    

        self.addROIRectAct.setIcon(self.icons['roiRectIcon'])
        self.addROIPolyAct.setIcon(self.icons['roiPolyIcon'])
      
        self.addROIRectAct.setShortcut("Ctrl+Shift+R")
        self.addROIPolyAct.setShortcut("Ctrl+Shift+P")  
      
        self.loadRoiAct = QtGui.QAction(self.icons['roiLoadIcon'], "L&oad ROI",   self, shortcut="Ctrl+O")                          
        self.copyRoiAct = QtGui.QAction(self.icons['roiCopyIcon'], "&Copy ROI",   self, shortcut="Ctrl+C")     
        self.saveRoiAct = QtGui.QAction(self.icons['roiSaveIcon'], "&Save ROI",   self, shortcut="Ctrl+S") 
        self.remRoiAct  = QtGui.QAction(self.icons['roiRemIcon'] , "&Remove ROI", self, shortcut="Ctrl+D")
        roiMenuActions  = [self.loadRoiAct,self.copyRoiAct,self.saveRoiAct,self.remRoiAct]
        roiMenuActFuncs = [self.vb.loadROI,self.vb.copyROI,self.vb.saveROI,self.vb.removeROI]        
        for i in xrange(len(roiMenuActions)):
            action   = roiMenuActions[i]
            function = roiMenuActFuncs[i]
            action.triggered[()].connect(function)
            self.roiMenu.addAction(action)
             
        # Actions for Analyse menu
        self.roiAnalysisAct = QtGui.QAction("&ROI analysis", self.viewMain, shortcut="Ctrl+R",triggered=self.getBMD)
        self.imgAnalysisAct = QtGui.QAction("&Image analysis", self.viewMain, shortcut="Ctrl+I",triggered=self.imageAnalysis)
        self.analyseMenu.addAction(self.roiAnalysisAct) 
        self.analyseMenu.addAction(self.imgAnalysisAct)
       
        # Actions for 
        self.aboutAct = QtGui.QAction("&About", self.viewMain, shortcut='F1', triggered=self.onAbout)
        self.aboutMenu.addAction(self.aboutAct)
        
        
    def setupSignals(self):
        """ Setup signals """
        self.sidePanel.imageFileList.itemSelectionChanged.connect(self.getImageToDisplay)
        self.sidePanel.buttImageAdd.clicked.connect(self.loadImages)
        self.sidePanel.buttImageRem.clicked.connect(self.removeImage)
        self.sidePanel.buttImageUp.clicked.connect(self.sidePanel.moveImageUp)
        self.sidePanel.buttImageDown.clicked.connect(self.sidePanel.moveImageDown) 
        
        self.sidePanel.roiMenu.button1.clicked[()].connect(self.vb.addROI)
        self.sidePanel.roiMenu.button2.clicked[()].connect(self.vb.addPolyRoiRequest)           

        self.sidePanel.buttRoiCopy.clicked[()].connect(self.vb.copyROI)
        self.sidePanel.buttRoiRem.clicked.connect(self.vb.removeROI)        
        self.sidePanel.buttRoiLoad.clicked.connect(self.vb.loadROI)
        self.sidePanel.buttRoiSave.clicked.connect(self.vb.saveROI)
        #self.vb.sigROIchanged.connect(self.updateROItools)
        
    def onAbout(self):
        """ About BMDanalyse message"""
        author  ='Michael Hogg'
        date    ='2012 - 2013'        
        version = self.__version__
            
        QtGui.QMessageBox.about(self, 'About BMDanalyse', 
            """
            <b>BMDanalyse</b>
            <p>A simple program for the analysis of a time series of Bone Mineral Density (BMD) images.</p>
            <p>Used to evaluate the bone gain / loss in a number of regions of interest (ROIs) over time, 
            typically due to bone remodelling as a result of stress shielding around an orthopaedic implant.</p>
            <p><table border="0" width="150">
            <tr>
            <td>Author:</td>
            <td>%s</td>
            </tr>
            <tr>
            <td>Version:</td>
            <td>%s</td>
            </tr>
            <tr>
            <td>Date:</td>
            <td>%s</td>
            </tr>            
            </table></p>
            """ % (author,version,date))

    def updateROItools(self,roi=None):
        """ Update ROI info box in side panel """ 
        if roi==None:
            self.sidePanel.updateRoiInfoBox()
        else:           
            roiState    = roi.getState()
            posx,posy   = roiState['pos']
            sizex,sizey = roiState['size']
            angle       = roiState['angle']
            name  = roi.name
            pos   = '(%.3f, %.3f)' % (posx,posy)
            size  = '(%.3f, %.3f)' % (sizex,sizey)
            angle = '%.3f' % angle
            self.sidePanel.updateRoiInfoBox(name,pos,size,angle)  
    
    def loadImages(self):
        """ Load an image to be analysed """
        newImages = {}
        fileNames = QtGui.QFileDialog.getOpenFileNames(self, self.tr("Load images"),QtCore.QDir.currentPath())
        
        # Fix for PySide. PySide doesn't support QStringList types. PyQt4 getOpenFileNames returns a QStringList, whereas PySide
        # returns a type (the first entry being the list of filenames).
        if isinstance(fileNames,types.TupleType): fileNames = fileNames[0]
        if hasattr(QtCore,'QStringList') and isinstance(fileNames, QtCore.QStringList): fileNames = [str(i) for i in fileNames]
        
        if len(fileNames)>0:
            for fileName in fileNames:
                if fileName!='':
                    imgarr = np.array(Image.open(str(fileName)))
                    imgarr = imgarr.swapaxes(0,1)
                    if   imgarr.ndim==2: imgarr = imgarr[:,::-1]
                    elif imgarr.ndim==3: imgarr = imgarr[:,::-1,:]                   
                    newImages[fileName] = imgarr
            
            # Add filenames to list widget. Only add new filenames. If filename exists aready, then
            # it will not be added, but data will be updated
            for fileName in sorted(newImages.keys()):
                if not self.imageFiles.has_key(fileName):
                    self.sidePanel.addImageToList(fileName)
                self.imageFiles[fileName] = newImages[fileName]
            
            # Show image in Main window
            self.vb.enableAutoRange()
            if self.sidePanel.imageFileList.currentRow()==-1: self.sidePanel.imageFileList.setCurrentRow(0)
            self.showImage(str(self.sidePanel.imageFileList.currentItem().text()))
            self.vb.disableAutoRange()            
            
    def removeImage(self):
        """ Remove image from sidePanel imageFileList """
        
        # Return if there is no image to remove
        if self.vb.img==None: return
        
        # Get current image in sidePanel imageFileList and remove from list
        currentRow = self.sidePanel.imageFileList.currentRow()
        image      = self.sidePanel.imageFileList.takeItem(currentRow)
        imageName  = str(image.text())
        
        # Delete key and value from dictionary 
        if imageName!='': del self.imageFiles[imageName]
        #self.imageFiles.pop(imageName,None)
        
        # Get image item in imageFileList to replace deleted image
        if self.sidePanel.imageFileList.count()==0:
            self.vb.enableAutoRange()
            self.vb.removeItem(self.vb.img)
            self.vb.showImage(None)
            #self.vb.img = None
            self.vb.disableAutoRange()
        else: 
            currentRow = self.sidePanel.imageFileList.currentRow()
            imageName  = str(self.sidePanel.imageFileList.item(currentRow).text())
            self.showImage(imageName)   

    def showImage(self,imageFilename):
        """ Shows image in main view """
        self.arr = self.imageFiles[imageFilename]
        self.vb.showImage(self.arr)
    
    def getImageToDisplay(self):
        """ Get current item in file list and display in main view"""
        try:    imageFilename = str(self.sidePanel.imageFileList.currentItem().text())
        except: pass
        else:   self.showImage(imageFilename)  

    def getBMD(self):
        """ Get change in BMD over time (e.g. for each image) for all ROIs. 
            
            Revised function that converts the list of images into a 3D array
            and then uses the relative position of the ROIs to the current
            image, self.vb.img, to get the average BMD value e.g. it doesn't use
            setImage to change the image in the view. This requires that all
            images are the same size and in the same position.
        """
        
        # Return if there is no image or rois in view
        if self.vb.img==None or len(self.vb.rois)==0: return               
        
        # Collect all images into a 3D array
        imageFilenames = self.sidePanel.getListOfImages()
        images    = [self.imageFiles[str(name.text())] for name in imageFilenames]
        imageData = np.dstack(images)
        numImages = len(images)           
        
        # Get BMD across image stack for each ROI
        numROIs = len(self.vb.rois)
        BMD     = np.zeros((numImages,numROIs),dtype=float) 
        self.roiNames = []   
        for i in xrange(numROIs):
            roi = self.vb.rois[i]
            self.roiNames.append(roi.name)
            arrRegion   = roi.getArrayRegion(imageData,self.vb.img, axes=(0,1))
            avgROIvalue = arrRegion.mean(axis=0).mean(axis=0)
            BMD[:,i]    = avgROIvalue
        
        # Calculate the BMD change (percentage of original)
        tol = 1.0e-06
        for i in xrange(numROIs):
            if abs(BMD[0,i])<tol: 
                BMD[:,i] = 100.
            else: 
                BMD[:,i] = BMD[:,i] / BMD[0,i] * 100.
        self.BMDchange = BMD-100.
        if self.timeData==None or self.timeData.size!=numImages:
            self.timeData = np.arange(numImages,dtype=float)
        
        # Plot results  
        self.showResults()
        
    def imageAnalysis(self):
        # Generate images of BMD change
        if self.vb.img==None: return
        self.showImageWin()
        
    def sliderValueChanged(self,value):
        self.imageWin.sliderLabel.setText('BMD change: >= %d %s' % (value,'%'))
        self.setLookupTable(value)
        self.imageWin.vb.img2.setLookupTable(self.lut)
        
    def setLookupTable(self,val):
        lut = []
        for i in range(256):
            if   i > 127+val:
                lut.append(matplotlib.cm.jet(255))
            elif i < 127-val:    
                lut.append(matplotlib.cm.jet(0))
            else:
                lut.append((0.0,0.0,0.0,0.0)) 
        lut = np.array(lut)*255
        self.lut = np.array(lut,dtype=np.ubyte)
     
    def createImageWin(self):
    
        self.buttMinimumSize = QtCore.QSize(70,36)
        self.iconSize = QtCore.QSize(24,24)
        
        if self.imageWin==None:
            
            self.imageWin = QtGui.QDialog(self, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |  \
                                          QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
            self.imageWin.setWindowTitle('BMDanalyse')
            self.imageWin.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.imageWin.setMinimumSize(250,500)
            self.imageWin.resize(self.imageWin.minimumSize()) 
            
            # Create viewBox  
            self.imageWin.glw = GraphicsLayoutWidget()  # A GraphicsLayout within a GraphicsView 
            self.imageWin.vb  = ImageAnalysisViewBox(lockAspect=True,enableMenu=True)
            self.imageWin.vb.disableAutoRange()
            self.imageWin.glw.addItem(self.imageWin.vb) 
            arr = self.imageFiles.values()[0]
            self.imageWin.vb.img1 = pg.ImageItem(arr,autoRange=False,autoLevels=False)
            self.imageWin.vb.addItem(self.imageWin.vb.img1)      
            self.imageWin.vb.img2 = pg.ImageItem(None,autoRange=False,autoLevels=False)
            self.imageWin.vb.addItem(self.imageWin.vb.img2)
            self.imageWin.vb.autoRange()
            lut = [ [ int(255*val) for val in matplotlib.cm.gray(i)[:3] ] for i in xrange(256) ]
            lut = np.array(lut,dtype=np.ubyte)         
            self.imageWin.vb.img1.setLookupTable(lut)
            
            # Label to show index of current image label
            self.imageCurrCont = QtGui.QFrame()
            self.imageCurrCont.setLineWidth(2)
            self.imageCurrCont.setFrameStyle(QtGui.QFrame.Panel | QtGui.QFrame.Raised)
            self.imageCurrCont.setMinimumWidth(70)
            self.imageWin.currLabel = QtGui.QLabel("")
            self.imageWin.currLabel.setAlignment(QtCore.Qt.AlignHCenter)            
            imageCurrContLayout = QtGui.QHBoxLayout()
            imageCurrContLayout.addWidget(self.imageWin.currLabel)
            self.imageCurrCont.setLayout(imageCurrContLayout)  
            
            # Create buttons to select images
            self.imageWin.buttCont = QtGui.QWidget()
            self.imageWin.buttPrev = QtGui.QPushButton(self.icons['imagePrevIcon'],"")
            self.imageWin.buttNext = QtGui.QPushButton(self.icons['imageNextIcon'],"")
            self.buttLayout = QtGui.QHBoxLayout()
            self.buttLayout.addStretch(1)
            self.buttLayout.addWidget(self.imageWin.buttPrev)
            self.buttLayout.addWidget(self.imageCurrCont)
            self.buttLayout.addWidget(self.imageWin.buttNext)
            self.buttLayout.addStretch(1)
            self.imageWin.buttCont.setLayout(self.buttLayout)
            self.imageWin.buttPrev.setMinimumSize(self.buttMinimumSize)
            self.imageWin.buttNext.setMinimumSize(self.buttMinimumSize)
            self.imageWin.buttPrev.setIconSize(self.iconSize) 
            self.imageWin.buttNext.setIconSize(self.iconSize)
            self.buttLayout.setContentsMargins(0,5,0,5)
            
            self.imageWin.buttPrev.clicked.connect(self.prevImage)
            self.imageWin.buttNext.clicked.connect(self.nextImage)
            
            # Create slider    
            self.imageWin.sliderCon = QtGui.QWidget()
            self.imageWin.slider = QtGui.QSlider(self)
            self.imageWin.slider.setOrientation(QtCore.Qt.Horizontal)
            self.imageWin.slider.setMinimum(1)
            self.imageWin.slider.setMaximum(100)
            self.imageWin.slider.setMinimumWidth(100)
            self.imageWin.slider.valueChanged.connect(self.sliderValueChanged)
            self.imageWin.sliderLabel = QtGui.QLabel('1')
            self.imageWin.sliderLabel.setMinimumWidth(120)
            self.sliderLayout = QtGui.QHBoxLayout()
            self.sliderLayout.addStretch(1)
            self.sliderLayout.addWidget(self.imageWin.sliderLabel)
            self.sliderLayout.addWidget(self.imageWin.slider)
            self.sliderLayout.addStretch(1)
            self.imageWin.sliderCon.setLayout(self.sliderLayout)
            self.sliderLayout.setContentsMargins(0,0,0,5)
            
            # Format image window
            self.imageWinLayout = QtGui.QVBoxLayout()
            self.imageWinLayout.addWidget(self.imageWin.glw)
            self.imageWinLayout.addWidget(self.imageWin.buttCont)
            self.imageWinLayout.addWidget(self.imageWin.sliderCon)
            self.imageWin.setLayout(self.imageWinLayout)
            
            self.imageWin.imagesRGB = None
            
        # Show
        self.imageWin.show()
        self.imageWin.slider.setValue(10)
        self.sliderValueChanged(10)
        self.imageWinIndex = 0
        
    def prevImage(self):
        #numImages = len(self.imageFiles)
        minIndex  = 0
        currIndex = self.imageWinIndex 
        prevIndex = currIndex - 1 
        self.imageWinIndex = max(prevIndex,minIndex)    
        self.updateImageWin()
        
    def nextImage(self):
        numImages = len(self.imageFiles)
        maxIndex  = numImages - 1
        currIndex = self.imageWinIndex
        nextIndex = currIndex + 1 
        self.imageWinIndex = min(nextIndex,maxIndex)
        self.updateImageWin()
        
    def updateImageWin(self):
        imageFilenames = self.sidePanel.getListOfImages()
        imageName      = imageFilenames[self.imageWinIndex]
        self.imageWin.vb.img1.setImage(self.imageFiles[str(imageName.text())],autoLevels=False) 
        self.imageWin.vb.img2.setImage(self.imageWin.imagesRGB[self.imageWinIndex],autoLevels=False) 
        self.imageWin.currLabel.setText("%i / %i" % (self.imageWinIndex+1,len(imageFilenames)))
        
    def showImageWin(self):
        self.createImageWin()
        #if self.imageWin.imagesRGB == None: self.imagesBMDpercentChange()
        self.imagesBMDpercentChange()
        self.updateImageWin()

    def imagesBMDpercentChange(self):
        
        # Get image arrays and convert to an array of floats
        imageFilenames = self.sidePanel.getListOfImages()
        images         = [ self.imageFiles[str(name.text())] for name in imageFilenames ]
        imagesConv = []
        for img in images: 
            image = img.copy()
            image[np.where(image==0)] = 1
            image = image.astype(np.float)
            imagesConv.append(image)
               
        # Calculate percentage change and set with limits -100% to +100%
        imagesPercCh = []
        imageInitial = imagesConv[0]
        for image in imagesConv:
            imagePercCh = (image-imageInitial)/imageInitial*100.
            imagePercCh[np.where(imagePercCh> 100.)] =  100.
            imagePercCh[np.where(imagePercCh<-100.)] = -100.
            imagesPercCh.append(imagePercCh)
            
        numImages  = len(imagesPercCh)
        self.imageWin.imagesRGB = []    
        for i in xrange(numImages):
            image = imagesPercCh[i]
            sx,sy = image.shape 
            #imageCh  = np.zeros((sx,sy),dtype=np.float)
            imageRGB = image*(255/200.)+(255/2.)
            self.imageWin.imagesRGB.append(imageRGB)
        
    def BMDtoCSVfile(self):
        """ Write BMD change to csv file """
        fileName = QtGui.QFileDialog.getSaveFileName(None,self.tr("Export to CSV"),QtCore.QDir.currentPath(),self.tr("CSV (*.csv)"))
        # Fix for PyQt/PySide compatibility. PyQt returns a QString, whereas PySide returns a tuple (first entry is filename as string)        
        if isinstance(fileName,types.TupleType): fileName = fileName[0]
        if hasattr(QtCore,'QString') and isinstance(fileName, QtCore.QString): fileName = str(fileName)            
        if not fileName=='':        
        #if not fileName.isEmpty():               
            textFile  = open(fileName,'w')
            numFrames, numROIs = self.BMDchange.shape    
            roiNames = self.roiNames
            header  = "%10s," % 'Time'
            header += ((numROIs-1)*'%10s,'+'%10s\n') % tuple(roiNames)
            textFile.write(header)
            for i in xrange(numFrames):
                textFile.write('%10.1f,' % self.timeData[i])
                for j in xrange(numROIs):
                    if j<numROIs-1: fmt = '%10.3f,'
                    else:           fmt = '%10.3f\n'
                    textFile.write(fmt % self.BMDchange[i,j])
            textFile.close()       

    def showResults(self,):
        """ Plots BMD change using matplotlib """
        # Create plot window       
        if self.plotWin==None:
            self.plotWin = QtGui.QDialog(self, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |  \
                                         QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
            self.plotWin.setWindowTitle('BMDanalyse')
            self.plotWin.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.plotWin.setMinimumSize(600,500)
            self.plotWin.resize(self.minimumSize()) 

            # Create Matplotlib widget
            self.mplw = MatplotlibWidget(size=(5,6))
            self.fig  = self.mplw.getFigure()
        
            self.editDataButton  = QtGui.QPushButton('Edit plot')
            self.exportCSVButton = QtGui.QPushButton('Export data')
            self.mplw.toolbar.addWidget(self.editDataButton)
            self.mplw.toolbar.addWidget(self.exportCSVButton)
            self.editDataButton.clicked.connect(self.showEditBox)
            self.exportCSVButton.clicked.connect(self.BMDtoCSVfile)

            # Format plot window
            self.plotWinLayout = QtGui.QVBoxLayout()
            self.plotWinLayout.addWidget(self.mplw)
            self.plotWin.setLayout(self.plotWinLayout)
        
        self.createFigure()
        self.plotWin.show()
        self.mplw.draw()
        
    def createFigure(self):
        """ Creates plot of results """
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.clear()
        self.fig.subplots_adjust(bottom=0.15,top=0.85,left=0.15,right=0.925)
        numFrames, numROIs = self.BMDchange.shape
        t = self.timeData
        # Plot data
        for i in xrange(numROIs):
            roiname = self.roiNames[i]
            self.ax1.plot(t,self.BMDchange[:,i],'-o',label=roiname,linewidth=2.0)
        kwargs = dict(y=1.05)  # Or kwargs = {'y':1.05}
        self.ax1.set_title('Change in Bone Mineral Density over time',fontsize=14,fontweight='roman',**kwargs)
        self.ax1.set_xlabel('Time',fontsize=10)
        self.ax1.set_ylabel('Change in BMD (%)',fontsize=10)
        self.ax1.legend(loc=0)
        matplotlib.pyplot.setp(self.ax1.get_xmajorticklabels(),  fontsize=10)
        matplotlib.pyplot.setp(self.ax1.get_ymajorticklabels(),  fontsize=10)
        matplotlib.pyplot.setp(self.ax1.get_legend().get_texts(),fontsize=10)  
        self.ax1.grid()  

    def fillEditBox(self):
        rows,cols = self.BMDchange.shape
        for i in xrange(rows):
            itmValue = '%.2f' % self.timeData[i]
            itm      = QtGui.QTableWidgetItem(itmValue)
            self.tableResults.setItem(i,0,itm)
            for j in xrange(cols):
                itmValue = '%.2f' % self.BMDchange[i,j]
                itm = QtGui.QTableWidgetItem(itmValue)
                self.tableResults.setItem(i,j+1,itm)

    def showEditBox(self):
        self.plotWin.editBox = QtGui.QDialog(self.plotWin, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
        self.plotWin.editBox.setWindowIcon(self.icons['BMDanalyseIcon']) 
        self.plotWin.editBox.setWindowTitle('BMDanalyse') 
        self.plotWin.editBox.setModal(True)
        # Add table
        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(10,10,10,10)
        layout.setSpacing(20)
        rows,cols = self.BMDchange.shape
        self.tableResults = MyTableWidget(rows,cols+1,self.plotWin.editBox)
        self.tableResults.verticalHeader().setVisible(True)
        # Set headers
        self.tableResults.setHorizontalHeaderItem(0,QtGui.QTableWidgetItem('Time'))
        for i in xrange(cols):
            header = QtGui.QTableWidgetItem(self.roiNames[i])
            self.tableResults.setHorizontalHeaderItem(i+1,header)
        # Add values to table
        self.fillEditBox()
        # Set layout
        layout.addWidget(self.tableResults)
        self.buttonsFrame  = QtGui.QFrame()
        self.buttonsLayout = QtGui.QHBoxLayout()
        self.buttonReset   = QtGui.QPushButton('Reset')
        self.buttonSave    = QtGui.QPushButton('Save')
        self.buttonClose   = QtGui.QPushButton('Cancel')
        self.buttonReset.setFixedWidth(50)
        self.buttonSave.setFixedWidth(50)
        self.buttonClose.setFixedWidth(50)
        self.buttonClose.clicked.connect(self.plotWin.editBox.close)
        self.buttonSave.clicked.connect(self.updateTableValues)
        self.buttonReset.clicked.connect(self.fillEditBox)
        self.buttonsLayout.addStretch(1)
        self.buttonsLayout.addWidget(self.buttonReset)
        self.buttonsLayout.addWidget(self.buttonSave)
        self.buttonsLayout.addWidget(self.buttonClose) 
        self.buttonsLayout.setContentsMargins(0,0,0,0) 
        self.buttonsFrame.setLayout(self.buttonsLayout)
        layout.addWidget(self.buttonsFrame)
        self.plotWin.editBox.setLayout(layout)
        self.plotWin.editBox.setMaximumSize(layout.sizeHint())
        self.plotWin.editBox.show()
        
    def updateTableValues(self):        
        # Create temporary arrays
        timeData  = self.timeData.copy()
        BMDchange = self.BMDchange.copy() 
        # Put the values from the tables into the temporary arrays
        rows = self.tableResults.rowCount()
        cols = self.tableResults.columnCount()
        for r in xrange(rows):
            for c in xrange(cols):
                item      = self.tableResults.item(r,c)
                itemValue = float(item.text())
                if c==0:
                    timeData[r] = itemValue 
                else: 
                    BMDchange[r,c-1] = itemValue
        # Check that time values are in increasing order. If so, then update arrays
        if any(np.diff(timeData)<=0):
            self.errorMessage = QtGui.QMessageBox()
            self.errorMessage.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.errorMessage.setWindowTitle('BMDanalyse')
            self.errorMessage.setText('Input error: Time values should be in order of increasing value')
            self.errorMessage.setIcon(QtGui.QMessageBox.Warning)           
            self.errorMessage.open()         
        else:         
            self.timeData  = timeData
            self.BMDchange = BMDchange
            self.createFigure()
            self.mplw.draw()
            self.plotWin.editBox.close()
Esempio n. 19
0
class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):

        QtGui.QMainWindow.__init__(self, parent)
        self.loadIcons()
        self.setupUserInterface()
        self.setupSignals()
        self.__version__ = __version__

        # Initialise variables
        self.imageFiles = {}
        self.timeData = None
        self.plotWin = None
        self.imageWin = None
        self.BMDchange = None
        self.roiNames = None

    def loadIcons(self):
        """ Load icons """
        self.icons = dict([
            ('BMDanalyseIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "logo.png"))),
            ('imageAddIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "file_add.png"))),
            ('imageRemIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons",
                                      "file_delete2.png"))),
            ('imageDownIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "arrow-up-2.png"))),
            ('imageUpIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons",
                                      "arrow-down-2.png"))),
            ('imagePrevIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "arrow-left.png"))),
            ('imageNextIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons",
                                      "arrow-right.png"))),
            ('roiAddIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "green-add3.png"))),
            ('roiRectIcon',
             QtGui.QIcon(
                 os.path.join(absDirPath, "icons", "rectangularIcon.png"))),
            ('roiPolyIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons",
                                      "polygonIcon.png"))),
            ('roiRemIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "red_delete.png"))),
            ('roiSaveIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "filesave.png"))),
            ('roiCopyIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons", "file_copy.png"))),
            ('roiLoadIcon',
             QtGui.QIcon(os.path.join(absDirPath, "icons",
                                      "opened-folder.png")))
        ])

    def setupUserInterface(self):
        """ Initialise the User Interface """

        # Left frame
        leftFrame = QtGui.QFrame()
        leftFrameLayout = QtGui.QHBoxLayout()
        leftFrame.setLayout(leftFrameLayout)
        leftFrame.setLineWidth(0)
        leftFrame.setFrameStyle(QtGui.QFrame.Panel)
        leftFrameLayout.setContentsMargins(0, 0, 5, 0)

        # Left frame contents
        self.viewMain = GraphicsLayoutWidget(
        )  # A GraphicsLayout within a GraphicsView
        leftFrameLayout.addWidget(self.viewMain)
        self.viewMain.setMinimumSize(200, 200)
        self.vb = MultiRoiViewBox(lockAspect=True, enableMenu=True)
        self.viewMain.addItem(self.vb)
        self.vb.disableAutoRange()

        # Right frame
        self.sidePanel = SidePanel(self)

        # UI window (containing left and right frames)
        UIwindow = QtGui.QWidget(self)
        UIwindowLayout = QtGui.QHBoxLayout()
        UIwindowSplitter = QtGui.QSplitter(QtCore.Qt.Horizontal)
        UIwindowLayout.addWidget(UIwindowSplitter)
        UIwindow.setLayout(UIwindowLayout)
        self.setCentralWidget(UIwindow)
        UIwindowSplitter.addWidget(leftFrame)
        UIwindowSplitter.addWidget(self.sidePanel)

        # Application window
        self.setWindowTitle('BMDanalyse')
        self.setWindowIcon(self.icons['BMDanalyseIcon'])
        self.setMinimumSize(600, 500)
        self.resize(self.minimumSize())

        # Window menus
        self.createMenus()
        self.createActions()

    def createMenus(self):

        # Menus
        menubar = self.menuBar()
        self.fileMenu = menubar.addMenu('&File')
        self.roiMenu = menubar.addMenu('&ROIs')
        self.submenu = self.roiMenu.addMenu(self.icons['roiAddIcon'],
                                            "Add ROI")
        self.analyseMenu = menubar.addMenu('&Analyse')
        self.aboutMenu = menubar.addMenu('A&bout')

    def createActions(self):

        # Actions for File menu
        self.loadImageAct = QtGui.QAction(self.icons['imageAddIcon'],
                                          "&Load image(s)",
                                          self,
                                          shortcut="Ctrl+L")
        self.removeImageAct = QtGui.QAction(self.icons['imageRemIcon'],
                                            "&Remove current image",
                                            self,
                                            shortcut="Ctrl+X")
        self.exitAct = QtGui.QAction("&Quit",
                                     self,
                                     shortcut="Ctrl+Q",
                                     statusTip="Exit the application")
        fileMenuActions = [
            self.loadImageAct, self.removeImageAct, self.exitAct
        ]
        fileMenuActFuncs = [self.loadImages, self.removeImage, self.close]
        for i in xrange(len(fileMenuActions)):
            action = fileMenuActions[i]
            function = fileMenuActFuncs[i]
            action.triggered[()].connect(function)
        self.fileMenu.addAction(self.loadImageAct)
        self.fileMenu.addAction(self.removeImageAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.exitAct)

        # Actions for ROI menu
        # Submenu to add ROIs

        #self.addROIRectAct = QActionCustom("Rectangular",self.submenu)
        #self.addROIPolyAct = QActionCustom("Polygon",self.submenu)
        self.addROIRectAct = QtGui.QAction("Rectangular", self.submenu)
        self.addROIPolyAct = QtGui.QAction("Polygon", self.submenu)

        #self.addROIRectAct.clickEvent.connect(self.vb.addROI)
        #self.addROIPolyAct.clickEvent.connect(self.vb.addPolyRoiRequest)
        self.addROIRectAct.triggered[()].connect(self.vb.addROI)
        self.addROIPolyAct.triggered[()].connect(self.vb.addPolyRoiRequest)

        self.submenu.addAction(self.addROIRectAct)
        self.submenu.addAction(self.addROIPolyAct)

        self.addROIRectAct.setIcon(self.icons['roiRectIcon'])
        self.addROIPolyAct.setIcon(self.icons['roiPolyIcon'])

        self.addROIRectAct.setShortcut("Ctrl+Shift+R")
        self.addROIPolyAct.setShortcut("Ctrl+Shift+P")

        self.loadRoiAct = QtGui.QAction(self.icons['roiLoadIcon'],
                                        "L&oad ROI",
                                        self,
                                        shortcut="Ctrl+O")
        self.copyRoiAct = QtGui.QAction(self.icons['roiCopyIcon'],
                                        "&Copy ROI",
                                        self,
                                        shortcut="Ctrl+C")
        self.saveRoiAct = QtGui.QAction(self.icons['roiSaveIcon'],
                                        "&Save ROI",
                                        self,
                                        shortcut="Ctrl+S")
        self.remRoiAct = QtGui.QAction(self.icons['roiRemIcon'],
                                       "&Remove ROI",
                                       self,
                                       shortcut="Ctrl+D")
        roiMenuActions = [
            self.loadRoiAct, self.copyRoiAct, self.saveRoiAct, self.remRoiAct
        ]
        roiMenuActFuncs = [
            self.vb.loadROI, self.vb.copyROI, self.vb.saveROI,
            self.vb.removeROI
        ]
        for i in xrange(len(roiMenuActions)):
            action = roiMenuActions[i]
            function = roiMenuActFuncs[i]
            action.triggered[()].connect(function)
            self.roiMenu.addAction(action)

        # Actions for Analyse menu
        self.roiAnalysisAct = QtGui.QAction("&ROI analysis",
                                            self.viewMain,
                                            shortcut="Ctrl+R",
                                            triggered=self.getBMD)
        self.imgAnalysisAct = QtGui.QAction("&Image analysis",
                                            self.viewMain,
                                            shortcut="Ctrl+I",
                                            triggered=self.imageAnalysis)
        self.analyseMenu.addAction(self.roiAnalysisAct)
        self.analyseMenu.addAction(self.imgAnalysisAct)

        # Actions for
        self.aboutAct = QtGui.QAction("&About",
                                      self.viewMain,
                                      shortcut='F1',
                                      triggered=self.onAbout)
        self.aboutMenu.addAction(self.aboutAct)

    def setupSignals(self):
        """ Setup signals """
        self.sidePanel.imageFileList.itemSelectionChanged.connect(
            self.getImageToDisplay)
        self.sidePanel.buttImageAdd.clicked.connect(self.loadImages)
        self.sidePanel.buttImageRem.clicked.connect(self.removeImage)
        self.sidePanel.buttImageUp.clicked.connect(self.sidePanel.moveImageUp)
        self.sidePanel.buttImageDown.clicked.connect(
            self.sidePanel.moveImageDown)

        self.sidePanel.roiMenu.button1.clicked[()].connect(self.vb.addROI)
        self.sidePanel.roiMenu.button2.clicked[()].connect(
            self.vb.addPolyRoiRequest)

        self.sidePanel.buttRoiCopy.clicked[()].connect(self.vb.copyROI)
        self.sidePanel.buttRoiRem.clicked.connect(self.vb.removeROI)
        self.sidePanel.buttRoiLoad.clicked.connect(self.vb.loadROI)
        self.sidePanel.buttRoiSave.clicked.connect(self.vb.saveROI)
        #self.vb.sigROIchanged.connect(self.updateROItools)

    def onAbout(self):
        """ About BMDanalyse message"""
        author = 'Michael Hogg'
        date = '2012 - 2013'
        version = self.__version__

        QtGui.QMessageBox.about(
            self, 'About BMDanalyse', """
            <b>BMDanalyse</b>
            <p>A simple program for the analysis of a time series of Bone Mineral Density (BMD) images.</p>
            <p>Used to evaluate the bone gain / loss in a number of regions of interest (ROIs) over time, 
            typically due to bone remodelling as a result of stress shielding around an orthopaedic implant.</p>
            <p><table border="0" width="150">
            <tr>
            <td>Author:</td>
            <td>%s</td>
            </tr>
            <tr>
            <td>Version:</td>
            <td>%s</td>
            </tr>
            <tr>
            <td>Date:</td>
            <td>%s</td>
            </tr>            
            </table></p>
            """ % (author, version, date))

    def updateROItools(self, roi=None):
        """ Update ROI info box in side panel """
        if roi == None:
            self.sidePanel.updateRoiInfoBox()
        else:
            roiState = roi.getState()
            posx, posy = roiState['pos']
            sizex, sizey = roiState['size']
            angle = roiState['angle']
            name = roi.name
            pos = '(%.3f, %.3f)' % (posx, posy)
            size = '(%.3f, %.3f)' % (sizex, sizey)
            angle = '%.3f' % angle
            self.sidePanel.updateRoiInfoBox(name, pos, size, angle)

    def loadImages(self):
        """ Load an image to be analysed """
        newImages = {}
        fileNames = QtGui.QFileDialog.getOpenFileNames(
            self, self.tr("Load images"), QtCore.QDir.currentPath())

        # Fix for PySide. PySide doesn't support QStringList types. PyQt4 getOpenFileNames returns a QStringList, whereas PySide
        # returns a type (the first entry being the list of filenames).
        if isinstance(fileNames, types.TupleType): fileNames = fileNames[0]
        if hasattr(QtCore, 'QStringList') and isinstance(
                fileNames, QtCore.QStringList):
            fileNames = [str(i) for i in fileNames]

        if len(fileNames) > 0:
            for fileName in fileNames:
                if fileName != '':
                    imgarr = np.array(Image.open(str(fileName)))
                    imgarr = imgarr.swapaxes(0, 1)
                    if imgarr.ndim == 2: imgarr = imgarr[:, ::-1]
                    elif imgarr.ndim == 3: imgarr = imgarr[:, ::-1, :]
                    newImages[fileName] = imgarr

            # Add filenames to list widget. Only add new filenames. If filename exists aready, then
            # it will not be added, but data will be updated
            for fileName in sorted(newImages.keys()):
                if not self.imageFiles.has_key(fileName):
                    self.sidePanel.addImageToList(fileName)
                self.imageFiles[fileName] = newImages[fileName]

            # Show image in Main window
            self.vb.enableAutoRange()
            if self.sidePanel.imageFileList.currentRow() == -1:
                self.sidePanel.imageFileList.setCurrentRow(0)
            self.showImage(
                str(self.sidePanel.imageFileList.currentItem().text()))
            self.vb.disableAutoRange()

    def removeImage(self):
        """ Remove image from sidePanel imageFileList """

        # Return if there is no image to remove
        if self.vb.img == None: return

        # Get current image in sidePanel imageFileList and remove from list
        currentRow = self.sidePanel.imageFileList.currentRow()
        image = self.sidePanel.imageFileList.takeItem(currentRow)
        imageName = str(image.text())

        # Delete key and value from dictionary
        if imageName != '': del self.imageFiles[imageName]
        #self.imageFiles.pop(imageName,None)

        # Get image item in imageFileList to replace deleted image
        if self.sidePanel.imageFileList.count() == 0:
            self.vb.enableAutoRange()
            self.vb.removeItem(self.vb.img)
            self.vb.showImage(None)
            #self.vb.img = None
            self.vb.disableAutoRange()
        else:
            currentRow = self.sidePanel.imageFileList.currentRow()
            imageName = str(
                self.sidePanel.imageFileList.item(currentRow).text())
            self.showImage(imageName)

    def showImage(self, imageFilename):
        """ Shows image in main view """
        self.arr = self.imageFiles[imageFilename]
        self.vb.showImage(self.arr)

    def getImageToDisplay(self):
        """ Get current item in file list and display in main view"""
        try:
            imageFilename = str(
                self.sidePanel.imageFileList.currentItem().text())
        except:
            pass
        else:
            self.showImage(imageFilename)

    def getBMD(self):
        """ Get change in BMD over time (e.g. for each image) for all ROIs. 
            
            Revised function that converts the list of images into a 3D array
            and then uses the relative position of the ROIs to the current
            image, self.vb.img, to get the average BMD value e.g. it doesn't use
            setImage to change the image in the view. This requires that all
            images are the same size and in the same position.
        """

        # Return if there is no image or rois in view
        if self.vb.img == None or len(self.vb.rois) == 0: return

        # Collect all images into a 3D array
        imageFilenames = self.sidePanel.getListOfImages()
        images = [self.imageFiles[str(name.text())] for name in imageFilenames]
        imageData = np.dstack(images)
        numImages = len(images)

        # Get BMD across image stack for each ROI
        numROIs = len(self.vb.rois)
        BMD = np.zeros((numImages, numROIs), dtype=float)
        self.roiNames = []
        for i in xrange(numROIs):
            roi = self.vb.rois[i]
            self.roiNames.append(roi.name)
            arrRegion = roi.getArrayRegion(imageData, self.vb.img, axes=(0, 1))
            avgROIvalue = arrRegion.mean(axis=0).mean(axis=0)
            BMD[:, i] = avgROIvalue

        # Calculate the BMD change (percentage of original)
        tol = 1.0e-06
        for i in xrange(numROIs):
            if abs(BMD[0, i]) < tol:
                BMD[:, i] = 100.
            else:
                BMD[:, i] = BMD[:, i] / BMD[0, i] * 100.
        self.BMDchange = BMD - 100.
        if self.timeData == None or self.timeData.size != numImages:
            self.timeData = np.arange(numImages, dtype=float)

        # Plot results
        self.showResults()

    def imageAnalysis(self):
        # Generate images of BMD change
        if self.vb.img == None: return
        self.showImageWin()

    def sliderValueChanged(self, value):
        self.imageWin.sliderLabel.setText('BMD change: >= %d %s' %
                                          (value, '%'))
        self.setLookupTable(value)
        self.imageWin.vb.img2.setLookupTable(self.lut)

    def setLookupTable(self, val):
        lut = []
        for i in range(256):
            if i > 127 + val:
                lut.append(matplotlib.cm.jet(255))
            elif i < 127 - val:
                lut.append(matplotlib.cm.jet(0))
            else:
                lut.append((0.0, 0.0, 0.0, 0.0))
        lut = np.array(lut) * 255
        self.lut = np.array(lut, dtype=np.ubyte)

    def createImageWin(self):

        self.buttMinimumSize = QtCore.QSize(70, 36)
        self.iconSize = QtCore.QSize(24, 24)

        if self.imageWin == None:

            self.imageWin = QtGui.QDialog(self, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |  \
                                          QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
            self.imageWin.setWindowTitle('BMDanalyse')
            self.imageWin.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.imageWin.setMinimumSize(250, 500)
            self.imageWin.resize(self.imageWin.minimumSize())

            # Create viewBox
            self.imageWin.glw = GraphicsLayoutWidget(
            )  # A GraphicsLayout within a GraphicsView
            self.imageWin.vb = ImageAnalysisViewBox(lockAspect=True,
                                                    enableMenu=True)
            self.imageWin.vb.disableAutoRange()
            self.imageWin.glw.addItem(self.imageWin.vb)
            arr = self.imageFiles.values()[0]
            self.imageWin.vb.img1 = pg.ImageItem(arr,
                                                 autoRange=False,
                                                 autoLevels=False)
            self.imageWin.vb.addItem(self.imageWin.vb.img1)
            self.imageWin.vb.img2 = pg.ImageItem(None,
                                                 autoRange=False,
                                                 autoLevels=False)
            self.imageWin.vb.addItem(self.imageWin.vb.img2)
            self.imageWin.vb.autoRange()
            lut = [[int(255 * val) for val in matplotlib.cm.gray(i)[:3]]
                   for i in xrange(256)]
            lut = np.array(lut, dtype=np.ubyte)
            self.imageWin.vb.img1.setLookupTable(lut)

            # Label to show index of current image label
            self.imageCurrCont = QtGui.QFrame()
            self.imageCurrCont.setLineWidth(2)
            self.imageCurrCont.setFrameStyle(QtGui.QFrame.Panel
                                             | QtGui.QFrame.Raised)
            self.imageCurrCont.setMinimumWidth(70)
            self.imageWin.currLabel = QtGui.QLabel("")
            self.imageWin.currLabel.setAlignment(QtCore.Qt.AlignHCenter)
            imageCurrContLayout = QtGui.QHBoxLayout()
            imageCurrContLayout.addWidget(self.imageWin.currLabel)
            self.imageCurrCont.setLayout(imageCurrContLayout)

            # Create buttons to select images
            self.imageWin.buttCont = QtGui.QWidget()
            self.imageWin.buttPrev = QtGui.QPushButton(
                self.icons['imagePrevIcon'], "")
            self.imageWin.buttNext = QtGui.QPushButton(
                self.icons['imageNextIcon'], "")
            self.buttLayout = QtGui.QHBoxLayout()
            self.buttLayout.addStretch(1)
            self.buttLayout.addWidget(self.imageWin.buttPrev)
            self.buttLayout.addWidget(self.imageCurrCont)
            self.buttLayout.addWidget(self.imageWin.buttNext)
            self.buttLayout.addStretch(1)
            self.imageWin.buttCont.setLayout(self.buttLayout)
            self.imageWin.buttPrev.setMinimumSize(self.buttMinimumSize)
            self.imageWin.buttNext.setMinimumSize(self.buttMinimumSize)
            self.imageWin.buttPrev.setIconSize(self.iconSize)
            self.imageWin.buttNext.setIconSize(self.iconSize)
            self.buttLayout.setContentsMargins(0, 5, 0, 5)

            self.imageWin.buttPrev.clicked.connect(self.prevImage)
            self.imageWin.buttNext.clicked.connect(self.nextImage)

            # Create slider
            self.imageWin.sliderCon = QtGui.QWidget()
            self.imageWin.slider = QtGui.QSlider(self)
            self.imageWin.slider.setOrientation(QtCore.Qt.Horizontal)
            self.imageWin.slider.setMinimum(1)
            self.imageWin.slider.setMaximum(100)
            self.imageWin.slider.setMinimumWidth(100)
            self.imageWin.slider.valueChanged.connect(self.sliderValueChanged)
            self.imageWin.sliderLabel = QtGui.QLabel('1')
            self.imageWin.sliderLabel.setMinimumWidth(120)
            self.sliderLayout = QtGui.QHBoxLayout()
            self.sliderLayout.addStretch(1)
            self.sliderLayout.addWidget(self.imageWin.sliderLabel)
            self.sliderLayout.addWidget(self.imageWin.slider)
            self.sliderLayout.addStretch(1)
            self.imageWin.sliderCon.setLayout(self.sliderLayout)
            self.sliderLayout.setContentsMargins(0, 0, 0, 5)

            # Format image window
            self.imageWinLayout = QtGui.QVBoxLayout()
            self.imageWinLayout.addWidget(self.imageWin.glw)
            self.imageWinLayout.addWidget(self.imageWin.buttCont)
            self.imageWinLayout.addWidget(self.imageWin.sliderCon)
            self.imageWin.setLayout(self.imageWinLayout)

            self.imageWin.imagesRGB = None

        # Show
        self.imageWin.show()
        self.imageWin.slider.setValue(10)
        self.sliderValueChanged(10)
        self.imageWinIndex = 0

    def prevImage(self):
        #numImages = len(self.imageFiles)
        minIndex = 0
        currIndex = self.imageWinIndex
        prevIndex = currIndex - 1
        self.imageWinIndex = max(prevIndex, minIndex)
        self.updateImageWin()

    def nextImage(self):
        numImages = len(self.imageFiles)
        maxIndex = numImages - 1
        currIndex = self.imageWinIndex
        nextIndex = currIndex + 1
        self.imageWinIndex = min(nextIndex, maxIndex)
        self.updateImageWin()

    def updateImageWin(self):
        imageFilenames = self.sidePanel.getListOfImages()
        imageName = imageFilenames[self.imageWinIndex]
        self.imageWin.vb.img1.setImage(self.imageFiles[str(imageName.text())],
                                       autoLevels=False)
        self.imageWin.vb.img2.setImage(
            self.imageWin.imagesRGB[self.imageWinIndex], autoLevels=False)
        self.imageWin.currLabel.setText(
            "%i / %i" % (self.imageWinIndex + 1, len(imageFilenames)))

    def showImageWin(self):
        self.createImageWin()
        #if self.imageWin.imagesRGB == None: self.imagesBMDpercentChange()
        self.imagesBMDpercentChange()
        self.updateImageWin()

    def imagesBMDpercentChange(self):

        # Get image arrays and convert to an array of floats
        imageFilenames = self.sidePanel.getListOfImages()
        images = [self.imageFiles[str(name.text())] for name in imageFilenames]
        imagesConv = []
        for img in images:
            image = img.copy()
            image[np.where(image == 0)] = 1
            image = image.astype(np.float)
            imagesConv.append(image)

        # Calculate percentage change and set with limits -100% to +100%
        imagesPercCh = []
        imageInitial = imagesConv[0]
        for image in imagesConv:
            imagePercCh = (image - imageInitial) / imageInitial * 100.
            imagePercCh[np.where(imagePercCh > 100.)] = 100.
            imagePercCh[np.where(imagePercCh < -100.)] = -100.
            imagesPercCh.append(imagePercCh)

        numImages = len(imagesPercCh)
        self.imageWin.imagesRGB = []
        for i in xrange(numImages):
            image = imagesPercCh[i]
            sx, sy = image.shape
            #imageCh  = np.zeros((sx,sy),dtype=np.float)
            imageRGB = image * (255 / 200.) + (255 / 2.)
            self.imageWin.imagesRGB.append(imageRGB)

    def BMDtoCSVfile(self):
        """ Write BMD change to csv file """
        fileName = QtGui.QFileDialog.getSaveFileName(None,
                                                     self.tr("Export to CSV"),
                                                     QtCore.QDir.currentPath(),
                                                     self.tr("CSV (*.csv)"))
        # Fix for PyQt/PySide compatibility. PyQt returns a QString, whereas PySide returns a tuple (first entry is filename as string)
        if isinstance(fileName, types.TupleType): fileName = fileName[0]
        if hasattr(QtCore, 'QString') and isinstance(fileName, QtCore.QString):
            fileName = str(fileName)
        if not fileName == '':
            #if not fileName.isEmpty():
            textFile = open(fileName, 'w')
            numFrames, numROIs = self.BMDchange.shape
            roiNames = self.roiNames
            header = "%10s," % 'Time'
            header += ((numROIs - 1) * '%10s,' + '%10s\n') % tuple(roiNames)
            textFile.write(header)
            for i in xrange(numFrames):
                textFile.write('%10.1f,' % self.timeData[i])
                for j in xrange(numROIs):
                    if j < numROIs - 1: fmt = '%10.3f,'
                    else: fmt = '%10.3f\n'
                    textFile.write(fmt % self.BMDchange[i, j])
            textFile.close()

    def showResults(self, ):
        """ Plots BMD change using matplotlib """
        # Create plot window
        if self.plotWin == None:
            self.plotWin = QtGui.QDialog(self, QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint |  \
                                         QtCore.Qt.WindowMinimizeButtonHint | QtCore.Qt.WindowMaximizeButtonHint)
            self.plotWin.setWindowTitle('BMDanalyse')
            self.plotWin.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.plotWin.setMinimumSize(600, 500)
            self.plotWin.resize(self.minimumSize())

            # Create Matplotlib widget
            self.mplw = MatplotlibWidget(size=(5, 6))
            self.fig = self.mplw.getFigure()

            self.editDataButton = QtGui.QPushButton('Edit plot')
            self.exportCSVButton = QtGui.QPushButton('Export data')
            self.mplw.toolbar.addWidget(self.editDataButton)
            self.mplw.toolbar.addWidget(self.exportCSVButton)
            self.editDataButton.clicked.connect(self.showEditBox)
            self.exportCSVButton.clicked.connect(self.BMDtoCSVfile)

            # Format plot window
            self.plotWinLayout = QtGui.QVBoxLayout()
            self.plotWinLayout.addWidget(self.mplw)
            self.plotWin.setLayout(self.plotWinLayout)

        self.createFigure()
        self.plotWin.show()
        self.mplw.draw()

    def createFigure(self):
        """ Creates plot of results """
        self.ax1 = self.fig.add_subplot(111)
        self.ax1.clear()
        self.fig.subplots_adjust(bottom=0.15, top=0.85, left=0.15, right=0.925)
        numFrames, numROIs = self.BMDchange.shape
        t = self.timeData
        # Plot data
        for i in xrange(numROIs):
            roiname = self.roiNames[i]
            self.ax1.plot(t,
                          self.BMDchange[:, i],
                          '-o',
                          label=roiname,
                          linewidth=2.0)
        kwargs = dict(y=1.05)  # Or kwargs = {'y':1.05}
        self.ax1.set_title('Change in Bone Mineral Density over time',
                           fontsize=14,
                           fontweight='roman',
                           **kwargs)
        self.ax1.set_xlabel('Time', fontsize=10)
        self.ax1.set_ylabel('Change in BMD (%)', fontsize=10)
        self.ax1.legend(loc=0)
        matplotlib.pyplot.setp(self.ax1.get_xmajorticklabels(), fontsize=10)
        matplotlib.pyplot.setp(self.ax1.get_ymajorticklabels(), fontsize=10)
        matplotlib.pyplot.setp(self.ax1.get_legend().get_texts(), fontsize=10)
        self.ax1.grid()

    def fillEditBox(self):
        rows, cols = self.BMDchange.shape
        for i in xrange(rows):
            itmValue = '%.2f' % self.timeData[i]
            itm = QtGui.QTableWidgetItem(itmValue)
            self.tableResults.setItem(i, 0, itm)
            for j in xrange(cols):
                itmValue = '%.2f' % self.BMDchange[i, j]
                itm = QtGui.QTableWidgetItem(itmValue)
                self.tableResults.setItem(i, j + 1, itm)

    def showEditBox(self):
        self.plotWin.editBox = QtGui.QDialog(
            self.plotWin,
            QtCore.Qt.WindowSystemMenuHint | QtCore.Qt.WindowTitleHint)
        self.plotWin.editBox.setWindowIcon(self.icons['BMDanalyseIcon'])
        self.plotWin.editBox.setWindowTitle('BMDanalyse')
        self.plotWin.editBox.setModal(True)
        # Add table
        layout = QtGui.QVBoxLayout()
        layout.setContentsMargins(10, 10, 10, 10)
        layout.setSpacing(20)
        rows, cols = self.BMDchange.shape
        self.tableResults = MyTableWidget(rows, cols + 1, self.plotWin.editBox)
        self.tableResults.verticalHeader().setVisible(True)
        # Set headers
        self.tableResults.setHorizontalHeaderItem(
            0, QtGui.QTableWidgetItem('Time'))
        for i in xrange(cols):
            header = QtGui.QTableWidgetItem(self.roiNames[i])
            self.tableResults.setHorizontalHeaderItem(i + 1, header)
        # Add values to table
        self.fillEditBox()
        # Set layout
        layout.addWidget(self.tableResults)
        self.buttonsFrame = QtGui.QFrame()
        self.buttonsLayout = QtGui.QHBoxLayout()
        self.buttonReset = QtGui.QPushButton('Reset')
        self.buttonSave = QtGui.QPushButton('Save')
        self.buttonClose = QtGui.QPushButton('Cancel')
        self.buttonReset.setFixedWidth(50)
        self.buttonSave.setFixedWidth(50)
        self.buttonClose.setFixedWidth(50)
        self.buttonClose.clicked.connect(self.plotWin.editBox.close)
        self.buttonSave.clicked.connect(self.updateTableValues)
        self.buttonReset.clicked.connect(self.fillEditBox)
        self.buttonsLayout.addStretch(1)
        self.buttonsLayout.addWidget(self.buttonReset)
        self.buttonsLayout.addWidget(self.buttonSave)
        self.buttonsLayout.addWidget(self.buttonClose)
        self.buttonsLayout.setContentsMargins(0, 0, 0, 0)
        self.buttonsFrame.setLayout(self.buttonsLayout)
        layout.addWidget(self.buttonsFrame)
        self.plotWin.editBox.setLayout(layout)
        self.plotWin.editBox.setMaximumSize(layout.sizeHint())
        self.plotWin.editBox.show()

    def updateTableValues(self):
        # Create temporary arrays
        timeData = self.timeData.copy()
        BMDchange = self.BMDchange.copy()
        # Put the values from the tables into the temporary arrays
        rows = self.tableResults.rowCount()
        cols = self.tableResults.columnCount()
        for r in xrange(rows):
            for c in xrange(cols):
                item = self.tableResults.item(r, c)
                itemValue = float(item.text())
                if c == 0:
                    timeData[r] = itemValue
                else:
                    BMDchange[r, c - 1] = itemValue
        # Check that time values are in increasing order. If so, then update arrays
        if any(np.diff(timeData) <= 0):
            self.errorMessage = QtGui.QMessageBox()
            self.errorMessage.setWindowIcon(self.icons['BMDanalyseIcon'])
            self.errorMessage.setWindowTitle('BMDanalyse')
            self.errorMessage.setText(
                'Input error: Time values should be in order of increasing value'
            )
            self.errorMessage.setIcon(QtGui.QMessageBox.Warning)
            self.errorMessage.open()
        else:
            self.timeData = timeData
            self.BMDchange = BMDchange
            self.createFigure()
            self.mplw.draw()
            self.plotWin.editBox.close()
Esempio n. 20
0
class MainWindow(QMainWindow):
    def __init__(self):
        super(MainWindow, self).__init__()
        self.createActions()
        self.createMenus()
        self.setGeometry(100, 100, 600, 900)

        self.centralWidget = QWidget()
        # GrphicsWidget()
        layout = QHBoxLayout(self.centralWidget)
        self.scrollArea = QScrollArea(self)
        self.mw = MatplotlibWidget(size=(3.0, 40.0), dpi=100)
        lplot = self.mw.getFigure().add_subplot(121)
        self.ax = self.mw.getFigure().gca()
        l, b, w, h = self.ax.get_position().bounds
        # print(l, b, w, h)
        # self.ax.invert_yaxis()
        self.ax.set_position([0.125, 0.05, 0.5, 0.94])

        # l, b, w, h = self.ax.get_position().bounds
        # print(l, b, w, h)
        self.mw.draw()
        # self.plotlayout.addWidget(self.mw)

        self.scrollArea.setWidget(self.mw)

        layout.addWidget(self.scrollArea)

        self.setCentralWidget(self.centralWidget)
        self.lastree = LasTree()
        self.logtree = LasTree()
        self.wellLoad()
        self.logtree.set_files(['GR', 'BS'])
        self.logtree.buildTreeWidget()
        self.logtree.tree.itemSelectionChanged.connect(self.logPlot)

        self.createDockWindows()

        # self.logFileList.itemSelectionChanged.connect(self.lasLoad)
        # if not self.las_just_selected:
        # self.logList.itemSelectionChanged.connect(self.logPlot)

        self.setWindowTitle("Loggy")

        # self.newLetter()
    def wellLoad(self):
        self.wellFolder = well_folder

        self.files = []
        for f in np.array(os.listdir(self.wellFolder)[:]):
            if f[-4:].lower() in ['.las', 'dlis']:
                self.files.append(f)
        self.files = np.array(self.files)
        files_w_path = [self.wellFolder + f for f in self.files]

        cols = []

        # self.files=np.array(os.listdir(self.wellFolder)[:])

        self.lastree.set_files(self.files)
        self.lastree.buildTreeWidget()
        self.lastree.tree.itemSelectionChanged.connect(self.lasLoad)

        self.lasLoadThread = LasLoadThread(files=files_w_path)

    # def lasBackgroundLoad():

    def lasLoad(self):
        las_name = self.lastree.tree.selectedItems()[0].text(
            0)  #self.logFileList.selectedItems()[0].text()
        if las_name in ['TVD', 'MD', 'LWD', 'WireLine']:
            return

        findex = np.where(self.files == las_name)[0][0]
        # print(findex)
        Loaded = False
        while (not Loaded):
            if (findex < len(self.lasLoadThread.Lases)):
                self.las = self.lasLoadThread.Lases[findex]
                Loaded = True
                self.logtree.tree.clear()
                # print('hi')
            else:
                # print('hello')

                # self.logtree.addItems(['Loading....'])
                time.sleep(1)

        if len(self.logtree.tree.selectedItems()) > 0:
            item = self.logtree.tree.selectedItems()[0]
            # print(dir(item))
            item.setSelected = False
        if not (len(self.las.keys()) < 1):
            # self.logtree = LasTree(self.las.keys())
            self.logtree.set_files(self.las.keys())
            self.logtree.buildTreeWidget()

            dcol = self.las.keys()[find_depth_indx(self.las)]
            self.depth_col = str_array2floats(self.las[dcol])
        # else:

        # self.las_just_selected = True

    def logPlot(self):

        # print(self.mw.getFigure().)
        # pass
        # if not self.las_just_selected:
        if len(self.logtree.tree.selectedItems()) > 0:
            keycol = self.logtree.tree.selectedItems()[0].text(0)
            try:
                self.log_col = str_array2floats(self.las[keycol])
                self.ax = LogPlot.basicPlot(self.ax,
                                            self.depth_col,
                                            self.log_col,
                                            lcolor='#800000')
                self.ax.set_ylim(500, 3000)
                self.ax.invert_yaxis()
            except:
                print('Unable to convert log to floats')
        self.mw.draw()

    def set_category(self):
        # qt_app = QApplication(sys.argv)
        # mnomonicsfile=mnomonicsfile
        # print(self.logtree.treeview_dict)
        # set_category_app = Categorize(self.logtree.treeview_dict,mnomonicsfile)
        print('*************************************************')
        print(self.logtree.treeview_dict)
        category_window = Categorize(self)
        category_window.set_params(self.logtree, mnomonicsfile)
        category_window.show()

        # self.logtree.tree.clear()
        # self.logtree.buildTreeWidget()
        # set_category_app.run()
        # self.logtree.buildTreeWidget()

    def createDockWindows(self):

        dock = QDockWidget("Log Files", self)
        dock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
        dock.setWidget(self.lastree.tree)
        #
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        self.set_category_button = QPushButton('Set Category', self)

        # self.layout.addWidget(self.logtree.tree)
        dock = QDockWidget("Set", self)
        dock.setWidget(self.set_category_button)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)
        dock = QDockWidget("Logs", self)

        dock.setWidget(self.logtree.tree)
        self.addDockWidget(Qt.LeftDockWidgetArea, dock)

        self.set_category_button.clicked.connect(self.set_category)

    def createActions(self):
        self.exitAct = QAction("E&xit",
                               self,
                               shortcut="Ctrl+Q",
                               triggered=self.close)
        self.openFileAct = QAction("&Open",
                                   self,
                                   shortcut="Ctrl+O",
                                   triggered=self.file_open)
        self.aboutAct = QAction("&About", self, triggered=self.about)

    def createMenus(self):
        self.fileMenu = QMenu("&File", self)
        # self.fileMenu.addAction(self.openAct)
        # self.fileMenu.addAction(self.printAct)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction(self.openFileAct)
        self.fileMenu.addAction(self.exitAct)

        self.helpMenu = QMenu("&Help", self)
        self.helpMenu.addAction(self.aboutAct)
        # self.helpMenu.addAction(self.aboutQtAct)

        self.menuBar().addMenu(self.fileMenu)
        # self.menuBar().addMenu(self.viewMenu)
        # self.menuBar().addMenu(self.digitizeMenu)
        self.menuBar().addMenu(self.helpMenu)

        self.file_toolbar = QToolBar("File")
        self.file_toolbar.setIconSize(QSize(24, 24))
        self.addToolBar(self.file_toolbar)

    def about(self):
        QMessageBox.about(
            self, "About Log splicer",
            "<p>The <b>Image Viewer</b> example shows how to combine "
            "(QScrollArea.widgetResizable), can be used to implement "
            "zooming and scaling features.</p>"
            "<p>In addition the example shows how to use QPainter to "
            "print an image.</p>")

    def file_open(self):
        print('Not yet set')