Redraw plots on orth cut value change

This commit is contained in:
2023-02-07 16:33:31 +01:00
parent 6b9555c33c
commit cb8fc3f4ff
3 changed files with 263 additions and 206 deletions

View File

@ -43,6 +43,7 @@ def create():
cif_data = {} cif_data = {}
params = {} params = {}
res_files = {} res_files = {}
_update_slice = None
app_dlfiles = app.DownloadFiles(n_files=1) app_dlfiles = app.DownloadFiles(n_files=1)
anglim_div = Div(text="Angular min/max limits:", margin=(5, 5, 0, 5)) anglim_div = Div(text="Angular min/max limits:", margin=(5, 5, 0, 5))
@ -302,10 +303,12 @@ def create():
preview_lists = TextAreaInput(title="Preview selected list:", width=600, height=150) preview_lists = TextAreaInput(title="Preview selected list:", width=600, height=150)
def plot_list_callback(): def plot_list_callback():
nonlocal _update_slice
fname = created_lists.value fname = created_lists.value
with io.StringIO(preview_lists.value) as fileobj: with io.StringIO(preview_lists.value) as fileobj:
fdata = pyzebra.parse_hkl(fileobj, fname) fdata = pyzebra.parse_hkl(fileobj, fname)
_plot(fname, [fdata]) _update_slice = _prepare_plotting(fname, [fdata])
_update_slice()
plot_list = Button(label="Plot selected list", button_type="primary", width=200) plot_list = Button(label="Plot selected list", button_type="primary", width=200)
plot_list.on_click(plot_list_callback) plot_list.on_click(plot_list_callback)
@ -321,22 +324,13 @@ def create():
cmap = Dark2[8] cmap = Dark2[8]
syms = ["circle", "inverted_triangle", "square", "diamond", "star", "triangle"] syms = ["circle", "inverted_triangle", "square", "diamond", "star", "triangle"]
def _plot(filenames, filedata): def _prepare_plotting(filenames, filedata):
orth_dir = list(map(float, hkl_normal.value.split())) orth_dir = list(map(float, hkl_normal.value.split()))
cut_tol = hkl_delta.value
cut_or = hkl_cut.value
x_dir = list(map(float, hkl_in_plane_x.value.split())) x_dir = list(map(float, hkl_in_plane_x.value.split()))
k = np.array(k_vectors.value.split()).astype(float).reshape(-1, 3) k = np.array(k_vectors.value.split()).astype(float).reshape(-1, 3)
tol_k = tol_k_ni.value tol_k = tol_k_ni.value
# different symbols based on file number
file_flag = 0 in disting_opt_cb.active
# scale marker size according to intensity
intensity_flag = 1 in disting_opt_cb.active
# use color to mark different propagation vectors
prop_legend_flag = 2 in disting_opt_cb.active
lattice = list(map(float, cryst_cell.value.strip().split())) lattice = list(map(float, cryst_cell.value.strip().split()))
alpha = lattice[3] * np.pi / 180.0 alpha = lattice[3] * np.pi / 180.0
beta = lattice[4] * np.pi / 180.0 beta = lattice[4] * np.pi / 180.0
@ -429,44 +423,6 @@ def create():
grid_source.data.update(xs=xs, ys=ys) grid_source.data.update(xs=xs, ys=ys)
minor_grid_source.data.update(xs=xs_minor, ys=ys_minor) minor_grid_source.data.update(xs=xs_minor, ys=ys_minor)
scan_x, scan_y = [], []
scan_m, scan_s, scan_c, scan_l = [], [], [], []
for j in range(len(hkl_coord)):
# Get middle hkl from list
hklm = M @ hkl_coord[j]
# Decide if point is in the cut
proj = np.dot(hklm, o_c)
if abs(proj - cut_or) >= cut_tol:
continue
if intensity_flag and max(intensity_vec) != 0:
markersize = max(1, int(intensity_vec[j] / max(intensity_vec) * 20))
else:
markersize = 4
if file_flag:
plot_symbol = syms[file_flag_vec[j]]
else:
plot_symbol = "circle"
if prop_legend_flag:
col_value = cmap[k_flag_vec[j]]
else:
col_value = "black"
# Plot middle point of scan
scan_x.append(hklm[0])
scan_y.append(hklm[1])
scan_m.append(plot_symbol)
scan_s.append(markersize)
# Color and legend label
scan_c.append(col_value)
scan_l.append(filenames[file_flag_vec[j]])
scatter_source.data.update(x=scan_x, y=scan_y, m=scan_m, s=scan_s, c=scan_c, l=scan_l)
arrow1.visible = True arrow1.visible = True
arrow1.x_end = x_c[0] arrow1.x_end = x_c[0]
arrow1.y_end = x_c[1] arrow1.y_end = x_c[1]
@ -478,23 +434,75 @@ def create():
x=[x_c[0] / 2, y_c[0] / 2 - 0.1], y=[x_c[1] - 0.1, y_c[1] / 2], text=["h", "k"] x=[x_c[0] / 2, y_c[0] / 2 - 0.1], y=[x_c[1] - 0.1, y_c[1] / 2], text=["h", "k"]
) )
# Legend items for different file entries (symbol) def _update_slice():
legend_items = [] cut_tol = hkl_delta.value
if file_flag: cut_or = hkl_cut.value
labels, inds = np.unique(scatter_source.data["l"], return_index=True)
for label, ind in zip(labels, inds):
legend_items.append(LegendItem(label=label, renderers=[scatter], index=ind))
# Legend items for propagation vector (color) # different symbols based on file number
if prop_legend_flag: file_flag = 0 in disting_opt_cb.active
labels, inds = np.unique(scatter_source.data["c"], return_index=True) # scale marker size according to intensity
for label, ind in zip(labels, inds): intensity_flag = 1 in disting_opt_cb.active
label = f"k={k[cmap.index(label)]}" # use color to mark different propagation vectors
legend_items.append(LegendItem(label=label, renderers=[scatter], index=ind)) prop_legend_flag = 2 in disting_opt_cb.active
plot.legend.items = legend_items scan_x, scan_y = [], []
scan_m, scan_s, scan_c, scan_l = [], [], [], []
for j in range(len(hkl_coord)):
# Get middle hkl from list
hklm = M @ hkl_coord[j]
# Decide if point is in the cut
proj = np.dot(hklm, o_c)
if abs(proj - cut_or) >= cut_tol:
continue
if intensity_flag and max(intensity_vec) != 0:
markersize = max(1, int(intensity_vec[j] / max(intensity_vec) * 20))
else:
markersize = 4
if file_flag:
plot_symbol = syms[file_flag_vec[j]]
else:
plot_symbol = "circle"
if prop_legend_flag:
col_value = cmap[k_flag_vec[j]]
else:
col_value = "black"
# Plot middle point of scan
scan_x.append(hklm[0])
scan_y.append(hklm[1])
scan_m.append(plot_symbol)
scan_s.append(markersize)
# Color and legend label
scan_c.append(col_value)
scan_l.append(filenames[file_flag_vec[j]])
scatter_source.data.update(x=scan_x, y=scan_y, m=scan_m, s=scan_s, c=scan_c, l=scan_l)
# Legend items for different file entries (symbol)
legend_items = []
if file_flag:
labels, inds = np.unique(scatter_source.data["l"], return_index=True)
for label, ind in zip(labels, inds):
legend_items.append(LegendItem(label=label, renderers=[scatter], index=ind))
# Legend items for propagation vector (color)
if prop_legend_flag:
labels, inds = np.unique(scatter_source.data["c"], return_index=True)
for label, ind in zip(labels, inds):
label = f"k={k[cmap.index(label)]}"
legend_items.append(LegendItem(label=label, renderers=[scatter], index=ind))
plot.legend.items = legend_items
return _update_slice
def plot_file_callback(): def plot_file_callback():
nonlocal _update_slice
fnames = [] fnames = []
fdata = [] fdata = []
for j, fname in enumerate(upload_data.filename): for j, fname in enumerate(upload_data.filename):
@ -509,7 +517,8 @@ def create():
fnames.append(fname) fnames.append(fname)
fdata.append(file_data) fdata.append(file_data)
_plot(fnames, fdata) _update_slice = _prepare_plotting(fnames, fdata)
_update_slice()
plot_file = Button(label="Plot selected file(s)", button_type="primary", width=200) plot_file = Button(label="Plot selected file(s)", button_type="primary", width=200)
plot_file.on_click(plot_file_callback) plot_file.on_click(plot_file_callback)
@ -546,7 +555,14 @@ def create():
hkl_div = Div(text="HKL:", margin=(5, 5, 0, 5)) hkl_div = Div(text="HKL:", margin=(5, 5, 0, 5))
hkl_normal = TextInput(title="normal", value="0 0 1", width=70) hkl_normal = TextInput(title="normal", value="0 0 1", width=70)
def hkl_cut_callback(_attr, _old, _new):
if _update_slice is not None:
_update_slice()
hkl_cut = Spinner(title="cut", value=0, step=0.1, width=70) hkl_cut = Spinner(title="cut", value=0, step=0.1, width=70)
hkl_cut.on_change("value_throttled", hkl_cut_callback)
hkl_delta = NumericInput(title="delta", value=0.1, mode="float", width=70) hkl_delta = NumericInput(title="delta", value=0.1, mode="float", width=70)
hkl_in_plane_x = TextInput(title="in-plane X", value="1 0 0", width=70) hkl_in_plane_x = TextInput(title="in-plane X", value="1 0 0", width=70)
hkl_in_plane_y = TextInput(title="in-plane Y", value="", width=100, disabled=True) hkl_in_plane_y = TextInput(title="in-plane Y", value="", width=100, disabled=True)

