Exemple #1
0
class BokehButton(BokehControl):
    def getBokehComponent(self):
        self.bk = Button(label=self._settings['label'])
        self.bk.on_event(ButtonClick, self.handle_click)
        return self.bk

    def handle_click(self, event):
        raise Exception("Should not be creating a general button")
Exemple #2
0
def create_disp():
    ##### 各画面要素作成
    # テーブル作成
    df_columns = target_data.columns.tolist()
    datatable_source = ColumnDataSource(data=target_data)
    table_columns = create_datatable_columns(df_columns)
    data_table = DataTable(source=datatable_source,
                           selectable=True,
                           columns=table_columns,
                           sortable=True)

    # カラムが変わった時に呼び出す関数リスト
    column_change_functions = []

    # 表示を切り替えるplotリスト
    visible_plots = []

    cm_operation_area, cm_plot_area = create_cm(column_change_functions,
                                                visible_plots,
                                                datatable_source)

    # upload button がクリックされた時の処理
    def upload_button_callback(event):
        global target_data
        global user
        csv_str = base64.b64decode(csv_input.value)
        target_data = pd.read_csv(io.BytesIO(csv_str))
        df_columns = target_data.columns.tolist()
        call_column_change(column_change_functions, df_columns)
        table_columns = create_datatable_columns(df_columns)
        data_table.columns = table_columns
        datatable_source.data = target_data
        data_table.update()
        try:
            user.csv_data = target_data.to_json()
            db.session.commit()
        except Exception as e:
            warn = str(e)

    # csvアップロード実行ボタン
    upload_button = Button(label="Upload", button_type="success")
    upload_button.on_event(ButtonClick, upload_button_callback)

    # ファイル選択ボックス
    csv_input = FileInput()

    scatter_operation_area, scatter_plot_area = create_scatter(
        column_change_functions, visible_plots, datatable_source)

    # サブオペレーションエリア
    sub_operation_area = Row(cm_operation_area, scatter_operation_area)

    operation_area = Column(csv_input, upload_button, sub_operation_area,
                            data_table)
    graph_area = Column(cm_plot_area, scatter_plot_area)
    layout_disp = Row(graph_area, operation_area)

    return layout_disp
Exemple #3
0
    def createFigures(self, metadata: Metadata):
        for i in range(len(metadata.Data.columns)):
            y1 = metadata.Data[i].astype(float)
            x1 = np.arange(0, y1.size, 1)

            plot = figure(
                tools="",
                title="Channel[" + str(i) + "] Sampling rate[1/" +
                str(metadata.Definitions["samplingfreq"]) + "]" +
                " Muscle names[" + str(metadata.SourceNames) + "]",
                width=1200,
                height=350,
                y_range=(metadata.Data[i].min(), metadata.Data[i].max()),
                x_range=(0, y1.size),
                name=str(uuid.uuid1())
                # y_axis_type="datetime", Does not make sence to time this really
                # x_axis_type="datetime",
            )
            plot.xaxis.axis_label = "Ticks[Individual samples]"
            plot.yaxis.axis_label = str(list(metadata.Units)[0])

            plot.add_tools(HelpTool(name=str(i) + "pt" + str(uuid.uuid1())))
            plot.add_tools(PanTool(name=str(i) + "pt" + str(uuid.uuid1())))
            plot.add_tools(ZoomInTool(name=str(i) + "zit" + str(uuid.uuid1())))
            plot.add_tools(ZoomOutTool(name=str(i) + "zot" +
                                       str(uuid.uuid1())))
            plot.add_tools(
                BoxSelectTool(name=str(i) + "bst" + str(uuid.uuid1())))
            plot.add_tools(ResetTool(name=str(i) + "rt" + str(uuid.uuid1())))
            plot.add_tools(SaveTool(name=str(i) + "st" + str(uuid.uuid1())))
            plot.line(x1, y1, line_width=1, name=str(i) + str(uuid.uuid1()))

            plot.scatter(
                "xvals",
                "yvals",
                source=self.DataSources[metadata.Definitions["phasename"] +
                                        metadata.Id][i],
                alpha=0,
                selection_color="firebrick",
                selection_line_alpha=0.1,
                nonselection_fill_alpha=0.0,
                name=str(uuid.uuid1()))

            btn = Button(label='Find similarities',
                         button_type='success',
                         width=100,
                         name=str(i) + str(uuid.uuid1()))
            btn.on_event(
                ButtonClick,
                partial(self.beforeClicked,
                        button=btn,
                        graphId=i,
                        metadata=metadata))
            self.Buttons.append(btn)
            self.Figures.append(plot)
def start_program():

    # Set up widgets
    text = TextInput(title="HashTag", placeholder='Write a HashTag')

    columns = [
        'Today', 'From yesterday', 'Two days ago', 'Three days ago',
        'Four days ago', 'Five days ago', 'Six days ago'
    ]
    days = Select(title='Days', value='Today', options=columns)

    button = Button(label="Fetch Data", button_type="success")
    button1 = Button(label="Refresh Map", button_type="danger", disabled=True)

    message_box = Div(text="Welcome")

    # Callback function for running the program when hastag requested
    def callback(event):
        if (text.value == ""):
            layout1.children[0] = display_message(
                "HashTag should not be Empty")
            return

        # Disabled the properties for user utill data is fetched
        button.disabled = True
        button.button_type = "danger"
        sentiment.disabled = True
        continent.disabled = True
        button1.disabled = True
        button1.button_type = "danger"

        old = 0
        if (days.value == "Today"):
            old = 0
        elif (days.value == "From yesterday"):
            old = 1
        elif (days.value == "Two days ago"):
            old = 2
        elif (days.value == "Three days ago"):
            old = 3
        elif (days.value == "Four days ago"):
            old = 4
        elif (days.value == "Five days ago"):
            old = 5
        else:
            old = 6

        #Calling the main function for retriving the data
        main(hashtag=text.value,
             days=old,
             layout=layout1,
             button=button,
             sentiment=sentiment,
             continent=continent,
             button1=button1)

    # create_figure function for creating the google map onto the browser with data from output.csv
    def create_figure(event):
        conti = continent.value
        senti = sentiment.value

        if (conti == "North America"):
            map_options = GMapOptions(lat=33.465777,
                                      lng=-88.369025,
                                      map_type="roadmap",
                                      zoom=3)
        elif (conti == "South America"):
            map_options = GMapOptions(lat=-8.783195,
                                      lng=-55.491477,
                                      map_type="roadmap",
                                      zoom=3)
        elif (conti == "Africa"):
            map_options = GMapOptions(lat=-8.783195,
                                      lng=34.508523,
                                      map_type="roadmap",
                                      zoom=3)
        elif (conti == "Asia"):
            map_options = GMapOptions(lat=34.047863,
                                      lng=100.619655,
                                      map_type="roadmap",
                                      zoom=3)
        elif (conti == "Europe"):
            map_options = GMapOptions(lat=54.525961,
                                      lng=15.255119,
                                      map_type="roadmap",
                                      zoom=3)
        elif (conti == "Antartica"):
            map_options = GMapOptions(lat=-82.862752,
                                      lng=135.000000,
                                      map_type="roadmap",
                                      zoom=3)
        else:
            map_options = GMapOptions(lat=-25.274398,
                                      lng=133.775136,
                                      map_type="roadmap",
                                      zoom=3)

        # Calling the Google API Key for displaying google maps
        p = gmap("AIzaSyCJMprrXTtmUqciVaVgskmHxskLkVjrE6A",
                 map_options,
                 title="World Map",
                 width=950)

        #Ploting the legends on the map
        p.circle(None,
                 None,
                 size=5,
                 fill_color="green",
                 fill_alpha=0.7,
                 legend="Positive")
        p.circle(None,
                 None,
                 size=5,
                 fill_color="yellow",
                 fill_alpha=0.7,
                 legend="Neutral")
        p.circle(None,
                 None,
                 size=5,
                 fill_color="red",
                 fill_alpha=0.7,
                 legend="Negative")

        # Load function for extracting data from "output.csv" file
        def load(data):
            lat = []
            lon = []

            with open('output.csv') as csvfile:
                reader = csv.DictReader(csvfile)
                for row in reader:
                    x = float(row["longitude"])
                    y = float(row["latitude"])
                    z = row["sentiment"]
                    if (z == data):
                        lat.append(y)
                        lon.append(x)
            data1 = dict(lat=lat, lon=lon)
            return data1

        # pointing the data on Google Maps
        if (senti == "All"):
            source = ColumnDataSource(data=load(data="positive"))
            p.circle(x="lon",
                     y="lat",
                     size=8,
                     fill_color="green",
                     fill_alpha=1.0,
                     source=source)
            source = ColumnDataSource(data=load(data="negative"))
            p.circle(x="lon",
                     y="lat",
                     size=8,
                     fill_color="red",
                     fill_alpha=1.0,
                     source=source)
            source = ColumnDataSource(data=load(data="neutral"))
            p.circle(x="lon",
                     y="lat",
                     size=8,
                     fill_color="yellow",
                     fill_alpha=1.0,
                     source=source)
        elif (senti == "Positive"):
            source = ColumnDataSource(data=load(data="positive"))
            p.circle(x="lon",
                     y="lat",
                     size=8,
                     fill_color="green",
                     fill_alpha=1.0,
                     source=source)
        elif (senti == "Negative"):
            source = ColumnDataSource(data=load(data="negative"))
            p.circle(x="lon",
                     y="lat",
                     size=8,
                     fill_color="red",
                     fill_alpha=1.0,
                     source=source)
        else:
            source = ColumnDataSource(data=load(data="neutral"))
            p.circle(x="lon",
                     y="lat",
                     size=8,
                     fill_color="yellow",
                     fill_alpha=1.0,
                     source=source)

        return p  #End of function create_figure()

    #update function for on_change event listener
    def update(attr, old, new):
        layout.children[1] = create_figure(event=None)

    #update1 function for on_click event listener
    def update1():
        layout.children[1] = create_figure(event=None)

    # Event listner for buttons
    button.on_event(ButtonClick, callback)
    button1.on_click(update1)

    #Set all Parameters for dropdown menus
    columns = ["All", "Positive", "Neutral", "Negative"]
    sentiment = Select(title='Sentiment',
                       value='All',
                       options=columns,
                       disabled=True)
    sentiment.on_change('value', update)

    continents = [
        "North America", "South America", "Africa", "Asia", "Antartica",
        "Europe", "Australia"
    ]
    continent = Select(title='Continents',
                       value='North America',
                       options=continents,
                       disabled=True)
    continent.on_change('value', update)

    # Set up layouts and add to document
    controls = widgetbox([text, days, button, sentiment, continent, button1])
    layout1 = column(display_message("Welcome"), controls)
    layout = row(layout1, create_figure(event=None))

    #Drawing widgets onto the browser
    curdoc().add_root(layout)
    curdoc().title = "World Map"
