示例#1
0
 def _color_change_hex(self):
     tmp_widget = self.sender()
     parent = tmp_widget.parent()
     name = tmp_widget.objectName()
     child = parent.findChild(QPushButton, name)
     result = tmp_widget.text()
     child.set_color(hex2rgba(result))
     pos_change = name.split('||')
     self.preferences_changed[pos_change[0]][pos_change[1]] = result
示例#2
0
    def apply_plugin_settings(self):
        """Apply configuration file's plugin settings."""
        # error no sel._starting_up atribute
        # if self._starting_up:
        #     self._starting_up = False

        # update colors from init
        self.bar_widget.canvas.bgcolor = CONF.get(self.parent().CONF_SECTION,
                                                  'bgcolor')
        self.bar_widget.buffer_rgba = hex2rgba(
            CONF.get(self.parent().CONF_SECTION, 'buffer_bar_color'))
        self.bar_widget.buffer_carray = np.array(
            [self.buffer_rgba, self.buffer_rgba])
        self.bar_widget.view_rgba = hex2rgba(
            CONF.get(self.parent().CONF_SECTION, 'view_bar_color'))
        self.bar_widget.view_carray = np.array(
            [self.view_rgba, self.view_rgba])

        # update disc thresh
        self.bar_widget.discont_thresh = CONF.get(self.parent().CONF_SECTION,
                                                  'discontinuity_limit')
示例#3
0
    def color_code(self):

        pcs = self.get_plot_containers()
        if not len(pcs):
            return

        if self.color_coding_mode == 0:
            c = hex2rgba(CONF.get(self.CONF_SECTION, 'init_line_color'))
            for pc in pcs:
                pc.line_color = c
                pc.container.item_widget.color_select.set_color(c)
            self.update_labels()
        elif self.color_coding_mode == 1:
            # Channels
             #TODO - in prefs, color.get_colormaps()
            cm = color.get_colormap(self.color_palette)
            colors = cm[np.linspace(0, 1, len(pcs))]

            for pc, c in zip(pcs, colors):
                pc.line_color = c.rgba[0]
                pc.container.item_widget.color_select.set_color(c.rgba[0])
            self.update_labels()
            # Acquire the colors based on number of channels
            # ???Introduce a limit??? If not the channels might be too simliar
        elif self.color_coding_mode == 2:
            # Groups
            ch_names = [x.orig_channel for x in pcs]
            g_names = []
            for ch_name in ch_names:
                stub = ''.join([i for i in ch_name if not i.isdigit()])
                g_names.append(stub)
            g_names = list(set(g_names))

            # TODO - in prefs, color.get_colormaps()
            cm = color.get_colormap(self.color_palette)
            colors = cm[np.linspace(0, 1, len(g_names))]

            for pc in pcs:
                stub = ''.join([i for i in pc.orig_channel if not i.isdigit()])
                c = colors[g_names.index(stub)]
                pc.line_color = c.rgba[0]
                pc.container.item_widget.color_select.set_color(c.rgba[0])

            self.update_labels()

        elif self.color_coding_mode == 3:
            # Amplitude
            pass
        else:
            pass

        self.update_signals()
示例#4
0
    def side_flash(self, color=None):

        color = hex2rgba(CONF.get(self.CONF_SECTION, 'side_flash_color'))

        if self.discont_side == 1:  # left
            pos = np.array([0., 0.1])
            color = np.vstack([color,
                               [0., 0., 0., 0.]])
        elif self.discont_side == 2:  # right
            pos = np.array([0.9, 1.0])
            color = np.vstack([[0., 0., 0., 0.],
                               color])
        else:
            pos = np.array([0., 0.])
            color = np.zeros([2, 4])

        self.disc_marker.set_data(pos, color)
        return
