Ejemplo n.º 1
0
 def __init__(self,
              fname=None,
              data=None,
              comment='#',
              skiprows=0,
              delimiter=' ',
              expressions={},
              autoupdate=False,
              parent=None,
              matplotlib=False,
              plotIndex=None,
              colors=None):
     QDialog.__init__(self, parent=parent)
     loadUi('UI_Forms/Data_Dialog.ui', self)
     self.colcycler = cycle(['r', 'g', 'b', 'c', 'm', 'y', 'w'])
     self.plotWidget = PlotWidget(parent=self, matplotlib=matplotlib)
     self.plotTab = self.tabWidget.addTab(self.plotWidget, 'Plots')
     self.tabWidget.setCurrentIndex(0)
     self.show()
     self.fileWatcher = QFileSystemWatcher()
     self.fileWatcher.fileChanged.connect(self.fileUpdated)
     self.cwd = None
     self.plotNum = 0
     self.xlabel = []
     self.ylabel = []
     self.oldPlotIndex = {}
     self.oldColors = {}
     self.dataAltered = False
     self.expressions = expressions
     if data is not None:
         self.data = data
         self.autoUpdateCheckBox.setEnabled(False)
     elif fname is not None:
         self.data = self.readData(fname,
                                   comment=comment,
                                   skiprows=skiprows,
                                   delimiter=delimiter)
     else:
         self.data = None
         self.autoUpdateCheckBox.setEnabled(False)
         self.saveDataPushButton.setEnabled(False)
         self.addRowPushButton.setEnabled(False)
         self.removeRowsPushButton.setEnabled(False)
         self.removeColumnPushButton.setEnabled(False)
     if self.data is not None:
         self.setMeta2Table()
         self.setData2Table()
         if plotIndex is None:
             self.addPlots(color=None)
         else:
             self.addMultiPlots(plotIndex=plotIndex, colors=colors)
     self.init_signals()
     self.okPushButton.setAutoDefault(False)
     self.make_default()
     self.setWindowTitle('Data Dialog')
     self.acceptData = True
Ejemplo n.º 2
0
 def create_UI(self):
     """
     Creates the widget user interface
     """
     loadUi('UI_Forms/Data_Reduction_Client.ui',self)
     self.poniFileLineEdit.setText(str(self.poniFile))
     self.maskFileLineEdit.setText(str(self.maskFile))
     self.darkFileLineEdit.setText(str(self.darkFile))
     self.extractedBaseFolderLineEdit.setText(self.extractedBaseFolder)
     self.radialPointsLineEdit.setText(str(self.npt))
     self.openDataPushButton.clicked.connect(self.openDataFiles)
     self.reducePushButton.clicked.connect(self.reduce_multiple)
     self.openDarkPushButton.clicked.connect(self.openDarkFile)
     self.openPoniPushButton.clicked.connect(lambda x: self.openPoniFile(file=None))
     self.calibratePushButton.clicked.connect(self.calibrate)
     self.maskFileLineEdit.returnPressed.connect(self.maskFileChanged)
     self.openMaskPushButton.clicked.connect(lambda x: self.openMaskFile(file=None))
     self.createMaskPushButton.clicked.connect(self.createMask)
     self.extractedFolderPushButton.clicked.connect(self.openFolder)
     self.extractedFolderLineEdit.textChanged.connect(self.extractedFolderChanged)
     self.polCorrComboBox.currentIndexChanged.connect(self.polarizationChanged)
     self.polarizationChanged()
     self.radialPointsLineEdit.returnPressed.connect(self.nptChanged)
     self.azimuthalRangeLineEdit.returnPressed.connect(self.azimuthalRangeChanged)
     self.azimuthalRangeChanged()
     #self.statusLabel.setStyleSheet("color:rgba(0,1,0,0)")
     self.imageWidget=Image_Widget(zeros((100,100)))
     self.cakedImageWidget=Image_Widget(zeros((100,100)))
     imgNumberLabel=QLabel('Image number')
     self.imgNumberSpinBox=QSpinBox()
     self.imgNumberSpinBox.setSingleStep(1)
     self.imageWidget.imageLayout.addWidget(imgNumberLabel,row=2,col=1)
     self.imageWidget.imageLayout.addWidget(self.imgNumberSpinBox,row=2,col=2)
     self.imageView=self.imageWidget.imageView.getView()
     self.plotWidget=PlotWidget()
     self.plotWidget.setXLabel('Q, &#8491;<sup>-1</sup>',fontsize=5)
     self.plotWidget.setYLabel('Intensity',fontsize=5)
     self.tabWidget.addTab(self.plotWidget,'Reduced 1D-data')
     self.tabWidget.addTab(self.imageWidget,'Masked 2D-data')
     self.tabWidget.addTab(self.cakedImageWidget,'Reduced Caked Data')
     
     self.serverAddress=self.serverAddressLineEdit.text()
     self.startClientPushButton.clicked.connect(self.startClient)
     self.stopClientPushButton.clicked.connect(self.stopClient)
     self.serverAddressLineEdit.returnPressed.connect(self.serverAddressChanged)
     
     self.startServerPushButton.clicked.connect(self.startServer)
     self.stopServerPushButton.clicked.connect(self.stopServer)
Ejemplo n.º 3
0
    def __init__(self):
        self.app = wx.App(False)

        wx.Frame.__init__(self, None, title="Nocturnal hypoglycemia prediction", size=(1100, 800))
        panel = wx.Panel(self)

        menu = wx.Menu()
        about = menu.Append(wx.ID_ABOUT, "&About", "Information about this program")
        self.Bind(wx.EVT_MENU, lambda x: self.OnAbout(), about)

        menuBar = wx.MenuBar()
        menuBar.Append(menu, "&Help")
        self.SetMenuBar(menuBar)

        label = wx.StaticText(panel, label="Train dataset path:", pos=(10, 10))
        self.m_train_dataset_path_edit = wx.TextCtrl(panel, pos=(10, 30), size=(800, 20))
        self.m_train_dataset_path_edit.SetValue(u"D:\GDrive\Диплом 2\DataPreparation\output1\\fixed_dataset+_train.xlsx")

        label = wx.StaticText(panel, label="Test dataset path:", pos=(10, 60))
        self.m_test_dataset_path_edit = wx.TextCtrl(panel, pos=(10, 80), size=(800, 20))
        self.m_test_dataset_path_edit.SetValue(u"D:\GDrive\Диплом 2\DataPreparation\output1\\fixed_dataset+_validate_known.xlsx")

        label = wx.StaticText(panel, label="Choose method:", pos=(10, 110))
        self.m_predictor_combobox = wx.ComboBox(panel, pos=(10, 130), size=wx.DefaultSize, choices=['stub RNN', 'stub RNN+demographic'], style=wx.CB_READONLY)

        self.m_test_button = wx.Button(panel, label="Test", pos=(10, 160), size=wx.DefaultSize)
        self.m_train_button = wx.Button(panel, label="Train", pos=(110, 160), size=wx.DefaultSize)

        label = wx.StaticText(panel, label="Prediction log:", pos=(10, 200))
        self.m_log = wx.TextCtrl(panel, pos=(10, 220), size=(360, 480), style=wx.TE_MULTILINE | wx.CB_READONLY)

        self.plot = PlotWidget(panel, pos=(400, 220), size=(10, 20))
Ejemplo n.º 4
0
 def build_screen(self, tree):
     self.remove_widget(self.loading)
     box_layout = BoxLayout(orientation="horizontal")
     splitter = Splitter(sizable_from="right")
     plot_widget = PlotWidget(tree.root)
     splitter.add_widget(FilesTreeWidget(tree, plot_widget.draw))
     box_layout.add_widget(splitter)
     box_layout.add_widget(plot_widget)
     self.add_widget(box_layout)
Ejemplo n.º 5
0
    def show_bar_plot(fig):
        """This static method show figure of the plot in anew windows """
        new_window = Toplevel(root)
        PlotWidget(new_window, fig)

        # sets the title of the
        # Toplevel widget
        new_window.title("Bar Plot")

        # sets the geometry of toplevel
        new_window.geometry("300x300")
Ejemplo n.º 6
0
    def createPlotWidget(self):
        self._mplFigure = Figure((8.0, 5.0), dpi=100)
        self._mplCanvas = FigureCanvasQTAgg(self._mplFigure)
        self._mplCanvas.installEventFilter(self._eventHandler)
        self._mplCanvas.mpl_connect('pick_event', self.onPick)
        self._mplAxes = self._mplFigure.add_subplot(1, 1, 1)
        self._plotWidget = PlotWidget()
        self._toobarMPL = NavigationToolbar2QT(self._mplCanvas, None)
        for act in self._toobarMPL.actions():
            actionName = str(act.text()).strip()
            self._mplNavigationActions[actionName] = act
        self._plotWidget.setCentralWidget(self._mplCanvas)
        self._toolbar = self._plotWidget.toolBar
        self.populateToolbar()

        self._popupMenu = QtGui.QMenu()
        self._popupMenu.addAction(self._actionLegend)

        # Connect evenement for the graphic scene
        self._mplCanvas.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self._mplCanvas.customContextMenuRequested.connect(self.onContextMenu)
        self._mplCanvas.mpl_connect('scroll_event', self.onScroll)
        self._mplCanvas.mpl_connect('button_press_event', self.onMousePress)
    def __init__(self):
        super().__init__()
        # widgets
        self.video_window=VideoWindow(PixelPermm = 314)
        self.fps=None #fps for saving
        self.xplot = PlotWidget('X displacement', label = 'X',color ='r')
        self.yplot = PlotWidget('Y displacement', label = 'Y',color ='g')
        self.zplot = PlotWidget('Z displacement', label = 'Z',color =(50, 100, 255))

        self.plot3D_widget = plot3D_widget()

        self.AnalysisWidget = AnalysisWidget()
        # controller

        self.video_saver=VideoSaver()
        self.isImageSaver=False  #True: image_saver will be chose in place of video saver

        self.csv_reader=CSV_Reader(flip_z = False)
        #----------------------------------------------------------------------
        # Toggle Comment/Uncomment to turn Z-plot ON and OFF
        #----------------------------------------------------------------------
        # VERTICAL LAYOUT ON THE LEFT
        
        v_left_layout=QtGui.QVBoxLayout()
        v_left_layout.addWidget(self.video_window)
        
        v_right_layout = QtGui.QVBoxLayout()
        v_right_layout.addWidget(self.plot3D_widget)
        # Comment/Uncomment below to remove the image analysis widget
        v_right_layout.addWidget(self.AnalysisWidget)
        # v_right_layout=QtGui.QVBoxLayout()
        # v_right_layout.addWidget(self.xplot)
        # v_right_layout.addWidget(self.yplot)
        # v_right_layout.addWidget(self.zplot)

        # v_right_layout.setStretchFactor(self.xplot,1)
        # v_right_layout.setStretchFactor(self.yplot,1)
        # v_right_layout.setStretchFactor(self.zplot,1)
        h_layout = QtGui.QHBoxLayout()
        h_layout.addLayout(v_left_layout)
#        h_layout.addLayout(v_right_layout)
        h_layout.addLayout(v_right_layout)

#        h_layout.addLayout(v_layout)
#        h_layout.addLayout(plot3D_layout)
        
        h_layout.setStretchFactor(v_left_layout,1)
#        h_layout.setStretchFactor(v_right_layout,1)
        h_layout.setStretchFactor(v_right_layout,1)
        # Final action     
#        self.setLayout(v_layout)
        self.setLayout(h_layout)
    def __init__(self, parent):
        super(QWidget, self).__init__(parent)
        self.layout = QGridLayout(self)

        # Initialize tab screen
        self.tabs = QTabWidget()
        self.tab1 = SettingsWidget(parent)
        self.tab2 = PlotWidget(parent)

        # Add tabs
        self.tabs.addTab(self.tab1, "")
        self.tabs.addTab(self.tab2, "")


        # Add tabs to widget
        self.layout.addWidget(self.tabs)
        self.setLayout(self.layout)
        self.initUI()
Ejemplo n.º 9
0
    def __init__(self):
        filename = "MainWindow.glade"
        builder = gtk.Builder()
        builder.add_from_file(filename)
        builder.connect_signals(self)

        self.window = builder.get_object("mainWindow")
        self.window.connect("destroy", self.onDeleteWindow)
        self.window.show_all()

        self.functionsVbox = builder.get_object("functionsVbox")
        self.addFunctionButton = builder.get_object("addFuncitonButton")

        self.viewParamsStatusBar = builder.get_object('viewParamsLabel')
        self.errorsStatusBar = builder.get_object('errorsLabel')

        self.eventbox1 = builder.get_object("eventbox1")
        self.plotWidget = PlotWidget()
        self.plotWidget.connect('view_updated', self.update_plotview_status_bar)
        self.plotWidget.update_view_info()
        self.plotWidget.show()
        self.eventbox1.add(self.plotWidget)
Ejemplo n.º 10
0
 def createPlotWidget(self):
   self._mplFigure = Figure((8.0,5.0), dpi=100)
   self._mplCanvas = FigureCanvasQTAgg(self._mplFigure)
   self._mplCanvas.installEventFilter(self._eventHandler)
   self._mplCanvas.mpl_connect('pick_event', self.onPick)
   self._mplAxes = self._mplFigure.add_subplot(1, 1, 1)
   self._plotWidget = PlotWidget()
   self._toobarMPL = NavigationToolbar2QT(self._mplCanvas, None) 
   for act in self._toobarMPL.actions():
     actionName = str(act.text()).strip()
     self._mplNavigationActions[actionName] = act
   self._plotWidget.setCentralWidget(self._mplCanvas)
   self._toolbar = self._plotWidget.toolBar
   self.populateToolbar()
    
   self._popupMenu = QtGui.QMenu()
   self._popupMenu.addAction(self._actionLegend)
   
   # Connect evenement for the graphic scene
   self._mplCanvas.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
   self._mplCanvas.customContextMenuRequested.connect(self.onContextMenu) 
   self._mplCanvas.mpl_connect('scroll_event', self.onScroll)
   self._mplCanvas.mpl_connect('button_press_event', self.onMousePress)
Ejemplo n.º 11
0
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(726, 588)
        self.verticalLayout = QtGui.QVBoxLayout(Form)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setMargin(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.splitter = QtGui.QSplitter(Form)
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.splitter.setObjectName("splitter")
        self.layoutWidget = QtGui.QWidget(self.splitter)
        self.layoutWidget.setObjectName("layoutWidget")
        self.gridLayout = QtGui.QGridLayout(self.layoutWidget)
        self.gridLayout.setMargin(0)
        self.gridLayout.setSpacing(0)
        self.gridLayout.setObjectName("gridLayout")
        self.graphicsView = GraphicsView(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(10)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth())
        self.graphicsView.setSizePolicy(sizePolicy)
        self.graphicsView.setObjectName("graphicsView")
        self.gridLayout.addWidget(self.graphicsView, 1, 0, 3, 1)
        self.roiBtn = QtGui.QPushButton(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.roiBtn.sizePolicy().hasHeightForWidth())
        self.roiBtn.setSizePolicy(sizePolicy)
        self.roiBtn.setMaximumSize(QtCore.QSize(30, 16777215))
        self.roiBtn.setCheckable(True)
        self.roiBtn.setObjectName("roiBtn")
        self.gridLayout.addWidget(self.roiBtn, 3, 3, 1, 1)
        self.gradientWidget = GradientWidget(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(100)
        sizePolicy.setHeightForWidth(self.gradientWidget.sizePolicy().hasHeightForWidth())
        self.gradientWidget.setSizePolicy(sizePolicy)
        self.gradientWidget.setObjectName("gradientWidget")
        self.gridLayout.addWidget(self.gradientWidget, 1, 3, 1, 1)
        self.normBtn = QtGui.QPushButton(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.normBtn.sizePolicy().hasHeightForWidth())
        self.normBtn.setSizePolicy(sizePolicy)
        self.normBtn.setMaximumSize(QtCore.QSize(30, 16777215))
        self.normBtn.setCheckable(True)
        self.normBtn.setObjectName("normBtn")
        self.gridLayout.addWidget(self.normBtn, 2, 3, 1, 1)
        self.normGroup = QtGui.QGroupBox(self.layoutWidget)
        self.normGroup.setObjectName("normGroup")
        self.gridLayout_2 = QtGui.QGridLayout(self.normGroup)
        self.gridLayout_2.setMargin(0)
        self.gridLayout_2.setSpacing(0)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.normSubtractRadio = QtGui.QRadioButton(self.normGroup)
        self.normSubtractRadio.setObjectName("normSubtractRadio")
        self.gridLayout_2.addWidget(self.normSubtractRadio, 0, 2, 1, 1)
        self.normDivideRadio = QtGui.QRadioButton(self.normGroup)
        self.normDivideRadio.setChecked(False)
        self.normDivideRadio.setObjectName("normDivideRadio")
        self.gridLayout_2.addWidget(self.normDivideRadio, 0, 1, 1, 1)
        self.label_5 = QtGui.QLabel(self.normGroup)
        font = QtGui.QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        self.gridLayout_2.addWidget(self.label_5, 0, 0, 1, 1)
        self.label_3 = QtGui.QLabel(self.normGroup)
        font = QtGui.QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.gridLayout_2.addWidget(self.label_3, 1, 0, 1, 1)
        self.label_4 = QtGui.QLabel(self.normGroup)
        font = QtGui.QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label_4.setFont(font)
        self.label_4.setObjectName("label_4")
        self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1)
        self.normROICheck = QtGui.QCheckBox(self.normGroup)
        self.normROICheck.setObjectName("normROICheck")
        self.gridLayout_2.addWidget(self.normROICheck, 1, 1, 1, 1)
        self.normXBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
        self.normXBlurSpin.setObjectName("normXBlurSpin")
        self.gridLayout_2.addWidget(self.normXBlurSpin, 2, 2, 1, 1)
        self.label_8 = QtGui.QLabel(self.normGroup)
        self.label_8.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label_8.setObjectName("label_8")
        self.gridLayout_2.addWidget(self.label_8, 2, 1, 1, 1)
        self.label_9 = QtGui.QLabel(self.normGroup)
        self.label_9.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label_9.setObjectName("label_9")
        self.gridLayout_2.addWidget(self.label_9, 2, 3, 1, 1)
        self.normYBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
        self.normYBlurSpin.setObjectName("normYBlurSpin")
        self.gridLayout_2.addWidget(self.normYBlurSpin, 2, 4, 1, 1)
        self.label_10 = QtGui.QLabel(self.normGroup)
        self.label_10.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label_10.setObjectName("label_10")
        self.gridLayout_2.addWidget(self.label_10, 2, 5, 1, 1)
        self.normOffRadio = QtGui.QRadioButton(self.normGroup)
        self.normOffRadio.setChecked(True)
        self.normOffRadio.setObjectName("normOffRadio")
        self.gridLayout_2.addWidget(self.normOffRadio, 0, 3, 1, 1)
        self.normTimeRangeCheck = QtGui.QCheckBox(self.normGroup)
        self.normTimeRangeCheck.setObjectName("normTimeRangeCheck")
        self.gridLayout_2.addWidget(self.normTimeRangeCheck, 1, 3, 1, 1)
        self.normFrameCheck = QtGui.QCheckBox(self.normGroup)
        self.normFrameCheck.setObjectName("normFrameCheck")
        self.gridLayout_2.addWidget(self.normFrameCheck, 1, 2, 1, 1)
        self.normTBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
        self.normTBlurSpin.setObjectName("normTBlurSpin")
        self.gridLayout_2.addWidget(self.normTBlurSpin, 2, 6, 1, 1)
        self.gridLayout.addWidget(self.normGroup, 0, 0, 1, 4)
        self.roiPlot = PlotWidget(self.splitter)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.roiPlot.sizePolicy().hasHeightForWidth())
        self.roiPlot.setSizePolicy(sizePolicy)
        self.roiPlot.setMinimumSize(QtCore.QSize(0, 40))
        self.roiPlot.setObjectName("roiPlot")
        self.verticalLayout.addWidget(self.splitter)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
Ejemplo n.º 12
0
class Data_Reducer(QWidget):
    """
    This widget is developed to reduce on the fly 2D SAXS data to azimuthally averaged 1D SAXS data
    """
    def __init__(self,poniFile=None,dataFile=None, darkFile=None, maskFile=None,extractedFolder='/tmp', npt=1000, transmission_corr=True, azimuthRange=(-180.0,180.0), parent=None):
        """
        poniFile is the calibration file obtained after Q-calibration
        """
        QWidget.__init__(self,parent)
        self.layout=QGridLayout(self)
        self.setup_dict=json.load(open('./SetupData/reducer_setup.txt','r'))
        if poniFile is not None:
            self.poniFile=poniFile
        else:
            self.poniFile=self.setup_dict['poniFile']
        if maskFile is not None:
            self.maskFile=maskFile
        else:
            self.maskFile=self.setup_dict['maskFile']
        self.dataFile=dataFile
        if darkFile is None:
            self.dark_corrected=False
            self.darkFile=''
        else:
            self.darkFile=darkFile
            self.dark_corrected=True
       
        self.curDir=os.getcwd()
        
        self.extractedFolder=extractedFolder
        self.npt=npt
        self.set_externally=False
        self.transmission_corr=transmission_corr        
        #ai=AIWidget()
        #self.layout.addWidget(ai)
        self.azimuthRange=azimuthRange
        self.create_UI()
        if os.path.exists(self.poniFile):
            self.openPoniFile(file=self.poniFile)
        if os.path.exists(self.maskFile):
            self.openMaskFile(file=self.maskFile)
        
        
        
        
    def create_UI(self):
        """
        Creates the widget user interface
        """
        row=0
        col=0
        dataFileLabel=QLabel('Data file')
        self.layout.addWidget(dataFileLabel,row,col)
        col+=1
        self.dataFileLineEdit=QLineEdit(self.dataFile)
        self.layout.addWidget(self.dataFileLineEdit,row,col,1,2)
        col+=2
        self.openDataPushButton=QPushButton('Select')
        self.openDataPushButton.clicked.connect(self.openDataFiles)
        self.layout.addWidget(self.openDataPushButton,row,col)
        col+=1
        self.reducePushButton=QPushButton('Reduce data')
        self.reducePushButton.clicked.connect(self.reduce_multiple)
        self.layout.addWidget(self.reducePushButton,row,col,1,1)
        
        row+=1
        col=0
        darkFileLabel=QLabel('Dark file')
        self.layout.addWidget(darkFileLabel,row,col)
        col+=1
        self.darkFileLineEdit=QLineEdit(self.darkFile)
        self.layout.addWidget(self.darkFileLineEdit,row,col,1,2)
        col+=2
        self.openDarkPushButton=QPushButton('Select')
        self.openDarkPushButton.clicked.connect(self.openDarkFile)
        self.layout.addWidget(self.openDarkPushButton,row,col)
        col+=1
        self.darkCheckBox=QCheckBox('Dark Correction')
        self.layout.addWidget(self.darkCheckBox,row,col)
        
        row+=1
        col=0
        poniFileLabel=QLabel('Calibration file')
        self.layout.addWidget(poniFileLabel,row,col)
        col+=1
        self.poniFileLineEdit=QLineEdit(self.poniFile)
        self.layout.addWidget(self.poniFileLineEdit,row,col,1,2)
        col+=2
        self.openPoniPushButton=QPushButton('Select')
        self.openPoniPushButton.clicked.connect(lambda x: self.openPoniFile(file=None))
        self.layout.addWidget(self.openPoniPushButton,row,col)
        col+=1
        self.calibratePushButton=QPushButton('Calibrate')
        self.calibratePushButton.clicked.connect(self.calibrate)
        self.layout.addWidget(self.calibratePushButton,row,col)
        
        row+=1
        col=0
        maskFileLabel=QLabel('Mask file')
        self.layout.addWidget(maskFileLabel,row,col)
        col+=1
        self.maskFileLineEdit=QLineEdit(self.maskFile)
        self.maskFileLineEdit.returnPressed.connect(self.maskFileChanged)
        self.layout.addWidget(self.maskFileLineEdit,row,col,1,2)
        col+=2
        self.openMaskPushButton=QPushButton('Select')
        self.openMaskPushButton.clicked.connect(lambda x: self.openMaskFile(file=None))
        self.layout.addWidget(self.openMaskPushButton,row,col)
        col+=1
        self.createMaskPushButton=QPushButton('Create mask')
        self.createMaskPushButton.clicked.connect(self.createMask)
        self.layout.addWidget(self.createMaskPushButton,row,col)
        
        
        row+=1
        col=0
        extractedFolderLabel=QLabel('Extracted folder')
        self.layout.addWidget(extractedFolderLabel,row,col)
        col+=1
        self.extractedFolderLineEdit=QLineEdit()
        self.layout.addWidget(self.extractedFolderLineEdit,row,col,1,2)
        col+=2
        self.extractedFolderPushButton=QPushButton('Select')
        self.extractedFolderPushButton.clicked.connect(self.openFolder)
        self.layout.addWidget(self.extractedFolderPushButton,row,col)
        
        row+=1
        col=0
        radialPointsLabel=QLabel('Radial Points')
        self.layout.addWidget(radialPointsLabel,row,col)
        col+=1
        self.radialPointsLineEdit=QLineEdit(str(self.npt))
        self.radialPointsLineEdit.returnPressed.connect(self.nptChanged)
        self.layout.addWidget(self.radialPointsLineEdit,row,col)
        col+=1
        azimuthRangeLabel=QLabel('Azimuthal Range (min:max)')
        self.layout.addWidget(azimuthRangeLabel,row,col)
        col+=1
        self.azimuthRangeLineEdit=QLineEdit('%.2f:%.2f'%(self.azimuthRange[0],self.azimuthRange[1]))
        self.azimuthRangeLineEdit.returnPressed.connect(self.azimuthRangeChanged)
        self.layout.addWidget(self.azimuthRangeLineEdit,row,col)
        col+=1
        self.transCorrCheckBox=QCheckBox('Transmission Correction')
        self.transCorrCheckBox.setTristate(False)
        self.transCorrCheckBox.setChecked(self.transmission_corr)
        self.layout.addWidget(self.transCorrCheckBox)
        
        
        row+=1
        col=0
        progressLabel=QLabel('Status')
        self.layout.addWidget(progressLabel,row,col,1,1)
        col+=1
        self.progressBar=QProgressBar()
        self.layout.addWidget(self.progressBar,row,col,1,1)
        col+=1
        self.statusLabel=QLabel('Idle')
        self.layout.addWidget(self.statusLabel,row,col,1,1)
        col+=1
        normLabel=QLabel('Normalized by')
        self.normComboBox=QComboBox()
        self.normComboBox.addItems(['BSDiode','Image sum','Monitor'])
        self.layout.addWidget(normLabel,row,col,1,1)
        col+=1
        self.layout.addWidget(self.normComboBox,row,col,1,1)
        
        row+=1
        col=0
        self.tabWidget=QTabWidget(self)
        self.layout.addWidget(self.tabWidget,row,col,20,5)
        self.imageWidget=Image_Widget(zeros((100,100)))
        imgNumberLabel=QLabel('Image number')
        self.imgNumberSpinBox=QSpinBox()
        self.imgNumberSpinBox.setSingleStep(1)
        self.imageWidget.imageLayout.addWidget(imgNumberLabel,row=2,col=1)
        self.imageWidget.imageLayout.addWidget(self.imgNumberSpinBox,row=2,col=2)
        self.imageView=self.imageWidget.imageView.getView()
        self.plotWidget=PlotWidget()
        self.plotWidget.setXLabel('Q, &#8491;<sup>-1</sup>',fontsize=5)
        self.plotWidget.setYLabel('Intensity',fontsize=5)
        self.tabWidget.addTab(self.plotWidget,'Reduced 1D-data')
        self.tabWidget.addTab(self.imageWidget,'Masked 2D-data')
       
        
        
    def createMask(self):
        """
        Opens a mask-widget to create mask file
        """
        fname=str(QFileDialog.getOpenFileName(self,'Select an image file', directory=self.curDir,filter='Image file (*.edf *.tif)')[0])
        if fname is not None or fname!='':
            img=fb.open(fname).data
            self.maskWidget=MaskWidget(img)
            self.maskWidget.saveMaskPushButton.clicked.disconnect()
            self.maskWidget.saveMaskPushButton.clicked.connect(self.save_mask)
            self.maskWidget.show()
        else:
            QMessageBox.warning(self,'File error','Please import a data file first for creating the mask',QMessageBox.Ok)
            
    def maskFileChanged(self):
        """
        Changes the mask file
        """
        maskFile=str(self.maskFileLineEdit.text())
        if str(maskFile)=='':
            self.maskFile=None
        elif os.path.exists(maskFile):
            self.maskFile=maskFile
        else:
            self.maskFile=None
            
    def save_mask(self):
        """
        Saves the entire mask combining all the shape ROIs
        """
        fname=str(QFileDialog.getSaveFileName(filter='Mask Files (*.msk)')[0])
        name,extn=os.path.splitext(fname)
        if extn=='':
            fname=name+'.msk'
        elif extn!='.msk':
            QMessageBox.warning(self,'File extension error','Please donot provide file extension other than ".msk". Thank you!')
            return
        else:
            tmpfile=fb.edfimage.EdfImage(data=self.maskWidget.full_mask_data.T,header=None)
            tmpfile.save(fname)
            self.maskFile=fname
            self.maskFileLineEdit.setText(self.maskFile)
            
    def calibrate(self):
        """
        Opens a calibartion widget to create calibration file
        """
        fname=str(QFileDialog.getOpenFileName(self,'Select calibration image',directory=self.curDir, filter='Calibration image (*.edf *.tif)')[0])
        if fname is not None:
            img=fb.open(fname).data
            pixel1=79.0
            pixel2=79.0
            self.calWidget=CalibrationWidget(img,pixel1,pixel2)
            self.calWidget.saveCalibrationPushButton.clicked.disconnect()
            self.calWidget.saveCalibrationPushButton.clicked.connect(self.save_calibration)
            self.calWidget.show()
        else:
            QMessageBox.warning(self,'File error','Please import a data file first for creating the calibration file',QMessageBox.Ok)
            
    def save_calibration(self):
        fname=str(QFileDialog.getSaveFileName(self,'Calibration file',directory=self.curDir,filter='Clibration files (*.poni)')[0])
        tfname=os.path.splitext(fname)[0]+'.poni'
        self.calWidget.applyPyFAI()
        self.calWidget.geo.save(tfname)      
        self.poniFile=tfname
        self.poniFileLineEdit.setText(self.poniFile)
        
        
    def openPoniFile(self,file=None):
        """
        Select and imports the calibration file
        """
        if file is None:
            self.poniFile=QFileDialog.getOpenFileName(self,'Select calibration file',directory=self.curDir,filter='Calibration file (*.poni)')[0]
            self.poniFileLineEdit.setText(self.poniFile)
        else:
            self.poniFile=file
        if os.path.exists(self.poniFile):
            self.setup_dict['poniFile']=self.poniFile
            json.dump(self.setup_dict,open('./SetupData/reducer_setup.txt','w'))
            fh=open(self.poniFile,'r')
            lines=fh.readlines()
            self.calib_data={}
            for line in lines:
                if line[0]!='#':
                    key,val=line.split(': ')
                    self.calib_data[key]=float(val)
            self.dist=self.calib_data['Distance']
            self.pixel1=self.calib_data['PixelSize1']
            self.pixel2=self.calib_data['PixelSize2']
            self.poni1=self.calib_data['Poni1']
            self.poni2=self.calib_data['Poni2']
            self.rot1=self.calib_data['Rot1']
            self.rot2=self.calib_data['Rot2']
            self.rot3=self.calib_data['Rot3']
            self.wavelength=self.calib_data['Wavelength']
            self.ai=AzimuthalIntegrator(dist=self.dist,poni1=self.poni1,poni2=self.poni2,pixel1=self.pixel1,pixel2=self.pixel2,rot1=self.rot1,rot2=self.rot2,rot3=self.rot3,wavelength=self.wavelength)
            #pos=[self.poni2/self.pixel2,self.poni1/self.pixel1]
            #self.roi=cake(pos,movable=False)
            #self.roi.sigRegionChangeStarted.connect(self.endAngleChanged)
            
            #self.imageView.addItem(self.roi)
        else:
            QMessageBox.warning(self,'File error','The calibration file '+self.poniFile+' doesnot exists.',QMessageBox.Ok)                
        
    def endAngleChanged(self,evt):
        print(evt.pos())
        
        
    def nptChanged(self):
        """
        Changes the number of radial points
        """
        try:
            self.npt=int(self.radialPointsLineEdit.text())
        except:
            QMessageBox.warning(self,'Value error', 'Please input positive integers only.',QMessageBox.Ok)
            
    def azimuthRangeChanged(self):
        """
        Changes the azimuth angular range
        """
        try:
            self.azimuthRange=tuple(map(float, self.azimuthRangeLineEdit.text().split(':')))
        except:
            QMessageBox.warning(self,'Value error','Please input min:max angles in floating point numbers',QMessageBox.Ok)
        
    def openDataFile(self):
        """
        Select and imports one data file
        """
        dataFile=QFileDialog.getOpenFileName(self,'Select data file',directory=self.curDir,filter='Data file (*.edf *.tif)')[0]
        if dataFile!='':
            self.dataFile=dataFile
            self.curDir=os.path.dirname(self.dataFile)
            self.dataFileLineEdit.setText(self.dataFile)
            self.data2d=fb.open(self.dataFile).data
            if self.darkFile is not None:
                self.applyDark()
            if self.maskFile is not None:
                self.applyMask()    
            self.imageWidget.setImage(self.data2d,transpose=True)
            self.tabWidget.setCurrentWidget(self.imageWidget)
            if not self.set_externally:
                self.extractedFolder=os.path.join(self.curDir,'extracted_pyFAI')
                if not os.path.exists(self.extractedFolder):
                    os.makedirs(self.extractedFolder)
                    
    def openDataFiles(self):
        """
        Selects and imports multiple data files
        """
        self.dataFiles=QFileDialog.getOpenFileNames(self,'Select data files', directory=self.curDir,filter='Data files (*.edf *.tif)')[0]
        if len(self.dataFiles)!=0:
            self.imgNumberSpinBox.valueChanged.connect(self.imageChanged)
            self.imgNumberSpinBox.setMinimum(0)
            self.imgNumberSpinBox.setMaximum(len(self.dataFiles)-1)
            self.dataFileLineEdit.setText(str(self.dataFiles))
            self.curDir=os.path.dirname(self.dataFiles[0])
            self.extractedFolder=os.path.join(self.curDir,'extracted_pyFAI')
            if not os.path.exists(self.extractedFolder):
                os.makedirs(self.extractedFolder)
            self.extractedFolderLineEdit.setText(self.extractedFolder)
            self.imgNumberSpinBox.setValue(0)
            self.imageChanged()
            
    def imageChanged(self):
        self.data2d=fb.open(self.dataFiles[self.imgNumberSpinBox.value()]).data
        if self.darkFile is not None:
            self.applyDark()
        if self.maskFile is not None:
            self.applyMask()    
        self.imageWidget.setImage(self.data2d,transpose=True)
            

                  
            
                
    def applyDark(self):
        if not self.dark_corrected and self.darkFile!='':
            self.dark2d=fb.open(self.darkFile).data
            self.data2d=self.data2d-self.dark2d
            self.dark_corrected=True
                
    def applyMask(self):
        self.mask2d=fb.open(self.maskFile).data
        self.data2d=self.data2d*(1+self.mask2d)/2.0
        self.mask_applied=True

    def openDarkFile(self):
        """
        Select and imports the dark file
        """
        self.darkFile=QFileDialog.getOpenFileName(self,'Select dark file',directory=self.curDir,filter='Dark file (*.edf)')[0]
        if self.darkFile!='':
            self.dark_corrected=False
            self.darkFileLineEdit.setText(self.darkFile)
            if self.dataFile is not None:
                self.data2d=fb.open(self.dataFile).data
                self.applyDark()
        
    
    def openMaskFile(self,file=None):
        """
        Select and imports the Mask file
        """
        if file is None:
            self.maskFile=QFileDialog.getOpenFileName(self,'Select mask file',directory=self.curDir,filter='Mask file (*.msk)')[0]
        else:
            self.maskFile=file
        if self.maskFile!='':
            self.mask_applied=False
            if os.path.exists(self.maskFile):
                self.curDir=os.path.dirname(self.maskFile)
                self.maskFileLineEdit.setText(self.maskFile)
                self.setup_dict['maskFile']=self.maskFile
                self.setup_dict['poniFile']=self.poniFile
                json.dump(self.setup_dict,open('./SetupData/reducer_setup.txt','w'))
            else:
                self.openMaskFile(file=None)
            if self.dataFile is not None:
                self.applyMask()
        else:
            self.maskFile=None
            self.maskFileLineEdit.clear()
            
            
        
    def openFolder(self):
        """
        Select the folder to save the reduce data
        """
        self.extractedFolder=QFileDialog.getExistingDirectory(self,'Select extracted directory',directory=self.curDir)
        if self.extractedFolder!='':
            self.extractedFolderLineEdit.setText(self.extractedFolder)
            self.set_externally=True
        
        
    def reduceData(self):
        """
        Reduces the 2d data to 1d data
        """
        print('Iloveu', self.darkFile)
        if (self.dataFile is not None) and (os.path.exists(self.dataFile)):
            if (self.poniFile is not None) and (os.path.exists(self.poniFile)):
