def get_save_layout_button(enable_button, from_main): from astronomicAL.utils import save_config if ("save_button" not in settings.keys()) or from_main: settings["save_button"] = pn.widgets.Button( name="Save Current Configuration", disabled=not (enable_button) ) layout_dict = {} text_area_input = TextAreaInput(value="") text_area_input.on_change( "value", partial( save_config.save_config_file_cb, trigger_text=text_area_input, autosave=False, ), ) settings["save_button"].jscallback( clicks=save_config.save_layout_js_cb, args=dict(text_area_input=text_area_input), ) settings["save_button"].on_click(_save_layout_button_cb) return settings["save_button"] if not from_main: settings["save_button"].disabled = not (enable_button) return settings["save_button"]
def test_single_row_copy_with_zero(self, bokeh_model_page): data = {'x': [1,2,3,4], 'y': [0, 0, 0, 0], 'd': ['foo', 'bar', 'baz', 'quux']} source = ColumnDataSource(data) table = DataTable(columns=[ TableColumn(field="x", title="x"), TableColumn(field="y", title="y"), TableColumn(field="d", title="d"), ], source=source) text_input = TextAreaInput(css_classes=["foo"]) text_input.js_on_change('value', CustomJS(code=RECORD("value", "cb_obj.value"))) page = bokeh_model_page(column(table, text_input)) # select the third row row = get_table_row(page.driver, 2) row.click() enter_text_in_element(page.driver, row, Keys.INSERT, mod=Keys.CONTROL, click=0, enter=False) input_el = page.driver.find_element_by_css_selector('.foo') enter_text_in_element(page.driver, input_el, Keys.INSERT, mod=Keys.SHIFT, enter=False) #enter_text_in_element(page.driver, input_el, "") sleep(0.5) results = page.results assert results['value'] == '1\t2\t0\tbar\n' assert page.has_no_console_errors()
def milestone_tab(self): self.milestone_subtitle = Div(text="Milestones & Major Accomplishments", css_classes=['subt-style']) self.milestone_inst = Div(text="Record any major milestones or accomplishments that occur throughout a night and the exposure numbers that correspond to it. If applicable, indicate the ID of exposures to ignore in a series.", css_classes=['inst-style'],width=1000) self.milestone_input = TextAreaInput(placeholder="Description", rows=10, cols=3, max_length=5000) self.milestone_exp_start = TextInput(title ='Exposure Start', placeholder='12345', value=None) self.milestone_exp_end = TextInput(title='Exposure End', placeholder='12345', value=None) self.milestone_exp_excl = TextInput(title='Excluded Exposures', placeholder='12346', value=None) self.milestone_btn = Button(label='Add Milestone', css_classes=['add_button']) self.milestone_alert = Div(text=' ', css_classes=['alert-style']) self.summary = TextAreaInput(rows=6, title='End of Night Summary',max_length=5000) self.summary_btn = Button(label='Add Summary', css_classes=['add_button'], width=300)
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) code = RECORD("data", "s.data") plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=code))) text_input = TextAreaInput(cols=20, css_classes=["foo"]) def cb(attr, old, new): foo.append((old, new)) source.data['val'] = [old, new] text_input.on_change('value', cb) doc.add_root(column(text_input, plot))
def modify_doc(doc): source = ColumnDataSource(dict(x=[1, 2], y=[1, 1], val=["a", "b"])) plot = Plot(plot_height=400, plot_width=400, x_range=Range1d(0, 1), y_range=Range1d(0, 1), min_border=0) plot.add_glyph(source, Circle(x='x', y='y', size=20)) code = RECORD("data", "s.data") plot.add_tools(CustomAction(callback=CustomJS(args=dict(s=source), code=code))) text_input = TextAreaInput(cols=20, css_classes=["foo"]) def cb(attr, old, new): foo.append((old, new)) source.data['val'] = [old, new] text_input.on_change('value', cb) doc.add_root(column(text_input, plot))
def create_text(cont): """ Create a box to enter text for each tab. Args: cont (str): Continent name. Returns: text_input (:obj:`TextAreaInput`): Text input box. """ text_input = TextAreaInput( value="", rows=6, title="Manually enter line-separated countries, hit tab when finished") text_input.on_change("value", text_update) return text_input
def test_displays_placeholder(self, bokeh_model_page): text_input = TextAreaInput(placeholder="placeholder", css_classes=["foo"]) page = bokeh_model_page(text_input) input_div = page.driver.find_element_by_class_name('foo') el = input_div.find_element_by_tag_name("textarea") assert el.get_attribute('placeholder') == "placeholder" assert page.has_no_console_errors()
def __init__(self): Report.__init__(self, 'OS') self.title = Div(text="DESI Nightly Intake - Operating Scientist", css_classes=['h1-title-style'], width=1000)# width=800, style={'font-size':'24pt','font-style':'bold'}) desc = """ The Operating Scientist (OS) is responsible for initializing the Night Log. Connect to an existing Night Log using the date or initialize tonight's log. Throughout the night, enter information about the exposures, weather, and problems. Complete the OS Checklist at least once every hour. """ self.instructions = Div(text=desc+self.time_note.text, css_classes=['inst-style'], width=500) self.line = Div(text='-----------------------------------------------------------------------------------------------------------------------------', width=1000) self.line2 = Div(text='-----------------------------------------------------------------------------------------------------------------------------', width=1000) self.init_bt = Button(label="Initialize Tonight's Log", css_classes=['init_button']) self.LO = Select(title='Lead Observer', value='Choose One', options=self.lo_names) self.OA = Select(title='Observing Assistant', value='Choose One', options=self.oa_names) self.page_logo = Div(text="<img src='OS_Report/static/logo.png'>", width=350, height=300) self.contributer_list = TextAreaInput(placeholder='Contributer names (include all)', rows=2, cols=3, title='Names of all Contributers') self.contributer_btn = Button(label='Update Contributer List', css_classes=['add_button'], width=300) self.connect_hdr = Div(text="Connect to Existing Night Log", css_classes=['subt-style'], width=800) self.init_hdr = Div(text="Initialize Tonight's Night Log", css_classes=['subt-style'], width=800) self.check_subtitle = Div(text="OS Checklist", css_classes=['subt-style']) self.checklist_inst = Div(text="Every hour, the OS is expected to monitor several things. After completing these tasks, record at what time they were completed. Be honest please!", css_classes=['inst-style'], width=1000) self.checklist.labels = ["Did you check the weather?", "Did you check the guiding?", "Did you check the positioner temperatures?","Did you check the FXC?", "Did you check the Cryostat?", "Did you do a connectivity aliveness check?","Did you check the Spectrograph Chiller?"] self.nl_submit_btn = Button(label='Submit NightLog & Publish Nightsum', width=300, css_classes=['add_button']) self.header_options = ['Startup','Calibration (Arcs/Twilight)','Focus','Observation','Other Acquisition','Comment']
def test_displays_placeholder(self, bokeh_model_page: BokehModelPage) -> None: text_input = TextAreaInput(placeholder="placeholder") page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, "textarea") assert el.get_attribute('placeholder') == "placeholder" assert page.has_no_console_errors()
def test_displays_text_input(self, bokeh_model_page): text_input = TextAreaInput(css_classes=["foo"]) page = bokeh_model_page(text_input) input_div = page.driver.find_element_by_class_name('foo') el = input_div.find_element_by_tag_name("textarea") assert el.tag_name == 'textarea' assert page.has_no_console_errors()
def test_displays_text_input(self, bokeh_model_page: BokehModelPage) -> None: text_input = TextAreaInput() page = bokeh_model_page(text_input) el = find_element_for(page.driver, text_input, "textarea") assert el.tag_name == 'textarea' assert page.has_no_console_errors()
def plan_tab(self): self.plan_subtitle = Div(text="Night Plan", css_classes=['subt-style']) self.plan_inst = Div(text="Input the major elements of the Night Plan found at the link below in the order expected for their completion.", css_classes=['inst-style'], width=1000) self.plan_txt = Div(text='<a href="https://desi.lbl.gov/trac/wiki/DESIOperations/ObservingPlans/">Tonights Plan Here</a>', css_classes=['inst-style'], width=500) self.plan_order = TextInput(title ='Expected Order:', placeholder='1', value=None) self.plan_input = TextAreaInput(placeholder="description", rows=8, cols=3, title="Describe item of the night plan:",max_length=5000) self.plan_btn = Button(label='Add', css_classes=['add_button']) self.plan_alert = Div(text=' ', css_classes=['alert-style'])
def test_server_on_change_round_trip( self, bokeh_server_page: BokehServerPage) -> None: text_input = TextAreaInput(cols=20) page = bokeh_server_page(mk_modify_doc(text_input)) el = find_element_for(page.driver, text_input, "textarea") enter_text_in_element(page.driver, el, "val1" + Keys.TAB) page.eval_custom_action() results = page.results assert results['data']['val'] == ["", "val1"]
p.yaxis.visible = None p.xgrid.grid_line_color = None p.ygrid.grid_line_color = None status = Paragraph(text="", width=900, height=100) tags_text = PreText(text="", width=400) profile_tags = CheckboxButtonGroup(labels=tags["PROFILE"], active=[], width=800) pol_tags = CheckboxButtonGroup(labels=tags["POLARIZATION"], active=[]) freq_tags = CheckboxButtonGroup(labels=tags["FREQUENCY"], active=[]) time_tags = CheckboxButtonGroup(labels=tags["TIME"], active=[]) observation_tags = CheckboxButtonGroup(labels=tags["OBSERVATION"], active=[]) apply_tags = Button(label="Apply tags", button_type="success") save = Button(label="Save tags", button_type="success") comments = TextAreaInput(value="", title="User comments", rows=6) getlatest = Toggle(label="Get latest webshot", button_type="primary") def get_url(psrname): url = "https://www.atnf.csiro.au/people/joh414/meerkat/{0}.html".format( psrname) return url def capture_screenshot(url): status.text = "Procuring a snapshot from the TPA webpage..." CHROME_PATH = '/usr/bin/google-chrome-stable' CHROMEDRIVER_PATH = '/usr/bin/chromedriver' WINDOW_SIZE = "900,600" chrome_options = Options()
def create(): doc = curdoc() det_data = {} cami_meta = {} def proposal_textinput_callback(_attr, _old, new): nonlocal cami_meta proposal = new.strip() for zebra_proposals_path in pyzebra.ZEBRA_PROPOSALS_PATHS: proposal_path = os.path.join(zebra_proposals_path, proposal) if os.path.isdir(proposal_path): # found it break else: raise ValueError(f"Can not find data for proposal '{proposal}'.") file_list = [] for file in os.listdir(proposal_path): if file.endswith(".hdf"): file_list.append((os.path.join(proposal_path, file), file)) file_select.options = file_list cami_meta = {} proposal_textinput = TextInput(title="Proposal number:", width=210) proposal_textinput.on_change("value", proposal_textinput_callback) def upload_button_callback(_attr, _old, new): nonlocal cami_meta with io.StringIO(base64.b64decode(new).decode()) as file: cami_meta = pyzebra.parse_h5meta(file) file_list = cami_meta["filelist"] file_select.options = [(entry, os.path.basename(entry)) for entry in file_list] upload_div = Div(text="or upload .cami file:", margin=(5, 5, 0, 5)) upload_button = FileInput(accept=".cami", width=200) upload_button.on_change("value", upload_button_callback) def update_image(index=None): if index is None: index = index_spinner.value current_image = det_data["data"][index] proj_v_line_source.data.update(x=np.arange(0, IMAGE_W) + 0.5, y=np.mean(current_image, axis=0)) proj_h_line_source.data.update(x=np.mean(current_image, axis=1), y=np.arange(0, IMAGE_H) + 0.5) image_source.data.update( h=[np.zeros((1, 1))], k=[np.zeros((1, 1))], l=[np.zeros((1, 1))], ) image_source.data.update(image=[current_image]) if main_auto_checkbox.active: im_min = np.min(current_image) im_max = np.max(current_image) display_min_spinner.value = im_min display_max_spinner.value = im_max image_glyph.color_mapper.low = im_min image_glyph.color_mapper.high = im_max if "mf" in det_data: metadata_table_source.data.update(mf=[det_data["mf"][index]]) else: metadata_table_source.data.update(mf=[None]) if "temp" in det_data: metadata_table_source.data.update(temp=[det_data["temp"][index]]) else: metadata_table_source.data.update(temp=[None]) gamma, nu = calculate_pol(det_data, index) omega = np.ones((IMAGE_H, IMAGE_W)) * det_data["omega"][index] image_source.data.update(gamma=[gamma], nu=[nu], omega=[omega]) def update_overview_plot(): h5_data = det_data["data"] n_im, n_y, n_x = h5_data.shape overview_x = np.mean(h5_data, axis=1) overview_y = np.mean(h5_data, axis=2) overview_plot_x_image_source.data.update(image=[overview_x], dw=[n_x], dh=[n_im]) overview_plot_y_image_source.data.update(image=[overview_y], dw=[n_y], dh=[n_im]) if proj_auto_checkbox.active: im_min = min(np.min(overview_x), np.min(overview_y)) im_max = max(np.max(overview_x), np.max(overview_y)) proj_display_min_spinner.value = im_min proj_display_max_spinner.value = im_max overview_plot_x_image_glyph.color_mapper.low = im_min overview_plot_y_image_glyph.color_mapper.low = im_min overview_plot_x_image_glyph.color_mapper.high = im_max overview_plot_y_image_glyph.color_mapper.high = im_max frame_range.start = 0 frame_range.end = n_im frame_range.reset_start = 0 frame_range.reset_end = n_im frame_range.bounds = (0, n_im) scan_motor = det_data["scan_motor"] overview_plot_y.axis[1].axis_label = f"Scanning motor, {scan_motor}" var = det_data[scan_motor] var_start = var[0] var_end = var[-1] + (var[-1] - var[0]) / (n_im - 1) scanning_motor_range.start = var_start scanning_motor_range.end = var_end scanning_motor_range.reset_start = var_start scanning_motor_range.reset_end = var_end # handle both, ascending and descending sequences scanning_motor_range.bounds = (min(var_start, var_end), max(var_start, var_end)) def file_select_callback(_attr, old, new): nonlocal det_data if not new: # skip empty selections return # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click) if len(new) > 1: # drop selection to the previous one file_select.value = old return if len(old) > 1: # skip unnecessary update caused by selection drop return det_data = pyzebra.read_detector_data(new[0]) if cami_meta and "crystal" in cami_meta: det_data["ub"] = cami_meta["crystal"]["UB"] index_spinner.value = 0 index_spinner.high = det_data["data"].shape[0] - 1 index_slider.end = det_data["data"].shape[0] - 1 zebra_mode = det_data["zebra_mode"] if zebra_mode == "nb": metadata_table_source.data.update(geom=["normal beam"]) else: # zebra_mode == "bi" metadata_table_source.data.update(geom=["bisecting"]) update_image(0) update_overview_plot() file_select = MultiSelect(title="Available .hdf files:", width=210, height=250) file_select.on_change("value", file_select_callback) def index_callback(_attr, _old, new): update_image(new) index_slider = Slider(value=0, start=0, end=1, show_value=False, width=400) index_spinner = Spinner(title="Image index:", value=0, low=0, width=100) index_spinner.on_change("value", index_callback) index_slider.js_link("value_throttled", index_spinner, "value") index_spinner.js_link("value", index_slider, "value") plot = Plot( x_range=Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)), y_range=Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)), plot_height=IMAGE_PLOT_H, plot_width=IMAGE_PLOT_W, toolbar_location="left", ) # ---- tools plot.toolbar.logo = None # ---- axes plot.add_layout(LinearAxis(), place="above") plot.add_layout(LinearAxis(major_label_orientation="vertical"), place="right") # ---- grid lines plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph image_source = ColumnDataSource( dict( image=[np.zeros((IMAGE_H, IMAGE_W), dtype="float32")], h=[np.zeros((1, 1))], k=[np.zeros((1, 1))], l=[np.zeros((1, 1))], gamma=[np.zeros((1, 1))], nu=[np.zeros((1, 1))], omega=[np.zeros((1, 1))], x=[0], y=[0], dw=[IMAGE_W], dh=[IMAGE_H], )) h_glyph = Image(image="h", x="x", y="y", dw="dw", dh="dh", global_alpha=0) k_glyph = Image(image="k", x="x", y="y", dw="dw", dh="dh", global_alpha=0) l_glyph = Image(image="l", x="x", y="y", dw="dw", dh="dh", global_alpha=0) gamma_glyph = Image(image="gamma", x="x", y="y", dw="dw", dh="dh", global_alpha=0) nu_glyph = Image(image="nu", x="x", y="y", dw="dw", dh="dh", global_alpha=0) omega_glyph = Image(image="omega", x="x", y="y", dw="dw", dh="dh", global_alpha=0) plot.add_glyph(image_source, h_glyph) plot.add_glyph(image_source, k_glyph) plot.add_glyph(image_source, l_glyph) plot.add_glyph(image_source, gamma_glyph) plot.add_glyph(image_source, nu_glyph) plot.add_glyph(image_source, omega_glyph) image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") plot.add_glyph(image_source, image_glyph, name="image_glyph") # ---- projections proj_v = Plot( x_range=plot.x_range, y_range=DataRange1d(), plot_height=150, plot_width=IMAGE_PLOT_W, toolbar_location=None, ) proj_v.add_layout(LinearAxis(major_label_orientation="vertical"), place="right") proj_v.add_layout(LinearAxis(major_label_text_font_size="0pt"), place="below") proj_v.add_layout(Grid(dimension=0, ticker=BasicTicker())) proj_v.add_layout(Grid(dimension=1, ticker=BasicTicker())) proj_v_line_source = ColumnDataSource(dict(x=[], y=[])) proj_v.add_glyph(proj_v_line_source, Line(x="x", y="y", line_color="steelblue")) proj_h = Plot( x_range=DataRange1d(), y_range=plot.y_range, plot_height=IMAGE_PLOT_H, plot_width=150, toolbar_location=None, ) proj_h.add_layout(LinearAxis(), place="above") proj_h.add_layout(LinearAxis(major_label_text_font_size="0pt"), place="left") proj_h.add_layout(Grid(dimension=0, ticker=BasicTicker())) proj_h.add_layout(Grid(dimension=1, ticker=BasicTicker())) proj_h_line_source = ColumnDataSource(dict(x=[], y=[])) proj_h.add_glyph(proj_h_line_source, Line(x="x", y="y", line_color="steelblue")) # add tools hovertool = HoverTool(tooltips=[ ("intensity", "@image"), ("gamma", "@gamma"), ("nu", "@nu"), ("omega", "@omega"), ("h", "@h"), ("k", "@k"), ("l", "@l"), ]) box_edit_source = ColumnDataSource(dict(x=[], y=[], width=[], height=[])) box_edit_glyph = Rect(x="x", y="y", width="width", height="height", fill_alpha=0, line_color="red") box_edit_renderer = plot.add_glyph(box_edit_source, box_edit_glyph) boxedittool = BoxEditTool(renderers=[box_edit_renderer], num_objects=1) def box_edit_callback(_attr, _old, new): if new["x"]: h5_data = det_data["data"] x_val = np.arange(h5_data.shape[0]) left = int(np.floor(new["x"][0])) right = int(np.ceil(new["x"][0] + new["width"][0])) bottom = int(np.floor(new["y"][0])) top = int(np.ceil(new["y"][0] + new["height"][0])) y_val = np.sum(h5_data[:, bottom:top, left:right], axis=(1, 2)) else: x_val = [] y_val = [] roi_avg_plot_line_source.data.update(x=x_val, y=y_val) box_edit_source.on_change("data", box_edit_callback) wheelzoomtool = WheelZoomTool(maintain_focus=False) plot.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), hovertool, boxedittool, ) plot.toolbar.active_scroll = wheelzoomtool # shared frame ranges frame_range = Range1d(0, 1, bounds=(0, 1)) scanning_motor_range = Range1d(0, 1, bounds=(0, 1)) det_x_range = Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)) overview_plot_x = Plot( title=Title(text="Projections on X-axis"), x_range=det_x_range, y_range=frame_range, extra_y_ranges={"scanning_motor": scanning_motor_range}, plot_height=400, plot_width=IMAGE_PLOT_W - 3, ) # ---- tools wheelzoomtool = WheelZoomTool(maintain_focus=False) overview_plot_x.toolbar.logo = None overview_plot_x.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), ) overview_plot_x.toolbar.active_scroll = wheelzoomtool # ---- axes overview_plot_x.add_layout(LinearAxis(axis_label="Coordinate X, pix"), place="below") overview_plot_x.add_layout(LinearAxis(axis_label="Frame", major_label_orientation="vertical"), place="left") # ---- grid lines overview_plot_x.add_layout(Grid(dimension=0, ticker=BasicTicker())) overview_plot_x.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph overview_plot_x_image_source = ColumnDataSource( dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_W], dh=[1])) overview_plot_x_image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") overview_plot_x.add_glyph(overview_plot_x_image_source, overview_plot_x_image_glyph, name="image_glyph") det_y_range = Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)) overview_plot_y = Plot( title=Title(text="Projections on Y-axis"), x_range=det_y_range, y_range=frame_range, extra_y_ranges={"scanning_motor": scanning_motor_range}, plot_height=400, plot_width=IMAGE_PLOT_H + 22, ) # ---- tools wheelzoomtool = WheelZoomTool(maintain_focus=False) overview_plot_y.toolbar.logo = None overview_plot_y.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), ) overview_plot_y.toolbar.active_scroll = wheelzoomtool # ---- axes overview_plot_y.add_layout(LinearAxis(axis_label="Coordinate Y, pix"), place="below") overview_plot_y.add_layout( LinearAxis( y_range_name="scanning_motor", axis_label="Scanning motor", major_label_orientation="vertical", ), place="right", ) # ---- grid lines overview_plot_y.add_layout(Grid(dimension=0, ticker=BasicTicker())) overview_plot_y.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph overview_plot_y_image_source = ColumnDataSource( dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[IMAGE_H], dh=[1])) overview_plot_y_image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") overview_plot_y.add_glyph(overview_plot_y_image_source, overview_plot_y_image_glyph, name="image_glyph") roi_avg_plot = Plot( x_range=DataRange1d(), y_range=DataRange1d(), plot_height=150, plot_width=IMAGE_PLOT_W, toolbar_location="left", ) # ---- tools roi_avg_plot.toolbar.logo = None # ---- axes roi_avg_plot.add_layout(LinearAxis(), place="below") roi_avg_plot.add_layout(LinearAxis(major_label_orientation="vertical"), place="left") # ---- grid lines roi_avg_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) roi_avg_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) roi_avg_plot_line_source = ColumnDataSource(dict(x=[], y=[])) roi_avg_plot.add_glyph(roi_avg_plot_line_source, Line(x="x", y="y", line_color="steelblue")) cmap_dict = { "gray": Greys256, "gray_reversed": Greys256[::-1], "plasma": Plasma256, "cividis": Cividis256, } def colormap_callback(_attr, _old, new): image_glyph.color_mapper = LinearColorMapper(palette=cmap_dict[new]) overview_plot_x_image_glyph.color_mapper = LinearColorMapper( palette=cmap_dict[new]) overview_plot_y_image_glyph.color_mapper = LinearColorMapper( palette=cmap_dict[new]) colormap = Select(title="Colormap:", options=list(cmap_dict.keys()), width=210) colormap.on_change("value", colormap_callback) colormap.value = "plasma" STEP = 1 def main_auto_checkbox_callback(state): if state: display_min_spinner.disabled = True display_max_spinner.disabled = True else: display_min_spinner.disabled = False display_max_spinner.disabled = False update_image() main_auto_checkbox = CheckboxGroup(labels=["Main Auto Range"], active=[0], width=145, margin=[10, 5, 0, 5]) main_auto_checkbox.on_click(main_auto_checkbox_callback) def display_max_spinner_callback(_attr, _old_value, new_value): display_min_spinner.high = new_value - STEP image_glyph.color_mapper.high = new_value display_max_spinner = Spinner( low=0 + STEP, value=1, step=STEP, disabled=bool(main_auto_checkbox.active), width=100, height=31, ) display_max_spinner.on_change("value", display_max_spinner_callback) def display_min_spinner_callback(_attr, _old_value, new_value): display_max_spinner.low = new_value + STEP image_glyph.color_mapper.low = new_value display_min_spinner = Spinner( low=0, high=1 - STEP, value=0, step=STEP, disabled=bool(main_auto_checkbox.active), width=100, height=31, ) display_min_spinner.on_change("value", display_min_spinner_callback) PROJ_STEP = 0.1 def proj_auto_checkbox_callback(state): if state: proj_display_min_spinner.disabled = True proj_display_max_spinner.disabled = True else: proj_display_min_spinner.disabled = False proj_display_max_spinner.disabled = False update_overview_plot() proj_auto_checkbox = CheckboxGroup(labels=["Projections Auto Range"], active=[0], width=145, margin=[10, 5, 0, 5]) proj_auto_checkbox.on_click(proj_auto_checkbox_callback) def proj_display_max_spinner_callback(_attr, _old_value, new_value): proj_display_min_spinner.high = new_value - PROJ_STEP overview_plot_x_image_glyph.color_mapper.high = new_value overview_plot_y_image_glyph.color_mapper.high = new_value proj_display_max_spinner = Spinner( low=0 + PROJ_STEP, value=1, step=PROJ_STEP, disabled=bool(proj_auto_checkbox.active), width=100, height=31, ) proj_display_max_spinner.on_change("value", proj_display_max_spinner_callback) def proj_display_min_spinner_callback(_attr, _old_value, new_value): proj_display_max_spinner.low = new_value + PROJ_STEP overview_plot_x_image_glyph.color_mapper.low = new_value overview_plot_y_image_glyph.color_mapper.low = new_value proj_display_min_spinner = Spinner( low=0, high=1 - PROJ_STEP, value=0, step=PROJ_STEP, disabled=bool(proj_auto_checkbox.active), width=100, height=31, ) proj_display_min_spinner.on_change("value", proj_display_min_spinner_callback) def hkl_button_callback(): index = index_spinner.value 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.on_click(hkl_button_callback) def events_list_callback(_attr, _old, new): doc.events_list_spind.value = new events_list = TextAreaInput(rows=7, width=830) events_list.on_change("value", events_list_callback) doc.events_list_hdf_viewer = events_list def add_event_button_callback(): diff_vec = [] p0 = [1.0, 0.0, 1.0] maxfev = 100000 wave = det_data["wave"] ddist = det_data["ddist"] gamma = det_data["gamma"][0] 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])) num_formatter = NumberFormatter(format="0.00", nan_format="") metadata_table = DataTable( source=metadata_table_source, columns=[ TableColumn(field="geom", title="Geometry", width=100), TableColumn(field="temp", title="Temperature", formatter=num_formatter, width=100), TableColumn(field="mf", title="Magnetic Field", formatter=num_formatter, width=100), ], width=300, height=50, autosize_mode="none", index_position=None, ) # Final layout import_layout = column(proposal_textinput, upload_div, upload_button, file_select) layout_image = column( gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False)) colormap_layout = column( colormap, main_auto_checkbox, row(display_min_spinner, display_max_spinner), proj_auto_checkbox, row(proj_display_min_spinner, proj_display_max_spinner), ) layout_controls = column( row(metadata_table, index_spinner, column(Spacer(height=25), index_slider)), row(add_event_button, hkl_button), row(events_list), ) layout_overview = column( gridplot( [[overview_plot_x, overview_plot_y]], toolbar_options=dict(logo=None), merge_tools=True, toolbar_location="left", ), ) tab_layout = row( column(import_layout, colormap_layout), column(layout_overview, layout_controls), column(roi_avg_plot, layout_image), ) return Panel(child=tab_layout, title="hdf viewer")
from bokeh.io import show from bokeh.models import CustomJS, TextAreaInput text_area_input = TextAreaInput(value="default", rows=6, title="Label:") text_area_input.js_on_change( "value", CustomJS(code=""" console.log('text_area_input: value=' + this.value, this.toString()) """)) show(text_area_input)
def create(): doc = curdoc() 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 lattice_const_textinput = TextInput( title="Lattice constants:", value="8.3211,8.3211,8.3211,90.00,90.00,90.00") max_res_spinner = Spinner(title="max-res:", value=2, step=0.01, width=145) seed_pool_size_spinner = Spinner(title="seed-pool-size:", value=5, step=0.01, width=145) seed_len_tol_spinner = Spinner(title="seed-len-tol:", value=0.02, step=0.01, width=145) seed_angle_tol_spinner = Spinner(title="seed-angle-tol:", value=1, step=0.01, width=145) eval_hkl_tol_spinner = Spinner(title="eval-hkl-tol:", value=0.15, step=0.01, width=145) diff_vec = [] ub_matrices = [] def process_button_callback(): # drop table selection to clear result fields results_table_source.selected.indices = [] nonlocal diff_vec with tempfile.TemporaryDirectory() as temp_dir: temp_peak_list_dir = os.path.join(temp_dir, "peak_list") os.mkdir(temp_peak_list_dir) temp_event_file = os.path.join(temp_peak_list_dir, "event-0.txt") temp_hkl_file = os.path.join(temp_dir, "hkl.h5") comp_proc = subprocess.run( [ "mpiexec", "-n", "2", "python", os.path.join(doc.spind_path, "gen_hkl_table.py"), lattice_const_textinput.value, "--max-res", str(max_res_spinner.value), "-o", temp_hkl_file, ], check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, ) print(" ".join(comp_proc.args)) print(comp_proc.stdout) # 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}:") with open(temp_event_file) as f: print(f.read()) comp_proc = subprocess.run( [ "mpiexec", "-n", "2", "python", os.path.join(doc.spind_path, "SPIND.py"), temp_peak_list_dir, temp_hkl_file, "-o", temp_dir, "--seed-pool-size", str(seed_pool_size_spinner.value), "--seed-len-tol", str(seed_len_tol_spinner.value), "--seed-angle-tol", str(seed_angle_tol_spinner.value), "--eval-hkl-tol", str(eval_hkl_tol_spinner.value), ], check=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, ) print(" ".join(comp_proc.args)) print(comp_proc.stdout) spind_out_file = os.path.join(temp_dir, "spind.txt") spind_res = dict( label=[], crystal_id=[], match_rate=[], matched_peaks=[], column_5=[], ub_matrix=[], ) try: with open(spind_out_file) as f_out: for line in f_out: c1, c2, c3, c4, c5, *c_rest = line.split() spind_res["label"].append(c1) spind_res["crystal_id"].append(c2) spind_res["match_rate"].append(c3) spind_res["matched_peaks"].append(c4) spind_res["column_5"].append(c5) # last digits are spind UB matrix vals = list(map(float, c_rest)) ub_matrix_spind = np.transpose( np.array(vals).reshape(3, 3)) ub_matrix = np.linalg.inv(ub_matrix_spind) ub_matrices.append(ub_matrix) spind_res["ub_matrix"].append( str(ub_matrix_spind * 1e-10)) print(f"Content of {spind_out_file}:") with open(spind_out_file) as f: print(f.read()) except FileNotFoundError: print("No results from spind") results_table_source.data.update(spind_res) process_button = Button(label="Process", button_type="primary") process_button.on_click(process_button_callback) if doc.spind_path is None: process_button.disabled = True ub_matrix_textareainput = TextAreaInput(title="UB matrix:", rows=7, width=400) hkl_textareainput = TextAreaInput(title="hkl values:", rows=7, width=400) def results_table_select_callback(_attr, old, new): if new: ind = new[0] ub_matrix = ub_matrices[ind] res = "" for vec in diff_vec: res += f"{ub_matrix @ vec}\n" ub_matrix_textareainput.value = str(ub_matrix * 1e10) hkl_textareainput.value = res else: ub_matrix_textareainput.value = "" hkl_textareainput.value = "" results_table_source = ColumnDataSource( dict(label=[], crystal_id=[], match_rate=[], matched_peaks=[], column_5=[], ub_matrix=[])) results_table = DataTable( source=results_table_source, columns=[ TableColumn(field="label", title="Label", width=50), TableColumn(field="crystal_id", title="Crystal ID", width=100), TableColumn(field="match_rate", title="Match Rate", width=100), TableColumn(field="matched_peaks", title="Matched Peaks", width=100), TableColumn(field="column_5", title="", width=100), TableColumn(field="ub_matrix", title="UB Matrix", width=700), ], height=300, width=1200, autosize_mode="none", index_position=None, ) 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)), ), ) return Panel(child=tab_layout, title="spind")
def get_layout(self): self.contributer_list = TextAreaInput( placeholder='Contributer names (include all)', rows=2, cols=3, title='Names of all Contributers') self.contributer_btn = Button(label='Update Contributer List', css_classes=['add_button'], width=300) self.connect_hdr = Div(text="Connect to Existing Night Log", css_classes=['subt-style'], width=800) self.init_hdr = Div(text="Update Tonight's Night Log", css_classes=['subt-style'], width=800) self.init_btn = Button(label="Update Tonight's Log", css_classes=['init_button'], width=200) self.os_name_1 = TextInput(title='Observing Scientist 1', placeholder='Ruth Bader Ginsberg') self.os_name_2 = TextInput(title='Observing Scientist 2', placeholder="Sandra Day O'Connor") self.dqs_name_1 = TextInput(title='Data Quality Scientist 1', placeholder='Sally Ride') self.dqs_name_2 = TextInput(title='Data Quality Scientist 2', placeholder="Mae Jemison") self.lo_names = [ 'None ', 'Liz Buckley-Geer', 'Ann Elliott', 'Parker Fagrelius', 'Satya Gontcho A Gontcho', 'James Lasker', 'Martin Landriau', 'Claire Poppett', 'Michael Schubnell', 'Luke Tyas', 'Other ' ] self.oa_names = [ 'None ', 'Karen Butler', 'Amy Robertson', 'Anthony Paat', 'Thaxton Smith', 'Dave Summers', 'Doug Williams', 'Other ' ] self.LO_1 = Select(title='Lead Observer 1', value='None', options=self.lo_names) self.LO_2 = Select(title='Lead Observer 2', value='None', options=self.lo_names) self.OA = Select(title='Observing Assistant', value='Choose One', options=self.oa_names) self.get_intro_layout() self.get_nl_layout() self.get_milestone_layout() self.get_plan_layout() self.get_os_exp_layout() self.get_prob_layout() self.get_checklist_layout() self.get_weather_layout() self.get_ns_layout() self.check_tab.title = 'OS Checklist' intro_layout = layout([ self.buffer, self.title, [self.page_logo, self.instructions], self.connect_hdr, [self.date_init, self.connect_bt ], self.connect_txt, self.line, self.init_hdr, [[self.os_name_1, self.os_name_2], [self.dqs_name_1, self.dqs_name_2], [self.LO_1, self.LO_2], self.OA], self.init_btn, self.line2, self.contributer_list, self.contributer_btn, self.nl_info, self.intro_txt ], width=1000) intro_tab = Panel(child=intro_layout, title="Initialization") self.layout = Tabs(tabs=[ intro_tab, self.plan_tab, self.milestone_tab, self.exp_tab, self.prob_tab, self.weather_tab, self.check_tab, self.nl_tab, self.ns_tab ], css_classes=['tabs-header'], sizing_mode="scale_both")
def prepare_server(doc, input_data, cell_stack, cell_markers=None, default_cell_marker=None): @lru_cache() def image_markers(lower=False, mapping=False): if mapping: return { y: j for j, y in sorted( ((i, x) for i, x in enumerate( image_markers(lower=lower, mapping=False))), key=lambda x: x[1].lower(), ) } if lower: return [ x.lower() for x in image_markers(lower=False, mapping=False) ] return (cell_markers if cell_markers is not None else [f"Marker {i + 1}" for i in range(cell_stack.shape[1])]) # Data sources ########################################################################### def prepare_data(input_data): data = input_data.copy() if "contour" in data and not all(x in data for x in ["contour_x", "contour_y"]): contour = parse_contour(data["contour"]) data["contour_x"] = contour[0] data["contour_y"] = contour[1] if "marked" not in data: data["marked"] = np.full(data.shape[0], "") source.data = data source = ColumnDataSource(data={}) prepare_data(input_data) image_source = ColumnDataSource( data=dict(image=[], dw=[], dh=[], contour_x=[], contour_y=[])) # Cell picture plot ########################################################################### def add_outline(): data = source.data if all(x in data for x in ["contour_x", "contour_y"]): cell_outline = cell_figure.patches( xs="contour_x", ys="contour_y", fill_color=None, line_color="red", name="cell_outline", source=image_source, ) cell_outline.level = "overlay" else: cell_outline = cell_figure.select(name="cell_outline") for x in cell_outline: cell_figure.renderers.remove(x) default_cell_marker = (0 if default_cell_marker is None else image_markers( mapping=True)[default_cell_marker]) cell_markers_select = Select( value=str(default_cell_marker), options=list( (str(i), x) for x, i in image_markers(mapping=True).items()), title="Marker cell image", ) cell_marker_input = AutocompleteInput( completions=list(image_markers()) + list(image_markers(lower=True)), min_characters=1, placeholder="Search for marker", ) cell_slider = RangeSlider(start=0, end=1, value=(0, 1), orientation="vertical", direction="rtl") metric_select = RadioButtonGroup(active=0, labels=CELL_IMAGE_METRICS[0]) stats = PreText(text="", width=100) cell_mapper = bokeh.models.mappers.LinearColorMapper(viridis(20), low=0, high=1000, high_color=None) cell_color_bar = ColorBar(color_mapper=cell_mapper, width=12, location=(0, 0)) cell_figure = figure( plot_width=450, plot_height=350, tools="pan,wheel_zoom,reset", toolbar_location="left", ) cell_image = cell_figure.image( image="image", color_mapper=cell_mapper, x=0, y=0, dw="dw", dh="dh", source=image_source, ) add_outline() cell_figure.add_layout(cell_color_bar, "right") # Edit data of selected cells ########################################################################### marker_edit_container = column() marker_edit_instances = [] def add_marker_edit_callback(): editor = ColumnEditor( source, marker_edit_container, log_widget=edit_selecton_log, editor_delete_callback=delete_marker_edit_callback, external_edit_callback=edit_selection_callback, ) marker_edit_instances.append(editor) def delete_marker_edit_callback(editor): idx = next(i for i, x in enumerate(marker_edit_instances) if x is editor) del marker_edit_instances[idx] file_name_text = Div() add_marker_edit_button = Button(label="+", button_type="success", align=("start", "end"), width=50) add_marker_edit_button.on_click(add_marker_edit_callback) edit_selection_submit = Button(label="Submit change", button_type="primary", align=("start", "end")) download_button = Button(label="Download edited data", button_type="success", align=("start", "end")) download_button.js_on_click( CustomJS(args=dict(source=source), code=DOWNLOAD_JS)) edit_selecton_log = TextAreaInput(value="", disabled=True, css_classes=["edit_log"], cols=30, rows=10) upload_file_input = FileInput(accept="text/csv", align=("end", "end")) # Cell table ########################################################################### default_data_table_cols = [ TableColumn(field="marked", title="Seen", width=20) ] data_table = DataTable(source=source, columns=default_data_table_cols, width=800) # Callbacks for buttons and widgets ########################################################################### def cell_slider_change(attrname, old, new): cell_mapper.low = new[0] cell_mapper.high = new[1] def selection_change(attrname, old, new): selected = source.selected.indices data = source.data if not selected: return mean_image = CELL_IMAGE_METRICS[1][metric_select.active]( cell_stack[selected, int(cell_markers_select.value), :, :], axis=0) image_data = { "image": [mean_image], "dw": [cell_stack.shape[2]], "dh": [cell_stack.shape[3]], } for coord in ["contour_x", "contour_y"]: try: image_data[coord] = list(data[coord][selected]) except KeyError: pass image_source.data = image_data image_extr = round_signif(mean_image.min()), round_signif( mean_image.max()) cell_slider.start = image_extr[0] cell_slider.end = image_extr[1] cell_slider.step = round_signif((image_extr[1] - image_extr[0]) / 50) cell_slider.value = image_extr stats.text = "n cells: " + str(len(selected)) def autocomplete_cell_change(attrname, old, new): try: idx = image_markers(mapping=True)[new] except KeyError: try: idx = image_markers(lower=True, mapping=True)[new] except KeyError: return cell_markers_select.value = str(idx) cell_marker_input.value = None def data_change(attrname, old, new): new_keys = [n for n in new.keys() if n not in set(old.keys())] for n in new_keys: data_table.columns.append(TableColumn(field=n, title=n)) def edit_selection_submit_click(): for x in marker_edit_instances: x.edit_callback() def edit_selection_callback(): idx = source.selected.indices try: if len(idx) == 1 and all( source.data[x.widgets["input_col"].value][idx] != "NA" for x in marker_edit_instances): source.selected.indices = [idx[0] + 1] except KeyError: pass def upload_file_callback(attrname, old, new): try: data_text = b64decode(new) data = pd.read_csv(BytesIO(data_text)) except Exception: file_name_text.text = f"Error loading file {upload_file_input.filename}" return file_name_text.text = f"Editing file {upload_file_input.filename}" # Have to regenerate contours try: del data["contour_x"] del data["contour_y"] except KeyError: pass data_table.columns = default_data_table_cols prepare_data(data) add_outline() source.selected.on_change("indices", selection_change) source.on_change("data", data_change) cell_slider.on_change("value", cell_slider_change) metric_select.on_change("active", selection_change) cell_markers_select.on_change("value", selection_change) cell_marker_input.on_change("value", autocomplete_cell_change) edit_selection_submit.on_click(edit_selection_submit_click) upload_file_input.on_change("value", upload_file_callback) style_div = Div(text=CUSTOM_CSS) # set up layout layout = column( row( column(data_table), column( cell_markers_select, cell_marker_input, metric_select, row(cell_figure, cell_slider), stats, ), ), file_name_text, marker_edit_container, add_marker_edit_button, row(edit_selection_submit, download_button, upload_file_input), edit_selecton_log, style_div, ) doc.add_root(layout) doc.title = "Cell classifier"
def create(): det_data = {} fit_params = {} js_data = ColumnDataSource( data=dict(content=["", ""], fname=["", ""], ext=["", ""])) def proposal_textinput_callback(_attr, _old, new): proposal = new.strip() for zebra_proposals_path in pyzebra.ZEBRA_PROPOSALS_PATHS: proposal_path = os.path.join(zebra_proposals_path, proposal) if os.path.isdir(proposal_path): # found it break else: raise ValueError(f"Can not find data for proposal '{proposal}'.") file_list = [] for file in os.listdir(proposal_path): if file.endswith((".ccl", ".dat")): file_list.append((os.path.join(proposal_path, file), file)) file_select.options = file_list file_open_button.disabled = False file_append_button.disabled = False proposal_textinput = TextInput(title="Proposal number:", width=210) proposal_textinput.on_change("value", proposal_textinput_callback) def _init_datatable(): scan_list = [s["idx"] for s in det_data] hkl = [f'{s["h"]} {s["k"]} {s["l"]}' for s in det_data] export = [s.get("active", True) for s in det_data] scan_table_source.data.update( scan=scan_list, hkl=hkl, fit=[0] * len(scan_list), export=export, ) scan_table_source.selected.indices = [] scan_table_source.selected.indices = [0] merge_options = [(str(i), f"{i} ({idx})") for i, idx in enumerate(scan_list)] merge_from_select.options = merge_options merge_from_select.value = merge_options[0][0] file_select = MultiSelect(title="Available .ccl/.dat files:", width=210, height=250) def file_open_button_callback(): nonlocal det_data det_data = [] for f_name in file_select.value: with open(f_name) as file: base, ext = os.path.splitext(f_name) if det_data: append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) pyzebra.merge_datasets(det_data, append_data) else: det_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(det_data, monitor_spinner.value) pyzebra.merge_duplicates(det_data) js_data.data.update(fname=[base, base]) _init_datatable() append_upload_button.disabled = False file_open_button = Button(label="Open New", width=100, disabled=True) file_open_button.on_click(file_open_button_callback) def file_append_button_callback(): for f_name in file_select.value: with open(f_name) as file: _, ext = os.path.splitext(f_name) append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) pyzebra.merge_datasets(det_data, append_data) _init_datatable() file_append_button = Button(label="Append", width=100, disabled=True) file_append_button.on_click(file_append_button_callback) def upload_button_callback(_attr, _old, new): nonlocal det_data det_data = [] for f_str, f_name in zip(new, upload_button.filename): with io.StringIO(base64.b64decode(f_str).decode()) as file: base, ext = os.path.splitext(f_name) if det_data: append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) pyzebra.merge_datasets(det_data, append_data) else: det_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(det_data, monitor_spinner.value) pyzebra.merge_duplicates(det_data) js_data.data.update(fname=[base, base]) _init_datatable() append_upload_button.disabled = False upload_div = Div(text="or upload new .ccl/.dat files:", margin=(5, 5, 0, 5)) upload_button = FileInput(accept=".ccl,.dat", multiple=True, width=200) upload_button.on_change("value", upload_button_callback) def append_upload_button_callback(_attr, _old, new): for f_str, f_name in zip(new, append_upload_button.filename): with io.StringIO(base64.b64decode(f_str).decode()) as file: _, ext = os.path.splitext(f_name) append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) pyzebra.merge_datasets(det_data, append_data) _init_datatable() append_upload_div = Div(text="append extra files:", margin=(5, 5, 0, 5)) append_upload_button = FileInput(accept=".ccl,.dat", multiple=True, width=200, disabled=True) append_upload_button.on_change("value", append_upload_button_callback) def monitor_spinner_callback(_attr, old, new): if det_data: pyzebra.normalize_dataset(det_data, new) _update_plot(_get_selected_scan()) monitor_spinner = Spinner(title="Monitor:", mode="int", value=100_000, low=1, width=145) monitor_spinner.on_change("value", monitor_spinner_callback) def _update_table(): fit_ok = [(1 if "fit" in scan else 0) for scan in det_data] scan_table_source.data.update(fit=fit_ok) def _update_plot(scan): scan_motor = scan["scan_motor"] y = scan["counts"] x = scan[scan_motor] plot.axis[0].axis_label = scan_motor plot_scatter_source.data.update(x=x, y=y, y_upper=y + np.sqrt(y), y_lower=y - np.sqrt(y)) fit = scan.get("fit") if fit is not None: x_fit = np.linspace(x[0], x[-1], 100) plot_fit_source.data.update(x=x_fit, y=fit.eval(x=x_fit)) x_bkg = [] y_bkg = [] xs_peak = [] ys_peak = [] comps = fit.eval_components(x=x_fit) for i, model in enumerate(fit_params): if "linear" in model: x_bkg = x_fit y_bkg = comps[f"f{i}_"] elif any(val in model for val in ("gaussian", "voigt", "pvoigt")): xs_peak.append(x_fit) ys_peak.append(comps[f"f{i}_"]) plot_bkg_source.data.update(x=x_bkg, y=y_bkg) plot_peak_source.data.update(xs=xs_peak, ys=ys_peak) fit_output_textinput.value = fit.fit_report() else: plot_fit_source.data.update(x=[], y=[]) plot_bkg_source.data.update(x=[], y=[]) plot_peak_source.data.update(xs=[], ys=[]) fit_output_textinput.value = "" # Main plot plot = Plot( x_range=DataRange1d(), y_range=DataRange1d(only_visible=True), plot_height=470, plot_width=700, ) plot.add_layout(LinearAxis(axis_label="Counts"), place="left") plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below") plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) plot_scatter_source = ColumnDataSource( dict(x=[0], y=[0], y_upper=[0], y_lower=[0])) plot_scatter = plot.add_glyph( plot_scatter_source, Scatter(x="x", y="y", line_color="steelblue")) plot.add_layout( Whisker(source=plot_scatter_source, base="x", upper="y_upper", lower="y_lower")) plot_fit_source = ColumnDataSource(dict(x=[0], y=[0])) plot_fit = plot.add_glyph(plot_fit_source, Line(x="x", y="y")) plot_bkg_source = ColumnDataSource(dict(x=[0], y=[0])) plot_bkg = plot.add_glyph( plot_bkg_source, Line(x="x", y="y", line_color="green", line_dash="dashed")) plot_peak_source = ColumnDataSource(dict(xs=[[0]], ys=[[0]])) plot_peak = plot.add_glyph( plot_peak_source, MultiLine(xs="xs", ys="ys", line_color="red", line_dash="dashed")) fit_from_span = Span(location=None, dimension="height", line_dash="dashed") plot.add_layout(fit_from_span) fit_to_span = Span(location=None, dimension="height", line_dash="dashed") plot.add_layout(fit_to_span) plot.add_layout( Legend( items=[ ("data", [plot_scatter]), ("best fit", [plot_fit]), ("peak", [plot_peak]), ("linear", [plot_bkg]), ], location="top_left", click_policy="hide", )) plot.add_tools(PanTool(), WheelZoomTool(), ResetTool()) plot.toolbar.logo = None # Scan select def scan_table_select_callback(_attr, old, new): if not new: # skip empty selections return # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click) if len(new) > 1: # drop selection to the previous one scan_table_source.selected.indices = old return if len(old) > 1: # skip unnecessary update caused by selection drop return _update_plot(det_data[new[0]]) def scan_table_source_callback(_attr, _old, _new): _update_preview() scan_table_source = ColumnDataSource( dict(scan=[], hkl=[], fit=[], export=[])) scan_table_source.on_change("data", scan_table_source_callback) scan_table = DataTable( source=scan_table_source, columns=[ TableColumn(field="scan", title="Scan", width=50), TableColumn(field="hkl", title="hkl", width=100), TableColumn(field="fit", title="Fit", width=50), TableColumn(field="export", title="Export", editor=CheckboxEditor(), width=50), ], width=310, # +60 because of the index column height=350, autosize_mode="none", editable=True, ) scan_table_source.selected.on_change("indices", scan_table_select_callback) def _get_selected_scan(): return det_data[scan_table_source.selected.indices[0]] merge_from_select = Select(title="scan:", width=145) def merge_button_callback(): scan_into = _get_selected_scan() scan_from = det_data[int(merge_from_select.value)] if scan_into is scan_from: print("WARNING: Selected scans for merging are identical") return pyzebra.merge_scans(scan_into, scan_from) _update_plot(_get_selected_scan()) merge_button = Button(label="Merge into current", width=145) merge_button.on_click(merge_button_callback) def restore_button_callback(): pyzebra.restore_scan(_get_selected_scan()) _update_plot(_get_selected_scan()) restore_button = Button(label="Restore scan", width=145) restore_button.on_click(restore_button_callback) def fit_from_spinner_callback(_attr, _old, new): fit_from_span.location = new fit_from_spinner = Spinner(title="Fit from:", width=145) fit_from_spinner.on_change("value", fit_from_spinner_callback) def fit_to_spinner_callback(_attr, _old, new): fit_to_span.location = new fit_to_spinner = Spinner(title="to:", width=145) fit_to_spinner.on_change("value", fit_to_spinner_callback) def fitparams_add_dropdown_callback(click): # bokeh requires (str, str) for MultiSelect options new_tag = f"{click.item}-{fitparams_select.tags[0]}" fitparams_select.options.append((new_tag, click.item)) fit_params[new_tag] = fitparams_factory(click.item) fitparams_select.tags[0] += 1 fitparams_add_dropdown = Dropdown( label="Add fit function", menu=[ ("Linear", "linear"), ("Gaussian", "gaussian"), ("Voigt", "voigt"), ("Pseudo Voigt", "pvoigt"), # ("Pseudo Voigt1", "pseudovoigt1"), ], width=145, ) fitparams_add_dropdown.on_click(fitparams_add_dropdown_callback) def fitparams_select_callback(_attr, old, new): # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click) if len(new) > 1: # drop selection to the previous one fitparams_select.value = old return if len(old) > 1: # skip unnecessary update caused by selection drop return if new: fitparams_table_source.data.update(fit_params[new[0]]) else: fitparams_table_source.data.update( dict(param=[], value=[], vary=[], min=[], max=[])) fitparams_select = MultiSelect(options=[], height=120, width=145) fitparams_select.tags = [0] fitparams_select.on_change("value", fitparams_select_callback) def fitparams_remove_button_callback(): if fitparams_select.value: sel_tag = fitparams_select.value[0] del fit_params[sel_tag] for elem in fitparams_select.options: if elem[0] == sel_tag: fitparams_select.options.remove(elem) break fitparams_select.value = [] fitparams_remove_button = Button(label="Remove fit function", width=145) fitparams_remove_button.on_click(fitparams_remove_button_callback) def fitparams_factory(function): if function == "linear": params = ["slope", "intercept"] elif function == "gaussian": params = ["amplitude", "center", "sigma"] elif function == "voigt": params = ["amplitude", "center", "sigma", "gamma"] elif function == "pvoigt": params = ["amplitude", "center", "sigma", "fraction"] elif function == "pseudovoigt1": params = ["amplitude", "center", "g_sigma", "l_sigma", "fraction"] else: raise ValueError("Unknown fit function") n = len(params) fitparams = dict( param=params, value=[None] * n, vary=[True] * n, min=[None] * n, max=[None] * n, ) if function == "linear": fitparams["value"] = [0, 1] fitparams["vary"] = [False, True] fitparams["min"] = [None, 0] elif function == "gaussian": fitparams["min"] = [0, None, None] return fitparams fitparams_table_source = ColumnDataSource( dict(param=[], value=[], vary=[], min=[], max=[])) fitparams_table = DataTable( source=fitparams_table_source, columns=[ TableColumn(field="param", title="Parameter"), TableColumn(field="value", title="Value", editor=NumberEditor()), TableColumn(field="vary", title="Vary", editor=CheckboxEditor()), TableColumn(field="min", title="Min", editor=NumberEditor()), TableColumn(field="max", title="Max", editor=NumberEditor()), ], height=200, width=350, index_position=None, editable=True, auto_edit=True, ) # start with `background` and `gauss` fit functions added fitparams_add_dropdown_callback(types.SimpleNamespace(item="linear")) fitparams_add_dropdown_callback(types.SimpleNamespace(item="gaussian")) fitparams_select.value = ["gaussian-1"] # add selection to gauss fit_output_textinput = TextAreaInput(title="Fit results:", width=750, height=200) def proc_all_button_callback(): for scan, export in zip(det_data, scan_table_source.data["export"]): if export: pyzebra.fit_scan(scan, fit_params, fit_from=fit_from_spinner.value, fit_to=fit_to_spinner.value) pyzebra.get_area( scan, area_method=AREA_METHODS[area_method_radiobutton.active], lorentz=lorentz_checkbox.active, ) _update_plot(_get_selected_scan()) _update_table() proc_all_button = Button(label="Process All", button_type="primary", width=145) proc_all_button.on_click(proc_all_button_callback) def proc_button_callback(): scan = _get_selected_scan() pyzebra.fit_scan(scan, fit_params, fit_from=fit_from_spinner.value, fit_to=fit_to_spinner.value) pyzebra.get_area( scan, area_method=AREA_METHODS[area_method_radiobutton.active], lorentz=lorentz_checkbox.active, ) _update_plot(scan) _update_table() proc_button = Button(label="Process Current", width=145) proc_button.on_click(proc_button_callback) area_method_div = Div(text="Intensity:", margin=(5, 5, 0, 5)) area_method_radiobutton = RadioGroup(labels=["Function", "Area"], active=0, width=145) lorentz_checkbox = CheckboxGroup(labels=["Lorentz Correction"], width=145, margin=(13, 5, 5, 5)) export_preview_textinput = TextAreaInput(title="Export file preview:", width=500, height=400) def _update_preview(): with tempfile.TemporaryDirectory() as temp_dir: temp_file = temp_dir + "/temp" export_data = [] for s, export in zip(det_data, scan_table_source.data["export"]): if export: export_data.append(s) pyzebra.export_1D( export_data, temp_file, export_target_select.value, hkl_precision=int(hkl_precision_select.value), ) exported_content = "" file_content = [] for ext in EXPORT_TARGETS[export_target_select.value]: fname = temp_file + ext if os.path.isfile(fname): with open(fname) as f: content = f.read() exported_content += f"{ext} file:\n" + content else: content = "" file_content.append(content) js_data.data.update(content=file_content) export_preview_textinput.value = exported_content def export_target_select_callback(_attr, _old, new): js_data.data.update(ext=EXPORT_TARGETS[new]) _update_preview() export_target_select = Select(title="Export target:", options=list(EXPORT_TARGETS.keys()), value="fullprof", width=80) export_target_select.on_change("value", export_target_select_callback) js_data.data.update(ext=EXPORT_TARGETS[export_target_select.value]) def hkl_precision_select_callback(_attr, _old, _new): _update_preview() hkl_precision_select = Select(title="hkl precision:", options=["2", "3", "4"], value="2", width=80) hkl_precision_select.on_change("value", hkl_precision_select_callback) save_button = Button(label="Download File(s)", button_type="success", width=200) save_button.js_on_click( CustomJS(args={"js_data": js_data}, code=javaScript)) fitpeak_controls = row( column(fitparams_add_dropdown, fitparams_select, fitparams_remove_button), fitparams_table, Spacer(width=20), column(fit_from_spinner, lorentz_checkbox, area_method_div, area_method_radiobutton), column(fit_to_spinner, proc_button, proc_all_button), ) scan_layout = column( scan_table, row(monitor_spinner, column(Spacer(height=19), restore_button)), row(column(Spacer(height=19), merge_button), merge_from_select), ) import_layout = column( proposal_textinput, file_select, row(file_open_button, file_append_button), upload_div, upload_button, append_upload_div, append_upload_button, ) export_layout = column( export_preview_textinput, row(export_target_select, hkl_precision_select, column(Spacer(height=19), row(save_button))), ) tab_layout = column( row(import_layout, scan_layout, plot, Spacer(width=30), export_layout), row(fitpeak_controls, fit_output_textinput), ) return Panel(child=tab_layout, title="ccl integrate")
sel_plot = Dropdown(label='Select plot type', button_type='success', menu=options, value='line') add_row = FileInput() inp_id = TextInput( placeholder='Insert ID', value='1', ) sh_ess = TextAreaInput( title='Essay %s: 338 words' % inp_id.value, rows=30, cols=50, value= """Dear local newspaper, I think effects computers have on people are great learning skills/affects because they give us time to chat with friends/new people, helps us learn about the globe(astronomy) and keeps us out of troble! Thing about! Dont you think so? How would you feel if your teenager is always on the phone with friends! Do you ever time to chat with your friends or buisness partner about things. Well now - there's a new way to chat the computer, theirs plenty of sites on the internet to do so: @ORGANIZATION1, @ORGANIZATION2, @CAPS1, facebook, myspace ect. Just think now while your setting up meeting with your boss on the computer, your teenager is having fun on the phone not rushing to get off cause you want to use it. How did you learn about other countrys/states outside of yours? Well I have by computer/internet, it's a new way to learn about what going on in our time! You might think your child spends a lot of time on the computer, but ask them so question about the economy, sea floor spreading or even about the @DATE1's you'll be surprise at how much he/she knows. Believe it or not the computer is much interesting then in class all day reading out of books. If your child is home on your computer or at a local library, it's better than being out with friends being fresh, or being perpressured to doing something they know isnt right. You might not know where your child is, @CAPS2 forbidde in a hospital bed because of a drive-by. Rather than your child on the computer learning, chatting or just playing games, safe and sound in your home or community place. Now I hope you have reached a point to understand and agree with me, because computers can have great effects on you or child because it gives us time to chat with friends/new people, helps us learn about the globe and believe or not keeps us out of troble. Thank you for listening.""" ) # ------------------------------------------------------------------------------ # Define functionality of controls num_tokens.on_change('value', update) sel_yaxis.on_change('value', update) sel_xaxis.on_change('value', update) sel_plot.on_change('value', update) add_row.on_change('value', change_file) inp_id.on_change('value', update_pie) # ------------------------------------------------------------------------------ # Define variable which holds the different columns of our dataframe
#data source from sklearn.datasets import load_iris iris = load_iris() df = pd.DataFrame(iris.data, columns=iris.feature_names) df["Species"] = pd.DataFrame(iris.target) df["Species"] = df["Species"].apply(lambda x: "A" if x == 0 else "B" if x == 1 else "C") #widgets for the model select_default = "A" select = Select(title="Product:", value=select_default, options=["A", "B", "C"]) select.max_width = 200 text_input = TextAreaInput(value='A', rows=6, title="Selected Product") text_input.max_width = 200 text_input.max_height = 70 # text_input.background_fill_color = "beige" colormap = {'A': 'red', 'B': 'green', 'C': 'blue'} df['colors'] = [colormap[x] for x in df['Species']] #dataource for the plots df1 = df.copy() df = df[df["Species"] == select_default] source = ColumnDataSource(df) group = df1.groupby("Species") source1 = ColumnDataSource(group)
def create(): det_data = [] fit_params = {} js_data = ColumnDataSource(data=dict(content=["", ""], fname=["", ""])) def proposal_textinput_callback(_attr, _old, new): proposal = new.strip() for zebra_proposals_path in pyzebra.ZEBRA_PROPOSALS_PATHS: proposal_path = os.path.join(zebra_proposals_path, proposal) if os.path.isdir(proposal_path): # found it break else: raise ValueError(f"Can not find data for proposal '{proposal}'.") file_list = [] for file in os.listdir(proposal_path): if file.endswith((".ccl", ".dat")): file_list.append((os.path.join(proposal_path, file), file)) file_select.options = file_list file_open_button.disabled = False file_append_button.disabled = False proposal_textinput = TextInput(title="Proposal number:", width=210) proposal_textinput.on_change("value", proposal_textinput_callback) def _init_datatable(): scan_list = [s["idx"] for s in det_data] file_list = [] for scan in det_data: file_list.append(os.path.basename(scan["original_filename"])) scan_table_source.data.update( file=file_list, scan=scan_list, param=[None] * len(scan_list), fit=[0] * len(scan_list), export=[True] * len(scan_list), ) scan_table_source.selected.indices = [] scan_table_source.selected.indices = [0] scan_motor_select.options = det_data[0]["scan_motors"] scan_motor_select.value = det_data[0]["scan_motor"] param_select.value = "user defined" file_select = MultiSelect(title="Available .ccl/.dat files:", width=210, height=250) def file_open_button_callback(): nonlocal det_data det_data = [] for f_name in file_select.value: with open(f_name) as file: base, ext = os.path.splitext(f_name) if det_data: append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) det_data.extend(append_data) else: det_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(det_data, monitor_spinner.value) js_data.data.update( fname=[base + ".comm", base + ".incomm"]) _init_datatable() append_upload_button.disabled = False file_open_button = Button(label="Open New", width=100, disabled=True) file_open_button.on_click(file_open_button_callback) def file_append_button_callback(): for f_name in file_select.value: with open(f_name) as file: _, ext = os.path.splitext(f_name) append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) det_data.extend(append_data) _init_datatable() file_append_button = Button(label="Append", width=100, disabled=True) file_append_button.on_click(file_append_button_callback) def upload_button_callback(_attr, _old, new): nonlocal det_data det_data = [] for f_str, f_name in zip(new, upload_button.filename): with io.StringIO(base64.b64decode(f_str).decode()) as file: base, ext = os.path.splitext(f_name) if det_data: append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) det_data.extend(append_data) else: det_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(det_data, monitor_spinner.value) js_data.data.update( fname=[base + ".comm", base + ".incomm"]) _init_datatable() append_upload_button.disabled = False upload_div = Div(text="or upload new .ccl/.dat files:", margin=(5, 5, 0, 5)) upload_button = FileInput(accept=".ccl,.dat", multiple=True, width=200) upload_button.on_change("value", upload_button_callback) def append_upload_button_callback(_attr, _old, new): for f_str, f_name in zip(new, append_upload_button.filename): with io.StringIO(base64.b64decode(f_str).decode()) as file: _, ext = os.path.splitext(f_name) append_data = pyzebra.parse_1D(file, ext) pyzebra.normalize_dataset(append_data, monitor_spinner.value) det_data.extend(append_data) _init_datatable() append_upload_div = Div(text="append extra files:", margin=(5, 5, 0, 5)) append_upload_button = FileInput(accept=".ccl,.dat", multiple=True, width=200, disabled=True) append_upload_button.on_change("value", append_upload_button_callback) def monitor_spinner_callback(_attr, _old, new): if det_data: pyzebra.normalize_dataset(det_data, new) _update_plot() monitor_spinner = Spinner(title="Monitor:", mode="int", value=100_000, low=1, width=145) monitor_spinner.on_change("value", monitor_spinner_callback) def scan_motor_select_callback(_attr, _old, new): if det_data: for scan in det_data: scan["scan_motor"] = new _update_plot() scan_motor_select = Select(title="Scan motor:", options=[], width=145) scan_motor_select.on_change("value", scan_motor_select_callback) def _update_table(): fit_ok = [(1 if "fit" in scan else 0) for scan in det_data] scan_table_source.data.update(fit=fit_ok) def _update_plot(): _update_single_scan_plot(_get_selected_scan()) _update_overview() def _update_single_scan_plot(scan): scan_motor = scan["scan_motor"] y = scan["counts"] x = scan[scan_motor] plot.axis[0].axis_label = scan_motor plot_scatter_source.data.update(x=x, y=y, y_upper=y + np.sqrt(y), y_lower=y - np.sqrt(y)) fit = scan.get("fit") if fit is not None: x_fit = np.linspace(x[0], x[-1], 100) plot_fit_source.data.update(x=x_fit, y=fit.eval(x=x_fit)) x_bkg = [] y_bkg = [] xs_peak = [] ys_peak = [] comps = fit.eval_components(x=x_fit) for i, model in enumerate(fit_params): if "linear" in model: x_bkg = x_fit y_bkg = comps[f"f{i}_"] elif any(val in model for val in ("gaussian", "voigt", "pvoigt")): xs_peak.append(x_fit) ys_peak.append(comps[f"f{i}_"]) plot_bkg_source.data.update(x=x_bkg, y=y_bkg) plot_peak_source.data.update(xs=xs_peak, ys=ys_peak) fit_output_textinput.value = fit.fit_report() else: plot_fit_source.data.update(x=[], y=[]) plot_bkg_source.data.update(x=[], y=[]) plot_peak_source.data.update(xs=[], ys=[]) fit_output_textinput.value = "" def _update_overview(): xs = [] ys = [] param = [] x = [] y = [] par = [] for s, p in enumerate(scan_table_source.data["param"]): if p is not None: scan = det_data[s] scan_motor = scan["scan_motor"] xs.append(scan[scan_motor]) x.extend(scan[scan_motor]) ys.append(scan["counts"]) y.extend([float(p)] * len(scan[scan_motor])) param.append(float(p)) par.extend(scan["counts"]) if det_data: scan_motor = det_data[0]["scan_motor"] ov_plot.axis[0].axis_label = scan_motor ov_param_plot.axis[0].axis_label = scan_motor ov_plot_mline_source.data.update(xs=xs, ys=ys, param=param, color=color_palette(len(xs))) if y: mapper["transform"].low = np.min([np.min(y) for y in ys]) mapper["transform"].high = np.max([np.max(y) for y in ys]) ov_param_plot_scatter_source.data.update(x=x, y=y, param=par) if y: interp_f = interpolate.interp2d(x, y, par) x1, x2 = min(x), max(x) y1, y2 = min(y), max(y) image = interp_f( np.linspace(x1, x2, ov_param_plot.inner_width // 10), np.linspace(y1, y2, ov_param_plot.inner_height // 10), assume_sorted=True, ) ov_param_plot_image_source.data.update(image=[image], x=[x1], y=[y1], dw=[x2 - x1], dh=[y2 - y1]) else: ov_param_plot_image_source.data.update(image=[], x=[], y=[], dw=[], dh=[]) def _update_param_plot(): x = [] y = [] fit_param = fit_param_select.value for s, p in zip(det_data, scan_table_source.data["param"]): if "fit" in s and fit_param: x.append(p) y.append(s["fit"].values[fit_param]) param_plot_scatter_source.data.update(x=x, y=y) # Main plot plot = Plot( x_range=DataRange1d(), y_range=DataRange1d(only_visible=True), plot_height=450, plot_width=700, ) plot.add_layout(LinearAxis(axis_label="Counts"), place="left") plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below") plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) plot_scatter_source = ColumnDataSource( dict(x=[0], y=[0], y_upper=[0], y_lower=[0])) plot_scatter = plot.add_glyph( plot_scatter_source, Scatter(x="x", y="y", line_color="steelblue")) plot.add_layout( Whisker(source=plot_scatter_source, base="x", upper="y_upper", lower="y_lower")) plot_fit_source = ColumnDataSource(dict(x=[0], y=[0])) plot_fit = plot.add_glyph(plot_fit_source, Line(x="x", y="y")) plot_bkg_source = ColumnDataSource(dict(x=[0], y=[0])) plot_bkg = plot.add_glyph( plot_bkg_source, Line(x="x", y="y", line_color="green", line_dash="dashed")) plot_peak_source = ColumnDataSource(dict(xs=[[0]], ys=[[0]])) plot_peak = plot.add_glyph( plot_peak_source, MultiLine(xs="xs", ys="ys", line_color="red", line_dash="dashed")) fit_from_span = Span(location=None, dimension="height", line_dash="dashed") plot.add_layout(fit_from_span) fit_to_span = Span(location=None, dimension="height", line_dash="dashed") plot.add_layout(fit_to_span) plot.add_layout( Legend( items=[ ("data", [plot_scatter]), ("best fit", [plot_fit]), ("peak", [plot_peak]), ("linear", [plot_bkg]), ], location="top_left", click_policy="hide", )) plot.add_tools(PanTool(), WheelZoomTool(), ResetTool()) plot.toolbar.logo = None # Overview multilines plot ov_plot = Plot(x_range=DataRange1d(), y_range=DataRange1d(), plot_height=450, plot_width=700) ov_plot.add_layout(LinearAxis(axis_label="Counts"), place="left") ov_plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below") ov_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) ov_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) ov_plot_mline_source = ColumnDataSource( dict(xs=[], ys=[], param=[], color=[])) ov_plot.add_glyph(ov_plot_mline_source, MultiLine(xs="xs", ys="ys", line_color="color")) hover_tool = HoverTool(tooltips=[("param", "@param")]) ov_plot.add_tools(PanTool(), WheelZoomTool(), hover_tool, ResetTool()) ov_plot.add_tools(PanTool(), WheelZoomTool(), ResetTool()) ov_plot.toolbar.logo = None # Overview perams plot ov_param_plot = Plot(x_range=DataRange1d(), y_range=DataRange1d(), plot_height=450, plot_width=700) ov_param_plot.add_layout(LinearAxis(axis_label="Param"), place="left") ov_param_plot.add_layout(LinearAxis(axis_label="Scan motor"), place="below") ov_param_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) ov_param_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) ov_param_plot_image_source = ColumnDataSource( dict(image=[], x=[], y=[], dw=[], dh=[])) ov_param_plot.add_glyph( ov_param_plot_image_source, Image(image="image", x="x", y="y", dw="dw", dh="dh")) ov_param_plot_scatter_source = ColumnDataSource(dict(x=[], y=[], param=[])) mapper = linear_cmap(field_name="param", palette=Turbo256, low=0, high=50) ov_param_plot.add_glyph( ov_param_plot_scatter_source, Scatter(x="x", y="y", line_color=mapper, fill_color=mapper, size=10), ) ov_param_plot.add_tools(PanTool(), WheelZoomTool(), ResetTool()) ov_param_plot.toolbar.logo = None # Parameter plot param_plot = Plot(x_range=DataRange1d(), y_range=DataRange1d(), plot_height=400, plot_width=700) param_plot.add_layout(LinearAxis(axis_label="Fit parameter"), place="left") param_plot.add_layout(LinearAxis(axis_label="Parameter"), place="below") param_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) param_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) param_plot_scatter_source = ColumnDataSource(dict(x=[], y=[])) param_plot.add_glyph(param_plot_scatter_source, Scatter(x="x", y="y")) param_plot.add_tools(PanTool(), WheelZoomTool(), ResetTool()) param_plot.toolbar.logo = None def fit_param_select_callback(_attr, _old, _new): _update_param_plot() fit_param_select = Select(title="Fit parameter", options=[], width=145) fit_param_select.on_change("value", fit_param_select_callback) # 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"), ]) # Scan select def scan_table_select_callback(_attr, old, new): if not new: # skip empty selections return # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click) if len(new) > 1: # drop selection to the previous one scan_table_source.selected.indices = old return if len(old) > 1: # skip unnecessary update caused by selection drop return _update_plot() def scan_table_source_callback(_attr, _old, _new): _update_preview() scan_table_source = ColumnDataSource( dict(file=[], scan=[], param=[], fit=[], export=[])) scan_table_source.on_change("data", scan_table_source_callback) scan_table = DataTable( source=scan_table_source, columns=[ TableColumn(field="file", title="file", width=150), TableColumn(field="scan", title="scan", width=50), TableColumn(field="param", title="param", editor=NumberEditor(), width=50), TableColumn(field="fit", title="Fit", width=50), TableColumn(field="export", title="Export", editor=CheckboxEditor(), width=50), ], width=410, # +60 because of the index column editable=True, autosize_mode="none", ) def scan_table_source_callback(_attr, _old, _new): if scan_table_source.selected.indices: _update_plot() scan_table_source.selected.on_change("indices", scan_table_select_callback) scan_table_source.on_change("data", scan_table_source_callback) def _get_selected_scan(): return det_data[scan_table_source.selected.indices[0]] def param_select_callback(_attr, _old, new): if new == "user defined": param = [None] * len(det_data) else: param = [scan[new] for scan in det_data] scan_table_source.data["param"] = param _update_param_plot() param_select = Select( title="Parameter:", options=["user defined", "temp", "mf", "h", "k", "l"], value="user defined", width=145, ) param_select.on_change("value", param_select_callback) def fit_from_spinner_callback(_attr, _old, new): fit_from_span.location = new fit_from_spinner = Spinner(title="Fit from:", width=145) fit_from_spinner.on_change("value", fit_from_spinner_callback) def fit_to_spinner_callback(_attr, _old, new): fit_to_span.location = new fit_to_spinner = Spinner(title="to:", width=145) fit_to_spinner.on_change("value", fit_to_spinner_callback) def fitparams_add_dropdown_callback(click): # bokeh requires (str, str) for MultiSelect options new_tag = f"{click.item}-{fitparams_select.tags[0]}" fitparams_select.options.append((new_tag, click.item)) fit_params[new_tag] = fitparams_factory(click.item) fitparams_select.tags[0] += 1 fitparams_add_dropdown = Dropdown( label="Add fit function", menu=[ ("Linear", "linear"), ("Gaussian", "gaussian"), ("Voigt", "voigt"), ("Pseudo Voigt", "pvoigt"), # ("Pseudo Voigt1", "pseudovoigt1"), ], width=145, ) fitparams_add_dropdown.on_click(fitparams_add_dropdown_callback) def fitparams_select_callback(_attr, old, new): # Avoid selection of multiple indicies (via Shift+Click or Ctrl+Click) if len(new) > 1: # drop selection to the previous one fitparams_select.value = old return if len(old) > 1: # skip unnecessary update caused by selection drop return if new: fitparams_table_source.data.update(fit_params[new[0]]) else: fitparams_table_source.data.update( dict(param=[], value=[], vary=[], min=[], max=[])) fitparams_select = MultiSelect(options=[], height=120, width=145) fitparams_select.tags = [0] fitparams_select.on_change("value", fitparams_select_callback) def fitparams_remove_button_callback(): if fitparams_select.value: sel_tag = fitparams_select.value[0] del fit_params[sel_tag] for elem in fitparams_select.options: if elem[0] == sel_tag: fitparams_select.options.remove(elem) break fitparams_select.value = [] fitparams_remove_button = Button(label="Remove fit function", width=145) fitparams_remove_button.on_click(fitparams_remove_button_callback) def fitparams_factory(function): if function == "linear": params = ["slope", "intercept"] elif function == "gaussian": params = ["amplitude", "center", "sigma"] elif function == "voigt": params = ["amplitude", "center", "sigma", "gamma"] elif function == "pvoigt": params = ["amplitude", "center", "sigma", "fraction"] elif function == "pseudovoigt1": params = ["amplitude", "center", "g_sigma", "l_sigma", "fraction"] else: raise ValueError("Unknown fit function") n = len(params) fitparams = dict( param=params, value=[None] * n, vary=[True] * n, min=[None] * n, max=[None] * n, ) if function == "linear": fitparams["value"] = [0, 1] fitparams["vary"] = [False, True] fitparams["min"] = [None, 0] elif function == "gaussian": fitparams["min"] = [0, None, None] return fitparams fitparams_table_source = ColumnDataSource( dict(param=[], value=[], vary=[], min=[], max=[])) fitparams_table = DataTable( source=fitparams_table_source, columns=[ TableColumn(field="param", title="Parameter"), TableColumn(field="value", title="Value", editor=NumberEditor()), TableColumn(field="vary", title="Vary", editor=CheckboxEditor()), TableColumn(field="min", title="Min", editor=NumberEditor()), TableColumn(field="max", title="Max", editor=NumberEditor()), ], height=200, width=350, index_position=None, editable=True, auto_edit=True, ) # start with `background` and `gauss` fit functions added fitparams_add_dropdown_callback(types.SimpleNamespace(item="linear")) fitparams_add_dropdown_callback(types.SimpleNamespace(item="gaussian")) fitparams_select.value = ["gaussian-1"] # add selection to gauss fit_output_textinput = TextAreaInput(title="Fit results:", width=750, height=200) def proc_all_button_callback(): for scan, export in zip(det_data, scan_table_source.data["export"]): if export: pyzebra.fit_scan(scan, fit_params, fit_from=fit_from_spinner.value, fit_to=fit_to_spinner.value) pyzebra.get_area( scan, area_method=AREA_METHODS[area_method_radiobutton.active], lorentz=lorentz_checkbox.active, ) _update_plot() _update_table() for scan in det_data: if "fit" in scan: options = list(scan["fit"].params.keys()) fit_param_select.options = options fit_param_select.value = options[0] break _update_param_plot() proc_all_button = Button(label="Process All", button_type="primary", width=145) proc_all_button.on_click(proc_all_button_callback) def proc_button_callback(): scan = _get_selected_scan() pyzebra.fit_scan(scan, fit_params, fit_from=fit_from_spinner.value, fit_to=fit_to_spinner.value) pyzebra.get_area( scan, area_method=AREA_METHODS[area_method_radiobutton.active], lorentz=lorentz_checkbox.active, ) _update_plot() _update_table() for scan in det_data: if "fit" in scan: options = list(scan["fit"].params.keys()) fit_param_select.options = options fit_param_select.value = options[0] break _update_param_plot() proc_button = Button(label="Process Current", width=145) proc_button.on_click(proc_button_callback) area_method_div = Div(text="Intensity:", margin=(5, 5, 0, 5)) area_method_radiobutton = RadioGroup(labels=["Function", "Area"], active=0, width=145) lorentz_checkbox = CheckboxGroup(labels=["Lorentz Correction"], width=145, margin=(13, 5, 5, 5)) export_preview_textinput = TextAreaInput(title="Export file preview:", width=450, height=400) def _update_preview(): with tempfile.TemporaryDirectory() as temp_dir: temp_file = temp_dir + "/temp" export_data = [] for s, export in zip(det_data, scan_table_source.data["export"]): if export: export_data.append(s) # pyzebra.export_1D(export_data, temp_file, "fullprof") exported_content = "" file_content = [] for ext in (".comm", ".incomm"): fname = temp_file + ext if os.path.isfile(fname): with open(fname) as f: content = f.read() exported_content += f"{ext} file:\n" + content else: content = "" file_content.append(content) js_data.data.update(content=file_content) export_preview_textinput.value = exported_content save_button = Button(label="Download File(s)", button_type="success", width=220) save_button.js_on_click( CustomJS(args={"js_data": js_data}, code=javaScript)) fitpeak_controls = row( column(fitparams_add_dropdown, fitparams_select, fitparams_remove_button), fitparams_table, Spacer(width=20), column(fit_from_spinner, lorentz_checkbox, area_method_div, area_method_radiobutton), column(fit_to_spinner, proc_button, proc_all_button), ) scan_layout = column(scan_table, row(monitor_spinner, scan_motor_select, param_select)) import_layout = column( proposal_textinput, file_select, row(file_open_button, file_append_button), upload_div, upload_button, append_upload_div, append_upload_button, ) export_layout = column(export_preview_textinput, row(save_button)) tab_layout = column( row(import_layout, scan_layout, plots, Spacer(width=30), export_layout), row(fitpeak_controls, fit_output_textinput), ) return Panel(child=tab_layout, title="param study")
url1 = 'latimes-state-totals.csv' g1_last_update = getDate(url1) g1_source = 'aggregation of all local agency reports logged by Los Angeles Times. '+\ 'URL: '+'https://github.com/datadesk/california-coronavirus-data/blob/master/latimes-state-totals.csv' ## define text for intro pre = PreText(text=""" Use the dropdown menu below to select the option. You can choose the new confirmed case or new death case for California in August, 2020. Your selection will be displayed in the box below. Hover on the line to see the details of a particular day. If the data is missing for a particular day, this means that the data is not available in the dataset. The source and the date for last update are displayed at the bottom of the plot. """, width=500, height=120) ## define text box textbox = TextAreaInput(value='New confirmed cases', rows=1, title='You are viewing:') data = pd.read_csv(url1) # select dates in August data = data[data['date'] >= '2020-08-01'] data = data[data['date'] < '2020-09-01'] width = 1200 # plot width data['date_time'] = pd.to_datetime(data['date']) df = pd.DataFrame({'x': data['date_time'], 'y': data['new_confirmed_cases']}) source = ColumnDataSource(df) p = figure(y_axis_label='Number of New Cases', title='New Cases vs. Date', x_axis_label='Date', x_axis_type='datetime', plot_width=width)
def create(): det_data = {} roi_selection = {} upload_div = Div(text="Open .cami file:") def upload_button_callback(_attr, _old, new): with io.StringIO(base64.b64decode(new).decode()) as file: h5meta_list = pyzebra.parse_h5meta(file) file_list = h5meta_list["filelist"] filelist.options = file_list filelist.value = file_list[0] upload_button = FileInput(accept=".cami") upload_button.on_change("value", upload_button_callback) def update_image(index=None): if index is None: index = index_spinner.value current_image = det_data["data"][index] proj_v_line_source.data.update(x=np.arange(0, IMAGE_W) + 0.5, y=np.mean(current_image, axis=0)) proj_h_line_source.data.update(x=np.mean(current_image, axis=1), y=np.arange(0, IMAGE_H) + 0.5) image_source.data.update( h=[np.zeros((1, 1))], k=[np.zeros((1, 1))], l=[np.zeros((1, 1))], ) image_source.data.update(image=[current_image]) if auto_toggle.active: im_max = int(np.max(current_image)) im_min = int(np.min(current_image)) display_min_spinner.value = im_min display_max_spinner.value = im_max image_glyph.color_mapper.low = im_min image_glyph.color_mapper.high = im_max def update_overview_plot(): h5_data = det_data["data"] n_im, n_y, n_x = h5_data.shape overview_x = np.mean(h5_data, axis=1) overview_y = np.mean(h5_data, axis=2) overview_plot_x_image_source.data.update(image=[overview_x], dw=[n_x]) overview_plot_y_image_source.data.update(image=[overview_y], dw=[n_y]) if frame_button_group.active == 0: # Frame overview_plot_x.axis[1].axis_label = "Frame" overview_plot_y.axis[1].axis_label = "Frame" overview_plot_x_image_source.data.update(y=[0], dh=[n_im]) overview_plot_y_image_source.data.update(y=[0], dh=[n_im]) elif frame_button_group.active == 1: # Omega overview_plot_x.axis[1].axis_label = "Omega" overview_plot_y.axis[1].axis_label = "Omega" om = det_data["rot_angle"] om_start = om[0] om_end = (om[-1] - om[0]) * n_im / (n_im - 1) overview_plot_x_image_source.data.update(y=[om_start], dh=[om_end]) overview_plot_y_image_source.data.update(y=[om_start], dh=[om_end]) def filelist_callback(_attr, _old, new): nonlocal det_data det_data = pyzebra.read_detector_data(new) index_spinner.value = 0 index_spinner.high = det_data["data"].shape[0] - 1 update_image(0) update_overview_plot() filelist = Select() filelist.on_change("value", filelist_callback) def index_spinner_callback(_attr, _old, new): update_image(new) index_spinner = Spinner(title="Image index:", value=0, low=0) index_spinner.on_change("value", index_spinner_callback) plot = Plot( x_range=Range1d(0, IMAGE_W, bounds=(0, IMAGE_W)), y_range=Range1d(0, IMAGE_H, bounds=(0, IMAGE_H)), plot_height=IMAGE_H * 3, plot_width=IMAGE_W * 3, toolbar_location="left", ) # ---- tools plot.toolbar.logo = None # ---- axes plot.add_layout(LinearAxis(), place="above") plot.add_layout(LinearAxis(major_label_orientation="vertical"), place="right") # ---- grid lines plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph image_source = ColumnDataSource( dict( image=[np.zeros((IMAGE_H, IMAGE_W), dtype="float32")], h=[np.zeros((1, 1))], k=[np.zeros((1, 1))], l=[np.zeros((1, 1))], x=[0], y=[0], dw=[IMAGE_W], dh=[IMAGE_H], )) h_glyph = Image(image="h", x="x", y="y", dw="dw", dh="dh", global_alpha=0) k_glyph = Image(image="k", x="x", y="y", dw="dw", dh="dh", global_alpha=0) l_glyph = Image(image="l", x="x", y="y", dw="dw", dh="dh", global_alpha=0) plot.add_glyph(image_source, h_glyph) plot.add_glyph(image_source, k_glyph) plot.add_glyph(image_source, l_glyph) image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") plot.add_glyph(image_source, image_glyph, name="image_glyph") # ---- projections proj_v = Plot( x_range=plot.x_range, y_range=DataRange1d(), plot_height=200, plot_width=IMAGE_W * 3, toolbar_location=None, ) proj_v.add_layout(LinearAxis(major_label_orientation="vertical"), place="right") proj_v.add_layout(LinearAxis(major_label_text_font_size="0pt"), place="below") proj_v.add_layout(Grid(dimension=0, ticker=BasicTicker())) proj_v.add_layout(Grid(dimension=1, ticker=BasicTicker())) proj_v_line_source = ColumnDataSource(dict(x=[], y=[])) proj_v.add_glyph(proj_v_line_source, Line(x="x", y="y", line_color="steelblue")) proj_h = Plot( x_range=DataRange1d(), y_range=plot.y_range, plot_height=IMAGE_H * 3, plot_width=200, toolbar_location=None, ) proj_h.add_layout(LinearAxis(), place="above") proj_h.add_layout(LinearAxis(major_label_text_font_size="0pt"), place="left") proj_h.add_layout(Grid(dimension=0, ticker=BasicTicker())) proj_h.add_layout(Grid(dimension=1, ticker=BasicTicker())) proj_h_line_source = ColumnDataSource(dict(x=[], y=[])) proj_h.add_glyph(proj_h_line_source, Line(x="x", y="y", line_color="steelblue")) # add tools hovertool = HoverTool(tooltips=[("intensity", "@image"), ("h", "@h"), ("k", "@k"), ("l", "@l")]) box_edit_source = ColumnDataSource(dict(x=[], y=[], width=[], height=[])) box_edit_glyph = Rect(x="x", y="y", width="width", height="height", fill_alpha=0, line_color="red") box_edit_renderer = plot.add_glyph(box_edit_source, box_edit_glyph) boxedittool = BoxEditTool(renderers=[box_edit_renderer], num_objects=1) def box_edit_callback(_attr, _old, new): if new["x"]: h5_data = det_data["data"] x_val = np.arange(h5_data.shape[0]) left = int(np.floor(new["x"][0])) right = int(np.ceil(new["x"][0] + new["width"][0])) bottom = int(np.floor(new["y"][0])) top = int(np.ceil(new["y"][0] + new["height"][0])) y_val = np.sum(h5_data[:, bottom:top, left:right], axis=(1, 2)) else: x_val = [] y_val = [] roi_avg_plot_line_source.data.update(x=x_val, y=y_val) box_edit_source.on_change("data", box_edit_callback) wheelzoomtool = WheelZoomTool(maintain_focus=False) plot.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), hovertool, boxedittool, ) plot.toolbar.active_scroll = wheelzoomtool # shared frame range frame_range = DataRange1d() det_x_range = DataRange1d() overview_plot_x = Plot( title=Title(text="Projections on X-axis"), x_range=det_x_range, y_range=frame_range, plot_height=400, plot_width=400, toolbar_location="left", ) # ---- tools wheelzoomtool = WheelZoomTool(maintain_focus=False) overview_plot_x.toolbar.logo = None overview_plot_x.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), ) overview_plot_x.toolbar.active_scroll = wheelzoomtool # ---- axes overview_plot_x.add_layout(LinearAxis(axis_label="Coordinate X, pix"), place="below") overview_plot_x.add_layout(LinearAxis(axis_label="Frame", major_label_orientation="vertical"), place="left") # ---- grid lines overview_plot_x.add_layout(Grid(dimension=0, ticker=BasicTicker())) overview_plot_x.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph overview_plot_x_image_source = ColumnDataSource( dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[1], dh=[1])) overview_plot_x_image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") overview_plot_x.add_glyph(overview_plot_x_image_source, overview_plot_x_image_glyph, name="image_glyph") det_y_range = DataRange1d() overview_plot_y = Plot( title=Title(text="Projections on Y-axis"), x_range=det_y_range, y_range=frame_range, plot_height=400, plot_width=400, toolbar_location="left", ) # ---- tools wheelzoomtool = WheelZoomTool(maintain_focus=False) overview_plot_y.toolbar.logo = None overview_plot_y.add_tools( PanTool(), BoxZoomTool(), wheelzoomtool, ResetTool(), ) overview_plot_y.toolbar.active_scroll = wheelzoomtool # ---- axes overview_plot_y.add_layout(LinearAxis(axis_label="Coordinate Y, pix"), place="below") overview_plot_y.add_layout(LinearAxis(axis_label="Frame", major_label_orientation="vertical"), place="left") # ---- grid lines overview_plot_y.add_layout(Grid(dimension=0, ticker=BasicTicker())) overview_plot_y.add_layout(Grid(dimension=1, ticker=BasicTicker())) # ---- rgba image glyph overview_plot_y_image_source = ColumnDataSource( dict(image=[np.zeros((1, 1), dtype="float32")], x=[0], y=[0], dw=[1], dh=[1])) overview_plot_y_image_glyph = Image(image="image", x="x", y="y", dw="dw", dh="dh") overview_plot_y.add_glyph(overview_plot_y_image_source, overview_plot_y_image_glyph, name="image_glyph") def frame_button_group_callback(_active): update_overview_plot() frame_button_group = RadioButtonGroup(labels=["Frames", "Omega"], active=0) frame_button_group.on_click(frame_button_group_callback) roi_avg_plot = Plot( x_range=DataRange1d(), y_range=DataRange1d(), plot_height=IMAGE_H * 3, plot_width=IMAGE_W * 3, toolbar_location="left", ) # ---- tools roi_avg_plot.toolbar.logo = None # ---- axes roi_avg_plot.add_layout(LinearAxis(), place="below") roi_avg_plot.add_layout(LinearAxis(major_label_orientation="vertical"), place="left") # ---- grid lines roi_avg_plot.add_layout(Grid(dimension=0, ticker=BasicTicker())) roi_avg_plot.add_layout(Grid(dimension=1, ticker=BasicTicker())) roi_avg_plot_line_source = ColumnDataSource(dict(x=[], y=[])) roi_avg_plot.add_glyph(roi_avg_plot_line_source, Line(x="x", y="y", line_color="steelblue")) cmap_dict = { "gray": Greys256, "gray_reversed": Greys256[::-1], "plasma": Plasma256, "cividis": Cividis256, } def colormap_callback(_attr, _old, new): image_glyph.color_mapper = LinearColorMapper(palette=cmap_dict[new]) overview_plot_x_image_glyph.color_mapper = LinearColorMapper( palette=cmap_dict[new]) overview_plot_y_image_glyph.color_mapper = LinearColorMapper( palette=cmap_dict[new]) colormap = Select(title="Colormap:", options=list(cmap_dict.keys())) colormap.on_change("value", colormap_callback) colormap.value = "plasma" radio_button_group = RadioButtonGroup(labels=["nb", "nb_bi"], active=0) STEP = 1 # ---- colormap auto toggle button def auto_toggle_callback(state): if state: display_min_spinner.disabled = True display_max_spinner.disabled = True else: display_min_spinner.disabled = False display_max_spinner.disabled = False update_image() auto_toggle = Toggle(label="Auto Range", active=True, button_type="default") auto_toggle.on_click(auto_toggle_callback) # ---- colormap display max value def display_max_spinner_callback(_attr, _old_value, new_value): display_min_spinner.high = new_value - STEP image_glyph.color_mapper.high = new_value display_max_spinner = Spinner( title="Maximal Display Value:", low=0 + STEP, value=1, step=STEP, disabled=auto_toggle.active, ) display_max_spinner.on_change("value", display_max_spinner_callback) # ---- colormap display min value def display_min_spinner_callback(_attr, _old_value, new_value): display_max_spinner.low = new_value + STEP image_glyph.color_mapper.low = new_value display_min_spinner = Spinner( title="Minimal Display Value:", high=1 - STEP, value=0, step=STEP, disabled=auto_toggle.active, ) display_min_spinner.on_change("value", display_min_spinner_callback) def hkl_button_callback(): index = index_spinner.value setup_type = "nb_bi" if radio_button_group.active else "nb" h, k, l = calculate_hkl(det_data, index, setup_type) image_source.data.update(h=[h], k=[k], l=[l]) hkl_button = Button(label="Calculate hkl (slow)") hkl_button.on_click(hkl_button_callback) selection_list = TextAreaInput(rows=7) def selection_button_callback(): nonlocal roi_selection selection = [ 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 = filelist.value[-8:-4] if filename_id in roi_selection: roi_selection[f"{filename_id}"].append(selection) else: roi_selection[f"{filename_id}"] = [selection] selection_list.value = str(roi_selection) selection_button = Button(label="Add selection") selection_button.on_click(selection_button_callback) # Final layout layout_image = column( gridplot([[proj_v, None], [plot, proj_h]], merge_tools=False), row(index_spinner)) colormap_layout = column(colormap, auto_toggle, display_max_spinner, display_min_spinner) hkl_layout = column(radio_button_group, hkl_button) layout_overview = column( gridplot( [[overview_plot_x, overview_plot_y]], toolbar_options=dict(logo=None), merge_tools=True, ), frame_button_group, ) tab_layout = row( column( upload_div, upload_button, filelist, layout_image, row(colormap_layout, hkl_layout), ), column( roi_avg_plot, layout_overview, row(selection_button, selection_list), ), ) return Panel(child=tab_layout, title="Data Viewer")
def __init__(self, type): self.test = False self.report_type = type self.utc = TimezoneInfo() self.kp_zone = TimezoneInfo(utc_offset=-7*u.hour) self.zones = [self.utc, self.kp_zone] self.datefmt = DateFormatter(format="%m/%d/%Y %H:%M:%S") self.inst_style = {'font-size':'150%'} self.subt_style = {'font-size':'200%','font-style':'bold'} self.title_style = {'font-size':'250%','font-style':'bold'} self.alert_style = {'font-size':'150%','color':'red'} self.nl_file = None self.intro_subtitle = Div(text="Connect to Night Log",css_classes=['subt-style']) self.time_note = Div(text="<b> Note: </b> Enter all times as HHMM (1818 = 18:18 = 6:18pm) in Kitt Peak local time. Either enter the time or hit the <b> Now </b> button if it just occured.", css_classes=['inst-style']) hostname = socket.gethostname() ip_address = socket.gethostbyname(hostname) if 'desi' in hostname: self.location = 'kpno' #self.conn = psycopg2.connect(host="desi-db", port="5442", database="desi_dev", user="******", password="******") elif 'app' in hostname: #this is not true. Needs to change. self.location = 'nersc' else: self.location = 'other' nw_dirs = {'nersc':'/global/cfs/cdirs/desi/spectro/nightwatch/nersc/', 'kpno':'/exposures/nightwatch/', 'other':None} self.nw_dir = nw_dirs[self.location] self.nl_dir = os.environ['NL_DIR'] self.your_name = TextInput(title ='Your Name', placeholder = 'John Smith') self.os_name_1 = TextInput(title ='Observing Scientist 1', placeholder = 'Ruth Bader Ginsberg') self.os_name_2 = TextInput(title ='Observing Scientist 2', placeholder = "Sandra Day O'Connor") self.lo_names = ['None ','Liz Buckley-Geer','Ann Elliott','Parker Fagrelius','Satya Gontcho A Gontcho','James Lasker','Martin Landriau','Claire Poppett','Michael Schubnell','Luke Tyas','Other '] self.oa_names = ['None ','Karen Butler','Amy Robertson','Anthony Paat','Dave Summers','Doug Williams','Other '] self.intro_txt = Div(text=' ') self.comment_txt = Div(text=" ", css_classes=['inst-style'], width=1000) self.date_init = Select(title="Existing Night Logs") self.time_title = Paragraph(text='Time* (Kitt Peak local time)', align='center') self.now_btn = Button(label='Now', css_classes=['now_button'], width=50) days = [d for d in os.listdir(self.nl_dir) if os.path.isdir(os.path.join(self.nl_dir, d))] init_nl_list = np.sort([day for day in days if 'nightlog_meta.json' in os.listdir(os.path.join(self.nl_dir,day))])[::-1][0:10] self.date_init.options = list(init_nl_list) self.date_init.value = init_nl_list[0] self.connect_txt = Div(text=' ', css_classes=['alert-style']) self.connect_bt = Button(label="Connect to Existing Night Log", css_classes=['connect_button']) self.exp_info = Div(text="Fill In Only Relevant Data. Mandatory fields have an asterisk*.", css_classes=['inst-style'],width=500) self.exp_comment = TextAreaInput(title ='Comment/Remark', placeholder = 'Humidity high for calibration lamps',value=None,rows=10, cols=5,width=800,max_length=5000) self.exp_time = TextInput(placeholder = '20:07',value=None, width=100) #title ='Time in Kitt Peak local time*', self.exp_btn = Button(label='Add', css_classes=['add_button']) self.exp_type = Select(title="Exposure Type", value = None, options=['None','Zero','Focus','Dark','Arc','FVC','DESI']) self.exp_alert = Div(text=' ', css_classes=['alert-style']) self.exp_exposure_start = TextInput(title='Exposure Number: First', placeholder='12345', value=None) self.exp_exposure_finish = TextInput(title='Exposure Number: Last', placeholder='12346', value=None) self.nl_subtitle = Div(text="Current DESI Night Log: {}".format(self.nl_file), css_classes=['subt-style']) self.nl_btn = Button(label='Get Current DESI Night Log', css_classes=['connect_button']) self.nl_text = Div(text=" ", css_classes=['inst-style'], width=1000) self.nl_alert = Div(text='You must be connected to a Night Log', css_classes=['alert-style'], width=500) self.nl_info = Div(text="Night Log Info:", css_classes=['inst-style'], width=500) self.exptable_alert = Div(text=" ",css_classes=['alert-style'], width=500) self.checklist = CheckboxGroup(labels=[]) self.check_time = TextInput(placeholder = '20:07', value=None) #title ='Time in Kitt Peak local time*', self.check_alert = Div(text=" ", css_classes=['alert-style']) self.check_btn = Button(label='Submit', css_classes=['add_button']) self.check_comment = TextAreaInput(title='Comment', placeholder='comment if necessary', rows=3, cols=3) self.prob_subtitle = Div(text="Problems", css_classes=['subt-style']) self.prob_inst = Div(text="Describe problems as they come up and at what time they occur. If there is an Alarm ID associated with the problem, include it, but leave blank if not. If possible, include a description of the remedy.", css_classes=['inst-style'], width=1000) self.prob_time = TextInput(placeholder = '20:07', value=None, width=100) #title ='Time in Kitt Peak local time*', self.prob_input = TextAreaInput(placeholder="NightWatch not plotting raw data", rows=10, cols=3, title="Problem Description*:") self.prob_alarm = TextInput(title='Alarm ID', placeholder='12', value=None, width=100) self.prob_action = TextAreaInput(title='Resolution/Action',placeholder='description',rows=10, cols=3) self.prob_btn = Button(label='Add', css_classes=['add_button']) self.prob_alert = Div(text=' ', css_classes=['alert-style']) self.img_subtitle = Div(text="Images", css_classes=['subt-style']) self.img_upinst = Div(text="Include images in the Night Log by uploading a png image from your local computer. Select file, write a comment and click Add", css_classes=['inst-style'], width=1000) self.img_upinst2 = Div(text=" Choose image to include with comment: ", css_classes=['inst-style']) self.img_upload = FileInput(accept=".png") self.img_upload.on_change('value', self.upload_image) self.img_upload_comments = FileInput(accept=".png") self.img_upload_comments.on_change('value', self.upload_image_comments) self.img_upload_comments_os = FileInput(accept=".png") self.img_upload_comments_os.on_change('value', self.upload_image_comments_os) self.img_upload_problems = FileInput(accept=".png") self.img_upload_problems.on_change('value', self.upload_image_problems) self.img_inst = Div(text="Include images in the Night Log by entering the location of the images on the desi cluster", css_classes=['inst-style'], width=1000) self.img_input = TextInput(title='image file location on desi cluster', placeholder='/n/home/desiobserver/image.png',value=None) self.img_comment = TextAreaInput(placeholder='comment about image', rows=8, cols=3, title='Image caption') self.img_btn = Button(label='Add', css_classes=['add_button']) self.img_alert = Div(text=" ",width=1000) self.plot_subtitle = Div(text="Telemetry Plots", css_classes=['subt-style']) self.DESI_Log = None self.save_telem_plots = False
from bokeh.io import output_file, show from bokeh.models import TextAreaInput output_file("text_input.html") text_input = TextAreaInput(value="default", rows=6, title="Label:") show(text_input)
def widgets(): from bokeh.io import show from bokeh.models import Select, CheckboxButtonGroup, Button, CheckboxGroup, ColorPicker, Dropdown, \ FileInput, MultiSelect, RadioButtonGroup, RadioGroup, Slider, RangeSlider, TextAreaInput, TextInput, Toggle, \ Paragraph, PreText, Div put_text('Button') button = Button(label="Foo", button_type="success") show(button) put_text('CheckboxButtonGroup') checkbox_button_group = CheckboxButtonGroup( labels=["Option 1", "Option 2", "Option 3"], active=[0, 1]) show(checkbox_button_group) put_text('CheckboxGroup') checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1]) show(checkbox_group) put_text('ColorPicker') color_picker = ColorPicker(color="#ff4466", title="Choose color:", width=200) show(color_picker) put_text('Dropdown') menu = [("Item 1", "item_1"), ("Item 2", "item_2"), None, ("Item 3", "item_3")] dropdown = Dropdown(label="Dropdown button", button_type="warning", menu=menu) show(dropdown) put_text('FileInput') file_input = FileInput() show(file_input) put_text('MultiSelect') multi_select = MultiSelect(title="Option:", value=["foo", "quux"], options=[("foo", "Foo"), ("bar", "BAR"), ("baz", "bAz"), ("quux", "quux")]) show(multi_select) put_text('RadioButtonGroup') radio_button_group = RadioButtonGroup( labels=["Option 1", "Option 2", "Option 3"], active=0) show(radio_button_group) put_text('RadioGroup') radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0) show(radio_group) put_text('Select') select = Select(title="Option:", value="foo", options=["foo", "bar", "baz", "quux"]) show(select) put_text('Slider') slider = Slider(start=0, end=10, value=1, step=.1, title="Stuff") show(slider) put_text('RangeSlider') range_slider = RangeSlider(start=0, end=10, value=(1, 9), step=.1, title="Stuff") show(range_slider) put_text('TextAreaInput') text_input = TextAreaInput(value="default", rows=6, title="Label:") show(text_input) put_text('TextInput') text_input = TextInput(value="default", title="Label:") show(text_input) put_text('Toggle') toggle = Toggle(label="Foo", button_type="success") show(toggle) put_text('Div') div = Div( text= """Your <a href="https://en.wikipedia.org/wiki/HTML">HTML</a>-supported text is initialized with the <b>text</b> argument. The remaining div arguments are <b>width</b> and <b>height</b>. For this example, those values are <i>200</i> and <i>100</i> respectively.""", width=200, height=100) show(div) put_text('Paragraph') p = Paragraph( text="""Your text is initialized with the 'text' argument. The remaining Paragraph arguments are 'width' and 'height'. For this example, those values are 200 and 100 respectively.""", width=200, height=100) show(p) put_text('PreText') pre = PreText(text="""Your text is initialized with the 'text' argument. The remaining Paragraph arguments are 'width' and 'height'. For this example, those values are 500 and 100 respectively.""", width=500, height=100) show(pre)
checkbox_group = CheckboxGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1]) radio_group = RadioGroup(labels=["Option 1", "Option 2", "Option 3"], active=0) checkbox_button_group = CheckboxButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1]) radio_button_group = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0) checkbox_button_group_vertical = CheckboxButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=[0, 1], orientation="vertical") radio_button_group_vertical = RadioButtonGroup(labels=["Option 1", "Option 2", "Option 3"], active=0, orientation="vertical") text_input = TextInput(placeholder="Enter value ...") completions = ["aaa", "aab", "aac", "baa", "caa"] autocomplete_input = AutocompleteInput(placeholder="Enter value (auto-complete) ...", completions=completions) text_area = TextAreaInput(placeholder="Enter text ...", cols=20, rows=10, value="uuu") select = Select(options=["Option 1", "Option 2", "Option 3"]) multi_select = MultiSelect(options=["Option %d" % (i+1) for i in range(16)], size=6) multi_choice = MultiChoice(options=["Option %d" % (i+1) for i in range(16)]) slider = Slider(value=10, start=0, end=100, step=0.5) range_slider = RangeSlider(value=[10, 90], start=0, end=100, step=0.5) date_slider = DateSlider(value=date(2016, 1, 1), start=date(2015, 1, 1), end=date(2017, 12, 31)) date_range_slider = DateRangeSlider(value=(date(2016, 1, 1), date(2016, 12, 31)), start=date(2015, 1, 1), end=date(2017, 12, 31))
from io import StringIO from bokeh.io import curdoc from bokeh.layouts import column, row from bokeh.models import Tabs, TextAreaInput import panel_ccl_integrate import panel_hdf_anatric import panel_hdf_viewer import panel_param_study import panel_spind doc = curdoc() sys.stdout = StringIO() stdout_textareainput = TextAreaInput(title="print output:", height=150) bokeh_stream = StringIO() bokeh_handler = logging.StreamHandler(bokeh_stream) bokeh_handler.setFormatter(logging.Formatter(logging.BASIC_FORMAT)) bokeh_logger = logging.getLogger("bokeh") bokeh_logger.addHandler(bokeh_handler) bokeh_log_textareainput = TextAreaInput(title="server output:", height=150) # Final layout tab_hdf_viewer = panel_hdf_viewer.create() tab_hdf_anatric = panel_hdf_anatric.create() tab_ccl_integrate = panel_ccl_integrate.create() tab_param_study = panel_param_study.create() tab_spind = panel_spind.create()
def create(): config = pyzebra.AnatricConfig() def _load_config_file(file): config.load_from_file(file) logfile_textinput.value = config.logfile logfile_verbosity_select.value = config.logfile_verbosity filelist_type.value = config.filelist_type filelist_format_textinput.value = config.filelist_format filelist_datapath_textinput.value = config.filelist_datapath filelist_ranges_textareainput.value = "\n".join( map(str, config.filelist_ranges)) crystal_sample_textinput.value = config.crystal_sample lambda_textinput.value = config.crystal_lambda zeroOM_textinput.value = config.crystal_zeroOM zeroSTT_textinput.value = config.crystal_zeroSTT zeroCHI_textinput.value = config.crystal_zeroCHI ub_textareainput.value = config.crystal_UB dataFactory_implementation_select.value = config.dataFactory_implementation dataFactory_dist1_textinput.value = config.dataFactory_dist1 reflectionPrinter_format_select.value = config.reflectionPrinter_format set_active_widgets(config.algorithm) if config.algorithm == "adaptivemaxcog": threshold_textinput.value = config.threshold shell_textinput.value = config.shell steepness_textinput.value = config.steepness duplicateDistance_textinput.value = config.duplicateDistance maxequal_textinput.value = config.maxequal aps_window_textinput.value = str( tuple(map(int, config.aps_window.values()))) elif config.algorithm == "adaptivedynamic": adm_window_textinput.value = str( tuple(map(int, config.adm_window.values()))) border_textinput.value = str( tuple(map(int, config.border.values()))) minWindow_textinput.value = str( tuple(map(int, config.minWindow.values()))) reflectionFile_textinput.value = config.reflectionFile targetMonitor_textinput.value = config.targetMonitor smoothSize_textinput.value = config.smoothSize loop_textinput.value = config.loop minPeakCount_textinput.value = config.minPeakCount displacementCurve_textinput.value = "\n".join( map(str, config.displacementCurve)) else: raise ValueError("Unknown processing mode.") def set_active_widgets(implementation): if implementation == "adaptivemaxcog": mode_radio_button_group.active = 0 disable_adaptivemaxcog = False disable_adaptivedynamic = True elif implementation == "adaptivedynamic": mode_radio_button_group.active = 1 disable_adaptivemaxcog = True disable_adaptivedynamic = False else: raise ValueError( "Implementation can be either 'adaptivemaxcog' or 'adaptivedynamic'" ) threshold_textinput.disabled = disable_adaptivemaxcog shell_textinput.disabled = disable_adaptivemaxcog steepness_textinput.disabled = disable_adaptivemaxcog duplicateDistance_textinput.disabled = disable_adaptivemaxcog maxequal_textinput.disabled = disable_adaptivemaxcog aps_window_textinput.disabled = disable_adaptivemaxcog adm_window_textinput.disabled = disable_adaptivedynamic border_textinput.disabled = disable_adaptivedynamic minWindow_textinput.disabled = disable_adaptivedynamic reflectionFile_textinput.disabled = disable_adaptivedynamic targetMonitor_textinput.disabled = disable_adaptivedynamic smoothSize_textinput.disabled = disable_adaptivedynamic loop_textinput.disabled = disable_adaptivedynamic minPeakCount_textinput.disabled = disable_adaptivedynamic displacementCurve_textinput.disabled = disable_adaptivedynamic upload_div = Div(text="Open XML configuration file:") def upload_button_callback(_attr, _old, new): with io.BytesIO(base64.b64decode(new)) as file: _load_config_file(file) upload_button = FileInput(accept=".xml") upload_button.on_change("value", upload_button_callback) # General parameters # ---- logfile def logfile_textinput_callback(_attr, _old, new): config.logfile = new logfile_textinput = TextInput(title="Logfile:", value="logfile.log", width=520) logfile_textinput.on_change("value", logfile_textinput_callback) def logfile_verbosity_select_callback(_attr, _old, new): config.logfile_verbosity = new logfile_verbosity_select = Select(title="verbosity:", options=["0", "5", "10", "15", "30"], width=70) logfile_verbosity_select.on_change("value", logfile_verbosity_select_callback) # ---- FileList def filelist_type_callback(_attr, _old, new): config.filelist_type = new filelist_type = Select(title="File List:", options=["TRICS", "SINQ"], width=100) filelist_type.on_change("value", filelist_type_callback) def filelist_format_textinput_callback(_attr, _old, new): config.filelist_format = new filelist_format_textinput = TextInput(title="format:", width=490) filelist_format_textinput.on_change("value", filelist_format_textinput_callback) def filelist_datapath_textinput_callback(_attr, _old, new): config.filelist_datapath = new filelist_datapath_textinput = TextInput(title="datapath:") filelist_datapath_textinput.on_change( "value", filelist_datapath_textinput_callback) def filelist_ranges_textareainput_callback(_attr, _old, new): ranges = [] for line in new.splitlines(): ranges.append(re.findall(r"\b\d+\b", line)) config.filelist_ranges = ranges filelist_ranges_textareainput = TextAreaInput(title="ranges:", height=100) filelist_ranges_textareainput.on_change( "value", filelist_ranges_textareainput_callback) # ---- crystal def crystal_sample_textinput_callback(_attr, _old, new): config.crystal_sample = new crystal_sample_textinput = TextInput(title="Sample Name:") crystal_sample_textinput.on_change("value", crystal_sample_textinput_callback) def lambda_textinput_callback(_attr, _old, new): config.crystal_lambda = new lambda_textinput = TextInput(title="lambda:", width=140) lambda_textinput.on_change("value", lambda_textinput_callback) def ub_textareainput_callback(_attr, _old, new): config.crystal_UB = new ub_textareainput = TextAreaInput(title="UB matrix:", height=100) ub_textareainput.on_change("value", ub_textareainput_callback) def zeroOM_textinput_callback(_attr, _old, new): config.crystal_zeroOM = new zeroOM_textinput = TextInput(title="zeroOM:", width=140) zeroOM_textinput.on_change("value", zeroOM_textinput_callback) def zeroSTT_textinput_callback(_attr, _old, new): config.crystal_zeroSTT = new zeroSTT_textinput = TextInput(title="zeroSTT:", width=140) zeroSTT_textinput.on_change("value", zeroSTT_textinput_callback) def zeroCHI_textinput_callback(_attr, _old, new): config.crystal_zeroCHI = new zeroCHI_textinput = TextInput(title="zeroCHI:", width=140) zeroCHI_textinput.on_change("value", zeroCHI_textinput_callback) # ---- DataFactory def dataFactory_implementation_select_callback(_attr, _old, new): config.dataFactory_implementation = new dataFactory_implementation_select = Select( title="DataFactory implementation:", options=DATA_FACTORY_IMPLEMENTATION, width=300, ) dataFactory_implementation_select.on_change( "value", dataFactory_implementation_select_callback) def dataFactory_dist1_textinput_callback(_attr, _old, new): config.dataFactory_dist1 = new dataFactory_dist1_textinput = TextInput(title="dist1:", width=290) dataFactory_dist1_textinput.on_change( "value", dataFactory_dist1_textinput_callback) # ---- BackgroundProcessor # ---- DetectorEfficency # ---- ReflectionPrinter def reflectionPrinter_format_select_callback(_attr, _old, new): config.reflectionPrinter_format = new reflectionPrinter_format_select = Select( title="ReflectionPrinter format:", options=REFLECTION_PRINTER_FORMATS, width=300, ) reflectionPrinter_format_select.on_change( "value", reflectionPrinter_format_select_callback) # Adaptive Peak Detection (adaptivemaxcog) # ---- threshold def threshold_textinput_callback(_attr, _old, new): config.threshold = new threshold_textinput = TextInput(title="Threshold:") threshold_textinput.on_change("value", threshold_textinput_callback) # ---- shell def shell_textinput_callback(_attr, _old, new): config.shell = new shell_textinput = TextInput(title="Shell:") shell_textinput.on_change("value", shell_textinput_callback) # ---- steepness def steepness_textinput_callback(_attr, _old, new): config.steepness = new steepness_textinput = TextInput(title="Steepness:") steepness_textinput.on_change("value", steepness_textinput_callback) # ---- duplicateDistance def duplicateDistance_textinput_callback(_attr, _old, new): config.duplicateDistance = new duplicateDistance_textinput = TextInput(title="Duplicate Distance:") duplicateDistance_textinput.on_change( "value", duplicateDistance_textinput_callback) # ---- maxequal def maxequal_textinput_callback(_attr, _old, new): config.maxequal = new maxequal_textinput = TextInput(title="Max Equal:") maxequal_textinput.on_change("value", maxequal_textinput_callback) # ---- window def aps_window_textinput_callback(_attr, _old, new): config.aps_window = dict( zip(("x", "y", "z"), re.findall(r"\b\d+\b", new))) aps_window_textinput = TextInput(title="Window (x, y, z):") aps_window_textinput.on_change("value", aps_window_textinput_callback) # Adaptive Dynamic Mask Integration (adaptivedynamic) # ---- window def adm_window_textinput_callback(_attr, _old, new): config.adm_window = dict( zip(("x", "y", "z"), re.findall(r"\b\d+\b", new))) adm_window_textinput = TextInput(title="Window (x, y, z):") adm_window_textinput.on_change("value", adm_window_textinput_callback) # ---- border def border_textinput_callback(_attr, _old, new): config.border = dict(zip(("x", "y", "z"), re.findall(r"\b\d+\b", new))) border_textinput = TextInput(title="Border (x, y, z):") border_textinput.on_change("value", border_textinput_callback) # ---- minWindow def minWindow_textinput_callback(_attr, _old, new): config.minWindow = dict( zip(("x", "y", "z"), re.findall(r"\b\d+\b", new))) minWindow_textinput = TextInput(title="Min Window (x, y, z):") minWindow_textinput.on_change("value", minWindow_textinput_callback) # ---- reflectionFile def reflectionFile_textinput_callback(_attr, _old, new): config.reflectionFile = new reflectionFile_textinput = TextInput(title="Reflection File:") reflectionFile_textinput.on_change("value", reflectionFile_textinput_callback) # ---- targetMonitor def targetMonitor_textinput_callback(_attr, _old, new): config.targetMonitor = new targetMonitor_textinput = TextInput(title="Target Monitor:") targetMonitor_textinput.on_change("value", targetMonitor_textinput_callback) # ---- smoothSize def smoothSize_textinput_callback(_attr, _old, new): config.smoothSize = new smoothSize_textinput = TextInput(title="Smooth Size:") smoothSize_textinput.on_change("value", smoothSize_textinput_callback) # ---- loop def loop_textinput_callback(_attr, _old, new): config.loop = new loop_textinput = TextInput(title="Loop:") loop_textinput.on_change("value", loop_textinput_callback) # ---- minPeakCount def minPeakCount_textinput_callback(_attr, _old, new): config.minPeakCount = new minPeakCount_textinput = TextInput(title="Min Peak Count:") minPeakCount_textinput.on_change("value", minPeakCount_textinput_callback) # ---- displacementCurve def displacementCurve_textinput_callback(_attr, _old, new): maps = [] for line in new.splitlines(): maps.append(re.findall(r"\d+(?:\.\d+)?", line)) config.displacementCurve = maps displacementCurve_textinput = TextAreaInput( title="Displacement Curve (twotheta, x, y):", height=100) displacementCurve_textinput.on_change( "value", displacementCurve_textinput_callback) def mode_radio_button_group_callback(active): if active == 0: config.algorithm = "adaptivemaxcog" set_active_widgets("adaptivemaxcog") else: config.algorithm = "adaptivedynamic" set_active_widgets("adaptivedynamic") mode_radio_button_group = RadioButtonGroup( labels=["Adaptive Peak Detection", "Adaptive Dynamic Integration"], active=0) mode_radio_button_group.on_click(mode_radio_button_group_callback) set_active_widgets("adaptivemaxcog") def process_button_callback(): with tempfile.TemporaryDirectory() as temp_dir: temp_file = temp_dir + "/temp.xml" config.save_as(temp_file) pyzebra.anatric(temp_file) with open(config.logfile) as f_log: output_log.value = f_log.read() process_button = Button(label="Process", button_type="primary") process_button.on_click(process_button_callback) output_log = TextAreaInput(title="Logfile output:", height=700, disabled=True) output_config = TextAreaInput(title="Current config:", height=700, width=400, disabled=True) tab_layout = row( column( upload_div, upload_button, row(logfile_textinput, logfile_verbosity_select), row(filelist_type, filelist_format_textinput), filelist_datapath_textinput, filelist_ranges_textareainput, crystal_sample_textinput, row(lambda_textinput, zeroOM_textinput, zeroSTT_textinput, zeroCHI_textinput), ub_textareainput, row(dataFactory_implementation_select, dataFactory_dist1_textinput), reflectionPrinter_format_select, process_button, ), column( mode_radio_button_group, row( column( threshold_textinput, shell_textinput, steepness_textinput, duplicateDistance_textinput, maxequal_textinput, aps_window_textinput, ), column( adm_window_textinput, border_textinput, minWindow_textinput, reflectionFile_textinput, targetMonitor_textinput, smoothSize_textinput, loop_textinput, minPeakCount_textinput, displacementCurve_textinput, ), ), ), output_config, output_log, ) async def update_config(): config.save_as("debug.xml") with open("debug.xml") as f_config: output_config.value = f_config.read() curdoc().add_periodic_callback(update_config, 1000) return Panel(child=tab_layout, title="Anatric")