Migrate to python/3.10 and bokeh/3.8
All checks were successful
pyzebra CI/CD pipeline / test-env (push) Successful in 2m20s
pyzebra CI/CD pipeline / prod-env (push) Has been skipped
pyzebra CI/CD pipeline / cleanup (push) Successful in 1s

* use TabPanel instead of Panel
* use scatter(marker=...) instead of specific marker function
* replace gridplot with grid
This commit is contained in:
2026-02-06 18:25:23 +01:00
parent 36cb92f6d5
commit e6e97be58a
13 changed files with 120 additions and 100 deletions

View File

@@ -21,7 +21,7 @@ jobs:
uses: actions/checkout@v4
- run: $CONDA/bin/conda build --no-anaconda-upload --output-folder $BUILD_DIR ./conda-recipe
- run: $CONDA/bin/conda remove --name test --all --keep-env -y
- run: $CONDA/bin/conda install --name test --channel $BUILD_DIR python=3.8 pyzebra -y
- run: $CONDA/bin/conda install --name test --channel $BUILD_DIR python=3.10 pyzebra -y
- run: sudo systemctl restart pyzebra-test.service
prod-env:
@@ -34,7 +34,7 @@ jobs:
uses: actions/checkout@v4
- run: $CONDA/bin/conda build --token ${{ secrets.ANACONDA_TOKEN }} --output-folder $BUILD_DIR ./conda-recipe
- run: $CONDA/bin/conda remove --name prod --all --keep-env -y
- run: $CONDA/bin/conda install --name prod --channel $BUILD_DIR python=3.8 pyzebra -y
- run: $CONDA/bin/conda install --name prod --channel $BUILD_DIR python=3.10 pyzebra -y
- run: sudo systemctl restart pyzebra-prod.service
cleanup:
@@ -42,4 +42,4 @@ jobs:
needs: [test-env, prod-env]
if: always()
steps:
- run: $CONDA/bin/conda build purge-all
- run: $CONDA/bin/conda build purge-all

View File

@@ -5,12 +5,12 @@ build-backend = "hatchling.build"
[project]
name = "pyzebra"
dynamic = ["version"] # version will be read from __init__.py
requires-python = ">=3.8"
requires-python = ">=3.10"
dependencies = [
"numpy",
"scipy",
"h5py",
"bokeh ~=2.4",
"bokeh ~=3.8",
"numba",
"lmfit >=1.0.2",
]

View File