#                self.statusLabel.setText('Busy')
#                self.progressBar.setRange(0, 0)
                imageData=fb.open(self.dataFile)
                #self.data2d=imageData.data
                #if self.maskFile is not None:
                #    self.applyMask()    
                #self.imageWidget.setImage(self.data2d,transpose=True)
                #self.tabWidget.setCurrentWidget(self.imageWidget)
                
                self.header=imageData.header
                try:
                    self.ai.set_wavelength(float(self.header['Wavelength'])*1e-10)
                except:
                    self.ai.set_wavelength(self.wavelength)
                print('Iloveu',self.darkFile)
                if os.path.exists(self.dataFile.split('.')[0]+'_dark.edf') and self.darkCheckBox.isChecked():
                    self.darkFile=self.dataFile.split('.')[0]+'_dark.edf'
                    dark=fb.open(self.darkFile)
                    self.darkFileLineEdit.setText(self.darkFile)
                    imageDark=dark.data                                     
                    self.header['BSDiode_corr']=max([1.0,(float(imageData.header['BSDiode'])-float(dark.header['BSDiode']))])
                    self.header['Monitor_corr']=max([1.0,(float(imageData.header['Monitor'])-float(dark.header['Monitor']))])
                    print("Dark File read from existing dark files")                    
                elif self.darkFile is not None and self.darkFile!='' and self.darkCheckBox.isChecked():
                    dark=fb.open(self.darkFile)
                    imageDark=dark.data                                     
                    self.header['BSDiode_corr']=max([1.0,(float(imageData.header['BSDiode'])-float(dark.header['BSDiode']))])
                    self.header['Monitor_corr']=max([1.0,(float(imageData.header['Monitor'])-float(dark.header['Monitor']))])
                    print("Dark File from memory subtracted")                
                else:
                    imageDark=None
                    try:
                        self.header['BSDiode_corr']=float(imageData.header['BSDiode'])
                        self.header['Monitor_corr']=float(imageData.header['Monitor'])
                    except:
                        self.transCorrCheckBox.setCheckState(Qt.Unchecked)
                    print("No dark correction done")
                if self.transCorrCheckBox.isChecked():
                    if str(self.normComboBox.currentText())=='BSDiode':
                        norm_factor=self.header['BSDiode_corr']#/float(self.header['count_time'])
                    elif str(self.normComboBox.currentText())=='Monitor':
                        norm_factor=self.header['Monitor_corr']
                    else:
                        norm_factor=sum(imageData.data)
                else:
                    norm_factor=1.0
                    
                if self.maskFile is not None:
                    imageMask=fb.open(self.maskFile).data
                else:
                    imageMask=None
                print(self.maskFile)
#                QApplication.processEvents()
                #print(self.azimuthRange)
                self.q,self.I,self.Ierr=self.ai.integrate1d(imageData.data,self.npt,error_model='poisson',mask=imageMask,dark=imageDark,unit='q_A^-1',normalization_factor=norm_factor,azimuth_range=self.azimuthRange)
                self.plotWidget.add_data(self.q,self.I,yerr=self.Ierr,name='Reduced data')
                self.plotWidget.setTitle(self.dataFile,fontsize=2)
#                self.progressBar.setRange(0,100)
#                self.progressBar.setValue(100)
#                self.statusLabel.setText('Idle')
#                QApplication.processEvents()
                self.saveData()
                self.tabWidget.setCurrentWidget(self.plotWidget)
            else:
                QMessageBox.warning(self,'Calibration File Error','Data reduction failed because either no calibration file provided or the provided file or path do not exists',QMessageBox.Ok)
                
        else:
            QMessageBox.warning(self,'Data File Error','No data file provided', QMessageBox.Ok)
            
    def reduce_multiple(self):
        """
        Reduce multiple files
        """
        #try:
        i=0
        self.progressBar.setRange(0,len(self.dataFiles))
        self.progressBar.setValue(i)
        self.statusLabel.setText('Busy')
        for file in self.dataFiles:
            self.dataFile=file
            QApplication.processEvents()
            self.reduceData()
            i=i+1
            self.progressBar.setValue(i)
            QApplication.processEvents()
        self.statusLabel.setText('Idle')
        #except:
        #    QMessageBox.warning(self,'File error','No data files to reduce',QMessageBox.Ok)
        
    def saveData(self):
        """
        saves the extracted data into a file
        """
        if not os.path.exists(self.extractedFolder):
            os.makedirs(self.extractedFolder)
        filename=os.path.join(self.extractedFolder,os.path.splitext(os.path.basename(self.dataFile))[0]+'.txt')
        headers='File extracted on '+time.asctime()+'\n'
        headers='Files used for extraction are:\n'
        headers+='Data file: '+self.dataFile+'\n'
        if self.darkFile is not None:
            headers+='Dark file: '+self.darkFile+'\n'
        else:
            headers+='Dark file: None\n'
        headers+='Poni file: '+self.poniFile+'\n'
        if self.maskFile is not None:
            headers+='mask file: '+self.maskFile+'\n'
        else:
            headers+='mask file: None\n'
        for key in self.header.keys():
            headers+=key+'='+str(self.header[key])+'\n'
        headers+='Q (A^-1)\t\tIntensity\t\tIntensity_err'
        data=vstack((self.q,self.I,self.Ierr)).T
        savetxt(filename,data,header=headers,comments='#')
Ejemplo n.º 13
0
 def create_UI(self):
     """
     Creates the widget user interface
     """
     row=0
     col=0
     dataFileLabel=QLabel('Data file')
     self.layout.addWidget(dataFileLabel,row,col)
     col+=1
     self.dataFileLineEdit=QLineEdit(self.dataFile)
     self.layout.addWidget(self.dataFileLineEdit,row,col,1,2)
     col+=2
     self.openDataPushButton=QPushButton('Select')
     self.openDataPushButton.clicked.connect(self.openDataFiles)
     self.layout.addWidget(self.openDataPushButton,row,col)
     col+=1
     self.reducePushButton=QPushButton('Reduce data')
     self.reducePushButton.clicked.connect(self.reduce_multiple)
     self.layout.addWidget(self.reducePushButton,row,col,1,1)
     
     row+=1
     col=0
     darkFileLabel=QLabel('Dark file')
     self.layout.addWidget(darkFileLabel,row,col)
     col+=1
     self.darkFileLineEdit=QLineEdit(self.darkFile)
     self.layout.addWidget(self.darkFileLineEdit,row,col,1,2)
     col+=2
     self.openDarkPushButton=QPushButton('Select')
     self.openDarkPushButton.clicked.connect(self.openDarkFile)
     self.layout.addWidget(self.openDarkPushButton,row,col)
     col+=1
     self.darkCheckBox=QCheckBox('Dark Correction')
     self.layout.addWidget(self.darkCheckBox,row,col)
     
     row+=1
     col=0
     poniFileLabel=QLabel('Calibration file')
     self.layout.addWidget(poniFileLabel,row,col)
     col+=1
     self.poniFileLineEdit=QLineEdit(self.poniFile)
     self.layout.addWidget(self.poniFileLineEdit,row,col,1,2)
     col+=2
     self.openPoniPushButton=QPushButton('Select')
     self.openPoniPushButton.clicked.connect(lambda x: self.openPoniFile(file=None))
     self.layout.addWidget(self.openPoniPushButton,row,col)
     col+=1
     self.calibratePushButton=QPushButton('Calibrate')
     self.calibratePushButton.clicked.connect(self.calibrate)
     self.layout.addWidget(self.calibratePushButton,row,col)
     
     row+=1
     col=0
     maskFileLabel=QLabel('Mask file')
     self.layout.addWidget(maskFileLabel,row,col)
     col+=1
     self.maskFileLineEdit=QLineEdit(self.maskFile)
     self.maskFileLineEdit.returnPressed.connect(self.maskFileChanged)
     self.layout.addWidget(self.maskFileLineEdit,row,col,1,2)
     col+=2
     self.openMaskPushButton=QPushButton('Select')
     self.openMaskPushButton.clicked.connect(lambda x: self.openMaskFile(file=None))
     self.layout.addWidget(self.openMaskPushButton,row,col)
     col+=1
     self.createMaskPushButton=QPushButton('Create mask')
     self.createMaskPushButton.clicked.connect(self.createMask)
     self.layout.addWidget(self.createMaskPushButton,row,col)
     
     
     row+=1
     col=0
     extractedFolderLabel=QLabel('Extracted folder')
     self.layout.addWidget(extractedFolderLabel,row,col)
     col+=1
     self.extractedFolderLineEdit=QLineEdit()
     self.layout.addWidget(self.extractedFolderLineEdit,row,col,1,2)
     col+=2
     self.extractedFolderPushButton=QPushButton('Select')
     self.extractedFolderPushButton.clicked.connect(self.openFolder)
     self.layout.addWidget(self.extractedFolderPushButton,row,col)
     
     row+=1
     col=0
     radialPointsLabel=QLabel('Radial Points')
     self.layout.addWidget(radialPointsLabel,row,col)
     col+=1
     self.radialPointsLineEdit=QLineEdit(str(self.npt))
     self.radialPointsLineEdit.returnPressed.connect(self.nptChanged)
     self.layout.addWidget(self.radialPointsLineEdit,row,col)
     col+=1
     azimuthRangeLabel=QLabel('Azimuthal Range (min:max)')
     self.layout.addWidget(azimuthRangeLabel,row,col)
     col+=1
     self.azimuthRangeLineEdit=QLineEdit('%.2f:%.2f'%(self.azimuthRange[0],self.azimuthRange[1]))
     self.azimuthRangeLineEdit.returnPressed.connect(self.azimuthRangeChanged)
     self.layout.addWidget(self.azimuthRangeLineEdit,row,col)
     col+=1
     self.transCorrCheckBox=QCheckBox('Transmission Correction')
     self.transCorrCheckBox.setTristate(False)
     self.transCorrCheckBox.setChecked(self.transmission_corr)
     self.layout.addWidget(self.transCorrCheckBox)
     
     
     row+=1
     col=0
     progressLabel=QLabel('Status')
     self.layout.addWidget(progressLabel,row,col,1,1)
     col+=1
     self.progressBar=QProgressBar()
     self.layout.addWidget(self.progressBar,row,col,1,1)
     col+=1
     self.statusLabel=QLabel('Idle')
     self.layout.addWidget(self.statusLabel,row,col,1,1)
     col+=1
     normLabel=QLabel('Normalized by')
     self.normComboBox=QComboBox()
     self.normComboBox.addItems(['BSDiode','Image sum','Monitor'])
     self.layout.addWidget(normLabel,row,col,1,1)
     col+=1
     self.layout.addWidget(self.normComboBox,row,col,1,1)
     
     row+=1
     col=0
     self.tabWidget=QTabWidget(self)
     self.layout.addWidget(self.tabWidget,row,col,20,5)
     self.imageWidget=Image_Widget(zeros((100,100)))
     imgNumberLabel=QLabel('Image number')
     self.imgNumberSpinBox=QSpinBox()
     self.imgNumberSpinBox.setSingleStep(1)
     self.imageWidget.imageLayout.addWidget(imgNumberLabel,row=2,col=1)
     self.imageWidget.imageLayout.addWidget(self.imgNumberSpinBox,row=2,col=2)
     self.imageView=self.imageWidget.imageView.getView()
     self.plotWidget=PlotWidget()
     self.plotWidget.setXLabel('Q, &#8491;<sup>-1</sup>',fontsize=5)
     self.plotWidget.setYLabel('Intensity',fontsize=5)
     self.tabWidget.addTab(self.plotWidget,'Reduced 1D-data')
     self.tabWidget.addTab(self.imageWidget,'Masked 2D-data')
Ejemplo n.º 14
0
    def __init__(self, sensor):
        QtWidgets.QMainWindow.__init__(self)  # super doesn't seem to work here
        self.setWindowTitle("MUGIC Plot")
        self.window_widget = QtWidgets.QWidget()
        self.main_layout = QtWidgets.QVBoxLayout()
        self.window_widget.setLayout(self.main_layout)
        self.setCentralWidget(self.window_widget)
        self.setMinimumSize(1500, 500)

        self.stream = sensor.stream

        # Create the plot widget to use as the central widget
        self.plot_widget = PlotWidget(sensor)
        self.main_layout.addWidget(self.plot_widget)

        # Create the control panel
        self.control_widget = QtWidgets.QWidget(self)
        self.control_layout = QtWidgets.QHBoxLayout()
        self.main_layout.addWidget(self.control_widget)
        self.control_widget.setLayout(self.control_layout)

        self.toggle_button = QtWidgets.QPushButton()
        self.toggle_button.setText("Start Recording")
        self.toggle_button.clicked.connect(self.toggle_recording)
        self.control_layout.addWidget(self.toggle_button)

        reset_button = QtWidgets.QPushButton()
        reset_button.setText("Reset")
        reset_button.clicked.connect(self.reset_recording)
        self.control_layout.addWidget(reset_button)

        export_button = QtWidgets.QPushButton()
        export_button.setText("Export")
        export_button.clicked.connect(self.export_csv)
        self.control_layout.addWidget(export_button)

        # Create the menu bar
        menu_bar = self.menuBar()
        file_menu = menu_bar.addMenu("File")
        run_menu = menu_bar.addMenu("Run")

        toggle_option = QtGui.QAction("Toggle recording", self)
        toggle_option.setShortcut("Ctrl+R")
        toggle_option.setStatusTip("Start/stop plotting data")
        toggle_option.triggered.connect(self.toggle_recording)
        run_menu.addAction(toggle_option)

        toggle_option = QtGui.QAction("Reset plots", self)
        toggle_option.setShortcut("Ctrl+Backspace")
        toggle_option.setStatusTip("Clear plotting data")
        toggle_option.triggered.connect(self.reset_recording)
        run_menu.addAction(toggle_option)

        export_option = QtGui.QAction("Export data...", self)
        export_option.setShortcut("Ctrl+S")
        export_option.setStatusTip("Export accumulated raw and processed data")
        export_option.triggered.connect(self.export_csv)
        file_menu.addAction(export_option)

        # Create the output console
        self.console = QtGui.QTextEdit()
        self.console.moveCursor(QtGui.QTextCursor.Start)
        self.console.ensureCursorVisible()
        self.main_layout.addWidget(self.console)

        # Hook up stdout to the console
        sys.stdout = TextStream()
        sys.stdout.signal.connect(self.update_text)

        # Start the plot loop
        self.timer = QtCore.QTimer()
        self.timer.timeout.connect(self.plot_widget.update)
        self.timer.start(10)
Ejemplo n.º 15
0
class XAnoS_Reducer(QWidget):
    """
    This widget is developed to reduce on the fly 2D SAXS data to azimuthally averaged 1D SAXS data
    """
    def __init__(self,poniFile=None,dataFile=None, darkFile=None, maskFile=None,extractedFolder='/tmp', npt=1000, azimuthalRange=(-180.0,180.0), parent=None):
        """
        poniFile is the calibration file obtained after Q-calibration
        """
        QWidget.__init__(self,parent)
        self.setup_dict=json.load(open('./SetupData/reducer_setup.txt','r'))
        if poniFile is not None:
            self.poniFile=poniFile
        else:
            self.poniFile=self.setup_dict['poniFile']
        if maskFile is not None:
            self.maskFile=maskFile
        else:
            self.maskFile=self.setup_dict['maskFile']
        self.dataFile=dataFile
        if darkFile is None:
            self.dark_corrected=False
            self.darkFile=''
        else:
            self.darkFile=darkFile
            self.dark_corrected=True
       
        self.curDir=os.getcwd()
        
        self.extractedBaseFolder=extractedFolder
        self.npt=npt
        self.set_externally=False
        #ai=AIWidget()
        #self.layout.addWidget(ai)
        self.azimuthalRange=azimuthalRange
        self.create_UI()
        if os.path.exists(self.poniFile):
            self.openPoniFile(file=self.poniFile)
        if os.path.exists(self.maskFile):
            self.openMaskFile(file=self.maskFile)   
        self.clientRunning=False     
        
        
    def create_UI(self):
        """
        Creates the widget user interface
        """
        loadUi('UI_Forms/Data_Reduction_Client.ui',self)
        self.poniFileLineEdit.setText(str(self.poniFile))
        self.maskFileLineEdit.setText(str(self.maskFile))
        self.darkFileLineEdit.setText(str(self.darkFile))
        self.extractedBaseFolderLineEdit.setText(self.extractedBaseFolder)
        self.radialPointsLineEdit.setText(str(self.npt))
        self.openDataPushButton.clicked.connect(self.openDataFiles)
        self.reducePushButton.clicked.connect(self.reduce_multiple)
        self.openDarkPushButton.clicked.connect(self.openDarkFile)
        self.openPoniPushButton.clicked.connect(lambda x: self.openPoniFile(file=None))
        self.calibratePushButton.clicked.connect(self.calibrate)
        self.maskFileLineEdit.returnPressed.connect(self.maskFileChanged)
        self.openMaskPushButton.clicked.connect(lambda x: self.openMaskFile(file=None))
        self.createMaskPushButton.clicked.connect(self.createMask)
        self.extractedFolderPushButton.clicked.connect(self.openFolder)
        self.extractedFolderLineEdit.textChanged.connect(self.extractedFolderChanged)
        self.polCorrComboBox.currentIndexChanged.connect(self.polarizationChanged)
        self.polarizationChanged()
        self.radialPointsLineEdit.returnPressed.connect(self.nptChanged)
        self.azimuthalRangeLineEdit.returnPressed.connect(self.azimuthalRangeChanged)
        self.azimuthalRangeChanged()
        #self.statusLabel.setStyleSheet("color:rgba(0,1,0,0)")
        self.imageWidget=Image_Widget(zeros((100,100)))
        self.cakedImageWidget=Image_Widget(zeros((100,100)))
        imgNumberLabel=QLabel('Image number')
        self.imgNumberSpinBox=QSpinBox()
        self.imgNumberSpinBox.setSingleStep(1)
        self.imageWidget.imageLayout.addWidget(imgNumberLabel,row=2,col=1)
        self.imageWidget.imageLayout.addWidget(self.imgNumberSpinBox,row=2,col=2)
        self.imageView=self.imageWidget.imageView.getView()
        self.plotWidget=PlotWidget()
        self.plotWidget.setXLabel('Q, &#8491;<sup>-1</sup>',fontsize=5)
        self.plotWidget.setYLabel('Intensity',fontsize=5)
        self.tabWidget.addTab(self.plotWidget,'Reduced 1D-data')
        self.tabWidget.addTab(self.imageWidget,'Masked 2D-data')
        self.tabWidget.addTab(self.cakedImageWidget,'Reduced Caked Data')
        
        self.serverAddress=self.serverAddressLineEdit.text()
        self.startClientPushButton.clicked.connect(self.startClient)
        self.stopClientPushButton.clicked.connect(self.stopClient)
        self.serverAddressLineEdit.returnPressed.connect(self.serverAddressChanged)
        
        self.startServerPushButton.clicked.connect(self.startServer)
        self.stopServerPushButton.clicked.connect(self.stopServer)
        
    def startServer(self):
        serverAddr=self.serverAddressLineEdit.text()
        dataDir=QFileDialog.getExistingDirectory(self,'Select data folder',options=QFileDialog.ShowDirsOnly)
        self.serverStatusLabel.setText('<font color="Red">Transmitting</font>')
        QApplication.processEvents()
        self.serverThread=QThread()
        self.zeromq_server=ZeroMQ_Server(serverAddr,dataDir)
        self.zeromq_server.moveToThread(self.serverThread)
        self.serverThread.started.connect(self.zeromq_server.loop)
        self.zeromq_server.messageEmitted.connect(self.updateServerMessage)
        self.zeromq_server.folderFinished.connect(self.serverDone)
        QTimer.singleShot(0,self.serverThread.start)

    
    def updateServerMessage(self,mesg):
        #self.serverStatusLabel.setText('<font color="Red">Transmitting</font>')
        self.serverMessageLabel.setText('Server sends: %s'%mesg)
        QApplication.processEvents()
        
    def serverDone(self):
        self.serverStatusLabel.setText('<font color="Green">Idle</font>')
        self.zeromq_server.socket.unbind(self.zeromq_server.socket.last_endpoint)
        self.serverThread.quit()
        self.serverThread.wait()
        self.serverThread.deleteLater()
        self.zeromq_server.deleteLater()
        
    def stopServer(self):
        try:
            self.zeromq_server.running=False
            self.serverStatusLabel.setText('<font color="Green">Idle</font>')
            self.zeromq_server.socket.unbind(self.zeromq_server.socket.last_endpoint)
            self.serverThread.quit()
            self.serverThread.wait()
            self.serverThread.deleteLater()
            self.zeromq_server.deleteLater()
        except:
            QMessageBox.warning(self,'Server Error','Start the server before stopping it')
        
    def enableClient(self,enable=True):
        self.startClientPushButton.setEnabled(enable)
        self.stopClientPushButton.setEnabled(enable)
        
    def enableServer(self,enable=True):
        self.startServerPushButton.setEnabled(enable)
        self.stopServerPushButton.setEnabled(enable)
        
        
    def startClient(self):
        if self.clientRunning:
            self.stopClient()
        else:
            self.clientFree=True
            self.clientRunning=True
            self.files=[]
            self.listenerThread = QThread()
            addr=self.clientAddressLineEdit.text()
            self.zeromq_listener = ZeroMQ_Listener(addr)
            self.zeromq_listener.moveToThread(self.listenerThread)
            self.listenerThread.started.connect(self.zeromq_listener.loop)
            self.zeromq_listener.messageReceived.connect(self.signal_received)
            QTimer.singleShot(0, self.listenerThread.start)
            QTimer.singleShot(0,self.clientReduce)
            self.clientStatusLabel.setText('<font color="red">Connected</font>')
            
    def stopClient(self):
        try:
            self.clientRunning=False
            self.clientFree=False
            self.zeromq_listener.messageReceived.disconnect()
            self.zeromq_listener.running=False
            self.listenerThread.quit()
            self.listenerThread.wait()
            self.listenerThread.deleteLater()
            self.zeromq_listener.deleteLater()
            self.clientStatusLabel.setText('<font color="green">Idle</font>')
        except:
            QMessageBox.warning(self,'Client Error', 'Please start the client first before closing.',QMessageBox.Ok)
        
        
    def serverAddressChanged(self):
        if self.clientRunning:
            self.startClient()
        
        
    def signal_received(self, message):
        self.clientMessageLabel.setText('Client receives: %s'%message)
        if 'dark.edf' not in message:
            self.files.append(message)
            
            
    def clientReduce(self):
        while self.clientFree:
            QApplication.processEvents()
            if len(self.files)>0:
                message=self.files[0]
                self.dataFiles=[message]
                self.dataFileLineEdit.setText(str(self.dataFiles))
                self.extractedBaseFolder=os.path.dirname(message)
                self.extractedFolder=os.path.join(self.extractedBaseFolder,self.extractedFolderLineEdit.text())
                if not os.path.exists(self.extractedFolder):
                    os.makedirs(self.extractedFolder)
                self.extractedBaseFolderLineEdit.setText(self.extractedBaseFolder)
                self.set_externally=True
                self.reduce_multiple()
                self.set_externally=False
                self.files.pop(0)
        
            
    def closeEvent(self, event):
        if self.clientRunning:
            self.stopClient()
        event.accept()
       
    def polarizationChanged(self):
        if self.polCorrComboBox.currentText()=='Horizontal':
            self.polarization_factor=1
        elif self.polCorrComboBox.currentText()=='Vertical':
            self.polarization_factor=-1
        elif self.polCorrComboBox.currentText()=='Circular':
            self.polarization_factor=0
        else:
            self.polarization_factor=None
            
    def createMask(self):
        """
        Opens a mask-widget to create mask file
        """
        fname=str(QFileDialog.getOpenFileName(self,'Select an image file', directory=self.curDir,filter='Image file (*.edf *.tif)')[0])
        if fname is not None or fname!='':
            img=fb.open(fname).data
            self.maskWidget=MaskWidget(img)
            self.maskWidget.saveMaskPushButton.clicked.disconnect()
            self.maskWidget.saveMaskPushButton.clicked.connect(self.save_mask)
            self.maskWidget.show()
        else:
            QMessageBox.warning(self,'File error','Please import a data file first for creating the mask',QMessageBox.Ok)
            
    def maskFileChanged(self):
        """
        Changes the mask file
        """
        maskFile=str(self.maskFileLineEdit.text())
        if str(maskFile)=='':
            self.maskFile=None
        elif os.path.exists(maskFile):
            self.maskFile=maskFile
        else:
            self.maskFile=None
            
    def save_mask(self):
        """
        Saves the entire mask combining all the shape ROIs
        """
        fname=str(QFileDialog.getSaveFileName(filter='Mask Files (*.msk)')[0])
        name,extn=os.path.splitext(fname)
        if extn=='':
            fname=name+'.msk'
        elif extn!='.msk':
            QMessageBox.warning(self,'File extension error','Please donot provide file extension other than ".msk". Thank you!')
            return
        else:
            tmpfile=fb.edfimage.EdfImage(data=self.maskWidget.full_mask_data.T,header=None)
            tmpfile.save(fname)
            self.maskFile=fname
            self.maskFileLineEdit.setText(self.maskFile)
            
    def calibrate(self):
        """
        Opens a calibartion widget to create calibration file
        """
        fname=str(QFileDialog.getOpenFileName(self,'Select calibration image',directory=self.curDir, filter='Calibration image (*.edf *.tif)')[0])
        if fname is not None:
            img=fb.open(fname).data
            if self.maskFile is not None:
                try:
                    mask=fb.open(self.maskFile).data
                except:
                    QMessageBox.warning(self,'Mask File Error','Cannot open %s.\n No masking will be done.'%self.maskFile)
                    mask=None
            else:
                mask=None
            pixel1=79.0
            pixel2=79.0
            self.calWidget=CalibrationWidget(img,pixel1,pixel2,mask=mask)
            self.calWidget.saveCalibrationPushButton.clicked.disconnect()
            self.calWidget.saveCalibrationPushButton.clicked.connect(self.save_calibration)
            self.calWidget.show()
        else:
            QMessageBox.warning(self,'File error','Please import a data file first for creating the calibration file',QMessageBox.Ok)
            
    def save_calibration(self):
        fname=str(QFileDialog.getSaveFileName(self,'Calibration file',directory=self.curDir,filter='Clibration files (*.poni)')[0])
        tfname=os.path.splitext(fname)[0]+'.poni'
        self.calWidget.applyPyFAI()
        self.calWidget.geo.save(tfname)      
        self.poniFile=tfname
        self.poniFileLineEdit.setText(self.poniFile)
        self.openPoniFile(file=self.poniFile)
        
    def openPoniFile(self,file=None):
        """
        Select and imports the calibration file
        """
        if file is None:
            self.poniFile=QFileDialog.getOpenFileName(self,'Select calibration file',directory=self.curDir,filter='Calibration file (*.poni)')[0]
            self.poniFileLineEdit.setText(self.poniFile)
        else:
            self.poniFile=file
        if os.path.exists(self.poniFile):
            self.setup_dict['poniFile']=self.poniFile
            json.dump(self.setup_dict,open('./SetupData/reducer_setup.txt','w'))
            fh=open(self.poniFile,'r')
            lines=fh.readlines()
            self.calib_data={}
            for line in lines:
                if line[0]!='#':
                    key,val=line.split(': ')
                    self.calib_data[key]=float(val)
            self.dist=self.calib_data['Distance']
            self.pixel1=self.calib_data['PixelSize1']
            self.pixel2=self.calib_data['PixelSize2']
            self.poni1=self.calib_data['Poni1']
            self.poni2=self.calib_data['Poni2']
            self.rot1=self.calib_data['Rot1']
            self.rot2=self.calib_data['Rot2']
            self.rot3=self.calib_data['Rot3']
            self.wavelength=self.calib_data['Wavelength']
            self.ai=AzimuthalIntegrator(dist=self.dist,poni1=self.poni1,poni2=self.poni2,pixel1=self.pixel1,pixel2=self.pixel2,rot1=self.rot1,rot2=self.rot2,rot3=self.rot3,wavelength=self.wavelength)
            #pos=[self.poni2/self.pixel2,self.poni1/self.pixel1]
            #self.roi=cake(pos,movable=False)
            #self.roi.sigRegionChangeStarted.connect(self.endAngleChanged)
            
            #self.imageView.addItem(self.roi)
        else:
            QMessageBox.warning(self,'File error','The calibration file '+self.poniFile+' doesnot exists.',QMessageBox.Ok)                
        
    def endAngleChanged(self,evt):
        print(evt.pos())
        
        
    def nptChanged(self):
        """
        Changes the number of radial points
        """
        try:
            self.npt=int(self.radialPointsLineEdit.text())
        except:
            QMessageBox.warning(self,'Value error', 'Please input positive integers only.',QMessageBox.Ok)
            
    def azimuthalRangeChanged(self):
        """
        Changes the azimuth angular range
        """
        try:
            self.azimuthalRange=tuple(map(float, self.azimuthalRangeLineEdit.text().split(':')))
        except:
            QMessageBox.warning(self,'Value error','Please input min:max angles in floating point numbers',QMessageBox.Ok)
        
    def openDataFile(self):
        """
        Select and imports one data file
        """
        dataFile=QFileDialog.getOpenFileName(self,'Select data file',directory=self.curDir,filter='Data file (*.edf *.tif)')[0]
        if dataFile!='':
            self.dataFile=dataFile
            self.curDir=os.path.dirname(self.dataFile)
            self.dataFileLineEdit.setText(self.dataFile)
            self.data2d=fb.open(self.dataFile).data
            if self.darkFile is not None:
                self.applyDark()
            if self.maskFile is not None:
                self.applyMask()    
            self.imageWidget.setImage(self.data2d,transpose=True)
            self.tabWidget.setCurrentWidget(self.imageWidget)
            if not self.set_externally:
                self.extractedFolder=os.path.join(self.curDir,self.extractedFolderLineEdit.text())
                if not os.path.exists(self.extractedFolder):
                    os.makedirs(self.extractedFolder)
                    
    def openDataFiles(self):
        """
        Selects and imports multiple data files
        """
        self.dataFiles=QFileDialog.getOpenFileNames(self,'Select data files', directory=self.curDir,filter='Data files (*.edf *.tif)')[0]
        if len(self.dataFiles)!=0:
            self.imgNumberSpinBox.valueChanged.connect(self.imageChanged)
            self.imgNumberSpinBox.setMinimum(0)
            self.imgNumberSpinBox.setMaximum(len(self.dataFiles)-1)
            self.dataFileLineEdit.setText(str(self.dataFiles))
            self.curDir=os.path.dirname(self.dataFiles[0])
            self.extractedBaseFolder=self.curDir
            self.extractedFolder=os.path.abspath(os.path.join(self.extractedBaseFolder,self.extractedFolderLineEdit.text()))
            if not os.path.exists(self.extractedFolder):
                os.makedirs(self.extractedFolder)
            self.extractedBaseFolderLineEdit.setText(self.extractedBaseFolder)
            self.imgNumberSpinBox.setValue(0)
            self.imageChanged()
            
    def imageChanged(self):
        self.data2d=fb.open(self.dataFiles[self.imgNumberSpinBox.value()]).data
        if self.darkFile is not None:
            self.applyDark()
        if self.maskFile is not None:
            self.applyMask()    
        self.imageWidget.setImage(self.data2d,transpose=True)
            

                  
            
                
    def applyDark(self):
        if not self.dark_corrected and self.darkFile!='':
            self.dark2d=fb.open(self.darkFile).data
            self.data2d=self.data2d-self.dark2d
            self.dark_corrected=True
                
    def applyMask(self):
        self.mask2d=fb.open(self.maskFile).data
        self.data2d=self.data2d*(1+self.mask2d)/2.0
        self.mask_applied=True

    def openDarkFile(self):
        """
        Select and imports the dark file
        """
        self.darkFile=QFileDialog.getOpenFileName(self,'Select dark file',directory=self.curDir,filter='Dark file (*.edf)')[0]
        if self.darkFile!='':
            self.dark_corrected=False
            self.darkFileLineEdit.setText(self.darkFile)
            if self.dataFile is not None:
                self.data2d=fb.open(self.dataFile).data
                self.applyDark()
        
    
    def openMaskFile(self,file=None):
        """
        Select and imports the Mask file
        """
        if file is None:
            self.maskFile=QFileDialog.getOpenFileName(self,'Select mask file',directory=self.curDir,filter='Mask file (*.msk)')[0]
        else:
            self.maskFile=file
        if self.maskFile!='':
            self.mask_applied=False
            if os.path.exists(self.maskFile):
                self.curDir=os.path.dirname(self.maskFile)
                self.maskFileLineEdit.setText(self.maskFile)
                self.setup_dict['maskFile']=self.maskFile
                self.setup_dict['poniFile']=self.poniFile
                json.dump(self.setup_dict,open('./SetupData/reducer_setup.txt','w'))
            else:
                self.openMaskFile(file=None)
            if self.dataFile is not None:
                self.applyMask()
        else:
            self.maskFile=None
            self.maskFileLineEdit.clear()
            
            
        
    def openFolder(self):
        """
        Select the folder to save the reduce data
        """
        oldfolder=self.extractedBaseFolder.text()
        folder=QFileDialog.getExistingDirectory(self,'Select extracted directory',directory=self.curDir)
        if folder!='':
            self.extractedBaseFolder=folder
            self.extractedBaseFolderLineEdit.setText(folder)
            self.extractedFolder=os.path.join(folder,self.extractedFolderLineEdit.text())
            self.set_externally=True
        else:
            self.extractedBaseFolder=oldfolder
            self.extractedBaseFolderLineEdit.setText(oldfolder)
            self.extractedFolder = os.path.join(oldfolder, self.extractedFolderLineEdit.text())
            self.set_externally = True


    def extractedFolderChanged(self,txt):
        self.extractedFolder=os.path.join(self.extractedBaseFolder,txt)
        self.set_externally=True

        
        
    def reduceData(self):
        """
        Reduces the 2d data to 1d data
        """
        if (self.dataFile is not None) and (os.path.exists(self.dataFile)):
            if (self.poniFile is not None) and (os.path.exists(self.poniFile)):
