From 1ac944dda852370d84943f8a8074cc95d532971b Mon Sep 17 00:00:00 2001 From: Jacqueline Garrahan Date: Fri, 3 Jun 2022 09:45:58 -0700 Subject: [PATCH 1/3] Check in prod example --- examples/lcls/README.md | 0 examples/lcls/epics_config.yml | 30 +++++++++++++++++++++++++ examples/lcls/server.py | 40 ++++++++++++++++++++++++++++++++++ examples/lcls/variables.yml | 29 ++++++++++++++++++++++++ 4 files changed, 99 insertions(+) create mode 100644 examples/lcls/README.md create mode 100644 examples/lcls/epics_config.yml create mode 100644 examples/lcls/server.py create mode 100644 examples/lcls/variables.yml diff --git a/examples/lcls/README.md b/examples/lcls/README.md new file mode 100644 index 0000000..e69de29 diff --git a/examples/lcls/epics_config.yml b/examples/lcls/epics_config.yml new file mode 100644 index 0000000..ea0827d --- /dev/null +++ b/examples/lcls/epics_config.yml @@ -0,0 +1,30 @@ +input_variables: + klys_li24_11: + pvname: KLYS:LI24:11:AMPL + protocol: ca + serve: false + + klys_li24_21: + pvname: KLYS:LI24:21:AMPL + protocol: ca + serve: false + + klys_li24_31: + pvname: KLYS:LI24:31:AMPL + protocol: ca + serve: false + + klys_li24_41: + pvname: KLYS:LI24:41:AMPL + protocol: ca + serve: false + + klys_li24_51: + pvname: KLYS:LI24:51:AMPL + protocol: ca + serve: false + +output_variables: + summation: + pvname: sample:summation + protocol: pva diff --git a/examples/lcls/server.py b/examples/lcls/server.py new file mode 100644 index 0000000..68676f3 --- /dev/null +++ b/examples/lcls/server.py @@ -0,0 +1,40 @@ +import numpy as np +from lume_model.models import BaseModel +from lume_model.utils import variables_from_yaml +from lume_epics.utils import config_from_yaml +from lume_epics.epics_server import Server +from pathlib import Path + + +class AmplSummationModel(BaseModel): + def __init__(self): + + variable_path = Path(__file__).parent / "variables.yml" + + with variable_path.open() as f: + input_variables, output_variables = variables_from_yaml(f) + + self.input_variables = input_variables + self.output_variables = output_variables + + def evaluate(self, input_variables): + + summation = sum([var.value for var in input_variables.values()]) + self.output_variables["summation"].value = summation + + return self.output_variables + + +if __name__ == "__main__": + # load epics configuration + epics_path = Path(__file__).parent / "epics_config.yml" + + with epics_path.open() as f: + epics_config = config_from_yaml(f) + + server = Server( + AmplSummationModel, + epics_config, + ) + # monitor = False does not loop in main thread + server.start(monitor=True) diff --git a/examples/lcls/variables.yml b/examples/lcls/variables.yml new file mode 100644 index 0000000..2365ca7 --- /dev/null +++ b/examples/lcls/variables.yml @@ -0,0 +1,29 @@ +input_variables: + klys_li24_11: + type: scalar + default: 1 # will be dropped in later lume-epics iter + range: [0, 100] # will be dropped in later lume-epics iter + + klys_li24_21: + type: scalar + default: 1 # will be dropped in later lume-epics iter + range: [0, 100] # will be dropped in later lume-epics iter + + klys_li24_31: + type: scalar + default: 1 # will be dropped in later lume-epics iter + range: [0, 100] # will be dropped in later lume-epics iter + + klys_li24_41: + type: scalar + default: 1 # will be dropped in later lume-epics iter + range: [0, 100] # will be dropped in later lume-epics iter + + klys_li24_51: + type: scalar + default: 1 # will be dropped in later lume-epics iter + range: [0, 100] # will be dropped in later lume-epics iter + +output_variables: + summation: + type: scalar From b79b4e5dffde1720dccce18a46b24885c4f41ebe Mon Sep 17 00:00:00 2001 From: Jacqueline Garrahan Date: Fri, 3 Jun 2022 09:56:02 -0700 Subject: [PATCH 2/3] BUG: Protocol existence for pva problematic --- lume_epics/client/controller.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/lume_epics/client/controller.py b/lume_epics/client/controller.py index 4e99720..5fea894 100644 --- a/lume_epics/client/controller.py +++ b/lume_epics/client/controller.py @@ -123,8 +123,7 @@ def _ca_value_callback(self, pvname, value, *args, **kwargs): self._last_updates[pvname] = update_datetime def _ca_connection_callback(self, *, pvname, conn, pv): - """Callback used for monitoring connection and setting values to None on disconnect. - """ + """Callback used for monitoring connection and setting values to None on disconnect.""" if not conn: self._pv_registry[pvname]["value"] = None @@ -208,7 +207,7 @@ def get(self, pvname: str, root: str = None) -> np.ndarray: if pv: val = pv["value"] if val is None: - if protocol: + if protocol == "ca": val = pv["pv"].get() elif protocol == "pva": @@ -438,7 +437,10 @@ def put_image( logger.debug(f"No initial value set for {pvname}.") def put_array( - self, varname, array: np.ndarray = None, timeout: float = 1.0, + self, + varname, + array: np.ndarray = None, + timeout: float = 1.0, ) -> None: """Assign the value of an array process variable. Allows updates to individual attributes. From 8d6dd6b78b98f5a1349ceae110d26e08ecf12791 Mon Sep 17 00:00:00 2001 From: Jacqueline Garrahan Date: Fri, 3 Jun 2022 09:56:28 -0700 Subject: [PATCH 3/3] Check in client --- examples/lcls/client.py | 64 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) create mode 100644 examples/lcls/client.py diff --git a/examples/lcls/client.py b/examples/lcls/client.py new file mode 100644 index 0000000..96fc7b1 --- /dev/null +++ b/examples/lcls/client.py @@ -0,0 +1,64 @@ +from bokeh.io import curdoc +from bokeh import palettes +from bokeh.layouts import column, row +from bokeh.models import LinearColorMapper, Div + +from lume_epics.client.controller import Controller +from lume_model.utils import variables_from_yaml +from lume_epics.utils import config_from_yaml + +from lume_epics.client.widgets.plots import ImagePlot, Striptool +from lume_epics.client.widgets.tables import ValueTable +from lume_epics.client.widgets.controls import build_sliders, EntryTable +from lume_epics.client.controller import Controller +from pathlib import Path + +variable_path = Path(__file__).parent / "variables.yml" + +with variable_path.open() as f: + input_variables, output_variables = variables_from_yaml(f) + +# load epics configuration +epics_path = Path(__file__).parent / "epics_config.yml" + +with epics_path.open() as f: + epics_config = config_from_yaml(f) + +# create controller from epics config +controller = Controller(epics_config) + +# prepare as list for rendering +input_variables = list(input_variables.values()) +output_variables = list(output_variables.values()) + +input_value_table = ValueTable(input_variables, controller) +output_value_table = ValueTable(output_variables, controller) + +title_div = Div( + text=f"LCLS ampl sum: Last update {controller.last_update}", + style={ + "font-size": "150%", + "color": "#3881e8", + "text-align": "center", + "width": "100%", + }, +) + + +def update_div_text(): + global controller + title_div.text = f"LCLS ampl sum: Last update {controller.last_update}" + + +# render +curdoc().title = "LCLS ampl" +curdoc().add_root( + column( + row(column(title_div)), + row(input_value_table.table, output_value_table.table), + ) +) + +# must add refresh callbacks +curdoc().add_periodic_callback(input_value_table.update, 250) +curdoc().add_periodic_callback(output_value_table.update, 250)