Exemple #5
0
    'Hermite': {
        'drag': [],
        'data': []
    },
    'Lagrange': {'data': []},
    'Catmull-Rom': {'data': []},
    'Four-Point': {'data': []},
}

show_convex_hull = False
curve, control, drag, hull = get_data(method)
plot = make_plot(curve, control, drag, method)

# Holder variable for Drag Eventz
drag_event = None

# Add Method Selection Dropdown and Handler
options = ['B-Spline', 'Hermite Interpolation', 'Hermite Spline', 'Lagrange Interpolation', 'Catmull-Rom Spline', 'Four Point Subdivision']
method_select = Select(value=method, title='Subdivision Method', options=options)
method_select.on_change('value', update_plot)

# Add Clear Button
clear_button = Button(label='Clear')
clear_button.on_event(ButtonClick, clear)

convex_hull_button = Button(label='Convex Hull')
convex_hull_button.on_event(ButtonClick, toggle_convex_hull)

curdoc().add_root(row(plot, column(method_select, clear_button, convex_hull_button)))
curdoc().title = 'Subdivision Methods Toolbox'
Exemple #6
0
def main() -> None:
    """メイン処理

    Returns:
        None: None
    """
    # データソースの初期設定
    source = ColumnDataSource(data=dict(length=[], width=[]))
    source.data = {"0": [], "1": []}
    df = pd.DataFrame()

    # CSVファイル設定テキストボックス
    csv_input = TextInput(value="default.csv", title="Input CSV")

    # 可視化手法選択ラジオボタン
    method_group = analysis_method()
    method_radio_group = RadioGroup(labels=list(method_group.keys()), active=0)

    # グラフ初期設定
    p = figure(
        tools=("pan,box_zoom,lasso_select,box_select,poly_select"
               ",tap,wheel_zoom,reset,save,zoom_in"),
        title="Analyze Result",
        plot_width=1000,
        plot_height=800,
    )
    p.circle(x="0", y="1", source=source)

    # データ表示データテーブル
    data_table = DataTable(source=source,
                           columns=[],
                           width=600,
                           height=500,
                           fit_columns=False)

    # 色設定項目用選択セレクトボックス
    def color_select_callback(attr, old, new) -> None:
        mapper = create_mapper(df, new)
        p.circle(x="0", y="1", source=source, line_color=mapper, color=mapper)

    color_select = Select(title="color:", value="0", options=[])
    color_select.on_change("value", color_select_callback)

    # 解析実行ボタン
    def execute_button_callback_inner(evnet):
        nonlocal df
        df = pd.read_csv(csv_input.value, index_col=0)
        result = method_group[method_radio_group.labels[
            method_radio_group.active]](df)
        source.data = to_source_data_from(df, result)
        data_table.columns = to_datatable_columns_from(df)
        mapper = create_mapper(df, df.columns.values[0])
        p.circle(x="0", y="1", source=source, line_color=mapper, color=mapper)
        p.add_tools(create_hover(["ID", df.columns.values[0]]))
        color_select.options = list(df.columns)

    execute_button = Button(label="Execute", button_type="success")
    execute_button.on_event(ButtonClick, execute_button_callback_inner)

    # レイアウト
    operation_area = Column(csv_input, method_radio_group, execute_button,
                            color_select, data_table)
    layout = Row(p, operation_area)
    curdoc().add_root(layout)
Exemple #7
0
    end=2.000,
    value=0.400,
    step=0.001,
    format="0[.]000",
)

slider_X_RADIUS.on_change(
    "value", lambda attr, old, new: slider_callback(attr, old, new))
slider_Y_RADIUS.on_change(
    "value", lambda attr, old, new: slider_callback(attr, old, new))

# save file
savefilename = TextInput(title="Save file as (.csv or .pkl)",
                         placeholder="edited_peaks.csv")
button = Button(label="Save", button_type="success")
button.on_event(ButtonClick, save_peaks)
# call fit_peaks
fit_button = Button(label="Fit selected cluster", button_type="primary")
radio_button_group = RadioButtonGroup(
    labels=["PV", "G", "L", "PV_L", "PV_G", "PV_PV", "G_L"], active=0)
lineshapes = {
    0: "PV",
    1: "G",
    2: "L",
    3: "PV_L",
    4: "PV_G",
    5: "PV_PV",
    6: "G_L"
}
ls_div = Div(
    text=
Exemple #8
0
                  options=x_select_options,
                  value='beatsperminute')

y_select_options = unsup_cols.copy()
y_select_options.append('ALL')
y_select = Select(title='Y-axis feature',
                  options=x_select_options,
                  value='energy')

controls = [x_select, y_select]
for control in controls:
    control.on_change('value', lambda attr, old, new: update())

# Cluster Buttons
cluster_button = Button(label='Plot inertia', button_type='success')
cluster_button.on_event(ButtonClick, calculate_inertia)

# KMeans controls
data_key_options = df.columns.tolist()
data_key_options.append('None')
data_key_select_1 = Select(title='Data Key #1',
                           options=data_key_options,
                           value='None')
data_key_select_2 = Select(title='Data Key #2',
                           options=data_key_options,
                           value='None')
n_cluster_slider = Slider(title='n_clusters=',
                          start=1,
                          end=10,
                          value=3,
                          step=1)
Exemple #9
0
squa = p.quad(top='top',
              bottom='bottom',
              left='left',
              right='right',
              color="navy",
              alpha=0.8,
              source=source)

p.xaxis.ticker = [x for x in range(-20, 20)]
p.yaxis.ticker = [x for x in range(-20, 20)]
circ.visible = False
squa.visible = False

text_input = TextInput(value="", title="INPUT (only numbers):")

circlebutton = Button(label="Circle", button_type="primary")
circlebutton.on_event(ButtonClick, circlecallback)

squarebutton = Button(label="Square", button_type="primary")
squarebutton.on_event(ButtonClick, squarecallback)

clearbutton = Button(label="Clear", button_type="warning")
clearbutton.on_event(ButtonClick, clearcallback)

div2 = Div(text='', width=300, height=100)

aa = row([text_input, circlebutton, squarebutton, clearbutton])
bb = column([p, aa, div2])
doc.add_root(bb)
show(bb)
Exemple #10
0
def create_scatter(column_change_functions, visible_plots, datatable_source):
    # 散布図x
    x_select = Select(title="散布図x:", value="", options=[""])
    # 散布図y
    y_select = Select(title="散布図y:", value="", options=[""])
    # 色カラム
    color_select = Select(title="色カラム:", value="", options=[""])

    # テーブルカラムが変わった時に呼ばれる関数
    def column_change(columns):
        x_select.options = columns
        y_select.options = columns
        color_select.options = columns

    column_change_functions.append(column_change)

    scatter_plot = figure(
        title="特徴量空間",
        tools=
        "zoom_in,wheel_zoom,box_zoom,hover,box_select,poly_select,lasso_select,tap,reset"
    )
    scatter_plot.visible = False
    visible_plots.append(scatter_plot)

    scatter_source = ColumnDataSource()

    def on_scatter_change(self, attr, *callbacks):
        data = target_data.loc[scatter_source.selected.indices, :]
        datatable_source.data = data

    def scatter_callbacks():
        global target_data
        col = color_select.value
        scatter_source.data = {
            col: target_data[col],
            'legend': [f'{col}_{x}' for x in target_data[col]],
            'x': target_data[x_select.value],
            'y': target_data[y_select.value]
        }
        mapper = linear_cmap(field_name=col,
                             palette=Viridis256,
                             low=target_data[col].min(),
                             high=target_data[col].max())
        plot = scatter_plot.circle(x="x",
                                   y="y",
                                   source=scatter_source,
                                   line_color=mapper,
                                   color=mapper,
                                   legend_field='legend')
        plot.data_source.selected.on_change('indices', on_scatter_change)
        scatter_plot.legend.location = "top_right"
        scatter_plot.legend.click_policy = "hide"

        scatter_plot.visible = True
        unvisible_other_plots(scatter_plot, visible_plots)

    # 散布図作成実行ボタン
    scatter_button = Button(label="散布図作成", button_type="success")
    scatter_button.on_event(ButtonClick, scatter_callbacks)

    # 散布図オペレーションエリア
    scatter_operation_area = Column(x_select, y_select, color_select,
                                    scatter_button)

    return scatter_operation_area, scatter_plot
Exemple #11
0
def create_cm(column_change_functions, visible_plots, datatable_source):
    # 正解ラベル
    label_select = Select(title="正解ラベル:", value="", options=[""])
    # 推論ラベル
    pred_select = Select(title="推論ラベル:", value="", options=[""])

    # テーブルカラムが変わった時に呼ばれる関数
    def column_change(columns):
        label_select.options = columns
        pred_select.options = columns

    column_change_functions.append(column_change)

    # 混同行列ヒートマップ
    confusion_matrix_source = ColumnDataSource(data={})

    tooltips = [
        ('count', '@count'),
        ('label', '$y{0}'),
        ('pred', '$x{0}'),
    ]
    hm = figure(title="混同行列",
                tools="hover",
                toolbar_location=None,
                tooltips=tooltips)
    hm.y_range.flipped = True
    hm.visible = False
    visible_plots.append(hm)

    def cm_callback():
        global target_data
        cm = confusion_matrix(target_data[label_select.value],
                              target_data[pred_select.value])
        cm = pd.DataFrame(cm)
        cm = cm.stack().reset_index().rename(
            columns={
                'level_0': label_select.value,
                'level_1': pred_select.value,
                0: 'count'
            })
        confusion_matrix_source.data = cm
        mapper = LinearColorMapper(palette=Viridis256,
                                   low=cm['count'].min(),
                                   high=cm['count'].max())
        hm.rect(x=pred_select.value,
                y=label_select.value,
                source=confusion_matrix_source,
                width=1,
                height=1,
                line_color=None,
                fill_color=transform('count', mapper))
        hm.text(x=pred_select.value,
                y=label_select.value,
                text="count",
                text_font_style="bold",
                source=confusion_matrix_source,
                text_align="left",
                text_baseline="middle")

        color_bar = ColorBar(color_mapper=mapper, label_standoff=12)
        hm.add_layout(color_bar, 'right')

        hm.visible = True
        unvisible_other_plots(hm, visible_plots)

    def cm_click_callback(event):
        label = round(event.y)
        pred = round(event.x)
        data = target_data[(target_data[label_select.value] == label)
                           & (target_data[pred_select.value] == pred)]
        datatable_source.data = data

    hm.on_event(DoubleTap, cm_click_callback)

    # 混同行列作成実行ボタン
    cm_button = Button(label="混同行列作成", button_type="success")
    cm_button.on_event(ButtonClick, cm_callback)

    # 混同行列オペレーションエリア
    cm_operation_area = Column(label_select, pred_select, cm_button)

    return cm_operation_area, hm
    else:
        #If the number of stations deployed is max, display message
        print("Max number of stations reached")