#                self.statusLabel.setText('Busy')
#                self.progressBar.setRange(0, 0)
                imageData=fb.open(self.dataFile)
                #self.data2d=imageData.data
                #if self.maskFile is not None:
                #    self.applyMask()    
                #self.imageWidget.setImage(self.data2d,transpose=True)
                #self.tabWidget.setCurrentWidget(self.imageWidget)
                
                self.header=imageData.header
                try:
                    self.ai.set_wavelength(float(self.header['Wavelength'])*1e-10)
                except:
                    self.ai.set_wavelength(self.wavelength)
                #print(self.darkFile)
                if os.path.exists(self.dataFile.split('.')[0]+'_dark.edf') and self.darkCheckBox.isChecked():
                    self.darkFile=self.dataFile.split('.')[0]+'_dark.edf'
                    dark=fb.open(self.darkFile)
                    self.darkFileLineEdit.setText(self.darkFile)
                    imageDark=dark.data                                     
                    self.header['BSDiode_corr']=max([1.0,(float(imageData.header['BSDiode'])-float(dark.header['BSDiode']))])
                    self.header['Monitor_corr']=max([1.0,(float(imageData.header['Monitor'])-float(dark.header['Monitor']))])
                    print("Dark File read from existing dark files")                    
                elif self.darkFile is not None and self.darkFile!='' and self.darkCheckBox.isChecked():
                    dark=fb.open(self.darkFile)
                    imageDark=dark.data                                     
                    self.header['BSDiode_corr']=max([1.0,(float(imageData.header['BSDiode'])-float(dark.header['BSDiode']))])
                    self.header['Monitor_corr']=max([1.0,(float(imageData.header['Monitor'])-float(dark.header['Monitor']))])
                    print("Dark File from memory subtracted")                
                else:
                    imageDark=None
                    try:
                        self.header['BSDiode_corr']=float(imageData.header['BSDiode'])
                        self.header['Monitor_corr']=float(imageData.header['Monitor'])
                        self.header['Transmission'] = float(imageData.header['Transmission'])
                    except:
                        self.normComboBox.setCurrentText('None')
                    print("No dark correction done")
                if str(self.normComboBox.currentText())=='BSDiode':
                    norm_factor=self.header['BSDiode_corr']#/self.header['Monitor_corr']#float(self.header[
                    # 'count_time'])
                elif str(self.normComboBox.currentText())=='TransDiode':
                    norm_factor=self.header['Transmission']*self.header['Monitor_corr']
                elif str(self.normComboBox.currentText())=='Monitor':
                    norm_factor=self.header['Monitor_corr']
                elif str(self.normComboBox.currentText())=='Image Sum':
                    norm_factor=sum(imageData.data)
                else:
                    norm_factor=1.0
                    
                if self.maskFile is not None:
                    imageMask=fb.open(self.maskFile).data
                else:
                    imageMask=None
#                QApplication.processEvents()
                #print(self.azimuthalRange)
                self.q,self.I,self.Ierr=self.ai.integrate1d(imageData.data,self.npt,error_model='poisson',mask=imageMask,dark=imageDark,unit='q_A^-1',normalization_factor=norm_factor,azimuth_range=self.azimuthalRange,polarization_factor=self.polarization_factor)
                self.plotWidget.add_data(self.q,self.I,yerr=self.Ierr,name='Reduced data')
                if not self.set_externally:
                    cakedI,qr,phir=self.ai.integrate2d(imageData.data,self.npt,mask=imageMask,dark=imageDark,unit='q_A^-1',normalization_factor=norm_factor,polarization_factor=self.polarization_factor)
                    self.cakedImageWidget.setImage(cakedI,xmin=qr[0],xmax=qr[-1],ymin=phir[0],ymax=phir[-1],transpose=True,xlabel='Q ', ylabel='phi ',unit=['&#8491;<sup>-1</sup>','degree'])
                    self.cakedImageWidget.imageView.view.setAspectLocked(False)
                    try:
                        self.azimuthalRegion.setRegion(self.azimuthalRange)
                    except:
                        self.azimuthalRegion=pg.LinearRegionItem(values=self.azimuthalRange,orientation=pg.LinearRegionItem.Horizontal,movable=True,bounds=[-180,180])
                        self.cakedImageWidget.imageView.getView().addItem(self.azimuthalRegion)
                        self.azimuthalRegion.sigRegionChanged.connect(self.azimuthalRegionChanged)
                self.plotWidget.setTitle(self.dataFile,fontsize=3)
#                self.progressBar.setRange(0,100)
#                self.progressBar.setValue(100)
#                self.statusLabel.setText('Idle')
#                QApplication.processEvents()
                self.saveData()
                #self.tabWidget.setCurrentWidget(self.plotWidget)
            else:
                QMessageBox.warning(self,'Calibration File Error','Data reduction failed because either no calibration file provided or the provided file or path do not exists',QMessageBox.Ok)
                
        else:
            QMessageBox.warning(self,'Data File Error','No data file provided', QMessageBox.Ok)
            
    def azimuthalRegionChanged(self):
        minp,maxp=self.azimuthalRegion.getRegion()
        self.azimuthalRangeLineEdit.setText('%.1f:%.1f'%(minp,maxp))
        self.azimuthalRange=[minp,maxp]
        self.set_externally=True
        
        
            
    def reduce_multiple(self):
        """
        Reduce multiple files
        """
        try:
            i=0
            self.progressBar.setRange(0,len(self.dataFiles))
            self.progressBar.setValue(i)
            self.statusLabel.setText('<font color="red">Busy</font>')
            for file in self.dataFiles:
                self.dataFile=file
                QApplication.processEvents()
                self.reduceData()
                i=i+1
                self.progressBar.setValue(i)
                QApplication.processEvents()
            self.statusLabel.setText('<font color="green">Idle</font>')
            self.progressBar.setValue(0)
        except:
            QMessageBox.warning(self,'File error','No data files to reduce',QMessageBox.Ok)
        
    def saveData(self):
        """
        saves the extracted data into a file
        """
        if not os.path.exists(self.extractedFolder):
            os.makedirs(self.extractedFolder)
        filename=os.path.join(self.extractedFolder,os.path.splitext(os.path.basename(self.dataFile))[0]+'.txt')
        headers='File extracted on '+time.asctime()+'\n'
        headers='Files used for extraction are:\n'
        headers+='Data file: '+self.dataFile+'\n'
        if self.darkFile is not None:
            headers+='Dark file: '+self.darkFile+'\n'
        else:
            headers+='Dark file: None\n'
        headers+='Poni file: '+self.poniFile+'\n'
        if self.maskFile is not None:
            headers+='mask file: '+self.maskFile+'\n'
        else:
            headers+='mask file: None\n'
        for key in self.header.keys():
            headers+=key+'='+str(self.header[key])+'\n'
        headers+="col_names=['Q (inv Angs)','Int','Int_err']\n"
        headers+='Q (inv Angs)\tInt\tInt_err'
        data=vstack((self.q,self.I,self.Ierr)).T
        savetxt(filename,data,header=headers,comments='#')
Ejemplo n.º 16
0
class View(wx.Frame):

    def __init__(self):
        self.app = wx.App(False)

        wx.Frame.__init__(self, None, title="Nocturnal hypoglycemia prediction", size=(1100, 800))
        panel = wx.Panel(self)

        menu = wx.Menu()
        about = menu.Append(wx.ID_ABOUT, "&About", "Information about this program")
        self.Bind(wx.EVT_MENU, lambda x: self.OnAbout(), about)

        menuBar = wx.MenuBar()
        menuBar.Append(menu, "&Help")
        self.SetMenuBar(menuBar)

        label = wx.StaticText(panel, label="Train dataset path:", pos=(10, 10))
        self.m_train_dataset_path_edit = wx.TextCtrl(panel, pos=(10, 30), size=(800, 20))
        self.m_train_dataset_path_edit.SetValue(u"D:\GDrive\Диплом 2\DataPreparation\output1\\fixed_dataset+_train.xlsx")

        label = wx.StaticText(panel, label="Test dataset path:", pos=(10, 60))
        self.m_test_dataset_path_edit = wx.TextCtrl(panel, pos=(10, 80), size=(800, 20))
        self.m_test_dataset_path_edit.SetValue(u"D:\GDrive\Диплом 2\DataPreparation\output1\\fixed_dataset+_validate_known.xlsx")

        label = wx.StaticText(panel, label="Choose method:", pos=(10, 110))
        self.m_predictor_combobox = wx.ComboBox(panel, pos=(10, 130), size=wx.DefaultSize, choices=['stub RNN', 'stub RNN+demographic'], style=wx.CB_READONLY)

        self.m_test_button = wx.Button(panel, label="Test", pos=(10, 160), size=wx.DefaultSize)
        self.m_train_button = wx.Button(panel, label="Train", pos=(110, 160), size=wx.DefaultSize)

        label = wx.StaticText(panel, label="Prediction log:", pos=(10, 200))
        self.m_log = wx.TextCtrl(panel, pos=(10, 220), size=(360, 480), style=wx.TE_MULTILINE | wx.CB_READONLY)

        self.plot = PlotWidget(panel, pos=(400, 220), size=(10, 20))

    def OnAbout(self):
        dlg = View.AboutBox()
        dlg.ShowModal()
        dlg.Destroy()

    # Custom bindings
    def SetOnTestAction(self, on_test_action):
        self.Bind(wx.EVT_BUTTON, lambda x: on_test_action(), self.m_test_button)

    def SetOnTrainAction(self, on_train_action):
        self.Bind(wx.EVT_BUTTON, lambda x: on_train_action(), self.m_train_button)

    # Custom functions
    def UpdateMethodList(self, i_method_list):
        self.m_predictor_combobox.Clear()
        for method in i_method_list:
            self.m_predictor_combobox.Append(method)
        self.m_predictor_combobox.SetSize((200, -1))

    def GetSelectedMethodName(self):
        return self.m_predictor_combobox.GetValue()

    def GetTrainDataPath(self):
        return self.m_train_dataset_path_edit.GetValue()

    def GetTestDataPath(self):
        return self.m_test_dataset_path_edit.GetValue()

    def PrintToLog(self, i_text):
        self.m_log.AppendText('[' + datetime.now().strftime('%Y-%m-%d %H:%M:%S') + '] ' + i_text + '\n')

    def PlotGraph(self, x_arr, y_arr, col):
        self.plot.draw(x_arr, y_arr, col)

    def ClearGraph(self):
        self.plot.clear()

    class AboutBox(wx.Dialog):

        aboutText = "\nThis application is a part of Master's Thesis \"Prediction of nocturnal hypoglycemia in patients with typr 1 diabetes using mrthods based on decision tree and methods based on neural networks\"\n" \
                    "\nAuthors: Dmytro Yurchenko and Serhii Sakharov\n" \
                    "\nKyiv Polytechnic Institute, Department of Applied Math, 2016"

        def __init__(self):
            wx.Dialog.__init__(self, None, -1, "About Nocturnal hypoglycemia prediction", style=wx.DEFAULT_DIALOG_STYLE|wx.THICK_FRAME|wx.RESIZE_BORDER|wx.TAB_TRAVERSAL)
            hwin = wx.StaticText(self, label=View.AboutBox.aboutText, size=(400,200))
            self.CentreOnParent(wx.BOTH)
            self.SetFocus()

    # Run (all settings must be done before this function run)
    def Run(self):
        self.Show(True)
        self.app.MainLoop()
Ejemplo n.º 17
0
Archivo: UI.py Proyecto: wkoder/mooi
    def _buildUI(self):
        self.setWindowTitle("MOOI: Multi-Objective Optimization Interface")
        self.resize(840, 480)
        self.statusBar().setSizeGripEnabled(False)
        self.statusBar().showMessage("Loading initial data...")

        # Plot widget
        self.plot = PlotWidget()
        self.plot.setMinimumSize(320, 480)
        self.plot.setAlignment(Qt.AlignCenter)
        self.plot.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.plot)

        # Function widget
        self.functionWidget = QListWidget()
        self.functionWidget.itemSelectionChanged.connect(self.solutionSelected)
        rightDock = QDockWidget("Functions", self)
        rightDock.setObjectName("Functions")
        rightDock.setWidget(self.functionWidget)
        rightDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.RightDockWidgetArea, rightDock)

        # Control widget
        self.showSolutionsRadio = QRadioButton("Functions")
        self.showSolutionsRadio.setChecked(True)
        self.showSolutionsRadio.toggled.connect(self._showSolution)
        self.showVariablesRadio = QRadioButton("Variables")

        radioWidget = QWidget()
        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.showSolutionsRadio)
        radioLayout.addWidget(self.showVariablesRadio)
        radioWidget.setLayout(radioLayout)

        self.generationLabel = QLabel("Run: 1")
        self.generationSlider = QSlider(Qt.Horizontal)
        self.generationSlider.setTickPosition(QSlider.TicksBothSides)
        self.generationSlider.setTracking(True)
        self.generationSlider.setMinimum(1)
        self.generationSlider.setMaximum(1)
        self.generationSlider.setTickInterval(1)
        self.generationSlider.valueChanged.connect(self._showSolution)

        self.solutionSelector = QWidget()
        self.solutionSelector.setLayout(QVBoxLayout())
        addSolutionButton = QPushButton("Add")
        addSolutionButton.clicked.connect(self.addImplementation)
        removeSolutionButton = QPushButton("Remove unselected")
        removeSolutionButton.clicked.connect(self.removeResult)
        solutionSelectorButtons = QWidget()
        solutionSelectorButtons.setLayout(QHBoxLayout())
        solutionSelectorButtons.layout().addWidget(addSolutionButton)
        solutionSelectorButtons.layout().addWidget(removeSolutionButton)
        self.solutionSelectorWidget = QWidget()
        self.solutionSelectorWidget.setLayout(QVBoxLayout())
        self.solutionSelectorWidget.layout().addWidget(solutionSelectorButtons)
        self.solutionSelectorWidget.layout().addWidget(self.solutionSelector)

        exportButton = QPushButton("Export image")
        exportButton.clicked.connect(self.exportImage)

        exportAllButton = QPushButton("Export all images")
        exportAllButton.clicked.connect(self.exportAllImages)

        computeMetricsButton = QPushButton("Compute metrics")
        computeMetricsButton.clicked.connect(self.computeMetricsAsync)

        refreshButton = QPushButton("Refresh")
        refreshButton.clicked.connect(self.updateUI)

        controlLayout = QVBoxLayout()
        controlLayout.addWidget(radioWidget)
        controlLayout.addWidget(self.generationLabel)
        controlLayout.addWidget(self.generationSlider)
        controlLayout.addWidget(self.solutionSelectorWidget)
        controlLayout.addStretch()
        controlLayout.addWidget(computeMetricsButton)
        controlLayout.addWidget(refreshButton)
        controlLayout.addWidget(exportButton)
        controlLayout.addWidget(exportAllButton)
        controlWidget = QWidget()
        controlWidget.setLayout(controlLayout)
        leftDock = QDockWidget("Control", self)
        leftDock.setObjectName("Control")
        leftDock.setWidget(controlWidget)
        leftDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, leftDock)

        # Metric widget
        self.metrics = MetricsPanel(self.analyzer)
        bottomDock = QDockWidget("Metrics", self)
        bottomDock.setObjectName("Metrics")
        bottomDock.setWidget(self.metrics)
        bottomDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.BottomDockWidgetArea, bottomDock)

        # Actions
        exitAction = QAction("&Exit", self)
        exitAction.setShortcut("Ctrl+Q")
        exitAction.setStatusTip("Exit application")
        exitAction.triggered.connect(qApp.quit)

        copyAction = QAction("&Copy", self)
        copyAction.setShortcut("Ctrl+C")
        copyAction.setStatusTip("Copy metrics")
        copyAction.triggered.connect(self.metrics.copyMetrics)

        aboutAction = QAction("&About", self)
        aboutAction.setStatusTip("About MOOI")
        aboutAction.triggered.connect(self.helpAbout)

        # Menus
        menubar = self.menuBar()
        fileMenu = menubar.addMenu("&File")
        fileMenu.addAction(copyAction)
        fileMenu.addAction(aboutAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)
Ejemplo n.º 18
0
class MainWindow(QMainWindow):

    __PREF_GEOM__ = "UI/Geometry"
    __PREF_STATE__ = "UI/State"
    __PREF_DIR__ = "Config/Directories"
    __PREF_SAVE__ = "Config/SaveDirectory"
    __PREF_SAVE_ALL__ = "Config/SaveAllDirectory"

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.analyzer = Analyzer()
        self.currentSolution = None

        self._buildUI()
        self._loadSettings()
        QTimer.singleShot(0, self._loadInitialData)

    def _buildUI(self):
        self.setWindowTitle("MOOI: Multi-Objective Optimization Interface")
        self.resize(840, 480)
        self.statusBar().setSizeGripEnabled(False)
        self.statusBar().showMessage("Loading initial data...")

        # Plot widget
        self.plot = PlotWidget()
        self.plot.setMinimumSize(320, 480)
        self.plot.setAlignment(Qt.AlignCenter)
        self.plot.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.plot)

        # Function widget
        self.functionWidget = QListWidget()
        self.functionWidget.itemSelectionChanged.connect(self.solutionSelected)
        rightDock = QDockWidget("Functions", self)
        rightDock.setObjectName("Functions")
        rightDock.setWidget(self.functionWidget)
        rightDock.setFeatures(QDockWidget.DockWidgetFloatable
                              | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.RightDockWidgetArea, rightDock)

        # Control widget
        self.showSolutionsRadio = QRadioButton("Functions")
        self.showSolutionsRadio.setChecked(True)
        self.showSolutionsRadio.toggled.connect(self._showSolution)
        self.showVariablesRadio = QRadioButton("Variables")

        radioWidget = QWidget()
        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.showSolutionsRadio)
        radioLayout.addWidget(self.showVariablesRadio)
        radioWidget.setLayout(radioLayout)

        self.generationLabel = QLabel("Run: 1")
        self.generationSlider = QSlider(Qt.Horizontal)
        self.generationSlider.setTickPosition(QSlider.TicksBothSides)
        self.generationSlider.setTracking(True)
        self.generationSlider.setMinimum(1)
        self.generationSlider.setMaximum(1)
        self.generationSlider.setTickInterval(1)
        self.generationSlider.valueChanged.connect(self._showSolution)

        self.solutionSelector = QWidget()
        self.solutionSelector.setLayout(QVBoxLayout())
        addSolutionButton = QPushButton("Add")
        addSolutionButton.clicked.connect(self.addImplementation)
        removeSolutionButton = QPushButton("Remove unselected")
        removeSolutionButton.clicked.connect(self.removeResult)
        solutionSelectorButtons = QWidget()
        solutionSelectorButtons.setLayout(QHBoxLayout())
        solutionSelectorButtons.layout().addWidget(addSolutionButton)
        solutionSelectorButtons.layout().addWidget(removeSolutionButton)
        self.solutionSelectorWidget = QWidget()
        self.solutionSelectorWidget.setLayout(QVBoxLayout())
        self.solutionSelectorWidget.layout().addWidget(solutionSelectorButtons)
        self.solutionSelectorWidget.layout().addWidget(self.solutionSelector)

        exportButton = QPushButton("Export image")
        exportButton.clicked.connect(self.exportImage)

        exportAllButton = QPushButton("Export all images")
        exportAllButton.clicked.connect(self.exportAllImages)

        computeMetricsButton = QPushButton("Compute metrics")
        computeMetricsButton.clicked.connect(self.computeMetricsAsync)

        refreshButton = QPushButton("Refresh")
        refreshButton.clicked.connect(self.updateUI)

        controlLayout = QVBoxLayout()
        controlLayout.addWidget(radioWidget)
        controlLayout.addWidget(self.generationLabel)
        controlLayout.addWidget(self.generationSlider)
        controlLayout.addWidget(self.solutionSelectorWidget)
        controlLayout.addStretch()
        controlLayout.addWidget(computeMetricsButton)
        controlLayout.addWidget(refreshButton)
        controlLayout.addWidget(exportButton)
        controlLayout.addWidget(exportAllButton)
        controlWidget = QWidget()
        controlWidget.setLayout(controlLayout)
        leftDock = QDockWidget("Control", self)
        leftDock.setObjectName("Control")
        leftDock.setWidget(controlWidget)
        leftDock.setFeatures(QDockWidget.DockWidgetFloatable
                             | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, leftDock)

        # Metric widget
        self.metrics = MetricsPanel(self.analyzer)
        bottomDock = QDockWidget("Metrics", self)
        bottomDock.setObjectName("Metrics")
        bottomDock.setWidget(self.metrics)
        bottomDock.setFeatures(QDockWidget.DockWidgetFloatable
                               | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.BottomDockWidgetArea, bottomDock)

        # Actions
        exitAction = QAction('&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(qApp.quit)

        copyAction = QAction("&Copy", self)
        copyAction.setShortcut("Ctrl+C")
        copyAction.setStatusTip('Copy metrics')
        copyAction.triggered.connect(self.metrics.copyMetrics)

        aboutAction = QAction("&About", self)
        aboutAction.setStatusTip('About MOOI')
        aboutAction.triggered.connect(self.helpAbout)

        # Menus
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(copyAction)
        fileMenu.addAction(aboutAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

    def _loadSettings(self):
        settings = QSettings()
        self.restoreState(
            settings.value(MainWindow.__PREF_STATE__).toByteArray())
        self.restoreGeometry(
            settings.value(MainWindow.__PREF_GEOM__).toByteArray())

        paretoDirectory = __RESOURCES_DIR__ + Analyzer.__PARETO__
        self.analyzer.setPareto(paretoDirectory)
        currentDirs = settings.value(MainWindow.__PREF_DIR__)
        if currentDirs is not None:
            self.analyzer.setResultDirectories(
                [directory.toString() for directory in currentDirs.toList()])

        self._updateSolutionSelection()

    def exportImage(self):
        settings = QSettings()
        filename = settings.value(MainWindow.__PREF_SAVE__)
        if filename is None:
            filename = os.path.dirname(__file__)
        else:
            filename = os.path.abspath(
                os.path.join(str(filename.toString()), os.path.pardir)) + "/"
        filename += "%s_%s.png" % (self.currentSolution.functionName, "fun" if
                                   self.isFunctionSpaceSelected() else "var")

        filename = QFileDialog.getSaveFileName(self, "Export image as",
                                               filename, ("PNG image (*.png)"))
        if filename is None or filename == "":
            return

        settings.setValue(MainWindow.__PREF_SAVE__, QVariant(filename))
        self._exportCurrentImage(filename)
        self.statusBar().showMessage("Image saved!", 5000)

    def isFunctionSpaceSelected(self):
        return self.showSolutionsRadio.isChecked()

    def _exportCurrentImage(self, filename=None):
        generation = self.generationSlider.value()
        self.generationLabel.setText("Run: %d" % generation)

        tmp = filename is None
        if tmp:
            prefix = "mooi_%s_" % self.currentSolution.functionName
            filename = tempfile.mkstemp(prefix=prefix,
                                        suffix=".png",
                                        text=False)[1]
        resultNames = self._getSelectedResultNames()
        self.analyzer.exportToImage(self.currentSolution, [generation-1]*len(resultNames), self.isFunctionSpaceSelected(), \
                                    resultNames, str(filename))
        if tmp:
            self.plot.setPlotPixmap(filename)
            try:
                os.remove(filename)
            except:
                print >> sys.stderr, "Couldn't delete temporal file: %s" % filename

    def _getSelectedResultNames(self):
        resultNames = []
        for i in xrange(self.analyzer.nResults):
            implementationItem = self.solutionSelector.layout().itemAt(
                i).widget()
            if implementationItem.isChecked():
                resultNames.append(str(implementationItem.text()))
        return resultNames

    def exportAllImages(self):
        settings = QSettings()
        directory = settings.value(MainWindow.__PREF_SAVE_ALL__).toString()
        directory = QFileDialog.getExistingDirectory(
            self, "Select a directory to export to", directory)
        if directory is None or not os.path.exists(directory):
            return

        self.analyzer.exportAllImages(directory,
                                      self._getSelectedResultNames())
        settings.setValue(MainWindow.__PREF_SAVEL_ALL__, QVariant(directory))
        self.statusBar().showMessage("Images saved!", 5000)

    def computeMetricsAsync(self):
        self.statusBar().showMessage("Computing metrics...")
        QTimer.singleShot(0, self.computeMetrics)

    def computeMetrics(self):
        self._computeMetrics(self.currentSolution.functionName)
        self.statusBar().showMessage("Metrics computed!", 5000)

    def _computeMetrics(self, functionName):
        pareto = self.analyzer.getFunctionPareto(functionName)
        solutions = self.analyzer.getFunctionResults(
            functionName, self._getSelectedResultNames())
        self.metrics.updateMetrics(pareto, solutions, functionName)

    def helpAbout(self):
        QMessageBox.about(
            self, "About Image Changer",
            """<b>Multi-Objective Optimization Interface</b> v%s
            <p>Copyright &copy; 2011-2012 %s All rights reserved.
            <p>This application can be used to perform simple optimization analysis.
            <p><a href='%s'>%s</a>
            <p>Python %s - Qt %s - PyQt %s on %s""" %
            (__VERSION__, __AUTHOR__, __WEBSITE__, __WEBSITE__,
             platform.python_version(), QT_VERSION_STR, PYQT_VERSION_STR,
             platform.system()))

    def addImplementation(self):
        if self.analyzer.nResults == 0:
            directory = ""
        else:
            directory = os.path.abspath(
                os.path.join(str(self.analyzer.resultDirectories[-1]),
                             os.path.pardir))
        directory = QFileDialog.getExistingDirectory(
            self, "Select a directory to scan", directory,
            QFileDialog.ShowDirsOnly)
        if not os.path.exists(
                directory) or directory in self.analyzer.resultDirectories:
            return

        self.analyzer.addResultDirectory(directory)
        self.addSolutionForSelection(self.analyzer.getResultName(directory))

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__,
                          QVariant(self.analyzer.resultDirectories))

    def removeResult(self):
        layout = self.solutionSelector.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            item = layout.itemAt(i)
            if not item.widget().isChecked(
            ):  # and self.analyzer.resultNames[i] != Analyzer.__PARETO__:
                item.widget().setVisible(False)
                layout.removeItem(item)
                self.analyzer.removeResultDirectory(
                    self.analyzer.resultDirectories[i])
        layout.update()

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__,
                          QVariant(self.analyzer.resultDirectories))

    def solutionSelected(self):
        selection = self.functionWidget.currentItem()
        if selection is None:
            return
        self.showSolution(str(selection.text()))

    def showSolution(self, functionName):
        self.currentSolution = self.analyzer.getResultsForFunction(
            functionName)
        self.metrics.clear()
        self._showSolution()

    def addSolutionForSelection(self, name):
        solution = QCheckBox(name)
        solution.setChecked(True)
        solution.stateChanged.connect(self._showSolution)
        self.solutionSelector.layout().addWidget(solution)
        self.solutionSelector.layout().update()

    def _updateSolutionSelection(self):
        self.clearWidget(self.solutionSelector)

        for directory in self.analyzer.resultDirectories:
            self.addSolutionForSelection(
                self.analyzer.getResultName(directory))

    def _showSolution(self):
        sol = self.currentSolution
        if sol is None:
            return

        if len(sol.variableImplementation
               ) == 0 and self.showVariablesRadio.isEnabled():
            self.showVariablesRadio.setEnabled(False)
            if self.showVariablesRadio.isChecked():
                self.showSolutionsRadio.setChecked(True)
        else:
            self.showVariablesRadio.setEnabled(True)

        if len(sol.functionImplementation
               ) == 0 and self.showSolutionsRadio.isEnabled():
            self.showSolutionsRadio.setEnabled(False)
            if self.showSolutionsRadio.isChecked():
                self.showVariablesRadio.setChecked(True)
        else:
            self.showSolutionsRadio.setEnabled(True)

        if self.showSolutionsRadio.isChecked():
            self.generationSlider.setMaximum(
                max([
                    sol.getFunctionSolution(impl).count()
                    for impl in sol.functionImplementation
                ]))
        else:
            self.generationSlider.setMaximum(
                max([
                    sol.getVariableSolution(impl).count()
                    for impl in sol.variableImplementation
                ]))
        self._exportCurrentImage()

    def clearWidget(self, widget):
        layout = widget.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            layout.removeItem(layout.itemAt(i))

    def updateUI(self):
        self.statusBar().showMessage("Updating solutions...")

        selectedRow = self.functionWidget.currentRow()
        self.functionWidget.clear()
        names = [] + self.analyzer.getFunctionNames()
        names.sort()
        for name in names:
            item = QListWidgetItem()
            item.setText(name)
            self.functionWidget.addItem(item)

        if self.functionWidget.count() > 0:
            self.functionWidget.setCurrentRow(
                selectedRow if selectedRow >= 0
                and selectedRow < self.functionWidget.count() else 0)
        self.statusBar().showMessage("Updated!", 5000)

    def _loadInitialData(self):
        self.updateUI()
        self.statusBar().showMessage("Ready!", 5000)

    def closeEvent(self, event):
        self.statusBar().showMessage("Closing...")
        settings = QSettings()
        settings.setValue(MainWindow.__PREF_GEOM__, self.saveGeometry())
        settings.setValue(MainWindow.__PREF_STATE__, self.saveState())
        self.plot.clear()
