def _init_edit_bt(self, flag_index):
        edit_flag_bt = Button(name='edit_flag_bt_{}'.format(flag_index),
                              label='',
                              width=30,
                              tags=['edit_flag_bt'],
                              css_classes=['edit_flag_bt'])

        def update_flag_value_edit_bt(flag_index=flag_index):
            self.update_flag_value(flag_value=flag_index,
                                   flag_to_update=None,
                                   row_indexes=self.env.selection)

        edit_flag_bt.on_click(update_flag_value_edit_bt)
        return edit_flag_bt
Beispiel #2
0
# # SELECT menu GUI
# selectoptions = ["Postive tested on Covid-19 virus", "Negative tested on Covid-19 virus", "Show both"]
# resultSelect = Select(title="What to show", options=selectoptions)

# TOOL BUTTON CALLBACKS -----------------------------------------------------------------------------------------------
# Test button GUI
lab = "Click me!"
but = Button(label=lab)


def callback_button1(
):  # simple test callback -> changes lable on button and reports a click to the console
    print("button was clicked!")


but.on_click(callback_button1)  # links the clickedcode to the button

# [END] TOOL BUTTON CALLBACKS -----------------------------------------------------------------------------------------

# general webpage & plots
title = Div(
    text=
    "<b>Visualisation tool of patients tested for Covid-19 of the Hospital Israelita Albert Einstein, at São Paulo, Brazil</b>",
    style={
        'font-size': '200%',
        'color': 'black'
    },
    width=800)

text = [title]
# gridplot
Beispiel #3
0
def modify_doc(doc):
    """Create and modify the bokeh document. Later run by the tornado
    server."""
    city_1_title = 'Search for the first city'
    city_2_title = 'Search for the second city'
    # Adding selectors, essentially the controls, to the app.
    city_1_select = AutocompleteInput(value=city_1,
                                      completions=cities_list,
                                      min_characters=3,
                                      title=city_1_title)
    city_2_select = AutocompleteInput(value=city_2,
                                      completions=cities_list,
                                      min_characters=3,
                                      title=city_2_title)
    variable_select = Select(value=variable,
                             title='Variable',
                             options=list(variable_dict.keys()))
    method_select = Select(value=method, title='Period', options=methods_list)
    # And a button to toggle display of trend.
    display_trend = Button(label='Display trends',
                           button_type='success',
                           width=50)

    # Initial plot for startup of app.
    plot = create_plot(source_1, source_2, title, variable, trend)

    def trend_update():
        """Custom callback in the event of button changing state."""
        # Make use of global variables.
        global trend, source_1, source_2, title, variable
        # Switch state of trend(bool)
        trend = not trend
        if trend:
            display_trend.label = 'Hide trends'
        else:
            display_trend.label = 'Show trends'
        layout.children[1] = create_plot(source_1, source_2, title, variable,
                                         trend)

    def update_plot(attrname, old, new):
        """This is called when any of the widgets are changed, updates the
        plot"""
        # Need to access the value of the global variables.
        global city_1, city_2, source_1, source_2, title, variable, method
        # Get the new value of cities and variable.
        city_1 = city_1_select.value
        city_2 = city_2_select.value
        variable = variable_select.value
        method = method_select.value
        # Set new title of plot based on new variables.
        title = (method + ' ' + variable.lower() + ' data from ' + city_1 +
                 ' and ' + city_2 + '.')
        # Get new source data based on the new parameters.
        source_1 = get_data(city_1, variable, method)
        source_2 = get_data(city_2, variable, method)
        # This is what is actually updating the plot, the plot is the second
        # child of the layout.
        layout.children[1] = create_plot(source_1, source_2, title, variable,
                                         trend)

    # Looping through all the selectors to detect changes.
    control_list = [
        city_1_select, city_2_select, variable_select, method_select
    ]
    for w in control_list:
        w.on_change('value', update_plot)
    # Need to treat button differently.
    display_trend.on_click(trend_update)
    # Title displayed on page.
    text = ('<font size="5">Welcome to the climtrend visualization tool.'
            ' Compare the climate in two cities by using the controls'
            ' below.</font>')
    p = Div(text=text, width=300, height=200)
    controls = column(p, city_1_select, city_2_select, variable_select,
                      method_select, display_trend)
    # Add the controls of the app and the plot to the first row of the layout.
    layout = row(controls, plot)
    doc.add_root(layout)
    doc.title = 'ClimTrend'
