Prepare spind input directly in hdf viewer

This commit is contained in:
usov_i 2021-06-23 11:25:44 +02:00
parent c10efeb9cc
commit 57e503fc3d
2 changed files with 124 additions and 128 deletions

View File

@ -1,8 +1,10 @@
import base64 import base64
import io import io
import math
import os import os
import numpy as np import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column, gridplot, row from bokeh.layouts import column, gridplot, row
from bokeh.models import ( from bokeh.models import (
BasicTicker, BasicTicker,
@ -40,6 +42,7 @@ from bokeh.models import (
WheelZoomTool, WheelZoomTool,
) )
from bokeh.palettes import Cividis256, Greys256, Plasma256 # pylint: disable=E0611 from bokeh.palettes import Cividis256, Greys256, Plasma256 # pylint: disable=E0611
from scipy.optimize import curve_fit
import pyzebra import pyzebra
@ -50,9 +53,9 @@ IMAGE_PLOT_H = int(IMAGE_H * 2) + 27
def create(): def create():
doc = curdoc()
det_data = {} det_data = {}
cami_meta = {} cami_meta = {}
roi_selection = {}
def proposal_textinput_callback(_attr, _old, new): def proposal_textinput_callback(_attr, _old, new):
nonlocal cami_meta nonlocal cami_meta
@ -573,29 +576,91 @@ def create():
hkl_button = Button(label="Calculate hkl (slow)", width=210) hkl_button = Button(label="Calculate hkl (slow)", width=210)
hkl_button.on_click(hkl_button_callback) hkl_button.on_click(hkl_button_callback)
selection_list = TextAreaInput(rows=7) def events_list_callback(_attr, _old, new):
doc.events_list_spind.value = new
def selection_button_callback(): events_list = TextAreaInput(rows=7, width=830)
nonlocal roi_selection events_list.on_change("value", events_list_callback)
selection = [ doc.events_list_hdf_viewer = events_list
int(np.floor(det_x_range.start)),
int(np.ceil(det_x_range.end)),
int(np.floor(det_y_range.start)),
int(np.ceil(det_y_range.end)),
int(np.floor(frame_range.start)),
int(np.ceil(frame_range.end)),
]
filename_id = file_select.value[0][-8:-4] def add_event_button_callback():
if filename_id in roi_selection: diff_vec = []
roi_selection[f"{filename_id}"].append(selection) p0 = [1.0, 0.0, 1.0]
else: maxfev = 100000
roi_selection[f"{filename_id}"] = [selection]
selection_list.value = str(roi_selection) wave = det_data["wave"]
ddist = det_data["ddist"]
selection_button = Button(label="Add selection") gamma = det_data["gamma"][0]
selection_button.on_click(selection_button_callback) omega = det_data["omega"][0]
nu = det_data["nu"][0]
chi = det_data["chi"][0]
phi = det_data["phi"][0]
scan_motor = det_data["scan_motor"]
var_angle = det_data[scan_motor]
x0 = int(np.floor(det_x_range.start))
xN = int(np.ceil(det_x_range.end))
y0 = int(np.floor(det_y_range.start))
yN = int(np.ceil(det_y_range.end))
fr0 = int(np.floor(frame_range.start))
frN = int(np.ceil(frame_range.end))
data_roi = det_data["data"][fr0:frN, y0:yN, x0:xN]
cnts = np.sum(data_roi, axis=(1, 2))
coeff, _ = curve_fit(gauss, range(len(cnts)), cnts, p0=p0, maxfev=maxfev)
m = cnts.mean()
sd = cnts.std()
snr_cnts = np.where(sd == 0, 0, m / sd)
frC = fr0 + coeff[1]
var_F = var_angle[math.floor(frC)]
var_C = var_angle[math.ceil(frC)]
frStep = frC - math.floor(frC)
var_step = var_C - var_F
var_p = var_F + var_step * frStep
if scan_motor == "gamma":
gamma = var_p
elif scan_motor == "omega":
omega = var_p
elif scan_motor == "nu":
nu = var_p
elif scan_motor == "chi":
chi = var_p
elif scan_motor == "phi":
phi = var_p
intensity = coeff[1] * abs(coeff[2] * var_step) * math.sqrt(2) * math.sqrt(np.pi)
projX = np.sum(data_roi, axis=(0, 1))
coeff, _ = curve_fit(gauss, range(len(projX)), projX, p0=p0, maxfev=maxfev)
x_pos = x0 + coeff[1]
projY = np.sum(data_roi, axis=(0, 2))
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
diff_vec.append(diff_vector)
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.on_click(add_event_button_callback)
metadata_table_source = ColumnDataSource(dict(geom=[""], temp=[None], mf=[None])) metadata_table_source = ColumnDataSource(dict(geom=[""], temp=[None], mf=[None]))
num_formatter = NumberFormatter(format="0.00", nan_format="") num_formatter = NumberFormatter(format="0.00", nan_format="")
@ -623,12 +688,10 @@ def create():
row(proj_display_min_spinner, proj_display_max_spinner), row(proj_display_min_spinner, proj_display_max_spinner),
) )
layout_controls = row( layout_controls = column(
column(selection_button, selection_list), row(metadata_table, index_spinner, column(Spacer(height=25), index_slider)),
Spacer(width=20), row(add_event_button, hkl_button),
column( row(events_list),
row(index_spinner, column(Spacer(height=25), index_slider)), metadata_table, hkl_button
),
) )
layout_overview = column( layout_overview = column(
@ -649,6 +712,17 @@ def create():
return Panel(child=tab_layout, title="hdf viewer") return Panel(child=tab_layout, title="hdf viewer")
def gauss(x, *p):
"""Defines Gaussian function
Args:
A - amplitude, mu - position of the center, sigma - width
Returns:
Gaussian function
"""
A, mu, sigma = p
return A * np.exp(-((x - mu) ** 2) / (2.0 * sigma ** 2))
def calculate_hkl(det_data, index): def calculate_hkl(det_data, index):
h = np.empty(shape=(IMAGE_H, IMAGE_W)) h = np.empty(shape=(IMAGE_H, IMAGE_W))
k = np.empty(shape=(IMAGE_H, IMAGE_W)) k = np.empty(shape=(IMAGE_H, IMAGE_W))

View File

@ -1,5 +1,3 @@
import ast
import math
import os import os
import subprocess import subprocess
import tempfile import tempfile
@ -17,16 +15,18 @@ from bokeh.models import (
TextAreaInput, TextAreaInput,
TextInput, TextInput,
) )
from scipy.optimize import curve_fit
import pyzebra
def create(): def create():
doc = curdoc() doc = curdoc()
path_prefix_textinput = TextInput(title="Path prefix:", value="") def events_list_callback(_attr, _old, new):
selection_list = TextAreaInput(title="ROIs:", rows=7) 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
lattice_const_textinput = TextInput( lattice_const_textinput = TextInput(
title="Lattice constants:", value="8.3211,8.3211,8.3211,90.00,90.00,90.00" title="Lattice constants:", value="8.3211,8.3211,8.3211,90.00,90.00,90.00"
) )
@ -49,7 +49,6 @@ def create():
os.mkdir(temp_peak_list_dir) os.mkdir(temp_peak_list_dir)
temp_event_file = os.path.join(temp_peak_list_dir, "event-0.txt") temp_event_file = os.path.join(temp_peak_list_dir, "event-0.txt")
temp_hkl_file = os.path.join(temp_dir, "hkl.h5") temp_hkl_file = os.path.join(temp_dir, "hkl.h5")
roi_dict = ast.literal_eval(selection_list.value)
comp_proc = subprocess.run( comp_proc = subprocess.run(
[ [
@ -72,7 +71,12 @@ def create():
print(" ".join(comp_proc.args)) print(" ".join(comp_proc.args))
print(comp_proc.stdout) print(comp_proc.stdout)
diff_vec = prepare_event_file(temp_event_file, roi_dict, path_prefix_textinput.value) # 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")
print(f"Content of {temp_event_file}:") print(f"Content of {temp_event_file}:")
with open(temp_event_file) as f: with open(temp_event_file) as f:
@ -179,10 +183,10 @@ def create():
results_table_source.selected.on_change("indices", results_table_select_callback) results_table_source.selected.on_change("indices", results_table_select_callback)
tab_layout = row( tab_layout = column(
events_list,
row(
column( column(
path_prefix_textinput,
selection_list,
lattice_const_textinput, lattice_const_textinput,
row(max_res_spinner, seed_pool_size_spinner), row(max_res_spinner, seed_pool_size_spinner),
row(seed_len_tol_spinner, seed_angle_tol_spinner), row(seed_len_tol_spinner, seed_angle_tol_spinner),
@ -190,89 +194,7 @@ def create():
process_button, process_button,
), ),
column(results_table, row(ub_matrix_textareainput, hkl_textareainput)), column(results_table, row(ub_matrix_textareainput, hkl_textareainput)),
),
) )
return Panel(child=tab_layout, title="spind") return Panel(child=tab_layout, title="spind")
def gauss(x, *p):
"""Defines Gaussian function
Args:
A - amplitude, mu - position of the center, sigma - width
Returns:
Gaussian function
"""
A, mu, sigma = p
return A * np.exp(-((x - mu) ** 2) / (2.0 * sigma ** 2))
def prepare_event_file(export_filename, roi_dict, path_prefix=""):
diff_vec = []
p0 = [1.0, 0.0, 1.0]
maxfev = 100000
with open(export_filename, "w") as f:
for file, rois in roi_dict.items():
dat = pyzebra.read_detector_data(path_prefix + file + ".hdf")
wave = dat["wave"]
ddist = dat["ddist"]
gamma = dat["gamma"][0]
omega = dat["omega"][0]
nu = dat["nu"][0]
chi = dat["chi"][0]
phi = dat["phi"][0]
scan_motor = dat["scan_motor"]
var_angle = dat[scan_motor]
for roi in rois:
x0, xN, y0, yN, fr0, frN = roi
data_roi = dat["data"][fr0:frN, y0:yN, x0:xN]
cnts = np.sum(data_roi, axis=(1, 2))
coeff, _ = curve_fit(gauss, range(len(cnts)), cnts, p0=p0, maxfev=maxfev)
m = cnts.mean()
sd = cnts.std()
snr_cnts = np.where(sd == 0, 0, m / sd)
frC = fr0 + coeff[1]
var_F = var_angle[math.floor(frC)]
var_C = var_angle[math.ceil(frC)]
frStep = frC - math.floor(frC)
var_step = var_C - var_F
var_p = var_F + var_step * frStep
if scan_motor == "gamma":
gamma = var_p
elif scan_motor == "omega":
omega = var_p
elif scan_motor == "nu":
nu = var_p
elif scan_motor == "chi":
chi = var_p
elif scan_motor == "phi":
phi = var_p
intensity = coeff[1] * abs(coeff[2] * var_step) * math.sqrt(2) * math.sqrt(np.pi)
projX = np.sum(data_roi, axis=(0, 1))
coeff, _ = curve_fit(gauss, range(len(projX)), projX, p0=p0, maxfev=maxfev)
x_pos = x0 + coeff[1]
projY = np.sum(data_roi, axis=(0, 2))
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
diff_vec.append(diff_vector)
f.write(f"{x_pos} {y_pos} {intensity} {snr_cnts} {dv1} {dv2} {dv3} {d_spacing}\n")
return diff_vec