@@ -3,8 +3,8 @@ import logging
from io import StringIO
from bokeh.io import curdoc
from bokeh.layouts import column, row
from bokeh.models import Button, Panel, Tabs, TextAreaInput, TextInput
from bokeh.layouts import column
from bokeh.models import Button, TabPanel, Tabs, TextAreaInput, TextInput
import pyzebra
from pyzebra.app import (
@@ -55,14 +55,14 @@ logger.setLevel(logging.INFO)
logger.addHandler(handler)
doc.logger = logger
log_textareainput = TextAreaInput(title="Logging output:")
log_textareainput = TextAreaInput(title="Logging output:", sizing_mode="stretch_both")
def proposal_textinput_callback(_attr, _old, _new):
apply_button.disabled = False
proposal_textinput = TextInput(title="Proposal number:", name="")
proposal_textinput = TextInput(title="Proposal number:", name="", sizing_mode="stretch_width")
proposal_textinput.on_change("value_input", proposal_textinput_callback)
doc.proposal_textinput = proposal_textinput
@@ -82,7 +82,7 @@ def apply_button_callback():
proposal_textinput.name = proposal_path
apply_button = Button(label="Apply", button_type="primary")
apply_button = Button(label="Apply", button_type="primary", width=300)
apply_button.on_click(apply_button_callback)
# Final layout
@@ -90,7 +90,7 @@ doc.add_root(
column(
Tabs(
tabs=[
Panel(child=column(proposal_textinput, apply_button), title="user config"),
TabPanel(child=column(proposal_textinput, apply_button), title="user config"),
panel_hdf_viewer.create(),
panel_hdf_anatric.create(),
panel_ccl_prepare.create(),
@@ -102,7 +102,8 @@ doc.add_root(
panel_spind.create(),
]
),
row(log_textareainput, sizing_mode="scale_both"),
log_textareainput,
sizing_mode="stretch_height",
)
)

View File

@@ -15,13 +15,13 @@ from bokeh.models import (
Div,
FileInput,
MultiSelect,
Panel,
RadioGroup,
Select,
Spacer,
Span,
Spinner,
TableColumn,
TabPanel,
TextAreaInput,
Whisker,
)
@@ -250,7 +250,8 @@ def create():
)
scatter1_source = ColumnDataSource(dict(x=[0], y=[0], y_upper=[0], y_lower=[0]))
plot.circle(
plot.scatter(
marker="circle",
source=scatter1_source,
line_color="steelblue",
fill_color="steelblue",
@@ -259,7 +260,8 @@ def create():
plot.add_layout(Whisker(source=scatter1_source, base="x", upper="y_upper", lower="y_lower"))
scatter2_source = ColumnDataSource(dict(x=[0], y=[0], y_upper=[0], y_lower=[0]))
plot.circle(
plot.scatter(
marker="circle",
source=scatter2_source,
line_color="firebrick",
fill_color="firebrick",
@@ -535,4 +537,4 @@ def create():
row(fitpeak_controls, app_fitctrl.result_textarea),
)
return Panel(child=tab_layout, title="ccl compare")
return TabPanel(child=tab_layout, title="ccl compare")

View File

@@ -11,11 +11,11 @@ from bokeh.models import (
ColumnDataSource,
DataTable,
Div,
Panel,
Select,
Spacer,
Span,
TableColumn,
TabPanel,
TextAreaInput,
Whisker,
)
@@ -121,8 +121,12 @@ def create():
)
scatter_source = ColumnDataSource(dict(x=[0], y=[0], y_upper=[0], y_lower=[0]))
plot.circle(
source=scatter_source, line_color="steelblue", fill_color="steelblue", legend_label="data"
plot.scatter(
marker="circle",
source=scatter_source,
line_color="steelblue",
fill_color="steelblue",
legend_label="data",
)
plot.add_layout(Whisker(source=scatter_source, base="x", upper="y_upper", lower="y_lower"))
@@ -364,4 +368,4 @@ def create():
row(fitpeak_controls, app_fitctrl.result_textarea),
)
return Panel(child=tab_layout, title="ccl integrate")
return TabPanel(child=tab_layout, title="ccl integrate")

View File

@@ -20,11 +20,11 @@ from bokeh.models import (
MultiSelect,
NormalHead,
NumericInput,
Panel,
RadioGroup,
Select,
Spacer,
Spinner,
TabPanel,
TextAreaInput,
TextInput,
)
@@ -89,7 +89,7 @@ def create():
ang_lims = pyzebra.read_geom_file(fileobj)
_update_ang_lims(ang_lims)
open_geom_div = Div(text="Open GEOM:")
open_geom_div = Div(text="Open GEOM:", margin=(12, 5, 5, 5))
open_geom = FileInput(accept=".geom", width=200)
open_geom.on_change("value", open_geom_callback)
@@ -99,7 +99,7 @@ def create():
params = pyzebra.read_cfl_file(fileobj)
_update_params(params)
open_cfl_div = Div(text="Open CFL:")
open_cfl_div = Div(text="Open CFL:", margin=(12, 5, 5, 5))
open_cfl = FileInput(accept=".cfl", width=200)
open_cfl.on_change("value", open_cfl_callback)
@@ -109,7 +109,7 @@ def create():
cif_data = pyzebra.read_cif_file(fileobj)
_update_params(cif_data)
open_cif_div = Div(text="Open CIF:")
open_cif_div = Div(text="Open CIF:", margin=(12, 5, 5, 5))
open_cif = FileInput(accept=".cif", width=200)
open_cif.on_change("value", open_cif_callback)
@@ -145,7 +145,7 @@ def create():
ub_matrix_calc = Button(label="UB matrix:", button_type="primary", width=100)
ub_matrix_calc.on_click(ub_matrix_calc_callback)
ub_matrix = TextInput(title="\u200B", width=600)
ub_matrix = TextInput(title="\u200b", width=600)
ranges_div = Div(text="Ranges:", margin=(5, 5, 0, 5))
ranges_hkl = TextInput(title="HKL", value="-25 25 -25 25 -25 25", width=250)
@@ -153,7 +153,7 @@ def create():
magstruct_div = Div(text="Magnetic structure:", margin=(5, 5, 0, 5))
magstruct_lattice = TextInput(title="lattice", width=100)
magstruct_kvec = TextAreaInput(title="k vector", width=150)
magstruct_kvec = TextAreaInput(title="k vector", rows=3, width=150)
def sorting0_callback(_attr, _old, new):
sorting_0_dt.value = ANG_CHUNK_DEFAULTS[new]
@@ -321,7 +321,7 @@ def create():
plot_list.on_click(plot_list_callback)
# Plot
upload_data_div = Div(text="Open hkl/mhkl data:")
upload_data_div = Div(text="Open hkl/mhkl data:", margin=(12, 5, 5, 5))
upload_data = FileInput(accept=".hkl,.mhkl", multiple=True, width=200)
min_grid_x = -10
@@ -667,7 +667,7 @@ def create():
)
k_vectors = TextAreaInput(
title="k vectors:", value="0.0 0.0 0.0\n0.5 0.0 0.0\n0.5 0.5 0.0", width=150
title="k vectors:", value="0.0 0.0 0.0\n0.5 0.0 0.0\n0.5 0.5 0.0", rows=3, width=150
)
tol_k_ni = NumericInput(title="k tolerance:", value=0.01, mode="float", width=100)
@@ -721,4 +721,4 @@ def create():
tab_layout = row(column1_layout, column2_layout)
return Panel(child=tab_layout, title="ccl prepare")
return TabPanel(child=tab_layout, title="ccl prepare")

View File

@@ -10,9 +10,9 @@ from bokeh.models import (
Button,
Div,
FileInput,
Panel,
Select,
Spacer,
TabPanel,
Tabs,
TextAreaInput,
TextInput,
@@ -82,7 +82,7 @@ def create():
with io.BytesIO(base64.b64decode(new)) as file:
_load_config_file(file)
upload_div = Div(text="Open .xml config:")
upload_div = Div(text="Open .xml config:", margin=(12, 5, 5, 5))
upload_button = FileInput(accept=".xml", width=200)
upload_button.on_change("value", upload_button_callback)
@@ -91,7 +91,9 @@ def create():
def logfile_textinput_callback(_attr, _old, new):
config.logfile = new
logfile_textinput = TextInput(title="Logfile:", value="logfile.log")
logfile_textinput = TextInput(
title="Logfile:", value="logfile.log", sizing_mode="stretch_width"
)
logfile_textinput.on_change("value", logfile_textinput_callback)
def logfile_verbosity_callback(_attr, _old, new):
@@ -104,7 +106,7 @@ def create():
def filelist_type_callback(_attr, _old, new):
config.filelist_type = new
filelist_type = Select(title="File List:", options=["TRICS", "SINQ"], width=100)
filelist_type = Select(title="File List:", options=["TRICS", "SINQ"], value="TRICS", width=100)
filelist_type.on_change("value", filelist_type_callback)
def filelist_format_textinput_callback(_attr, _old, new):
@@ -116,7 +118,7 @@ def create():
def filelist_datapath_textinput_callback(_attr, _old, new):
config.filelist_datapath = new
filelist_datapath_textinput = TextInput(title="datapath:")
filelist_datapath_textinput = TextInput(title="datapath:", sizing_mode="stretch_width")
filelist_datapath_textinput.on_change("value", filelist_datapath_textinput_callback)
def filelist_ranges_textareainput_callback(_attr, _old, new):
@@ -125,7 +127,9 @@ def create():
ranges.append(re.findall(r"\b\d+\b", line))
config.filelist_ranges = ranges
filelist_ranges_textareainput = TextAreaInput(title="ranges:", rows=1)
filelist_ranges_textareainput = TextAreaInput(
title="ranges:", rows=1, sizing_mode="stretch_width"
)
filelist_ranges_textareainput.on_change("value", filelist_ranges_textareainput_callback)
# ---- crystal
@@ -144,7 +148,7 @@ def create():
def ub_textareainput_callback(_attr, _old, new):
config.crystal_UB = new
ub_textareainput = TextAreaInput(title="UB matrix:", height=100)
ub_textareainput = TextAreaInput(title="UB matrix:", height=100, sizing_mode="stretch_width")
ub_textareainput.on_change("value", ub_textareainput_callback)
def zeroOM_textinput_callback(_attr, _old, new):
@@ -170,7 +174,10 @@ def create():
config.dataFactory_implementation = new
dataFactory_implementation_select = Select(
title="DataFactory implement.:", options=DATA_FACTORY_IMPLEMENTATION, width=145
title="DataFactory implement.:",
options=DATA_FACTORY_IMPLEMENTATION,
value=DATA_FACTORY_IMPLEMENTATION[0],
width=145,
)
dataFactory_implementation_select.on_change("value", dataFactory_implementation_select_callback)
@@ -201,7 +208,10 @@ def create():
config.reflectionPrinter_format = new
reflectionPrinter_format_select = Select(
title="ReflectionPrinter format:", options=REFLECTION_PRINTER_FORMATS, width=145
title="ReflectionPrinter format:",
options=REFLECTION_PRINTER_FORMATS,
value=REFLECTION_PRINTER_FORMATS[0],
width=145,
)
reflectionPrinter_format_select.on_change("value", reflectionPrinter_format_select_callback)
@@ -325,14 +335,14 @@ def create():
algorithm_params = Tabs(
tabs=[
Panel(
TabPanel(
child=column(
row(threshold_textinput, shell_textinput, steepness_textinput),
row(duplicateDistance_textinput, maxequal_textinput, aps_window_textinput),
),
title="Peak Search",
),
Panel(
TabPanel(
child=column(
row(adm_window_textinput, border_textinput, minWindow_textinput),
row(reflectionFile_textinput, targetMonitor_textinput, smoothSize_textinput),
@@ -360,7 +370,7 @@ def create():
with open(os.path.join(temp_dir, config.reflectionPrinter_file)) as f_res:
output_res.value = f_res.read()
process_button = Button(label="Process", button_type="primary")
process_button = Button(label="Process", button_type="primary", width=300)
process_button.on_click(process_button_callback)
output_log = TextAreaInput(title="Logfile output:", height=320, width=465, disabled=True)
@@ -368,8 +378,8 @@ def create():
output_config = TextAreaInput(title="Current config:", height=320, width=465, disabled=True)
general_params_layout = column(
row(column(Spacer(height=2), upload_div), upload_button),
row(logfile_textinput, logfile_verbosity),
row(upload_div, upload_button),
row(logfile_textinput, logfile_verbosity, sizing_mode="stretch_width"),
row(filelist_type, filelist_format_textinput),
filelist_datapath_textinput,
filelist_ranges_textareainput,
@@ -387,7 +397,7 @@ def create():
tab_layout = row(
general_params_layout,
column(output_config, algorithm_params, row(process_button)),
column(output_config, algorithm_params, process_button),
column(output_log, output_res),
)
@@ -396,4 +406,4 @@ def create():
doc.add_periodic_callback(update_config, 1000)
return Panel(child=tab_layout, title="hdf anatric")
return TabPanel(child=tab_layout, title="hdf anatric")

View File

@@ -4,8 +4,9 @@ import os
import numpy as np
from bokeh.io import curdoc
from bokeh.layouts import column, gridplot, row
from bokeh.layouts import column, grid, row
from bokeh.models import (
BoxZoomTool,
Button,
CellEditor,
CheckboxGroup,
@@ -17,12 +18,15 @@ from bokeh.models import (
MultiSelect,
NumberEditor,
NumberFormatter,
Panel,
PanTool,
Range1d,
ResetTool,
Select,
Spinner,
TableColumn,
TabPanel,
Tabs,
WheelZoomTool,
)
from bokeh.plotting import figure
@@ -293,6 +297,7 @@ def create():
frame_range = Range1d(0, 1, bounds=(0, 1))
scanning_motor_range = Range1d(0, 1, bounds=(0, 1))
color_mapper_proj = LinearColorMapper()
shared_tools = [PanTool(), BoxZoomTool(), WheelZoomTool(maintain_focus=False), ResetTool()]
det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W))
proj_x_plot = figure(
@@ -304,12 +309,11 @@ def create():
extra_y_ranges={"scanning_motor": scanning_motor_range},
height=540,
width=IMAGE_PLOT_W - 3,
tools="pan,box_zoom,wheel_zoom,reset",
active_scroll="wheel_zoom",
tools=shared_tools,
toolbar_location=None,
)
proj_x_plot.yaxis.major_label_orientation = "vertical"
proj_x_plot.toolbar.tools[2].maintain_focus = False
proj_x_image_source = ColumnDataSource(
dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_W], dh=[1])
@@ -328,13 +332,13 @@ def create():
extra_y_ranges={"scanning_motor": scanning_motor_range},
height=540,
width=IMAGE_PLOT_H + 22,
tools="pan,box_zoom,wheel_zoom,reset",
active_scroll="wheel_zoom",
tools=shared_tools,
active_scroll=shared_tools[2],
)
proj_y_plot.yaxis.y_range_name = "scanning_motor"
proj_y_plot.yaxis.major_label_orientation = "vertical"
proj_y_plot.toolbar.tools[2].maintain_focus = False
proj_y_plot.toolbar.logo = None
proj_y_image_source = ColumnDataSource(
dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_H], dh=[1])
@@ -418,7 +422,7 @@ def create():
)
param_scatter_source = ColumnDataSource(dict(x=[], y=[]))
param_plot.circle(source=param_scatter_source)
param_plot.scatter(marker="circle", source=param_scatter_source)
param_plot.toolbar.logo = None
@@ -487,18 +491,13 @@ def create():
proc_all_button,
)
layout_proj = column(
gridplot(
[[proj_x_plot, proj_y_plot]], toolbar_options={"logo": None}, toolbar_location="right"
),
layout_controls,
)
layout_proj = column(grid([[proj_x_plot, proj_y_plot]]), layout_controls)
# Plot tabs
plots = Tabs(
tabs=[
Panel(child=layout_proj, title="single scan"),
Panel(child=column(param_plot, row(fit_param_select)), title="parameter plot"),
TabPanel(child=layout_proj, title="single scan"),
TabPanel(child=column(param_plot, row(fit_param_select)), title="parameter plot"),
]
)
@@ -515,4 +514,4 @@ def create():
tab_layout = column(row(import_layout, scan_layout, plots))
return Panel(child=tab_layout, title="hdf param study")
return TabPanel(child=tab_layout, title="hdf param study")

View File

@@ -5,9 +5,10 @@ import os
import numpy as np
from bokeh.events import MouseEnter
from bokeh.io import curdoc
from bokeh.layouts import column, gridplot, row
from bokeh.layouts import column, grid, row
from bokeh.models import (
BoxEditTool,
BoxZoomTool,
Button,
CellEditor,
CheckboxGroup,
@@ -21,15 +22,18 @@ from bokeh.models import (
LogColorMapper,
MultiSelect,
NumberFormatter,
Panel,
PanTool,
RadioGroup,
Range1d,
ResetTool,
Select,
Slider,
Spacer,
Spinner,
TableColumn,
TabPanel,
Tabs,
WheelZoomTool,
)
from bokeh.plotting import figure
@@ -579,6 +583,7 @@ def create():
scanning_motor_range = Range1d(0, 1, bounds=(0, 1))
lin_color_mapper_proj = LinearColorMapper(low=0, high=1)
log_color_mapper_proj = LogColorMapper(low=0, high=1)
shared_tools = [PanTool(), BoxZoomTool(), WheelZoomTool(maintain_focus=False), ResetTool()]
det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W))
gamma_range = Range1d(0, 1, bounds=(0, 1))
@@ -592,12 +597,11 @@ def create():
extra_y_ranges={"scanning_motor": scanning_motor_range},
height=540,
width=IMAGE_PLOT_W - 3,
tools="pan,box_zoom,wheel_zoom,reset",
active_scroll="wheel_zoom",
tools=shared_tools,
toolbar_location=None,
)
proj_x_plot.yaxis.major_label_orientation = "vertical"
proj_x_plot.toolbar.tools[2].maintain_focus = False
proj_x_plot.add_layout(LinearAxis(x_range_name="gamma", axis_label="Gamma, deg"), place="above")
@@ -620,13 +624,13 @@ def create():
extra_y_ranges={"scanning_motor": scanning_motor_range},
height=540,
width=IMAGE_PLOT_H + 22,
tools="pan,box_zoom,wheel_zoom,reset",
active_scroll="wheel_zoom",
tools=shared_tools,
active_scroll=shared_tools[2],
)
proj_y_plot.yaxis.y_range_name = "scanning_motor"
proj_y_plot.yaxis.major_label_orientation = "vertical"
proj_y_plot.toolbar.tools[2].maintain_focus = False
proj_y_plot.toolbar.logo = None
proj_y_plot.add_layout(LinearAxis(x_range_name="nu", axis_label="Nu, deg"), place="above")
@@ -890,8 +894,8 @@ def create():
# Final layout
peak_tables = Tabs(
tabs=[
Panel(child=events_table, title="Actual peak center"),
Panel(child=detcenter_table, title="Peak in the detector center"),
TabPanel(child=events_table, title="Actual peak center"),
TabPanel(child=detcenter_table, title="Peak in the detector center"),
]
)
@@ -905,7 +909,7 @@ def create():
row(file_open_button, file_append_button),
)
layout_image = column(gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False))
layout_image = column(grid([[proj_v, None], [plot, proj_h]]))
colormap_layout = column(
row(colormap_select, column(Spacer(height=15), colormap_scale_rg)),
main_auto_checkbox,
@@ -919,11 +923,7 @@ def create():
row(column(add_event_button, remove_event_button), peak_tables),
)
layout_proj = column(
gridplot(
[[proj_x_plot, proj_y_plot]], toolbar_options={"logo": None}, toolbar_location="right"
)
)
layout_proj = grid([[proj_x_plot, proj_y_plot]])
scan_layout = column(
scan_table,
@@ -937,7 +937,7 @@ def create():
column(roi_avg_plot, layout_image),
)
return Panel(child=tab_layout, title="hdf viewer")
return TabPanel(child=tab_layout, title="hdf viewer")
def calculate_hkl(scan, index):