Ejemplo n.º 19
0
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(1029, 526)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
        self.gridLayout = QtGui.QGridLayout()
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.PlotWidget = PlotWidget(self.centralwidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                                       QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.PlotWidget.sizePolicy().hasHeightForWidth())
        self.PlotWidget.setSizePolicy(sizePolicy)
        self.PlotWidget.setAutoFillBackground(False)
        self.PlotWidget.setObjectName(_fromUtf8("PlotWidget"))
        self.gridLayout.addWidget(self.PlotWidget, 0, 0, 3, 1)
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1029, 30))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QtGui.QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuHelp = QtGui.QMenu(self.menubar)
        self.menuHelp.setObjectName(_fromUtf8("menuHelp"))
        self.menuView = QtGui.QMenu(self.menubar)
        self.menuView.setObjectName(_fromUtf8("menuView"))
        self.menuPaper_format = QtGui.QMenu(self.menuView)
        self.menuPaper_format.setObjectName(_fromUtf8("menuPaper_format"))
        self.menuAnnotation_Toolbar = QtGui.QMenu(self.menuView)
        self.menuAnnotation_Toolbar.setObjectName(
            _fromUtf8("menuAnnotation_Toolbar"))
        self.menuTools = QtGui.QMenu(self.menubar)
        self.menuTools.setObjectName(_fromUtf8("menuTools"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.dockClinInfo = QtGui.QDockWidget(MainWindow)
        self.dockClinInfo.setObjectName(_fromUtf8("dockClinInfo"))
        self.dockClinInfoContents = QtGui.QWidget()
        self.dockClinInfoContents.setObjectName(
            _fromUtf8("dockClinInfoContents"))
        self.dockClinInfo.setWidget(self.dockClinInfoContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2),
                                 self.dockClinInfo)
        self.dockDataBrowser = QtGui.QDockWidget(MainWindow)
        self.dockDataBrowser.setObjectName(_fromUtf8("dockDataBrowser"))
        self.dockWidgetContents = QtGui.QWidget()
        self.dockWidgetContents.setObjectName(_fromUtf8("dockWidgetContents"))
        self.dockDataBrowser.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1),
                                 self.dockDataBrowser)
        self.toolBar = QtGui.QToolBar(MainWindow)
        self.toolBar.setEnabled(True)
        font = QtGui.QFont()
        font.setPointSize(8)
        self.toolBar.setFont(font)
        self.toolBar.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.toolBar.setMovable(True)
        self.toolBar.setAllowedAreas(QtCore.Qt.AllToolBarAreas)
        self.toolBar.setIconSize(QtCore.QSize(22, 22))
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.toolBar.setFloatable(False)
        self.toolBar.setObjectName(_fromUtf8("toolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.actionOpen = QtGui.QAction(MainWindow)
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/document-open-3.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.actionOpen.setIcon(icon)
        self.actionOpen.setStatusTip(_fromUtf8(""))
        self.actionOpen.setObjectName(_fromUtf8("actionOpen"))
        self.actionClose = QtGui.QAction(MainWindow)
        icon1 = QtGui.QIcon()
        icon1.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/document-close-3.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.actionClose.setIcon(icon1)
        self.actionClose.setObjectName(_fromUtf8("actionClose"))
        self.actionQuit = QtGui.QAction(MainWindow)
        icon2 = QtGui.QIcon()
        icon2.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/application-exit-4.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.actionQuit.setIcon(icon2)
        self.actionQuit.setObjectName(_fromUtf8("actionQuit"))
        self.actionAbout = QtGui.QAction(MainWindow)
        self.actionAbout.setObjectName(_fromUtf8("actionAbout"))
        self.actionConvert_files = QtGui.QAction(MainWindow)
        self.actionConvert_files.setObjectName(
            _fromUtf8("actionConvert_files"))
        self.actionOpen_folder = QtGui.QAction(MainWindow)
        self.actionOpen_folder.setObjectName(_fromUtf8("actionOpen_folder"))
        self.actionAttribute_selection = QtGui.QAction(MainWindow)
        self.actionAttribute_selection.setObjectName(
            _fromUtf8("actionAttribute_selection"))
        self.actionDownload_CTU_UHB_data = QtGui.QAction(MainWindow)
        self.actionDownload_CTU_UHB_data.setObjectName(
            _fromUtf8("actionDownload_CTU_UHB_data"))
        self.actionData_browser = QtGui.QAction(MainWindow)
        self.actionData_browser.setCheckable(True)
        self.actionData_browser.setObjectName(_fromUtf8("actionData_browser"))
        self.actionExport_to_PDF = QtGui.QAction(MainWindow)
        self.actionExport_to_PDF.setEnabled(True)
        icon3 = QtGui.QIcon()
        icon3.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/pdf_icon2.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionExport_to_PDF.setIcon(icon3)
        self.actionExport_to_PDF.setObjectName(
            _fromUtf8("actionExport_to_PDF"))
        self.actionEU = QtGui.QAction(MainWindow)
        self.actionEU.setCheckable(True)
        self.actionEU.setObjectName(_fromUtf8("actionEU"))
        self.actionUS = QtGui.QAction(MainWindow)
        self.actionUS.setCheckable(True)
        self.actionUS.setObjectName(_fromUtf8("actionUS"))
        self.actionSet_Clear_Baseline = QtGui.QAction(MainWindow)
        self.actionSet_Clear_Baseline.setObjectName(
            _fromUtf8("actionSet_Clear_Baseline"))
        self.actionBasal = QtGui.QAction(MainWindow)
        self.actionBasal.setCheckable(True)
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/actions/icons/basal.png")),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionBasal.setIcon(icon4)
        self.actionBasal.setObjectName(_fromUtf8("actionBasal"))
        self.actionBaseline = QtGui.QAction(MainWindow)
        self.actionBaseline.setCheckable(True)
        icon5 = QtGui.QIcon()
        icon5.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/baseline.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionBaseline.setIcon(icon5)
        self.actionBaseline.setObjectName(_fromUtf8("actionBaseline"))
        self.actionRecovery = QtGui.QAction(MainWindow)
        self.actionRecovery.setCheckable(True)
        icon6 = QtGui.QIcon()
        icon6.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/recovery.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionRecovery.setIcon(icon6)
        self.actionRecovery.setObjectName(_fromUtf8("actionRecovery"))
        self.actionCursor = QtGui.QAction(MainWindow)
        self.actionCursor.setCheckable(True)
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/actions/icons/cursor.png")),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionCursor.setIcon(icon7)
        self.actionCursor.setObjectName(_fromUtf8("actionCursor"))
        self.actionNote = QtGui.QAction(MainWindow)
        self.actionNote.setCheckable(True)
        icon8 = QtGui.QIcon()
        icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/actions/icons/note.png")),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionNote.setIcon(icon8)
        self.actionNote.setObjectName(_fromUtf8("actionNote"))
        self.actionSave = QtGui.QAction(MainWindow)
        self.actionSave.setEnabled(False)
        icon9 = QtGui.QIcon()
        icon9.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/save_icon.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionSave.setIcon(icon9)
        self.actionSave.setObjectName(_fromUtf8("actionSave"))
        self.actionDelete = QtGui.QAction(MainWindow)
        self.actionDelete.setEnabled(True)
        icon10 = QtGui.QIcon()
        icon10.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/recycle_bin.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionDelete.setIcon(icon10)
        self.actionDelete.setObjectName(_fromUtf8("actionDelete"))
        self.actionSent_annotations = QtGui.QAction(MainWindow)
        self.actionSent_annotations.setObjectName(
            _fromUtf8("actionSent_annotations"))
        self.actionNo_recovery = QtGui.QAction(MainWindow)
        self.actionNo_recovery.setCheckable(True)
        icon11 = QtGui.QIcon()
        icon11.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/no_recovery.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionNo_recovery.setIcon(icon11)
        self.actionNo_recovery.setObjectName(_fromUtf8("actionNo_recovery"))
        self.actionEllipse = QtGui.QAction(MainWindow)
        self.actionEllipse.setCheckable(True)
        icon12 = QtGui.QIcon()
        icon12.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/ellipse-icon.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEllipse.setIcon(icon12)
        self.actionEllipse.setObjectName(_fromUtf8("actionEllipse"))
        self.actionExcessive_UA = QtGui.QAction(MainWindow)
        self.actionExcessive_UA.setCheckable(True)
        icon13 = QtGui.QIcon()
        icon13.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/excessive_ua.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionExcessive_UA.setIcon(icon13)
        self.actionExcessive_UA.setObjectName(_fromUtf8("actionExcessive_UA"))
        self.actionAnnToolbarVisible = QtGui.QAction(MainWindow)
        self.actionAnnToolbarVisible.setCheckable(True)
        self.actionAnnToolbarVisible.setObjectName(
            _fromUtf8("actionAnnToolbarVisible"))
        self.actionAnnToolbarAlign_right = QtGui.QAction(MainWindow)
        self.actionAnnToolbarAlign_right.setCheckable(True)
        self.actionAnnToolbarAlign_right.setObjectName(
            _fromUtf8("actionAnnToolbarAlign_right"))
        self.actionClinical_information = QtGui.QAction(MainWindow)
        self.actionClinical_information.setCheckable(True)
        self.actionClinical_information.setObjectName(
            _fromUtf8("actionClinical_information"))
        self.actionEllipseNote = QtGui.QAction(MainWindow)
        self.actionEllipseNote.setCheckable(True)
        icon14 = QtGui.QIcon()
        icon14.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/ellipse-note-icon.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEllipseNote.setIcon(icon14)
        self.actionEllipseNote.setObjectName(_fromUtf8("actionEllipseNote"))
        self.actionFloating_Baseline = QtGui.QAction(MainWindow)
        self.actionFloating_Baseline.setCheckable(True)
        icon15 = QtGui.QIcon()
        icon15.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/floating_baseline.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionFloating_Baseline.setIcon(icon15)
        self.actionFloating_Baseline.setObjectName(
            _fromUtf8("actionFloating_Baseline"))
        self.actionAcceleration = QtGui.QAction(MainWindow)
        self.actionAcceleration.setCheckable(True)
        icon16 = QtGui.QIcon()
        icon16.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/acceleration.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionAcceleration.setIcon(icon16)
        self.actionAcceleration.setObjectName(_fromUtf8("actionAcceleration"))
        self.actionDeceleration = QtGui.QAction(MainWindow)
        self.actionDeceleration.setCheckable(True)
        icon17 = QtGui.QIcon()
        icon17.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/deceleration.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionDeceleration.setIcon(icon17)
        self.actionDeceleration.setObjectName(_fromUtf8("actionDeceleration"))
        self.actionUA = QtGui.QAction(MainWindow)
        self.actionUA.setCheckable(True)
        icon18 = QtGui.QIcon()
        icon18.addPixmap(
            QtGui.QPixmap(
                _fromUtf8(":/actions/icons/uterine_contraction.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionUA.setIcon(icon18)
        self.actionUA.setObjectName(_fromUtf8("actionUA"))
        self.actionCaliper = QtGui.QAction(MainWindow)
        self.actionCaliper.setCheckable(True)
        icon19 = QtGui.QIcon()
        icon19.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/caliper.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionCaliper.setIcon(icon19)
        self.actionCaliper.setObjectName(_fromUtf8("actionCaliper"))
        self.actionCaliperFHR = QtGui.QAction(MainWindow)
        self.actionCaliperFHR.setCheckable(True)
        self.actionCaliperFHR.setObjectName(_fromUtf8("actionCaliperFHR"))
        self.actionCaliperTOCO = QtGui.QAction(MainWindow)
        self.actionCaliperTOCO.setCheckable(True)
        self.actionCaliperTOCO.setObjectName(_fromUtf8("actionCaliperTOCO"))
        self.actionFIGO_acc_dec = QtGui.QAction(MainWindow)
        self.actionFIGO_acc_dec.setObjectName(_fromUtf8("actionFIGO_acc_dec"))
        self.actionFIGO_UA = QtGui.QAction(MainWindow)
        self.actionFIGO_UA.setObjectName(_fromUtf8("actionFIGO_UA"))
        self.actionCaliperReset = QtGui.QAction(MainWindow)
        self.actionCaliperReset.setObjectName(_fromUtf8("actionCaliperReset"))
        self.actionAnnShowHide = QtGui.QAction(MainWindow)
        icon20 = QtGui.QIcon()
        icon20.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/ann_visibility.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionAnnShowHide.setIcon(icon20)
        self.actionAnnShowHide.setObjectName(_fromUtf8("actionAnnShowHide"))
        self.actionDebug_CalibSignal = QtGui.QAction(MainWindow)
        self.actionDebug_CalibSignal.setObjectName(
            _fromUtf8("actionDebug_CalibSignal"))
        self.actionEvaluationNote = QtGui.QAction(MainWindow)
        self.actionEvaluationNote.setCheckable(True)
        icon21 = QtGui.QIcon()
        icon21.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/assessment.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEvaluationNote.setIcon(icon21)
        self.actionEvaluationNote.setObjectName(
            _fromUtf8("actionEvaluationNote"))
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionOpen_folder)
        self.menuFile.addAction(self.actionExport_to_PDF)
        self.menuFile.addAction(self.actionQuit)
        self.menuHelp.addAction(self.actionAbout)
        self.menuPaper_format.addAction(self.actionEU)
        self.menuPaper_format.addAction(self.actionUS)
        self.menuAnnotation_Toolbar.addAction(self.actionAnnToolbarVisible)
        self.menuAnnotation_Toolbar.addAction(self.actionAnnToolbarAlign_right)
        self.menuView.addAction(self.actionClinical_information)
        self.menuView.addAction(self.actionData_browser)
        self.menuView.addAction(self.menuPaper_format.menuAction())
        self.menuView.addAction(self.menuAnnotation_Toolbar.menuAction())
        self.menuTools.addAction(self.actionAttribute_selection)
        self.menuTools.addAction(self.actionConvert_files)
        self.menuTools.addAction(self.actionDownload_CTU_UHB_data)
        self.menuTools.addAction(self.actionSent_annotations)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuView.menuAction())
        self.menubar.addAction(self.menuTools.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())
        self.toolBar.addAction(self.actionCursor)
        self.toolBar.addAction(self.actionBasal)
        self.toolBar.addAction(self.actionBaseline)
        self.toolBar.addAction(self.actionRecovery)
        self.toolBar.addAction(self.actionNo_recovery)
        self.toolBar.addAction(self.actionExcessive_UA)
        self.toolBar.addAction(self.actionEllipseNote)
        self.toolBar.addAction(self.actionNote)
        self.toolBar.addAction(self.actionEvaluationNote)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionCaliper)
        self.toolBar.addAction(self.actionSave)
        self.toolBar.addAction(self.actionDelete)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionFloating_Baseline)
        self.toolBar.addAction(self.actionAcceleration)
        self.toolBar.addAction(self.actionDeceleration)
        self.toolBar.addAction(self.actionUA)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
Ejemplo n.º 20
0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(1029, 526)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayout_2 = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout_2.setObjectName(_fromUtf8("gridLayout_2"))
        self.gridLayout = QtGui.QGridLayout()
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.PlotWidget = PlotWidget(self.centralwidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,
                                       QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            self.PlotWidget.sizePolicy().hasHeightForWidth())
        self.PlotWidget.setSizePolicy(sizePolicy)
        self.PlotWidget.setAutoFillBackground(False)
        self.PlotWidget.setObjectName(_fromUtf8("PlotWidget"))
        self.gridLayout.addWidget(self.PlotWidget, 0, 0, 3, 1)
        self.gridLayout_2.addLayout(self.gridLayout, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 1029, 30))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        self.menuFile = QtGui.QMenu(self.menubar)
        self.menuFile.setObjectName(_fromUtf8("menuFile"))
        self.menuHelp = QtGui.QMenu(self.menubar)
        self.menuHelp.setObjectName(_fromUtf8("menuHelp"))
        self.menuView = QtGui.QMenu(self.menubar)
        self.menuView.setObjectName(_fromUtf8("menuView"))
        self.menuPaper_format = QtGui.QMenu(self.menuView)
        self.menuPaper_format.setObjectName(_fromUtf8("menuPaper_format"))
        self.menuAnnotation_Toolbar = QtGui.QMenu(self.menuView)
        self.menuAnnotation_Toolbar.setObjectName(
            _fromUtf8("menuAnnotation_Toolbar"))
        self.menuTools = QtGui.QMenu(self.menubar)
        self.menuTools.setObjectName(_fromUtf8("menuTools"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)
        self.dockClinInfo = QtGui.QDockWidget(MainWindow)
        self.dockClinInfo.setObjectName(_fromUtf8("dockClinInfo"))
        self.dockClinInfoContents = QtGui.QWidget()
        self.dockClinInfoContents.setObjectName(
            _fromUtf8("dockClinInfoContents"))
        self.dockClinInfo.setWidget(self.dockClinInfoContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(2),
                                 self.dockClinInfo)
        self.dockDataBrowser = QtGui.QDockWidget(MainWindow)
        self.dockDataBrowser.setObjectName(_fromUtf8("dockDataBrowser"))
        self.dockWidgetContents = QtGui.QWidget()
        self.dockWidgetContents.setObjectName(_fromUtf8("dockWidgetContents"))
        self.dockDataBrowser.setWidget(self.dockWidgetContents)
        MainWindow.addDockWidget(QtCore.Qt.DockWidgetArea(1),
                                 self.dockDataBrowser)
        self.toolBar = QtGui.QToolBar(MainWindow)
        self.toolBar.setEnabled(True)
        font = QtGui.QFont()
        font.setPointSize(8)
        self.toolBar.setFont(font)
        self.toolBar.setCursor(QtGui.QCursor(QtCore.Qt.ArrowCursor))
        self.toolBar.setMovable(True)
        self.toolBar.setAllowedAreas(QtCore.Qt.AllToolBarAreas)
        self.toolBar.setIconSize(QtCore.QSize(22, 22))
        self.toolBar.setToolButtonStyle(QtCore.Qt.ToolButtonTextUnderIcon)
        self.toolBar.setFloatable(False)
        self.toolBar.setObjectName(_fromUtf8("toolBar"))
        MainWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
        self.actionOpen = QtGui.QAction(MainWindow)
        icon = QtGui.QIcon()
        icon.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/document-open-3.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.actionOpen.setIcon(icon)
        self.actionOpen.setStatusTip(_fromUtf8(""))
        self.actionOpen.setObjectName(_fromUtf8("actionOpen"))
        self.actionClose = QtGui.QAction(MainWindow)
        icon1 = QtGui.QIcon()
        icon1.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/document-close-3.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.actionClose.setIcon(icon1)
        self.actionClose.setObjectName(_fromUtf8("actionClose"))
        self.actionQuit = QtGui.QAction(MainWindow)
        icon2 = QtGui.QIcon()
        icon2.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/application-exit-4.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.On)
        self.actionQuit.setIcon(icon2)
        self.actionQuit.setObjectName(_fromUtf8("actionQuit"))
        self.actionAbout = QtGui.QAction(MainWindow)
        self.actionAbout.setObjectName(_fromUtf8("actionAbout"))
        self.actionConvert_files = QtGui.QAction(MainWindow)
        self.actionConvert_files.setObjectName(
            _fromUtf8("actionConvert_files"))
        self.actionOpen_folder = QtGui.QAction(MainWindow)
        self.actionOpen_folder.setObjectName(_fromUtf8("actionOpen_folder"))
        self.actionAttribute_selection = QtGui.QAction(MainWindow)
        self.actionAttribute_selection.setObjectName(
            _fromUtf8("actionAttribute_selection"))
        self.actionDownload_CTU_UHB_data = QtGui.QAction(MainWindow)
        self.actionDownload_CTU_UHB_data.setObjectName(
            _fromUtf8("actionDownload_CTU_UHB_data"))
        self.actionData_browser = QtGui.QAction(MainWindow)
        self.actionData_browser.setCheckable(True)
        self.actionData_browser.setObjectName(_fromUtf8("actionData_browser"))
        self.actionExport_to_PDF = QtGui.QAction(MainWindow)
        self.actionExport_to_PDF.setEnabled(True)
        icon3 = QtGui.QIcon()
        icon3.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/pdf_icon2.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionExport_to_PDF.setIcon(icon3)
        self.actionExport_to_PDF.setObjectName(
            _fromUtf8("actionExport_to_PDF"))
        self.actionEU = QtGui.QAction(MainWindow)
        self.actionEU.setCheckable(True)
        self.actionEU.setObjectName(_fromUtf8("actionEU"))
        self.actionUS = QtGui.QAction(MainWindow)
        self.actionUS.setCheckable(True)
        self.actionUS.setObjectName(_fromUtf8("actionUS"))
        self.actionSet_Clear_Baseline = QtGui.QAction(MainWindow)
        self.actionSet_Clear_Baseline.setObjectName(
            _fromUtf8("actionSet_Clear_Baseline"))
        self.actionBasal = QtGui.QAction(MainWindow)
        self.actionBasal.setCheckable(True)
        icon4 = QtGui.QIcon()
        icon4.addPixmap(QtGui.QPixmap(_fromUtf8(":/actions/icons/basal.png")),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionBasal.setIcon(icon4)
        self.actionBasal.setObjectName(_fromUtf8("actionBasal"))
        self.actionBaseline = QtGui.QAction(MainWindow)
        self.actionBaseline.setCheckable(True)
        icon5 = QtGui.QIcon()
        icon5.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/baseline.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionBaseline.setIcon(icon5)
        self.actionBaseline.setObjectName(_fromUtf8("actionBaseline"))
        self.actionRecovery = QtGui.QAction(MainWindow)
        self.actionRecovery.setCheckable(True)
        icon6 = QtGui.QIcon()
        icon6.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/recovery.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionRecovery.setIcon(icon6)
        self.actionRecovery.setObjectName(_fromUtf8("actionRecovery"))
        self.actionCursor = QtGui.QAction(MainWindow)
        self.actionCursor.setCheckable(True)
        icon7 = QtGui.QIcon()
        icon7.addPixmap(QtGui.QPixmap(_fromUtf8(":/actions/icons/cursor.png")),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionCursor.setIcon(icon7)
        self.actionCursor.setObjectName(_fromUtf8("actionCursor"))
        self.actionNote = QtGui.QAction(MainWindow)
        self.actionNote.setCheckable(True)
        icon8 = QtGui.QIcon()
        icon8.addPixmap(QtGui.QPixmap(_fromUtf8(":/actions/icons/note.png")),
                        QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionNote.setIcon(icon8)
        self.actionNote.setObjectName(_fromUtf8("actionNote"))
        self.actionSave = QtGui.QAction(MainWindow)
        self.actionSave.setEnabled(False)
        icon9 = QtGui.QIcon()
        icon9.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/save_icon.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionSave.setIcon(icon9)
        self.actionSave.setObjectName(_fromUtf8("actionSave"))
        self.actionDelete = QtGui.QAction(MainWindow)
        self.actionDelete.setEnabled(True)
        icon10 = QtGui.QIcon()
        icon10.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/recycle_bin.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionDelete.setIcon(icon10)
        self.actionDelete.setObjectName(_fromUtf8("actionDelete"))
        self.actionSent_annotations = QtGui.QAction(MainWindow)
        self.actionSent_annotations.setObjectName(
            _fromUtf8("actionSent_annotations"))
        self.actionNo_recovery = QtGui.QAction(MainWindow)
        self.actionNo_recovery.setCheckable(True)
        icon11 = QtGui.QIcon()
        icon11.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/no_recovery.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionNo_recovery.setIcon(icon11)
        self.actionNo_recovery.setObjectName(_fromUtf8("actionNo_recovery"))
        self.actionEllipse = QtGui.QAction(MainWindow)
        self.actionEllipse.setCheckable(True)
        icon12 = QtGui.QIcon()
        icon12.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/ellipse-icon.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEllipse.setIcon(icon12)
        self.actionEllipse.setObjectName(_fromUtf8("actionEllipse"))
        self.actionExcessive_UA = QtGui.QAction(MainWindow)
        self.actionExcessive_UA.setCheckable(True)
        icon13 = QtGui.QIcon()
        icon13.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/excessive_ua.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionExcessive_UA.setIcon(icon13)
        self.actionExcessive_UA.setObjectName(_fromUtf8("actionExcessive_UA"))
        self.actionAnnToolbarVisible = QtGui.QAction(MainWindow)
        self.actionAnnToolbarVisible.setCheckable(True)
        self.actionAnnToolbarVisible.setObjectName(
            _fromUtf8("actionAnnToolbarVisible"))
        self.actionAnnToolbarAlign_right = QtGui.QAction(MainWindow)
        self.actionAnnToolbarAlign_right.setCheckable(True)
        self.actionAnnToolbarAlign_right.setObjectName(
            _fromUtf8("actionAnnToolbarAlign_right"))
        self.actionClinical_information = QtGui.QAction(MainWindow)
        self.actionClinical_information.setCheckable(True)
        self.actionClinical_information.setObjectName(
            _fromUtf8("actionClinical_information"))
        self.actionEllipseNote = QtGui.QAction(MainWindow)
        self.actionEllipseNote.setCheckable(True)
        icon14 = QtGui.QIcon()
        icon14.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/ellipse-note-icon.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEllipseNote.setIcon(icon14)
        self.actionEllipseNote.setObjectName(_fromUtf8("actionEllipseNote"))
        self.actionFloating_Baseline = QtGui.QAction(MainWindow)
        self.actionFloating_Baseline.setCheckable(True)
        icon15 = QtGui.QIcon()
        icon15.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/floating_baseline.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionFloating_Baseline.setIcon(icon15)
        self.actionFloating_Baseline.setObjectName(
            _fromUtf8("actionFloating_Baseline"))
        self.actionAcceleration = QtGui.QAction(MainWindow)
        self.actionAcceleration.setCheckable(True)
        icon16 = QtGui.QIcon()
        icon16.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/acceleration.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionAcceleration.setIcon(icon16)
        self.actionAcceleration.setObjectName(_fromUtf8("actionAcceleration"))
        self.actionDeceleration = QtGui.QAction(MainWindow)
        self.actionDeceleration.setCheckable(True)
        icon17 = QtGui.QIcon()
        icon17.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/deceleration.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionDeceleration.setIcon(icon17)
        self.actionDeceleration.setObjectName(_fromUtf8("actionDeceleration"))
        self.actionUA = QtGui.QAction(MainWindow)
        self.actionUA.setCheckable(True)
        icon18 = QtGui.QIcon()
        icon18.addPixmap(
            QtGui.QPixmap(
                _fromUtf8(":/actions/icons/uterine_contraction.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionUA.setIcon(icon18)
        self.actionUA.setObjectName(_fromUtf8("actionUA"))
        self.actionCaliper = QtGui.QAction(MainWindow)
        self.actionCaliper.setCheckable(True)
        icon19 = QtGui.QIcon()
        icon19.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/caliper.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionCaliper.setIcon(icon19)
        self.actionCaliper.setObjectName(_fromUtf8("actionCaliper"))
        self.actionCaliperFHR = QtGui.QAction(MainWindow)
        self.actionCaliperFHR.setCheckable(True)
        self.actionCaliperFHR.setObjectName(_fromUtf8("actionCaliperFHR"))
        self.actionCaliperTOCO = QtGui.QAction(MainWindow)
        self.actionCaliperTOCO.setCheckable(True)
        self.actionCaliperTOCO.setObjectName(_fromUtf8("actionCaliperTOCO"))
        self.actionFIGO_acc_dec = QtGui.QAction(MainWindow)
        self.actionFIGO_acc_dec.setObjectName(_fromUtf8("actionFIGO_acc_dec"))
        self.actionFIGO_UA = QtGui.QAction(MainWindow)
        self.actionFIGO_UA.setObjectName(_fromUtf8("actionFIGO_UA"))
        self.actionCaliperReset = QtGui.QAction(MainWindow)
        self.actionCaliperReset.setObjectName(_fromUtf8("actionCaliperReset"))
        self.actionAnnShowHide = QtGui.QAction(MainWindow)
        icon20 = QtGui.QIcon()
        icon20.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/ann_visibility.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionAnnShowHide.setIcon(icon20)
        self.actionAnnShowHide.setObjectName(_fromUtf8("actionAnnShowHide"))
        self.actionDebug_CalibSignal = QtGui.QAction(MainWindow)
        self.actionDebug_CalibSignal.setObjectName(
            _fromUtf8("actionDebug_CalibSignal"))
        self.actionEvaluationNote = QtGui.QAction(MainWindow)
        self.actionEvaluationNote.setCheckable(True)
        icon21 = QtGui.QIcon()
        icon21.addPixmap(
            QtGui.QPixmap(_fromUtf8(":/actions/icons/assessment.png")),
            QtGui.QIcon.Normal, QtGui.QIcon.Off)
        self.actionEvaluationNote.setIcon(icon21)
        self.actionEvaluationNote.setObjectName(
            _fromUtf8("actionEvaluationNote"))
        self.menuFile.addAction(self.actionOpen)
        self.menuFile.addAction(self.actionOpen_folder)
        self.menuFile.addAction(self.actionExport_to_PDF)
        self.menuFile.addAction(self.actionQuit)
        self.menuHelp.addAction(self.actionAbout)
        self.menuPaper_format.addAction(self.actionEU)
        self.menuPaper_format.addAction(self.actionUS)
        self.menuAnnotation_Toolbar.addAction(self.actionAnnToolbarVisible)
        self.menuAnnotation_Toolbar.addAction(self.actionAnnToolbarAlign_right)
        self.menuView.addAction(self.actionClinical_information)
        self.menuView.addAction(self.actionData_browser)
        self.menuView.addAction(self.menuPaper_format.menuAction())
        self.menuView.addAction(self.menuAnnotation_Toolbar.menuAction())
        self.menuTools.addAction(self.actionAttribute_selection)
        self.menuTools.addAction(self.actionConvert_files)
        self.menuTools.addAction(self.actionDownload_CTU_UHB_data)
        self.menuTools.addAction(self.actionSent_annotations)
        self.menubar.addAction(self.menuFile.menuAction())
        self.menubar.addAction(self.menuView.menuAction())
        self.menubar.addAction(self.menuTools.menuAction())
        self.menubar.addAction(self.menuHelp.menuAction())
        self.toolBar.addAction(self.actionCursor)
        self.toolBar.addAction(self.actionBasal)
        self.toolBar.addAction(self.actionBaseline)
        self.toolBar.addAction(self.actionRecovery)
        self.toolBar.addAction(self.actionNo_recovery)
        self.toolBar.addAction(self.actionExcessive_UA)
        self.toolBar.addAction(self.actionEllipseNote)
        self.toolBar.addAction(self.actionNote)
        self.toolBar.addAction(self.actionEvaluationNote)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionCaliper)
        self.toolBar.addAction(self.actionSave)
        self.toolBar.addAction(self.actionDelete)
        self.toolBar.addSeparator()
        self.toolBar.addAction(self.actionFloating_Baseline)
        self.toolBar.addAction(self.actionAcceleration)
        self.toolBar.addAction(self.actionDeceleration)
        self.toolBar.addAction(self.actionUA)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(
            _translate("MainWindow", "CTGViewerLite", None))
        self.menuFile.setTitle(_translate("MainWindow", "File", None))
        self.menuHelp.setTitle(_translate("MainWindow", "Help", None))
        self.menuView.setTitle(_translate("MainWindow", "View", None))
        self.menuPaper_format.setTitle(
            _translate("MainWindow", "Paper format", None))
        self.menuAnnotation_Toolbar.setTitle(
            _translate("MainWindow", "Annotation Toolbar", None))
        self.menuTools.setTitle(_translate("MainWindow", "Tools", None))
        self.dockClinInfo.setWindowTitle(
            _translate("MainWindow", "Clinical information", None))
        self.dockDataBrowser.setWindowTitle(
            _translate("MainWindow", "Data browser", None))
        self.toolBar.setWindowTitle(_translate("MainWindow", "toolBar", None))
        self.actionOpen.setText(_translate("MainWindow", "&Open file", None))
        self.actionOpen.setIconText(_translate("MainWindow", "Open file",
                                               None))
        self.actionOpen.setShortcut(_translate("MainWindow", "Ctrl+O", None))
        self.actionClose.setText(_translate("MainWindow", "&Close", None))
        self.actionClose.setShortcut(_translate("MainWindow", "Ctrl+W", None))
        self.actionQuit.setText(_translate("MainWindow", "&Quit", None))
        self.actionQuit.setToolTip(_translate("MainWindow", "Quit", None))
        self.actionQuit.setShortcut(_translate("MainWindow", "Ctrl+Q", None))
        self.actionAbout.setText(_translate("MainWindow", "About", None))
        self.actionConvert_files.setText(
            _translate("MainWindow", "Convert files", None))
        self.actionOpen_folder.setText(
            _translate("MainWindow", "Open folder", None))
        self.actionOpen_folder.setShortcut(
            _translate("MainWindow", "Ctrl+Alt+O", None))
        self.actionAttribute_selection.setText(
            _translate("MainWindow", "Attribute selection", None))
        self.actionDownload_CTU_UHB_data.setText(
            _translate("MainWindow", "Download CTU-UHB data", None))
        self.actionData_browser.setText(
            _translate("MainWindow", "Data browser", None))
        self.actionExport_to_PDF.setText(
            _translate("MainWindow", "Export to PDF", None))
        self.actionExport_to_PDF.setShortcut(
            _translate("MainWindow", "Ctrl+Shift+E", None))
        self.actionEU.setText(
            _translate("MainWindow", "EU (1cm/min, 20bpm/cm)", None))
        self.actionEU.setToolTip(
            _translate("MainWindow", "EU (1cm/min., 20bpm/cm)", None))
        self.actionUS.setText(
            _translate("MainWindow", "US (3cm/min, 30bpm/cm)", None))
        self.actionUS.setToolTip(
            _translate("MainWindow", "US (3cm/min., 30bpm/cm)", None))
        self.actionSet_Clear_Baseline.setText(
            _translate("MainWindow", "Set/Clear Baseline", None))
        self.actionSet_Clear_Baseline.setShortcut(
            _translate("MainWindow", "Ctrl+B", None))
        self.actionBasal.setText(_translate("MainWindow", "basal", None))
        self.actionBasal.setIconText(_translate("MainWindow", "Basal", None))
        self.actionBasal.setToolTip(
            _translate("MainWindow", "Draw basal heart rate line", None))
        self.actionBaseline.setText(_translate("MainWindow", "baseline", None))
        self.actionBaseline.setIconText(
            _translate("MainWindow", "Baseline", None))
        self.actionBaseline.setToolTip(
            _translate("MainWindow", "Draw a baseline (B)", None))
        self.actionBaseline.setShortcut(_translate("MainWindow", "B", None))
        self.actionRecovery.setText(_translate("MainWindow", "recovery", None))
        self.actionRecovery.setIconText(
            _translate("MainWindow", "Recovery", None))
        self.actionRecovery.setToolTip(
            _translate("MainWindow", "Recovery (R)", None))
        self.actionRecovery.setShortcut(_translate("MainWindow", "R", None))
        self.actionCursor.setText(_translate("MainWindow", "select", None))
        self.actionCursor.setIconText(_translate("MainWindow", "Select", None))
        self.actionCursor.setToolTip(
            _translate("MainWindow", "Select and move (S)", None))
        self.actionCursor.setShortcut(_translate("MainWindow", "S", None))
        self.actionNote.setText(_translate("MainWindow", "note", None))
        self.actionNote.setIconText(_translate("MainWindow", "Note", None))
        self.actionNote.setToolTip(_translate("MainWindow", "Add note", None))
        self.actionSave.setText(_translate("MainWindow", "save", None))
        self.actionSave.setIconText(_translate("MainWindow", "Save", None))
        self.actionSave.setToolTip(
            _translate("MainWindow", "Save all changes", None))
        self.actionSave.setShortcut(_translate("MainWindow", "Ctrl+S", None))
        self.actionDelete.setText(_translate("MainWindow", "Delete", None))
        self.actionDelete.setIconText(
            _translate("MainWindow", "Delete All", None))
        self.actionDelete.setToolTip(
            _translate("MainWindow", "Delete all annotations", None))
        self.actionSent_annotations.setText(
            _translate("MainWindow", "Sent annotations", None))
        self.actionNo_recovery.setText(
            _translate("MainWindow", "No recovery", None))
        self.actionEllipse.setText(_translate("MainWindow", "Mark", None))
        self.actionEllipse.setToolTip(
            _translate("MainWindow", "Draw mark (ellipse)", None))
        self.actionExcessive_UA.setText(
            _translate("MainWindow", "Excessive UA", None))
        self.actionExcessive_UA.setToolTip(
            _translate("MainWindow", "Excessive uterine contractions", None))
        self.actionAnnToolbarVisible.setText(
            _translate("MainWindow", "Show/hide", None))
        self.actionAnnToolbarVisible.setToolTip(
            _translate("MainWindow",
                       "Show/hide annotation toolbar and annotations", None))
        self.actionAnnToolbarAlign_right.setText(
            _translate("MainWindow", "Align right", None))
        self.actionClinical_information.setText(
            _translate("MainWindow", "Clinical information", None))
        self.actionEllipseNote.setText(_translate("MainWindow", "Mark ", None))
        self.actionEllipseNote.setToolTip(
            _translate("MainWindow", "Mark with note", None))
        self.actionFloating_Baseline.setText(
            _translate("MainWindow", "Float. Baseline", None))
        self.actionFloating_Baseline.setToolTip(
            _translate("MainWindow", "Add Floating Baseline (F)", None))
        self.actionFloating_Baseline.setShortcut(
            _translate("MainWindow", "F", None))
        self.actionAcceleration.setText(_translate("MainWindow", "Accel",
                                                   None))
        self.actionAcceleration.setToolTip(
            _translate("MainWindow", "Add acceleration (A)", None))
        self.actionAcceleration.setShortcut(_translate("MainWindow", "A",
                                                       None))
        self.actionDeceleration.setText(_translate("MainWindow", "Decel",
                                                   None))
        self.actionDeceleration.setToolTip(
            _translate("MainWindow", "Add deceleration (D)", None))
        self.actionDeceleration.setShortcut(_translate("MainWindow", "D",
                                                       None))
        self.actionUA.setText(_translate("MainWindow", "UA", None))
        self.actionUA.setToolTip(
            _translate("MainWindow", "Add uterine contraction (U)", None))
        self.actionUA.setShortcut(_translate("MainWindow", "U", None))
        self.actionCaliper.setText(_translate("MainWindow", "Caliper", None))
        self.actionCaliper.setToolTip(
            _translate("MainWindow", "Caliper (C)", None))
        self.actionCaliper.setShortcut(_translate("MainWindow", "C", None))
        self.actionCaliperFHR.setText(_translate("MainWindow", "FHR", None))
        self.actionCaliperFHR.setToolTip(
            _translate("MainWindow", "Enable caliper FHR", None))
        self.actionCaliperTOCO.setText(_translate("MainWindow", "TOCO", None))
        self.actionCaliperTOCO.setToolTip(
            _translate("MainWindow", "Enable caliper TOCO", None))
        self.actionFIGO_acc_dec.setText(
            _translate("MainWindow", "FIGO acc/dec", None))
        self.actionFIGO_acc_dec.setToolTip(
            _translate("MainWindow", "FIGO requirements for acc/dec", None))
        self.actionFIGO_UA.setText(_translate("MainWindow", "FIGO UA", None))
        self.actionFIGO_UA.setToolTip(
            _translate("MainWindow", "Requirements for uterine contractions",
                       None))
        self.actionCaliperReset.setText(
            _translate("MainWindow", "Reset caliper", None))
        self.actionCaliperReset.setToolTip(
            _translate("MainWindow", "Reset caliper settings", None))
        self.actionAnnShowHide.setText(
            _translate("MainWindow", "Show/hide", None))
        self.actionAnnShowHide.setToolTip(
            _translate("MainWindow", "Show/hide annotations", None))
        self.actionDebug_CalibSignal.setText(
            _translate("MainWindow", "Plot calibration signal", None))
        self.actionDebug_CalibSignal.setToolTip(
            _translate("MainWindow", "Plot calibration signal", None))
        self.actionEvaluationNote.setText(
            _translate("MainWindow", "Evaluation", None))
        self.actionEvaluationNote.setToolTip(
            _translate(
                "MainWindow",
                "Evaluation (Initial CTG, level of concern, intervention, pH)",
                None))
        self.actionEvaluationNote.setShortcut(
            _translate("MainWindow", "E", None))
class CentralWidget(QtWidgets.QWidget):
    
    def __init__(self):
        super().__init__()
        # widgets
        self.video_window=VideoWindow(PixelPermm = 314)
        self.fps=None #fps for saving
        self.xplot = PlotWidget('X displacement', label = 'X',color ='r')
        self.yplot = PlotWidget('Y displacement', label = 'Y',color ='g')
        self.zplot = PlotWidget('Z displacement', label = 'Z',color =(50, 100, 255))

        self.plot3D_widget = plot3D_widget()

        self.AnalysisWidget = AnalysisWidget()
        # controller

        self.video_saver=VideoSaver()
        self.isImageSaver=False  #True: image_saver will be chose in place of video saver

        self.csv_reader=CSV_Reader(flip_z = False)
        #----------------------------------------------------------------------
        # Toggle Comment/Uncomment to turn Z-plot ON and OFF
        #----------------------------------------------------------------------
        # VERTICAL LAYOUT ON THE LEFT
        
        v_left_layout=QtGui.QVBoxLayout()
        v_left_layout.addWidget(self.video_window)
        
        v_right_layout = QtGui.QVBoxLayout()
        v_right_layout.addWidget(self.plot3D_widget)
        # Comment/Uncomment below to remove the image analysis widget
        v_right_layout.addWidget(self.AnalysisWidget)
        # v_right_layout=QtGui.QVBoxLayout()
        # v_right_layout.addWidget(self.xplot)
        # v_right_layout.addWidget(self.yplot)
        # v_right_layout.addWidget(self.zplot)

        # v_right_layout.setStretchFactor(self.xplot,1)
        # v_right_layout.setStretchFactor(self.yplot,1)
        # v_right_layout.setStretchFactor(self.zplot,1)
        h_layout = QtGui.QHBoxLayout()
        h_layout.addLayout(v_left_layout)
#        h_layout.addLayout(v_right_layout)
        h_layout.addLayout(v_right_layout)

#        h_layout.addLayout(v_layout)
#        h_layout.addLayout(plot3D_layout)
        
        h_layout.setStretchFactor(v_left_layout,1)
#        h_layout.setStretchFactor(v_right_layout,1)
        h_layout.setStretchFactor(v_right_layout,1)
        # Final action     
#        self.setLayout(v_layout)
        self.setLayout(h_layout)
        
    def update_recording_fps(self,fps):
        self.fps=np.round(fps,2)
        
    def record_change(self,isRecording):
        self.isRecording=isRecording
        if isRecording:
            options_recording = options_Recording()
            options_recording.recording_instructions.connect(self.create_video)
            options_recording.exec_()
        else:
            self.terminate_video()
            
    def create_video(self,recording_instructions):
        self.folder_path=recording_instructions.folder_path
        print(self.folder_path)
        self.quality=recording_instructions.quality
        print(self.quality)
        self.isImageSaver=recording_instructions.isImageSaver
        print(self.isImageSaver)
        
        if self.isImageSaver:
            self.image_saver.start(self.folder_path,self.fps)
        else:
            self.video_saver.start(self.folder_path,self.fps)
        
    def add_frame(self,img, image_name): #img is the trigger for adding a new image
        print('try add frame')
        plotx=self.xplot.export_plot(self.quality)
        ploty=self.yplot.export_plot(self.quality)
        plotz=self.zplot.export_plot(self.quality)
        print('try 2')
        plot3d=self.plot3D_widget.plot3D.export_plot(self.quality)
        print('koik')
        if self.isImageSaver:
            self.image_saver.register(image_name, img,plotx,ploty,plotz,plot3d)
        else:
            self.video_saver.register(img,plotx,ploty,plotz,plot3d)
        print('images added')
        
    def add_name(self,imgName):
        if self.isImageSaver:
            self.image_saver.register_name(imgName)
        
    def terminate_video(self):
        if self.isImageSaver:
            self.image_saver.wait() #all element in the queue should be processed
            self.image_saver.stop() #release the video
        else:
            self.image_saver.wait() #all element in the queue should be processed
            self.video_saver.stop() #release the video

    def connect_all(self):
        
        self.csv_reader.Time_data.connect(self.xplot.update_Time)
        self.csv_reader.Time_data.connect(self.yplot.update_Time)
        self.csv_reader.Time_data.connect(self.zplot.update_Time)
        
        self.csv_reader.Xobj_data.connect(self.xplot.update_plot)
        self.csv_reader.Yobj_data.connect(self.yplot.update_plot)
        self.csv_reader.Zobj_data.connect(self.zplot.update_plot)
        self.csv_reader.fps_data.connect(self.update_recording_fps)
        
        self.csv_reader.Time_data.connect(self.plot3D_widget.plot3D.update_Time)
        self.csv_reader.Xobj_data.connect(self.plot3D_widget.plot3D.update_X)
        self.csv_reader.Yobj_data.connect(self.plot3D_widget.plot3D.update_Y)
        self.csv_reader.Zobj_data.connect(self.plot3D_widget.plot3D.update_Z)
        
        self.csv_reader.ImageTime_data.connect(self.video_window.initialize_image_time)
        self.csv_reader.ObjLoc_data.connect(self.video_window.initialize_obj_centroids)
        self.csv_reader.ImageNames_data.connect(self.video_window.initialize_image_names)
        
        # Added Image Index as another connection
#        self.csv_reader.ImageIndex_data.connect(self.video_window.initialize_image_index)
        
        self.video_window.update_plot.connect(self.xplot.update_cursor)
        self.video_window.update_plot.connect(self.yplot.update_cursor)
        self.video_window.update_plot.connect(self.zplot.update_cursor)
        
       
        self.video_window.update_3Dplot.connect(self.plot3D_widget.plot3D.move_marker)
        
        self.video_window.record_signal.connect(self.record_change)
        self.video_window.image_to_record.connect(self.add_frame)
        self.video_window.imageName.connect(self.add_name)

        # Image analysis widget connections
        self.AnalysisWidget.show_roi.connect(self.video_window.toggle_ROI_show)

        self.video_window.roi_pos_signal.connect(self.AnalysisWidget.update_pos_display)
        self.video_window.roi_size_signal.connect(self.AnalysisWidget.update_size_display)

        # metadata
        self.csv_reader.pixelpermm_data.connect(self.video_window.update_pixelsize)
Ejemplo n.º 22
0
class Data_Dialog(QDialog):
    def __init__(self,
                 fname=None,
                 data=None,
                 comment='#',
                 skiprows=0,
                 delimiter=' ',
                 expressions={},
                 autoupdate=False,
                 parent=None,
                 matplotlib=False,
                 plotIndex=None,
                 colors=None):
        QDialog.__init__(self, parent=parent)
        loadUi('UI_Forms/Data_Dialog.ui', self)
        self.colcycler = cycle(['r', 'g', 'b', 'c', 'm', 'y', 'w'])
        self.plotWidget = PlotWidget(parent=self, matplotlib=matplotlib)
        self.plotTab = self.tabWidget.addTab(self.plotWidget, 'Plots')
        self.tabWidget.setCurrentIndex(0)
        self.show()
        self.fileWatcher = QFileSystemWatcher()
        self.fileWatcher.fileChanged.connect(self.fileUpdated)
        self.cwd = None
        self.plotNum = 0
        self.xlabel = []
        self.ylabel = []
        self.oldPlotIndex = {}
        self.oldColors = {}
        self.dataAltered = False
        self.expressions = expressions
        if data is not None:
            self.data = data
            self.autoUpdateCheckBox.setEnabled(False)
        elif fname is not None:
            self.data = self.readData(fname,
                                      comment=comment,
                                      skiprows=skiprows,
                                      delimiter=delimiter)
        else:
            self.data = None
            self.autoUpdateCheckBox.setEnabled(False)
            self.saveDataPushButton.setEnabled(False)
            self.addRowPushButton.setEnabled(False)
            self.removeRowsPushButton.setEnabled(False)
            self.removeColumnPushButton.setEnabled(False)
        if self.data is not None:
            self.setMeta2Table()
            self.setData2Table()
            if plotIndex is None:
                self.addPlots(color=None)
            else:
                self.addMultiPlots(plotIndex=plotIndex, colors=colors)
        self.init_signals()
        self.okPushButton.setAutoDefault(False)
        self.make_default()
        self.setWindowTitle('Data Dialog')
        self.acceptData = True

        #self.setWindowSize((600,400))
        # if self.parentWidget() is not None:
        #     self.addPlotPushButton.setEnabled(False)
        #     self.removePlotPushButton.setEnabled(False)

    def make_default(self):
        self.okPushButton.setAutoDefault(False)
        self.closePushButton.setAutoDefault(False)
        self.openDataFilePushButton.setAutoDefault(False)
        self.saveDataPushButton.setAutoDefault(False)
        self.okPushButton.setDefault(False)
        self.closePushButton.setDefault(False)
        self.openDataFilePushButton.setDefault(False)
        self.saveDataPushButton.setDefault(False)

    def init_signals(self):
        self.closePushButton.clicked.connect(self.closeWidget)
        self.okPushButton.clicked.connect(self.acceptWidget)
        self.openDataFilePushButton.clicked.connect(self.openFile)
        self.autoUpdateCheckBox.stateChanged.connect(self.autoUpdate_ON_OFF)
        self.saveDataPushButton.clicked.connect(self.saveData)
        self.addPlotPushButton.clicked.connect(
            lambda x: self.addPlots(plotIndex=None))
        self.plotSetupTableWidget.cellChanged.connect(self.updatePlotData)
        self.removePlotPushButton.clicked.connect(self.removePlots)

        self.addMetaDataPushButton.clicked.connect(self.addMetaData)
        self.metaDataTableWidget.itemChanged.connect(self.metaDataChanged)
        self.metaDataTableWidget.itemClicked.connect(self.metaDataClicked)
        self.metaDataTableWidget.itemSelectionChanged.connect(
            self.metaDataSelectionChanged)
        self.removeMetaDataPushButton.clicked.connect(self.removeMetaData)

        self.dataTableWidget.itemChanged.connect(self.dataChanged)
        self.editColumnPushButton.clicked.connect(self.editDataColumn)
        self.addColumnPushButton.clicked.connect(
            lambda x: self.addDataColumn(colName='Col_X'))
        self.removeColumnPushButton.clicked.connect(self.removeDataColumn)
        self.removeRowsPushButton.clicked.connect(self.removeDataRows)
        self.dataTableWidget.setSelection
        self.dataTableWidget.horizontalHeader().sortIndicatorChanged.connect(
            self.dataSorted)
        self.addRowPushButton.clicked.connect(self.addDataRow)

    def closeWidget(self):
        self.acceptData = False
        self.reject()

    def acceptWidget(self):
        self.acceptData = True
        self.accept()

    def addMetaData(self):
        """
        Opens a MetaData Dialog and by accepting the dialog inputs the data to the MetaDataTable
        """

        self.metaDialog = MetaData_Dialog()
        if self.metaDialog.exec_():
            name, value = self.metaDialog.parNameLineEdit.text(
            ), self.metaDialog.parValueLineEdit.text()
            if name not in self.data['meta'].keys():
                row = self.metaDataTableWidget.rowCount()
                self.metaDataTableWidget.insertRow(row)
                self.metaDataTableWidget.setItem(row, 0,
                                                 QTableWidgetItem(name))
                self.metaDataTableWidget.setItem(row, 1,
                                                 QTableWidgetItem(value))
                try:
                    self.data['meta'][name] = eval(value)
                except:
                    self.data['meta'][name] = value
            else:
                QMessageBox.warning(
                    self, "Parameter Exists",
                    "The parameter %s already exists in meta data. Please provide a different parameter name"
                    % name, QMessageBox.Ok)
                self.addMetaData()

    def removeMetaData(self):
        """
        Removes the selected Metadata from the table
        """
        self.metaDataTableWidget.itemSelectionChanged.disconnect()
        rows = list(
            set([
                item.row()
                for item in self.metaDataTableWidget.selectedItems()
            ]))
        for row in rows:
            key = self.metaDataTableWidget.item(row, 0).text()
            if key != 'col_names':
                del self.data['meta'][key]
                self.metaDataTableWidget.removeRow(row)
            else:
                QMessageBox.warning(self, 'Restricted Parameter',
                                    'You cannot delete the parameter %s' % key,
                                    QMessageBox.Ok)
        self.metaDataTableWidget.itemSelectionChanged.connect(
            self.metaDataSelectionChanged)

    def metaDataChanged(self, item):
        """
        Updates the value metadata as per the changes in the metaDataTableWidget
        """
        row = item.row()
        col = item.column()
        key = self.metaDataTableWidget.item(row, 0).text()
        if col != 0:
            try:
                self.data['meta'][key] = eval(item.text())
            except:
                self.data['meta'][key] = item.text()
            if self.metaDataTableWidget.item(
                    row, 0).text() == 'col_names' and len(
                        self.data['meta'][key]) != len(
                            self.data['data'].columns):
                QMessageBox.warning(
                    self, 'Restricted Parameter',
                    'Please provide same length of col_names as the number of the column of the data'
                )
                self.data['meta'][key] = eval(self.oldMetaText)
                item.setText(self.oldMetaText)
            elif self.metaDataTableWidget.item(
                    row, 0).text() == 'col_names' and len(
                        self.data['meta'][key]) == len(
                            self.data['data'].columns):
                self.data['data'].columns = self.data['meta'][key]
                self.dataTableWidget.setHorizontalHeaderLabels(
                    self.data['meta'][key])
                self.dataAltered = True
                self.resetPlotSetup()
                self.dataAltered = False
        else:
            if self.oldMetaText == 'col_names':
                QMessageBox.warning(
                    self, 'Restricted Parameter',
                    'col_names is a restricted parameter the name of which cannot be changed',
                    QMessageBox.Ok)
                item.setText(self.oldMetaText)
            elif item.text() not in self.data['meta'].keys():
                self.data['meta'][key] = self.data['meta'][self.oldMetaText]
                del self.data['meta'][self.oldMetaText]
            else:
                self.metaDataTableWidget.itemChanged.disconnect()
                QMessageBox.warning(
                    self, "Parameter Exists",
                    "The parameter %s already exists in meta data. Please provide a different parameter name"
                    % item.text(), QMessageBox.Ok)
                item.setText(self.oldMetaText)
                self.metaDataTableWidget.itemChanged.connect(
                    self.metaDataChanged)
        self.oldMetaText = item.text()

    def metaDataClicked(self, item):
        self.oldMetaText = item.text()

    def metaDataSelectionChanged(self):
        self.oldMetaText = self.metaDataTableWidget.selectedItems()[0].text()

    def dataChanged(self, item):
        row, col = item.row(), item.column()
        key = self.dataTableWidget.horizontalHeaderItem(col).text()
        self.data['data'][key][row] = eval(item.text())
        self.dataAltered = True
        self.resetPlotSetup()
        self.dataAltered = False

    def dataSorted(self):
        """
        Updates the data after sorting the DataTableWidget
        """
        self.getDataFromTable()
        self.dataAltered = True
        self.resetPlotSetup()
        self.dataAltered = False

    def addDataRow(self):
        try:
            self.dataTableWidget.itemChanged.disconnect()
        except:
            pass
        row = self.dataTableWidget.currentRow()
        self.dataTableWidget.insertRow(row + 1)
        for col in range(self.dataTableWidget.columnCount()):
            self.dataTableWidget.setItem(
                row + 1, col,
                QCustomTableWidgetItem(
                    float(self.dataTableWidget.item(row, col).text())))
        self.getDataFromTable()
        self.dataAltered = True
        self.resetPlotSetup()
        self.dataAltered = False
        self.dataTableWidget.itemChanged.connect(self.dataChanged)

    def editDataColumn(self):
        if self.data is not None:
            items = self.dataTableWidget.selectedItems()
            selCols = list([item.column() for item in items])
            if len(selCols) == 1:
                colName = self.dataTableWidget.horizontalHeaderItem(
                    selCols[0]).text()
                self.addDataColumn(colName=colName,
                                   expr=self.expressions[colName],
                                   new=False)
            else:
                QMessageBox.warning(
                    self, 'Column Selection Error',
                    'Please select only elements of a single column.',
                    QMessageBox.Ok)
        else:
            QMessageBox.warning(self, 'Data error', 'There is no data',
                                QMessageBox.Ok)

    def addDataColumn(self, colName='Col_X', expr=None, new=True):
        if self.data is not None:
            row, col = self.data['data'].shape
            self.insertColDialog = InsertCol_Dialog(colName=colName,
                                                    minCounter=1,
                                                    maxCounter=row,
                                                    expr=expr)
            if self.insertColDialog.exec_():
                imin = eval(self.insertColDialog.minCounterLineEdit.text())
                imax = eval(self.insertColDialog.maxCounterLineEdit.text())
                i = arange(imin, imax + 1)
                colname = self.insertColDialog.colNameLineEdit.text()
                data = copy.copy(self.data)
                if new:
                    if colname not in self.data['data'].columns:
                        try:
                            self.data['data'][colname] = eval(expr)
                        except:
                            try:
                                expr = self.insertColDialog.colExprTextEdit.toPlainText(
                                )
                                cexpr = expr.replace('col',
                                                     "self.data['data']")
                                self.data['data'][colname] = eval(cexpr)
                                self.data['meta']['col_names'].append(colname)
                            except:
                                QMessageBox.warning(
                                    self, 'Column Error',
                                    'Please check the expression.\n The expression should be in this format:\n col[column_name]*5',
                                    QMessageBox.Ok)
                                self.addDataColumn(colName='Col_X', expr=expr)
                        self.expressions[colname] = expr
                        self.setData2Table()
                        self.setMeta2Table()
                        self.dataAltered = True
                        self.resetPlotSetup()
                        self.dataAltered = False
                    else:
                        QMessageBox.warning(
                            self, 'Column Name Error',
                            'Please choose different column name than the exisiting ones',
                            QMessageBox.Ok)
                        self.addDataColumn(colName='Col_X', expr=expr)
                else:
                    try:
                        self.data['data'][colname] = eval(expr)
                    except:
                        try:
                            expr = self.insertColDialog.colExprTextEdit.toPlainText(
                            )
                            cexpr = expr.replace('col', "self.data['data\']")
                            self.data['data'][colname] = eval(cexpr)
                        except:
                            QMessageBox.warning(
                                self, 'Column Error',
                                'Please check the expression.\n The expression should be in this format:\n col[column_name]*5',
                                QMessageBox.Ok)
                            self.addDataColumn(colName='Col_X', expr=expr)
                        self.expressions[colname] = expr
                        self.setData2Table()
                        self.setMeta2Table()
                        self.dataAltered = True
                        self.resetPlotSetup()
                        self.dataAltered = False
        else:
            self.data = {}
            self.insertColDialog = InsertCol_Dialog(colName=colName,
                                                    minCounter=1,
                                                    maxCounter=100,
                                                    expr=expr)
            if self.insertColDialog.exec_():
                imin = eval(self.insertColDialog.minCounterLineEdit.text())
                imax = eval(self.insertColDialog.maxCounterLineEdit.text())
                i = arange(imin, imax + 1)
                colname = self.insertColDialog.colNameLineEdit.text()
                expr = self.insertColDialog.colExprTextEdit.toPlainText()
                expr = expr.replace('col.', "self.data['data']")
                try:
                    self.data['data'] = pd.DataFrame(eval(expr),
                                                     columns=[colname])
                    self.data['meta'] = {}
                    self.data['meta']['col_names'] = [colname]
                    self.setData2Table()
                    self.setMeta2Table()
                    self.dataAltered = True
                    self.resetPlotSetup()
                    self.dataAltered = False
                    self.saveDataPushButton.setEnabled(True)
                    self.addRowPushButton.setEnabled(True)
                    self.removeRowsPushButton.setEnabled(True)
                    self.removeColumnPushButton.setEnabled(True)
                    self.expressions[colname] = expr
                except:
                    QMessageBox.warning(
                        self, 'Column Error',
                        'Please check the expression.\n The expression should be in this format:\n col.column_name*5',
                        QMessageBox.Ok)
                    self.data = None
                    self.addDataColumn(colName='Col_X', expr=expr)

    def removeDataColumn(self):
        """
        Removes selected columns from dataTableWidget
        """
        colIndexes = [
            index.column() for index in
            self.dataTableWidget.selectionModel().selectedColumns()
        ]
        colIndexes.sort(reverse=True)
        if self.dataTableWidget.columnCount() - len(
                colIndexes) >= 2 or self.plotSetupTableWidget.rowCount() == 0:
            for index in colIndexes:
                colname = self.data['meta']['col_names'][index]
                self.data['meta']['col_names'].pop(index)
                del self.expressions[colname]
                self.dataTableWidget.removeColumn(index)
            if self.dataTableWidget.columnCount() != 0:
                self.getDataFromTable()
                self.setMeta2Table()
                self.dataAltered = True
                self.resetPlotSetup()
                self.dataAltered = False
            else:
                self.data['data'] = None
                self.dataTableWidget.clear()
                #self.metaDataTableWidget.clear()
                self.autoUpdateCheckBox.setEnabled(False)
                self.saveDataPushButton.setEnabled(False)
                self.addRowPushButton.setEnabled(False)
                self.removeRowsPushButton.setEnabled(False)
                self.removeColumnPushButton.setEnabled(False)
        else:
            QMessageBox.warning(
                self, 'Remove Error',
                'Cannot remove these many columns because Data Dialog needs to have atleast two columns',
                QMessageBox.Ok)

    def removeDataRows(self):
        rowIndexes = [
            index.row()
            for index in self.dataTableWidget.selectionModel().selectedRows()
        ]
        rowIndexes.sort(reverse=True)
        if len(rowIndexes) > 0:
            ans = QMessageBox.question(
                self, 'Confirmation',
                'Are you sure of removing the selected rows?', QMessageBox.Yes,
                QMessageBox.No)
            if ans == QMessageBox.Yes:
                for i in rowIndexes:
                    self.dataTableWidget.removeRow(i)
                self.getDataFromTable()
                self.dataAltered = True
                self.resetPlotSetup()
                self.dataAltered = False

    def setMeta2Table(self):
        """
        Populates the metaDataTable widget with metadata available from the data
        """
        try:
            self.metaDataTableWidget.itemChanged.disconnect()
            self.metaDataTableWidget.itemSelectionChanged.disconnect()
        except:
            pass
        self.metaDataTableWidget.clear()
        self.metaDataTableWidget.setColumnCount(2)
        self.metaDataTableWidget.setRowCount(len(self.data['meta'].keys()))
        for num, key in enumerate(self.data['meta'].keys()):
            self.metaDataTableWidget.setItem(num, 0, QTableWidgetItem(key))
            self.metaDataTableWidget.setItem(
                num, 1, QTableWidgetItem(str(self.data['meta'][key])))
        if 'col_names' not in self.data['meta'].keys():
            self.data['meta']['col_names'] = self.data['data'].columns.tolist()
            self.metaDataTableWidget.insertRow(
                self.metaDataTableWidget.rowCount())
            self.metaDataTableWidget.setItem(num + 1, 0,
                                             QTableWidgetItem('col_names'))
            self.metaDataTableWidget.setItem(
                num + 1, 1,
                QTableWidgetItem(str(self.data['meta']['col_names'])))
        self.metaDataTableWidget.setHorizontalHeaderLabels(
            ['Parameter', 'Value'])
        self.metaDataTableWidget.itemChanged.connect(self.metaDataChanged)
        self.metaDataTableWidget.itemSelectionChanged.connect(
            self.metaDataSelectionChanged)

    def getMetaFromTable(self):
        self.data['meta'] = {}
        for i in range(self.metaDataTableWidget.rowCount()):
            try:
                self.data['meta'][self.metaDataTableWidget.item(
                    i, 0).text()] = eval(
                        self.metaDataTableWidget.item(i, 1).text())
            except:
                self.data['meta'][self.metaDataTableWidget.item(
                    i, 0).text()] = self.metaDataTableWidget.item(i, 1).text()

    def setData2Table(self):
        """
        Populates the dataTableWidget with data available from data
        """
        try:
            self.dataTableWidget.itemChanged.disconnect()
        except:
            pass
        self.dataTableWidget.clear()
        self.dataTableWidget.setColumnCount(len(self.data['data'].columns))
        self.dataTableWidget.setRowCount(len(self.data['data'].index))
        for j, colname in enumerate(self.data['data'].columns):
            if colname not in self.expressions.keys():
                self.expressions[colname] = "col['%s']" % colname
            for i in range(len(self.data['data'].index)):
                #self.dataTableWidget.setItem(i,j,QTableWidgetItem(str(self.data['data'][colname][i])))
                self.dataTableWidget.setItem(
                    i, j,
                    QCustomTableWidgetItem(self.data['data'][colname][i]))
        self.dataTableWidget.setHorizontalHeaderLabels(
            self.data['data'].columns.values.tolist())
        self.dataTableWidget.itemChanged.connect(self.dataChanged)

    def getDataFromTable(self):
        self.data['data'] = pd.DataFrame()
        for col in range(self.dataTableWidget.columnCount()):
            label = self.dataTableWidget.horizontalHeaderItem(col).text()
            self.data['data'][label] = array([
                float(self.dataTableWidget.item(i, col).text())
                for i in range(self.dataTableWidget.rowCount())
            ])

    def readData(self, fname, skiprows=0, comment='#', delimiter=' '):
        """
        Read data from a file and put it in dictionary structure with keys 'meta' and 'data' and the data would look like the following
        data={'meta':meta_dictionary,'data'=pandas_dataframe}
        """
        if os.path.exists(os.path.abspath(fname)):
            self.data = {}
            self.fname = fname
            self.dataFileLineEdit.setText(self.fname)
            self.cwd = os.path.dirname(self.fname)
            fh = open(os.path.abspath(self.fname), 'r')
            lines = fh.readlines()
            fh.close()
            self.data['meta'] = {}
            for line in lines[skiprows:]:
                if line[0] == comment:
                    try:
                        key, value = line[1:].strip().split('=')
                        try:
                            self.data['meta'][key] = eval(
                                value
                            )  # When the value is either valid number, lists, arrays, dictionaries
                        except:
                            self.data['meta'][
                                key] = value  # When the value is just a string
                    except:
                        pass
                else:
                    if '\t' in line:
                        delimiter = '\t'
                    elif ',' in line:
                        delimiter = ','
                    elif ' ' in line:
                        delimiter = ' '
                    break
            if 'col_names' in self.data['meta'].keys():
                self.data['data'] = pd.read_csv(
                    self.fname,
                    comment=comment,
                    names=self.data['meta']['col_names'],
                    header=None,
                    sep=delimiter)
                if not all(self.data['data'].isnull().values):
                    self.data['data'] = pd.DataFrame(
                        loadtxt(self.fname, skiprows=skiprows),
                        columns=self.data['meta']['col_names'])
            else:
                self.data['data'] = pd.read_csv(self.fname,
                                                comment=comment,
                                                header=None,
                                                sep=delimiter)
                if not all(self.data['data'].isnull()):
                    self.data['data'] = pd.DataFrame(
                        loadtxt(self.fname, skiprows=skiprows))
                self.data['data'].columns = [
                    'Col_%d' % i
                    for i in self.data['data'].columns.values.tolist()
                ]
                self.data['meta']['col_names'] = self.data[
                    'data'].columns.values.tolist()
            self.autoUpdate_ON_OFF()
            self.autoUpdateCheckBox.setEnabled(True)
            self.saveDataPushButton.setEnabled(True)
            self.addRowPushButton.setEnabled(True)
            self.removeRowsPushButton.setEnabled(True)
            self.removeColumnPushButton.setEnabled(True)
            return self.data
        else:
            QMessageBox.warning(self, 'File Error', 'The file doesnot exists!')
            return None

    def fileUpdated(self, fname):
        QTest.qWait(1000)
        self.readData(fname=fname)
        if self.data is not None:
            self.setMeta2Table()
            self.setData2Table()
            self.dataAltered = True
            self.resetPlotSetup()
            self.dataAltered = False

    def autoUpdate_ON_OFF(self):
        files = self.fileWatcher.files()
        if len(files) != 0:
            self.fileWatcher.removePaths(files)
        if self.autoUpdateCheckBox.isChecked():
            self.fileWatcher.addPath(self.fname)

    def saveData(self):
        """
        Save data to a file
        """
        fname = QFileDialog.getSaveFileName(self,
                                            'Save file as',
                                            self.cwd,
                                            filter='*.*')[0]
        if fname != '':
            ext = os.path.splitext(fname)[1]
            if ext == '':
                ext = '.txt'
                fname = fname + ext
            header = 'File saved on %s\n' % time.asctime()
            for key in self.data['meta'].keys():
                header = header + '%s=%s\n' % (key, str(
                    self.data['meta'][key]))
            if 'col_names' not in self.data['meta'].keys():
                header = header + 'col_names=%s\n' % str(
                    self.data['data'].columns.tolist())
            savetxt(fname,
                    self.data['data'].values,
                    header=header,
                    comments='#')

    def openFile(self):
        """
        Opens a openFileDialog to open a data file
        """
        if self.cwd is not None:
            fname = QFileDialog.getOpenFileName(self,
                                                'Select a data file to open',
                                                directory=self.cwd,
                                                filter='*.*')[0]
        else:
            fname = QFileDialog.getOpenFileName(self,
                                                'Select a data file to open',
                                                directory='',
                                                filter='*.*')[0]
        if fname != '':
            self.data = self.readData(fname=fname)
            if self.data is not None:
                self.setMeta2Table()
                self.setData2Table()
                self.dataAltered = True
                self.resetPlotSetup()
                self.dataAltered = False

    def resetPlotSetup(self):
        try:
            self.plotSetupTableWidget.cellChanged.disconnect()
        except:
            pass
        columns = self.data['data'].columns.tolist()
        self.xlabel = []
        self.ylabel = []
        for row in range(self.plotSetupTableWidget.rowCount()):
            for i in range(1, 3):
                self.plotSetupTableWidget.cellWidget(
                    row, i).currentIndexChanged.disconnect()
                self.plotSetupTableWidget.cellWidget(row, i).clear()
                self.plotSetupTableWidget.cellWidget(row, i).addItems(columns)
                self.plotSetupTableWidget.cellWidget(row,
                                                     i).setCurrentIndex(i - 1)
                self.plotSetupTableWidget.cellWidget(
                    row, i).currentIndexChanged.connect(self.updateCellData)
            self.xlabel.append(
                '[%s]' %
                self.plotSetupTableWidget.cellWidget(row, 1).currentText())
            self.ylabel.append(
                '[%s]' %
                self.plotSetupTableWidget.cellWidget(row, 2).currentText())
            self.plotSetupTableWidget.cellWidget(
                row, 3).currentIndexChanged.disconnect()
            self.plotSetupTableWidget.cellWidget(row, 3).clear()
            self.plotSetupTableWidget.cellWidget(row, 3).addItems(['None'] +
                                                                  columns)
            self.plotSetupTableWidget.cellWidget(row, 3).setCurrentIndex(0)
            self.plotSetupTableWidget.cellWidget(
                row, 3).currentIndexChanged.connect(self.updateCellData)
            self.plotSetupTableWidget.setCurrentCell(row, 3)
            color = self.plotSetupTableWidget.cellWidget(row, 4).color()
            self.plotSetupTableWidget.setCellWidget(
                row, 4, pg.ColorButton(color=color))
            self.plotSetupTableWidget.cellWidget(
                row, 4).sigColorChanging.connect(self.updateCellData)
            self.plotSetupTableWidget.cellWidget(
                row, 4).sigColorChanged.connect(self.updateCellData)
            self.updatePlotData(row, i)
        self.plotSetupTableWidget.cellChanged.connect(self.updatePlotData)

    def addMultiPlots(self, plotIndex=None, colors=None):
        for key in plotIndex.keys():
            pi = plotIndex[key]
            if colors is None:
                color = next(self.colcycler
                             )  #array([random.randint(200, high=255),0,0])
                print(color)
            else:
                color = colors[key]
            self.addPlots(plotIndex=pi, color=color)

    def addPlots(self, plotIndex=None, color=None):
        #self.plotSetupTableWidget.clear()
        # if self.parentWidget() is None or self.plotSetupTableWidget.rowCount()==0:
        try:
            self.plotSetupTableWidget.cellChanged.disconnect()
        except:
            pass
        columns = self.data['data'].columns.tolist()
        if len(columns) >= 2:
            self.plotSetupTableWidget.insertRow(
                self.plotSetupTableWidget.rowCount())
            row = self.plotSetupTableWidget.rowCount() - 1
            self.plotSetupTableWidget.setItem(
                row, 0, QTableWidgetItem('Data_%d' % self.plotNum))
            for i in range(1, 3):
                self.plotSetupTableWidget.setCellWidget(row, i, QComboBox())
                self.plotSetupTableWidget.cellWidget(row, i).addItems(columns)
                if plotIndex is not None:
                    self.plotSetupTableWidget.cellWidget(
                        row, i).setCurrentIndex(plotIndex[i - 1])
                else:
                    self.plotSetupTableWidget.cellWidget(
                        row, i).setCurrentIndex(i - 1)
                self.plotSetupTableWidget.cellWidget(
                    row, i).currentIndexChanged.connect(self.updateCellData)
            self.xlabel.append(
                '[%s]' %
                self.plotSetupTableWidget.cellWidget(row, 1).currentText())
            self.ylabel.append(
                '[%s]' %
                self.plotSetupTableWidget.cellWidget(row, 2).currentText())
            self.plotSetupTableWidget.setCellWidget(row, 3, QComboBox())
            self.plotSetupTableWidget.cellWidget(row, 3).addItems(['None'] +
                                                                  columns)
            if color is None:
                color = next(self.colcycler
                             )  #array([random.randint(200, high=255),0,0])
            self.plotSetupTableWidget.setCellWidget(
                row, 4, pg.ColorButton(color=color))
            self.plotSetupTableWidget.cellWidget(
                row, 4).sigColorChanging.connect(self.updateCellData)
            self.plotSetupTableWidget.cellWidget(
                row, 4).sigColorChanged.connect(self.updateCellData)
            if plotIndex is not None:
                self.plotSetupTableWidget.cellWidget(row, 3).setCurrentIndex(
                    plotIndex[-1])
            else:
                # try:
                #     self.plotSetupTableWidget.cellWidget(row,3).setCurrentIndex(2)
                # except:
                #
                self.plotSetupTableWidget.cellWidget(row, 3).setCurrentIndex(0)
            self.plotSetupTableWidget.cellWidget(
                row, 3).currentIndexChanged.connect(self.updateCellData)
            self.plotSetupTableWidget.setCurrentCell(row, 3)
            self.updatePlotData(row, 3)
            self.plotNum += 1
        else:
            QMessageBox.warning(
                self, 'Data file error',
                'The data file do not have two or more columns to be plotted.',
                QMessageBox.Ok)
        self.plotSetupTableWidget.cellChanged.connect(self.updatePlotData)
        # else:
        #     QMessageBox.warning(self,'Warning','As the Data Dialog is used within another widget you cannot add more plots',QMessageBox.Ok)

    def removePlots(self):
        """
        Removes data for PlotSetup
        """
        try:
            self.plotSetupTableWidget.cellChanged.disconnect()
        except:
            pass
        rowIndexes = self.plotSetupTableWidget.selectionModel().selectedRows()
        selectedRows = [index.row() for index in rowIndexes]
        selectedRows.sort(reverse=True)
        if self.parentWidget() is None:
            for row in selectedRows:
                name = self.plotSetupTableWidget.item(row, 0).text()
                self.plotWidget.remove_data([name])
                self.plotSetupTableWidget.removeRow(row)
        else:
            if self.plotSetupTableWidget.rowCount() - len(rowIndexes) >= 1:
                for row in selectedRows:
                    name = self.plotSetupTableWidget.item(row, 0).text()
                    self.plotWidget.remove_data([name])
                    self.plotSetupTableWidget.removeRow(row)
            else:
                QMessageBox.warning(
                    self, 'Warning',
                    'Cannot remove single plots from Data Dialog because the Data Dialog is used within another widget',
                    QMessageBox.Ok)
        self.updatePlot()
        self.plotSetupTableWidget.cellChanged.connect(self.updatePlotData)

    def updatePlotData(self, row, col):
        #row=self.plotSetupTableWidget.currentRow()
        name = self.plotSetupTableWidget.item(row, 0).text()
        if self.dataAltered:
            for i in range(1, 4):
                try:
                    self.plotSetupTableWidget.cellWidget(
                        row, i).setCurrentIndex(self.oldPlotIndex[name][i - 1])
                except:
                    pass
        xcol, ycol, yerrcol = [
            self.plotSetupTableWidget.cellWidget(row, i).currentText()
            for i in range(1, 4)
        ]
        #ycol=self.plotSetupTableWidget.cellWidget(row,2).currentText()
        #yerrcol=self.plotSetupTableWidget.cellWidget(row,3).currentText()
        if yerrcol != 'None':
            if ycol == 'fit':
                self.plotWidget.add_data(
                    self.data['data'][xcol].values,
                    self.data['data'][ycol].values,
                    yerr=self.data['data'][yerrcol].values,
                    name=name,
                    fit=True,
                    color=self.plotSetupTableWidget.cellWidget(row, 4).color())
            else:
                self.plotWidget.add_data(
                    self.data['data'][xcol].values,
                    self.data['data'][ycol].values,
                    yerr=self.data['data'][yerrcol].values,
                    name=name,
                    fit=False,
                    color=self.plotSetupTableWidget.cellWidget(row, 4).color())
        else:
            if ycol == 'fit':
                self.plotWidget.add_data(
                    self.data['data'][xcol].values,
                    self.data['data'][ycol].values,
                    name=name,
                    fit=True,
                    color=self.plotSetupTableWidget.cellWidget(row, 4).color())
            else:
                self.plotWidget.add_data(
                    self.data['data'][xcol].values,
                    self.data['data'][ycol].values,
                    name=name,
                    fit=False,
                    color=self.plotSetupTableWidget.cellWidget(row, 4).color())
        self.xlabel[row] = '[%s]' % self.plotSetupTableWidget.cellWidget(
            row, 1).currentText()
        self.ylabel[row] = '[%s]' % self.plotSetupTableWidget.cellWidget(
            row, 2).currentText()
        self.updatePlot()
        self.oldPlotIndex[name] = [
            self.plotSetupTableWidget.cellWidget(row, i).currentIndex()
            for i in range(1, 4)
        ]

    def updateCellData(self, index):
        row = self.plotSetupTableWidget.indexAt(self.sender().pos()).row()
        self.updatePlotData(row, index)

    def updatePlot(self):
        self.make_default()
        names = [
            self.plotSetupTableWidget.item(i, 0).text()
            for i in range(self.plotSetupTableWidget.rowCount())
        ]
        #self.plotColIndex=[self.plotSetupTableWidget.cellWidget(0,i).currentIndex() for i in range(1,4)]
        self.plotColIndex = {}
        self.externalData = {}
        self.plotColors = {}
        for i in range(self.plotSetupTableWidget.rowCount()):
            key = self.plotSetupTableWidget.cellWidget(i, 2).currentText()
            self.plotColIndex[key] = [
                self.plotSetupTableWidget.cellWidget(i, j).currentIndex()
                for j in range(1, 4)
            ]
            self.plotColors[key] = self.plotSetupTableWidget.cellWidget(
                i, 4).color()
            self.externalData[key] = copy.copy(self.data['meta'])
            self.externalData[key]['x'] = copy.copy(
                self.data['data'][self.plotSetupTableWidget.cellWidget(
                    i, 1).currentText()].values)
            self.externalData[key]['y'] = copy.copy(
                self.data['data'][self.plotSetupTableWidget.cellWidget(
                    i, 2).currentText()].values)
            if self.plotSetupTableWidget.cellWidget(i,
                                                    3).currentText() == 'None':
                self.externalData[key]['yerr'] = ones_like(
                    self.externalData[key]['x'])
            else:
                self.externalData[key]['yerr'] = copy.copy(
                    self.data['data'][self.plotSetupTableWidget.cellWidget(
                        i, 3).currentText()].values)
            self.externalData[key][
                'color'] = self.plotSetupTableWidget.cellWidget(i, 4).color()
        self.plotWidget.Plot(names)
        self.plotWidget.setXLabel(' '.join(self.xlabel))
        self.plotWidget.setYLabel(' '.join(self.ylabel))
Ejemplo n.º 23
0
    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(726, 588)
        self.verticalLayout = QtGui.QVBoxLayout(Form)
        self.verticalLayout.setSpacing(0)
        self.verticalLayout.setMargin(0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.splitter = QtGui.QSplitter(Form)
        self.splitter.setOrientation(QtCore.Qt.Vertical)
        self.splitter.setObjectName("splitter")
        self.layoutWidget = QtGui.QWidget(self.splitter)
        self.layoutWidget.setObjectName("layoutWidget")
        self.gridLayout = QtGui.QGridLayout(self.layoutWidget)
        self.gridLayout.setMargin(0)
        self.gridLayout.setSpacing(0)
        self.gridLayout.setObjectName("gridLayout")
        self.graphicsView = GraphicsView(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(10)
        sizePolicy.setVerticalStretch(10)
        sizePolicy.setHeightForWidth(self.graphicsView.sizePolicy().hasHeightForWidth())
        self.graphicsView.setSizePolicy(sizePolicy)
        self.graphicsView.setObjectName("graphicsView")
        self.gridLayout.addWidget(self.graphicsView, 1, 0, 3, 1)
        self.roiBtn = QtGui.QPushButton(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.roiBtn.sizePolicy().hasHeightForWidth())
        self.roiBtn.setSizePolicy(sizePolicy)
        self.roiBtn.setMaximumSize(QtCore.QSize(30, 16777215))
        self.roiBtn.setCheckable(True)
        self.roiBtn.setObjectName("roiBtn")
        self.gridLayout.addWidget(self.roiBtn, 3, 3, 1, 1)
        self.gradientWidget = GradientWidget(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Expanding)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(100)
        sizePolicy.setHeightForWidth(self.gradientWidget.sizePolicy().hasHeightForWidth())
        self.gradientWidget.setSizePolicy(sizePolicy)
        self.gradientWidget.setObjectName("gradientWidget")
        self.gridLayout.addWidget(self.gradientWidget, 1, 3, 1, 1)
        self.normBtn = QtGui.QPushButton(self.layoutWidget)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Minimum, QtGui.QSizePolicy.Fixed)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(1)
        sizePolicy.setHeightForWidth(self.normBtn.sizePolicy().hasHeightForWidth())
        self.normBtn.setSizePolicy(sizePolicy)
        self.normBtn.setMaximumSize(QtCore.QSize(30, 16777215))
        self.normBtn.setCheckable(True)
        self.normBtn.setObjectName("normBtn")
        self.gridLayout.addWidget(self.normBtn, 2, 3, 1, 1)
        self.normGroup = QtGui.QGroupBox(self.layoutWidget)
        self.normGroup.setObjectName("normGroup")
        self.gridLayout_2 = QtGui.QGridLayout(self.normGroup)
        self.gridLayout_2.setMargin(0)
        self.gridLayout_2.setSpacing(0)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.normSubtractRadio = QtGui.QRadioButton(self.normGroup)
        self.normSubtractRadio.setObjectName("normSubtractRadio")
        self.gridLayout_2.addWidget(self.normSubtractRadio, 0, 2, 1, 1)
        self.normDivideRadio = QtGui.QRadioButton(self.normGroup)
        self.normDivideRadio.setChecked(False)
        self.normDivideRadio.setObjectName("normDivideRadio")
        self.gridLayout_2.addWidget(self.normDivideRadio, 0, 1, 1, 1)
        self.label_5 = QtGui.QLabel(self.normGroup)
        font = QtGui.QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label_5.setFont(font)
        self.label_5.setObjectName("label_5")
        self.gridLayout_2.addWidget(self.label_5, 0, 0, 1, 1)
        self.label_3 = QtGui.QLabel(self.normGroup)
        font = QtGui.QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label_3.setFont(font)
        self.label_3.setObjectName("label_3")
        self.gridLayout_2.addWidget(self.label_3, 1, 0, 1, 1)
        self.label_4 = QtGui.QLabel(self.normGroup)
        font = QtGui.QFont()
        font.setWeight(75)
        font.setBold(True)
        self.label_4.setFont(font)
        self.label_4.setObjectName("label_4")
        self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1)
        self.normROICheck = QtGui.QCheckBox(self.normGroup)
        self.normROICheck.setObjectName("normROICheck")
        self.gridLayout_2.addWidget(self.normROICheck, 1, 1, 1, 1)
        self.normXBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
        self.normXBlurSpin.setObjectName("normXBlurSpin")
        self.gridLayout_2.addWidget(self.normXBlurSpin, 2, 2, 1, 1)
        self.label_8 = QtGui.QLabel(self.normGroup)
        self.label_8.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label_8.setObjectName("label_8")
        self.gridLayout_2.addWidget(self.label_8, 2, 1, 1, 1)
        self.label_9 = QtGui.QLabel(self.normGroup)
        self.label_9.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label_9.setObjectName("label_9")
        self.gridLayout_2.addWidget(self.label_9, 2, 3, 1, 1)
        self.normYBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
        self.normYBlurSpin.setObjectName("normYBlurSpin")
        self.gridLayout_2.addWidget(self.normYBlurSpin, 2, 4, 1, 1)
        self.label_10 = QtGui.QLabel(self.normGroup)
        self.label_10.setAlignment(QtCore.Qt.AlignRight|QtCore.Qt.AlignTrailing|QtCore.Qt.AlignVCenter)
        self.label_10.setObjectName("label_10")
        self.gridLayout_2.addWidget(self.label_10, 2, 5, 1, 1)
        self.normOffRadio = QtGui.QRadioButton(self.normGroup)
        self.normOffRadio.setChecked(True)
        self.normOffRadio.setObjectName("normOffRadio")
        self.gridLayout_2.addWidget(self.normOffRadio, 0, 3, 1, 1)
        self.normTimeRangeCheck = QtGui.QCheckBox(self.normGroup)
        self.normTimeRangeCheck.setObjectName("normTimeRangeCheck")
        self.gridLayout_2.addWidget(self.normTimeRangeCheck, 1, 3, 1, 1)
        self.normFrameCheck = QtGui.QCheckBox(self.normGroup)
        self.normFrameCheck.setObjectName("normFrameCheck")
        self.gridLayout_2.addWidget(self.normFrameCheck, 1, 2, 1, 1)
        self.normTBlurSpin = QtGui.QDoubleSpinBox(self.normGroup)
        self.normTBlurSpin.setObjectName("normTBlurSpin")
        self.gridLayout_2.addWidget(self.normTBlurSpin, 2, 6, 1, 1)
        self.gridLayout.addWidget(self.normGroup, 0, 0, 1, 4)
        self.roiPlot = PlotWidget(self.splitter)
        sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred, QtGui.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(self.roiPlot.sizePolicy().hasHeightForWidth())
        self.roiPlot.setSizePolicy(sizePolicy)
        self.roiPlot.setMinimumSize(QtCore.QSize(0, 40))
        self.roiPlot.setObjectName("roiPlot")
        self.verticalLayout.addWidget(self.splitter)

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)
Ejemplo n.º 24
0
Archivo: UI.py Proyecto: wkoder/mooi
class MainWindow(QMainWindow):

    __PREF_GEOM__ = "UI/Geometry"
    __PREF_STATE__ = "UI/State"
    __PREF_DIR__ = "Config/Directories"
    __PREF_SAVE__ = "Config/SaveDirectory"
    __PREF_SAVE_ALL__ = "Config/SaveAllDirectory"

    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)

        self.analyzer = Analyzer()
        self.currentSolution = None

        self._buildUI()
        self._loadSettings()
        QTimer.singleShot(0, self._loadInitialData)

    def _buildUI(self):
        self.setWindowTitle("MOOI: Multi-Objective Optimization Interface")
        self.resize(840, 480)
        self.statusBar().setSizeGripEnabled(False)
        self.statusBar().showMessage("Loading initial data...")

        # Plot widget
        self.plot = PlotWidget()
        self.plot.setMinimumSize(320, 480)
        self.plot.setAlignment(Qt.AlignCenter)
        self.plot.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.plot)

        # Function widget
        self.functionWidget = QListWidget()
        self.functionWidget.itemSelectionChanged.connect(self.solutionSelected)
        rightDock = QDockWidget("Functions", self)
        rightDock.setObjectName("Functions")
        rightDock.setWidget(self.functionWidget)
        rightDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.RightDockWidgetArea, rightDock)

        # Control widget
        self.showSolutionsRadio = QRadioButton("Functions")
        self.showSolutionsRadio.setChecked(True)
        self.showSolutionsRadio.toggled.connect(self._showSolution)
        self.showVariablesRadio = QRadioButton("Variables")

        radioWidget = QWidget()
        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.showSolutionsRadio)
        radioLayout.addWidget(self.showVariablesRadio)
        radioWidget.setLayout(radioLayout)

        self.generationLabel = QLabel("Run: 1")
        self.generationSlider = QSlider(Qt.Horizontal)
        self.generationSlider.setTickPosition(QSlider.TicksBothSides)
        self.generationSlider.setTracking(True)
        self.generationSlider.setMinimum(1)
        self.generationSlider.setMaximum(1)
        self.generationSlider.setTickInterval(1)
        self.generationSlider.valueChanged.connect(self._showSolution)

        self.solutionSelector = QWidget()
        self.solutionSelector.setLayout(QVBoxLayout())
        addSolutionButton = QPushButton("Add")
        addSolutionButton.clicked.connect(self.addImplementation)
        removeSolutionButton = QPushButton("Remove unselected")
        removeSolutionButton.clicked.connect(self.removeResult)
        solutionSelectorButtons = QWidget()
        solutionSelectorButtons.setLayout(QHBoxLayout())
        solutionSelectorButtons.layout().addWidget(addSolutionButton)
        solutionSelectorButtons.layout().addWidget(removeSolutionButton)
        self.solutionSelectorWidget = QWidget()
        self.solutionSelectorWidget.setLayout(QVBoxLayout())
        self.solutionSelectorWidget.layout().addWidget(solutionSelectorButtons)
        self.solutionSelectorWidget.layout().addWidget(self.solutionSelector)

        exportButton = QPushButton("Export image")
        exportButton.clicked.connect(self.exportImage)

        exportAllButton = QPushButton("Export all images")
        exportAllButton.clicked.connect(self.exportAllImages)

        computeMetricsButton = QPushButton("Compute metrics")
        computeMetricsButton.clicked.connect(self.computeMetricsAsync)

        refreshButton = QPushButton("Refresh")
        refreshButton.clicked.connect(self.updateUI)

        controlLayout = QVBoxLayout()
        controlLayout.addWidget(radioWidget)
        controlLayout.addWidget(self.generationLabel)
        controlLayout.addWidget(self.generationSlider)
        controlLayout.addWidget(self.solutionSelectorWidget)
        controlLayout.addStretch()
        controlLayout.addWidget(computeMetricsButton)
        controlLayout.addWidget(refreshButton)
        controlLayout.addWidget(exportButton)
        controlLayout.addWidget(exportAllButton)
        controlWidget = QWidget()
        controlWidget.setLayout(controlLayout)
        leftDock = QDockWidget("Control", self)
        leftDock.setObjectName("Control")
        leftDock.setWidget(controlWidget)
        leftDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, leftDock)

        # Metric widget
        self.metrics = MetricsPanel(self.analyzer)
        bottomDock = QDockWidget("Metrics", self)
        bottomDock.setObjectName("Metrics")
        bottomDock.setWidget(self.metrics)
        bottomDock.setFeatures(QDockWidget.DockWidgetFloatable | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.BottomDockWidgetArea, bottomDock)

        # Actions
        exitAction = QAction("&Exit", self)
        exitAction.setShortcut("Ctrl+Q")
        exitAction.setStatusTip("Exit application")
        exitAction.triggered.connect(qApp.quit)

        copyAction = QAction("&Copy", self)
        copyAction.setShortcut("Ctrl+C")
        copyAction.setStatusTip("Copy metrics")
        copyAction.triggered.connect(self.metrics.copyMetrics)

        aboutAction = QAction("&About", self)
        aboutAction.setStatusTip("About MOOI")
        aboutAction.triggered.connect(self.helpAbout)

        # Menus
        menubar = self.menuBar()
        fileMenu = menubar.addMenu("&File")
        fileMenu.addAction(copyAction)
        fileMenu.addAction(aboutAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)

    def _loadSettings(self):
        settings = QSettings()
        self.restoreState(settings.value(MainWindow.__PREF_STATE__).toByteArray())
        self.restoreGeometry(settings.value(MainWindow.__PREF_GEOM__).toByteArray())

        paretoDirectory = __RESOURCES_DIR__ + Analyzer.__PARETO__
        self.analyzer.setPareto(paretoDirectory)
        currentDirs = settings.value(MainWindow.__PREF_DIR__)
        if currentDirs is not None:
            self.analyzer.setResultDirectories([directory.toString() for directory in currentDirs.toList()])

        self._updateSolutionSelection()

    def exportImage(self):
        settings = QSettings()
        filename = settings.value(MainWindow.__PREF_SAVE__)
        if filename is None:
            filename = os.path.dirname(__file__)
        else:
            filename = os.path.abspath(os.path.join(str(filename.toString()), os.path.pardir)) + "/"
        filename += "%s_%s.png" % (
            self.currentSolution.functionName,
            "fun" if self.isFunctionSpaceSelected() else "var",
        )

        filename = QFileDialog.getSaveFileName(self, "Export image as", filename, ("PNG image (*.png)"))
        if filename is None or filename == "":
            return

        settings.setValue(MainWindow.__PREF_SAVE__, QVariant(filename))
        self._exportCurrentImage(filename)
        self.statusBar().showMessage("Image saved!", 5000)

    def isFunctionSpaceSelected(self):
        return self.showSolutionsRadio.isChecked()

    def _exportCurrentImage(self, filename=None):
        generation = self.generationSlider.value()
        self.generationLabel.setText("Run: %d" % generation)

        tmp = filename is None
        if tmp:
            prefix = "mooi_%s_" % self.currentSolution.functionName
            filename = tempfile.mkstemp(prefix=prefix, suffix=".png", text=False)[1]
        resultNames = self._getSelectedResultNames()
        self.analyzer.exportToImage(
            self.currentSolution,
            [generation - 1] * len(resultNames),
            self.isFunctionSpaceSelected(),
            resultNames,
            str(filename),
        )
        if tmp:
            self.plot.setPlotPixmap(filename)
            try:
                os.remove(filename)
            except:
                print >>sys.stderr, "Couldn't delete temporal file: %s" % filename

    def _getSelectedResultNames(self):
        resultNames = []
        for i in xrange(self.analyzer.nResults):
            implementationItem = self.solutionSelector.layout().itemAt(i).widget()
            if implementationItem.isChecked():
                resultNames.append(str(implementationItem.text()))
        return resultNames

    def exportAllImages(self):
        settings = QSettings()
        directory = settings.value(MainWindow.__PREF_SAVE_ALL__).toString()
        directory = QFileDialog.getExistingDirectory(self, "Select a directory to export to", directory)
        if directory is None or not os.path.exists(directory):
            return

        self.analyzer.exportAllImages(directory, self._getSelectedResultNames())
        settings.setValue(MainWindow.__PREF_SAVEL_ALL__, QVariant(directory))
        self.statusBar().showMessage("Images saved!", 5000)

    def computeMetricsAsync(self):
        self.statusBar().showMessage("Computing metrics...")
        QTimer.singleShot(0, self.computeMetrics)

    def computeMetrics(self):
        self._computeMetrics(self.currentSolution.functionName)
        self.statusBar().showMessage("Metrics computed!", 5000)

    def _computeMetrics(self, functionName):
        pareto = self.analyzer.getFunctionPareto(functionName)
        solutions = self.analyzer.getFunctionResults(functionName, self._getSelectedResultNames())
        self.metrics.updateMetrics(pareto, solutions, functionName)

    def helpAbout(self):
        QMessageBox.about(
            self,
            "About Image Changer",
            """<b>Multi-Objective Optimization Interface</b> v%s
            <p>Copyright &copy; 2011-2012 %s All rights reserved.
            <p>This application can be used to perform simple optimization analysis.
            <p><a href='%s'>%s</a>
            <p>Python %s - Qt %s - PyQt %s on %s"""
            % (
                __VERSION__,
                __AUTHOR__,
                __WEBSITE__,
                __WEBSITE__,
                platform.python_version(),
                QT_VERSION_STR,
                PYQT_VERSION_STR,
                platform.system(),
            ),
        )

    def addImplementation(self):
        if self.analyzer.nResults == 0:
            directory = ""
        else:
            directory = os.path.abspath(os.path.join(str(self.analyzer.resultDirectories[-1]), os.path.pardir))
        directory = QFileDialog.getExistingDirectory(
            self, "Select a directory to scan", directory, QFileDialog.ShowDirsOnly
        )
        if not os.path.exists(directory) or directory in self.analyzer.resultDirectories:
            return

        self.analyzer.addResultDirectory(directory)
        self.addSolutionForSelection(self.analyzer.getResultName(directory))

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__, QVariant(self.analyzer.resultDirectories))

    def removeResult(self):
        layout = self.solutionSelector.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            item = layout.itemAt(i)
            if not item.widget().isChecked():  # and self.analyzer.resultNames[i] != Analyzer.__PARETO__:
                item.widget().setVisible(False)
                layout.removeItem(item)
                self.analyzer.removeResultDirectory(self.analyzer.resultDirectories[i])
        layout.update()

        settings = QSettings()
        settings.setValue(MainWindow.__PREF_DIR__, QVariant(self.analyzer.resultDirectories))

    def solutionSelected(self):
        selection = self.functionWidget.currentItem()
        if selection is None:
            return
        self.showSolution(str(selection.text()))

    def showSolution(self, functionName):
        self.currentSolution = self.analyzer.getResultsForFunction(functionName)
        self.metrics.clear()
        self._showSolution()

    def addSolutionForSelection(self, name):
        solution = QCheckBox(name)
        solution.setChecked(True)
        solution.stateChanged.connect(self._showSolution)
        self.solutionSelector.layout().addWidget(solution)
        self.solutionSelector.layout().update()

    def _updateSolutionSelection(self):
        self.clearWidget(self.solutionSelector)

        for directory in self.analyzer.resultDirectories:
            self.addSolutionForSelection(self.analyzer.getResultName(directory))

    def _showSolution(self):
        sol = self.currentSolution
        if sol is None:
            return

        if len(sol.variableImplementation) == 0 and self.showVariablesRadio.isEnabled():
            self.showVariablesRadio.setEnabled(False)
            if self.showVariablesRadio.isChecked():
                self.showSolutionsRadio.setChecked(True)
        else:
            self.showVariablesRadio.setEnabled(True)

        if len(sol.functionImplementation) == 0 and self.showSolutionsRadio.isEnabled():
            self.showSolutionsRadio.setEnabled(False)
            if self.showSolutionsRadio.isChecked():
                self.showVariablesRadio.setChecked(True)
        else:
            self.showSolutionsRadio.setEnabled(True)

        if self.showSolutionsRadio.isChecked():
            self.generationSlider.setMaximum(
                max([sol.getFunctionSolution(impl).count() for impl in sol.functionImplementation])
            )
        else:
            self.generationSlider.setMaximum(
                max([sol.getVariableSolution(impl).count() for impl in sol.variableImplementation])
            )
        self._exportCurrentImage()

    def clearWidget(self, widget):
        layout = widget.layout()
        for i in xrange(layout.count() - 1, -1, -1):
            layout.removeItem(layout.itemAt(i))

    def updateUI(self):
        self.statusBar().showMessage("Updating solutions...")

        selectedRow = self.functionWidget.currentRow()
        self.functionWidget.clear()
        names = [] + self.analyzer.getFunctionNames()
        names.sort()
        for name in names:
            item = QListWidgetItem()
            item.setText(name)
            self.functionWidget.addItem(item)

        if self.functionWidget.count() > 0:
            self.functionWidget.setCurrentRow(
                selectedRow if selectedRow >= 0 and selectedRow < self.functionWidget.count() else 0
            )
        self.statusBar().showMessage("Updated!", 5000)

    def _loadInitialData(self):
        self.updateUI()
        self.statusBar().showMessage("Ready!", 5000)

    def closeEvent(self, event):
        self.statusBar().showMessage("Closing...")
        settings = QSettings()
        settings.setValue(MainWindow.__PREF_GEOM__, self.saveGeometry())
        settings.setValue(MainWindow.__PREF_STATE__, self.saveState())
        self.plot.clear()