Beispiel #4
0
class BokehDataTable(Environment):
    ''' DataTable Controls and events '''
    env = Environment

    def __init__(self, **kwargs):
        lg.info('-- INIT BOKEH DATATABLE')
        self.env.bk_table = self

        self.s = 0  # current sample
        self.ns = 0  # number of samples
        self.table_df = None
        self.update_params()

        self.flag_formatter = None
        self.value_formatter = None
        self.param_formatter = None
        self.env.dt_manual_update = True

        self._init_templates()
        self._init_datatable()
        self._init_sample_buttons()

    def _init_templates(self):
        switch_case = ''
        for c, v in CIRCLE_COLORS.items():
            switch_case += "case '{}': return('{}'); break;\n".format(
                str(c), v)
        flag_template = """
            <div style="font-weight: bold; color: <%=
                (function colorfromint() {{
                    switch (value) {{
                        {}
                        default: return('black');
                    }}
                }}()) %>; " ><%= value %>
            </div>
        """.format(switch_case)
        self.flag_formatter = HTMLTemplateFormatter(
            template=flag_template
        )  # TODO: to show float numbers NumberFormatter should be used

        value_template = """
            <div style="font-weight: <%=
                (function colorfromint() {
                    switch (value) {
                        case 'NaN': return('bold'); break
                        default: return('normal');
                    }
                }()) %>; color: <%=
                (function colorfromint() {
                    switch (value) {
                        case 'NaN': return('red'); break
                        default: return('black');
                    }
                }()) %>; " ><%= value %>
            </div>
        """
        # lg.info('>> TEMPLATE: {}'.format(value_template))
        self.value_formatter = HTMLTemplateFormatter(template=value_template)

        param_template = """
            <div style="font-weight: bold;"><%= value %></div>
        """
        # lg.info('>> TEMPLATE: {}'.format(param_template))
        self.param_formatter = HTMLTemplateFormatter(template=param_template)

    def _init_datatable(self):
        columns = [
            TableColumn(
                width=80,
                field="parameter",
                title="Parameter",
                formatter=self.param_formatter,
                editor=CellEditor()  # non editable
            ),
            TableColumn(width=50,
                        field="value",
                        title="Value",
                        formatter=self.value_formatter,
                        editor=CellEditor()),
            TableColumn(width=40,
                        field="flag",
                        title="Flag",
                        formatter=self.flag_formatter,
                        editor=StringEditor()),
        ]
        self.table_df = pd.DataFrame(
            dict(
                parameter=self.params,
                value=[''] * len(self.params),
                flag=[''] * len(self.params),
            ))
        table_cds = ColumnDataSource(self.table_df)
        self.data_table = DataTable(
            width=190,
            height=125,
            source=table_cds,
            columns=columns,
            editable=
            True,  # TODO: check if there is a better way than https://stackoverflow.com/a/49424647/4891717
            fit_columns=False,  # avoids horizontal scrolls bar
            index_position=None,  # hides index column
            selectable=True,  # this is needed to edit cells
            reorderable=
            False,  # NOTE: this needs jquery ui, but it is not needed
            scroll_to_selection=False,  # not needed
            sortable=False,  # not needed
        )

        self.data_table.source.on_change('data', self.on_change_data_source)

    def _init_sample_buttons(self):
        lg.info('-- SET SAMPLE BUTTONS')

        def next_sample():
            lg.info('>> NEXT SAMPLE')
            if self.s < self.ns:
                self.env.doc.hold('collect')
                self.s += 1
                self.sample_div.text = ' {} / {}'.format(self.s, self.ns)
                self.env.cur_nearby_prof = None  # to reset the extra stt profile to plot
                self.env.dt_next_sample = True
                self._update_dt_sample()
                self.env.doc.unhold()

        def previous_sample():
            lg.info('>> PREVIOUS SAMPLE')
            if self.s > 1:
                self.env.doc.hold('collect')
                self.s -= 1
                self.sample_div.text = ' {} / {}'.format(self.s, self.ns)
                self.env.cur_nearby_prof = None
                self.env.dt_previous_sample = True
                self._update_dt_sample()
                self.env.doc.unhold()

        self.next_bt = Button(label=">", button_type="success", width=30)
        self.sample_div = Div(
            text='0 / 0',
            width=100,
            height=30,
            css_classes=['sample_div'],
        )
        self.previous_bt = Button(label="<", button_type="success", width=30)
        self.next_bt.on_click(next_sample)
        self.previous_bt.on_click(previous_sample)

    def update_params(self):
        self.params = self.env.cruise_data.get_cols_by_type(['param'])
        self.params.insert(0, STNNBR)

    def update_dt_source(self):
        ''' Updates the datatable source depending on the selected samples
        '''
        lg.info('-- UPDATE DATATABLE SOURCE')
        self.update_params()
        df = self.env.cds_df.iloc[self.env.selection]
        df_filter = self.env.cruise_data.get_cols_by_type(
            ['param', 'param_flag', 'qc_param_flag'])
        df_filter.insert(0, STNNBR)
        df = df.filter(df_filter)
        self.table_df = df  # TODO: check if it has the same order as the selection)
        self.ns = len(self.env.selection)
        self.s = 1 if self.env.selection != [] else 0
        self.sample_div.text = ' {} / {}'.format(self.s, self.ns)
        self._update_dt_sample()

    def _update_dt_sample(self):
        ''' Updates the datatable with the data of the self.s
        '''
        lg.info('-- UPDATE DT SAMPLE')
        flag_values = []
        param_values = []
        if self.s != 0:
            self.env.sample_to_select = self.env.selection[self.s - 1]

            for p in self.params:
                v = self.table_df.loc[self.env.sample_to_select, p]
                # lg.info('>> V: {} | TYPE: {}'.format(v, type(v)))
                if not isinstance(v, str):
                    if np.isnan(v):
                        v = 'NaN'
                    else:
                        v = str(v)
                param_values.append(v)

                fp = p + FLAG_END
                if fp in self.table_df.columns:
                    fv = self.table_df.loc[self.env.sample_to_select, fp]
                    if not isinstance(fv, str):
                        if np.isnan(fv):
                            fv = 'NaN'
                        else:
                            fv = str(fv)
                    flag_values.append(fv)
                else:
                    flag_values.append('-')
        else:
            self.env.sample_to_select = None
            param_values = [''] * len(self.params)
            flag_values = [''] * len(self.params)
        new_vals_dict = {
            'parameter': self.params,
            'value': param_values,
            'flag': flag_values
        }
        lg.info('>> NEW VALS DICT: \n\n{}'.format(new_vals_dict))
        lg.info('>> LENS (PARAMETER, VALUE, FLAG) = ({}, {}, {})'.format(
            len(self.params), len(param_values), len(flag_values)))

        lg.info('>> DT_MANUAL_UPDATE IN _UPDATE_DT_SAMPLE: {}'.format(
            self.env.dt_manual_update))
        # self.env.dt_manual_update = False  # just in case
        self.data_table.source.data = new_vals_dict
        # self.env.dt_manual_update = True

        self.env.bk_sources.update_prof_sources(force_selection=True)

    def on_change_data_source(self, attr, old, new):
        indices = list(range(self.table_df.size))
        # changes = [(param_name, index, old_value, new_value)]
        changes = [(self.params[i], i, j, k)
                   for i, j, k in zip(indices, old['flag'], new['flag'])
                   if j != k]

        # lg.info('>> CHANGES: {}'.format(changes))
        # lg.info('>> SELECTION = {} | DF_MANUAL_UPDATE = {}'.format(self.env.selection, self.env.dt_manual_update))
        # lg.info('>> DT_NEXT_SAMPLE = {} | DF_PREVIOUS_SAMPLE = {}'.format(self.env.dt_next_sample, self.env.dt_previous_sample))

        error = False

        # This happens when the DataFrame is empty (Reset button or the initial state)
        if self.env.selection == [] and self.env.dt_manual_update:
            error = True

        if self.env.selection != [] and self.env.dt_manual_update and changes != []:
            # if len(changes) == 1:  # NOTE: if it is a manual update the length should be 1
            #       but I am getting size 1 when the whole DataTable CDS is updated
            #       I do not why is this happening
            if not (self.env.dt_next_sample or self.env.dt_previous_sample):
                for t in changes:
                    if t[2] == '-':
                        error = True
                        self.env.bk_bridge.error_js(
                            'This parameter does not have any flag column associated.'
                        )
                    else:
                        try:
                            new_flag_val = int(t[3])
                        except:
                            error = True
                            self.env.bk_bridge.error_js(
                                'The value should be an integer.')
                        else:
                            if new_flag_val not in self.env.bk_flags.all_flags_list:
                                error = True
                                self.env.bk_bridge.error_js(
                                    'The cell value should be a valid flag value.'
                                )
                            else:
                                self.env.dt_manual_update = False
                                self.env.bk_flags.update_flag_value(
                                    flag_to_update=t[0] + FLAG_END,
                                    flag_value=new_flag_val,
                                    row_indexes=[self.env.sample_to_select])
                                self.env.dt_manual_update = True
            else:
                self.env.dt_next_sample = False
                self.env.dt_previous_sample = False

        if error:
            self.rollback(changes)

    def rollback(self, changes):
        lg.info('-- DATATABLE ROLLBACK')
        if self.env.selection != []:
            for t in changes:
                patch = {
                    'flag': [
                        (t[1], t[2]),
                    ]
                }  # rollback to the old value
                self.env.dt_manual_update = False
                self.data_table.source.patch(patch)
                self.env.dt_manual_update = True
        else:
            if changes != []:
                for t in changes:
                    patch = {
                        'flag': [
                            (t[1], ''),
                        ]
                    }  # rollback to the initial value
                    self.env.dt_manual_update = False
                    self.data_table.source.patch(patch)
                    self.env.dt_manual_update = True
            else:
                self.env.dt_manual_update = False
                self.table_df = pd.DataFrame(
                    dict(
                        parameter=self.params,  # remove flags from here
                        value=[''] * len(self.params),
                        flag=[''] * len(self.params),
                    ))
                self.data_table.source.data = self.table_df.to_dict('list')
                self.env.dt_manual_update = True
