err = np.zeros([num_trials, 1], dtype='float') Sn = np.zeros([N, num_dim, num_trials], dtype='float') #P_new(idx,:), iter(idx,:), err(idx,:)]= calc_3d_tdoa_position(Sn(:,:, idx), Po, v) for idx in range(0, num_trials): Sn[:, :, idx] = S + np.random.normal(0, range_err, size=(N, num_dim)) Tn = T + np.random.normal(0, time_err, size=(N)) P_new[idx], iter[idx], err[idx] = calc_tdoa_position(Sn[:, :, idx], Tn, Po, v) # get the center/means in each direction cp = np.mean(P_new, axis=0) r_x, r_y, aou = calc_covariance_matrix(P_new, cp, num_trials) # results_div.text = tdoa_results + str(aou) + "</font>" aou_text.value = "{:.6f}".format(aou) # st_source.data = dict(sx=Sn[:, 0, :].reshape(-1), sy=Sn[:, 1, :].reshape(-1)) etx_source.data = dict(x=P_new[:, 0]*1, y=P_new[:, 1]*1) ctx_source.data = dict(x=[cp[0]*1], y=[cp[1]*1]) ell_source.data = dict(x=r_x*1, y=r_y*1) # setup the event callbacks for the plot st_source.js_on_change('patching', update_plot_callback) ig_source.js_on_change('patching', update_plot_callback) tx_source.js_on_change('patching', update_plot_callback) p_err_spin.js_on_change('value', update_plot_callback) t_err_spin.js_on_change('value', update_plot_callback) # p_err_spin.on_change('value', update_plot)
def doc_maker(): ''' make the whole document ''' global spt_data, custom_path curdoc().clear() # removes everything in the current document # dropdown to select a spectrum select_spectrum = Select(title="Select a spectrum:", value='', options=[''] + sorted(os.listdir(spec_path)), name="select_spectrum", width=200) # textinput to give the full path to the location of spectra path_input = TextInput(title='Spectra folder', width=200, name="path_input") path_input.on_change('value', update_spec_path) # button to load the spectrum selected in the 'select_spectrum' dropdown load_button = Button(label='Load spectrum', width=200, css_classes=["custom_button"]) load_button.on_click(load_spectrum) if spt_data == {}: curdoc().add_root(widgetbox(path_input, select_spectrum, load_button)) if custom_path: path_input.value = custom_path else: path_input.value = spec_path return spectrum = spt_data['cur_spec'] header = spt_data[spectrum]['header'] species = np.array([spt_data[spectrum]['columns'][var] for var in header]) SZA = str(spt_data[spectrum]['sza']) zobs = str(spt_data[spectrum]['zobs']) freq = species[0] # the frequency list tm = species[1] # measured transmittance list tc = species[2] # calculated transmittance list cont = species[3] # continuum not_gas = 4 # number of column that are not retrieved species residuals = spt_data[spectrum]['resid'] # 100*(calculated - measured) sigma_rms = spt_data[spectrum]['rms_resid'] # sqrt(mean(residuals**2)) # spectrum figure fig = figure(name="spec_fig", title=spectrum + '; SZA=' + SZA + '; zobs=' + zobs + 'km; %resid=100*(Measured-Calculated); RMSresid=' + ('%.4f' % sigma_rms) + '%', plot_width=1000, plot_height=400, tools=TOOLS, y_range=Range1d(-0.04, 1.04), outline_line_alpha=0, active_inspect="crosshair", active_drag="box_zoom") # residual figure fig_resid = figure(name="resid_fig", plot_width=1000, plot_height=150, x_range=fig.x_range, tools=TOOLS, y_range=Range1d(-3, 3), outline_line_alpha=0, active_inspect="crosshair", active_drag="box_zoom") # axes labels fig_resid.xaxis.axis_label = u'Wavenumber (cm\u207B\u00B9)' fig_resid.yaxis.axis_label = '% Residuals' fig.yaxis.axis_label = 'Transmittance' #fig.xaxis.axis_label = u'Wavenumber (cm\u207B\u00B9)' for elem in [fig, fig_resid]: elem.yaxis.axis_label_text_font_size = "14pt" elem.yaxis.major_label_text_font_size = "13pt" elem.xaxis.axis_label_text_font_size = "14pt" elem.xaxis.major_label_text_font_size = "13pt" N_plots = list( range(len(species) - 2) ) # a range list from 0 to the number of plots, used by the checkbox group # group of checkboxes that will be used to toggle line and HoverTool visibility checkbox = CheckboxGroup(labels=header[3:] + ['Measured', 'Calculated'], active=N_plots, width=200) # plotting species lines plots = [] for j in range(len(species) - not_gas): try: plots.append( fig.line(x=freq, y=species[j + not_gas], color=colors[header[j + not_gas]], line_width=2, name=header[j + not_gas])) except KeyError: print( 'KeyError:', header[j + not_gas], 'is not specified in the "colors" dictionary, you need to add it with an associated color' ) sys.exit() # each line has a associated hovertool with a callback that looks at the checkboxes status for the tool visibility. fig.add_tools( HoverTool(mode='vline', line_policy='prev', renderers=[plots[j]], names=[header[j + not_gas]], tooltips=OrderedDict([('name', header[j + not_gas]), ('index', '$index'), ('(x;y)', '(@x{0.00} ; @y{0.000})') ]))) # adding the measured spectrum plots.append(fig.line(x=freq, y=tm, color='black', line_width=2, name='Tm')) fig.add_tools( HoverTool(mode='vline', line_policy='prev', renderers=[plots[j + 1]], names=['Tm'], tooltips=OrderedDict([('name', 'Measured'), ('index', '$index'), ('(x;y)', '(@x{0.00} ; @y{0.000})')]))) # adding the calculated spectrum plots.append( fig.line(x=freq, y=tc, color='chartreuse', line_width=2, name='Tc')) #fig.add_tools( HoverTool(mode='vline',line_policy='prev',renderers=[plots[j+2]],names=['Tc'],tooltips=OrderedDict( [('name','Calculated'),('index','$index'),('(x;y)','(@x{0.00} ; @y{0.000})')] )) ) # adding the continuum #plots.append(fig.line(x=freq,y=cont,color='#FF3399',line_dash='dashed',line_width=2,name='Cont')) #fig.add_tools( HoverTool(mode='vline',line_policy='prev',renderers=[plots[j+1]],names=['Cont'],tooltips=OrderedDict( [('name','Continuum'),('index','$index'),('(x;y)','(@x{0.00} ; @y{0.000})')] )) ) # legend outside of the figure fig_legend = Legend(items=[(header[j + not_gas], [plots[j]]) for j in range(len(species) - not_gas)] + [('Measured', [plots[-2]]), ('Calculated', [plots[-1]])], location=(0, 0), border_line_alpha=0) fig.add_layout(fig_legend, 'right') fig.legend.click_policy = "hide" fig.legend.inactive_fill_alpha = 0.6 # now the residual figure fig_resid.line(x=freq, y=residuals, color='black', name='residuals') fig_resid.line(x=freq, y=np.zeros(len(freq)), color='red') fig_resid.add_tools( HoverTool(mode='vline', line_policy='prev', names=['residuals'], tooltips={ 'index': '$index', '(x;y)': '($x{0.00} ; $y{0.000})' })) # set up a dummy legend for the residual figure so that it aligns with the spectrum figure dummy = fig_resid.line(x=freq, y=[0 for i in range(len(freq))], color='white', visible=False, alpha=0) fig_resid_legend = Legend(items=[(' ', [dummy])], location=(0, 0), border_line_alpha=0) fig_resid.add_layout(fig_resid_legend, 'right') # checkbox group callback checkbox_iterable = [('p' + str(i), plots[i]) for i in N_plots] + [('checkbox', checkbox)] checkbox_code = ''.join([ 'p' + str(i) + '.visible = checkbox.active.includes(' + str(i) + ');' for i in N_plots ]) checkbox.callback = CustomJS( args={key: value for key, value in checkbox_iterable}, code=checkbox_code) # button to uncheck all checkboxes clear_button = Button(label='Hide all lines', width=200) clear_button_code = """checkbox.active=[];""" + checkbox_code clear_button.callback = CustomJS( args={key: value for key, value in checkbox_iterable}, code=clear_button_code) # button to check all checkboxes check_button = Button(label='Show all lines', width=200) check_button_code = """checkbox.active=""" + str( N_plots) + """;""" + checkbox_code check_button.callback = CustomJS( args={key: value for key, value in checkbox_iterable}, code=check_button_code) # extension for the saved file name based on the path to spectra ext = custom_path.split(os.sep)[-2] # title div div = Div( text='<p align="center"><font size=4><b>{}</b></font></p>'.format(ext), width=fig.plot_width - 100) add_vlinked_crosshairs(fig, fig_resid) sub_grid = gridplot([[fig], [fig_resid], [div]], toolbar_location="left") # button to activate/deactivate hover tools hover_button = Button(label='Enable hover tools', button_type='success', width=200) hover_list = [i for i in sub_grid.select({"type": HoverTool})] # in 'comp' mode, each plot has a different hover tool, I hide them and this button will click them all at once. hover_button_code = """ if(cb_obj.button_type.includes("success")){ cb_obj.button_type = 'warning'; cb_obj.label = 'Disable hover tools' } else { cb_obj.button_type = 'success'; cb_obj.label= 'Enable hover tools'; } """ + ''.join([ "hover{}.active = !hover{}.active;".format(i, i) for i in range(len(hover_list)) ]) hover_button.callback = CustomJS( args={'hover{}'.format(i): elem for i, elem in enumerate(hover_list)}, code=hover_button_code) # put all the widgets in a box group = widgetbox(clear_button, check_button, hover_button, width=200, name="group") # the final grid for static plots grid = gridplot([[sub_grid, group]], toolbar_location=None) # save a standalone html document in spectra_app/save with open(os.path.join(save_path, '{}_{}.html'.format(spectrum, ext)), 'w') as outfile: outfile.write(file_html(grid, CDN, spectrum[:12] + spectrum[-3:])) group = widgetbox(clear_button, check_button, hover_button, path_input, select_spectrum, load_button, width=200) app_grid = gridplot([[sub_grid, group]], toolbar_location=None) # add that grid to the document curdoc().add_root(app_grid) if custom_path: path_input.value = custom_path else: path_input.value = spec_path