示例#5
0
    def add_signal_container(self, orig_channel):
        container_items = self.visible_channels.get_container_items()

        mf_scale_fatcor = None
        scale_factors = [x.pvc.scale_factor for x in container_items]
        if scale_factors:
            # In case of half/half, let python choose :-)
            mf_scale_fatcor = max(scale_factors, key=scale_factors.count)

        # Get the max span and assign to new signals
        largest_ss = self.data_map.get_active_largest_ss()

        pc = SignalContainer(orig_channel)
        ci = sm.ODS.data_map['channels'] == pc.orig_channel
        ci_entry = sm.ODS.data_map[ci]
        pc.fsamp = ci_entry['fsamp'][0]
        pc.unit = ci_entry['unit'][0]
        pc.ufact = ci_entry['ufact'][0]
        pc.nsamp = ci_entry['nsamp'][0]
        pc.start_time = ci_entry['uutc_ss'][0][0]

        antialias = CONF.get(self.CONF_SECTION, 'antialiasing')
        if antialias == 'filter':
            pc.N = int(self.canvas.central_widget.width)
        elif antialias == 'min_max':
            pc.N = None

        c = hex2rgba(CONF.get(self.CONF_SECTION, 'init_line_color'))

        pc.line_color = np.array(c)

        pc.data_array_pos = [np.where(ci)[0][0]]

        # Scale factor
        if mf_scale_fatcor:
            pc.scale_factor = mf_scale_fatcor
        # Time span
        init_tscale = CONF.get(self.CONF_SECTION, 'init_time_scale')*1e6
        if np.diff(largest_ss):
            pc.uutc_ss = largest_ss
        else:
            pc.uutc_ss = [pc.start_time, pc.start_time+init_tscale]

        return pc
示例#6
0
    def plot_disconts(self):

        dm = self.main.signal_display.data_map
        uutc = dm.get_active_largest_ss()
        view_span = np.diff(uutc)

        if not self.metadata_reload_flag:
            if self.previous_view_span == view_span:
                return

        self.previous_view_span = view_span

        if self.main.signal_display.cong_discontinuities is None:
            self.disc_bar.visible = False
            return
        else:
            self.disc_bar.visible = True

        # Big discontinuities that will trigger skipping
        cong_disconts = self.main.signal_display.cong_discontinuities
        large_disconts_idxs = np.diff(cong_disconts) > view_span
        large_disconts_idxs = large_disconts_idxs.ravel()
        large_disconts = cong_disconts[large_disconts_idxs]

        disc_color = hex2rgba(
            CONF.get(self.parent().CONF_SECTION, 'discontinuity_color'))

        pos = np.zeros(len(large_disconts) * 4)
        self.discont_colors = np.zeros([len(large_disconts) * 4, 4])
        for i, gen_discont in enumerate(large_disconts):

            pos[i * 4 + 0] = self.uutc_to_pos(gen_discont[0])
            pos[i * 4 + 1] = self.uutc_to_pos(gen_discont[0])
            pos[i * 4 + 2] = self.uutc_to_pos(gen_discont[1])
            pos[i * 4 + 3] = self.uutc_to_pos(gen_discont[1])
            self.discont_colors[i * 4 + 1] = disc_color
            self.discont_colors[i * 4 + 2] = disc_color

        # Create a big linear region
        self.disc_bar.set_data(pos, color=self.discont_colors)

        return
示例#7
0
 def change_color(self, color):
     self.pvc.line_color = hex2rgba(color.name() + 'ff')
     # TODO - move this to a signal
     self.sd.update_signals()