class BokehEvents(Environment):
    ''' Controls and events. The widgets and buttons are created here
        Also some other events and triggers such as update points selections
    '''
    env = Environment

    def __init__(self, **kwargs):
        lg.info('-- INIT BOKEH EVENTS')
        self.env.bk_events = self

        self.env.source.selected.on_change('indices', self._update_selection)
        self.env.wmts_map_source.selected.on_change('indices',
                                                    self._update_map_selection)

        self._init_cb_prof_invsbl_points()
        self._init_profile_nav()
        self._init_nearby_prof_cb()
        self._init_tabs()

    def _update_selection(self, attr, old, new_indices):
        ''' This is run when some elements are selected:
                @attr: 'selected'
                @old: >> does not work well yet with the new Selection class?
                @new: >> new_indices store the new selection indices list
        '''
        lg.info('-- UPDATE SELECTION: {}'.format(new_indices))
        self.env.dt_manual_update = False
        if self.env.selection != new_indices and new_indices != []:
            self.env.selection = new_indices
            self.env.sample_to_select = None  # this is reselected later on `_upd_prof_srcs`
            self.env.stt_to_select = None
            self.env.cur_nearby_prof = None
            self.env.cur_partial_stt_selection = []

            self._update_map_selection_prog(new_indices)
            self.env.bk_table.update_dt_source(
            )  # prof sources is updated inside
            self.env.reset_selection = False
        elif self.env.selection != [] and new_indices == []:
            # NOTE: Keeps the selection when the user click on a space without any sample
            if self.env.reset_selection:
                lg.info('>> RESET SELECTION')
                self.env.selection = []
                self.env.sample_to_select = None  # this is reselected later on `_upd_prof_srcs`
                self.env.stt_to_select = None
                self.env.cur_nearby_prof = None
                self.env.cur_partial_stt_selection = []
                self.env.reset_selection = False
            else:
                lg.info('>> KEEP SELECTION')
                self.env.source.selected.indices = self.env.selection  # keep selection
        self.env.dt_manual_update = True  # reactivate the manual update of the datatable

    def _update_map_selection(self, attr, old, new_indices):
        lg.info('-- UPDATE MAP SELECTION')
        if self.env.map_selection != new_indices and new_indices != []:  # this can be triggered by the user, and programmatically??
            lg.info('>> NEW MAP SELECTION: {}'.format(new_indices))
            self.env.map_selection = new_indices

            # triggers the _update_selection
            # lg.info('>> MAP SOURCE: {}'.format(self.env.wmts_map_source.data))
            selected_stts = list(
                self.env.wmts_map_source.data[STNNBR][new_indices])
            # self.env.cur_partial_stt_selection = selected_stts

            # TODO: how to get all the indices of the current selected stations?? by self.env.cds_df is updated??
            sel_inds = list(self.env.cds_df[self.env.cds_df[STNNBR].isin(
                selected_stts)].index)

            self.env.source.selected.indices = sel_inds
            self._update_selection(
                attr='selected',
                old=None,
                new_indices=self.env.source.selected.
                indices  # I need to trigger this manually as well
            )

        elif self.env.map_selection != [] and new_indices == []:
            if self.env.reset_selection:
                lg.info('>> RESET MAP SELECTION')
                self.env.map_selection = []
                self.env.wmts_map_source.selected.indices = []
            else:
                lg.info('>> KEEP MAP SELECTION')
                self.env.wmts_map_source.selected.indices = self.env.map_selection

    def _update_map_selection_prog(self, new_indices):
        ''' Updates the map selection programmatically with the stations of the selected samples
                @new_indices: list of indices of the selected samples (cds_df)
        '''
        lg.info('-- UPDATE MAP SELECTION PROGRAMMATICALLY')
        if self.env.map_selection != new_indices and new_indices != []:  # this can be triggered by the user, and programmatically??
            stt_to_select = list(self.env.cds_df.loc[new_indices, STNNBR])
            indices_to_select = list(self.env.wmts_map_df[
                self.env.wmts_map_df[STNNBR].isin(stt_to_select)].index)
            self.env.map_selection = indices_to_select
            self.env.wmts_map_source.selected.indices = indices_to_select
        elif self.env.map_selection != [] and new_indices == []:
            if self.env.reset_selection:
                lg.info('>> RESET MAP SELECTION')
                self.env.map_selection = []
                self.env.wmts_map_source.selected.indices = []

    def _init_cb_prof_invsbl_points(self):
        ''' Plot the profiles with the visible points or with the invisible as well
        '''
        def on_click_cb_prof_invsbl_points(active_list):
            if active_list == [0]:
                self.env.plot_prof_invsbl_points = True
            else:
                self.env.plot_prof_invsbl_points = False
            self.env.bk_sources._upd_prof_srcs()

        self.cb_prof_invsbl_points = CheckboxGroup(
            width=200,
            height=10,
            labels=['Fixed profiles'],  # Plot invisible points on profiles
            active=[],
            css_classes=['fixed_profiles_cb', 'bokeh_hidden'])
        self.cb_prof_invsbl_points.on_click(on_click_cb_prof_invsbl_points)

    def _init_profile_nav(self):
        def next_profile():
            if self.nearby_prof_cb:
                lg.info('-- NEXT PROFILE')
                s = self.env.stations
                next_pos = s.index(self.env.cur_nearby_prof) + 1
                if next_pos < len(self.env.stations):
                    if s[next_pos] == self.env.stt_to_select:
                        next_pos = next_pos + 1
                if next_pos < len(self.env.stations):
                    self.env.cur_nearby_prof = s[next_pos]
                    self.env.bk_sources._upd_prof_srcs(force_selection=True)
                    self.nearby_prof_div.text = str(
                        int(self.env.cur_nearby_prof))

                    # adjust disabled buttons
                    if next_pos + 1 == len(self.env.stations):
                        self.next_prof_bt.disabled = True
                    self.previous_prof_bt.disabled = False

        def previous_profile():
            lg.info('-- PREVIOUS PROFILE')
            if self.nearby_prof_cb:
                s = self.env.stations
                previous_pos = s.index(self.env.cur_nearby_prof) - 1
                if previous_pos >= 0:
                    if s[previous_pos] == self.env.stt_to_select:
                        previous_pos = previous_pos - 1
                if previous_pos >= 0:
                    self.env.cur_nearby_prof = s[previous_pos]
                    self.env.bk_sources._upd_prof_srcs(force_selection=True)
                    self.nearby_prof_div.text = str(
                        int(self.env.cur_nearby_prof))

                    # adjust disabled buttons
                    if previous_pos == 0:
                        self.previous_prof_bt.disabled = True
                    self.next_prof_bt.disabled = False

        self.next_prof_bt = Button(
            width=30,
            disabled=True,
            label=">",
            button_type="success",
        )
        self.nearby_prof_div = Div(
            width=100,
            height=30,
            text='None',
            css_classes=['cur_stt'],
        )
        self.previous_prof_bt = Button(
            width=30,
            disabled=True,
            label="<",
            button_type="success",
        )
        self.next_prof_bt.on_click(next_profile)
        self.previous_prof_bt.on_click(previous_profile)

    def _init_nearby_prof_cb(self):
        def on_click_nearby_prof(active_list):
            lg.info('-- ONCLICK NEARBY PROF')
            lg.info('>> SELECTED STT: {}'.format(self.env.stt_to_select))
            if 0 in active_list:
                self.env.plot_nearby_prof = True
                self.set_cur_nearby_prof()
                self.env.bk_sources._upd_prof_srcs(force_selection=True)
            else:
                self.env.plot_nearby_prof = False
                self.next_prof_bt.disabled = True
                self.previous_prof_bt.disabled = True
                self.env.cur_nearby_prof = None
                self.nearby_prof_div.text = 'None'
                self.env.bk_sources._upd_prof_srcs(force_selection=True)

        self.nearby_prof_cb = CheckboxGroup(
            width=200,
            height=20,
            labels=['Show nearby station'],
            active=[],
            css_classes=['show_nearby_station_cb', 'bokeh_hidden'])
        self.nearby_prof_cb.on_click(on_click_nearby_prof)

    def set_cur_nearby_prof(self):
        lg.info('-- SET CUR NEARBY PROF')
        self.next_prof_bt.disabled = False  # TODO: if the database has only one station?
        self.previous_prof_bt.disabled = False

        # NOTE: get the default extra station: the next one if exists
        #       if not, the previous one
        if self.env.stt_to_select is not None:
            next_pos = self.env.stations.index(self.env.stt_to_select) + 1
            if next_pos < len(self.env.stations):
                self.env.cur_nearby_prof = self.env.stations[next_pos]
                self.nearby_prof_div.text = str(int(self.env.cur_nearby_prof))
            else:
                previous_pos = self.env.stations.index(
                    self.env.stt_to_select) - 1
                if previous_pos >= 0:
                    self.env.cur_nearby_prof = self.env.stations[previous_pos]
                    self.nearby_prof_div.text = str(
                        int(self.env.cur_nearby_prof))

    def _init_tabs(self):
        lg.info('-- INIT TABS')
        panel_list = []
        # lg.info('>> self.env.TABS_FLAGS_PLOTS: {}'.format(self.env.tabs_flags_plots))
        SORT_TABS = False
        if SORT_TABS:
            ordered_tab_list = sorted(self.env.tabs_flags_plots)
        else:
            ordered_tab_list = list(self.env.tabs_flags_plots.keys())
        self.env.cur_tab = ordered_tab_list[
            0]  # self.env.cur_tab initialization
        self.env.cur_flag = self.env.cur_tab + FLAG_END  # self.env.cur_tab initialization

        ly_settings = self.env.f_handler.get_layout_settings()
        for tab in ordered_tab_list:
            indices = self.env.tabs_flags_plots[tab]['plots']
            children = [
                x.plot for x in self.env.bk_plots if x.n_plot in indices
            ]
            # lg.info('>> CHILDREN: {}'.format(children))
            gp = gridplot(
                children=children,
                ncols=ly_settings['ncols'],
                plot_width=ly_settings[
                    'plot_width'],  # if 350 then the points are blurred
                plot_height=ly_settings['plot_height'],
                toolbar_location=
                'left',  # TODO: separate the toolbars to set some tools active by default,
                #       like this the hover icon can be shown as well
            )
            name = 'panel_{}'.format(tab.lower())
            panel_list.append(
                Panel(
                    name='panel_{}'.format(tab.lower()),
                    child=gp,
                    title=tab,
                ))  # TODO: closable=True

        lg.info('>> TABS WIDGET: {}'.format(self.env.tabs_widget))
        if self.env.tabs_widget is None:
            self.env.tabs_widget = Tabs(
                name='tabs_widget',
                tabs=panel_list,
                width=1250,
            )
        else:
            self.env.tabs_widget.tabs.clear()
            self.env.tabs_widget.tabs = panel_list

        def update_active_tab(attr, old, new):
            lg.info('-- UPDATE ACTIVE TAB | OLD: {} | NEW: {}'.format(
                old, new))
            self.env.cur_tab = self.env.tabs_widget.tabs[new].title
            lg.info('>> CUR TAB: {}'.format(self.env.cur_tab))
            flag = self.env.tabs_flags_plots[self.env.cur_tab]['flag']
            if self.env.flagger_select.value != flag:
                self.env.tab_change = True
                self.env.flagger_select.value = flag  # if they concide the update of the select is not triggered

        self.env.tabs_widget.on_change('active', update_active_tab)