View File

@@ -15,12 +15,12 @@ from bokeh.models import (
HoverTool,
LinearColorMapper,
NumberEditor,
Panel,
Range1d,
Select,
Spacer,
Span,
TableColumn,
TabPanel,
Tabs,
TextAreaInput,
Whisker,
@@ -218,8 +218,12 @@ def create():
)
scatter_source = ColumnDataSource(dict(x=[0], y=[0], y_upper=[0], y_lower=[0]))
plot.circle(
source=scatter_source, line_color="steelblue", fill_color="steelblue", legend_label="data"
plot.scatter(
marker="circle",
source=scatter_source,
line_color="steelblue",
fill_color="steelblue",
legend_label="data",
)
plot.add_layout(Whisker(source=scatter_source, base="x", upper="y_upper", lower="y_lower"))
@@ -274,7 +278,7 @@ def create():
ov_param_plot.image(source=ov_param_image_source, color_mapper=color_mapper)
ov_param_scatter_source = ColumnDataSource(dict(x=[], y=[]))
ov_param_plot.dot(source=ov_param_scatter_source, size=15, color="black")
ov_param_plot.scatter(marker="dot", source=ov_param_scatter_source, size=15, color="black")
ov_param_plot.toolbar.logo = None
@@ -288,7 +292,7 @@ def create():
)
param_scatter_source = ColumnDataSource(dict(x=[], y=[], y_upper=[], y_lower=[]))
param_plot.circle(source=param_scatter_source)
param_plot.scatter(marker="circle", source=param_scatter_source)
param_plot.add_layout(
Whisker(source=param_scatter_source, base="x", upper="y_upper", lower="y_lower")
)
@@ -304,10 +308,10 @@ def create():
# Plot tabs
plots = Tabs(
tabs=[
Panel(child=plot, title="single scan"),
Panel(child=ov_plot, title="overview"),
Panel(child=ov_param_plot, title="overview map"),
Panel(child=column(param_plot, row(fit_param_select)), title="parameter plot"),
TabPanel(child=plot, title="single scan"),
TabPanel(child=ov_plot, title="overview"),
TabPanel(child=ov_param_plot, title="overview map"),
TabPanel(child=column(param_plot, row(fit_param_select)), title="parameter plot"),
]
)
@@ -515,4 +519,4 @@ def create():
row(fitpeak_controls, app_fitctrl.result_textarea),
)
return Panel(child=tab_layout, title="param study")
return TabPanel(child=tab_layout, title="param study")