Ejemplo n.º 25
0
    def _buildUI(self):
        self.setWindowTitle("MOOI: Multi-Objective Optimization Interface")
        self.resize(840, 480)
        self.statusBar().setSizeGripEnabled(False)
        self.statusBar().showMessage("Loading initial data...")

        # Plot widget
        self.plot = PlotWidget()
        self.plot.setMinimumSize(320, 480)
        self.plot.setAlignment(Qt.AlignCenter)
        self.plot.setContextMenuPolicy(Qt.ActionsContextMenu)
        self.setCentralWidget(self.plot)

        # Function widget
        self.functionWidget = QListWidget()
        self.functionWidget.itemSelectionChanged.connect(self.solutionSelected)
        rightDock = QDockWidget("Functions", self)
        rightDock.setObjectName("Functions")
        rightDock.setWidget(self.functionWidget)
        rightDock.setFeatures(QDockWidget.DockWidgetFloatable
                              | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.RightDockWidgetArea, rightDock)

        # Control widget
        self.showSolutionsRadio = QRadioButton("Functions")
        self.showSolutionsRadio.setChecked(True)
        self.showSolutionsRadio.toggled.connect(self._showSolution)
        self.showVariablesRadio = QRadioButton("Variables")

        radioWidget = QWidget()
        radioLayout = QHBoxLayout()
        radioLayout.addWidget(self.showSolutionsRadio)
        radioLayout.addWidget(self.showVariablesRadio)
        radioWidget.setLayout(radioLayout)

        self.generationLabel = QLabel("Run: 1")
        self.generationSlider = QSlider(Qt.Horizontal)
        self.generationSlider.setTickPosition(QSlider.TicksBothSides)
        self.generationSlider.setTracking(True)
        self.generationSlider.setMinimum(1)
        self.generationSlider.setMaximum(1)
        self.generationSlider.setTickInterval(1)
        self.generationSlider.valueChanged.connect(self._showSolution)

        self.solutionSelector = QWidget()
        self.solutionSelector.setLayout(QVBoxLayout())
        addSolutionButton = QPushButton("Add")
        addSolutionButton.clicked.connect(self.addImplementation)
        removeSolutionButton = QPushButton("Remove unselected")
        removeSolutionButton.clicked.connect(self.removeResult)
        solutionSelectorButtons = QWidget()
        solutionSelectorButtons.setLayout(QHBoxLayout())
        solutionSelectorButtons.layout().addWidget(addSolutionButton)
        solutionSelectorButtons.layout().addWidget(removeSolutionButton)
        self.solutionSelectorWidget = QWidget()
        self.solutionSelectorWidget.setLayout(QVBoxLayout())
        self.solutionSelectorWidget.layout().addWidget(solutionSelectorButtons)
        self.solutionSelectorWidget.layout().addWidget(self.solutionSelector)

        exportButton = QPushButton("Export image")
        exportButton.clicked.connect(self.exportImage)

        exportAllButton = QPushButton("Export all images")
        exportAllButton.clicked.connect(self.exportAllImages)

        computeMetricsButton = QPushButton("Compute metrics")
        computeMetricsButton.clicked.connect(self.computeMetricsAsync)

        refreshButton = QPushButton("Refresh")
        refreshButton.clicked.connect(self.updateUI)

        controlLayout = QVBoxLayout()
        controlLayout.addWidget(radioWidget)
        controlLayout.addWidget(self.generationLabel)
        controlLayout.addWidget(self.generationSlider)
        controlLayout.addWidget(self.solutionSelectorWidget)
        controlLayout.addStretch()
        controlLayout.addWidget(computeMetricsButton)
        controlLayout.addWidget(refreshButton)
        controlLayout.addWidget(exportButton)
        controlLayout.addWidget(exportAllButton)
        controlWidget = QWidget()
        controlWidget.setLayout(controlLayout)
        leftDock = QDockWidget("Control", self)
        leftDock.setObjectName("Control")
        leftDock.setWidget(controlWidget)
        leftDock.setFeatures(QDockWidget.DockWidgetFloatable
                             | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.LeftDockWidgetArea, leftDock)

        # Metric widget
        self.metrics = MetricsPanel(self.analyzer)
        bottomDock = QDockWidget("Metrics", self)
        bottomDock.setObjectName("Metrics")
        bottomDock.setWidget(self.metrics)
        bottomDock.setFeatures(QDockWidget.DockWidgetFloatable
                               | QDockWidget.DockWidgetMovable)
        self.addDockWidget(Qt.BottomDockWidgetArea, bottomDock)

        # Actions
        exitAction = QAction('&Exit', self)
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(qApp.quit)

        copyAction = QAction("&Copy", self)
        copyAction.setShortcut("Ctrl+C")
        copyAction.setStatusTip('Copy metrics')
        copyAction.triggered.connect(self.metrics.copyMetrics)

        aboutAction = QAction("&About", self)
        aboutAction.setStatusTip('About MOOI')
        aboutAction.triggered.connect(self.helpAbout)

        # Menus
        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(copyAction)
        fileMenu.addAction(aboutAction)
        fileMenu.addSeparator()
        fileMenu.addAction(exitAction)