示例#8
0
    def __init__(self, parent):
        super(BarWidget, self).__init__(parent)

        # Widget configuration
        self.setMaximumHeight(30)
        self.setMinimumHeight(30)

        # Widget layout
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        # Covenience transcripts
        self.main = self.parent().main

        self.recording_duration = None
        self.recording_start = None
        self.recording_span = None
        self.previous_view_span = 0
        self.metadata_reload_flag = False

        self.discont_thresh = CONF.get(self.parent().CONF_SECTION,
                                       'discontinuity_limit')

        # Camera
        self.camera = NavigationCamera(self)

        # Vispy canvas
        self.canvas = scene.SceneCanvas(show=True,
                                        keys='interactive',
                                        parent=self,
                                        bgcolor=CONF.get(
                                            self.parent().CONF_SECTION,
                                            'bgcolor'))

        self.nav_view = self.canvas.central_widget.add_view(camera=self.camera)

        layout.addWidget(self.canvas.native)

        # ---- Linear regions for tracking -----

        # Linear region for buffer
        pos = np.array([0, 0], dtype=np.float32)
        self.buffer_rgba = hex2rgba(
            CONF.get(self.parent().CONF_SECTION, 'buffer_bar_color'))
        self.buffer_carray = np.array([self.buffer_rgba, self.buffer_rgba])

        self.buffer_bar = LinearRegion(pos,
                                       self.buffer_carray,
                                       parent=self.nav_view.scene)

        # Linear region for displayed signal
        pos = np.array([0, 0], dtype=np.float32)
        self.view_rgba = hex2rgba(
            CONF.get(self.parent().CONF_SECTION, 'view_bar_color'))
        self.view_carray = np.array([self.view_rgba, self.view_rgba])
        self.view_bar = LinearRegion(pos,
                                     self.view_carray,
                                     parent=self.nav_view.scene)
        self.view_bar.transform = scene.transforms.STTransform(scale=(1, 1))

        # Linear region for discontinuities
        pos = np.arange(self.nav_view.size[0])
        color = np.zeros([self.nav_view.size[0], 4])
        self.disc_bar = LinearRegion(pos, color, parent=self.nav_view.scene)
        self.disc_bar.transform = scene.transforms.STTransform(scale=(1, 1))

        # TODO - nigh and day regions

        self.discontinuities = []
        self.discont_region = []
        self.discont_colors = []

        self.setLayout(layout)