View File

@@ -16,11 +16,11 @@ from bokeh.models import (
LinearColorMapper,
LogColorMapper,
NumericInput,
Panel,
RadioGroup,
Select,
Spacer,
Spinner,
TabPanel,
TextInput,
)
from bokeh.plotting import figure
@@ -35,10 +35,10 @@ def create():
doc = curdoc()
log = doc.logger
_update_slice = None
measured_data_div = Div(text="Measured <b>HDF</b> data:")
measured_data_div = Div(text="Measured <b>HDF</b> data:", margin=(12, 5, 5, 5))
measured_data = FileInput(accept=".hdf", multiple=True, width=200)
upload_hkl_div = Div(text="Open hkl/mhkl data:")
upload_hkl_div = Div(text="Open hkl/mhkl data:", margin=(12, 5, 5, 5))
upload_hkl_fi = FileInput(accept=".hkl,.mhkl", multiple=True, width=200)
def _prepare_plotting():
@@ -439,4 +439,4 @@ def create():
tab_layout = row(column1_layout, Spacer(width=50), column2_layout)
return Panel(child=tab_layout, title="plot data")
return TabPanel(child=tab_layout, title="plot data")

View File

@@ -9,9 +9,9 @@ from bokeh.models import (
Button,
ColumnDataSource,
DataTable,
Panel,
Spinner,
TableColumn,
TabPanel,
TextAreaInput,
TextInput,
)
@@ -156,7 +156,7 @@ def create():
results_table_source.data.update(spind_res)
process_button = Button(label="Process", button_type="primary")
process_button = Button(label="Process", button_type="primary", width=300)
process_button.on_click(process_button_callback)
if doc.spind_path is None:
@@ -220,4 +220,4 @@ def create():
doc.add_periodic_callback(update_npeaks_spinner, 1000)
return Panel(child=tab_layout, title="spind")
return TabPanel(child=tab_layout, title="spind")

View File

@@ -35,10 +35,10 @@ class PlotHKL:
log = doc.logger
_update_slice = None
measured_data_div = Div(text="Measured <b>CCL</b> data:")
measured_data_div = Div(text="Measured <b>CCL</b> data:", margin=(12, 5, 5, 5))
measured_data = FileInput(accept=".ccl", multiple=True, width=200)
upload_hkl_div = Div(text="Open hkl/mhkl data:")
upload_hkl_div = Div(text="Open hkl/mhkl data:", margin=(12, 5, 5, 5))
upload_hkl_fi = FileInput(accept=".hkl,.mhkl", multiple=True, width=200)
min_grid_x = -10
@@ -515,7 +515,7 @@ class PlotHKL:
)
k_vectors = TextAreaInput(
title="k vectors:", value="0.0 0.0 0.0\n0.5 0.0 0.0\n0.5 0.5 0.0", width=150
title="k vectors:", value="0.0 0.0 0.0\n0.5 0.0 0.0\n0.5 0.5 0.0", rows=3, width=150
)
res_mult_ni = NumericInput(title="Resolution mult:", value=10, mode="int", width=100)
tol_k_ni = NumericInput(title="k tolerance:", value=0.01, mode="float", width=100)