Ejemplo n.º 1
0
 def generateLegendMenu(self):
     self.menuLegend = QtGui.QMenu(self.menubar)
     self.menuLegend.setTitle('Legend')
     self.actionGenerateLegend = QtGui.QAction(self)
     self.actionGenerateLegend.setText('Generate Draggable Legend')
     self.menuLegend.addAction(self.actionGenerateLegend)
     self.menubar.addAction(self.menuLegend.menuAction())
     self.connect(self.actionGenerateLegend, QtCore.SIGNAL('triggered()'),
                  self.generateLegend)
Ejemplo n.º 2
0
    def __init__(self, canvas, parent, coordinates=True):
        NavigationToolbar2QT.__init__(self, canvas, parent, coordinates)
        self.setIconSize(QtCore.QSize(16, 16))

        self.ct = None
        self.mw = None
        self._idPress1 = None
        self._idPress2 = None
        self._idPress3 = None
Ejemplo n.º 3
0
 def add_QDateTimeEdit(self, spec):
     widget = QtWidgets.QDateTimeEdit(spec.get('default',
                                               datetime.utcnow()))
     self.fields[spec['name']] = widget
     widget.setTime(QtCore.QTime(0, 0, 0))
     widget.setCalendarPopup(True)
     label_text = spec.get('label', spec['name'])
     self.layout.addWidget(QtWidgets.QLabel(label_text))
     self.layout.addWidget(widget)
Ejemplo n.º 4
0
class DimensionWidget(QW.QWidget):
    """
    Widget to select dimensions
    """

    #: Signal emitted when value is changed
    valueChanged = QtCore.Signal(int)

    def __init__(self, dimension):
        """
        Construct the widget

        Args:
            dimension: xarray.DataArray
        """
        super().__init__()

        main_layout = QW.QHBoxLayout(self)

        #: The dimension represented by this widget
        self.dimension = dimension

        self.title = QW.QLabel(dimension.name)
        self.textbox = QW.QLineEdit()
        self.slider = QW.QSlider(orientation=QtCore.Qt.Horizontal)

        self.slider.setMinimum(0)
        self.slider.setMaximum(dimension.size - 1)

        self.slider.valueChanged.connect(self._update_from_slider)
        self.textbox.returnPressed.connect(self._update_from_value)

        self.slider.setValue(0)
        self.textbox.setText(str(self.dimension[0].values))

        main_layout.addWidget(self.title)
        main_layout.addWidget(self.textbox)
        main_layout.addWidget(self.slider)

    def _update_from_value(self):
        value = self.textbox.text()
        value = numpy.asscalar(numpy.array(value, dtype=self.dimension.dtype))
        index = self.dimension.to_index().get_loc(value, method='nearest')
        self.slider.setValue(index)

    def _update_from_slider(self, value):
        self.textbox.setText(str(self.dimension[value].values))
        self.valueChanged.emit(value)

    def value(self):
        """
        The current slider index
        """
        return self.slider.value()
Ejemplo n.º 5
0
class ComponentsList(QtCore.QObject):
    '''
    Keep track of Components in a list and emit signals.
    Methods 'append' and 'remove' are provided and emit signals,
    direct access to the list is allowed with 'ComponentList.list',
    but not recommended.'''
    componentAppended = QtCore.pyqtSignal(object, name="ComponentAppended")
    componentRemoved = QtCore.pyqtSignal(object, name="ComponentRemoved")

    def __init__(self):
        super(ComponentsList, self).__init__()
        self.list = []

    def append(self, item):
        self.list.append(item)
        self.componentAppended.emit(item)

    def remove(self, item):
        self.list.remove(item)
        self.componentRemoved.emit(item)

    def index(self, item):
        return self.list.index(item)

    def __delitem__(self, key):
        self.list.__delitem__(key)

    def __getitem__(self, key):
        return self.list.__getitem__(key)

    def __setitem__(self, key, value):
        self.list.__setitem__(key, value)

    def __len__(self):
        return len(self.list)

    def __repr__(self):
        return self.list.__repr__()
Ejemplo n.º 6
0
    def __init__(self):
        self.blocksr80comm = False
        self.blockv80comm = False  #True
        self.blockmotorcomm = False
        super().__init__()
        #
        #
        self.title = 'Ny-Ålesund Emission Measurements'
        self.setWindowTitle(self.title)
        #
        self.checkbox = False
        #
        self.emailsent = 0
        #
        self.initUI()
        #
        #        self._update_canvas()
        #
        self.bck = QtCore.QTimer()
        self.bck.setInterval(1000)
        self.bck.timeout.connect(self.Update_StatusBox)
        self.bck.start()

        self.rseq = QtCore.QTimer()
        self.rseq.setInterval(1000)
        self.rseq.timeout.connect(self.run_sequence)
        self.rseq.start()

        self.check_cond = QtCore.QTimer()
        self.check_cond.setInterval(1000)
        self.check_cond.timeout.connect(self.check_conditions)
        self.check_cond.start()

        self.timer_al = QtCore.QTimer()
        self.timer_al.setInterval(100)
        self.timer_al.timeout.connect(self._update_actual_line)
        self.timer_al.start()
Ejemplo n.º 7
0
    def __init__(self,
                 wib_server='127.0.0.1',
                 config='femb0.json',
                 grid=False):
        super().__init__()

        self.wib = WIB(wib_server)
        self.config = config

        self._main = QtWidgets.QWidget()
        self._main.setFocusPolicy(QtCore.Qt.StrongFocus)
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)

        self.grid = QtWidgets.QGridLayout()
        if grid:
            self.views = [Hist2DView(), FFTView(), MeanView(), RMSView()]
            for i, v in enumerate(self.views):
                self.grid.addWidget(v, i % 2, i // 2)
        else:
            self.views = [Hist2DView(), MeanRMSView(), FFTView()]
            for i, v in enumerate(self.views):
                self.grid.addWidget(v, 0, i)
        layout.addLayout(self.grid)

        nav_layout = QtWidgets.QHBoxLayout()

        button = QtWidgets.QPushButton('Configure')
        nav_layout.addWidget(button)
        button.setToolTip('Configure WIB and front end')
        button.clicked.connect(self.configure_wib)

        button = QtWidgets.QPushButton('Acquire')
        nav_layout.addWidget(button)
        button.setToolTip('Read WIB Spy Buffer')
        button.clicked.connect(self.acquire_data)

        button = QtWidgets.QPushButton('Continuous')
        nav_layout.addWidget(button)
        button.setToolTip('Repeat acquisitions until stopped')
        button.clicked.connect(self.toggle_continuous)
        self.continuious_button = button

        self.timer = QtCore.QTimer(self)
        self.timer.timeout.connect(self.acquire_data)

        layout.addLayout(nav_layout)

        self.plot()
Ejemplo n.º 8
0
class Trace(QtCore.QThread):
    """ timer for the IOC measurement"""
    ##--------Signal Definition--------##
    started = QtCore.pyqtSignal()
    finished = QtCore.pyqtSignal('PyQt_PyObject')
    ##--------CONSTRUCTOR--------##    
    def __init__(self,interval): # t--interval call the hFunction
        QtCore.QThread.__init__(self)
        self.interval = interval
        self.evented = threading.Event()  # 引入事件进行定时器的设置
        self.trace_points = None
        self.trace_time = None
        self.trace_value = {} 
        self.trace_triggerlevel = None
        self.trace_offsettime = None     
    #Execute
    def run(self):
        self.started.emit()
        while not self.evented.is_set():
            self.evented.wait(self.interval)
            #self.trace_points = caget('SRFLab-010:RFS-PM-01:Trace_points.VAL', as_string=False)
            self.trace_time = caget('SRFLab-010:RFS-PM-01:Trace_time.VAL', as_string=False)
            self.trace_value = caget('SRFLab-010:RFS-PM-01:Value_trace.VAL', as_string=False)
            self.trace_triggerlevel = caget('SRFLab-010:RFS-PM-01:Trace_level_callback_DBM.VAL', as_string=False)
            self.trace_offsettime = caget('SRFLab-010:RFS-PM-01:Trace_offset_time_callback.VAL',as_string=False)
            self.trace_points = len(self.trace_value)
            psen = TraceMeasure()
            psen._array = self.trace_value
            psen._points = self.trace_points
            psen._time = self.trace_time
            psen._triggerlevel = self.trace_triggerlevel
            psen._offsetTime = self.trace_offsettime
            self.finished.emit(psen)
    #STOP
    def cancel(self):
        self.evented.set()
Ejemplo n.º 9
0
 def save(self):
     self.frame_no = self.frame_no - np.int(self.frame_no != 0)
     self.save_btns.setText("Saving Progressing")
     self.directory = self.get_video_directory()
     if self.directory == None:
         self.directory = "kimo"
     frame = cv2.imread(f"imgs/img{self.graph_index}_0.jpeg")
     height, width, layers = frame.shape
     self.save_progress.show()
     self.video = cv2.VideoWriter(f"{self.directory}.avi", 0, 5,
                                  (width, height))
     self.index = 0
     self.timer = QtCore.QTimer()
     self.timer.setInterval(20)
     self.timer.timeout.connect(
         lambda: self.save_video_iterate(width, height))
     self.timer.start()
Ejemplo n.º 10
0
    def _init_toolbar(self):
        # ! Choose icon theme
        if self.darkMode == True:
            self.basedir = os.path.join(self.main_dir, 'data', 'resources',
                                        'images_dark',
                                        'matplotlib-dark-images')
        else:
            self.basedir = os.path.join(matplotlib.rcParams['datapath'],
                                        'images')

        for text, tooltip_text, image_file, callback in self.toolitems:
            if text is None:
                self.addSeparator()
            else:
                a = self.addAction(self._icon(image_file + '.png'), text,
                                   getattr(self, callback))
                self._actions[callback] = a
                if callback in ['zoom', 'pan']:
                    a.setCheckable(True)
                if tooltip_text is not None:
                    a.setToolTip(tooltip_text)
                if text == 'Subplots':
                    a = self.addAction(self._icon("qt4_editor_options.png"),
                                       'Customize', self.edit_parameters)
                    a.setToolTip('Edit axis, curve and image parameters')

        # Add the x,y location widget at the right side of the toolbar
        # The stretch factor is 1 which means any resizing of the toolbar
        # will resize this label instead of the buttons.
        if self.coordinates:
            self.locLabel = QtWidgets.QLabel("", self)
            self.locLabel.setAlignment(QtCore.Qt.AlignRight
                                       | QtCore.Qt.AlignTop)
            self.locLabel.setSizePolicy(
                QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                      QtWidgets.QSizePolicy.Ignored))
            labelAction = self.addWidget(self.locLabel)
            labelAction.setVisible(True)

        # Esthetic adjustments - we need to set these explicitly in PyQt5
        # otherwise the layout looks different - but we don't want to set it if
        # not using HiDPI icons otherwise they look worse than before.
        if is_pyqt5() and self.canvas._dpi_ratio > 1:
            self.setIconSize(QtCore.QSize(24, 24))
            self.layout().setSpacing(12)