示例#9
0
    def __init__(self, parent):
        super(SignalDisplay, self).__init__(parent)

        # Covenience transcripts
        self.main = self.parent()

        # Widget behavior
        self.setAcceptDrops(True)

        # Plot variables
        self.sample_map = []
        self.plot_containers = []
        # TODO: Selected signal plot used for data shifting, colors, etc
        self.master_pc = None
        self.master_plot = None  # TODO - to be deleted
        self.curr_pc = None
        self.rect_rel_w_pos = None
        self.rect_rel_h_pos = None
        self.resize_flag = False
        self.highlight_mode = False
        self.measurement_mode = False
        self.autoscale = False

        self.disconts_processed = False

        self.data_map = DataMap()
        self.data_source = sm.ODS

        self.data_array = None

        # Widget layout
        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        # These variables are assigned in channels plugin
        self.hidden_channels = None
        self.visible_channels = None

        # Setup camera
        self.camera = SignalCamera()

        # Autoslide
        self.slide_worker_stopped = True
        # TODO: this should be i config
        self.slide_worker = TimerWorker(1)
        self.slide_worker_thread = QThread()
        self.slide_worker.moveToThread(self.slide_worker_thread)
        self.start_slide_worker.connect(self.slide_worker.run)
        self.stop_slide_worker.connect(self.slide_worker.interupt)
        self.slide_worker.time_passed.connect(self.autoslide)
        self.slide_worker_thread.start()

        # Vispy canvas
        self.canvas = scene.SceneCanvas(show=True, keys='interactive',
                                        parent=self,
                                        bgcolor=CONF.get(self.CONF_SECTION,
                                                         'bgcolor'))

        self.canvas.connect(self.on_key_press)
        self.canvas.connect(self.on_key_release)
        self.canvas.connect(self.on_mouse_move)
        self.canvas.connect(self.on_mouse_press)
        self.canvas.connect(self.on_mouse_release)
        self.canvas.connect(self.on_mouse_wheel)
        self.canvas.connect(self.on_resize)

        # Timer to let the scene redraw if key is hit
        self.event_time = time()
        self.plot_update_done = False

        # ??? Create two viewboxes - for labels and signals

        self.signal_view = self.canvas.central_widget.add_view(
                camera=self.camera)

        self.cong_discontinuities = None

        self.color_coding_mode = 0
        self.color_palette = CONF.get(self.CONF_SECTION, 'color_palette')

        self.update_cam_state()

        # ----- Initial visuals operations-----

        # TODO - Add crosshair color to CONF
        # Measurements
        ch_color = CONF.get(self.CONF_SECTION, 'init_crosshair_color')
        self.crosshair = Crosshair(parent=self.signal_view.scene,
                                   color=hex2rgba(ch_color))
        m_color = CONF.get(self.CONF_SECTION, 'init_marker_color')
        # TODO marker color
        self.marker = Markers(parent=self.signal_view.scene)
        self.xaxis = Axis(parent=self.signal_view.scene,
                          tick_direction=(0., 1.),
                          axis_width=1, tick_width=1,
                          anchors=('center', 'top'),
                          axis_color=m_color,
                          tick_color=m_color,
                          text_color=m_color)
        self.x_tick_spacing = 1000
        self.yaxis = Axis(parent=self.signal_view.scene,
                          tick_direction=(1., 0.),
                          axis_width=1, tick_width=1,
                          anchors=('left', 'center'),
                          axis_color=m_color,
                          tick_color=m_color,
                          text_color=m_color)
        self.y_tick_spacing = 100
        self.measure_line = Line(parent=self.signal_view.scene,
                                 width=3, color=m_color)
        # TODO - textbox
        self.describe_text = Text(anchor_x='left',
                                  anchor_y='bottom',
                                  parent=self.signal_view.scene,
                                  color=m_color)

        # Signal highlighting
        self.highlight_rec = Mesh(parent=self.signal_view.scene,
                                  color=np.array([0., 0., 0., 0.]),
                                  mode='triangle_fan')

        # Grid
        self.grid = None

        # Discontinuity
        self.disc_marker = LinearRegion(np.array([0, 0]),
                                        np.array([[0., 0., 0., 0.],
                                                 [0., 0., 0., 0.]]),
                                        parent=self.signal_view.scene)

        self.signal_label_dict = {}
        # Main signal visal with labels
        w = CONF.get(self.CONF_SECTION, 'init_line_width')
        self.signal_visual = Multiline(width=w,
                                       parent=self.signal_view.scene)
        self.label_visual = Text(anchor_x='left',
                                 anchor_y='top',
                                 parent=self.signal_view.scene)

        # TODO - one set of x and y axes for measurements

        # ----- Tool bar -----
        btn_layout = QHBoxLayout()
        for btn in self.setup_buttons():
            if btn is None:
                continue
            btn.setAutoRaise(True)
            btn.setIconSize(QSize(20, 20))
            btn_layout.addWidget(btn)
#        if options_button:
#            btn_layout.addStretch()
#            btn_layout.addWidget(options_button, Qt.AlignRight)

        # TODO - this is temporary - solve the rendering in different thread
        select_mode = QComboBox(self)
        select_mode.insertItems(0, ['Browse', 'Research'])
        antialias = CONF.get(self.CONF_SECTION, 'antialiasing')
        if antialias == 'filter':
            select_mode.setCurrentIndex(0)
        elif antialias == 'min_max':
            select_mode.setCurrentIndex(1)

        select_mode.currentIndexChanged.connect(self.switch_display_mode)
        btn_layout.addWidget(select_mode)

        # Color coding
        color_code = QComboBox(self)
        color_code.insertItems(0, ['None', 'Channel', 'Group', 'Amplitude'])
        color_code.currentIndexChanged.connect(self.switch_cc_mode)
        btn_layout.addWidget(color_code)

        # Metadata reload button
        btn_layout.setAlignment(Qt.AlignLeft)
        layout = create_plugin_layout(btn_layout)

        # ----- Set layout -----
        layout.addWidget(self.canvas.native)

        # Set the whole layout
        self.setLayout(layout)

        # Connect signals
        self.main.sig_file_opened.connect(self.initialize_data_map)
        self.main.metadata_reloaded.connect(self.create_conglomerate_disconts)
        self.plots_changed.connect(self.set_plot_update)
        self.plots_changed.connect(self.subsample)
        self.plots_changed.connect(self.rescale_grid)
        self.input_recieved.connect(self.set_highlight_mode)
        self.input_recieved.connect(self.show_measure_line)
        self.canvas_resized.connect(self.update_subsample)