Ejemplo n.º 26
0
class XYView(View):
    AUTOFIT_MARGIN = 0.03  # 3%

    # See http://matplotlib.org/api/markers_api.html:
    CURVE_MARKERS = [
        "o",  #  circle
        "*",  # star
        "+",  # plus
        "x",  # x
        "s",  # square
        "p",  # pentagon
        "h",  # hexagon1
        "8",  # octagon
        "D",  # diamond
        "^",  # triangle_up
        "<",  # triangle_left
        ">",  # triangle_right
        "1",  # tri_down
        "2",  # tri_up
        "3",  # tri_left
        "4",  # tri_right
        "v",  # triangle_down
        "H",  # hexagon2
        "d",  # thin diamond
        "",  # NO MARKER
    ]

    _DEFAULT_LEGEND_STATE = False  # for test purposes mainly - initial status of the legend

    def __init__(self, controller):
        View.__init__(self, controller)
        self._eventHandler = EventHandler()

        self._curveViews = {}  # key: curve (model) ID, value: CurveView
        self._salomeViewID = None
        self._mplFigure = None
        self._mplAxes = None
        self._mplCanvas = None
        self._plotWidget = None
        self._sgPyQt = self._controller._sgPyQt
        self._toolbar = None
        self._mplNavigationActions = {}
        self._toobarMPL = None
        self._grid = None
        self._currCrv = None  # current curve selected in the view

        self._legend = None
        self._legendLoc = "right"  # "right" or "bottom"

        self._fitArea = False
        self._zoomPan = False
        self._dragOnDrop = False
        self._move = False

        self._patch = None
        self._xdata = None
        self._ydata = None
        self._defaultLineStyle = None
        self._last_point = None
        self._lastMarkerID = -1
        self._blockLogSignal = False

        self._axisXSciNotation = False
        self._axisYSciNotation = False
        self._prevTitle = None

    def __repaintOK(self):
        """ To be called inside XYView each time a low-level expansive matplotlib methods is to be invoked.
    @return False if painting is currently locked, in which case it will also register the current XYView 
    as needing a refresh when unlocked
    """
        ret = self._controller._plotManager.isRepaintLocked()
        if ret:
            self._controller._plotManager.registerRepaint(self._model)
        return (not ret)

    def appendCurve(self, curveID):
        newC = CurveView(self._controller, self)
        newC.setModel(self._model._curves[curveID])
        newC.setMPLAxes(self._mplAxes)
        newC.draw()
        newC.setMarker(self.getMarker(go_next=True))
        self._curveViews[curveID] = newC

    def removeCurve(self, curveID):
        v = self._curveViews.pop(curveID)
        v.erase()
        if self._currCrv is not None and self._currCrv.getID() == curveID:
            self._currCrv = None

    def cleanBeforeClose(self):
        """ Clean some items to avoid accumulating stuff in memory """
        self._mplFigure.clear()
        plt.close(self._mplFigure)
        self._plotWidget.clearAll()
        # For memory debugging only:
        import gc
        gc.collect()

    def repaint(self):
        if self.__repaintOK():
            Logger.Debug("XYView::draw")
            self._mplCanvas.draw()

    def onXLabelChange(self):
        if self.__repaintOK():
            self._mplAxes.set_xlabel(self._model._xlabel)
            self.repaint()

    def onYLabelChange(self):
        if self.__repaintOK():
            self._mplAxes.set_ylabel(self._model._ylabel)
            self.repaint()

    def onTitleChange(self):
        if self.__repaintOK():
            self._mplAxes.set_title(self._model._title)
            self.updateViewTitle()
            self.repaint()

    def onCurveTitleChange(self):
        # Updating the legend should suffice
        self.showHideLegend()

    def onClearAll(self):
        """ Just does an update with a reset of the marker cycle. """
        if self.__repaintOK():
            self._lastMarkerID = -1
            self.update()

    def onPick(self, event):
        """ MPL callback when picking
    """
        if event.mouseevent.button == 1:
            selected_id = -1
            a = event.artist
            for crv_id, cv in self._curveViews.items():
                if cv._mplLines[0] is a:
                    selected_id = crv_id
            # Use the plotmanager so that other plot sets get their current reset:
            self._controller._plotManager.setCurrentCurve(selected_id)

    def createAndAddLocalAction(self, icon_file, short_name):
        return self._toolbar.addAction(
            self._sgPyQt.loadIcon("CURVEPLOT", icon_file), short_name)

    def createPlotWidget(self):
        self._mplFigure = Figure((8.0, 5.0), dpi=100)
        self._mplCanvas = FigureCanvasQTAgg(self._mplFigure)
        self._mplCanvas.installEventFilter(self._eventHandler)
        self._mplCanvas.mpl_connect('pick_event', self.onPick)
        self._mplAxes = self._mplFigure.add_subplot(1, 1, 1)
        self._plotWidget = PlotWidget()
        self._toobarMPL = NavigationToolbar2QT(self._mplCanvas, None)
        for act in self._toobarMPL.actions():
            actionName = str(act.text()).strip()
            self._mplNavigationActions[actionName] = act
        self._plotWidget.setCentralWidget(self._mplCanvas)
        self._toolbar = self._plotWidget.toolBar
        self.populateToolbar()

        self._popupMenu = QtGui.QMenu()
        self._popupMenu.addAction(self._actionLegend)

        # Connect evenement for the graphic scene
        self._mplCanvas.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self._mplCanvas.customContextMenuRequested.connect(self.onContextMenu)
        self._mplCanvas.mpl_connect('scroll_event', self.onScroll)
        self._mplCanvas.mpl_connect('button_press_event', self.onMousePress)

    def populateToolbar(self):
        # Action to dump view in a file
        a = self.createAndAddLocalAction("dump_view.png", trQ("DUMP_VIEW_TXT"))
        a.triggered.connect(self.dumpView)
        self._toolbar.addSeparator()
        # Actions to manipulate the scene
        a = self.createAndAddLocalAction("fit_all.png", trQ("FIT_ALL_TXT"))
        a.triggered.connect(self.autoFit)
        #    Zoom and pan are mutually exclusive but can be both de-activated:
        self._zoomAction = self.createAndAddLocalAction(
            "fit_area.png", trQ("FIT_AREA_TXT"))
        self._zoomAction.triggered.connect(self.zoomArea)
        self._zoomAction.setCheckable(True)
        self._panAction = self.createAndAddLocalAction("zoom_pan.png",
                                                       trQ("ZOOM_PAN_TXT"))
        self._panAction.triggered.connect(self.pan)
        self._panAction.setCheckable(True)
        self._toolbar.addSeparator()
        # Actions to change the representation of curves
        self._curveActionGroup = QtGui.QActionGroup(self._plotWidget)
        self._pointsAction = self.createAndAddLocalAction(
            "draw_points.png", trQ("DRAW_POINTS_TXT"))
        self._pointsAction.setCheckable(True)
        self._linesAction = self.createAndAddLocalAction(
            "draw_lines.png", trQ("DRAW_LINES_TXT"))
        self._linesAction.setCheckable(True)
        self._curveActionGroup.addAction(self._pointsAction)
        self._curveActionGroup.addAction(self._linesAction)
        self._linesAction.setChecked(True)
        self._curveActionGroup.triggered.connect(self.changeModeCurve)
        self._curveActionGroup.setExclusive(True)
        self._toolbar.addSeparator()
        # Actions to draw horizontal curves as linear or logarithmic
        self._horActionGroup = QtGui.QActionGroup(self._plotWidget)
        self._horLinearAction = self.createAndAddLocalAction(
            "hor_linear.png", trQ("HOR_LINEAR_TXT"))
        self._horLinearAction.setCheckable(True)
        self._horLogarithmicAction = self.createAndAddLocalAction(
            "hor_logarithmic.png", trQ("HOR_LOGARITHMIC_TXT"))
        self._horLogarithmicAction.setCheckable(True)
        self._horActionGroup.addAction(self._horLinearAction)
        self._horActionGroup.addAction(self._horLogarithmicAction)
        self._horLinearAction.setChecked(True)
        self._horActionGroup.triggered.connect(self.onViewHorizontalMode)
        self._toolbar.addSeparator()
        # Actions to draw vertical curves as linear or logarithmic
        self._verActionGroup = QtGui.QActionGroup(self._plotWidget)
        self._verLinearAction = self.createAndAddLocalAction(
            "ver_linear.png", trQ("VER_LINEAR_TXT"))
        self._verLinearAction.setCheckable(True)
        self._verLogarithmicAction = self.createAndAddLocalAction(
            "ver_logarithmic.png", trQ("VER_LOGARITHMIC_TXT"))
        self._verLogarithmicAction.setCheckable(True)
        self._verActionGroup.addAction(self._verLinearAction)
        self._verActionGroup.addAction(self._verLogarithmicAction)
        self._verLinearAction.setChecked(True)
        self._verActionGroup.triggered.connect(self.onViewVerticalMode)
        self._verActionGroup.setExclusive(True)
        self._toolbar.addSeparator()
        # Action to show or hide the legend
        self._actionLegend = self.createAndAddLocalAction(
            "legend.png", trQ("SHOW_LEGEND_TXT"))
        self._actionLegend.setCheckable(True)
        self._actionLegend.triggered.connect(self.showHideLegend)
        if self._DEFAULT_LEGEND_STATE:
            self._actionLegend.setChecked(True)
        self._toolbar.addSeparator()
        # Action to set the preferences
        a = self.createAndAddLocalAction("settings.png", trQ("SETTINGS_TXT"))
        a.triggered.connect(self.onSettings)
        pass

    def dumpView(self):
        # Choice of the view backup file
        filters = []
        for form in [
                "IMAGES_FILES", "PDF_FILES", "POSTSCRIPT_FILES",
                "ENCAPSULATED_POSTSCRIPT_FILES"
        ]:
            filters.append(trQ(form))
        fileName = self._sgPyQt.getFileName(self._sgPyQt.getDesktop(), "",
                                            filters, trQ("DUMP_VIEW_FILE"),
                                            False)
        if not fileName.isEmpty():
            name = str(fileName)
            self._mplAxes.figure.savefig(name)
        pass

    def autoFit(self, check=True, repaint=True):
        if self.__repaintOK():
            self._mplAxes.relim()
            xm, xM = self._mplAxes.xaxis.get_data_interval()
            ym, yM = self._mplAxes.yaxis.get_data_interval()
            i = yM - ym
            self._mplAxes.axis([
                xm, xM, ym - i * self.AUTOFIT_MARGIN,
                yM + i * self.AUTOFIT_MARGIN
            ])
            if repaint:
                self.repaint()

    def zoomArea(self):
        if self._panAction.isChecked() and self._zoomAction.isChecked():
            self._panAction.setChecked(False)
        # Trigger underlying matplotlib action:
        self._mplNavigationActions["Zoom"].trigger()

    def pan(self):
        if self._panAction.isChecked() and self._zoomAction.isChecked():
            self._zoomAction.setChecked(False)
        # Trigger underlying matplotlib action:
        self._mplNavigationActions["Pan"].trigger()

    def getMarker(self, go_next=False):
        if go_next:
            self._lastMarkerID = (self._lastMarkerID + 1) % len(
                self.CURVE_MARKERS)
        return self.CURVE_MARKERS[self._lastMarkerID]

    def changeModeCurve(self, repaint=True):
        if not self.__repaintOK():
            return
        action = self._curveActionGroup.checkedAction()
        if action is self._pointsAction:
            for crv_view in self._curveViews.values():
                crv_view.setLineStyle("None")
        elif action is self._linesAction:
            for crv_view in self._curveViews.values():
                crv_view.setLineStyle("-")
        else:
            raise NotImplementedError
        if repaint:
            self.repaint()

    def setXLog(self, log, repaint=True):
        if not self.__repaintOK():
            return
        self._blockLogSignal = True
        if log:
            self._mplAxes.set_xscale('log')
            self._horLogarithmicAction.setChecked(True)
        else:
            self._mplAxes.set_xscale('linear')
            self._horLinearAction.setChecked(True)
        if repaint:
            self.autoFit()
            self.repaint()
        self._blockLogSignal = False

    def setYLog(self, log, repaint=True):
        if not self.__repaintOK():
            return
        self._blockLogSignal = True
        if log:
            self._mplAxes.set_yscale('log')
            self._verLogarithmicAction.setChecked(True)
        else:
            self._mplAxes.set_yscale('linear')
            self._verLinearAction.setChecked(True)
        if repaint:
            self.autoFit()
            self.repaint()
        self._blockLogSignal = False

    def setXSciNotation(self, sciNotation, repaint=True):
        self._axisXSciNotation = sciNotation
        self.changeFormatAxis()
        if repaint:
            self.repaint()

    def setYSciNotation(self, sciNotation, repaint=True):
        self._axisYSciNotation = sciNotation
        self.changeFormatAxis()
        if repaint:
            self.repaint()

    def onViewHorizontalMode(self, checked=True, repaint=True):
        if self._blockLogSignal:
            return
        action = self._horActionGroup.checkedAction()
        if action is self._horLinearAction:
            self.setXLog(False, repaint)
        elif action is self._horLogarithmicAction:
            self.setXLog(True, repaint)
        else:
            raise NotImplementedError

    def onViewVerticalMode(self, checked=True, repaint=True):
        if self._blockLogSignal:
            return
        action = self._verActionGroup.checkedAction()
        if action is self._verLinearAction:
            self.setYLog(False, repaint)
        elif action is self._verLogarithmicAction:
            self.setYLog(True, repaint)
        else:
            raise NotImplementedError
        if repaint:
            self.repaint()

    def __adjustFigureMargins(self, withLegend):
        """ Adjust figure margins to make room for the legend """
        if withLegend:
            leg = self._legend
            bbox = leg.get_window_extent()
            # In axes coordinates:
            bbox2 = bbox.transformed(leg.figure.transFigure.inverted())
            if self._legendLoc == "right":
                self._mplFigure.subplots_adjust(right=1.0 -
                                                (bbox2.width + 0.02))
            elif self._legendLoc == "bottom":
                self._mplFigure.subplots_adjust(bottom=bbox2.height + 0.1)
        else:
            # Reset to default (rc) values
            self._mplFigure.subplots_adjust(bottom=0.1, right=0.9)

    def setLegendVisible(self, visible, repaint=True):
        if visible and not self._actionLegend.isChecked():
            self._actionLegend.setChecked(True)
            self.showHideLegend(repaint=repaint)
        if not visible and self._actionLegend.isChecked():
            self._actionLegend.setChecked(False)
            self.showHideLegend(repaint=repaint)

    def showHideLegend(self, actionChecked=None, repaint=True):
        if not self.__repaintOK():  # Show/hide legend is extremely costly
            return

        show = self._actionLegend.isChecked()
        nCurves = len(self._curveViews)
        if nCurves > 10: fontSize = 'x-small'
        else: fontSize = None

        if nCurves == 0:
            # Remove legend
            leg = self._mplAxes.legend()
            if leg is not None: leg.remove()
        if show and nCurves > 0:
            # Recreate legend from scratch
            if self._legend is not None:
                self._legend = None
                self._mplAxes._legend = None
            if self._legendLoc == "bottom":
                self._legend = self._mplAxes.legend(loc="upper left",
                                                    bbox_to_anchor=(0.0, -0.05,
                                                                    1.0,
                                                                    -0.05),
                                                    borderaxespad=0.0,
                                                    mode="expand",
                                                    fancybox=True,
                                                    shadow=True,
                                                    ncol=3,
                                                    prop={
                                                        'size': fontSize,
                                                        'style': 'italic'
                                                    })
            elif self._legendLoc == "right":
                self._legend = self._mplAxes.legend(loc="upper left",
                                                    bbox_to_anchor=(1.02, 1.0),
                                                    borderaxespad=0.0,
                                                    ncol=1,
                                                    fancybox=True,
                                                    shadow=True,
                                                    prop={
                                                        'size': fontSize,
                                                        'style': 'italic'
                                                    })
            else:
                raise Exception(
                    "Invalid legend placement! Must be 'bottom' or 'right'")
            # Canvas must be drawn so we can adjust the figure placement:
            self._mplCanvas.draw()
            self.__adjustFigureMargins(withLegend=True)
        else:
            if self._legend is None:
                # Nothing to do
                return
            else:
                self._legend.set_visible(False)
                self._legend = None
                self._mplAxes._legend = None
                self._mplCanvas.draw()
                self.__adjustFigureMargins(withLegend=False)

        curr_crv = self._model._currentCurve
        if curr_crv is None: curr_title = None
        else: curr_title = curr_crv.getTitle()
        if self._legend is not None:
            for label in self._legend.get_texts():
                text = label.get_text()
                if (text == curr_title):
                    label.set_backgroundcolor('0.85')
                else:
                    label.set_backgroundcolor('white')

        if repaint:
            self.repaint()

    def onSettings(self, trigger=False, dlg_test=None):
        dlg = dlg_test or PlotSettings()
        dlg.titleEdit.setText(self._mplAxes.get_title())
        dlg.axisXTitleEdit.setText(self._mplAxes.get_xlabel())
        dlg.axisYTitleEdit.setText(self._mplAxes.get_ylabel())
        dlg.gridCheckBox.setChecked(
            self._mplAxes.xaxis._gridOnMajor
        )  # could not find a relevant API to check this
        dlg.axisXSciCheckBox.setChecked(self._axisXSciNotation)
        dlg.axisYSciCheckBox.setChecked(self._axisYSciNotation)
        xmin, xmax = self._mplAxes.get_xlim()
        ymin, ymax = self._mplAxes.get_ylim()
        xminText = "%g" % xmin
        xmaxText = "%g" % xmax
        yminText = "%g" % ymin
        ymaxText = "%g" % ymax
        dlg.axisXMinEdit.setText(xminText)
        dlg.axisXMaxEdit.setText(xmaxText)
        dlg.axisYMinEdit.setText(yminText)
        dlg.axisYMaxEdit.setText(ymaxText)
        # List of markers
        dlg.markerCurve.clear()
        for marker in self.CURVE_MARKERS:
            dlg.markerCurve.addItem(marker)
        curr_crv = self._model.getCurrentCurve()
        if not curr_crv is None:
            dlg.colorCurve.setEnabled(True)
            dlg.markerCurve.setEnabled(True)
            name = curr_crv.getTitle()
            dlg.nameCurve.setText(name)
            view = self._curveViews[curr_crv.getID()]
            marker = view.getMarker()
            color = view.getColor()
            index = dlg.markerCurve.findText(marker)
            dlg.markerCurve.setCurrentIndex(index)
            rgb = colors.colorConverter.to_rgb(color)
            dlg.setRGB(rgb[0], rgb[1], rgb[2])
        else:
            dlg.colorCurve.setEnabled(False)
            dlg.markerCurve.setEnabled(False)
            dlg.nameCurve.setText("")
            view = None
        if self._legend is None:
            dlg.showLegendCheckBox.setChecked(False)
            dlg.legendPositionComboBox.setEnabled(False)
        else:
            if self._legend.get_visible():
                dlg.showLegendCheckBox.setChecked(True)
                dlg.legendPositionComboBox.setEnabled(True)
                if self._legendLoc == "bottom":
                    dlg.legendPositionComboBox.setCurrentIndex(0)
                elif self._legendLoc == "right":
                    dlg.legendPositionComboBox.setCurrentIndex(1)
            else:
                dlg.showLegendCheckBox.setChecked(False)
                dlg.legendPositionComboBox.setEnabled(False)

        if dlg.exec_():
            # Title
            self._model.setTitle(dlg.titleEdit.text())
            # Axis
            self._model.setXLabel(dlg.axisXTitleEdit.text())
            self._model.setYLabel(dlg.axisYTitleEdit.text())
            # Grid
            if dlg.gridCheckBox.isChecked():
                self._mplAxes.grid(True)
            else:
                self._mplAxes.grid(False)
            # Legend
            if dlg.showLegendCheckBox.isChecked():
                self._actionLegend.setChecked(True)
                if dlg.legendPositionComboBox.currentIndex() == 0:
                    self._legendLoc = "bottom"
                elif dlg.legendPositionComboBox.currentIndex() == 1:
                    self._legendLoc = "right"
            else:
                self._actionLegend.setChecked(False)
            xminText = dlg.axisXMinEdit.text()
            xmaxText = dlg.axisXMaxEdit.text()
            yminText = dlg.axisYMinEdit.text()
            ymaxText = dlg.axisYMaxEdit.text()
            self._mplAxes.axis([
                float(xminText),
                float(xmaxText),
                float(yminText),
                float(ymaxText)
            ])
            self._axisXSciNotation = dlg.axisXSciCheckBox.isChecked()
            self._axisYSciNotation = dlg.axisYSciCheckBox.isChecked()
            self.changeFormatAxis()
            # Color and marker of the curve
            if view:
                view.setColor(dlg.getRGB())
                view.setMarker(
                    self.CURVE_MARKERS[dlg.markerCurve.currentIndex()])
            self.showHideLegend(repaint=True)
            self._mplCanvas.draw()
        pass

    def updateViewTitle(self):
        s = ""
        if self._model._title != "":
            s = " - %s" % self._model._title
        title = "CurvePlot (%d)%s" % (self._model.getID(), s)
        self._sgPyQt.setViewTitle(self._salomeViewID, title)

    def onCurrentPlotSetChange(self):
        """ Avoid a unnecessary call to update() when just switching current plot set! """
        pass

    def onCurrentCurveChange(self):
        curr_crv2 = self._model.getCurrentCurve()
        if curr_crv2 != self._currCrv:
            if self._currCrv is not None:
                view = self._curveViews[self._currCrv.getID()]
                view.toggleHighlight(False)
            if not curr_crv2 is None:
                view = self._curveViews[curr_crv2.getID()]
                view.toggleHighlight(True)
            self._currCrv = curr_crv2
            self.showHideLegend(repaint=False)  # redo legend
            self.repaint()

    def changeFormatAxis(self):
        if not self.__repaintOK():
            return

        # don't try to switch to sci notation if we are not using the
        # matplotlib.ticker.ScalarFormatter (i.e. if in Log for ex.)
        if self._horLinearAction.isChecked():
            if self._axisXSciNotation:
                self._mplAxes.ticklabel_format(style='sci',
                                               scilimits=(0, 0),
                                               axis='x')
            else:
                self._mplAxes.ticklabel_format(style='plain', axis='x')
        if self._verLinearAction.isChecked():
            if self._axisYSciNotation:
                self._mplAxes.ticklabel_format(style='sci',
                                               scilimits=(0, 0),
                                               axis='y')
            else:
                self._mplAxes.ticklabel_format(style='plain', axis='y')

    def update(self):
        if self._salomeViewID is None:
            self.createPlotWidget()
            self._salomeViewID = self._sgPyQt.createView(
                "CurvePlot", self._plotWidget)
            Logger.Debug("Creating SALOME view ID=%d" % self._salomeViewID)
            self._sgPyQt.setViewVisible(self._salomeViewID, True)

        self.updateViewTitle()

        # Check list of curve views:
        set_mod = set(self._model._curves.keys())
        set_view = set(self._curveViews.keys())

        # Deleted/Added curves:
        dels = set_view - set_mod
        added = set_mod - set_view

        for d in dels:
            self.removeCurve(d)

        if not len(self._curveViews):
            # Reset color cycle
            self._mplAxes.set_color_cycle(None)

        for a in added:
            self.appendCurve(a)

        # Axes labels and title
        self._mplAxes.set_xlabel(self._model._xlabel)
        self._mplAxes.set_ylabel(self._model._ylabel)
        self._mplAxes.set_title(self._model._title)

        self.onViewHorizontalMode(repaint=False)
        self.onViewVerticalMode(repaint=False)
        self.changeModeCurve(repaint=False)
        self.showHideLegend(
            repaint=False
        )  # The canvas is repainted anyway (needed to get legend bounding box)
        self.changeFormatAxis()

        # Redo auto-fit
        self.autoFit(repaint=False)
        self.repaint()

    def onDataChange(self):
        # the rest is done in the CurveView:
        self.autoFit(repaint=True)

    def onMousePress(self, event):
        if event.button == 3:
            if self._panAction.isChecked():
                self._panAction.setChecked(False)
            if self._zoomAction.isChecked():
                self._zoomAction.setChecked(False)

    def onContextMenu(self, position):
        pos = self._mplCanvas.mapToGlobal(
            QtCore.QPoint(position.x(), position.y()))
        self._popupMenu.exec_(pos)

    def onScroll(self, event):
        # Event location (x and y)
        xdata = event.xdata
        ydata = event.ydata

        cur_xlim = self._mplAxes.get_xlim()
        cur_ylim = self._mplAxes.get_ylim()

        base_scale = 2.
        if event.button == 'down':
            # deal with zoom in
            scale_factor = 1 / base_scale
        elif event.button == 'up':
            # deal with zoom out
            scale_factor = base_scale
        else:
            # deal with something that should never happen
            scale_factor = 1

        new_width = (cur_xlim[1] - cur_xlim[0]) * scale_factor
        new_height = (cur_ylim[1] - cur_ylim[0]) * scale_factor

        relx = (cur_xlim[1] - xdata) / (cur_xlim[1] - cur_xlim[0])
        rely = (cur_ylim[1] - ydata) / (cur_ylim[1] - cur_ylim[0])

        self._mplAxes.set_xlim(
            [xdata - new_width * (1 - relx), xdata + new_width * (relx)])
        self._mplAxes.set_ylim(
            [ydata - new_height * (1 - rely), ydata + new_height * (rely)])

        self.repaint()
        pass

    def onPressEvent(self, event):
        if event.button == 3:
            #self._mplCanvas.emit(QtCore.SIGNAL("button_release_event()"))
            canvasSize = event.canvas.geometry()
            point = event.canvas.mapToGlobal(
                QtCore.QPoint(event.x,
                              canvasSize.height() - event.y))
            self._popupMenu.exec_(point)
        else:
            print "Press event on the other button"
        #if event.button == 3 :
        #  canvasSize = event.canvas.geometry()
        #  point = event.canvas.mapToGlobal(QtCore.QPoint(event.x,canvasSize.height()-event.y))
        #  self._popupMenu.move(point)
        #  self._popupMenu.show()

    def onMotionEvent(self, event):
        print "OnMotionEvent ", event.button
        #if event.button == 3 :
        #  event.button = None
        #  return True

    def onReleaseEvent(self, event):
        print "OnReleaseEvent ", event.button