Ejemplo n.º 11
0
    def _init_toolbar(self):
        self.basedir = resource_filename('VisualPIC.Icons.mpl', '')

        for text, tooltip_text, image_file, callback in self.toolitems:
            if text is None:
                self.addSeparator()
            else:
                a = self.addAction(self._icon(image_file + '.svg'), text,
                                   getattr(self, callback))
                self._actions[callback] = a
                if callback in ['zoom', 'pan']:
                    a.setCheckable(True)
                if tooltip_text is not None:
                    a.setToolTip(tooltip_text)
                if text == 'Subplots':
                    a = self.addAction(self._icon("qt4_editor_options.svg"),
                                       'Customize', self.edit_parameters)
                    a.setToolTip('Edit axis, curve and image parameters')

        self.buttons = {}

        # Add the x,y location widget at the right side of the toolbar
        # The stretch factor is 1 which means any resizing of the toolbar
        # will resize this label instead of the buttons.
        if self.coordinates:
            self.locLabel = QtWidgets.QLabel("", self)
            self.locLabel.setAlignment(QtCore.Qt.AlignRight
                                       | QtCore.Qt.AlignTop)
            self.locLabel.setSizePolicy(
                QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding,
                                      QtWidgets.QSizePolicy.Ignored))
            labelAction = self.addWidget(self.locLabel)
            labelAction.setVisible(True)

        # reference holder for subplots_adjust window
        self.adj_window = None

        # Esthetic adjustments - we need to set these explicitly in PyQt5
        # otherwise the layout looks different - but we don't want to set it if
        # not using HiDPI icons otherwise they look worse than before.
        if is_pyqt5():
            self.setIconSize(QtCore.QSize(24, 24))
            self.layout().setSpacing(12)
Ejemplo n.º 12
0
    def initialize_map(self, restart=0):
        if restart == 1:
            if self.index > 0:
                self.timer.stop()
                self.pc.remove()
                self.cax.cla()
                self.index = 0
                self.fig.delaxes(self.cax)
                divider = make_axes_locatable(self.ax)
                self.cax = divider.append_axes('right', size='3%', pad=0)
                self.timer.start()

        else:
            self.fig, self.ax = plt.subplots()
            self.divider = make_axes_locatable(self.ax)
            self.cax = self.divider.append_axes('right', size='3%', pad=0)

            self.map = Basemap(projection='cyl',
                               resolution='h',
                               llcrnrlat=-90,
                               urcrnrlat=90,
                               llcrnrlon=-180,
                               urcrnrlon=180,
                               ax=self.ax)
            self.map.drawmapboundary(fill_color='aqua')
            self.map.fillcontinents(color='darkblue', lake_color='aqua')
            self.map.drawcoastlines()
            self.map.readshapefile(
                'ne_10m_admin_0_countries/ne_10m_admin_0_countries',
                'countries')
            plotWidget = FigureCanvas(self.fig)
            cid = self.fig.canvas.mpl_connect('button_press_event',
                                              self.on_press)
            self.index = 0
            self.ui.map_layout.addWidget(plotWidget)
            self.save_map_v = save_video(self, self.index, 0,
                                         self.ui.save_li[0],
                                         self.ui.prpgress_li[0])
            self.timer = QtCore.QTimer()
            self.timer.setInterval(80)
            self.timer.timeout.connect(self.update_map)
            self.timer_li.append(self.timer)
            self.timer.start()
Ejemplo n.º 13
0
 def initialize_bubble(self, restart=0):
     if restart == 1:
         self.timer1.stop()
         self.ax1.cla()
         self.index1 = 0
         self.timer1.start()
     else:
         self.fig1, self.ax1 = plt.subplots()
         plotWidget = FigureCanvas(self.fig1)
         self.ui.buble_layout.addWidget(plotWidget)
         self.index1 = 0
         self.last_values = [[0] * self.countries_no] * 3
         self.save_buble_v = save_video(self, self.index1, 1,
                                        self.ui.save_li[1],
                                        self.ui.prpgress_li[1])
         self.timer1 = QtCore.QTimer()
         self.timer1.setInterval(15)
         self.timer1.timeout.connect(self.update_bubble)
         self.timer_li.append(self.timer1)
         self.timer1.start()
Ejemplo n.º 14
0
    def __init__(self, model, interactive, data=None):
        """
        :param model: model.Model
        :param interactive: bool
            Boolean indicating if we are running in an interactive setting
            such as an ipython session. Helpful for deciding to parse CLI args,
            or not.
        :param data:
            Some type of array container, e.g. pandas.DataFrame,
            see `View.load_seria`

        """
        super(View, self).__init__()
        self.actions = {}
        self.model = model

        self.avail_slots_by_signal = {}
        self.avail_slots_by_signal['sig_new_data'] = [self.model.add_dataitem]
        self.avail_slots_by_signal['sig_new_markings'] = [
            self.model.new_markings_from_description
        ]
        self.avail_slots_by_signal['sig_apply_on_visible'] = [
            self.model.apply_on_visible,
        ]

        self.avail_signals = {}
        # Populate initially with signals from model
        for k, v in self.model.signals.items():
            self.avail_signals[k] = v

        self.draw_timer = QtCore.QTimer()
        self.init_ui()
        self.canvas_redraw()

        if not interactive:
            QtCore.QTimer.singleShot(0, self.parse_sysargs)
        if data is not None:
            logger.debug('Scheduling load-data callback')
            QtCore.QTimer.singleShot(0, lambda: self.load_seria(data))
Ejemplo n.º 15
0
    def __init__(self, publisher, *args, **kwargs):
        self.pub = publisher

        # Initialise the different maps for the display of the mems surface
        self.map_index, self.map_index_h = fits.getdata(FCTRLV2_PATH + MEMS_INDEX_NAME, header=True)
        self.map_height, self.map_width = np.shape(self.map_index)
        self.map_opd = np.ones((self.map_height, self.map_width))
        self.map_opd[self.map_index == 0] = 0
        self.map_centers = np.loadtxt(FCTRLV2_PATH + MEMS_CENTERS_NAME, dtype=np.int)
        self.map_radius_x = np.ones((self.map_height, self.map_width))
        self.map_radius_y = np.ones((self.map_height, self.map_width))
        self.compute_radii()

        # Initialise the figure (canvas)
        MyMplCanvas.__init__(self, *args, **kwargs)
        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.update_figure)
        timer.start(100)

        self.mems = Mems(self.pub)
        self.mems.connect()
        self.mems.flat()
 def setup(self):
     for label, value in self.data:
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtWidgets.QLabel(" "),
                                    QtWidgets.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtWidgets.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif (label.lower() not in BLACKLIST
               and mcolors.is_color_like(value)):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, str):
             field = QtWidgets.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             # Note: get() below checks the type of value[0] in self.data so
             # it is essential that value gets modified in-place.
             # This means that the code is actually broken in the case where
             # value is a tuple, but fortunately we always pass a list...
             selindex = value.pop(0)
             field = QtWidgets.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [key for key, _val in value]
                 value = [val for _key, val in value]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, Integral):
                 _log.warning(
                     "index '%s' is invalid (label: %s, value: %s)",
                     selindex, label, value)
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtWidgets.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else:
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, Integral):
             field = QtWidgets.QSpinBox(self)
             field.setRange(-10**9, 10**9)
             field.setValue(value)
         elif isinstance(value, Real):
             field = QtWidgets.QLineEdit(repr(value), self)
             field.setCursorPosition(0)
             field.setValidator(QtGui.QDoubleValidator(field))
             field.validator().setLocale(QtCore.QLocale("C"))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             field.textChanged.connect(lambda text: dialog.update_buttons())
         elif isinstance(value, datetime.datetime):
             field = QtWidgets.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtWidgets.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtWidgets.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