示例#10
0
    def _build_option_stack(self):
        '''
            create editable options with visible current values,
             editation type is define by the option possible values
        :return:
        '''

        # temporary prototype
        self.stack_layout_dict = {}
        self.options = {}
        # create stack with all editable sections
        self.stack_layout_dict = {
            section: QFormLayout()
            for section in self.sections
        }

        for section in self.sections:
            options = CONF.options(section=section)
            if 'enable' in options:
                options.remove('enable')

            self.options[section] = options
            for option in options:
                option_val = CONF.get(section, option)

                name_reference = section + '||' + option
                # boolean (true/False) setup
                if isinstance(option_val, bool):
                    tmp_widget = QCheckBox('On/Off')
                    tmp_widget.setObjectName(name_reference)
                    if option_val:
                        tmp_widget.setChecked(True)
                    else:
                        tmp_widget.setChecked(False)
                    tmp_widget.stateChanged.connect(self._boolean_state)

                # one string or color setup
                if isinstance(option_val, str):
                    # TODO take care of hexa strings withou alpha channel
                    if (len(option_val) == 9) & (option_val.startswith('#')):
                        tmp_widget = QHBoxLayout()
                        tmp_val = PreferenceLineedit(option_val,
                                                     name_reference, 9)
                        tmp_col = ColorButton(hex2rgba(option_val))
                        tmp_col.setObjectName(name_reference)
                        tmp_col.color_changed.connect(self._color_change)
                        tmp_val.editingFinished.connect(self._color_change_hex)
                        tmp_widget.addWidget(tmp_val)
                        tmp_widget.addWidget(tmp_col)
                    else:
                        tmp_widget = PreferenceLineedit(option_val,
                                                        name_reference,
                                                        max_len=100)
                        tmp_widget.editingFinished.connect(self._line_edit)

                # configuration of list (multiple selection)
                if (isinstance(option_val, tuple)
                        | isinstance(option_val, list)):
                    tmp_widget = QHBoxLayout()

                    for i, val in enumerate(option_val):
                        name_loc = name_reference + '||{}'.format(i)
                        if isinstance(val, int):
                            validator = QIntValidator()
                        else:
                            validator = None
                        tmp_val = PreferenceLineedit(str(val),
                                                     name_loc,
                                                     validator=validator)
                        tmp_val.editingFinished.connect(self._line_edit_multi)
                        tmp_widget.addWidget(tmp_val)

                    self.preferences_changed[section][option] = \
                        list(option_val)

                # configuration of single number
                if isinstance(option_val, int) & ~isinstance(option_val, bool):
                    tmp_widget = PreferenceLineedit(str(option_val),
                                                    name_reference,
                                                    max_len=4,
                                                    validator=QIntValidator())
                    tmp_widget.editingFinished.connect(self._line_edit)

                if option.split('/')[0] in self.sections:
                    _, option = option.split('/')

                # Create nice option name
                first_letter = option[0]
                option = option.replace(first_letter, first_letter.upper(), 1)
                option = option.replace('_', ' ')
                self.stack_layout_dict[section].addRow(str(option), tmp_widget)

        # build whole stack
        for section in self.sections:
            tmp = QWidget()
            tmp.setLayout(self.stack_layout_dict[section])
            self.options_editor.addWidget(tmp)