Ejemplo n.º 27
0
class XYView(View):
  AUTOFIT_MARGIN = 0.03  # 3%
  
  # See http://matplotlib.org/api/markers_api.html:
  CURVE_MARKERS = [ "o" ,#  circle
                    "*",  # star
                    "+",  # plus
                    "x",  # x
                    "s",  # square
                    "p",  # pentagon
                    "h",  # hexagon1
                    "8",  # octagon
                    "D",  # diamond
                    "^",  # triangle_up
                    "<",  # triangle_left
                    ">",  # triangle_right
                    "1",  # tri_down
                    "2",  # tri_up
                    "3",  # tri_left
                    "4",  # tri_right
                    "v",  # triangle_down
                    "H",  # hexagon2
                    "d",  # thin diamond
                    "",   # NO MARKER
                   ]
  
  _DEFAULT_LEGEND_STATE = False   # for test purposes mainly - initial status of the legend
  
  def __init__(self, controller):
    View.__init__(self, controller)
    self._eventHandler = EventHandler()
    
    self._curveViews = {}    # key: curve (model) ID, value: CurveView
    self._salomeViewID = None
    self._mplFigure = None
    self._mplAxes = None
    self._mplCanvas = None
    self._plotWidget = None
    self._sgPyQt = self._controller._sgPyQt
    self._toolbar = None
    self._mplNavigationActions = {}
    self._toobarMPL = None
    self._grid = None
    self._currCrv = None   # current curve selected in the view
    
    self._legend = None
    self._legendLoc = "right"  # "right" or "bottom"
    
    self._fitArea = False
    self._zoomPan = False
    self._dragOnDrop = False
    self._move = False
    
    self._patch = None
    self._xdata = None
    self._ydata = None
    self._defaultLineStyle = None
    self._last_point = None
    self._lastMarkerID = -1
    self._blockLogSignal = False
    
    self._axisXSciNotation = False
    self._axisYSciNotation = False
    self._prevTitle = None
    
  def __repaintOK(self):
    """ To be called inside XYView each time a low-level expansive matplotlib methods is to be invoked.
    @return False if painting is currently locked, in which case it will also register the current XYView 
    as needing a refresh when unlocked
    """
    ret = self._controller._plotManager.isRepaintLocked()
    if ret:
      self._controller._plotManager.registerRepaint(self._model)
    return (not ret)
    
  def appendCurve(self, curveID):
    newC = CurveView(self._controller, self)
    newC.setModel(self._model._curves[curveID])
    newC.setMPLAxes(self._mplAxes) 
    newC.draw()
    newC.setMarker(self.getMarker(go_next=True))
    self._curveViews[curveID] = newC 
    
  def removeCurve(self, curveID):
    v = self._curveViews.pop(curveID)
    v.erase()
    if self._currCrv is not None and self._currCrv.getID() == curveID:
      self._currCrv = None
  
  def cleanBeforeClose(self):
    """ Clean some items to avoid accumulating stuff in memory """
    self._mplFigure.clear()
    plt.close(self._mplFigure)
    self._plotWidget.clearAll()
    # For memory debugging only:
    import gc
    gc.collect()
  
  def repaint(self):
    if self.__repaintOK():
      Logger.Debug("XYView::draw")
      self._mplCanvas.draw()

  def onXLabelChange(self):
    if self.__repaintOK():
      self._mplAxes.set_xlabel(self._model._xlabel)
      self.repaint()
    
  def onYLabelChange(self):
    if self.__repaintOK():
      self._mplAxes.set_ylabel(self._model._ylabel)
      self.repaint()
  
  def onTitleChange(self):
    if self.__repaintOK():
      self._mplAxes.set_title(self._model._title)
      self.updateViewTitle()
      self.repaint()
  
  def onCurveTitleChange(self):
    # Updating the legend should suffice
    self.showHideLegend()
  
  def onClearAll(self):
    """ Just does an update with a reset of the marker cycle. """
    if self.__repaintOK():
      self._lastMarkerID = -1
      self.update()
  
  def onPick(self, event):
    """ MPL callback when picking
    """
    if event.mouseevent.button == 1:
      selected_id = -1
      a = event.artist
      for crv_id, cv in self._curveViews.items():
        if cv._mplLines[0] is a:
          selected_id = crv_id
      # Use the plotmanager so that other plot sets get their current reset:
      self._controller._plotManager.setCurrentCurve(selected_id)
  
  def createAndAddLocalAction(self, icon_file, short_name):
    return self._toolbar.addAction(self._sgPyQt.loadIcon("CURVEPLOT", icon_file), short_name)
    
  def createPlotWidget(self):
    self._mplFigure = Figure((8.0,5.0), dpi=100)
    self._mplCanvas = FigureCanvasQTAgg(self._mplFigure)
    self._mplCanvas.installEventFilter(self._eventHandler)
    self._mplCanvas.mpl_connect('pick_event', self.onPick)
    self._mplAxes = self._mplFigure.add_subplot(1, 1, 1)
    self._plotWidget = PlotWidget()
    self._toobarMPL = NavigationToolbar2QT(self._mplCanvas, None) 
    for act in self._toobarMPL.actions():
      actionName = str(act.text()).strip()
      self._mplNavigationActions[actionName] = act
    self._plotWidget.setCentralWidget(self._mplCanvas)
    self._toolbar = self._plotWidget.toolBar
    self.populateToolbar()
     
    self._popupMenu = QtGui.QMenu()
    self._popupMenu.addAction(self._actionLegend)
    
    # Connect evenement for the graphic scene
    self._mplCanvas.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
    self._mplCanvas.customContextMenuRequested.connect(self.onContextMenu) 
    self._mplCanvas.mpl_connect('scroll_event', self.onScroll)
    self._mplCanvas.mpl_connect('button_press_event', self.onMousePress)
  
  def populateToolbar(self):
    # Action to dump view in a file
    a = self.createAndAddLocalAction("dump_view.png", trQ("DUMP_VIEW_TXT"))
    a.triggered.connect(self.dumpView)
    self._toolbar.addSeparator()
    # Actions to manipulate the scene
    a = self.createAndAddLocalAction("fit_all.png", trQ("FIT_ALL_TXT"))
    a.triggered.connect(self.autoFit)
    #    Zoom and pan are mutually exclusive but can be both de-activated: 
    self._zoomAction = self.createAndAddLocalAction("fit_area.png", trQ("FIT_AREA_TXT"))
    self._zoomAction.triggered.connect(self.zoomArea)
    self._zoomAction.setCheckable(True)
    self._panAction = self.createAndAddLocalAction("zoom_pan.png", trQ("ZOOM_PAN_TXT"))
    self._panAction.triggered.connect(self.pan)
    self._panAction.setCheckable(True)
    self._toolbar.addSeparator()
    # Actions to change the representation of curves
    self._curveActionGroup = QtGui.QActionGroup(self._plotWidget)
    self._pointsAction = self.createAndAddLocalAction("draw_points.png", trQ("DRAW_POINTS_TXT"))
    self._pointsAction.setCheckable(True)
    self._linesAction = self.createAndAddLocalAction("draw_lines.png", trQ("DRAW_LINES_TXT"))
    self._linesAction.setCheckable(True)
    self._curveActionGroup.addAction(self._pointsAction)
    self._curveActionGroup.addAction(self._linesAction)
    self._linesAction.setChecked(True)
    self._curveActionGroup.triggered.connect(self.changeModeCurve)
    self._curveActionGroup.setExclusive(True)
    self._toolbar.addSeparator()
    # Actions to draw horizontal curves as linear or logarithmic
    self._horActionGroup = QtGui.QActionGroup(self._plotWidget)
    self._horLinearAction = self.createAndAddLocalAction("hor_linear.png", trQ("HOR_LINEAR_TXT"))
    self._horLinearAction.setCheckable(True)
    self._horLogarithmicAction = self.createAndAddLocalAction("hor_logarithmic.png", trQ("HOR_LOGARITHMIC_TXT"))
    self._horLogarithmicAction.setCheckable(True)
    self._horActionGroup.addAction(self._horLinearAction)
    self._horActionGroup.addAction(self._horLogarithmicAction)
    self._horLinearAction.setChecked(True)
    self._horActionGroup.triggered.connect(self.onViewHorizontalMode)
    self._toolbar.addSeparator()
    # Actions to draw vertical curves as linear or logarithmic
    self._verActionGroup = QtGui.QActionGroup(self._plotWidget)
    self._verLinearAction = self.createAndAddLocalAction("ver_linear.png", trQ("VER_LINEAR_TXT"))
    self._verLinearAction.setCheckable(True)
    self._verLogarithmicAction = self.createAndAddLocalAction("ver_logarithmic.png", trQ("VER_LOGARITHMIC_TXT"))
    self._verLogarithmicAction.setCheckable(True)
    self._verActionGroup.addAction(self._verLinearAction)
    self._verActionGroup.addAction(self._verLogarithmicAction)
    self._verLinearAction.setChecked(True)
    self._verActionGroup.triggered.connect(self.onViewVerticalMode)
    self._verActionGroup.setExclusive(True)
    self._toolbar.addSeparator()
    # Action to show or hide the legend 
    self._actionLegend = self.createAndAddLocalAction("legend.png", trQ("SHOW_LEGEND_TXT"))
    self._actionLegend.setCheckable(True)
    self._actionLegend.triggered.connect(self.showHideLegend)
    if self._DEFAULT_LEGEND_STATE:
      self._actionLegend.setChecked(True)
    self._toolbar.addSeparator()
    # Action to set the preferences
    a = self.createAndAddLocalAction("settings.png", trQ("SETTINGS_TXT"))
    a.triggered.connect(self.onSettings)
    pass
    
  def dumpView(self):
    # Choice of the view backup file
    filters = []
    for form in ["IMAGES_FILES", "PDF_FILES", "POSTSCRIPT_FILES", "ENCAPSULATED_POSTSCRIPT_FILES"]:
      filters.append(trQ(form))
    fileName = self._sgPyQt.getFileName(self._sgPyQt.getDesktop(),
                                        "",
                                        filters,
                                        trQ("DUMP_VIEW_FILE"),
                                        False )
    if not fileName.isEmpty():
      name = str(fileName)
      self._mplAxes.figure.savefig(name)
    pass
    
  def autoFit(self, check=True, repaint=True):
    if self.__repaintOK():
      self._mplAxes.relim()
      xm, xM = self._mplAxes.xaxis.get_data_interval()
      ym, yM = self._mplAxes.yaxis.get_data_interval()
      i = yM-ym
      self._mplAxes.axis([xm, xM, ym-i*self.AUTOFIT_MARGIN, yM+i*self.AUTOFIT_MARGIN])
      if repaint:
        self.repaint()
  
  def zoomArea(self):
    if self._panAction.isChecked() and self._zoomAction.isChecked():
      self._panAction.setChecked(False)
    # Trigger underlying matplotlib action:
    self._mplNavigationActions["Zoom"].trigger()
  
  def pan(self):
    if self._panAction.isChecked() and self._zoomAction.isChecked():
      self._zoomAction.setChecked(False)
    # Trigger underlying matplotlib action:
    self._mplNavigationActions["Pan"].trigger()

  def getMarker(self, go_next=False):
    if go_next:
      self._lastMarkerID = (self._lastMarkerID+1) % len(self.CURVE_MARKERS)
    return self.CURVE_MARKERS[self._lastMarkerID]

  def changeModeCurve(self, repaint=True):
    if not self.__repaintOK():
      return
    action = self._curveActionGroup.checkedAction()
    if action is self._pointsAction :
      for crv_view in self._curveViews.values():
        crv_view.setLineStyle("None")
    elif action is self._linesAction :
      for crv_view in self._curveViews.values():
        crv_view.setLineStyle("-")
    else :
      raise NotImplementedError
    if repaint:
      self.repaint()
  
  def setXLog(self, log, repaint=True):
    if not self.__repaintOK():
      return
    self._blockLogSignal = True
    if log:
      self._mplAxes.set_xscale('log')
      self._horLogarithmicAction.setChecked(True)
    else:
      self._mplAxes.set_xscale('linear')
      self._horLinearAction.setChecked(True)
    if repaint:
      self.autoFit()
      self.repaint()
    self._blockLogSignal = False

  def setYLog(self, log, repaint=True):
    if not self.__repaintOK():
      return
    self._blockLogSignal = True
    if log:
      self._mplAxes.set_yscale('log')
      self._verLogarithmicAction.setChecked(True)
    else:
      self._mplAxes.set_yscale('linear')
      self._verLinearAction.setChecked(True)
    if repaint:
      self.autoFit()
      self.repaint()
    self._blockLogSignal = False
    
  def setXSciNotation(self, sciNotation, repaint=True):
    self._axisXSciNotation = sciNotation
    self.changeFormatAxis()
    if repaint:
      self.repaint()
   
  def setYSciNotation(self, sciNotation, repaint=True):
    self._axisYSciNotation = sciNotation
    self.changeFormatAxis()
    if repaint:
      self.repaint()
    
  def onViewHorizontalMode(self, checked=True, repaint=True):
    if self._blockLogSignal:
      return
    action = self._horActionGroup.checkedAction()  
    if action is self._horLinearAction:
      self.setXLog(False, repaint)
    elif action is self._horLogarithmicAction:
      self.setXLog(True, repaint)
    else:
      raise NotImplementedError
  
  def onViewVerticalMode(self, checked=True, repaint=True):
    if self._blockLogSignal:
      return
    action = self._verActionGroup.checkedAction()  
    if action is self._verLinearAction:
      self.setYLog(False, repaint)
    elif action is self._verLogarithmicAction:
      self.setYLog(True, repaint)
    else:
      raise NotImplementedError
    if repaint:
      self.repaint()
  
  def __adjustFigureMargins(self, withLegend):
    """ Adjust figure margins to make room for the legend """
    if withLegend:
      leg = self._legend
      bbox = leg.get_window_extent()
      # In axes coordinates: 
      bbox2 = bbox.transformed(leg.figure.transFigure.inverted())
      if self._legendLoc == "right":
        self._mplFigure.subplots_adjust(right=1.0-(bbox2.width+0.02))
      elif self._legendLoc == "bottom":
        self._mplFigure.subplots_adjust(bottom=bbox2.height+0.1)
    else:
      # Reset to default (rc) values
      self._mplFigure.subplots_adjust(bottom=0.1, right=0.9)
  
  def setLegendVisible(self, visible, repaint=True):
    if visible and not self._actionLegend.isChecked():
      self._actionLegend.setChecked(True)
      self.showHideLegend(repaint=repaint)
    if not visible and self._actionLegend.isChecked():
      self._actionLegend.setChecked(False)
      self.showHideLegend(repaint=repaint)
  
  def showHideLegend(self, actionChecked=None, repaint=True):
    if not self.__repaintOK():  # Show/hide legend is extremely costly
      return
    
    show = self._actionLegend.isChecked()
    nCurves = len(self._curveViews)
    if nCurves > 10: fontSize = 'x-small'
    else:            fontSize = None
    
    if nCurves == 0:
      # Remove legend 
      leg = self._mplAxes.legend()
      if leg is not None: leg.remove()
    if show and nCurves > 0:
      # Recreate legend from scratch
      if self._legend is not None:
        self._legend = None
        self._mplAxes._legend = None
      if self._legendLoc == "bottom":
        self._legend = self._mplAxes.legend(loc="upper left", bbox_to_anchor=(0.0, -0.05, 1.0, -0.05), 
                                            borderaxespad=0.0, mode="expand", fancybox=True, 
                                            shadow=True, ncol=3, prop={'size':fontSize, 'style': 'italic'})
      elif self._legendLoc == "right":
        self._legend = self._mplAxes.legend(loc="upper left", bbox_to_anchor=(1.02,1.0), borderaxespad=0.0,
                                            ncol=1, fancybox=True, shadow=True, prop={'size':fontSize, 'style': 'italic'})
      else:
        raise Exception("Invalid legend placement! Must be 'bottom' or 'right'")
      # Canvas must be drawn so we can adjust the figure placement:
      self._mplCanvas.draw()
      self.__adjustFigureMargins(withLegend=True)
    else:
      if self._legend is None:
        # Nothing to do
        return
      else:
        self._legend.set_visible(False)
        self._legend = None
        self._mplAxes._legend = None
        self._mplCanvas.draw()
        self.__adjustFigureMargins(withLegend=False)
    
    curr_crv = self._model._currentCurve
    if curr_crv is None: curr_title = None
    else:                curr_title = curr_crv.getTitle()
    if self._legend is not None:
      for label in self._legend.get_texts() :
        text = label.get_text()
        if (text == curr_title):
          label.set_backgroundcolor('0.85')
        else :
          label.set_backgroundcolor('white')
        
    if repaint:
      self.repaint()
   
  def onSettings(self, trigger=False, dlg_test=None):
    dlg = dlg_test or PlotSettings()
    dlg.titleEdit.setText(self._mplAxes.get_title())
    dlg.axisXTitleEdit.setText(self._mplAxes.get_xlabel())
    dlg.axisYTitleEdit.setText(self._mplAxes.get_ylabel())
    dlg.gridCheckBox.setChecked(self._mplAxes.xaxis._gridOnMajor)  # could not find a relevant API to check this
    dlg.axisXSciCheckBox.setChecked(self._axisXSciNotation)
    dlg.axisYSciCheckBox.setChecked(self._axisYSciNotation)
    xmin, xmax = self._mplAxes.get_xlim()
    ymin, ymax = self._mplAxes.get_ylim()
    xminText = "%g" %xmin
    xmaxText = "%g" %xmax
    yminText = "%g" %ymin
    ymaxText = "%g" %ymax
    dlg.axisXMinEdit.setText(xminText)
    dlg.axisXMaxEdit.setText(xmaxText)
    dlg.axisYMinEdit.setText(yminText)
    dlg.axisYMaxEdit.setText(ymaxText)
    # List of markers
    dlg.markerCurve.clear()
    for marker in self.CURVE_MARKERS :
      dlg.markerCurve.addItem(marker)
    curr_crv = self._model.getCurrentCurve()
    if not curr_crv is None:
      dlg.colorCurve.setEnabled(True)
      dlg.markerCurve.setEnabled(True)
      name = curr_crv.getTitle()
      dlg.nameCurve.setText(name)
      view = self._curveViews[curr_crv.getID()] 
      marker = view.getMarker()
      color = view.getColor()
      index = dlg.markerCurve.findText(marker)
      dlg.markerCurve.setCurrentIndex(index)
      rgb = colors.colorConverter.to_rgb(color)
      dlg.setRGB(rgb[0],rgb[1],rgb[2])
    else :
      dlg.colorCurve.setEnabled(False)
      dlg.markerCurve.setEnabled(False)
      dlg.nameCurve.setText("")
      view = None
    if self._legend is None:
      dlg.showLegendCheckBox.setChecked(False)
      dlg.legendPositionComboBox.setEnabled(False)
    else :
      if self._legend.get_visible():
        dlg.showLegendCheckBox.setChecked(True)
        dlg.legendPositionComboBox.setEnabled(True)
        if self._legendLoc == "bottom":
          dlg.legendPositionComboBox.setCurrentIndex(0)
        elif self._legendLoc == "right" :
          dlg.legendPositionComboBox.setCurrentIndex(1)
      else :
        dlg.showLegendCheckBox.setChecked(False)
        dlg.legendPositionComboBox.setEnabled(False)    
             
    if dlg.exec_():
      # Title
      self._model.setTitle(dlg.titleEdit.text())
      # Axis
      self._model.setXLabel(dlg.axisXTitleEdit.text())
      self._model.setYLabel(dlg.axisYTitleEdit.text())
      # Grid
      if dlg.gridCheckBox.isChecked() :
        self._mplAxes.grid(True)
      else :
        self._mplAxes.grid(False)
      # Legend
      if  dlg.showLegendCheckBox.isChecked():
        self._actionLegend.setChecked(True)
        if dlg.legendPositionComboBox.currentIndex() == 0 :
          self._legendLoc = "bottom"
        elif dlg.legendPositionComboBox.currentIndex() == 1 :
          self._legendLoc = "right"
      else :
        self._actionLegend.setChecked(False)
      xminText = dlg.axisXMinEdit.text()
      xmaxText = dlg.axisXMaxEdit.text()
      yminText = dlg.axisYMinEdit.text()
      ymaxText = dlg.axisYMaxEdit.text()
      self._mplAxes.axis([float(xminText), float(xmaxText), float(yminText), float(ymaxText)] )
      self._axisXSciNotation = dlg.axisXSciCheckBox.isChecked()
      self._axisYSciNotation = dlg.axisYSciCheckBox.isChecked()
      self.changeFormatAxis()
      # Color and marker of the curve
      if view:
        view.setColor(dlg.getRGB()) 
        view.setMarker(self.CURVE_MARKERS[dlg.markerCurve.currentIndex()])
      self.showHideLegend(repaint=True)
      self._mplCanvas.draw()
    pass
    
  def updateViewTitle(self):
    s = ""
    if self._model._title != "":
      s = " - %s" % self._model._title
    title = "CurvePlot (%d)%s" % (self._model.getID(), s)
    self._sgPyQt.setViewTitle(self._salomeViewID, title)
    
  def onCurrentPlotSetChange(self):
    """ Avoid a unnecessary call to update() when just switching current plot set! """ 
    pass
  
  def onCurrentCurveChange(self):
    curr_crv2 = self._model.getCurrentCurve()
    if curr_crv2 != self._currCrv:
      if self._currCrv is not None:
        view = self._curveViews[self._currCrv.getID()]
        view.toggleHighlight(False)
      if not curr_crv2 is None:
        view = self._curveViews[curr_crv2.getID()] 
        view.toggleHighlight(True)
      self._currCrv = curr_crv2
      self.showHideLegend(repaint=False) # redo legend
      self.repaint() 
      
  def changeFormatAxis(self) :
    if not self.__repaintOK():
      return
    
    # don't try to switch to sci notation if we are not using the 
    # matplotlib.ticker.ScalarFormatter (i.e. if in Log for ex.)
    if self._horLinearAction.isChecked():
      if self._axisXSciNotation :
        self._mplAxes.ticklabel_format(style='sci',scilimits=(0,0), axis='x')
      else :
        self._mplAxes.ticklabel_format(style='plain',axis='x')
    if self._verLinearAction.isChecked():    
      if self._axisYSciNotation :
        self._mplAxes.ticklabel_format(style='sci',scilimits=(0,0), axis='y')
      else :
        self._mplAxes.ticklabel_format(style='plain',axis='y')
    
  def update(self):
    if self._salomeViewID is None:
      self.createPlotWidget()
      self._salomeViewID = self._sgPyQt.createView("CurvePlot", self._plotWidget)
      Logger.Debug("Creating SALOME view ID=%d" % self._salomeViewID)
      self._sgPyQt.setViewVisible(self._salomeViewID, True)
    
    self.updateViewTitle()
    
    # Check list of curve views:
    set_mod = set(self._model._curves.keys())
    set_view = set(self._curveViews.keys())
    
    # Deleted/Added curves:
    dels = set_view - set_mod
    added = set_mod - set_view
    
    for d in dels:
      self.removeCurve(d)

    if not len(self._curveViews):
      # Reset color cycle 
      self._mplAxes.set_color_cycle(None)

    for a in added:
      self.appendCurve(a)

    # Axes labels and title
    self._mplAxes.set_xlabel(self._model._xlabel)
    self._mplAxes.set_ylabel(self._model._ylabel)
    self._mplAxes.set_title(self._model._title)

    self.onViewHorizontalMode(repaint=False)
    self.onViewVerticalMode(repaint=False)
    self.changeModeCurve(repaint=False)
    self.showHideLegend(repaint=False)   # The canvas is repainted anyway (needed to get legend bounding box)
    self.changeFormatAxis()

    # Redo auto-fit
    self.autoFit(repaint=False)
    self.repaint()
  
  def onDataChange(self):
    # the rest is done in the CurveView:
    self.autoFit(repaint=True)
    
  def onMousePress(self, event):
    if event.button == 3 :
      if self._panAction.isChecked():
        self._panAction.setChecked(False)
      if self._zoomAction.isChecked():
        self._zoomAction.setChecked(False)
    
  def onContextMenu(self, position):
    pos = self._mplCanvas.mapToGlobal(QtCore.QPoint(position.x(),position.y()))
    self._popupMenu.exec_(pos)
    
  def onScroll(self, event):
    # Event location (x and y)
    xdata = event.xdata
    ydata = event.ydata
    
    cur_xlim = self._mplAxes.get_xlim()
    cur_ylim = self._mplAxes.get_ylim()
    
    base_scale = 2.
    if event.button == 'down':
      # deal with zoom in
      scale_factor = 1 / base_scale
    elif event.button == 'up':
      # deal with zoom out
      scale_factor = base_scale
    else:
      # deal with something that should never happen
      scale_factor = 1
    
    new_width = (cur_xlim[1] - cur_xlim[0]) * scale_factor
    new_height = (cur_ylim[1] - cur_ylim[0]) * scale_factor

    relx = (cur_xlim[1] - xdata)/(cur_xlim[1] - cur_xlim[0])
    rely = (cur_ylim[1] - ydata)/(cur_ylim[1] - cur_ylim[0])

    self._mplAxes.set_xlim([xdata - new_width * (1-relx), xdata + new_width * (relx)])
    self._mplAxes.set_ylim([ydata - new_height * (1-rely), ydata + new_height * (rely)])
    
    self.repaint()
    pass
    
  def onPressEvent(self, event):
    if event.button == 3 :
      #self._mplCanvas.emit(QtCore.SIGNAL("button_release_event()"))
      canvasSize = event.canvas.geometry()
      point = event.canvas.mapToGlobal(QtCore.QPoint(event.x,canvasSize.height()-event.y))
      self._popupMenu.exec_(point)
    else :
      print "Press event on the other button"
    #if event.button == 3 :
    #  canvasSize = event.canvas.geometry()
    #  point = event.canvas.mapToGlobal(QtCore.QPoint(event.x,canvasSize.height()-event.y))
    #  self._popupMenu.move(point)
    #  self._popupMenu.show()
   
  def onMotionEvent(self, event):
    print "OnMotionEvent ",event.button
    #if event.button == 3 :
    #  event.button = None
    #  return True
   
  def onReleaseEvent(self, event):
    print "OnReleaseEvent ",event.button