Beispiel #6
0
labeling_input = widgetbox(labeling_x_mu, labeling_y_mu, labeling_x_var,
                           labeling_y_var, labeling_thr)
inputs = [hijacking_input, good_user_input, labeling_input]

# Plot the ROC curve

roc_source = ColumnDataSource(data=dict(x=[], y=[]))


def train_and_evaluate():
    global hijackers, good_users, labeling, roc_source
    fpr, tpr = calculate_roc(hijackers, good_users, labeling)
    roc_source.data = dict(x=fpr, y=tpr)


train_and_evaluate()
roc = figure(title='RoC', x_axis_label='False positive rate',
             y_axis_label='True Positive Rate', x_range=(0, 1), y_range=(0, 1),
             width=1000)
roc.line([0, 1], [0, 1], color='navy', line_width=1.0, line_dash='dashed')
roc.line(x='x', y='y', source=roc_source, color='darkorange', line_width=1.0,
         line_dash='dashed')

button = Button(label='Calculate ROC')
button.on_click(train_and_evaluate)

# Add the simulation and ROC curve to DOM.

curdoc().add_root(column(row(space_plot, *inputs), row(roc, widgetbox(button))))
curdoc().title = 'Recall vs accuracy trade-off'
class BokehFlags(Environment):
    ''' Class to manage Flag Controls and its Events
    '''
    env = Environment

    @property
    def all_flags_list(self):
        # NOTE: current available flags on the CDS plus flags with 0 elements
        return sorted([i for i, fg_str in self.env.all_flags.items()])

        # TODO: If you want to assign a new flag value out of this list,
        #       a mechanism to add a new value should be added

    def __init__(self, **kwargs):
        self.env.bk_flags = self
        self.env.visible_flags = self.all_flags_list
        self.all_flags_vb_bt = None
        self.flags_control_header_row = None
        self.flag_rows = []

        self._init_flagger_select()
        self._init_flags_control_header()
        self._init_flags_control_table()

    def _init_flagger_select(self):
        lg.info('-- INIT FLAGGER SELECT')
        options = self.env.cruise_data.get_cols_by_type(
            ['param_flag', 'qc_param_flag'])
        options = sorted(options)
        self.env.flagger_select = Select(
            value=self.env.cur_flag,
            options=options,
            css_classes=['flagger_select'],
        )

        def update_select_flag_value(attr, old, new):
            lg.info('-- SELECT VALUE | OLD: {} | NEW: {}'.format(old, new))
            self.env.cur_flag = new
            if self.env.tab_change:
                self.env.tab_change = False
            else:
                lg.info('-- SELECT CHANGE')
                self.env.bk_bridge.call_js({
                    'object': 'tools',
                    'function': 'show_wait_cursor',
                })
                self.env.tabs_flags_plots[self.env.cur_tab]['flag'] = new

                # TODO: replot of all the colors of the tab
                #       some of the glyphs could be invisible
                #       only an indices update is needed

                cur_plot_list = self.env.tabs_flags_plots[
                    self.env.cur_tab]['plots']
                self.env.doc.hold('collect')
                self.env.bk_plots_handler.replot_color_circles(
                    only_cur_tab=True)
                self.env.bk_sources._upd_prof_srcs(
                )  # TODO: keep the selection as it is >> keep_selection = True
                #       I do this here because some point could be invisible for
                #       other tab
                self.env.doc.unhold()
                self.env.bk_bridge.call_js({
                    'object': 'tools',
                    'function': 'show_default_cursor',
                })

        self.env.flagger_select.on_change('value', update_select_flag_value)

    def _init_flags_control_header(self):
        lg.info('-- FLAGS CONTROL HEADER')
        self.all_flags_vb_bt = Button(
            name='all_flags_bt',
            label='',
            width=30,
            css_classes=['eye_bt'],
        )

        def all_flags_vb_bt_callback():
            lg.info('-- ALL FLAGS VISIBLE CALLBACK')
            self.env.bk_bridge.call_js({
                'object': 'tools',
                'function': 'show_wait_cursor',
            })
            all_flags_bt = self.env.doc.select_one(dict(name='all_flags_bt'))
            eye_slash_bt = True if 'eye_slash_bt' in all_flags_bt.css_classes else False
            if eye_slash_bt:
                self.env.doc.set_select(selector=dict(tags=['vb_bt']),
                                        updates=dict(css_classes=['eye_bt']))
            else:
                self.env.doc.set_select(
                    selector=dict(tags=['vb_bt']),
                    updates=dict(css_classes=['eye_slash_bt']))

            new_visible_flags = []
            if 'eye_bt' in all_flags_bt.css_classes:
                all_flags_bt.css_classes = ['eye_slash_bt']
            else:
                new_visible_flags = self.all_flags_list
                all_flags_bt.css_classes = ['eye_bt']
            lg.info('>> NEW VISIBLE FLAGS: {}'.format(new_visible_flags))
            self._update_visible_flags(new_visible_flags)
            self.env.bk_bridge.call_js({
                'object': 'tools',
                'function': 'show_default_cursor',
            })

        self.all_flags_vb_bt.on_click(all_flags_vb_bt_callback)

        # TODO: replace this div with the flag selection dropdown
        #       or maybe there would be too many control on one place

        flag_controls_title_div = Div(
            name='flag_controls_title',
            text='All the flags',
            width=100,
            height=25,
            css_classes=['flag_controls_title'],
        )

        self.flags_control_header_row = row(
            children=[self.all_flags_vb_bt, flag_controls_title_div],
            width=200,
            height=25,
        )

    def _init_flags_control_table(self):
        ''' Reminder:
                self.env.all_flags = {
                    2: 'FLAG 2',
                    3: 'FLAG 3',
                    ...
                }
        '''
        lg.info('-- INIT FLAGS CONTROL TABLE')
        # lg.info('-- ALL FLAGS DICTIONARY: {}'.format(self.env.all_flags))

        for flag_index, str_value in self.env.all_flags.items():

            def change_flag_vb(flag_index=flag_index):
                self.env.bk_bridge.call_js({
                    'object': 'tools',
                    'function': 'show_wait_cursor',
                })
                vb_bt_to_change = self.env.doc.select_one(
                    dict(name='flag_vb_bt_{}'.format(flag_index)))
                lg.info('>> CHANGING VISIBILITY: {}'.format(
                    'flag_vb_bt_{}'.format(flag_index)))

                new_visible_flags = self.env.visible_flags.copy()
                if 'eye_bt' in vb_bt_to_change.css_classes:
                    new_visible_flags.remove(flag_index)
                    vb_bt_to_change.css_classes = ['eye_slash_bt']
                else:
                    new_visible_flags.append(flag_index)
                    vb_bt_to_change.css_classes = ['eye_bt']
                self._update_visible_flags(new_visible_flags)
                self.env.bk_bridge.call_js({
                    'object': 'tools',
                    'function': 'show_default_cursor',
                })

            vb_bt = Button(
                name='flag_vb_bt_{}'.format(flag_index),
                label='',
                width=30,
                tags=['vb_bt'],
                css_classes=['eye_bt'],
            )
            vb_bt.on_click(change_flag_vb)

            edit_flag_bt = self._init_edit_bt(flag_index)

            fg_str_div = Div(name='fg_str_div_{}'.format(flag_index),
                             text='{}'.format(str_value),
                             width=100,
                             height=25,
                             tags=['fg_str_div'],
                             css_classes=['fg_str_div'],
                             style={
                                 'color': CIRCLE_COLORS[flag_index],
                                 'font-weight': 'bold',
                             })

            flag_row = row(
                name='flag_row_{}'.format(flag_index),
                children=[vb_bt, edit_flag_bt, fg_str_div],
                width=200,
                height=25,
            )

            # self.env.flag_vb_bts.append(vb_bt)
            self.flag_rows.append(flag_row)

        self.env.flags_control_col = column(
            name='flags_control_col',
            children=[self.flags_control_header_row] + self.flag_rows,
            css_classes=['flags_control_col'],
        )

    def _init_edit_bt(self, flag_index):
        edit_flag_bt = Button(name='edit_flag_bt_{}'.format(flag_index),
                              label='',
                              width=30,
                              tags=['edit_flag_bt'],
                              css_classes=['edit_flag_bt'])

        def update_flag_value_edit_bt(flag_index=flag_index):
            self.update_flag_value(flag_value=flag_index,
                                   flag_to_update=None,
                                   row_indexes=self.env.selection)

        edit_flag_bt.on_click(update_flag_value_edit_bt)
        return edit_flag_bt

    def update_flag_value(self,
                          flag_value=None,
                          flag_to_update=None,
                          row_indexes=[]):
        lg.info('-- UPDATE FLAG VALUE')
        self.env.bk_bridge.call_js({
            'object': 'tools',
            'function': 'show_wait_cursor',
        })
        if flag_value is None:
            lg.error(
                '>> An empty flag value got to `self.env.bk_flags.update_flag_value()`'
            )
        if flag_to_update is None:
            flag_to_update = self.env.cur_flag
        if row_indexes == []:
            lg.error('>> NO row_indexes selected')

        self.env.cruise_data.update_flag_values(
            column=flag_to_update,
            new_flag_value=flag_value,
            row_indices=row_indexes,
        )
        new_values = np.array(self.env.source.data[flag_to_update],
                              dtype=int)  # TODO: Int8 or Int64
        new_values[row_indexes] = flag_value
        self.env.source.data[flag_to_update] = new_values
        self.env.bk_sources.cds_df[flag_to_update] = new_values

        # Updating flag colors
        self.env.doc.hold('collect')
        self.env.bk_plots_handler.replot_color_circles()

        # NOTE: update datatable and prof sources is needed because the new flag could be invisible,
        #       then the profiles should be invisible as well
        # self.env.bk_table.update_dt_source()
        self.env.bk_sources._upd_prof_srcs(force_selection=True)

        self.env.doc.unhold()

        self.env.bk_bridge.call_js({
            'object': 'tools',
            'function': 'show_default_cursor',
        })
        self.env.bk_bridge.call_js({
            'object':
            'tools',
            'function':
            'show_snackbar',
            'params': [
                '{} values of {} updated with the flag value {}'.format(
                    len(row_indexes),
                    flag_to_update,
                    flag_value,
                )
            ],
        })

    def _update_visible_flags(self, to_visible_flags=[]):
        ''' Makes visible the flags passed as argument, and make invisible the rest
                @to_visible_flags: all the visible (or to make visible) flags indices
        '''
        lg.info('-- UPDATE VISIBLE FLAGS')

        to_visible = []
        to_invisible = []
        for flag_index, flag_str in self.env.all_flags.items():
            if flag_index in self.env.visible_flags and flag_index not in to_visible_flags:
                to_invisible.append('GR_FLAG_{}'.format(flag_index))
            if flag_index not in self.env.visible_flags and flag_index in to_visible_flags:
                to_visible.append('GR_FLAG_{}'.format(flag_index))

        # lg.info('>> TO VISIBLE FLAGS: {}'.format(to_visible_flags))
        # lg.info('>> TO VISIBLE: {}'.format(to_visible))
        # lg.info('>> TO INVISIBLE: {}'.format(to_invisible))

        self.env.doc.hold('collect')
        if to_visible != []:
            self.env.doc.set_select(selector=dict(tags=to_visible),
                                    updates=dict(visible=True))
        if to_invisible != []:
            self.env.doc.set_select(selector=dict(tags=to_invisible),
                                    updates=dict(visible=False))

        all_flags_bt = self.env.doc.select_one(dict(name='all_flags_bt'))
        if to_visible_flags == []:
            all_flags_bt.css_classes = ['eye_slash_bt']
        else:
            all_flags_bt.css_classes = ['eye_bt']

        self.env.visible_flags = to_visible_flags.copy()
        self.env.bk_sources._upd_prof_srcs(force_selection=True)
        self.env.doc.unhold()

    def reset_all_flags(self):
        lg.info('-- RESET ALL FLAGS')
        if sorted(self.env.visible_flags) != self.all_flags_list:
            self.env.doc.set_select(selector=dict(tags=['vb_bt']),
                                    updates=dict(css_classes=['eye_bt']))

            to_visible = []
            for flag_index, flag_str in self.env.all_flags.items():
                if flag_index not in self.env.visible_flags:
                    to_visible.append('GR_FLAG_{}'.format(flag_index))

            self.env.doc.set_select(selector=dict(tags=to_visible),
                                    updates=dict(visible=True))
            self.env.visible_flags = self.all_flags_list

            all_flags_bt = self.env.doc.select_one(dict(name='all_flags_bt'))
            all_flags_bt.css_classes = ['eye_bt']
    def _init_flags_control_table(self):
        ''' Reminder:
                self.env.all_flags = {
                    2: 'FLAG 2',
                    3: 'FLAG 3',
                    ...
                }
        '''
        lg.info('-- INIT FLAGS CONTROL TABLE')
        # lg.info('-- ALL FLAGS DICTIONARY: {}'.format(self.env.all_flags))

        for flag_index, str_value in self.env.all_flags.items():

            def change_flag_vb(flag_index=flag_index):
                self.env.bk_bridge.call_js({
                    'object': 'tools',
                    'function': 'show_wait_cursor',
                })
                vb_bt_to_change = self.env.doc.select_one(
                    dict(name='flag_vb_bt_{}'.format(flag_index)))
                lg.info('>> CHANGING VISIBILITY: {}'.format(
                    'flag_vb_bt_{}'.format(flag_index)))

                new_visible_flags = self.env.visible_flags.copy()
                if 'eye_bt' in vb_bt_to_change.css_classes:
                    new_visible_flags.remove(flag_index)
                    vb_bt_to_change.css_classes = ['eye_slash_bt']
                else:
                    new_visible_flags.append(flag_index)
                    vb_bt_to_change.css_classes = ['eye_bt']
                self._update_visible_flags(new_visible_flags)
                self.env.bk_bridge.call_js({
                    'object': 'tools',
                    'function': 'show_default_cursor',
                })

            vb_bt = Button(
                name='flag_vb_bt_{}'.format(flag_index),
                label='',
                width=30,
                tags=['vb_bt'],
                css_classes=['eye_bt'],
            )
            vb_bt.on_click(change_flag_vb)

            edit_flag_bt = self._init_edit_bt(flag_index)

            fg_str_div = Div(name='fg_str_div_{}'.format(flag_index),
                             text='{}'.format(str_value),
                             width=100,
                             height=25,
                             tags=['fg_str_div'],
                             css_classes=['fg_str_div'],
                             style={
                                 'color': CIRCLE_COLORS[flag_index],
                                 'font-weight': 'bold',
                             })

            flag_row = row(
                name='flag_row_{}'.format(flag_index),
                children=[vb_bt, edit_flag_bt, fg_str_div],
                width=200,
                height=25,
            )

            # self.env.flag_vb_bts.append(vb_bt)
            self.flag_rows.append(flag_row)

        self.env.flags_control_col = column(
            name='flags_control_col',
            children=[self.flags_control_header_row] + self.flag_rows,
            css_classes=['flags_control_col'],
        )
