From c2bd6c25f538da9c411921852166962af95b0390 Mon Sep 17 00:00:00 2001 From: Ivan Usov Date: Tue, 29 Jun 2021 18:30:59 +0200 Subject: [PATCH] Improve hdf_viewer -> spind user interation Fix #33 --- pyzebra/app/panel_hdf_viewer.py | 91 +++++++++++++++++++++++---------- pyzebra/app/panel_spind.py | 63 +++++++++++++++-------- 2 files changed, 106 insertions(+), 48 deletions(-) diff --git a/pyzebra/app/panel_hdf_viewer.py b/pyzebra/app/panel_hdf_viewer.py index 95eca36..409a861 100644 --- a/pyzebra/app/panel_hdf_viewer.py +++ b/pyzebra/app/panel_hdf_viewer.py @@ -36,7 +36,6 @@ from bokeh.models import ( Spacer, Spinner, TableColumn, - TextAreaInput, TextInput, Title, WheelZoomTool, @@ -57,6 +56,8 @@ def create(): det_data = {} cami_meta = {} + num_formatter = NumberFormatter(format="0.00", nan_format="") + def proposal_textinput_callback(_attr, _old, new): nonlocal cami_meta proposal = new.strip() @@ -570,18 +571,46 @@ def create(): h, k, l = calculate_hkl(det_data, index) image_source.data.update(h=[h], k=[k], l=[l]) - hkl_button = Button(label="Calculate hkl (slow)", width=210) + hkl_button = Button(label="Calculate hkl (slow)", width=145) hkl_button.on_click(hkl_button_callback) - def events_list_callback(_attr, _old, new): - doc.events_list_spind.value = new + events_data = dict( + wave=[], + ddist=[], + frame=[], + x_pos=[], + y_pos=[], + intensity=[], + snr_cnts=[], + gamma=[], + omega=[], + chi=[], + phi=[], + nu=[], + ) + doc.events_data = events_data - events_list = TextAreaInput(rows=7, width=830) - events_list.on_change("value", events_list_callback) - doc.events_list_hdf_viewer = events_list + events_table_source = ColumnDataSource(events_data) + events_table = DataTable( + source=events_table_source, + columns=[ + TableColumn(field="frame", title="Frame", formatter=num_formatter, width=70), + TableColumn(field="x_pos", title="X", formatter=num_formatter, width=70), + TableColumn(field="y_pos", title="Y", formatter=num_formatter, width=70), + TableColumn(field="intensity", title="Intensity", formatter=num_formatter, width=70), + TableColumn(field="gamma", title="Gamma", formatter=num_formatter, width=70), + TableColumn(field="omega", title="Omega", formatter=num_formatter, width=70), + TableColumn(field="chi", title="Chi", formatter=num_formatter, width=70), + TableColumn(field="phi", title="Phi", formatter=num_formatter, width=70), + TableColumn(field="nu", title="Nu", formatter=num_formatter, width=70), + ], + height=150, + width=630, + autosize_mode="none", + index_position=None, + ) def add_event_button_callback(): - diff_vec = [] p0 = [1.0, 0.0, 1.0] maxfev = 100000 @@ -640,27 +669,36 @@ def create(): coeff, _ = curve_fit(gauss, range(len(projY)), projY, p0=p0, maxfev=maxfev) y_pos = y0 + coeff[1] - ga, nu = pyzebra.det2pol(ddist, gamma, nu, x_pos, y_pos) - diff_vector = pyzebra.z1frmd(wave, ga, omega, chi, phi, nu) - d_spacing = float(pyzebra.dandth(wave, diff_vector)[0]) - diff_vector = diff_vector.flatten() * 1e10 - dv1, dv2, dv3 = diff_vector + events_data["wave"].append(wave) + events_data["ddist"].append(ddist) + events_data["frame"].append(frC) + events_data["x_pos"].append(x_pos) + events_data["y_pos"].append(y_pos) + events_data["intensity"].append(intensity) + events_data["snr_cnts"].append(snr_cnts) + events_data["gamma"].append(gamma) + events_data["omega"].append(omega) + events_data["chi"].append(chi) + events_data["phi"].append(phi) + events_data["nu"].append(nu) - diff_vec.append(diff_vector) + events_table_source.data = events_data - if events_list.value and not events_list.value.endswith("\n"): - events_list.value = events_list.value + "\n" - - events_list.value = ( - events_list.value - + f"{x_pos} {y_pos} {intensity} {snr_cnts} {dv1} {dv2} {dv3} {d_spacing}" - ) - - add_event_button = Button(label="Add spind event") + add_event_button = Button(label="Add spind event", width=145) add_event_button.on_click(add_event_button_callback) + def remove_event_button_callback(): + ind2remove = events_table_source.selected.indices + for value in events_data.values(): + for ind in reversed(ind2remove): + del value[ind] + + events_table_source.data = events_data + + remove_event_button = Button(label="Remove spind event", width=145) + remove_event_button.on_click(remove_event_button_callback) + metadata_table_source = ColumnDataSource(dict(geom=[""], temp=[None], mf=[None])) - num_formatter = NumberFormatter(format="0.00", nan_format="") metadata_table = DataTable( source=metadata_table_source, columns=[ @@ -687,8 +725,7 @@ def create(): layout_controls = column( row(metadata_table, index_spinner, column(Spacer(height=25), index_slider)), - row(add_event_button, hkl_button), - row(events_list), + row(column(add_event_button, remove_event_button), events_table), ) layout_overview = column( @@ -703,7 +740,7 @@ def create(): tab_layout = row( column(import_layout, colormap_layout), column(layout_overview, layout_controls), - column(roi_avg_plot, layout_image), + column(roi_avg_plot, layout_image, hkl_button), ) return Panel(child=tab_layout, title="hdf viewer") diff --git a/pyzebra/app/panel_spind.py b/pyzebra/app/panel_spind.py index 755bb33..1f600af 100644 --- a/pyzebra/app/panel_spind.py +++ b/pyzebra/app/panel_spind.py @@ -16,17 +16,14 @@ from bokeh.models import ( TextInput, ) +import pyzebra + def create(): doc = curdoc() + events_data = doc.events_data - def events_list_callback(_attr, _old, new): - doc.events_list_hdf_viewer.value = new - - events_list = TextAreaInput(title="Spind events:", rows=7, width=1500) - events_list.on_change("value", events_list_callback) - doc.events_list_spind = events_list - + npeaks_spinner = Spinner(title="Number of peaks from hdf_view panel:", disabled=True) lattice_const_textinput = TextInput( title="Lattice constants:", value="8.3211,8.3211,8.3211,90.00,90.00,90.00" ) @@ -74,9 +71,30 @@ def create(): # prepare an event file diff_vec = [] with open(temp_event_file, "w") as f: - for event in events_list.value.splitlines(): - diff_vec.append(np.array(event.split()[4:7], dtype=float)) - f.write(event + "\n") + npeaks = len(next(iter(doc.events_data.values()))) + for ind in range(npeaks): + wave = events_data["wave"][ind] + ddist = events_data["ddist"][ind] + x_pos = events_data["x_pos"][ind] + y_pos = events_data["y_pos"][ind] + intensity = events_data["intensity"][ind] + snr_cnts = events_data["snr_cnts"][ind] + gamma = events_data["gamma"][ind] + omega = events_data["omega"][ind] + chi = events_data["chi"][ind] + phi = events_data["phi"][ind] + nu = events_data["nu"][ind] + + ga, nu = pyzebra.det2pol(ddist, gamma, nu, x_pos, y_pos) + diff_vector = pyzebra.z1frmd(wave, ga, omega, chi, phi, nu) + d_spacing = float(pyzebra.dandth(wave, diff_vector)[0]) + diff_vector = diff_vector.flatten() * 1e10 + dv1, dv2, dv3 = diff_vector + + diff_vec.append(diff_vector) + f.write( + f"{x_pos} {y_pos} {intensity} {snr_cnts} {dv1} {dv2} {dv3} {d_spacing}\n" + ) print(f"Content of {temp_event_file}:") with open(temp_event_file) as f: @@ -183,18 +201,21 @@ def create(): results_table_source.selected.on_change("indices", results_table_select_callback) - tab_layout = column( - events_list, - row( - column( - lattice_const_textinput, - row(max_res_spinner, seed_pool_size_spinner), - row(seed_len_tol_spinner, seed_angle_tol_spinner), - row(eval_hkl_tol_spinner), - process_button, - ), - column(results_table, row(ub_matrix_textareainput, hkl_textareainput)), + tab_layout = row( + column( + npeaks_spinner, + lattice_const_textinput, + row(max_res_spinner, seed_pool_size_spinner), + row(seed_len_tol_spinner, seed_angle_tol_spinner), + row(eval_hkl_tol_spinner), + process_button, ), + column(results_table, row(ub_matrix_textareainput, hkl_textareainput)), ) + async def update_npeaks_spinner(): + npeaks_spinner.value = len(next(iter(doc.events_data.values()))) + + doc.add_periodic_callback(update_npeaks_spinner, 1000) + return Panel(child=tab_layout, title="spind")