Example #1
0
def spectroscopy_plot(source_id):
    """TODO normalization? should this be handled at data ingestion or plot-time?"""
    source = Source.query.get(source_id)
    spectra = Source.query.get(source_id).spectra
    if len(spectra) == 0:
        return None, None, None

    color_map = dict(zip([s.id for s in spectra], viridis(len(spectra))))
    data = pd.concat(
        [pd.DataFrame({'wavelength': s.wavelengths,
                       'flux': s.fluxes, 'id': s.id,
                       'instrument': s.instrument.telescope.nickname})
         for i, s in enumerate(spectra)]
    )
    split = data.groupby('id')
    hover = HoverTool(tooltips=[('wavelength', '$x'), ('flux', '$y'),
                                ('instrument', '@instrument')])
    plot = figure(plot_width=600, plot_height=300, sizing_mode='scale_both',
                  tools='box_zoom,wheel_zoom,pan,reset',
                  active_drag='box_zoom')
    plot.add_tools(hover)
    model_dict = {}
    for i, (key, df) in enumerate(split):
        model_dict['s' + str(i)] = plot.line(x='wavelength', y='flux',
                                             color=color_map[key],
                                             source=ColumnDataSource(df))
    plot.xaxis.axis_label = 'Wavelength (Å)'
    plot.yaxis.axis_label = 'Flux'
    plot.toolbar.logo = None

    # TODO how to choose a good default?
    plot.y_range = Range1d(0, 1.03 * data.flux.max())

    toggle = CheckboxWithLegendGroup(labels=[s.instrument.telescope.nickname
                                             for s in spectra],
                                     active=list(range(len(spectra))),
                                     width=100,
                                     colors=[color_map[k] for k, df in split])
    toggle.callback = CustomJS(args={'toggle': toggle, **model_dict},
                               code="""
          for (let i = 0; i < toggle.labels.length; i++) {
              eval("s" + i).visible = (toggle.active.includes(i))
          }
    """)

    elements = CheckboxWithLegendGroup(
        labels=list(SPEC_LINES.keys()),
        active=[], width=80,
        colors=[c for w, c in SPEC_LINES.values()]
    )
    z = TextInput(value=str(source.redshift), title="z:")
    v_exp = TextInput(value='0', title="v_exp:")
    for i, (wavelengths, color) in enumerate(SPEC_LINES.values()):
        el_data = pd.DataFrame({'wavelength': wavelengths})
        el_data['x'] = el_data['wavelength'] * (1 + source.redshift)
        model_dict[f'el{i}'] = plot.segment(x0='x', x1='x',
                                            # TODO change limits
                                            y0=0, y1=1e-13, color=color,
                                            source=ColumnDataSource(el_data))
        model_dict[f'el{i}'].visible = False

    # TODO callback policy: don't require submit for text changes?
    elements.callback = CustomJS(args={'elements': elements, 'z': z,
                                       'v_exp': v_exp, **model_dict},
                                 code="""
          let c = 299792.458; // speed of light in km / s
          for (let i = 0; i < elements.labels.length; i++) {
              let el = eval("el" + i);
              el.visible = (elements.active.includes(i))
              el.data_source.data.x = el.data_source.data.wavelength.map(
                  x_i => (x_i * (1 + parseFloat(z.value)) /
                                (1 + parseFloat(v_exp.value) / c))
              );
              el.data_source.change.emit();
          }
    """)
    z.callback = elements.callback
    v_exp.callback = elements.callback

    layout = row(plot, toggle, elements, column(z, v_exp))
    return _plot_to_json(layout)
Example #2
0
in_model_rdn_btn.callback = CustomJS(
    args=dict(radioButton=in_model_rdn_btn),
    code=bgui_js_handlers.in_model_rdn_btn_callback_code)
in_model_rdn_btn.on_change("active", selected_model_changed)
in_min_time = ColumnDataSource(data=dict(val=[MIN_LP_TIME]))
in_time_slider = Slider(start=MIN_LP_TIME,
                        end=MAX_LP_TIME,
                        value=10,
                        step=1,
                        title="Set the time for calculation [hrs]")
in_capacity_txt = TextInput(value="100", title="Set the capacity:")
in_capacity_txt.callback = CustomJS(
    args={
        'min_time': in_min_time,
        'time': in_time_slider,
        'radioButton': in_model_rdn_btn
    },
    code=bgui_js_handlers.in_capacity_txt_callback_code)
calculation_button = Button(label='Calculate', button_type="success")
upl_file_souce = ColumnDataSource({'file_contents': [], 'file_name': []})
upl_file_souce.on_change('data', upl_file_callback)
upload_btn = Button(label="Upload", button_type="default")
upload_btn.callback = CustomJS(args=dict(file_source=upl_file_souce),
                               code=bgui_js_handlers.upload_btn_callback_code)

################### RESULTS - bokeh models #######################
BED_fig = figure(x_range=(0, 1151),
                 y_range=(0, 2049),
                 plot_width=750,
                 plot_height=36 * NUM_PATIENTS)  #toolbar_location="above"