Beispiel #9
0
class PSUGUI(TabbedGUI):
    """@brief Responsible for plotting data on tab 0 with no other tabs."""

    CFG_FILENAME = ".RS310P_GUI.cfg"
    AMPS = "amps"
    VOLTS = "volts"
    PLOT_SECONDS = "plotSeconds"
    CFG_DICT = {VOLTS: "5", AMPS: "1", PLOT_SECONDS: 300}

    def __init__(self, docTitle, bokehPort=12000):
        """@Constructor"""
        super().__init__(docTitle, bokehPort=bokehPort)
        self._figTable = [[]]
        self._grid = None
        self._textBuffer = ""
        self._psu = None
        self._on = False

    def info(self, msg):
        """@brief Display an info level message."""
        self.statusBarWrapper.setStatus("INFO:  " + msg)

    def error(self, msg):
        """@brief Display an error level message."""
        self.statusBarWrapper.setStatus("ERROR: " + msg)

    def debug(self, msg):
        """@brief Display an error level message."""
        pass

    def addRow(self):
        """@brief Add an empty row to the figures."""
        self._figTable.append([])

    def addToRow(self, fig):
        """@brief Add a figure to the end of the current row of figues.
           @param fig The figure to add."""
        self._figTable[-1].append(fig)

    def createPlot(
        self,
        doc,
    ):
        """@brief create a plot figure.
           @param doc The document to add the plot to."""
        self._doc = doc
        self._doc.title = "RS310P PSU Controller"

        self.statusBarWrapper = StatusBarWrapper()
        self._pconfig = ConfigManager(self, PSUGUI.CFG_FILENAME,
                                      PSUGUI.CFG_DICT)
        self._pconfig.load()

        plotPanel = self._getPlotPanel()

        self._tabList.append(
            Panel(child=plotPanel, title="DC Power Supply Control"))
        self._doc.add_root(Tabs(tabs=self._tabList))
        self._doc.add_periodic_callback(self._viewUpdate, 500)

    def _viewUpdate(self):
        if self._on:
            volts, amps, watts = self._psu.getOutputStats()
            self._opTableWrapper.setRows([[volts, amps, watts]])
            self._updatePlot(volts, amps, watts)

    def _updatePlot(self, volts, amps, watts):
        """@brief called periodically to update the plot trace."""
        plotPoints = self.plotHistorySpinner.value * 2
        now = datetime.now()
        newVolts = {'x': [now], 'y': [volts]}
        self._voltsSource.stream(newVolts, rollover=plotPoints)

        newAmps = {'x': [now], 'y': [amps]}
        self._ampsSource.stream(newAmps, rollover=plotPoints)

        newWatts = {'x': [now], 'y': [watts]}
        self._wattsSource.stream(newWatts, rollover=plotPoints)

    def _getPlotPanel(self):
        """@brief Add tab that shows plot data updates."""

        self._figTable.append([])
        self._voltsSource = ColumnDataSource({'x': [], 'y': []})
        self._ampsSource = ColumnDataSource({'x': [], 'y': []})
        self._wattsSource = ColumnDataSource({'x': [], 'y': []})
        fig = figure(toolbar_location='above',
                     x_axis_type="datetime",
                     x_axis_location="below")
        fig.line(source=self._voltsSource,
                 line_color="blue",
                 legend_label="Volts")
        fig.line(source=self._ampsSource,
                 line_color="green",
                 legend_label="Amps")
        fig.line(source=self._wattsSource,
                 line_color="red",
                 legend_label="Watts")
        fig.legend.location = 'top_left'
        self._figTable[-1].append(fig)
        self._grid = gridplot(children=self._figTable,
                              sizing_mode='scale_both',
                              toolbar_location='right')

        self.selectSerialPort = Select(title="Serial Port:")
        self.selectSerialPort.options = glob.glob('/dev/ttyU*')

        self.outputVoltageSpinner = Spinner(title="Output Voltage (Volts)",
                                            low=0,
                                            high=40,
                                            step=0.5,
                                            value=self._pconfig.getAttr(
                                                PSUGUI.VOLTS))
        self.currentLimitSpinner = Spinner(title="Currnet Limit (Amps)",
                                           low=0,
                                           high=10,
                                           step=0.25,
                                           value=self._pconfig.getAttr(
                                               PSUGUI.AMPS))
        self.plotHistorySpinner = Spinner(title="Plot History (Seconds)",
                                          low=1,
                                          high=10000,
                                          step=1,
                                          value=self._pconfig.getAttr(
                                              PSUGUI.PLOT_SECONDS))

        self._setButton = Button(label="Set")
        self._setButton.on_click(self._setHandler)
        self._setButton.disabled = True

        self._onButton = Button(label="On")
        self._onButton.on_click(self._psuOnHandler)

        shutdownButtonWrapper = ShutdownButtonWrapper(self._quit)
        controlPanel = column([
            self.selectSerialPort, self._onButton, self.outputVoltageSpinner,
            self.currentLimitSpinner, self._setButton, self.plotHistorySpinner,
            shutdownButtonWrapper.getWidget()
        ])

        self._opTableWrapper = ReadOnlyTableWrapper(("volts", "amps", "watts"),
                                                    heightPolicy="fixed",
                                                    height=65,
                                                    showLastRows=0)

        plotPanel = column([self._grid, self._opTableWrapper.getWidget()])
        panel2 = row([controlPanel, plotPanel])
        plotPanel = column([panel2, self.statusBarWrapper.getWidget()])
        return plotPanel

    def _quit(self):
        if self._on:
            self._psuOff()
        self._run(self._delayedShutdown)
        self._doc.clear()

    def _delayedShutdown(self):
        """@brief Allow time for browser page to clear before shutdown."""
        volts = self.outputVoltageSpinner.value
        amps = self.currentLimitSpinner.value
        self._pconfig.addAttr(PSUGUI.VOLTS, volts)
        self._pconfig.addAttr(PSUGUI.AMPS, amps)
        self._pconfig.addAttr(PSUGUI.PLOT_SECONDS,
                              self.plotHistorySpinner.value)
        self._pconfig.store()
        sleep(0.5)
        self._sendUpdateEvent(
            PSUGUIUpdateEvent(PSUGUIUpdateEvent.SHUTDOWN_SERVER))

    def _psuOnHandler(self):
        """@brief event handler."""
        #Stop the user from clicking the button again until this click has been processed.
        self._onButton.disabled = True
        #Turn the PSUon/off method outside GUI thread
        self._run(self._powerOnOff)

    def _setHandler(self):
        """@brief event handler."""
        #Turn the PSUon/off method outside GUI thread
        self._run(self._setPSU)

    def _rxUpdateEvent(self, updateEvent):
        """@brief Receive an event into the GUI context to update the GUI.
           @param updateEvent An PSUGUIUpdateEvent instance."""
        if updateEvent.id == PSUGUIUpdateEvent.UPDATE_STATUS_TEXT:
            self.statusBarWrapper.setStatus(updateEvent.argList[0])

        elif updateEvent.id == PSUGUIUpdateEvent.CONNECTING_TO_PSU:
            self._onButton.button_type = "success"
            self._onButton.disabled = True
            self.statusBarWrapper.setStatus(updateEvent.argList[0])

        elif updateEvent.id == PSUGUIUpdateEvent.PSU_CONNECT_FAILED:
            self._onButton.button_type = "default"
            self._onButton.disabled = False
            self._setButton.disabled = True
            self._setButton.button_type = "default"
            self.statusBarWrapper.setStatus(updateEvent.argList[0])

        elif updateEvent.id == PSUGUIUpdateEvent.CONNECTED_TO_PSU:
            self._setButton.button_type = "success"
            self._setButton.disabled = False
            self._onButton.button_type = "success"
            self._onButton.disabled = False
            self._onButton.label = "Off"
            self.statusBarWrapper.setStatus("PSU ON")
            self._pconfig.addAttr(PSUGUI.VOLTS,
                                  self.outputVoltageSpinner.value)
            self._pconfig.addAttr(PSUGUI.AMPS, self.currentLimitSpinner.value)
            self._pconfig.addAttr(PSUGUI.PLOT_SECONDS,
                                  self.plotHistorySpinner.value)
            self._pconfig.store()

        elif updateEvent.id == PSUGUIUpdateEvent.TURNING_PSU_OFF:
            self._onButton.button_type = "default"
            self._setButton.disabled = True
            self._onButton.disabled = True
            self._setButton.button_type = "default"
            self.statusBarWrapper.setStatus("Turning PSU OFF")

        elif updateEvent.id == PSUGUIUpdateEvent.PSU_OFF:
            self._onButton.button_type = "default"
            self._onButton.disabled = False
            self._onButton.label = "On"
            self.statusBarWrapper.setStatus("PSU OFF")

        elif updateEvent.id == PSUGUIUpdateEvent.SET_PSU_STATE:
            volts = self.outputVoltageSpinner.value
            amps = self.currentLimitSpinner.value
            self._pconfig.addAttr(PSUGUI.VOLTS, volts)
            self._pconfig.addAttr(PSUGUI.AMPS, amps)
            self._pconfig.addAttr(PSUGUI.PLOT_SECONDS,
                                  self.plotHistorySpinner.value)
            self._pconfig.store()
            self.statusBarWrapper.setStatus(
                "Set {:.2f} volts with a {:.3f} amp current limit".format(
                    volts, amps))

        elif updateEvent.id == PSUGUIUpdateEvent.SHUTDOWN_SERVER:
            self.stopServer()
            print("PJA: SERVER SHUTDOWN.")

    def _powerOnOff(self):
        """@brief Called to turn the PSU on/off"""
        if self._on:
            self._psuOff()
        else:
            self._psuOn()

    def _setPSU(self):
        """@brief Called when the PSU is on to set the state of the PSU."""
        volts = self.outputVoltageSpinner.value
        amps = self.currentLimitSpinner.value
        self._psu.setVoltage(volts)
        self._psu.setCurrentLimit(amps)
        self._sendUpdateEvent(UpdateEvent(PSUGUIUpdateEvent.SET_PSU_STATE))

    def getSelectedSerialPort(self):
        """@brief Get the selected serial port.
           @return the selected Serial port or None if not selected."""
        selectedSerialPort = None
        if len(self.selectSerialPort.options) == 1:
            selectedSerialPort = self.selectSerialPort.options[0]
        elif self.selectSerialPort.value:
            selectedSerialPort = self.selectSerialPort.value

        if not selectedSerialPort and len(self.selectSerialPort.options) > 0:
            selectedSerialPort = self.selectSerialPort.options[0]

        return selectedSerialPort

    def _psuOff(self):
        """@brief Turn the PSU off."""
        self._sendUpdateEvent(UpdateEvent(PSUGUIUpdateEvent.TURNING_PSU_OFF))
        self._on = False
        self._psu.setOutput(False)
        self._psu.disconnect()
        self._psu = None
        self._sendUpdateEvent(UpdateEvent(PSUGUIUpdateEvent.PSU_OFF))

    def _psuOn(self):
        """@brief Connect to the PDU.
           @return True if successfully connected to a PSU."""
        serialPort = None
        try:
            serialPort = self.getSelectedSerialPort()
            if serialPort:
                self._sendUpdateEvent(
                    UpdateEvent(PSUGUIUpdateEvent.CONNECTING_TO_PSU,
                                ("Connecting to {}".format(serialPort), )))
                self._psu = ETMXXXXP(serialPort)
                self._psu.connect()
                self._psu.getOutput()
                #Ensure the voltage comes up from a low voltage rather than down
                #from a previously higher voltage
                self._psu.setVoltage(0)
                self._psu.setVoltage(self.outputVoltageSpinner.value)
                self._psu.setCurrentLimit(self.currentLimitSpinner.value)
                self._psu.setOutput(True)
                self._on = True
                self._sendUpdateEvent(
                    UpdateEvent(PSUGUIUpdateEvent.CONNECTED_TO_PSU))
            else:
                self._sendUpdateEvent(
                    UpdateEvent(PSUGUIUpdateEvent.PSU_CONNECT_FAILED, (
                        "Failed to to connect to PSU as no serial port was selected.",
                    )))
        except Exception as ex:
            print(ex)
            if self._psu:
                self._psu.disconnect()
                self._psu = None
            if serialPort:
                self._sendUpdateEvent(
                    UpdateEvent(
                        PSUGUIUpdateEvent.PSU_CONNECT_FAILED,
                        ("Failed to connect to PSU on {}".format(serialPort),
                         )))
            else:
                self._sendUpdateEvent(
                    UpdateEvent(
                        PSUGUIUpdateEvent.PSU_CONNECT_FAILED,
                        ("Failed to connect to PSU on {}".format(serialPort),
                         )))
                self.setStatus("Failed to connect to PSU.")