class FormWidget(QtWidgets.QWidget):
    update_buttons = QtCore.Signal()

    def __init__(self, data, comment="", with_margin=False, parent=None):
        """
        Parameters
        ----------
        data : list of (label, value) pairs
            The data to be edited in the form.
        comment : str, optional

        with_margin : bool, optional, default: False
            If False, the form elements reach to the border of the widget.
            This is the desired behavior if the FormWidget is used as a widget
            alongside with other widgets such as a QComboBox, which also do
            not have a margin around them.
            However, a margin can be desired if the FormWidget is the only
            widget within a container, e.g. a tab in a QTabWidget.
        parent : QWidget or None
            The parent widget.
        """
        QtWidgets.QWidget.__init__(self, parent)
        self.data = copy.deepcopy(data)
        self.widgets = []
        self.formlayout = QtWidgets.QFormLayout(self)
        if not with_margin:
            self.formlayout.setContentsMargins(0, 0, 0, 0)
        if comment:
            self.formlayout.addRow(QtWidgets.QLabel(comment))
            self.formlayout.addRow(QtWidgets.QLabel(" "))

    def get_dialog(self):
        """Return FormDialog instance"""
        dialog = self.parent()
        while not isinstance(dialog, QtWidgets.QDialog):
            dialog = dialog.parent()
        return dialog

    def setup(self):
        for label, value in self.data:
            if label is None and value is None:
                # Separator: (None, None)
                self.formlayout.addRow(QtWidgets.QLabel(" "),
                                       QtWidgets.QLabel(" "))
                self.widgets.append(None)
                continue
            elif label is None:
                # Comment
                self.formlayout.addRow(QtWidgets.QLabel(value))
                self.widgets.append(None)
                continue
            elif tuple_to_qfont(value) is not None:
                field = FontLayout(value, self)
            elif (label.lower() not in BLACKLIST
                  and mcolors.is_color_like(value)):
                field = ColorLayout(to_qcolor(value), self)
            elif isinstance(value, str):
                field = QtWidgets.QLineEdit(value, self)
            elif isinstance(value, (list, tuple)):
                if isinstance(value, tuple):
                    value = list(value)
                # Note: get() below checks the type of value[0] in self.data so
                # it is essential that value gets modified in-place.
                # This means that the code is actually broken in the case where
                # value is a tuple, but fortunately we always pass a list...
                selindex = value.pop(0)
                field = QtWidgets.QComboBox(self)
                if isinstance(value[0], (list, tuple)):
                    keys = [key for key, _val in value]
                    value = [val for _key, val in value]
                else:
                    keys = value
                field.addItems(value)
                if selindex in value:
                    selindex = value.index(selindex)
                elif selindex in keys:
                    selindex = keys.index(selindex)
                elif not isinstance(selindex, Integral):
                    _log.warning(
                        "index '%s' is invalid (label: %s, value: %s)",
                        selindex, label, value)
                    selindex = 0
                field.setCurrentIndex(selindex)
            elif isinstance(value, bool):
                field = QtWidgets.QCheckBox(self)
                if value:
                    field.setCheckState(QtCore.Qt.Checked)
                else:
                    field.setCheckState(QtCore.Qt.Unchecked)
            elif isinstance(value, Integral):
                field = QtWidgets.QSpinBox(self)
                field.setRange(-10**9, 10**9)
                field.setValue(value)
            elif isinstance(value, Real):
                field = QtWidgets.QLineEdit(repr(value), self)
                field.setCursorPosition(0)
                field.setValidator(QtGui.QDoubleValidator(field))
                field.validator().setLocale(QtCore.QLocale("C"))
                dialog = self.get_dialog()
                dialog.register_float_field(field)
                field.textChanged.connect(lambda text: dialog.update_buttons())
            elif isinstance(value, datetime.datetime):
                field = QtWidgets.QDateTimeEdit(self)
                field.setDateTime(value)
            elif isinstance(value, datetime.date):
                field = QtWidgets.QDateEdit(self)
                field.setDate(value)
            else:
                field = QtWidgets.QLineEdit(repr(value), self)
            self.formlayout.addRow(label, field)
            self.widgets.append(field)

    def get(self):
        valuelist = []
        for index, (label, value) in enumerate(self.data):
            field = self.widgets[index]
            if label is None:
                # Separator / Comment
                continue
            elif tuple_to_qfont(value) is not None:
                value = field.get_font()
            elif isinstance(value, str) or mcolors.is_color_like(value):
                value = str(field.text())
            elif isinstance(value, (list, tuple)):
                index = int(field.currentIndex())
                if isinstance(value[0], (list, tuple)):
                    value = value[index][0]
                else:
                    value = value[index]
            elif isinstance(value, bool):
                value = field.checkState() == QtCore.Qt.Checked
            elif isinstance(value, Integral):
                value = int(field.value())
            elif isinstance(value, Real):
                value = float(str(field.text()))
            elif isinstance(value, datetime.datetime):
                value = field.dateTime().toPyDateTime()
            elif isinstance(value, datetime.date):
                value = field.date().toPyDate()
            else:
                value = eval(str(field.text()))
            valuelist.append(value)
        return valuelist
Ejemplo n.º 18
0
 def __init__(self,wib_server='127.0.0.1',config='default.json',rows=1,cols=1,layout=None):
     super().__init__()
     plot_layout = layout
     
     self.context = zmq.Context()
     self.socket = self.context.socket(zmq.REQ)
     self.socket.connect('tcp://%s:1234'%wib_server)
     self.config = config
     
     self.samples = None
     self.timestamps = None
     
     self._main = QtWidgets.QWidget()
     self._main.setFocusPolicy(QtCore.Qt.StrongFocus)
     self.setCentralWidget(self._main)
     layout = QtWidgets.QVBoxLayout(self._main)
     
     button_layout = QtWidgets.QHBoxLayout()
     
     button = QtWidgets.QPushButton('Reshape')
     button_layout.addWidget(button)
     button.setToolTip('Change the plot grid shape')
     button.clicked.connect(self.reshape_prompt)
     
     button = QtWidgets.QPushButton('Load Layout')
     button_layout.addWidget(button)
     button.setToolTip('Save plot layout and selected signals')
     button.clicked.connect(self.load_layout)
     
     button = QtWidgets.QPushButton('Save Layout')
     button_layout.addWidget(button)
     button.setToolTip('Load plot layout and selected signals')
     button.clicked.connect(self.save_layout)
     
     layout.addLayout(button_layout)
     
     self.grid = QtWidgets.QGridLayout()
     self.views = []
     self.reshape(rows,cols)
     layout.addLayout(self.grid)
     
     nav_layout = QtWidgets.QHBoxLayout()
     
     button = QtWidgets.QPushButton('Configure')
     nav_layout.addWidget(button)
     button.setToolTip('Configure WIB and front end')
     button.clicked.connect(self.configure_wib)
     
     button = QtWidgets.QPushButton('Enable Pulser')
     nav_layout.addWidget(button)
     button.setToolTip('Toggle calibration pulser')
     button.clicked.connect(self.toggle_pulser)
     self.pulser_button = button
     
     button = QtWidgets.QPushButton('Acquire')
     nav_layout.addWidget(button)
     button.setToolTip('Read WIB Spy Buffer')
     button.clicked.connect(self.acquire_data)
     
     button = QtWidgets.QPushButton('Continuous')
     nav_layout.addWidget(button)
     button.setToolTip('Repeat acquisitions until stopped')
     button.clicked.connect(self.toggle_continuious)
     self.continuious_button = button
     
     self.timer = QtCore.QTimer(self)
     self.timer.timeout.connect(self.acquire_data)
     
     layout.addLayout(nav_layout)
     
     if plot_layout:
         self.load_layout(plot_layout)
     self.plot_selected()
Ejemplo n.º 19
0
import time
import pickle
import argparse
import numpy as np
import zmq
import json
from collections import deque

import wib_pb2 as wib

try:
    from matplotlib.backends.qt_compat import QtCore, QtWidgets, QtGui
except:
    from matplotlib.backends.backend_qt4agg import QtCore, QtWidgets, QtGui

if int(QtCore.qVersion().split('.')[0]) >= 5:
    from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
    from matplotlib.backends.backend_qt4agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
        