View File

@ -27,10 +27,11 @@ from pyzebra.app.panel_hdf_viewer import calculate_hkl
def create(): def create():
_update_slice = None
measured_data_div = Div(text="Measured data:") measured_data_div = Div(text="Measured data:")
measured_data = FileInput(accept=".hdf", multiple=True, width=200) measured_data = FileInput(accept=".hdf", multiple=True, width=200)
def plot_file_callback(): def _prepare_plotting():
flag_ub = bool(redef_ub_cb.active) flag_ub = bool(redef_ub_cb.active)
flag_lattice = bool(redef_lattice_cb.active) flag_lattice = bool(redef_lattice_cb.active)
@ -43,12 +44,6 @@ def create():
# where delta is max distance a data point can have from cut in rlu units # where delta is max distance a data point can have from cut in rlu units
orth_dir = list(map(float, hkl_normal.value.split())) orth_dir = list(map(float, hkl_normal.value.split()))
# Where should cut be along orthogonal direction (Mutliplication factor onto orth_dir)
orth_cut = hkl_cut.value
# Width of cut
delta = hkl_delta.value
# Load data files # Load data files
md_fnames = measured_data.filename md_fnames = measured_data.filename
md_fdata = measured_data.value md_fdata = measured_data.value
@ -59,7 +54,7 @@ def create():
det_data = pyzebra.read_detector_data(io.BytesIO(base64.b64decode(fdata))) det_data = pyzebra.read_detector_data(io.BytesIO(base64.b64decode(fdata)))
except: except:
print(f"Error loading {fname}") print(f"Error loading {fname}")
return return None
if ind == 0: if ind == 0:
if not flag_ub: if not flag_ub:
@ -134,62 +129,76 @@ def create():
y_c = np.cross(x_c, o_c) y_c = np.cross(x_c, o_c)
hkl_in_plane_y.value = " ".join([f"{val:.1f}" for val in y_c]) hkl_in_plane_y.value = " ".join([f"{val:.1f}" for val in y_c])
# Calculate distance of all points to plane def _update_slice():
Q = np.array(o_c) * orth_cut # Where should cut be along orthogonal direction (Mutliplication factor onto orth_dir)
N = o_c / np.sqrt(np.sum(o_c**2)) orth_cut = hkl_cut.value
v = np.empty(np.shape(hkl_c))
v[:, :, :, :, 0] = hkl_c[:, :, :, :, 0] - Q
dist = np.abs(np.dot(N, v))
dist = np.squeeze(dist)
dist = np.transpose(dist)
# Find points within acceptable distance of plane defined by o_c # Width of cut
ind = np.where(abs(dist) < delta) delta = hkl_delta.value
# Project points onto axes # Calculate distance of all points to plane
x = np.dot(x_c / np.sqrt(np.sum(x_c**2)), hkl_c) Q = np.array(o_c) * orth_cut
y = np.dot(y_c / np.sqrt(np.sum(y_c**2)), hkl_c) N = o_c / np.sqrt(np.sum(o_c**2))
v = np.empty(np.shape(hkl_c))
v[:, :, :, :, 0] = hkl_c[:, :, :, :, 0] - Q
dist = np.abs(np.dot(N, v))
dist = np.squeeze(dist)
dist = np.transpose(dist)
# take care of dimensions # Find points within acceptable distance of plane defined by o_c
x = np.squeeze(x) ind = np.where(abs(dist) < delta)
x = np.transpose(x)
y = np.squeeze(y)
y = np.transpose(y)
# Get slices: # Project points onto axes
x_slice = x[ind] x = np.dot(x_c / np.sqrt(np.sum(x_c**2)), hkl_c)
y_slice = y[ind] y = np.dot(y_c / np.sqrt(np.sum(y_c**2)), hkl_c)
I_slice = I_matrix[ind]
# Meshgrid limits for plotting # take care of dimensions
if auto_range_cb.active: x = np.squeeze(x)
min_x = np.min(x_slice) x = np.transpose(x)
max_x = np.max(x_slice) y = np.squeeze(y)
min_y = np.min(y_slice) y = np.transpose(y)
max_y = np.max(y_slice)
xrange_min_ni.value = min_x
xrange_max_ni.value = max_x
yrange_min_ni.value = min_y
yrange_max_ni.value = max_y
else:
min_x = xrange_min_ni.value
max_x = xrange_max_ni.value
min_y = yrange_min_ni.value
max_y = yrange_max_ni.value
delta_x = xrange_step_ni.value # Get slices:
delta_y = yrange_step_ni.value x_slice = x[ind]
y_slice = y[ind]
I_slice = I_matrix[ind]
# Create interpolated mesh grid for plotting # Meshgrid limits for plotting
grid_x, grid_y = np.mgrid[min_x:max_x:delta_x, min_y:max_y:delta_y] if auto_range_cb.active:
I = interpolate.griddata((x_slice, y_slice), I_slice, (grid_x, grid_y)) min_x = np.min(x_slice)
max_x = np.max(x_slice)
min_y = np.min(y_slice)
max_y = np.max(y_slice)
xrange_min_ni.value = min_x
xrange_max_ni.value = max_x
yrange_min_ni.value = min_y
yrange_max_ni.value = max_y
else:
min_x = xrange_min_ni.value
max_x = xrange_max_ni.value
min_y = yrange_min_ni.value
max_y = yrange_max_ni.value
# Update plot delta_x = xrange_step_ni.value
display_min_ni.value = 0 delta_y = yrange_step_ni.value
display_max_ni.value = np.max(I_slice) * 0.25
image_source.data.update( # Create interpolated mesh grid for plotting
image=[I.T], x=[min_x], dw=[max_x - min_x], y=[min_y], dh=[max_y - min_y] grid_x, grid_y = np.mgrid[min_x:max_x:delta_x, min_y:max_y:delta_y]
) I = interpolate.griddata((x_slice, y_slice), I_slice, (grid_x, grid_y))
# Update plot
display_min_ni.value = 0
display_max_ni.value = np.max(I_slice) * 0.25
image_source.data.update(
image=[I.T], x=[min_x], dw=[max_x - min_x], y=[min_y], dh=[max_y - min_y]
)
return _update_slice
def plot_file_callback():
nonlocal _update_slice
_update_slice = _prepare_plotting()
_update_slice()
plot_file = Button(label="Plot selected file(s)", button_type="primary", width=200) plot_file = Button(label="Plot selected file(s)", button_type="primary", width=200)
plot_file.on_click(plot_file_callback) plot_file.on_click(plot_file_callback)
@ -209,7 +218,14 @@ def create():
hkl_div = Div(text="HKL:", margin=(5, 5, 0, 5)) hkl_div = Div(text="HKL:", margin=(5, 5, 0, 5))
hkl_normal = TextInput(title="normal", value="0 0 1", width=70) hkl_normal = TextInput(title="normal", value="0 0 1", width=70)
def hkl_cut_callback(_attr, _old, _new):
if _update_slice is not None:
_update_slice()
hkl_cut = Spinner(title="cut", value=0, step=0.1, width=70) hkl_cut = Spinner(title="cut", value=0, step=0.1, width=70)
hkl_cut.on_change("value_throttled", hkl_cut_callback)
hkl_delta = NumericInput(title="delta", value=0.1, mode="float", width=70) hkl_delta = NumericInput(title="delta", value=0.1, mode="float", width=70)
hkl_in_plane_x = TextInput(title="in-plane X", value="1 0 0", width=70) hkl_in_plane_x = TextInput(title="in-plane X", value="1 0 0", width=70)
hkl_in_plane_y = TextInput(title="in-plane Y", value="", width=100, disabled=True) hkl_in_plane_y = TextInput(title="in-plane Y", value="", width=100, disabled=True)