Beispiel #10
0
                options=[x[0] for x in collections.Counter(ptree.leaf_cds.data['genus']).most_common()],\
                width=200,height=70)
gms.on_change('value',lambda attr,old,new:gmsfunc())

kms=MultiSelect(title='Kingdom',\
                options=[x[0] for x in collections.Counter(ptree.leaf_cds.data['superkingdom']).most_common()],\
                width=200,height=70)
kms.on_change('value',lambda attr,old,new:kmsfunc())

sfms=MultiSelect(title='Subfams',\
                options=[x[0] for x in collections.Counter(ptree.leaf_cds.data['subfamstr']).most_common()],\
                width=150,height=70)
sfms.on_change('value',lambda attr,old,new:sfmsfunc())

tcb=Button(label='CalcTC',width=80,height=40)
tcb.on_click(tcbfunc)
#splist=list(set(ptree.leaf_cds.data['species']))
#splist.sorted(key=ptree.leaf_cds.data['species'])
#acw=AutocompleteInput(title='Organism name',completions=list(set(ptree.leaf_cds.data['species'])),width=200,height=50)
acw=AutocompleteInput(title='Organism name',\
    completions=[x[0] for x in collections.Counter(ptree.leaf_cds.data['species']).most_common()],\
    width=200,height=50)