class CustomNavToolbar(NavigationToolbar):
    NavigationToolbar.toolitems = (
        ('Signals','Choose signal traces to show', 'choose', 'choose'),
        ('Autoscale', 'Autoscale axes for each new event', 'autoscale','autoscale'),
        ('Legend', 'Toggle legend', 'legend','legend'),
        (None, None, None, None),
        ('Home', 'Reset original view', 'home', 'home'),
        ('Back', 'Back to previous view', 'back', 'back'),
        ('Forward', 'Forward to next view', 'forward', 'forward'),
Ejemplo n.º 20
0
import sys
import time

import numpy as np

from matplotlib.backends.qt_compat import QtCore, QtWidgets

if QtCore.qVersion() >= "5.":
    from matplotlib.backends.backend_qt5agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
else:
    from matplotlib.backends.backend_qt4agg import (
        FigureCanvas, NavigationToolbar2QT as NavigationToolbar)
from matplotlib.figure import Figure


class ApplicationWindow(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self._main = QtWidgets.QWidget()
        self.setCentralWidget(self._main)
        layout = QtWidgets.QVBoxLayout(self._main)

        static_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(static_canvas)
        self.addToolBar(NavigationToolbar(static_canvas, self))

        dynamic_canvas = FigureCanvas(Figure(figsize=(5, 3)))
        layout.addWidget(dynamic_canvas)
        self.addToolBar(QtCore.Qt.BottomToolBarArea,
                        NavigationToolbar(dynamic_canvas, self))
Ejemplo n.º 21
0
 def setup(self):
     for label, value in self.data:
         if DEBUG:
             print("value:", value)
         if label is None and value is None:
             # Separator: (None, None)
             self.formlayout.addRow(QtWidgets.QLabel(" "),
                                    QtWidgets.QLabel(" "))
             self.widgets.append(None)
             continue
         elif label is None:
             # Comment
             self.formlayout.addRow(QtWidgets.QLabel(value))
             self.widgets.append(None)
             continue
         elif tuple_to_qfont(value) is not None:
             field = FontLayout(value, self)
         elif label.lower() not in BLACKLIST and is_color_like(value):
             field = ColorLayout(to_qcolor(value), self)
         elif isinstance(value, six.string_types):
             field = QtWidgets.QLineEdit(value, self)
         elif isinstance(value, (list, tuple)):
             if isinstance(value, tuple):
                 value = list(value)
             selindex = value.pop(0)
             field = QtWidgets.QComboBox(self)
             if isinstance(value[0], (list, tuple)):
                 keys = [key for key, _val in value]
                 value = [val for _key, val in value]
             else:
                 keys = value
             field.addItems(value)
             if selindex in value:
                 selindex = value.index(selindex)
             elif selindex in keys:
                 selindex = keys.index(selindex)
             elif not isinstance(selindex, int):
                 print("Warning: '%s' index is invalid (label: "
                       "%s, value: %s)" % (selindex, label, value),
                       file=STDERR)
                 selindex = 0
             field.setCurrentIndex(selindex)
         elif isinstance(value, bool):
             field = QtWidgets.QCheckBox(self)
             if value:
                 field.setCheckState(QtCore.Qt.Checked)
             else:
                 field.setCheckState(QtCore.Qt.Unchecked)
         elif isinstance(value, float):
             field = QtWidgets.QLineEdit(repr(value), self)
             field.setCursorPosition(0)
             field.setValidator(QtGui.QDoubleValidator(field))
             field.validator().setLocale(QtCore.QLocale("C"))
             dialog = self.get_dialog()
             dialog.register_float_field(field)
             field.textChanged.connect(lambda text: dialog.update_buttons())
         elif isinstance(value, int):
             field = QtWidgets.QSpinBox(self)
             field.setRange(-1e9, 1e9)
             field.setValue(value)
         elif isinstance(value, datetime.datetime):
             field = QtWidgets.QDateTimeEdit(self)
             field.setDateTime(value)
         elif isinstance(value, datetime.date):
             field = QtWidgets.QDateEdit(self)
             field.setDate(value)
         else:
             field = QtWidgets.QLineEdit(repr(value), self)
         self.formlayout.addRow(label, field)
         self.widgets.append(field)
Ejemplo n.º 22
0
class Start(QMainWindow):
    clicked = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(Start, self).__init__()
        self.ui = parent
        self.sens_objects = {
        }  ## Collection of Sensor objects for station for one month
        self.home()

    def home(self):
        print("HOME CALLED")
        # print("static_canvas",self.static_canvas)
        self.ui.mplwidget_top.canvas.figure.clf()
        self.ui.mplwidget_bottom.canvas.figure.clf()
        self._static_ax = self.ui.mplwidget_top.canvas.figure.subplots()
        self._static_fig = self.ui.mplwidget_top.canvas.figure
        self.pid = -99
        self.cid = -98
        self.toolbar1 = self._static_fig.canvas.toolbar  # Get the toolbar handler
        self.toolbar1.update()  # Update the toolbar memory
        # self._residual_fig = self.ui.mplwidget_bottom.canvas.figure
        self._residual_ax = self.ui.mplwidget_bottom.canvas.figure.subplots()
        self.ui.save_btn.clicked.connect(self.save_to_ts_files)
        self.ui.ref_level_btn.clicked.connect(self.show_ref_dialog)

    def make_sensor_buttons(self, sensors):
        # Remove all sensor checkbox widgets from the layout
        # every time new data is loaded
        for i in range(self.ui.verticalLayout_left_top.count()):
            item = self.ui.verticalLayout_left_top.itemAt(i)
            # self.verticalLayout_left_top.removeWidget(item.widget())
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()
        for i in range(self.ui.verticalLayout_bottom.count()):
            item = self.ui.verticalLayout_bottom.itemAt(i)
            # self.verticalLayout_left_top.removeWidget(item.widget())
            widget = item.widget()
            if widget is not None:
                widget.deleteLater()

        # sensors' keys are names of all sensors which carry
        # all of the data associated with it
        # Make copy of it so we can use its keys and assign radio buttons to it
        # If we do not make a copy then the  sensors values would get
        # overwritten by radio button objects
        self.sensor_dict = dict(sensors)
        self.sensor_dict2 = dict(sensors)

        # Counter added to figure out when the last item was added
        # Set alignment of the last item to push all the radio buttons up
        counter = len(sensors.items())
        for key, value in sensors.items():
            counter -= 1
            self.sensor_radio_btns = QtWidgets.QRadioButton(key, self)
            self.sensor_check_btns = QtWidgets.QCheckBox(key, self)
            self.sensor_dict[key] = self.sensor_radio_btns
            self.sensor_dict2[key] = self.sensor_check_btns
            self.ui.buttonGroup_data.addButton(self.sensor_dict[key])
            self.ui.buttonGroup_residual.addButton(self.sensor_dict2[key])
            if (counter > 0):
                self.ui.verticalLayout_left_top.addWidget(
                    self.sensor_dict[key])
                self.ui.verticalLayout_bottom.addWidget(self.sensor_dict2[key])
            else:
                self.ui.verticalLayout_left_top.addWidget(
                    self.sensor_dict[key], 0, QtCore.Qt.AlignTop)
                self.ui.verticalLayout_bottom.addWidget(
                    self.sensor_dict2[key], 0, QtCore.Qt.AlignTop)

            self.sensor_dict[key].setText(key)

        # radio_btn_HF = QtWidgets.QRadioButton("Minute", self)
        # radio_btn_HF.setChecked(True)
        self.mode = self.ui.radioButton_Minute.text()

        self.sensor_dict["PRD"].setChecked(True)
        self.sens_str = "PRD"
        # self.sensor_dict2["PRD"].setEnabled(False)
        self.sensor_dict2["ALL"].setEnabled(False)
        self.plot(all=False)
        self.ui.buttonGroup_data.buttonClicked.connect(self.on_sensor_changed)
        self.ui.buttonGroup_residual.buttonClicked.connect(
            self.on_residual_sensor_changed)
        self.ui.buttonGroup_resolution.buttonClicked.connect(
            self.on_frequency_changed)

    def on_sensor_changed(self, btn):
        print(btn.text())
        if (btn.text() == "ALL"):
            # TODO: plot_all and plot should be merged to one function
            self.ui.save_btn.setEnabled(False)
            self.ui.ref_level_btn.setEnabled(False)
            self.plot(all=True)
        else:
            self.ui.save_btn.setEnabled(True)
            self.ui.ref_level_btn.setEnabled(True)
            self.sens_str = btn.text()
            self._update_top_canvas(btn.text())
            self.ui.lineEdit.setText(
                self.sens_objects[self.sens_str].header[0])
            self.update_graph_values()

        # Update residual buttons and graph when the top sensor is changed
        # self.on_residual_sensor_changed(None)
        # Clear residual buttons and graph when the top sensor is changed
        for button in self.ui.buttonGroup_residual.buttons():
            button.setChecked(False)
        self._residual_ax.cla()
        self._residual_ax.figure.canvas.draw()
        # print("ref height:",self.sens_objects[self.sens_str].height)

    def on_frequency_changed(self, btn):
        print("Frequency changed", btn.text())
        self.mode = btn.text()
        if (self.mode == "Minute"):
            self.sensor_dict2["PRD"].setEnabled(True)
        else:
            self.sensor_dict2["PRD"].setEnabled(False)
        self.on_residual_sensor_changed()

    def update_graph_values(self):
        # convert 'nans' back to 9999s
        nan_ind = np.argwhere(np.isnan(self.browser.data))
        self.browser.data[nan_ind] = 9999
        # we want the sensor data object to point to self.browser.data and not self.browser.data.copy()
        # because when the self.browser.data is modified on the graph
        # the sensor data object will automatically be modified as well
        self.sens_objects[self.sens_str].data = self.browser.data

    def on_residual_sensor_changed(self):
        self._residual_ax.cla()
        self._residual_ax.figure.canvas.draw()

        checkedItems = [
            button for button in self.ui.buttonGroup_residual.buttons()
            if button.isChecked()
        ]
        if (checkedItems):
            for button in checkedItems:
                self.calculate_and_plot_residuals(self.sens_str, button.text(),
                                                  self.mode)
        else:
            self._residual_ax.cla()
            self._residual_ax.figure.canvas.draw()

    def plot(self, all=False):
        # Set the data browser object to NoneType on every file load
        self.browser = None
        self._static_ax.cla()
        self._residual_ax.cla()
        self._residual_ax.figure.canvas.draw()

        if all:
            lineEditText = 'No Header -- Plotting all sensors'
            sens_objects = self.sens_objects
            title = 'Relative levels = signal - average over selected period'
        else:
            lineEditText = self.sens_objects[self.sens_str].header[0]
            sens_objects = [self.sens_str]
            title = 'Tide Prediction'
        self.ui.lineEdit.setText(lineEditText)
        for sens in sens_objects:
            ## Set 9999s to NaN so they don't show up on the graph
            ## when initially plotted
            ## nans are converted back to 9999s when file is saved
            if sens == "ALL":
                pass
            else:
                data_flat = self.sens_objects[sens].get_flat_data()
                time = self.sens_objects[sens].get_time_vector()
                nines_ind = np.where(data_flat == 9999)
                data_flat[nines_ind] = float('nan')
                if all:
                    mean = np.nanmean(data_flat)
                else:
                    mean = 0
                # t = np.linspace(0, 10, 501)
                # t = np.arange(data.size)

                t = time
                y = data_flat - mean
                # self._static_ax.plot(t, np.tan(t), ".")
                line, = self._static_ax.plot(
                    t, y, '-', picker=5, lw=0.5,
                    markersize=3)  # 5 points tolerance
                # self._static_fig = self.static_canvas.figure
                if all:
                    line.set_label(sens)
                    self._static_ax.legend()
                self._static_ax.set_title(title)

                self._static_ax.autoscale(enable=True, axis='both', tight=True)
                self._static_ax.set_xlim([t[0], t[-1]])
                self._static_ax.margins(0.05, 0.05)

                self.ui.mplwidget_top.canvas.setFocusPolicy(
                    QtCore.Qt.ClickFocus)
                self.ui.mplwidget_top.canvas.setFocus()
                self.ui.mplwidget_top.canvas.figure.tight_layout()
                # self.toolbar1 = self._static_fig.canvas.toolbar #Get the toolbar handler
                self.toolbar1.update()  # Update the toolbar memory
                self.ui.mplwidget_top.canvas.draw()

    def calculate_and_plot_residuals(self, sens_str1, sens_str2, mode):
        # resample_freq = min(int(self.sens_objects[sens_str1].rate), int(self.sens_objects[sens_str2].rate))
        # _freq = str(resample_freq)+'min'
        #
        # # Get a date range to create pandas time Series
        # # using the sampling frequency of the sensor
        # rng1 = date_range(self.sens_objects[sens_str1].date, periods = self.sens_objects[sens_str1].data.size, freq=_freq)
        # ts1 = Series(self.sens_objects[sens_str1].data, rng1)
        #
        # rng2 = date_range(self.sens_objects[sens_str2].date, periods = self.sens_objects[sens_str2].data.size, freq=_freq)
        # ts2 = Series(self.sens_objects[sens_str2].data, rng2)

        # resample the data and linearly interpolate the missing values
        # upsampled = ts.resample(_freq)
        # interp = upsampled.interpolate()
        if mode == "Hourly":
            data_obj = {}
            # data_obj["prd"]={'time':filt.datenum2(self.sens_objects["PRD"].get_time_vector()), 'station':'014', 'sealevel':self.sens_objects["PRD"].get_flat_data().copy()}
            # for key in self.sens_objects.keys():
            #     print("KEY", key)
            sl_data = self.sens_objects[sens_str1].get_flat_data().copy()
            sl_data = self.remove_9s(sl_data)
            sl_data = sl_data - int(self.sens_objects[sens_str1].height)
            data_obj[sens_str1.lower()] = {
                'time':
                filt.datenum2(self.sens_objects[sens_str1].get_time_vector()),
                'station':
                '014',
                'sealevel':
                sl_data
            }

            sl_data2 = self.sens_objects[sens_str2].get_flat_data().copy()
            sl_data2 = self.remove_9s(sl_data2)
            sl_data2 = sl_data2 - int(self.sens_objects[sens_str2].height)
            data_obj[sens_str2.lower()] = {
                'time':
                filt.datenum2(self.sens_objects[sens_str2].get_time_vector()),
                'station':
                '014',
                'sealevel':
                sl_data2
            }

            year = self.sens_objects[sens_str2].date.astype(object).year
            month = self.sens_objects[sens_str2].date.astype(object).month
            data_hr = filt.hr_process_2(
                data_obj, filt.datetime(year, month, 1, 0, 0, 0),
                filt.datetime(year, month + 1, 1, 0, 0, 0))

            if sens_str1 != "PRD":
                hr_resid = data_hr[sens_str1.lower()]["sealevel"] - data_hr[
                    sens_str2.lower()]["sealevel"]
                time = [
                    filt.matlab2datetime(tval[0])
                    for tval in data_hr[list(data_hr.keys())[0]]['time']
                ]
                self.generic_plot(self.ui.mplwidget_bottom.canvas,
                                  time,
                                  hr_resid,
                                  sens_str1,
                                  sens_str2,
                                  "Hourly Residual",
                                  is_interactive=False)
            else:
                self.show_custom_message(
                    "Warning",
                    "For hourly residual an actual channel needs to be selected in the top plot."
                )
                self.generic_plot(
                    self.ui.mplwidget_bottom.canvas, [0], [0],
                    sens_str1,
                    sens_str2,
                    "Choose a channel in the top plot other than PRD",
                    is_interactive=False)

        else:
            newd1 = self.resample2(sens_str1)
            newd2 = self.resample2(sens_str2)
            # newd1 = ts1.resample(_freq).interpolate()
            # newd2 = ts2.resample(_freq).interpolate()
            if (newd1.size > newd2.size):
                resid = newd2 - newd1[:newd2.size]
            else:
                resid = newd1 - newd2[:newd1.size]

            # time = np.array([self.sens_objects[sens_str1].date + np.timedelta64(i*int(1), 'm') for i in range(resid.size)])
            # time = np.arange(resid.size)
            time = date_range(self.sens_objects[sens_str1].date,
                              periods=resid.size,
                              freq='1min')
            self.generic_plot(self.ui.mplwidget_bottom.canvas,
                              time,
                              resid,
                              sens_str1,
                              sens_str2,
                              "Residual",
                              is_interactive=False)

    def generic_plot(self, canvas, x, y, sens1, sens2, title, is_interactive):
        print("GENERIC PLOT CALLED")
        # self._residual_ax = canvas.figure.subplots()

        line, = self._residual_ax.plot(x,
                                       y,
                                       '-',
                                       picker=5,
                                       lw=0.5,
                                       markersize=3)  # 5 points tolerance
        line.set_gid(sens2)
        self._residual_fig = canvas.figure
        self._residual_ax.set_title(title)
        line.set_label(title + ": " + sens1 + " - " + sens2)
        self._residual_ax.autoscale(enable=True, axis='both', tight=True)
        self._residual_ax.set_xlim([x[0], x[-1]])
        self._residual_ax.margins(0.05, 0.05)
        self._residual_ax.legend()

        if (is_interactive):
            self.browser = PointBrowser(x, y, self._residual_ax, line,
                                        self._residual_fig,
                                        self.find_outliers(x, y, sens1))
            self.browser.onDataEnd += self.show_message
            canvas.mpl_connect('pick_event', self.browser.onpick)
            canvas.mpl_connect('key_press_event', self.browser.onpress)
            ## need to activate focus onto the mpl canvas so that the keyboard can be used
            canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
            canvas.setFocus()

        self._residual_ax.figure.tight_layout()
        self.toolbar2 = self._residual_fig.canvas.toolbar  # Get the toolbar handler
        self.toolbar2.update()  # Update the toolbar memory

        self._residual_ax.figure.canvas.draw()

    def _update_top_canvas(self, sens):
        data_flat = self.sens_objects[sens].get_flat_data()
        nines_ind = np.where(data_flat == 9999)
        # nonines_data = data_flat.copy()
        # nonines_data[nines_ind] = float('nan')
        # data_flat = nonines_data
        # data_flat =data_flat - np.nanmean(data_flat)
        if (len(nines_ind[0]) < data_flat.size):
            # data_flat[nines_ind] = float('nan')
            pass
        else:
            self.show_custom_message("Warning",
                                     "The following sensor has no data")
        self._static_ax.clear()
        # disconnect canvas pick and press events when a new sensor is selected
        # to eliminate multiple callbacks on sensor change
        # self.static_canvas.mpl_disconnect(self.pidP)
        # self.static_canvas.mpl_disconnect(self.cidP)
        self.ui.mplwidget_top.canvas.mpl_disconnect(self.pid)
        self.ui.mplwidget_top.canvas.mpl_disconnect(self.cid)
        if self.browser:
            self.browser.onDataEnd -= self.show_message
            self.browser.disconnect()
        # time = np.arange(data_flat.size)
        time = self.sens_objects[sens].get_time_vector()
        self.line, = self._static_ax.plot(time,
                                          data_flat,
                                          '-',
                                          picker=5,
                                          lw=0.5,
                                          markersize=3)

        self._static_ax.set_title(
            'select a point you would like to remove and press "D"')
        self.browser = PointBrowser(time, data_flat, self._static_ax,
                                    self.line, self._static_fig,
                                    self.find_outliers(time, data_flat, sens))
        self.browser.onDataEnd += self.show_message
        self.browser.on_sensor_change_update()
        # update event ids so that they can be disconnect on next sensor change
        self.pid = self.ui.mplwidget_top.canvas.mpl_connect(
            'pick_event', self.browser.onpick)
        self.cid = self.ui.mplwidget_top.canvas.mpl_connect(
            'key_press_event', self.browser.onpress)
        ## need to activate focus onto the mpl canvas so that the keyboard can be used
        self.toolbar1.update()
        self.ui.mplwidget_top.canvas.setFocusPolicy(QtCore.Qt.ClickFocus)
        self.ui.mplwidget_top.canvas.setFocus()

    def find_outliers(self, t, data, sens):

        channel_freq = self.sens_objects[sens].rate
        _freq = channel_freq + 'min'

        nines_ind = np.where(data == 9999)
        nonines_data = data.copy()
        nonines_data[nines_ind] = float('nan')
        # Get a date range to create pandas time Series
        # using the sampling frequency of the sensor
        rng = date_range(t[0], t[-1], freq=_freq)
        ts = Series(nonines_data, rng)

        # resample the data and linearly interpolate the missing values
        upsampled = ts.resample(_freq)
        interp = upsampled.interpolate()

        # calculate a window size for moving average routine so the window
        # size is always 60 minutes long
        window_size = 60 // int(channel_freq)

        # calculate moving average including the interolated data
        # moving_average removes big outliers before calculating moving average
        y_av = self.moving_average(np.asarray(interp.tolist()), window_size)
        # y_av = self.moving_average(data, 30)
        # missing=np.argwhere(np.isnan(y_av))
        # y_av[missing] = np.nanmean(y_av)

        # calculate the residual between the actual data and the moving average
        # and then find the data that lies outside of sigma*std
        residual = nonines_data - y_av
        std = np.nanstd(residual)
        sigma = 3.0

        itemindex = np.where((nonines_data > y_av + (sigma * std))
                             | (nonines_data < y_av - (sigma * std)))
        return itemindex

    def moving_average(self, data, window_size):
        """ Computes moving average using discrete linear convolution of two one dimensional sequences.
        Args:
        -----
                data (pandas.Series): independent variable
                window_size (int): rolling window size

        Returns:
        --------
                ndarray of linear convolution

        References:
        ------------
        [1] Wikipedia, "Convolution", http://en.wikipedia.org/wiki/Convolution.
        [2] API Reference: https://docs.scipy.org/doc/numpy/reference/generated/numpy.convolve.html

        """
        # REMOVE GLOBAL OUTLIERS FROM MOVING AVERAGE CALCULATION nk
        filtered_data = data.copy()
        # my_mad=np.nanmedian(np.abs(filtered_data-np.nanmedian(filtered_data)))
        # my_mean=np.nanmean(filtered_data)

        my_mean = np.nanmean(filtered_data)
        my_std = np.nanstd(filtered_data)

        # itemindex = np.where(((filtered_data>my_mean+4*my_mad )  | (filtered_data<my_mean-4*my_mad)))
        itemindex = np.where(((filtered_data > my_mean + 3 * my_std) |
                              (filtered_data < my_mean - 3 * my_std)))
        filtered_data[itemindex] = np.nanmean(filtered_data)
        # Fix boundary effects by adding prepending and appending values to the data
        filtered_data = np.insert(
            filtered_data, 0,
            np.ones(window_size) *
            np.nanmean(filtered_data[:window_size // 2]))
        filtered_data = np.insert(
            filtered_data, filtered_data.size,
            np.ones(window_size) *
            np.nanmean(filtered_data[-window_size // 2:]))
        window = np.ones(int(window_size)) / float(window_size)
        # return (np.convolve(filtered_data, window, 'same')[window_size:-window_size],itemindex)
        return np.convolve(filtered_data, window,
                           'same')[window_size:-window_size]

    def resample2(self, sens_str):
        data = self.sens_objects[sens_str].data.copy()
        nines_ind = np.where(data == 9999)
        data[nines_ind] = float('nan')
        ave = np.nanmean(data)
        datas = data[0:-1] - ave  # int(self.sens_objects[sens_str].height)
        datae = data[1:] - ave  # int(self.sens_objects[sens_str].height)
        yc = (datae - datas) / int(self.sens_objects[sens_str].rate)

        min_data = []
        for j in range(0, len(datas)):
            for i in range(0, int(self.sens_objects[sens_str].rate)):
                min_data.append(float(datas[j] + yc[j]))
        # nan_ind = np.argwhere(np.isnan(min_data))
        # min_data[nan_ind] = 9999
        return np.asarray(min_data)

    def show_message(self, *args):
        print("SHOW MESSAGE", *args)
        # choice = QtWidgets.QMessageBox.information(self, 'The end of data has been reached',  'The end of data has been reached', QtWidgets.QMessageBox.Ok)
        self.show_custom_message(*args, *args)

    def show_ref_dialog(self):
        try:
            self.browser
        except AttributeError:
            self.show_custom_message("Error!",
                                     "Data needs to be loaded first.")
            return
        else:
            if (self.is_digit(str(self.ui.refLevelEdit.text()))):
                # text, result = QtWidgets.QInputDialog.getText(self, 'My Input Dialog', 'Enter start date and time:')
                date, time, result = DateDialog.getDateTime(self)
                ISOstring = date.toString('yyyy-MM-dd') + 'T' + time.toString(
                    "HH:mm")
                if result:
                    REF_diff = int(str(self.ui.refLevelEdit.text())) - int(
                        self.sens_objects[self.sens_str].height)
                    new_REF = REF_diff + int(
                        self.sens_objects[self.sens_str].height)
                    # offset the data
                    self.browser.offset_data(ISOstring, REF_diff)
                    # format the new reference to a 4 character string (i.e add leading zeros if necessary)
                    # update the header
                    new_header = self.sens_objects[self.sens_str].header[0][:60] + '{:04d}'.format(new_REF) + \
                                 self.sens_objects[self.sens_str].header[0][64:]
                    self.sens_objects[self.sens_str].header[0] = new_header
                    self.ui.lineEdit.setText(
                        self.sens_objects[self.sens_str].header[0])
                    print("Succesfully changed to: ",
                          str(self.ui.refLevelEdit.text()))

            else:
                self.show_custom_message("Error!",
                                         "The value entered is not a number.")
                return

    def is_digit(self, n):
        try:
            int(n)
            return True
        except ValueError:
            return False

    def remove_9s(self, data):
        nines_ind = np.where(data == 9999)
        data[nines_ind] = float('nan')
        return data

    def show_custom_message(self, title, descrip):
        choice = QtWidgets.QMessageBox.information(self, title, descrip,
                                                   QtWidgets.QMessageBox.Ok)

    def save_to_ts_files(self):
        # Deleting tkey "ALL" from the list of sensors
        if "ALL" in self.sens_objects:
            del self.sens_objects["ALL"]
        if (self.sens_objects):
            months = len(
                self.sens_objects["PRD"].line_num)  # amount of months loaded
            # print("Amount of months loaded", months)
            assem_data = [
                [] for j in range(months)
            ]  # initial an empty list of lists with the number of months
            nan_ind = np.argwhere(np.isnan(self.browser.data))
            # print("NAN INDICES",nan_ind)
            # self.browser.data[nan_ind] = 9999
            # self.sens_objects[self.sens_str].data = self.browser.data
            # separate PRD from the rest because it has to be saved on the top file
            # Because dictionaries are unordered
            prd_list = [[] for j in range(months)]

            # Cycle through each month loaded
            for m in range(months):
                # Cycle through each month loaded, where key is the sensor name
                # Use value instead of self.sens_objects[key]?
                for key, value in self.sens_objects.items():
                    # Add header
                    # separate PRD from the rest because it has to be saved on the top file
                    if (key == "PRD"):
                        prd_list[m].append(
                            self.sens_objects[key].header[m].strip("\n"))
                    else:
                        assem_data[m].append(
                            self.sens_objects[key].header[m].strip("\n"))
                    # The ugly range is calculating start and end line numbers for each month that was Loaded
                    # so that the data can be saved to separate, monthly files
                    for i in range(
                            sum(self.sens_objects[key].line_num[:]) -
                            sum(self.sens_objects[key].line_num[m:]),
                            sum(self.sens_objects[key].line_num[:]) -
                            sum(self.sens_objects[key].line_num[m:]) +
                            self.sens_objects[key].line_num[m]):
                        # File formatting is differs based on the sampling rate of a sensor
                        if (int(self.sens_objects[key].rate) >= 5):
                            # Get only sealevel reading, without anything else (no time/date etc)
                            data = ''.join(
                                '{:5.0f}'.format(e)
                                for e in self.sens_objects[key].data.flatten()
                                [i * 12:12 + i * 12].tolist())
                            # The columns/rows containing only time/data and no sealevel measurements
                            it_col_formatted = '  ' + self.sens_objects[key].type + '  ' + \
                                               self.sens_objects[key].time_info[i][8:12].strip()[-2:] + \
                                               self.sens_objects[key].time_info[i][12:20]
                            # assem_data.append(info_time_col[i][0:]+data)
                            if (key == "PRD"):
                                prd_list[m].append(''.join(it_col_formatted) +
                                                   data)
                            else:
                                assem_data[m].append(
                                    ''.join(it_col_formatted) + data)
                        else:
                            data = ''.join(
                                '{:4.0f}'.format(e)
                                for e in self.sens_objects[key].data.flatten()
                                [i * 15:15 + i * 15].tolist())
                            it_col_formatted = '  ' + self.sens_objects[key].type + '  ' + \
                                               self.sens_objects[key].time_info[i][8:12].strip()[-2:] + \
                                               self.sens_objects[key].time_info[i][12:20]
                            # assem_data.append(info_time_col[i][0:]+data)
                            assem_data[m].append(''.join(it_col_formatted) +
                                                 data)
                    if (key == "PRD"):
                        prd_list[m].append('9' * 80)
                    else:
                        assem_data[m].append('9' * 80)
                del data
                # find the start date lines of each monp file that was loaded
                date_str = self.sens_objects[key].time_info[
                    sum(self.sens_objects[key].line_num[:]) -
                    sum(self.sens_objects[key].line_num[m:])]
                month_int = int(date_str[12:14][-2:])
                month_str = "{:02}".format(month_int)
                year_str = date_str[8:12][-2:]
                station_num = self.sens_objects[key].type[0:-3]
                file_name = 't' + station_num + year_str + month_str
                file_extension = '.dat'
                try:
                    with open(
                            st.get_path(st.SAVE_KEY) + '/' + file_name +
                            file_extension, 'w') as the_file:
                        for lin in prd_list[m]:
                            the_file.write(lin + "\n")
                        for line in assem_data[m]:
                            the_file.write(line + "\n")
                        # Each file ends with two lines of 80 9s that's why adding an additional one
                        the_file.write('9' * 80 + "\n")
                    self.show_custom_message(
                        "Success", "Success \n" + file_name + file_extension +
                        " Saved to " + st.get_path(st.SAVE_KEY) + "\n")
                except IOError as e:
                    self.show_custom_message(
                        "Error", "Cannot Save to " + st.get_path(st.SAVE_KEY) +
                        "\n" + str(e) +
                        "\n Please select a different path to save to")
                self.save_fast_delivery(self.sens_objects)
                self.save_mat_high_fq(file_name)
            # if result == True:
            #     print("Succesfully changed to: ", str(self.refLevelEdit.text()))
        else:
            self.show_custom_message("Warning", "You haven't loaded any data.")

    # this function is called for every month of data loaded
    def save_mat_high_fq(self, file_name):
        import scipy.io as sio
        if st.get_path(st.HF_PATH):
            save_path = st.get_path(st.HF_PATH)
        else:
            self.show_custom_message(
                "Warning",
                "Please select a location where you would like your high "
                "frequency matlab data "
                "to be saved. Click save again once selected.")
            return

        for key, value in self.sens_objects.items():
            sl_data = self.sens_objects[key].get_flat_data().copy()
            sl_data = self.remove_9s(sl_data)
            sl_data = sl_data - int(self.sens_objects[key].height)
            time = filt.datenum2(self.sens_objects[key].get_time_vector())
            data_obj = [time, sl_data]
            # transposing the data so that it matches the shape of the UHSLC matlab format
            matlab_obj = {
                'NNNN': file_name + key.lower(),
                file_name + key.lower(): np.transpose(data_obj, (1, 0))
            }
            try:
                sio.savemat(save_path + '/' + file_name + key.lower() + '.mat',
                            matlab_obj)
                self.show_custom_message(
                    "Success", "Success \n" + file_name + key.lower() +
                    '.mat' + " Saved to " + st.get_path(st.HF_PATH) + "\n")
            except IOError as e:
                self.show_custom_message(
                    "Error", "Cannot Save to high frequency (.mat) data to" +
                    st.get_path(st.HF_PATH) + "\n" + str(e) +
                    "\n Please select a different path to save to")

    def save_fast_delivery(self, _data):
        import scipy.io as sio
        # 1. Check if the .din file was added and that it still exist at that path
        #       b) also check that a save folder is set up
        # 2. If it does. load in the primary channel for our station
        # 3. If it does not exist, display a warning message on how to add it and that the FD data won't be saved
        # 4. Perform filtering and save
        din_path = None
        save_path = None
        if st.get_path(st.DIN_PATH):
            din_path = st.get_path(st.DIN_PATH)
        else:
            self.show_custom_message(
                "Warning",
                "The fast delivery data cannot be processed because you haven't selected"
                "the .din file location. Press F1 to access the menu to select it. And "
                "then click the save button again.")
            return

        if st.get_path(st.FD_PATH):
            save_path = st.get_path(st.FD_PATH)
        else:
            self.show_custom_message(
                "Warning",
                "Please select a location where you would like your hourly and daily data"
                "to be saved. Click save again once selected.")
            return

        data_obj = {}

        station_num = _data["PRD"].type[0:-3]
        primary_sensor = filt.get_channel_priority(
            din_path, station_num)[0].upper(
            )  # returns multiple sensor in order of importance
        if primary_sensor not in _data:
            self.show_custom_message(
                "Error", f"Your .din file says that {primary_sensor} "
                f"is the primary sensor but the file you have loaded does "
                f"not contain that sensor. Hourly and daily data will not be saved."
            )
            return
        sl_data = _data[primary_sensor].get_flat_data().copy()
        sl_data = self.remove_9s(sl_data)
        sl_data = sl_data - int(_data[primary_sensor].height)
        data_obj[primary_sensor.lower()] = {
            'time': filt.datenum2(_data[primary_sensor].get_time_vector()),
            'station': station_num,
            'sealevel': sl_data
        }

        year = _data[primary_sensor].date.astype(object).year
        month = _data[primary_sensor].date.astype(object).month

        #  Filter to hourly
        data_hr = filt.hr_process_2(data_obj,
                                    filt.datetime(year, month, 1, 0, 0, 0),
                                    filt.datetime(year, month + 1, 1, 0, 0, 0))

        # for channel parameters see filt.channel_merge function
        # We are not actually merging channels here (not needed for fast delivery)
        # But we still need to run the data through the merge function, even though we are only using one channel
        # in order to get the correct output data format suitable for the daily filter
        ch_params = [{primary_sensor.lower(): 0}]
        hourly_merged = filt.channel_merge(data_hr, ch_params)

        # Note that hourly merged returns a channel attribute which is an array of integers representing channel type.
        # used for a particular day of data. In Fast delivery, all the number should be the same because no merge
        # int -> channel name mapping is inside of filtering.py var_flag function
        data_day = filt.day_119filt(hourly_merged,
                                    _data[primary_sensor].location[0])

        month_str = "{:02}".format(month)
        hourly_filename = save_path + '/' + 'th' + str(station_num) + str(
            year)[-2:] + month_str + '.mat'
        daily_filename = save_path + '/' + 'da' + str(station_num) + str(
            year)[-2:] + month_str + '.mat'
        sio.savemat(hourly_filename, data_hr)
        sio.savemat(daily_filename, data_day)
        self.show_custom_message(
            "Success", "Success \n Hourly and Daily Date Saved to " +
            st.get_path(st.FD_PATH) + "\n")

        monthly_mean = np.round(np.nanmean(data_day['sealevel'])).astype(int)
        # Remove nans, replace with 9999 to match the legacy files
        nan_ind = np.argwhere(np.isnan(data_day['sealevel']))
        data_day['sealevel'][nan_ind] = 9999
        sl_round_up = np.round(data_day['sealevel']).astype(
            int)  # round up sealevel data and convert to int

        # right justify with 5 spaces
        sl_str = [str(x).rjust(5, ' ')
                  for x in sl_round_up]  # convert data to string

        daily_filename = save_path + '/' + 'da' + str(station_num) + str(
            year)[-2:] + month_str + '.dat'

        # format the date and name strings to match the legacy .dat format
        month_str = str(month).rjust(2, ' ')
        station_name = _data[primary_sensor].name.ljust(7)
        line_begin_str = f'{station_name}WOC {year}{month_str}'
        counter = 1
        try:
            with open(daily_filename, 'w') as the_file:
                for i, sl in enumerate(sl_str):
                    if i % 11 == 0:
                        line_str = line_begin_str + str(
                            counter) + " " + ''.join(sl_str[i:i + 11])
                        if counter == 3:
                            line_str = line_str.ljust(75)
                            final_str = line_str[:-5] + str(monthly_mean)
                            line_str = final_str
                        the_file.write(line_str + "\n")
                        counter += 1
        except IOError as e:
            self.show_custom_message(
                "Error", "Cannot Save to " + daily_filename + "\n" + str(e) +
                "\n Please select a different path to save to")
Ejemplo n.º 23
0
 def __init__(self, parent=None):
     super().__init__(parent)
     self.setFixedSize(20, 20)
     self.setIconSize(QtCore.QSize(12, 12))
     self.clicked.connect(self.choose_color)
     self._color = QtGui.QColor()
Ejemplo n.º 24
0
class FormWidget(QtWidgets.QWidget):
    update_buttons = QtCore.Signal()

    def __init__(self, data, comment="", parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        self.data = copy.deepcopy(data)
        self.widgets = []
        self.formlayout = QtWidgets.QFormLayout(self)
        if comment:
            self.formlayout.addRow(QtWidgets.QLabel(comment))
            self.formlayout.addRow(QtWidgets.QLabel(" "))

    def get_dialog(self):
        """Return FormDialog instance"""
        dialog = self.parent()
        while not isinstance(dialog, QtWidgets.QDialog):
            dialog = dialog.parent()
        return dialog

    def setup(self):
        for label, value in self.data:
            if label is None and value is None:
                # Separator: (None, None)
                self.formlayout.addRow(QtWidgets.QLabel(" "),
                                       QtWidgets.QLabel(" "))
                self.widgets.append(None)
                continue
            elif label is None:
                # Comment
                self.formlayout.addRow(QtWidgets.QLabel(value))
                self.widgets.append(None)
                continue
            elif tuple_to_qfont(value) is not None:
                field = FontLayout(value, self)
            elif (label.lower() not in BLACKLIST
                  and mcolors.is_color_like(value)):
                field = ColorLayout(to_qcolor(value), self)
            elif isinstance(value, str):
                field = QtWidgets.QLineEdit(value, self)
            elif isinstance(value, (list, tuple)):
                if isinstance(value, tuple):
                    value = list(value)
                # Note: get() below checks the type of value[0] in self.data so
                # it is essential that value gets modified in-place.
                # This means that the code is actually broken in the case where
                # value is a tuple, but fortunately we always pass a list...
                selindex = value.pop(0)
                field = QtWidgets.QComboBox(self)
                if isinstance(value[0], (list, tuple)):
                    keys = [key for key, _val in value]
                    value = [val for _key, val in value]
                else:
                    keys = value
                field.addItems(value)
                if selindex in value:
                    selindex = value.index(selindex)
                elif selindex in keys:
                    selindex = keys.index(selindex)
                elif not isinstance(selindex, Integral):
                    _log.warning(
                        "index '%s' is invalid (label: %s, value: %s)",
                        selindex, label, value)
                    selindex = 0
                field.setCurrentIndex(selindex)
            elif isinstance(value, bool):
                field = QtWidgets.QCheckBox(self)
                if value:
                    field.setCheckState(QtCore.Qt.Checked)
                else:
                    field.setCheckState(QtCore.Qt.Unchecked)
            elif isinstance(value, Integral):
                field = QtWidgets.QSpinBox(self)
                field.setRange(-1e9, 1e9)
                field.setValue(value)
            elif isinstance(value, Real):
                field = QtWidgets.QLineEdit(repr(value), self)
                field.setCursorPosition(0)
                field.setValidator(QtGui.QDoubleValidator(field))
                field.validator().setLocale(QtCore.QLocale("C"))
                dialog = self.get_dialog()
                dialog.register_float_field(field)
                field.textChanged.connect(lambda text: dialog.update_buttons())
            elif isinstance(value, datetime.datetime):
                field = QtWidgets.QDateTimeEdit(self)
                field.setDateTime(value)
            elif isinstance(value, datetime.date):
                field = QtWidgets.QDateEdit(self)
                field.setDate(value)
            else:
                field = QtWidgets.QLineEdit(repr(value), self)
            self.formlayout.addRow(label, field)
            self.widgets.append(field)

    def get(self):
        valuelist = []
        for index, (label, value) in enumerate(self.data):
            field = self.widgets[index]
            if label is None:
                # Separator / Comment
                continue
            elif tuple_to_qfont(value) is not None:
                value = field.get_font()
            elif isinstance(value, str) or mcolors.is_color_like(value):
                value = str(field.text())
            elif isinstance(value, (list, tuple)):
                index = int(field.currentIndex())
                if isinstance(value[0], (list, tuple)):
                    value = value[index][0]
                else:
                    value = value[index]
            elif isinstance(value, bool):
                value = field.checkState() == QtCore.Qt.Checked
            elif isinstance(value, Integral):
                value = int(field.value())
            elif isinstance(value, Real):
                value = float(str(field.text()))
            elif isinstance(value, datetime.datetime):
                value = field.dateTime().toPyDateTime()
            elif isinstance(value, datetime.date):
                value = field.date().toPyDate()
            else:
                value = eval(str(field.text()))
            valuelist.append(value)
        return valuelist
Ejemplo n.º 25
0
 def __init__(self, *args, **kwargs):
     MyMplCanvas.__init__(self, *args, **kwargs)
     timer = QtCore.QTimer(self)
     timer.timeout.connect(self.update_figure)
     timer.start(20)
Ejemplo n.º 26
0
class ColorBarWidget(QW.QWidget):
    """
    Contains the colour bar and controls to change bounds
    """

    valueChanged = QtCore.Signal(float, float)

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

        main_layout = QW.QVBoxLayout(self)

        figure = Figure()
        figure.set_frameon(False)
        self.canvas = FigureCanvas(figure)
        self.canvas.setStyleSheet("background-color:transparent;")
        self.axis = self.canvas.figure.add_axes([0, 0.05, 0.2, 0.9])

        self.upperTextBox = QW.QLineEdit()
        self.lowerTextBox = QW.QLineEdit()

        main_layout.addWidget(self.upperTextBox)
        main_layout.addWidget(self.canvas)
        main_layout.addWidget(self.lowerTextBox)

        self.upperTextBox.returnPressed.connect(self._update_bounds)
        self.lowerTextBox.returnPressed.connect(self._update_bounds)

        #: Colour bar limits
        self.bounds = [numpy.nan, numpy.nan]

        self.setFixedWidth(80)

    def setBounds(self, bounds):
        self.bounds = bounds

        self.lowerTextBox.setText("%.2e" % bounds[0])
        self.upperTextBox.setText("%.2e" % bounds[1])

    def redraw(self, plot):
        """
        Redraw the colour bar
        """
        self.axis.clear()
        if plot is not None:
            plt.colorbar(plot, cax=self.axis)

        self.canvas.draw()

    def get_plot_args(self):
        kwargs = {}
        if self.bounds[0] < 0 < self.bounds[1]:
            kwargs['vmax'] = numpy.abs(self.bounds).max()
            kwargs['vmin'] = -kwargs['vmax']
        else:
            kwargs['vmin'] = self.bounds[0]
            kwargs['vmax'] = self.bounds[1]
        return kwargs

    def _update_bounds(self):
        values = [self.lowerTextBox.text(), self.upperTextBox.text()]
        self.bounds = numpy.array(values, dtype=self.bounds.dtype)
        self.valueChanged.emit(self.bounds[0], self.bounds[1])
 def __init__(self, parent=None):
     QtWidgets.QPushButton.__init__(self, parent)
     self.setFixedSize(20, 20)
     self.setIconSize(QtCore.QSize(12, 12))
     self.clicked.connect(self.choose_color)
     self._color = QtGui.QColor()
Ejemplo n.º 28
0
class FormWidget(QtWidgets.QWidget):
    update_buttons = QtCore.Signal()

    def __init__(self, data, comment="", parent=None):
        QtWidgets.QWidget.__init__(self, parent)
        from copy import deepcopy
        self.data = deepcopy(data)
        self.widgets = []
        self.formlayout = QtWidgets.QFormLayout(self)
        if comment:
            self.formlayout.addRow(QtWidgets.QLabel(comment))
            self.formlayout.addRow(QtWidgets.QLabel(" "))
        if DEBUG:
            print("\n" + ("*" * 80))
            print("DATA:", self.data)
            print("*" * 80)
            print("COMMENT:", comment)
            print("*" * 80)

    def get_dialog(self):
        """Return FormDialog instance"""
        dialog = self.parent()
        while not isinstance(dialog, QtWidgets.QDialog):
            dialog = dialog.parent()
        return dialog

    def setup(self):
        for label, value in self.data:
            if DEBUG:
                print("value:", value)
            if label is None and value is None:
                # Separator: (None, None)
                self.formlayout.addRow(QtWidgets.QLabel(" "),
                                       QtWidgets.QLabel(" "))
                self.widgets.append(None)
                continue
            elif label is None:
                # Comment
                self.formlayout.addRow(QtWidgets.QLabel(value))
                self.widgets.append(None)
                continue
            elif tuple_to_qfont(value) is not None:
                field = FontLayout(value, self)
            elif label.lower() not in BLACKLIST and is_color_like(value):
                field = ColorLayout(to_qcolor(value), self)
            elif isinstance(value, six.string_types):
                field = QtWidgets.QLineEdit(value, self)
            elif isinstance(value, (list, tuple)):
                if isinstance(value, tuple):
                    value = list(value)
                selindex = value.pop(0)
                field = QtWidgets.QComboBox(self)
                if isinstance(value[0], (list, tuple)):
                    keys = [key for key, _val in value]
                    value = [val for _key, val in value]
                else:
                    keys = value
                field.addItems(value)
                if selindex in value:
                    selindex = value.index(selindex)
                elif selindex in keys:
                    selindex = keys.index(selindex)
                elif not isinstance(selindex, int):
                    print("Warning: '%s' index is invalid (label: "
                          "%s, value: %s)" % (selindex, label, value),
                          file=STDERR)
                    selindex = 0
                field.setCurrentIndex(selindex)
            elif isinstance(value, bool):
                field = QtWidgets.QCheckBox(self)
                if value:
                    field.setCheckState(QtCore.Qt.Checked)
                else:
                    field.setCheckState(QtCore.Qt.Unchecked)
            elif isinstance(value, float):
                field = QtWidgets.QLineEdit(repr(value), self)
                field.setCursorPosition(0)
                field.setValidator(QtGui.QDoubleValidator(field))
                field.validator().setLocale(QtCore.QLocale("C"))
                dialog = self.get_dialog()
                dialog.register_float_field(field)
                field.textChanged.connect(lambda text: dialog.update_buttons())
            elif isinstance(value, int):
                field = QtWidgets.QSpinBox(self)
                field.setRange(-1e9, 1e9)
                field.setValue(value)
            elif isinstance(value, datetime.datetime):
                field = QtWidgets.QDateTimeEdit(self)
                field.setDateTime(value)
            elif isinstance(value, datetime.date):
                field = QtWidgets.QDateEdit(self)
                field.setDate(value)
            else:
                field = QtWidgets.QLineEdit(repr(value), self)
            self.formlayout.addRow(label, field)
            self.widgets.append(field)

    def get(self):
        valuelist = []
        for index, (label, value) in enumerate(self.data):
            field = self.widgets[index]
            if label is None:
                # Separator / Comment
                continue
            elif tuple_to_qfont(value) is not None:
                value = field.get_font()
            elif isinstance(value, six.string_types) or is_color_like(value):
                value = six.text_type(field.text())
            elif isinstance(value, (list, tuple)):
                index = int(field.currentIndex())
                if isinstance(value[0], (list, tuple)):
                    value = value[index][0]
                else:
                    value = value[index]
            elif isinstance(value, bool):
                value = field.checkState() == QtCore.Qt.Checked
            elif isinstance(value, float):
                value = float(str(field.text()))
            elif isinstance(value, int):
                value = int(field.value())
            elif isinstance(value, datetime.datetime):
                value = field.dateTime().toPyDateTime()
            elif isinstance(value, datetime.date):
                value = field.date().toPyDate()
            else:
                value = eval(str(field.text()))
            valuelist.append(value)
        return valuelist
Ejemplo n.º 29
0
 class Teleporter(QtCore.QObject):
     name_doc_escape = QtCore.Signal(str, dict, object)
Ejemplo n.º 30
0
class HelpScreen(QMainWindow):
    clicked = QtCore.pyqtSignal()

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

        # Object for data persistence
        # self.settings = QtCore.QSettings('UHSLC', 'com.uhslc.qcsoft')
        # st.SETTINGS.remove("savepath")
        self.ui = parent

        # If a save path hasn't been defined, give it a home directory
        if (st.get_path(st.SAVE_KEY)):
            self.ui.lineEditPath.setPlaceholderText(st.get_path(st.SAVE_KEY))
        else:
            st.SETTINGS.setValue(st.SAVE_KEY, os.path.expanduser('~'))
            self.ui.lineEditPath.setPlaceholderText(os.path.expanduser('~'))

        self.ui.lineEditLoadPath.setPlaceholderText(st.get_path(st.LOAD_KEY))

        # If a fast delivery save path hasn't been defined, give it a home directory
        if (st.get_path(st.FD_PATH)):
            self.ui.lineEditFDPath.setPlaceholderText(st.get_path(st.FD_PATH))
        else:
            st.SETTINGS.setValue(st.FD_PATH, os.path.expanduser('~'))
            self.ui.lineEditFDPath.setPlaceholderText(os.path.expanduser('~'))

        # If a high frequency data save path hasn't been defined, give it a home directory
        if (st.get_path(st.HF_PATH)):
            self.ui.lineEditHFPath.setPlaceholderText(st.get_path(st.HF_PATH))
        else:
            st.SETTINGS.setValue(st.HF_PATH, os.path.expanduser('~'))
            self.ui.lineEditHFPath.setPlaceholderText(os.path.expanduser('~'))

        if st.get_path(st.DIN_PATH):
            self.ui.lineEdit_din.setPlaceholderText(st.get_path(st.DIN_PATH))

        saveButton = self.ui.pushButton_save_folder
        loadButton = self.ui.pushButton_load_folder
        dinSave = self.ui.pushButton_din
        FDSave = self.ui.pushButton_fd_folder
        hf_save = self.ui.pushButton_hf_data

        saveButton.clicked.connect(
            lambda: self.savePath(self.ui.lineEditPath, st.SAVE_KEY))
        loadButton.clicked.connect(
            lambda: self.savePath(self.ui.lineEditLoadPath, st.LOAD_KEY))
        dinSave.clicked.connect(
            lambda: self.saveDIN(self.ui.lineEdit_din, st.DIN_PATH))
        FDSave.clicked.connect(
            lambda: self.savePath(self.ui.lineEditFDPath, st.FD_PATH))
        hf_save.clicked.connect(
            lambda: self.savePath(self.ui.lineEditFDPath, st.HF_PATH))

    def savePath(self, lineEditObj, setStr):
        folder_name = QtWidgets.QFileDialog.getExistingDirectory(
            self, 'Select a Folder')
        if (folder_name):
            st.SETTINGS.setValue(setStr, folder_name)
            st.SETTINGS.sync()
            lineEditObj.setPlaceholderText(st.get_path(setStr))
            lineEditObj.setText("")
        else:
            pass

    def saveDIN(self, lineEditObj, setStr):
        filters = "*.din"
        if st.DIN_PATH:
            path = st.DIN_PATH
        else:
            path = os.path.expanduser('~')
        file_name = QtWidgets.QFileDialog.getOpenFileNames(
            self, 'Open File', path, filters)
        if (file_name):
            st.SETTINGS.setValue(setStr, file_name[0][0])
            st.SETTINGS.sync()
            lineEditObj.setPlaceholderText(st.get_path(setStr))
            lineEditObj.setText("")
        else:
            pass