Ejemplo n.º 28
0
class NeonPlot:
    def __init__(self):
        filename = "MainWindow.glade"
        builder = gtk.Builder()
        builder.add_from_file(filename)
        builder.connect_signals(self)

        self.window = builder.get_object("mainWindow")
        self.window.connect("destroy", self.onDeleteWindow)
        self.window.show_all()

        self.functionsVbox = builder.get_object("functionsVbox")
        self.addFunctionButton = builder.get_object("addFuncitonButton")

        self.viewParamsStatusBar = builder.get_object('viewParamsLabel')
        self.errorsStatusBar = builder.get_object('errorsLabel')

        self.eventbox1 = builder.get_object("eventbox1")
        self.plotWidget = PlotWidget()
        self.plotWidget.connect('view_updated', self.update_plotview_status_bar)
        self.plotWidget.update_view_info()
        self.plotWidget.show()
        self.eventbox1.add(self.plotWidget)

        #self.viewCursorMenuItem = builder.get_object('viewCursor')
        #self.viewCursorMenuItem.connect("toggled", self.viewCursor_toggled_cb)

        # test = builder.get_object("eventbox1")
        #test.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#FF8"))

    def update_plotview_status_bar(self, widget):
        self.viewParamsStatusBar.set_text('Środek: ' + str(widget.center) + ', skala: ' + str(widget.scale) + ' px/j')

    def viewCursor_toggled_cb(self, widget):
        self.plotWidget.show_cursor = widget.active

    def viewGridlines_toggled_cb(self, widget):
        self.plotWidget.show_gridlines = widget.active

    def on_howToUse_activate(self, widget):
        filename = "HowToWindow.glade"
        builder = gtk.Builder()
        builder.add_from_file(filename)
        builder.connect_signals(self)
        window = builder.get_object("howToWindow")
        window.show_all()

    def open_about_window_cb(self, widget):
        filename = "AboutWindow.glade"
        builder = gtk.Builder()
        builder.add_from_file(filename)
        builder.connect_signals(self)
        window = builder.get_object("aboutWindow")
        window.show_all()

    def addFunction(self, widget):

        # DrawableFunction
        drawableFunction = DrawableFunction()
        self.plotWidget.add_function(drawableFunction)

        # GtkEventBox (will contain all elements)
        eventBox = gtk.EventBox()
        eventBox.show()

        # GtkFixed and setting its height
        fixed = gtk.Fixed()
        fixed.show()
        fixed.set_size_request(-1, 60)

        # "x" button
        removeButton = gtk.Button()
        removeButton.show()
        removeButton.set_size_request(45, 21)
        removeButton.set_label('usuń')
        removeButton.connect("clicked", self.removeFunction, drawableFunction, eventBox)
        fixed.put(removeButton, 197, 2)

        # "choose color" button
        changeColorButton = gtk.Button()
        changeColorButton.show()
        changeColorButton.set_size_request(73, 21)
        changeColorButton.set_label('zmień kolor')
        changeColorButton.connect("clicked", self.changeColor, drawableFunction, eventBox)
        fixed.put(changeColorButton, 120, 2)

        # text field
        textField = gtk.Entry()
        textField.show()
        textField.set_size_request(230, 27)
        textField.connect('changed', self.editFunction, drawableFunction)
        fixed.put(textField, 10, 23)

        # "draw' checkbox
        checkBox = gtk.CheckButton()
        checkBox.show()
        checkBox.set_size_request(70, 27)
        checkBox.set_label('aktywna')
        checkBox.set_active(True)
        checkBox.connect('toggled', self.showOrHideFunction, drawableFunction)
        fixed.put(checkBox, 10, 0)

        eventBox.modify_bg(gtk.STATE_NORMAL, gtk.gdk.Color("#CCCCCC"))

        # adding the event box as a child of the functionsVbox
        eventBox.add(fixed)
        self.functionsVbox.pack_start(eventBox, False, True, 1)

        # move the function adding button to the end of the Vbox
        self.functionsVbox.reorder_child(self.addFunctionButton, -1)

        # placing cursor in the newly added Entry
        textField.grab_focus()

        return eventBox, textField, checkBox, drawableFunction

    def on_readFromFile_activate(self, widget):
        openDialog = gtk.FileChooserDialog('Wskaż plik, z którego mają zostać załadowane funkcje',
                                           self.window, gtk.FILE_CHOOSER_ACTION_OPEN,
                                           (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_OPEN, gtk.RESPONSE_OK))
        openDialog.set_default_response(gtk.RESPONSE_OK)

        filter = gtk.FileFilter()
        filter.set_name("Pliki XML (*.xml)")
        filter.add_pattern("*.xml")
        openDialog.add_filter(filter)

        response = openDialog.run()

        if response == gtk.RESPONSE_OK:
            self.on_clearList_activate(None)

            tree = ElementTree.parse(openDialog.get_filename())
            root = tree.getroot()

            for f in root:
                eventBox, textField, checkBox, drawableFunction = self.addFunction(None)

                color = f.find('color')

                gtkColor = gtk.gdk.Color(float(color.get('red')),
                                         float(color.get('green')),
                                         float(color.get('blue')))
                drawableFunction.color = color_from_gtk_to_float(gtkColor)
                eventBox.modify_bg(gtk.STATE_NORMAL, gtkColor)
                checkBox.set_active(f.get('active') == 'True')
                textField.set_text(f.find('code').text.strip())

        openDialog.destroy()

    def on_saveToFile_activate(self, widget):
        saveDialog = gtk.FileChooserDialog('Wskaż plik gdzie zapisać funkcje',
                                           self.window, gtk.FILE_CHOOSER_ACTION_SAVE,
                                           (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL,
                                            gtk.STOCK_SAVE, gtk.RESPONSE_OK))
        saveDialog.set_default_response(gtk.RESPONSE_OK)

        filter = gtk.FileFilter()
        filter.set_name("Pliki XML (*.xml)")
        filter.add_pattern("*.xml")
        saveDialog.add_filter(filter)

        response = saveDialog.run()

        if response == gtk.RESPONSE_OK:
            functions = self.plotWidget.functions

            top = Element('functions')

            for f in functions:
                functionTag = SubElement(top, 'function')

                functionTag.set('active', str(f.enabled))

                colorTag = SubElement(functionTag, 'color')
                colorTag.set('red', str(f.color.r))
                colorTag.set('green', str(f.color.g))
                colorTag.set('blue', str(f.color.b))

                codeTag = SubElement(functionTag, 'code')
                codeTag.text = f.function_evaluator.function_string

            with open(saveDialog.get_filename(), 'w') as file:
                file.write(prettify(top))

        saveDialog.destroy()

    def on_clearList_activate(self, widget):
        self.plotWidget.functions = []

        for item in self.functionsVbox:
            if type(item) is gtk.EventBox:
                self.functionsVbox.remove(item)

    def on_zoomIn_activate(self, widget):
        self.plotWidget.zoom_in()

    def on_zoomOut_activate(self, widget):
        self.plotWidget.zoom_out()

    def on_reset_activate(self, widget):
        self.plotWidget.reset_view()
        self.plotWidget.queue_draw()

    def showOrHideFunction(self, checkBox, drawableFunction):
        drawableFunction.enabled = checkBox.get_active()
        self.plotWidget.queue_draw()

    def editFunction(self, entry, drawableFunction):
        newText = entry.get_text()
        drawableFunction.function_evaluator.set_function(newText)

        entry.modify_base(gtk.STATE_NORMAL,
                          gtk.gdk.Color("#FFF"
                                        if drawableFunction.function_evaluator.can_be_drawn or newText
                                        is "" else "#F66"))
        self.errorsStatusBar.set_text(translate_to_polish(drawableFunction.function_evaluator.errors))

        self.plotWidget.queue_draw()

    def changeColor(self, button, drawableFunction, eventBox):
        csw = ColorSelectionWindow(self.plotWidget, drawableFunction, eventBox)
        csw.show_window()

    def removeFunction(self, widget, drawableFunction, eventBox):
        self.plotWidget.functions.remove(drawableFunction)
        self.functionsVbox.remove(eventBox)
        self.plotWidget.queue_draw()

    def onDeleteWindow(self, *args):
        gtk.main_quit(*args)