View File

@ -31,6 +31,7 @@ import pyzebra
class PlotHKL: class PlotHKL:
def __init__(self): def __init__(self):
_update_slice = None
measured_data_div = Div(text="Measured data:") measured_data_div = Div(text="Measured data:")
measured_data = FileInput(accept=".ccl", multiple=True, width=200) measured_data = FileInput(accept=".ccl", multiple=True, width=200)
@ -41,23 +42,13 @@ class PlotHKL:
cmap = Dark2[8] cmap = Dark2[8]
syms = ["circle", "inverted_triangle", "square", "diamond", "star", "triangle"] syms = ["circle", "inverted_triangle", "square", "diamond", "star", "triangle"]
def plot_file_callback(): def _prepare_plotting():
orth_dir = list(map(float, hkl_normal.value.split())) orth_dir = list(map(float, hkl_normal.value.split()))
cut_tol = hkl_delta.value
cut_or = hkl_cut.value
x_dir = list(map(float, hkl_in_plane_x.value.split())) x_dir = list(map(float, hkl_in_plane_x.value.split()))
k = np.array(k_vectors.value.split()).astype(float).reshape(-1, 3) k = np.array(k_vectors.value.split()).astype(float).reshape(-1, 3)
tol_k = tol_k_ni.value tol_k = tol_k_ni.value
# different symbols based on file number
file_flag = 0 in disting_opt_cb.active
# scale marker size according to intensity
intensity_flag = 1 in disting_opt_cb.active
# use color to mark different propagation vectors
prop_legend_flag = 2 in disting_opt_cb.active
# use resolution ellipsis
res_flag = disting_opt_rb.active
# multiplier for resolution function (in case of samples with large mosaicity) # multiplier for resolution function (in case of samples with large mosaicity)
res_mult = res_mult_ni.value res_mult = res_mult_ni.value
@ -72,7 +63,7 @@ class PlotHKL:
file_data = pyzebra.parse_1D(file, ext) file_data = pyzebra.parse_1D(file, ext)
except: except:
print(f"Error loading {md_fnames[0]}") print(f"Error loading {md_fnames[0]}")
return return None
alpha = file_data[0]["alpha_cell"] * np.pi / 180.0 alpha = file_data[0]["alpha_cell"] * np.pi / 180.0
beta = file_data[0]["beta_cell"] * np.pi / 180.0 beta = file_data[0]["beta_cell"] * np.pi / 180.0
@ -124,7 +115,7 @@ class PlotHKL:
file_data = pyzebra.parse_1D(file, ext) file_data = pyzebra.parse_1D(file, ext)
except: except:
print(f"Error loading {md_fname}") print(f"Error loading {md_fname}")
return return None
pyzebra.normalize_dataset(file_data) pyzebra.normalize_dataset(file_data)
@ -216,63 +207,6 @@ class PlotHKL:
grid_source.data.update(xs=xs, ys=ys) grid_source.data.update(xs=xs, ys=ys)
minor_grid_source.data.update(xs=xs_minor, ys=ys_minor) minor_grid_source.data.update(xs=xs_minor, ys=ys_minor)
el_x, el_y, el_w, el_h, el_c = [], [], [], [], []
scan_xs, scan_ys, scan_x, scan_y = [], [], [], []
scan_m, scan_s, scan_c, scan_l = [], [], [], []
for j in range(len(hkl_coord)):
# Get middle hkl from list
hklm = M @ hkl_coord[j][2]
# Decide if point is in the cut
proj = np.dot(hklm, o_c)
if abs(proj - cut_or) >= cut_tol:
continue
hkl1 = M @ hkl_coord[j][0]
hkl2 = M @ hkl_coord[j][1]
if intensity_flag:
markersize = max(1, int(intensity_vec[j] / max(intensity_vec) * 20))
else:
markersize = 4
if file_flag:
plot_symbol = syms[file_flag_vec[j]]
else:
plot_symbol = "circle"
if prop_legend_flag:
col_value = cmap[k_flag_vec[j]]
else:
col_value = "black"
if res_flag:
# Generate series of ellipses along scan line
el_x.extend(np.linspace(hkl1[0], hkl2[0], num=res_N))
el_y.extend(np.linspace(hkl1[1], hkl2[1], num=res_N))
el_w.extend(np.array(res_vec_x[j]) * 2)
el_h.extend(np.array(res_vec_y[j]) * 2)
el_c.extend([col_value] * res_N)
else:
# Plot scan line
scan_xs.append([hkl1[0], hkl2[0]])
scan_ys.append([hkl1[1], hkl2[1]])
# Plot middle point of scan
scan_x.append(hklm[0])
scan_y.append(hklm[1])
scan_m.append(plot_symbol)
scan_s.append(markersize)
# Color and legend label
scan_c.append(col_value)
scan_l.append(md_fnames[file_flag_vec[j]])
ellipse_source.data.update(x=el_x, y=el_y, width=el_w, height=el_h, c=el_c)
scan_source.data.update(
xs=scan_xs, ys=scan_ys, x=scan_x, y=scan_y, m=scan_m, s=scan_s, c=scan_c, l=scan_l
)
arrow1.visible = True arrow1.visible = True
arrow1.x_end = x_c[0] arrow1.x_end = x_c[0]
arrow1.y_end = x_c[1] arrow1.y_end = x_c[1]
@ -284,26 +218,110 @@ class PlotHKL:
x=[x_c[0] / 2, y_c[0] / 2 - 0.1], y=[x_c[1] - 0.1, y_c[1] / 2], text=["h", "k"] x=[x_c[0] / 2, y_c[0] / 2 - 0.1], y=[x_c[1] - 0.1, y_c[1] / 2], text=["h", "k"]
) )
# Legend items for different file entries (symbol) def _update_slice():
legend_items = [] cut_tol = hkl_delta.value
if not res_flag and file_flag: cut_or = hkl_cut.value
labels, inds = np.unique(scan_source.data["l"], return_index=True)
for label, ind in zip(labels, inds):
legend_items.append(LegendItem(label=label, renderers=[scatter], index=ind))
# Legend items for propagation vector (color) # different symbols based on file number
if prop_legend_flag: file_flag = 0 in disting_opt_cb.active
if res_flag: # scale marker size according to intensity
source, render = ellipse_source, ellipse intensity_flag = 1 in disting_opt_cb.active
else: # use color to mark different propagation vectors
source, render = scan_source, mline prop_legend_flag = 2 in disting_opt_cb.active
# use resolution ellipsis
res_flag = disting_opt_rb.active
labels, inds = np.unique(source.data["c"], return_index=True) el_x, el_y, el_w, el_h, el_c = [], [], [], [], []
for label, ind in zip(labels, inds): scan_xs, scan_ys, scan_x, scan_y = [], [], [], []
label = f"k={k[cmap.index(label)]}" scan_m, scan_s, scan_c, scan_l = [], [], [], []
legend_items.append(LegendItem(label=label, renderers=[render], index=ind)) for j in range(len(hkl_coord)):
# Get middle hkl from list
hklm = M @ hkl_coord[j][2]
plot.legend.items = legend_items # Decide if point is in the cut
proj = np.dot(hklm, o_c)
if abs(proj - cut_or) >= cut_tol:
continue
hkl1 = M @ hkl_coord[j][0]
hkl2 = M @ hkl_coord[j][1]
if intensity_flag:
markersize = max(1, int(intensity_vec[j] / max(intensity_vec) * 20))
else:
markersize = 4
if file_flag:
plot_symbol = syms[file_flag_vec[j]]
else:
plot_symbol = "circle"
if prop_legend_flag:
col_value = cmap[k_flag_vec[j]]
else:
col_value = "black"
if res_flag:
# Generate series of ellipses along scan line
el_x.extend(np.linspace(hkl1[0], hkl2[0], num=res_N))
el_y.extend(np.linspace(hkl1[1], hkl2[1], num=res_N))
el_w.extend(np.array(res_vec_x[j]) * 2)
el_h.extend(np.array(res_vec_y[j]) * 2)
el_c.extend([col_value] * res_N)
else:
# Plot scan line
scan_xs.append([hkl1[0], hkl2[0]])
scan_ys.append([hkl1[1], hkl2[1]])
# Plot middle point of scan
scan_x.append(hklm[0])
scan_y.append(hklm[1])
scan_m.append(plot_symbol)
scan_s.append(markersize)
# Color and legend label
scan_c.append(col_value)
scan_l.append(md_fnames[file_flag_vec[j]])
ellipse_source.data.update(x=el_x, y=el_y, width=el_w, height=el_h, c=el_c)
scan_source.data.update(
xs=scan_xs,
ys=scan_ys,
x=scan_x,
y=scan_y,
m=scan_m,
s=scan_s,
c=scan_c,
l=scan_l,
)
# Legend items for different file entries (symbol)
legend_items = []
if not res_flag and file_flag:
labels, inds = np.unique(scan_source.data["l"], return_index=True)
for label, ind in zip(labels, inds):
legend_items.append(LegendItem(label=label, renderers=[scatter], index=ind))
# Legend items for propagation vector (color)
if prop_legend_flag:
if res_flag:
source, render = ellipse_source, ellipse
else:
source, render = scan_source, mline
labels, inds = np.unique(source.data["c"], return_index=True)
for label, ind in zip(labels, inds):
label = f"k={k[cmap.index(label)]}"
legend_items.append(LegendItem(label=label, renderers=[render], index=ind))
plot.legend.items = legend_items
return _update_slice
def plot_file_callback():
nonlocal _update_slice
_update_slice = _prepare_plotting()
_update_slice()
plot_file = Button(label="Plot selected file(s)", button_type="primary", width=200) plot_file = Button(label="Plot selected file(s)", button_type="primary", width=200)
plot_file.on_click(plot_file_callback) plot_file.on_click(plot_file_callback)
@ -348,7 +366,14 @@ class PlotHKL:
hkl_div = Div(text="HKL:", margin=(5, 5, 0, 5)) hkl_div = Div(text="HKL:", margin=(5, 5, 0, 5))
hkl_normal = TextInput(title="normal", value="0 0 1", width=70) hkl_normal = TextInput(title="normal", value="0 0 1", width=70)
def hkl_cut_callback(_attr, _old, _new):
if _update_slice is not None:
_update_slice()
hkl_cut = Spinner(title="cut", value=0, step=0.1, width=70) hkl_cut = Spinner(title="cut", value=0, step=0.1, width=70)
hkl_cut.on_change("value_throttled", hkl_cut_callback)
hkl_delta = NumericInput(title="delta", value=0.1, mode="float", width=70) hkl_delta = NumericInput(title="delta", value=0.1, mode="float", width=70)
hkl_in_plane_x = TextInput(title="in-plane X", value="1 0 0", width=70) hkl_in_plane_x = TextInput(title="in-plane X", value="1 0 0", width=70)
hkl_in_plane_y = TextInput(title="in-plane Y", value="", width=100, disabled=True) hkl_in_plane_y = TextInput(title="in-plane Y", value="", width=100, disabled=True)