#
#-----------------------------------------------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------------------------------------------




#-------------------------------This allows you to interact with the drone sim button to start the drone simulation-----------------------
#-----------------------------------------------------------------------------------------------------------------------------------------
#
def callbackSimRun(event):
    eventTrigger(coordList)
#
#-----------------------------------------------------------------------------------------------------------------------------------------
#-----------------------------------------------------------------------------------------------------------------------------------------




#These plot the new stations and the button to run the simulation
p.on_event(DoubleTap, callback)
button_widget.on_event(ButtonClick, callbackSimRun)

#This sets the layout of the plot
layout=Column(p,widgetbox(button_widget))

#This updates the plot to the server
curdoc().add_root(layout)
def modify_doc(doc):

    p1 = figure(plot_width=600, plot_height=500, title='Quantum Tunneling Animation')
    p1.xaxis.axis_label = 'position (Angstrom)'
    p1.yaxis.axis_label = 'Amplitude Squared (normalized)'
    p1.toolbar.logo = None
    p1.toolbar_location = None
    r11 = p1.line([], [], legend='Barrier', color=Colorblind[8][5], line_width=2)
    r12 = p1.line([], [], legend='Wavefunction', color=Colorblind[8][7], line_width=2)

    p2 = figure(plot_width=400, plot_height=250, title='Normalized wavefunctions at start')
    p2.xaxis.axis_label = 'position (Angstrom)'
    p2.yaxis.axis_label = 'Amplitude'
    p2.toolbar.logo = None
    p2.toolbar_location = None
    r21 = p2.line([], [], legend='Barrier', color=Colorblind[8][5])
    r22 = p2.line([], [], legend='Magnitude', color=Colorblind[8][7])
    r23 = p2.line([], [], legend='Real part', color=Colorblind[8][0])
    r24 = p2.line([], [], legend='Imag. part', color=Colorblind[8][6])
 
    p3 = figure(plot_width=400, plot_height=250, title='Normalized wavefunctions at end')
    p3.xaxis.axis_label = 'position (Angstrom)'
    p3.yaxis.axis_label = 'Amplitude'
    p3.toolbar.logo = None
    p3.toolbar_location = None
    r31 = p3.line([], [], color=Colorblind[8][5])
    r32 = p3.line([], [], color=Colorblind[8][7])
    r33 = p3.line([], [], color=Colorblind[8][0])
    r34 = p3.line([], [], color=Colorblind[8][6])

    barrier_height = Slider(title='Barrier Height (eV)', value=600, start=20, end=1000, step=100)
    barrier_width = Slider(title='Barrier Width (Angstrom)', value=0.3, start=0.3, end=1.0, step=0.1)
    electron_energy = Slider(title='Electron Energy (eV)', value=500, start=10, end=900, step=100)
    psi_spread = Slider(title='Wavefunction Spread (Angstrom)', value=0.8, start=0.3, end=1.0, step=0.1)
    startbutton = Button(label='Start', button_type='success')
    textdisp = Div(text='''<b>Note:</b> Wait for simulation  to stop before pressing buttons.''')
    texttitle = Div(text='''<b>QUANTUM TUNNELING</b>''', width=1000)
    textdesc = Div(text='''This application simulates quantum tunneling of an electron across a potential barrier 
                           by solving the Schrodinger's equation using the finite-difference time-domain method.
                           You can change the height and width of the barrier, as well as the energy and spread
                           of the electron to see how it would affect the probability of tunneling.''', width=1000)
    textrel = Div(text='''Learn more about quantum mechanics especially in the context of quantum computing in <b>ES 170</b>''', width=1000)

    def run_qt_sim(event):
    
        # Reset plots
        r21.data_source.data['x'] = []
        r22.data_source.data['x'] = []
        r23.data_source.data['x'] = []
        r24.data_source.data['x'] = []
        r21.data_source.data['y'] = []      
        r22.data_source.data['y'] = []
        r23.data_source.data['y'] = []
        r24.data_source.data['y'] = []
        r31.data_source.data['x'] = []
        r32.data_source.data['x'] = []
        r33.data_source.data['x'] = []
        r34.data_source.data['x'] = []
        r31.data_source.data['y'] = []
        r32.data_source.data['y'] = []
        r33.data_source.data['y'] = []
        r34.data_source.data['y'] = []

        # Get widget values
        V0 = barrier_height.value
        bw = barrier_width.value
        ke = electron_energy.value
        sig = psi_spread.value

        # Create Qtunnel object
        qt = Qtunnel(V0, bw, ke, sig)
        
        # Plot initial states
        r21.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r22.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r23.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r24.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r21.data_source.data['y'] = qt.Vx / np.amax(qt.Vx)
        r22.data_source.data['y'] = qt.psimag / np.amax(qt.psimaginit)
        r23.data_source.data['y'] = qt.psir / np.amax(qt.psirinit)
        r24.data_source.data['y'] = qt.psii / np.amax(qt.psiiinit) 
        r11.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r12.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r11.data_source.data['y'] = qt.Vx / np.amax(qt.Vx)

        for n in range(qt.tt):
            qt.fdtd_update()
            qt.update_plots(r12)


        # Plot final states
        r31.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r32.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r33.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r34.data_source.data['x'] = qt.lx / sc.value('Angstrom star')
        r31.data_source.data['y'] = qt.Vx / np.amax(qt.Vx)
        r32.data_source.data['y'] = qt.psimag / np.amax(qt.psimaginit)
        r33.data_source.data['y'] = qt.psir / np.amax(qt.psirinit)
        r34.data_source.data['y'] = qt.psii / np.amax(qt.psiiinit) 

    # Setup callbacks
    startbutton.on_event(ButtonClick, run_qt_sim)
    doc.add_root(column(texttitle, textdesc, row(barrier_height, barrier_width, textdisp), 
                 row(electron_energy, psi_spread, startbutton), row(p1, column(p2, p3)), textrel)) 
Exemple #14
0
class Module(pyl.Model):
    def startServer(self):
        print("Starting Server")
        self.session.loop_until_closed()  # run forever

    def callback(self, event):
        print("ASDF")
        self.moduleData["/outputs/keypress"] = ord('q')

    def initialise(self, simData):

        #self.server = threading.Thread(target=self.startServer)
        #self.server.start()
        #time.sleep(5)
        self.curdoc = curdoc()
        self.session = push_session(self.curdoc)

        data_points = 200

        time_step = simData["/simulation/time_step"]

        self.plot_time = deque()
        for i in range(data_points):
            self.plot_time.append((-data_points + i) * time_step)
        simData["/self/data_to_time"] = self.plot_time

        simData["/self/data_to_time"] = np.arange(data_points)

        for monitor in simData["/inputs/monitor"]:
            #simData["/self/data_to_plot/" + monitor] = deque()
            simData["/self/data_to_plot/" + monitor] = np.ones(data_points)
            #for i in range(data_points):
            #    simData["/self/data_to_plot/" + monitor].append(i)

        #for monitor in simData["/inputs/monitor"]:
        #    simData["/self/source"] = ColumnDataSource(data=dict(x=simData["/self/data_to_time"], y=simData["/self/data_to_plot/" + monitor]))

        simData["/self/update_plot"] = True
        simData["/self/updateRate"] = 0.001

        # Set up plot
        # self.plot = figure(plot_height=400, plot_width=400, title="my sine wave",
        #             tools="crosshair,pan,reset,save,wheel_zoom",
        #             #x_range=[0, 4*np.pi], y_range=[-2.5, 2.5])

        self.plot = []

        for monitor in simData["/inputs/monitor"]:
            self.plot.append(
                figure(plot_height=400,
                       plot_width=400,
                       title=monitor,
                       tools="crosshair,pan,reset,save,wheel_zoom"))
            #x_range=[0, 4*np.pi], y_range=[-2.5, 2.5])

        for idx, monitor in enumerate(simData["/inputs/monitor"]):
            simData["/self/line/" + monitor] = self.plot[idx].line(
                x=simData["/self/data_to_time"],
                y=simData["/self/data_to_plot/" + monitor],
                line_width=3,
                line_alpha=0.6)
            #simData["/self/line/" + monitor] = self.plot.line(x=[0], y=[0], line_width=3, line_alpha=0.6)
            #self.line = self.plot.line(x=simData["/self/data_to_time"], y=simData["/self/data_to_plot/" + monitor], line_width=3, line_alpha=0.6)

        self.button = Button()
        self.button.on_event(ButtonClick, self.callback)

        self.box = widgetbox(self.button)
        self.PlotLayout = layout(self.plot, self.box)
        self.session.show(self.PlotLayout)

        self.t = []

        self.y = {}
        for monitor in simData["/inputs/monitor"]:
            self.y[monitor] = []

    def execute(self, simData):

        debug("Executing my Model {} Iteration {}".format(
            self.name, simData["/simulation/iteration"]))

        iteration = simData["/simulation/iteration"]
        time_step = simData["/simulation/time_step"]

        self.t.append(iteration * time_step)
        for idx, monitor in enumerate(simData["/inputs/monitor"]):
            self.y[monitor].append(simData["/inputs/signal" + str(idx + 1)])

        if (iteration *
                time_step) % simData["/self/updateRate"] < time_step * 0.1:
            if (self.button.clicks != 0):
                print(self.button.clicks)
            if simData["/self/update_plot"]:
                for monitor in simData["/inputs/monitor"]:
                    #self.t = np.arange(len(self.y[monitor]))
                    simData["/self/line/" + monitor].data_source.stream(
                        {
                            'x': self.t,
                            'y': self.y[monitor]
                        }, 200)
                    self.y[monitor] = []
                self.session.force_roundtrip()
                self.t = []