acw.on_change('value',lambda attr,old,new:acfunc())

accacw=AutocompleteInput(title='Accession',\
    completions=ptree.leaf_cds.data['gbacc'][:],width=200,height=50)
accacw.on_change('value',lambda attr,old,new:accacfunc())


if len(sys.argv)>3:
    preselfpath=os.path.join(os.environ['SCIENCEDIR'],'GHSeqs',ghfam.upper(),sys.argv[3])
## there is a bug in bokeh image_rgba to be used later that requires the following flipping
## https://github.com/bokeh/bokeh/issues/1666
logo = logo[::-1]
plogo = figure(x_range=(0, 25),
               y_range=(0, 15),
               tools=[],
               plot_width=333,
               plot_height=250)
plogo.xgrid.grid_line_color = None
plogo.ygrid.grid_line_color = None
plogo.image_rgba(image=[logo], x=[0], y=[0], dw=[25], dh=[15])
plogo.xaxis.visible = False
plogo.yaxis.visible = False

div1 = Div(
    text=
    """<font size=6><b><h>EuroLeague in a Spreadsheet</b></h></font></br></br><font size=5>With COVID-19 hitting sports hard - just as with everything else - spreadsheets finally get the position they deserve in sports. Euroleague was suspended before the regular season ended. Simulate the rest of the regular season and the playoffs to get your sports fix <br><br>Basketball Guru (@wiseballsguru), K. Pelechrinis (@kpelechrinis). </font><br></br></br><br></br></br>""",
    width=800,
    height=250)