def modify_doc(doc):

    p1 = figure(plot_width=500,
                plot_height=300,
                title='Histogram of Coin Toss Game simulation for Player 1',
                tools='',
                background_fill_color='#fafafa')
    r1 = p1.quad(top=[],
                 bottom=0,
                 left=[],
                 right=[],
                 fill_color="navy",
                 line_color="white",
                 alpha=0.5)
    lb1 = Label(x=120,
                y=120,
                x_units='screen',
                y_units='screen',
                text='',
                render_mode='css',
                background_fill_color='white',
                background_fill_alpha=0.5)
    lbwinloss1 = Label(x=200,
                       y=90,
                       x_units='screen',
                       y_units='screen',
                       text='',
                       render_mode='css',
                       background_fill_color='white',
                       background_fill_alpha=0.5)
    p1.y_range.start = 0
    p1.add_layout(lb1)
    p1.add_layout(lbwinloss1)
    p1.xaxis.axis_label = 'Number of tosses to reach endgame'
    p1.yaxis.axis_label = 'counts'
    p1.toolbar.logo = None
    p2 = figure(plot_width=500,
                plot_height=300,
                title='Histogram of Coin Toss Game simulation for Player 2',
                tools='',
                background_fill_color='#fafafa')
    r2 = p2.quad(top=[],
                 bottom=0,
                 left=[],
                 right=[],
                 fill_color="navy",
                 line_color="white",
                 alpha=0.5)
    lb2 = Label(x=120,
                y=120,
                x_units='screen',
                y_units='screen',
                text='',
                render_mode='css',
                background_fill_color='white',
                background_fill_alpha=0.5)
    lbwinloss2 = Label(x=200,
                       y=90,
                       x_units='screen',
                       y_units='screen',
                       text='',
                       render_mode='css',
                       background_fill_color='white',
                       background_fill_alpha=0.5)
    p2.y_range.start = 0
    p2.add_layout(lb2)
    p2.add_layout(lbwinloss2)
    p2.xaxis.axis_label = 'Number of tosses to reach endgame'
    p2.yaxis.axis_label = 'counts'
    p2.toolbar.logo = None
    number_of_games = Slider(title='Number of Games',
                             value=500,
                             start=1,
                             end=5000,
                             step=1)
    endgame1 = TextInput(value="HT", title='Player 1 Endgame:')
    endgame2 = TextInput(value="HH", title='Player 2 Endgame:')
    startbutton = Button(label='Start', button_type='success')
    texttitle = Div(
        text='''<b>BAYSIAN MIND: SIMULATING A COIN TOSSING GAME</b>''',
        width=1000)
    textdesc = Div(
        text=
        '''This app simulates a coin tossing game where two players pick a sequence of head/tail occurances. 
                   A coin is tossed until the chosen sequences occur and the game ends and the player who picked the 
                   endgame sequence that occurs first wins. So, the objective is to chose an endgame that will end the 
                   game with the least number of tosses. The app simulates a given number of coin toss games with the 
                   chosen endgame sequences. The average number of tosses required to win is computed and its distribution 
                   is plotted.''',
        width=1000)
    textrel = Div(
        text=
        '''Learn more about our Bayesian mind and how it affects technology, ethics, and society in <b>ES 28</b>''',
        width=1000)
    textdisp = Div(
        text=
        '''<b>Note: </b> Enter a sequence of Capital H's and T's to represent heads and tails, respectively. 
                   Please only enter Capitol H and T, entering any other letter will return an error and stop the app. Also, 
                   for a fair comparision the players should enter the same number of letters in their sequence''',
        width=600)

    def check_winner(c1, c2):
        if np.mean(c1.counter) < np.mean(c2.counter):
            lbwinloss1.text = 'You Win!'
            lbwinloss2.text = 'You lose!'
            lbwinloss1.text_color = 'green'
            lbwinloss2.text_color = 'red'
        else:
            lbwinloss1.text = 'You Lose!'
            lbwinloss2.text = 'You Win!'
            lbwinloss1.text_color = 'red'
            lbwinloss2.text_color = 'green'

    # Start the coin tossing game simulation
    def start_tossing(event):
        ng = number_of_games.value
        eg1 = endgame1.value
        eg2 = endgame2.value
        c1 = CoinToss(ng, eg1)
        c1.run()
        c1.plot_counts(r1, lb1)
        c2 = CoinToss(ng, eg2)
        c2.run()
        c2.plot_counts(r2, lb2)
        check_winner(c1, c2)

    # Setup callbacks
    startbutton.on_event(ButtonClick, start_tossing)
    # Setup layout and add to document

    doc.add_root(
        column(texttitle, textdesc, number_of_games, textdisp,
               row(endgame1, endgame2), startbutton, row(p1, p2), textrel))
Exemple #16
0
# Button definition and actions
def show_dataset(event):
    #    source_table.data = (data_to_fill)
    #    data_table.source.data = data_to_fill

    #update data
    update_dataset_lists(event)
    show_data_curves(event)


showDataBtn = Button(label='Show the Sample DataSet',
                     width=360,
                     height=50,
                     button_type="primary")
showDataBtn.on_event(ButtonClick, show_dataset)

# Add table
table_title = Div(text='The dataset is listed here: ')
table_output = widgetbox(table_title, data_table)

#Add all things in a row
param_inst_txt = Div(text='Specific all parameters here along with the dataset.'\
                     'Click on \'show dataset\' will reveal a subset of the sample data. ',
                     height = 50)
inputs = widgetbox(select, kernelSelect, datasetSelect, width=400)

data_table_top_right = widgetbox(data_table, showDataBtn, width=400)

# Add illustration on Optimization:
param_txt = Div(text='Specify Learning Task',
def modify_doc(doc):

    # Initializing arrays for plotting
    def InitPlotArrays():
        timepoints.fill(np.nan)
        poscar1.fill(np.nan)
        poscar1_est.fill(np.nan)
        poscar1_meas.fill(np.nan)
        poscar2.fill(np.nan)
        car_sep.fill(np.nan)
        car2_acc.fill(np.nan)
        poscar2_kf.fill(np.nan)
        car_sep_kf.fill(np.nan)
        car2_acc_kf.fill(np.nan)
        noiserange.fill(np.nan)
        pdf_proc.fill(np.nan)
        pdf_meas.fill(np.nan)

    # Setup plots
    InitPlotArrays()

    # Adding legends
    p1 = figure(plot_width=300,
                plot_height=120,
                x_range=[-0.5, 20],
                y_range=[-1, 5])
    colors = ['darkslategray', 'gold', 'crimson']
    p1.rect([0.2, 0.2, 0.2], [4, 2, 0],
            width=1,
            height=1,
            color=colors,
            width_units='data',
            height_units='data')
    label1 = Label(x=1,
                   y=3.3,
                   x_units='data',
                   y_units='data',
                   text='Leading Car')
    label2 = Label(x=1,
                   y=1.3,
                   x_units='data',
                   y_units='data',
                   text='Following Car')
    label3 = Label(x=1,
                   y=-0.7,
                   x_units='data',
                   y_units='data',
                   text='Following Car with Kalman Filter')
    p1.add_layout(label1)
    p1.add_layout(label2)
    p1.add_layout(label3)
    p1.yaxis.visible = False
    p1.ygrid.visible = False
    p1.xaxis.visible = False
    p1.xgrid.visible = False
    p1.toolbar.logo = None
    p1.toolbar_location = None

    # Figure 1
    p2 = figure(plot_width=400, plot_height=200, title='Noise Distributions')
    r21 = p2.line(noiserange,
                  pdf_proc,
                  line_color='seagreen',
                  line_width=4,
                  legend='Process')
    r22 = p2.line(noiserange,
                  pdf_meas,
                  line_color='greenyellow',
                  line_width=4,
                  legend='Measurement')
    p2.toolbar.logo = None
    p2.toolbar_location = None
    p2.legend.location = 'top_left'

    # Figure 2
    p3 = figure(plot_width=1000,
                plot_height=150,
                x_axis_label='position',
                title='Car Following Animation',
                x_range=[0, dist_size],
                y_range=[-0.4, 0.4])
    colors = ['darkslategray', 'gold', 'crimson']
    r31 = p3.rect(x=[car1_initpos, car2_initpos, car2_initpos],
                  y=[0.0, -0.2, 0.2],
                  width=car_size,
                  height=8,
                  color=colors,
                  width_units='data',
                  height_units='screen')
    r32 = p3.line(x=[car1_initpos - car_size / 2, car1_initpos - car_size / 2],
                  y=[-0.4, 0.4])
    r33 = p3.line(x=[
        car1_initpos + car_size / 2 - dist_sep,
        car1_initpos + car_size / 2 - dist_sep
    ],
                  y=[-0.4, 0.4])
    p3.yaxis.visible = False
    p3.ygrid.visible = False
    p3.toolbar.logo = None
    p3.toolbar_location = None

    # Figure 3
    p4 = figure(plot_width=500,
                plot_height=400,
                x_axis_label='time',
                y_axis_label='position',
                title='Car Positions',
                x_range=[0, timesteps * dt],
                y_range=[0, dist_size])
    r41 = p4.line(timepoints, poscar1, color='darkslategray', line_width=4)
    r42 = p4.line(timepoints,
                  poscar1_meas,
                  color='royalblue',
                  legend='Measured position',
                  line_width=4)
    r43 = p4.line(timepoints,
                  poscar1_est,
                  color='skyblue',
                  legend='KF estimated position',
                  line_width=4)
    r44 = p4.line(timepoints, poscar2, color='gold', line_width=4)
    r45 = p4.line(timepoints, poscar2_kf, color='crimson', line_width=4)
    p4.legend.location = 'bottom_right'
    p4.toolbar.logo = None
    p4.toolbar_location = None

    # Figure 4
    p5 = figure(plot_width=500,
                plot_height=200,
                x_axis_label='time',
                y_axis_label='separation',
                title='Car Separations',
                x_range=[0, timesteps * dt],
                y_range=[0, 3 * dist_sep])
    r51 = p5.line(timepoints, car_sep, color='gold', line_width=4)
    r52 = p5.line(timepoints, car_sep_kf, color='crimson', line_width=4)
    p5.toolbar.logo = None
    p5.toolbar_location = None

    # Figure 5
    p6 = figure(plot_width=500,
                plot_height=200,
                x_axis_label='time',
                y_axis_label='acceleration',
                title='Following Car Accelerations',
                x_range=[0, timesteps * dt],
                y_range=[-car2_maxbrake / 2, car2_maxacc])
    r61 = p6.line(timepoints, car2_acc, color='gold', line_width=4)
    r62 = p6.line(timepoints, car2_acc_kf, color='crimson', line_width=4)
    p6.toolbar.logo = None
    p6.toolbar_location = None

    # Setup widgets
    procnoise_slider = Slider(title='Process Noise',
                              value=0.0,
                              start=0.0,
                              end=1.5,
                              step=0.1)
    measnoise_slider = Slider(title='Measurement Noise',
                              value=0.0,
                              start=0.0,
                              end=1.5,
                              step=0.1)
    TextDisp = Div(
        text=
        '''<b>Note:</b> Wait for the plots to stop updating before hitting Start.'''
    )
    TextDesc = Div(
        text=
        '''This simulation shows how Kalman Filtering can be used to improve autonomous car following. 
                   The red car uses a Kalman filter to filter out noise inherent in the detection of the car in the front.
                   You can increase or decrease the noise level by dragging the sliders.
                   The yellow car uses the raw sensor data. Both cars aim to achieve a fixed separation between itself and
                   (vertical blue line in the Car Following Animation) the leading car. 
                   The plots below show car positions, separations, and accelarations.''',
        width=1000)
    textrel = Div(
        text=
        '''Learn more about this app works, Kalman filters, and their applications in <b>ES/AM 115</b> ''',
        width=1000)
    TextTitle = Div(
        text='''<b>KALMAN FILTER FOR AUTONOMOUS CAR FOLLOWING</b>''',
        width=1000)
    StartButton = Button(label='Start', button_type="success")

    #def RunCarFollowing(attr, old, new):
    def RunCarFollowing(event):
        # Get current widget values
        PN = procnoise_slider.value
        MN = measnoise_slider.value
        # Setup initial values
        InitPlotArrays()
        pos1real = car1_initpos
        pos2 = car2_initpos
        pos2_kf = car2_initpos
        vel2 = car2_initvel
        vel2_kf = car2_initvel
        acc2 = car2_initacc
        acc2_kf = car2_initacc
        tt = 0
        realt = 0

        # Update noise distributions
        nlim = max(PN, MN)
        global noiserange, pdf_proc, pdf_meas
        noiserange = np.linspace(-4 * nlim, 4 * nlim, timesteps)
        if PN == 0:
            pdf_proc = np.zeros(np.shape(noiserange))
        else:
            pdf_proc = 1 / (PN * np.sqrt(2 * np.pi)) * np.exp(-noiserange**2 /
                                                              (2 * PN**2))
        if MN == 0:
            pdf_meas = np.zeros(np.shape(noiserange))
        else:
            pdf_meas = 1 / (MN * np.sqrt(2 * np.pi)) * np.exp(-noiserange**2 /
                                                              (2 * MN**2))

        r21.data_source.data['x'] = noiserange
        r21.data_source.data['y'] = pdf_proc
        r22.data_source.data['x'] = noiserange
        r22.data_source.data['y'] = pdf_meas

        # Initialize Kalman Filter
        f = KalmanFilter(dim_x=2, dim_z=1)  # initialize Kalman filter object
        f.x = np.array([
            [car1_initpos],  # position
            [car1_vel]
        ])  # velocity
        f.F = np.array([
            [1.0, 1.0],  # state transition matrix
            [0.0, 1.0]
        ])
        f.H = np.array([[1.0, 0.0]])  # measurement function
        f.P = np.array([
            [1000.0, 0.0],  # apriori state covariance
            [0.0, 1000.0]
        ])
        f.R = np.array([[5.0]])  # measurement noise covariance
        # Process noise
        if PN == 0:
            f.Q = np.zeros([2, 2])
        else:
            f.Q = Q_discrete_white_noise(dim=2, dt=dt, var=PN**2)

        # Loop for updating positions
        for tt in range(timesteps):

            # Real position of leading car
            pos1real = pos1real + car1_vel * dt

            # Measurement of position of leading car with noise
            z = np.random.normal(pos1real, MN)

            # Kalman Filter predict and update steps
            f.predict(
            )  # predict next state using Kalman filter state propagation equation
            f.update(z)  # add new measurement (z) to the Kalman filter

            # Following car update without Kalman Filter
            dx = z - pos2
            err = (dx - dist_sep) / dist_sep
            if err > 1.0: err = 1.0
            # Acceleration model
            if err > 0:
                acc2 = err * car2_maxacc
            else:
                acc2 = err * car2_maxbrake
            vel2 = vel2 + acc2 * dt
            # crash protection
            if vel2 < 0:
                vel2 = 0
                acc2 = 0
            # update position
            pos2 = pos2 + vel2 * dt + 0.5 * acc2 * dt**2

            # Following car update with Kalman Filter
            dx_kf = f.x[0, 0] - pos2_kf
            err_kf = (dx_kf - dist_sep) / dist_sep
            if err_kf > 1.0: err_kf = 1.0
            # Acceleration model
            if err_kf > 0:
                acc2_kf = err_kf * car2_maxacc
            else:
                acc2_kf = err_kf * car2_maxbrake
            vel2_kf = vel2_kf + acc2_kf * dt
            # crash protection
            if vel2_kf < 0:
                vel2_kf = 0
                acc2_kf = 0
            # update position
            pos2_kf = pos2_kf + vel2_kf * dt + 0.5 * acc2_kf * dt**2

            # Update arrays for plotting
            global timepoints, poscar1, poscar2, poscar1_est, car_sep
            timepoints[tt] = tt * dt
            poscar1[tt] = pos1real
            poscar1_est[tt] = f.x[0, 0]
            poscar1_meas[tt] = z
            poscar2[tt] = pos2
            poscar2_kf[tt] = pos2_kf
            car_sep[tt] = pos1real - pos2
            car_sep_kf[tt] = pos1real - pos2_kf
            car2_acc[tt] = acc2
            car2_acc_kf[tt] = acc2_kf

            # Update plots (both cars)
            #first row
            r31.data_source.data['x'] = [pos1real, pos2, pos2_kf]
            r32.data_source.data['x'] = [
                pos1real - car_size / 2, pos1real - car_size / 2
            ]
            r33.data_source.data['x'] = [
                pos1real + car_size / 2 - dist_sep,
                pos1real + car_size / 2 - dist_sep
            ]
            #second row
            r41.data_source.data['x'] = timepoints
            r41.data_source.data['y'] = poscar1
            r42.data_source.data['x'] = timepoints
            r42.data_source.data['y'] = poscar1_meas
            r43.data_source.data['x'] = timepoints
            r43.data_source.data['y'] = poscar1_est
            r44.data_source.data['x'] = timepoints
            r44.data_source.data['y'] = poscar2
            r45.data_source.data['x'] = timepoints
            r45.data_source.data['y'] = poscar2_kf
            r51.data_source.data['x'] = timepoints
            r51.data_source.data['y'] = car_sep
            r52.data_source.data['x'] = timepoints
            r52.data_source.data['y'] = car_sep_kf
            r61.data_source.data['x'] = timepoints
            r61.data_source.data['y'] = car2_acc
            r62.data_source.data['x'] = timepoints
            r62.data_source.data['y'] = car2_acc_kf

            #             # Update plots (only car without KF)
            #             #first row
            #             r31.data_source.data['x'] = [pos1real, pos2, 0]
            #             r32.data_source.data['x'] = [pos1real - car_size / 2, pos1real - car_size / 2]
            #             r33.data_source.data['x'] = [pos1real + car_size / 2 - dist_sep, pos1real + car_size / 2 - dist_sep]
            #             #second row
            #             r41.data_source.data['x'] = timepoints
            #             r41.data_source.data['y'] = poscar1
            #             r42.data_source.data['x'] = timepoints
            #             r42.data_source.data['y'] = poscar1_meas
            #             r44.data_source.data['x'] = timepoints
            #             r44.data_source.data['y'] = poscar2
            #             r51.data_source.data['x'] = timepoints
            #             r51.data_source.data['y'] = car_sep
            #             r61.data_source.data['x'] = timepoints
            #             r61.data_source.data['y'] = car2_acc

            time.sleep(0.05)

    # Setup callbacks
    StartButton.on_event(ButtonClick, RunCarFollowing)
    # Setup layout and add to document
    wInputs = widgetbox(procnoise_slider, measnoise_slider, TextDisp,
                        StartButton)

    doc.add_root(
        column(TextTitle, TextDesc, row(p1, p2, wInputs), p3,
               row(p4, column(p5, p6)), textrel))
Exemple #18
0
# Neighbors Select
neighbors_select = df['State'].unique().tolist()
neighbors_select.append('Select value ...')
neighbors_select = Select(title='Neighboring States',
                          options=neighbors_select,
                          value='Select value ...')
neighbors_select.on_change('value', lambda attr, old, new: update())

# Download button
download_button_table1 = Button(label="Export as CSV", button_type="success")
download_button_table1.callback = CustomJS(
    args=dict(source=source),
    code=open('custom_js/download_states_overview.js').read())

reset_button_table1 = Button(label='Reset Table', button_type='primary')
reset_button_table1.on_event(ButtonClick, reset_overview_table)

# DataTable2 ================ #

# State Select
state_select = df2['State'].unique().tolist()
state_select.append('All')
state_select = Select(title='State', options=state_select, value='All')
state_select.on_change('value', lambda attr, old, new: update())

# Funding Select
funding_select = df2['FundingDescription'].unique().tolist()
funding_select.append('N/A')
funding_select.append('Select value ...')
funding_select = Select(title='Funding',
                        options=funding_select,
def modify_doc(doc):

    # Setup plots
    p1 = figure(plot_width=400,
                plot_height=300,
                x_axis_label='time',
                x_range=[0, timesteps * samplingtime],
                y_range=[-maxsetpoint, maxsetpoint],
                title='PID controller input and output')
    p2 = figure(plot_width=400,
                plot_height=300,
                x_axis_label='time',
                x_range=[0, timesteps * samplingtime],
                title='PID controller error')
    r1 = p1.line(timepoints,
                 setpoints,
                 line_color='cornflowerblue',
                 legend='input',
                 line_width=2)
    r2 = p1.line(timepoints,
                 outputs,
                 line_color='indianred',
                 legend='output',
                 line_width=2)
    r3 = p2.line(timepoints,
                 errors,
                 line_color='indigo',
                 legend='error',
                 line_width=2)
    p1.legend.location = 'top_left'
    p2.legend.location = 'top_left'

    # Setup widgets
    Kp = Slider(title='Kp', value=0.75, start=0.0, end=1.5, step=0.15)
    Ki = Slider(title='Ki', value=0.5, start=0.0, end=1.0, step=0.1)
    Kd = Slider(title='Kd', value=0.05, start=0.0, end=0.1, step=0.01)
    InputFunction = Select(title='Input Function',
                           value='step',
                           options=['noise', 'step', 'square', 'sine'])
    TextDisp = Div(
        text=
        '''<b>Note:</b> Wait for the plots to stop updating before hitting Start.'''
    )
    StartButton = Button(label='Start', button_type='success')

    def RunPID(event):
        # Get current widget values
        kp = Kp.value
        ki = Ki.value
        kd = Kd.value
        inputfunc = InputFunction.value
        # Create PID class object
        pid = PID(kp, ki, kd)
        pid.initialize()
        for nn in range(1, timesteps, 1):
            # Inputs
            if inputfunc == 'noise':
                # null input
                if nn > 30:
                    pid.setpoint = 0.5 * np.random.randn()
            if inputfunc == 'step':
                # step function
                if nn > 30:
                    pid.setpoint = maxsetpoint
            elif inputfunc == 'square':
                # square wave
                if nn > 30:
                    pid.setpoint = maxsetpoint * np.sign(
                        np.sin(4 * np.pi * (nn - 30) / timesteps))
            elif inputfunc == 'sine':
                # sine wave
                if nn > 30:
                    pid.setpoint = maxsetpoint * np.sin(4 * np.pi *
                                                        (nn - 30) / timesteps)
            # Outputs
            if nn > 30:
                pid.processval = pid.processval + (pid.controlvar - (1.0 / nn))
            pid.controlLoop()
            global outputs
            outputs[nn] = pid.processval
            global timepoints
            timepoints[nn] = nn * samplingtime
            global setpoints
            setpoints[nn] = pid.setpoint
            global errors
            errors[nn] = pid.error
            # Update plots
            r1.data_source.data['x'] = timepoints
            r1.data_source.data['y'] = setpoints
            r2.data_source.data['x'] = timepoints
            r2.data_source.data['y'] = outputs
            r3.data_source.data['x'] = timepoints
            r3.data_source.data['y'] = errors

    # Setup callbacks
    StartButton.on_event(ButtonClick, RunPID)

    # Setup layout and add to document
    wInputs = widgetbox(InputFunction, Kp, Ki, Kd, TextDisp, StartButton)

    doc.add_root(row(wInputs, p1, p2, width=1000))
Exemple #20
0
class BokehScript:
    def __init__(self, argv):

        args = docopt(__doc__, argv=argv)
        self._args = check_input(args)
        self._path = Path(args.get("<peaklist>"))
        self._data_path = args.get("<data>")
        self.read_config()
        self._peakipy_data = LoadData(
            self._path, self._data_path, dims=self.dims, verbose=True
        )
        # check dataframe is usable
        self.peakipy_data.check_data_frame()
        # make temporary paths
        self.make_temp_files()

        self.make_data_source()
        self.setup_radii_sliders()
        self.setup_save_buttons()
        self.setup_quit_button()
        self.setup_plot()

    def init(self, doc):
        """ initialise the bokeh app """

        doc.add_root(
            column(
                self.intro_div,
                row(column(self.p, self.doc_link), column(self.data_table, self.tabs)),
                sizing_mode="stretch_both",
            )
        )
        doc.title = "peakipy: Edit Fits"

    @property
    def args(self):
        return self._args

    @property
    def path(self):
        return self._path

    @property
    def data_path(self):
        return self._data_path

    @property
    def peakipy_data(self):
        return self._peakipy_data

    def make_temp_files(self):
        # Temp files
        self.TEMP_PATH = Path("tmp")
        self.TEMP_PATH.mkdir(parents=True, exist_ok=True)

        self.TEMP_OUT_CSV = self.TEMP_PATH / Path("tmp_out.csv")
        self.TEMP_INPUT_CSV = self.TEMP_PATH / Path("tmp.csv")

        self.TEMP_OUT_PLOT = self.TEMP_PATH / Path("plots")
        self.TEMP_OUT_PLOT.mkdir(parents=True, exist_ok=True)

    def make_data_source(self):
        # make datasource
        self.source = ColumnDataSource()
        self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)
        return self.source

    def read_config(self):
        #  read dims from config
        config_path = Path("peakipy.config")
        if config_path.exists():
            try:
                config = json.load(open(config_path))
                print(f"Using config file with --dims={config.get('--dims')}")
                dims = config.get("--dims", [0, 1, 2])
                self._dims = ",".join(str(i) for i in dims)
                self.thres = config.get("--thres")
            except json.decoder.JSONDecodeError:
                print(
                    Fore.RED
                    + "Your peakipy.config file is corrupted - maybe your JSON is not correct..."
                )
                print(Fore.RED + "Not using it.")
                self._dims = self.args.get("--dims")
                self.thres = False

        else:
            # get dim numbers from commandline
            self._dims = self.args.get("--dims")
            self.thres = False

        self.dims = [int(i) for i in self._dims.split(",")]

    def setup_radii_sliders(self):
        # configure sliders for setting radii
        self.slider_X_RADIUS = Slider(
            title="X_RADIUS - ppm",
            start=0.001,
            end=0.200,
            value=0.040,
            step=0.001,
            format="0[.]000",
        )
        self.slider_Y_RADIUS = Slider(
            title="Y_RADIUS - ppm",
            start=0.010,
            end=2.000,
            value=0.400,
            step=0.001,
            format="0[.]000",
        )

        self.slider_X_RADIUS.on_change(
            "value", lambda attr, old, new: self.slider_callback_x(attr, old, new)
        )
        self.slider_Y_RADIUS.on_change(
            "value", lambda attr, old, new: self.slider_callback_y(attr, old, new)
        )

    def setup_save_buttons(self):
        # save file
        self.savefilename = TextInput(
            title="Save file as (.csv)", placeholder="edited_peaks.csv"
        )
        self.button = Button(label="Save", button_type="success")
        self.button.on_event(ButtonClick, self.save_peaks)

    def setup_quit_button(self):
        # Quit button
        self.exit_button = Button(label="Quit", button_type="warning")
        self.exit_button.on_event(ButtonClick, self.exit_edit_peaks)

    def setup_plot(self):
        """" code to setup the bokeh plots """
        #  make bokeh figure
        tools = [
            "tap",
            "box_zoom",
            "lasso_select",
            "box_select",
            "wheel_zoom",
            "pan",
            "reset",
        ]
        self.p = figure(
            x_range=(self.peakipy_data.f2_ppm_0, self.peakipy_data.f2_ppm_1),
            y_range=(self.peakipy_data.f1_ppm_0, self.peakipy_data.f1_ppm_1),
            x_axis_label=f"{self.peakipy_data.f2_label} - ppm",
            y_axis_label=f"{self.peakipy_data.f1_label} - ppm",
            tools=tools,
            active_drag="pan",
            active_scroll="wheel_zoom",
            active_tap=None,
        )
        if not self.thres:
            self.thres = threshold_otsu(self.peakipy_data.data[0])
        self.contour_start = self.thres  # contour level start value
        self.contour_num = 20  # number of contour levels
        self.contour_factor = 1.20  # scaling factor between contour levels
        cl = self.contour_start * self.contour_factor ** np.arange(self.contour_num)
        if len(cl) > 1 and np.min(np.diff(cl)) <= 0.0:
            print(f"Setting contour levels to np.abs({cl})")
            cl = np.abs(cl)
        self.extent = (
            self.peakipy_data.f2_ppm_0,
            self.peakipy_data.f2_ppm_1,
            self.peakipy_data.f1_ppm_0,
            self.peakipy_data.f1_ppm_1,
        )
        self.spec_source = get_contour_data(
            self.peakipy_data.data[0], cl, extent=self.extent, cmap=viridis
        )
        #  negative contours
        self.spec_source_neg = get_contour_data(
            self.peakipy_data.data[0] * -1.0, cl, extent=self.extent, cmap=autumn
        )
        self.p.multi_line(
            xs="xs", ys="ys", line_color="line_color", source=self.spec_source
        )
        self.p.multi_line(
            xs="xs", ys="ys", line_color="line_color", source=self.spec_source_neg
        )
        # contour_num = Slider(title="contour number", value=20, start=1, end=50,step=1)
        # contour_start = Slider(title="contour start", value=100000, start=1000, end=10000000,step=1000)
        self.contour_start = TextInput(
            value="%.2e" % self.thres, title="Contour level:", width=100
        )
        # contour_factor = Slider(title="contour factor", value=1.20, start=1., end=2.,step=0.05)
        self.contour_start.on_change("value", self.update_contour)
        # for w in [contour_num,contour_start,contour_factor]:
        #    w.on_change("value",update_contour)

        #  plot mask outlines
        el = self.p.ellipse(
            x="X_PPM",
            y="Y_PPM",
            width="X_DIAMETER_PPM",
            height="Y_DIAMETER_PPM",
            source=self.source,
            fill_color="color",
            fill_alpha=0.1,
            line_dash="dotted",
            line_color="red",
        )

        self.p.add_tools(
            HoverTool(
                tooltips=[
                    ("Index", "$index"),
                    ("Assignment", "@ASS"),
                    ("CLUSTID", "@CLUSTID"),
                    ("RADII", "@X_RADIUS_PPM{0.000}, @Y_RADIUS_PPM{0.000}"),
                    (
                        f"{self.peakipy_data.f2_label},{self.peakipy_data.f1_label}",
                        "$x{0.000} ppm, $y{0.000} ppm",
                    ),
                ],
                mode="mouse",
                # add renderers
                renderers=[el],
            )
        )
        # p.toolbar.active_scroll = "auto"
        # draw border around spectrum area
        spec_border_x = [
            self.peakipy_data.f2_ppm_min,
            self.peakipy_data.f2_ppm_min,
            self.peakipy_data.f2_ppm_max,
            self.peakipy_data.f2_ppm_max,
            self.peakipy_data.f2_ppm_min,
        ]

        spec_border_y = [
            self.peakipy_data.f1_ppm_min,
            self.peakipy_data.f1_ppm_max,
            self.peakipy_data.f1_ppm_max,
            self.peakipy_data.f1_ppm_min,
            self.peakipy_data.f1_ppm_min,
        ]

        self.p.line(
            spec_border_x,
            spec_border_y,
            line_width=1,
            line_color="black",
            line_dash="dotted",
            line_alpha=0.5,
        )
        self.p.circle(x="X_PPM", y="Y_PPM", source=self.source, color="color")
        # plot cluster numbers
        self.p.text(
            x="X_PPM",
            y="Y_PPM",
            text="CLUSTID",
            text_color="color",
            source=self.source,
            text_font_size="8pt",
            text_font_style="bold",
        )

        self.p.on_event(DoubleTap, self.peak_pick_callback)

        self.pos_neg_contour_dic = {0: "pos/neg", 1: "pos", 2: "neg"}
        self.pos_neg_contour_radiobutton = RadioButtonGroup(
            labels=[
                self.pos_neg_contour_dic[i] for i in self.pos_neg_contour_dic.keys()
            ],
            active=0,
        )
        self.pos_neg_contour_radiobutton.on_change("active", self.update_contour)
        # call fit_peaks
        self.fit_button = Button(label="Fit selected cluster", button_type="primary")
        # lineshape selection
        self.lineshapes = {
            0: "PV",
            1: "V",
            2: "G",
            3: "L",
            4: "PV_PV",
            # 5: "PV_L",
            # 6: "PV_G",
            # 7: "G_L",
        }
        self.radio_button_group = RadioButtonGroup(
            labels=[self.lineshapes[i] for i in self.lineshapes.keys()], active=0
        )
        self.ls_div = Div(
            text="""Choose lineshape you wish to fit. This can be Voigt (V), pseudo-Voigt (PV), Gaussian (G), Lorentzian (L).
            PV_PV fits a PV lineshape with independent "fraction" parameters for the direct and indirect dimensions"""
        )
        self.clust_div = Div(
            text="""If you want to adjust how the peaks are automatically clustered then try changing the
                width/diameter/height (integer values) of the structuring element used during the binary dilation step
                (you can also remove it by selecting 'None'). Increasing the size of the structuring element will cause
                peaks to be more readily incorporated into clusters. Be sure to save your peak list before doing this as
                any manual edits will be lost."""
        )
        self.intro_div = Div(
            text="""<h2>peakipy - interactive fit adjustment </h2> 
            """
        )

        self.doc_link = Div(
            text="<h3><a href='https://j-brady.github.io/peakipy/build/usage/instructions.html', target='_blank'> ℹ️ click here for documentation</a></h3>"
        )
        self.fit_reports = ""
        self.fit_reports_div = Div(text="", height=400, style={"overflow": "scroll"})
        # Plane selection
        self.select_planes_list = [
            f"{i}"
            for i in range(self.peakipy_data.data.shape[self.peakipy_data.planes])
        ]
        self.select_plane = Select(
            title="Select plane:",
            value=self.select_planes_list[0],
            options=self.select_planes_list,
        )
        self.select_planes_dic = {
            f"{i}": i
            for i in range(self.peakipy_data.data.shape[self.peakipy_data.planes])
        }
        self.select_plane.on_change("value", self.update_contour)

        self.checkbox_group = CheckboxGroup(
            labels=["fit current plane only"], active=[]
        )

        #  not sure this is needed
        selected_df = self.peakipy_data.df.copy()

        self.fit_button.on_event(ButtonClick, self.fit_selected)

        columns = [
            TableColumn(field="ASS", title="Assignment"),
            TableColumn(field="CLUSTID", title="Cluster", editor=IntEditor()),
            TableColumn(
                field="X_PPM",
                title=f"{self.peakipy_data.f2_label}",
                editor=NumberEditor(step=0.0001),
                formatter=NumberFormatter(format="0.0000"),
            ),
            TableColumn(
                field="Y_PPM",
                title=f"{self.peakipy_data.f1_label}",
                editor=NumberEditor(step=0.0001),
                formatter=NumberFormatter(format="0.0000"),
            ),
            TableColumn(
                field="X_RADIUS_PPM",
                title=f"{self.peakipy_data.f2_label} radius (ppm)",
                editor=NumberEditor(step=0.0001),
                formatter=NumberFormatter(format="0.0000"),
            ),
            TableColumn(
                field="Y_RADIUS_PPM",
                title=f"{self.peakipy_data.f1_label} radius (ppm)",
                editor=NumberEditor(step=0.0001),
                formatter=NumberFormatter(format="0.0000"),
            ),
            TableColumn(
                field="XW_HZ",
                title=f"{self.peakipy_data.f2_label} LW (Hz)",
                editor=NumberEditor(step=0.01),
                formatter=NumberFormatter(format="0.00"),
            ),
            TableColumn(
                field="YW_HZ",
                title=f"{self.peakipy_data.f1_label} LW (Hz)",
                editor=NumberEditor(step=0.01),
                formatter=NumberFormatter(format="0.00"),
            ),
            TableColumn(
                field="VOL", title="Volume", formatter=NumberFormatter(format="0.0")
            ),
            TableColumn(
                field="include",
                title="Include",
                editor=SelectEditor(options=["yes", "no"]),
            ),
            TableColumn(field="MEMCNT", title="MEMCNT", editor=IntEditor()),
        ]

        self.data_table = DataTable(
            source=self.source, columns=columns, editable=True, fit_columns=True
        )

        # callback for adding
        # source.selected.on_change('indices', callback)
        self.source.selected.on_change("indices", self.select_callback)

        # Document layout
        fitting_controls = column(
            row(
                column(self.slider_X_RADIUS, self.slider_Y_RADIUS),
                column(
                    row(
                        widgetbox(self.contour_start, self.pos_neg_contour_radiobutton)
                    ),
                    widgetbox(self.fit_button),
                ),
            ),
            row(
                column(widgetbox(self.ls_div), widgetbox(self.radio_button_group)),
                column(widgetbox(self.select_plane), widgetbox(self.checkbox_group)),
            ),
        )

        # reclustering tab
        self.struct_el = Select(
            title="Structuring element:",
            value="disk",
            options=["square", "disk", "rectangle", "None", "mask_method"],
            width=100,
        )
        self.struct_el_size = TextInput(
            value="3",
            title="Size(width/radius or width,height for rectangle):",
            width=100,
        )

        self.recluster = Button(label="Re-cluster", button_type="warning")
        self.recluster.on_event(ButtonClick, self.recluster_peaks)

        # edit_fits tabs
        fitting_layout = fitting_controls
        log_layout = self.fit_reports_div
        recluster_layout = row(
            self.clust_div,
            column(
                self.contour_start, self.struct_el, self.struct_el_size, self.recluster
            ),
        )
        save_layout = column(self.savefilename, self.button, self.exit_button)

        fitting_tab = Panel(child=fitting_layout, title="Peak fitting")
        log_tab = Panel(child=log_layout, title="Log")
        recluster_tab = Panel(child=recluster_layout, title="Re-cluster peaks")
        save_tab = Panel(child=save_layout, title="Save edited peaklist")
        self.tabs = Tabs(
            tabs=[fitting_tab, log_tab, recluster_tab, save_tab],
            sizing_mode="scale_both",
        )

    def recluster_peaks(self, event):

        if self.struct_el.value == "mask_method":
            self.struc_size = tuple(
                [float(i) for i in self.struct_el_size.value.split(",")]
            )
            print(self.struc_size)
            self.peakipy_data.mask_method(overlap=self.struc_size[0])
        else:
            self.struc_size = tuple(
                [int(i) for i in self.struct_el_size.value.split(",")]
            )
            print(self.struc_size)
            self.peakipy_data.clusters(
                thres=eval(self.contour_start.value),
                struc_el=self.struct_el.value,
                struc_size=self.struc_size,
            )
        # update data source
        self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)

        return self.peakipy_data.df

    def update_memcnt(self):

        for ind, group in self.peakipy_data.df.groupby("CLUSTID"):
            self.peakipy_data.df.loc[group.index, "MEMCNT"] = len(group)

        # set cluster colors (set to black if singlet peaks)
        self.peakipy_data.df["color"] = self.peakipy_data.df.apply(
            lambda x: Category20[20][int(x.CLUSTID) % 20] if x.MEMCNT > 1 else "black",
            axis=1,
        )
        # change color of excluded peaks
        include_no = self.peakipy_data.df.include == "no"
        self.peakipy_data.df.loc[include_no, "color"] = "ghostwhite"
        # update source data
        self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)
        return self.peakipy_data.df

    def fit_selected(self, event):

        selectionIndex = self.source.selected.indices
        current = self.peakipy_data.df.iloc[selectionIndex]

        self.peakipy_data.df.loc[
            selectionIndex, "X_RADIUS_PPM"
        ] = self.slider_X_RADIUS.value
        self.peakipy_data.df.loc[
            selectionIndex, "Y_RADIUS_PPM"
        ] = self.slider_Y_RADIUS.value

        self.peakipy_data.df.loc[selectionIndex, "X_DIAMETER_PPM"] = (
            current["X_RADIUS_PPM"] * 2.0
        )
        self.peakipy_data.df.loc[selectionIndex, "Y_DIAMETER_PPM"] = (
            current["Y_RADIUS_PPM"] * 2.0
        )

        selected_df = self.peakipy_data.df[
            self.peakipy_data.df.CLUSTID.isin(list(current.CLUSTID))
        ]

        selected_df.to_csv(self.TEMP_INPUT_CSV)

        lineshape = self.lineshapes[self.radio_button_group.active]
        if self.checkbox_group.active == []:
            print(Fore.YELLOW + "Using LS = ", lineshape)
            fit_command = f"peakipy fit {self.TEMP_INPUT_CSV} {self.data_path} {self.TEMP_OUT_CSV} --lineshape={lineshape} --dims={self._dims}"
            plot_command = f"peakipy check {self.TEMP_OUT_CSV} {self.data_path} -l -i -s --outname={self.TEMP_OUT_PLOT / Path('tmp.pdf')}"
        else:
            plane_index = self.select_plane.value
            print(Fore.YELLOW + "Using LS = ", lineshape)
            print(Fore.YELLOW + f"Only fitting plane {plane_index}")
            fit_command = f"peakipy fit {self.TEMP_INPUT_CSV} {self.data_path} {self.TEMP_OUT_CSV} --lineshape={lineshape} --dims={self._dims} --plane={plane_index}"
            plot_command = f"peakipy check {self.TEMP_OUT_CSV} {self.data_path} -l -i -s --outname={self.TEMP_OUT_PLOT / Path('tmp.pdf')} --plane={plane_index}"

        print(Fore.BLUE + fit_command)
        self.fit_reports += fit_command + "<br>"

        stdout = check_output(fit_command.split(" "))
        self.fit_reports += stdout.decode() + "<br><hr><br>"
        self.fit_reports = self.fit_reports.replace("\n", "<br>")
        self.fit_reports_div.text = log_div % (log_style, self.fit_reports)
        # plot data
        os.system(plot_command)

    def save_peaks(self, event):

        if self.savefilename.value:
            to_save = Path(self.savefilename.value)
        else:
            to_save = Path(self.savefilename.placeholder)

        if to_save.exists():
            shutil.copy(f"{to_save}", f"{to_save}.bak")
            print(f"Making backup {to_save}.bak")

        print(Fore.GREEN + f"Saving peaks to {to_save}")
        if to_save.suffix == ".csv":
            self.peakipy_data.df.to_csv(to_save, float_format="%.4f", index=False)
        else:
            self.peakipy_data.df.to_pickle(to_save)

    def select_callback(self, attrname, old, new):
        # print(Fore.RED + "Calling Select Callback")
        # selectionIndex = self.source.selected.indices
        # current = self.peakipy_data.df.iloc[selectionIndex]

        for col in self.peakipy_data.df.columns:
            self.peakipy_data.df.loc[:, col] = self.source.data[col]
        # self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)
        # update memcnt
        self.update_memcnt()
        # print(Fore.YELLOW + "Finished Calling Select Callback")

    def peak_pick_callback(self, event):
        # global so that df is updated globally
        x_radius_ppm = 0.035
        y_radius_ppm = 0.35
        x_radius = x_radius_ppm * self.peakipy_data.pt_per_ppm_f2
        y_radius = y_radius_ppm * self.peakipy_data.pt_per_ppm_f1
        x_diameter_ppm = x_radius_ppm * 2.0
        y_diameter_ppm = y_radius_ppm * 2.0
        clustid = self.peakipy_data.df.CLUSTID.max() + 1
        index = self.peakipy_data.df.INDEX.max() + 1
        x_ppm = event.x
        y_ppm = event.y
        x_axis = self.peakipy_data.uc_f2.f(x_ppm, "ppm")
        y_axis = self.peakipy_data.uc_f1.f(y_ppm, "ppm")
        xw_hz = 20.0
        yw_hz = 20.0
        xw = xw_hz * self.peakipy_data.pt_per_hz_f2
        yw = yw_hz * self.peakipy_data.pt_per_hz_f1
        assignment = f"test_peak_{index}_{clustid}"
        height = self.peakipy_data.data[0][int(y_axis), int(x_axis)]
        volume = height
        print(
            Fore.BLUE + f"""Adding peak at {assignment}: {event.x:.3f},{event.y:.3f}"""
        )

        new_peak = {
            "INDEX": index,
            "X_PPM": x_ppm,
            "Y_PPM": y_ppm,
            "HEIGHT": height,
            "VOL": volume,
            "XW_HZ": xw_hz,
            "YW_HZ": yw_hz,
            "X_AXIS": int(np.floor(x_axis)),  # integers
            "Y_AXIS": int(np.floor(y_axis)),  # integers
            "X_AXISf": x_axis,
            "Y_AXISf": y_axis,
            "XW": xw,
            "YW": yw,
            "ASS": assignment,
            "X_RADIUS_PPM": x_radius_ppm,
            "Y_RADIUS_PPM": y_radius_ppm,
            "X_RADIUS": x_radius,
            "Y_RADIUS": y_radius,
            "CLUSTID": clustid,
            "MEMCNT": 1,
            "X_DIAMETER_PPM": x_diameter_ppm,
            "Y_DIAMETER_PPM": y_diameter_ppm,
            "Edited": True,
            "include": "yes",
            "color": "black",
        }
        self.peakipy_data.df = self.peakipy_data.df.append(new_peak, ignore_index=True)
        self.update_memcnt()

    def slider_callback_x(self, attrname, old, new):

        selectionIndex = self.source.selected.indices
        current = self.peakipy_data.df.iloc[selectionIndex]
        self.peakipy_data.df.loc[selectionIndex, "X_RADIUS"] = (
            self.slider_X_RADIUS.value * self.peakipy_data.pt_per_ppm_f2
        )
        self.peakipy_data.df.loc[
            selectionIndex, "X_RADIUS_PPM"
        ] = self.slider_X_RADIUS.value

        self.peakipy_data.df.loc[selectionIndex, "X_DIAMETER_PPM"] = (
            current["X_RADIUS_PPM"] * 2.0
        )
        self.peakipy_data.df.loc[selectionIndex, "X_DIAMETER"] = (
            current["X_RADIUS"] * 2.0
        )

        # set edited rows to True
        self.peakipy_data.df.loc[selectionIndex, "Edited"] = True

        self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)

    def slider_callback_y(self, attrname, old, new):

        selectionIndex = self.source.selected.indices
        current = self.peakipy_data.df.iloc[selectionIndex]
        self.peakipy_data.df.loc[selectionIndex, "Y_RADIUS"] = (
            self.slider_Y_RADIUS.value * self.peakipy_data.pt_per_ppm_f1
        )
        self.peakipy_data.df.loc[
            selectionIndex, "Y_RADIUS_PPM"
        ] = self.slider_Y_RADIUS.value

        self.peakipy_data.df.loc[selectionIndex, "Y_DIAMETER_PPM"] = (
            current["Y_RADIUS_PPM"] * 2.0
        )
        self.peakipy_data.df.loc[selectionIndex, "Y_DIAMETER"] = (
            current["Y_RADIUS"] * 2.0
        )

        # set edited rows to True
        self.peakipy_data.df.loc[selectionIndex, "Edited"] = True

        self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)

    # def slider_callback(self, attrname, old, new, dim="X"):
    #
    #     selectionIndex = self.source.selected.indices
    #     current = self.peakipy_data.df.iloc[selectionIndex]
    #     self.peakipy_data.df.loc[selectionIndex, f"{dim}_RADIUS"] = (
    #             self.slider_Y_RADIUS.value * self.peakipy_data.pt_per_ppm_f1
    #     )
    #     self.peakipy_data.df.loc[
    #         selectionIndex, f"{dim}_RADIUS_PPM"
    #     ] = self.slider_Y_RADIUS.value
    #
    #     self.peakipy_data.df.loc[selectionIndex, f"{dim}_DIAMETER_PPM"] = (
    #             current[f"{dim}_RADIUS_PPM"] * 2.0
    #     )
    #     self.peakipy_data.df.loc[selectionIndex, f"{dim}_DIAMETER"] = (
    #             current[f"{dim}_RADIUS"] * 2.0
    #     )
    #
    #     set edited rows to True
    #     self.peakipy_data.df.loc[selectionIndex, "Edited"] = True

    # selected_df = df[df.CLUSTID.isin(list(current.CLUSTID))]
    # print(list(selected_df))
    # self.source.data = ColumnDataSource.from_df(self.peakipy_data.df)

    # def slider_callback_x(self, attrname, old, new):
    #
    #     self.slider_callback(attrname, old, new, dim="X")
    #
    # def slider_callback_y(self, attrname, old, new):
    #
    #     self.slider_callback(attrname, old, new, dim="Y")

    def update_contour(self, attrname, old, new):

        new_cs = eval(self.contour_start.value)
        cl = new_cs * self.contour_factor ** np.arange(self.contour_num)
        if len(cl) > 1 and np.min(np.diff(cl)) <= 0.0:
            print(f"Setting contour levels to np.abs({cl})")
            cl = np.abs(cl)
        plane_index = self.select_planes_dic[self.select_plane.value]

        pos_neg = self.pos_neg_contour_dic[self.pos_neg_contour_radiobutton.active]
        if pos_neg == "pos/neg":
            self.spec_source.data = get_contour_data(
                self.peakipy_data.data[plane_index],
                cl,
                extent=self.extent,
                cmap=viridis,
            ).data
            self.spec_source_neg.data = get_contour_data(
                self.peakipy_data.data[plane_index] * -1.0,
                cl,
                extent=self.extent,
                cmap=autumn,
            ).data

        elif pos_neg == "pos":
            self.spec_source.data = get_contour_data(
                self.peakipy_data.data[plane_index],
                cl,
                extent=self.extent,
                cmap=viridis,
            ).data
            self.spec_source_neg.data = get_contour_data(
                self.peakipy_data.data[plane_index] * 0.0,
                cl,
                extent=self.extent,
                cmap=autumn,
            ).data

        elif pos_neg == "neg":
            self.spec_source.data = get_contour_data(
                self.peakipy_data.data[plane_index] * 0.0,
                cl,
                extent=self.extent,
                cmap=viridis,
            ).data
            self.spec_source_neg.data = get_contour_data(
                self.peakipy_data.data[plane_index] * -1.0,
                cl,
                extent=self.extent,
                cmap=autumn,
            ).data

        # print("Value of checkbox",checkbox_group.active)

    def exit_edit_peaks(self, event):
        sys.exit()