button = Button(label="Simulate", button_type="success", width=250)
button.on_click(sim_callback)

div2 = Div(text="""""", width=350)
div3 = Div(text="""""", width=100)

#layout = layout([[div1,],[button,],[table_standings,table_playoffs]])
layout = (column(row(div1, div3, plogo), row(button),
                 row(table_standings, div2, table_playoffs)))
curdoc().add_root(layout)
Beispiel #12
0
    plot.children[1] = column(create_plots(Estimators))

#lowecase innerscope variables
variable1, variable2 = Variable1, Variable2

#Create the widgets
drop1 = Select(title="Variable 1",
               options=list(X.columns.values),
               value=variable1)

drop2 = Select(title="Variable 2",
               options=list(X.columns.values),
               value=variable2)

drop3 = Select(title="variable 3", options=list(X.columns.values), value=y)

estimator_names = [str(estimator).split("(")[0] for estimator in Estimators]
estimator_indices = [str(i) for i, name in enumerate(estimator_names)]
estimator_select = MultiSelect(title="Estimators",
                               options=estimator_names,
                               value=estimator_names[0:5])

button = Button(label="Update", button_type="success")
button.on_click(update)

plot = row(widgetbox(drop1, drop2, drop3, estimator_select, button),
           column(create_plots(Estimators)))

curdoc().add_root(plot)
curdoc().title = "Wage Data Visualisation"