From f1887e5f22a7dfb6e80b8aeae5c6c2108481bc6f Mon Sep 17 00:00:00 2001 From: gac-furka Date: Wed, 10 May 2023 15:05:22 +0200 Subject: [PATCH] May updates --- .furka.py.swo | Bin 16384 -> 0 bytes Run_table_update.py | 573 ++++++++++++++++++++++++++++++++++++++++++++ channels.py | 80 +++++++ furka.py | 159 ++++++------ qspace.py | 91 ++++++- spreadsheet.py | 94 ++++++++ tt_lib.py | 60 +++++ 7 files changed, 968 insertions(+), 89 deletions(-) delete mode 100644 .furka.py.swo create mode 100644 Run_table_update.py create mode 100644 channels.py create mode 100644 spreadsheet.py create mode 100644 tt_lib.py diff --git a/.furka.py.swo b/.furka.py.swo deleted file mode 100644 index f70213c8f5e6e025bfafc1d2733b30f0c0233575..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16384 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 MS|Ty|E?(3A7f6;?mH+?% diff --git a/Run_table_update.py b/Run_table_update.py new file mode 100644 index 0000000..d386516 --- /dev/null +++ b/Run_table_update.py @@ -0,0 +1,573 @@ +from sfdata import SFDataFiles +from sfdata import SFScanInfo +import pandas as pd +import glob +import datetime +import warnings +import io +import os +import time +import numpy as np +## You may need this !pip install lxml +warnings.filterwarnings('ignore') + +def PVchs(): + pv_name_dict={"SATUN:FELPHOTENE":'FEL_en (keV)', + "SATUN13-UIND030:POL-SET": 'Polarisation', + "SATOP11-OSGM087:exitslit": 'Exit_slit (um)', + "SATOP11-OSGM087:photonenergy": "Mono_en (eV)", + "SATFE10-OGAT053:transmission": "Gas_trans", + "SATFE10-PEPG046:PHOTON-ENERGY-PER-PULSE-AVG": "FEL_pulse_en (uJ)", + "SATES30-ARES:MOT_2TRY.RBV": "diode_otr_tth (deg)", + "SATES30-ARES:MOT_DRY.RBV": "diode_inr_tth (deg)", + "SATES30-ARES:MOT_SRZ.RBV": "sample_chi (deg)", + "SATES30-ARES:MOT_SRY.RBV": "sample_th (deg)", + "SATES30-ARES:MOT_SRX.RBV": "sample_phi (deg)", + "SATES30-ARES:MOT_STX.RBV": "sample_x (mm)", + "SATES30-ARES:MOT_STY.RBV": "sample_y (mm)", + "SATES30-ARES:MOT_STZ.RBV": "sample_z (mm)", + "SATES30-LS336:C_RBV": "sample_temp (K)", + "SATES30-LS336:A_RBV": "cryo_temp (K)", + "SLAAT-LGEN:DLY_OFFS1": "LXT_off1 (us)", + "SLAAT01-LTIM-PDLY:DELAY": "LXT_delay (ps)", + "SLAAT01-LTIM-PDLY:DELAY_Z_OFFS": "LXT_off1 (ps)", + "SLAAT31-LMOT-M801:MOT.RBV": "800_WP (deg)", + "SLAAT31-LMOT-M802:MOT.RBV": "comp1", + "SLAAT31-LMOT-M803:MOT.RBV": "comp2", + "SLAAT31-LMOT-M804:MOT.RBV": "comp3", + "SLAAT31-LMOT-M805:MOT.RBV": "comp4", + "SLAAT31-LMOT-M806:MOT.RBV": "EOS_delay (mm)", + "SLAAT31-LMOT-M807:MOT.RBV": "WL_delay (mm)", + "SLAAT31-LMOT-M808:MOT.RBV": "800_delay (mm)", + } + return pv_name_dict + +def colors(): + dict_colors = { + 'yellow_light' : ('#BF8F00', '2px solid #BF8F00', '#FFF2CC', '#FFFFFF'), + 'grey_light' : ('#808080', '2px solid #808080', '#EDEDED', '#FFFFFF'), + 'blue_light' : ('#305496', '2px solid #305496', '#D9E1F2', '#FFFFFF'), + 'orange_light' : ('#C65911', '2px solid #C65911', '#FCE4D6', '#FFFFFF'), + 'green_light' : ('#548235', '2px solid #548235', '#E2EFDA', '#FFFFFF'), + 'red_light' : ('#823535', '2px solid #823535', '#efdada', '#FFFFFF'), + 'yellow_dark' : ('#FFFFFF', '2px solid #BF8F00', '#FFF2CC', '#BF8F00'), + 'grey_dark' : ('#FFFFFF', '2px solid #808080', '#EDEDED', '#808080'), + 'blue_dark': ('#FFFFFF', '2px solid #305496', '#D9E1F2', '#305496'), + 'blue_yellow': ('#FFFFFF', '2px solid #305496', '#ecedbe', '#305496'), + 'orange_dark' : ('#FFFFFF', '2px solid #C65911', '#FCE4D6', '#C65911'), + 'green_dark' : ('#FFFFFF', '2px solid #548235', '#E2EFDA', '#548235'), + 'red_dark' : ('#FFFFFF', '2px solid #823535', '#efdada', '#823535') + } + return (dict_colors) + +def build_table_nocondition( + df, + color, + font_size='12px', + font_family='Century Gothic, sans-serif', + text_align='center', + width='600px', + index=False, + even_color='black', + even_bg_color='white', + odd_bg_color=None, + border_bottom_color=None, + escape=True, + width_dict=[], + padding="10px 10px 3px 3px", + float_format=None): + dict_colors = colors() + + if df.empty: + return '' + + # Set color + color, border_bottom, odd_background_color, header_background_color = dict_colors[color] + + if odd_bg_color: + odd_background_color = odd_bg_color + + if border_bottom_color: + border_bottom = border_bottom_color + + a = 0 + while a != len(df): + if a == 0: + df_html_output = df.iloc[[a]].to_html( + na_rep="", + index=index, + border=0, + escape=escape, + float_format=float_format, + ) + # change format of header + if index: + df_html_output = df_html_output.replace('' + ,'', len(df.columns)+1) + + df_html_output = df_html_output.replace('' + ,'') + + else: + df_html_output = df_html_output.replace('' + ,'') + + #change format of table + df_html_output = df_html_output.replace('' + ,'') + body = """

""" + format(df_html_output) + + a = 1 + + elif a % 2 == 0: + df_html_output = df.iloc[[a]].to_html(na_rep = "", index = index, header = False, escape=escape) + + # change format of index + df_html_output = df_html_output.replace('' + ,'') + + #change format of table + df_html_output = df_html_output.replace('' + ,'') + + body = body + format(df_html_output) + + a += 1 + + elif a % 2 != 0: + df_html_output = df.iloc[[a]].to_html(na_rep = "", index = index, header = False, escape=escape) + + # change format of index + df_html_output = df_html_output.replace('' + ,'') + + #change format of table + df_html_output = df_html_output.replace('' + ,'') + body = body + format(df_html_output) + + a += 1 + + body = body + """

""" + + body = body.replace(""" + + + + + + """,""" + + """).replace(""" + + +
+ + """,""" + + """) + + if len(width_dict) == len(df.columns): + width_body = '' + w = 0 + for line in io.StringIO(body): + line = line.replace("\n", "") + width_body = width_body + repr(line).replace("width: auto", 'width: ' + width_dict[w])[1:] + if str(repr(line))[:10] == "' ' + ,' + + +
', len(df.columns)+1) + + df_html_output = df_html_output.replace('' + ,'') + + else: + df_html_output = df_html_output.replace('' + ,'') + + #change format of table + df_html_output = df_html_output.replace('' + ,'') + body = """

""" + format(df_html_output) + + a = 1 + + elif a % 2 == 0: + df_html_output = df.iloc[[a]].to_html(na_rep = "", index = index, header = False, escape=escape) + + # change format of index + df_html_output = df_html_output.replace('

' + ,'') + + #change format of table + df_html_output = df_html_output.replace('' + ,'') + + body = body + format(df_html_output) + + a += 1 + + elif a % 2 != 0: + df_html_output = df.iloc[[a]].to_html(na_rep = "", index = index, header = False, escape=escape) + + # change format of index + df_html_output = df_html_output.replace('' + ,'') + + #change format of table + df_html_output = df_html_output.replace('' + ,'') + body = body + format(df_html_output) + + a += 1 + + body = body + """

""" + + body = body.replace("""
+ + + """,""" + + """).replace(""" + + +
+ + """,""" + + """) + + if conditions: + for k in conditions.keys(): + try: + conditions[k]['index'] = list(df.columns).index(k) + width_body = '' + w = 0 + for line in io.StringIO(body): + updated_body = False + if w == conditions[k]['index']: + try: + if float(repr(line).split('>')[1].split('<')[0]) < conditions[k]['min']: + if 'color: black' in repr(line): + width_body = width_body + repr(line).replace("color: black", 'color: ' + conditions[k]['min_color'])[1:] + elif 'color: white' in repr(line): + width_body = width_body + repr(line).replace("color: white", 'color: ' + conditions[k]['min_color'])[1:] + else: + width_body = width_body + repr(line).replace('">', '; color: ' + conditions[k]['min_color'] + '">')[1:] + updated_body = True + elif float(repr(line).split('>')[1].split('<')[0]) > conditions[k]['max']: + if 'color: black' in repr(line): + width_body = width_body + repr(line).replace("color: black", 'color: ' + conditions[k]['max_color'])[1:] + elif 'color: white' in repr(line): + width_body = width_body + repr(line).replace("color: white", 'color: ' + conditions[k]['max_color'])[1:] + else: + width_body = width_body + repr(line).replace('">', '; color: ' + conditions[k]['max_color'] + '">')[1:] + updated_body = True + except: + pass + if not updated_body: + width_body = width_body + repr(line)[1:] + + if str(repr(line))[:10] == "' keep_running_for*60*60: + print('Not running any more.') + break + print('Waiting to check.') + time.sleep(check_interval*60) + + + + + + diff --git a/channels.py b/channels.py new file mode 100644 index 0000000..95e004b --- /dev/null +++ b/channels.py @@ -0,0 +1,80 @@ +#Channels +channels = [ + "SATFE10-PEPG046:FCUP-INTENSITY-CAL", + "SATFE10-PEPG046-EVR0:CALCI", + "SATFE10-PEPG046:PHOTON-ENERGY-PER-PULSE-AVG", + "SATES30-LSCP10-FNS:CH0:VAL_GET", + "SATES30-LSCP10-FNS:CH1:VAL_GET", + "SATES30-LSCP10-FNS:CH2:VAL_GET", + "SATES30-LSCP10-FNS:CH3:VAL_GET", + "SATES30-LSCP10-FNS:CH4:VAL_GET", + "SATOP31-PMOS132-2D:SPECTRUM_CENTER", + "SATOP31-PMOS132-2D:SPECTRUM_FWHM", + "SATOP31-PMOS132-2D:SPECTRUM_X", + "SATOP31-PMOS132-2D:SPECTRUM_Y", +# "SATOP31-PMOS132-2D:FPICTURE", + "SATOP31-PMOS132-2D:processing_parameters", +# "SATES30-CVME-EVR0:CALCS", +# "SATES30-LSCP10-FNS:CH0:WFMi", +# "SATES31-CAMS187-RIXS1:SPC", +# "SATES31-CAMS187-RIXS1:SPC_gauss", +# "SATES31-CAMS187-RIXS1:SPC_wgt", +# "SATES31-CAMS187-RIXS1:Spectrum", +# "SATES31-CAMS187-RIXS1:evt_list", + "SATES30-CAMS182-GIGE2:FPICTURE", + "SATES31-CAMS187-RIXS1:FPICTURE", + "SATES31-CAMS187-RIXS1:x_profile", + "SATES31-CAMS187-RIXS1:y_profile", + "SATES31-CAMS187-RIXS1:intensity", + "SATES30-CVME-EVR0:DUMMY_PV1_NBS", + "SATES30-CVME-EVR0:DUMMY_PV2_NBS", + "SATES30-CVME-EVR0:DUMMY_PV3_NBS", + "SATES30-CVME-EVR0:DUMMY_PV4_NBS", + "SATES30-CVME-EVR0:DUMMY_PV5_NBS", + "SATES30-CVME-EVR0:DUMMY_PV6_NBS", + "SATES30-CVME-EVR0:DUMMY_PV7_NBS", + "SATES30-CVME-EVR0:DUMMY_PV8_NBS", + "SATES30-CVME-EVR0:DUMMY_PV9_NBS", + "SATES30-CVME-EVR0:DUMMY_PV10_NBS", + "SATES30-CVME-EVR0:CALCY", + "SLAAT31-LSCP1-FNS:CH0:VAL_GET", + "SLAAT31-LSCP1-FNS:CH1:VAL_GET", + "SLAAT31-LTIM01-EVR0:CALCI", + "SLAAT31-LTIM01-EVR0:CALCS", + "SAT-CVME_TIFALL5:EvtSet", + "SAT-CVME_TIFALL6:EvtSet" + +] + +pvs = [ + "SATFE10-PEPG046:PHOTON-ENERGY-PER-PULSE-AVG", + "SATUN13-UIND030:POL-SET", + "SATES30-ARES:MOT_2TRY.RBV", + "SATES30-ARES:MOT_DRY.RBV", + "SATES30-ARES:MOT_STX.RBV", + "SATES30-ARES:MOT_STY.RBV", + "SATES30-ARES:MOT_STZ.RBV", + "SATES30-ARES:MOT_SRX.RBV", + "SATES30-ARES:MOT_SRY.RBV", + "SATES30-ARES:MOT_SRZ.RBV", + "SLAAT31-LMOT-M801:MOT.RBV", + "SLAAT31-LMOT-M802:MOT.RBV", + "SLAAT31-LMOT-M803:MOT.RBV", + "SLAAT31-LMOT-M804:MOT.RBV", + "SLAAT31-LMOT-M805:MOT.RBV", + "SLAAT31-LMOT-M806:MOT.RBV", + "SLAAT31-LMOT-M807:MOT.RBV", + "SLAAT31-LMOT-M808:MOT.RBV", + "SATOP11-OSGM087:exitslit", + "SATOP11-OSGM087:photonenergy", + "SATUN:FELPHOTENE", + "SATFE10-OGAT053:transmission", + "SATES30-LS336:C_RBV", + "SATES30-LS336:A_RBV", + "SLAAT01-LTIM-PDLY:DELAY", + "SLAAT-LGEN:DLY_OFFS1", + "SLAAT01-LTIM-PDLY:DELAY_Z_OFFS", + "SATOP21-PMOS127-2D:SPECTRUM_X", + "SATOP21-PMOS127-2D:SPECTRUM_Y" +] + diff --git a/furka.py b/furka.py index de1b21a..483a4f7 100644 --- a/furka.py +++ b/furka.py @@ -14,6 +14,10 @@ from slic.gui import GUI from slic.utils import devices from slic.utils import as_shortcut, Marker +from spreadsheet import overview, print_overview, print_line_for_spreadsheet +from channels import channels, pvs + + from undulator import Undulators from undulator import Mono from undulator import Coupled_MonoUnd @@ -30,34 +34,54 @@ from constraints import ExtraConstraint dummy = DummyAdjustable(units="au") + +from slic.devices.general.smaract import SmarActAxis +parab_RY = SmarActAxis("SATES30-XSMA182:MOT4", name="Parab RY") +parab_RX = SmarActAxis("SATES30-XSMA182:MOT7", name="Parab RX") +taget_along_beam = SmarActAxis("SATES30-XSMA184:MOT6", name="Target along beam") + + +#Retro Chamber Motors #mot_x = Motor("SATES30-RETRO:MOT_X", name="Retro X") -mot_y = Motor("SATES30-RETRO:MOT_Y", name="Retro Y") +#mot_y = Motor("SATES30-RETRO:MOT_Y", name="Retro Y") #mot_z = Motor("SATES30-RETRO:MOT_Z", name="Retro Z") #mot_theta = Motor("SATES30-RETRO:MOT_RY", name="Retro Theta") - #retro = SimpleDevice("Retro Stages", x=mot_x, y=mot_y, z=mot_z, theta=mot_theta) -KBV_RX = PVAdjustable("SATOP31-OKBV178:W_RX.VAL", pvname_moving="SATOP31-OKBV178:MOVING", name = "KB_Vertical_RX") -#KBV_RX = PVAdjustable("SATOP31-OKBV178:W_RX.VAL", process_time=1, name = "KBV_RX") -KBH_RY = PVAdjustable("SATOP31-OKBH179:W_RY.VAL", pvname_moving="SATOP31-OKBH179:MOVING", name = "KB_Horiz_RY") -#KBH_RY = PVAdjustable("SATOP31-OKBH179:W_RY.VAL", process_time=1, name = "KBH_RY") -lxt = PVAdjustable("SLAAT01-LTIM-PDLY:DELAY", pvname_done_moving="SLAAT01-LTIM-PDLY:WAITING", name="LXT") +#Furka Kbs motors +KBV_RX = PVAdjustable("SATOP31-OKBV178:W_RX.VAL", pvname_moving="SATOP31-OKBV178:MOVING", name = "KB Ver RX") +KBH_RY = PVAdjustable("SATOP31-OKBH179:W_RY.VAL", pvname_moving="SATOP31-OKBH179:MOVING", name = "KB Horiz RY") -#mono_slits = PVAdjustable("SATOP11-OSGM087:EXITSLIT",pvname_done_moving="SATOP31-OEXS132:MOT_H.DMOV", name = "Mono_Slits" ) +## PMOS adjustables +PMOS127_FOCUS = PVAdjustable("SLAAT-GSLENS0:SET_CTS_POWER", process_time=1, name="PMOS127_FOCUS") +PMOS132_FOCUS = PVAdjustable("SLAAT-GSLENS1:SET_CTS_POWER", process_time=1, name="PMOS132_FOCUS") +#PMOS_FOCUS = PVAdjustable("SLAAT-GSLENS1:SET_CTS_POWER", process_time=1, name="PMOS_FOCUS") +MONO_G_rad = PVAdjustable("SATOP11-OSGM087:G_RADIUS", pvname_moving="SATOP11-OSGM087:MONO_STATUS", name="MONO_G_rad") +MONO_M_rad = PVAdjustable("SATOP11-OSGM087:M_RADIUS", pvname_moving="SATOP11-OSGM087:MONO_STATUS", name="MONO_M_rad") +MONO_M_curv = PVAdjustable("SATOP11-OSGM087:M_CURVATURE", pvname_moving="SATOP11-OSGM087:MONO_STATUS", name="MONO_M_curv") + +## OAPU085 +OAPU085_vert = PVAdjustable("SATOP11-OAPU085:MOTOR_Y.VAL", process_time=1, name="OAPU085_vert") + +##mono_slits = PVAdjustable("SATOP11-OSGM087:EXITSLIT",pvname_done_moving="SATOP31-OEXS132:MOT_H.DMOV", name = "Mono_Slits" ) + +#undulators set-up n_und_ref = 13 n_unds = [ 6, 7, 8, 9, 10, 11, 12, 13, # 14 is the CHIC 15, 16, 17, 18, 19, 20, 21, 22 ] chic_fudge_offset = 0 -Mon2Unds_offset = 9 +Mon2Unds_offset = 1.8 und = Undulators(n_unds, n_und_ref, chic_fudge_offset, name="z Athos Undulators") #und = Undulators(name="Undulators") + +#Mono set up mono_name = "Athos_mono" pv_mono_name="SATOP11-OSGM087" @@ -69,11 +93,17 @@ MonUnd = Coupled_MonoUnd( name="Mono+Und" ) -tth_scan = Coupled_tth(delta=0.3885, name="theta 2theta") +Mon_ES = PVAdjustable("SATOP11-OSGM087:EXITSLIT", pvname_done_moving="SATOP31-OEXS132:MOT_H.DMOV", name = "Mono ES") +gas_attenuator_trans = PVAdjustable("SATFE10-OGAT053:TRANSMISSION", process_time=20, name="Gas Attenuator Transmission") + lakeshore = PVAdjustable("SATES30-LS336:LOOP1_SP", "SATES30-LS336:A_RBV", accuracy=0.25, name="Lakeshore Temp") +#att = Attenuator("SATFE10-OATT064") +#shutter = Shutter("SATOP31-OPSH138") + + #lakeshore = LakeShore(name="Temperature") @@ -83,98 +113,67 @@ wl = Wavelength(Mon) -mu = Motor("SATES30-RIXS:MOT_SRY.VAL") -chi = Motor("SATES30-RIXS:MOT_SRZ.VAL") -phi = Motor("SATES30-RIXS:MOT_SRX.VAL") -nu = Motor("SATES30-RIXS:MOT_DRY.VAL") +#Diffractometer motions +mu = Motor("SATES30-ARES:MOT_SRY.VAL", name = "Diff RY") +chi = Motor("SATES30-ARES:MOT_SRZ.VAL", name = "Diff RZ") +phi = Motor("SATES30-ARES:MOT_SRX.VAL", name = "Diff RX") +nu = Motor("SATES30-ARES:MOT_DRY.VAL", name = "Diff DRY") q = QSpace3D("SOMETHING:Q", mu, chi, phi, nu, wl) -TX = Motor("SATES30-RIXS:MOT_STX.VAL") -TY = Motor("SATES30-RIXS:MOT_STY.VAL") -TZ = Motor("SATES30-RIXS:MOT_STZ.VAL") -TwoTRY=Motor("SATES30-RIXS:MOT_2TRY.VAL") +TX = Motor("SATES30-ARES:MOT_STX.VAL", name = "Diff TX") +TY = Motor("SATES30-ARES:MOT_STY.VAL", name = "Diff TY") +TZ = Motor("SATES30-ARES:MOT_STZ.VAL", name = "Diff TZ") +TwoTRY=Motor("SATES30-ARES:MOT_2TRY.VAL", name = "Diff 2TRY") + + +tth_scan = Coupled_tth(delta=0.3885, name="theta 2theta") -PICO_X1 = PVAdjustable("SLAAT31-LMNP-PICO11:DRIVE", name="PICO X1") + +#fake_mu = HistoryDummy.init_from(mu) +#fake_chi = HistoryDummy.init_from(chi) +#fake_phi = HistoryDummy.init_from(phi) +#fake_nu = HistoryDummy.init_from(nu) +#fake_q = QSpace3D("FAKE:Q", fake_mu, fake_chi, fake_phi, fake_nu, wl) +##fake_q.set_lattice("FAKE:Q", fake_mu, fake_chi, fake_phi, fake_nu, wl) + + + +#Laser motors + +lxt = PVAdjustable("SLAAT01-LTIM-PDLY:DELAY", pvname_done_moving="SLAAT01-LTIM-PDLY:WAITING", name="LXT") + +PICO_X1 = PVAdjustable("SLAAT31-LMNP-PICO11:DRIVE", name="PICO X1") PICO_Y1 = PVAdjustable("SLAAT31-LMNP-PICO12:DRIVE", name="PICO Y1") +Thz_delay = Motor("SLAAT31-LMOT-M806:MOT", name="Thz Delay") +WL_delay = Motor("SLAAT31-LMOT-M807:MOT", name="WL Delay") +gate_delay = Motor("SLAAT31-LMOT-M808:MOT", name="Gate Delay") - - -fake_mu = HistoryDummy.init_from(mu) -fake_chi = HistoryDummy.init_from(chi) -fake_phi = HistoryDummy.init_from(phi) -fake_nu = HistoryDummy.init_from(nu) -fake_q = QSpace3D("FAKE:Q", fake_mu, fake_chi, fake_phi, fake_nu, wl) -#fake_q.set_lattice("FAKE:Q", fake_mu, fake_chi, fake_phi, fake_nu, wl) - -laser_delay = Motor("SLAAT31-LMOT-M808:MOT", name="Laser Delay") laser_WP = Motor("SLAAT31-LMOT-M801:MOT", name="Laser WavePlate") -channels = [ - "SATFE10-PEPG046:FCUP-INTENSITY-CAL", - "SATFE10-PEPG046-EVR0:CALCI", - "SATFE10-PEPG046:PHOTON-ENERGY-PER-PULSE-AVG", - "SATES30-LSCP10-FNS:CH0:VAL_GET", - "SATES30-LSCP10-FNS:CH1:VAL_GET", - "SATES30-LSCP10-FNS:CH2:VAL_GET", - "SATES30-LSCP10-FNS:CH3:VAL_GET", - "SATES30-LSCP10-FNS:CH4:VAL_GET", -# "SATOP31-PMOS132-2D:SPECTRUM_CENTER", -# "SATOP31-PMOS132-2D:SPECTRUM_FWHM", -# "SATOP31-PMOS132-2D:SPECTRUM_X", -# "SATOP31-PMOS132-2D:SPECTRUM_Y", -# "SATOP31-PMOS132-2D:processing_parameters", -# "SATES30-CVME-EVR0:CALCS", - "SLAAT21-LSCP01-FNS:CH0:VAL_GET", - "SLAAT21-LSCP01:CH0:1", -# "SATES30-LSCP10-FNS:CH0:WFMi" -# "SATES31-CAMS187-RIXS1:SPC", -# "SATES31-CAMS187-RIXS1:SPC_gauss", -# "SATES31-CAMS187-RIXS1:SPC_wgt", -# "SATES31-CAMS187-RIXS1:Spectrum", -# "SATES31-CAMS187-RIXS1:evt_list", -# "SATES31-CAMS187-RIXS1:FPICTURE" - "SATES30-CVME-EVR0:DUMMY_PV1_NBS", - "SATES30-CVME-EVR0:DUMMY_PV2_NBS", - "SATES30-CVME-EVR0:DUMMY_PV3_NBS", - "SATES30-CVME-EVR0:DUMMY_PV4_NBS", - "SATES30-CVME-EVR0:DUMMY_PV5_NBS", - "SATES30-CVME-EVR0:DUMMY_PV6_NBS", - "SATES30-CVME-EVR0:DUMMY_PV7_NBS", - "SATES30-CVME-EVR0:DUMMY_PV8_NBS", - "SATES30-CVME-EVR0:DUMMY_PV9_NBS", - "SATES30-CVME-EVR0:DUMMY_PV10_NBS" -] -pvs = [ - "SATFE10-PEPG046:PHOTON-ENERGY-PER-PULSE-AVG", - "SATES30-RETRO:MOT_RY.RBV", - "SATES30-RETRO:MOT_X.RBV", - "SATES30-RETRO:MOT_Y.RBV", - "SATES30-RETRO:MOT_Z.RBV", - "SATUN:FELPHOTENE" -] -live_channels = [ - "SATES30-LSCP10-FNS:CH0:VAL_GET", - "SATES30-LSCP10-FNS:CH1:VAL_GET", -# "SATES30-LSCP10-FNS:CH0:WFM" -# "SATES30-LSCP10-FNS:CH4:VAL_GET" -] +#overview.Thz_delay = Thz_delay + + + instrument = "furka" -pgroup = "p19735" #Commissioning p group +pgroup = "p20452" #Commissioning p group #check_intensity = PVCondition("SATFE10-PEPG046:FCUP-INTENSITY-CAL", vmin=5, vmax=None, wait_time=3, required_fraction=0.8) -#check_intensity = None check_intensity = PVCondition("SATBD01-DBPM060:Q2", vmin=5, vmax=None, wait_time=1, required_fraction=0.8) +#check_intensity = None + daq = SFAcquisition(instrument, pgroup, default_channels=channels, default_pvs=pvs, rate_multiplicator=1) +daq.update_config_pvs() #daq = FakeAcquisition(instrument, pgroup, default_channels=channels, default_pvs=pvs, rate_multiplicator=1) +#daq = BSAcquisition .... TBI #daqPV = PVAcquisition(instrument, pgroup, default_channels=live_channels) scan = Scanner(default_acquisitions=[daq], condition=check_intensity) diff --git a/qspace.py b/qspace.py index 6ba98c2..6d145b5 100644 --- a/qspace.py +++ b/qspace.py @@ -87,7 +87,7 @@ class QSpace3D(Device): for name, value in kwargs.items(): setattr(self.dc.cons, name, value) - def get_position(self, *args, extra_cons=None): + def get_position(self, *args, extra_cons): wl = self.wavelength.get_current_value() res = self.dc.hkl.get_position(*args, wl) if extra_cons: @@ -120,7 +120,66 @@ class QSpace3D(Device): # if I understand the examples/code correctly, then some more method calls are mandatory? # those should probably all get shortcuts... + def _get_hkl(self): + angles = self._get_angles() + return self._calc_hkl(*angles) + def _get_angles(self): + ms = self.motors + mu = ms.mu.get_current_value() + chi = ms.chi.get_current_value() + phi = ms.phi.get_current_value() + nu = ms.nu.get_current_value() + return mu, chi, phi, nu + + def _calc_hkl(self, mu, chi, phi, nu): + wl = self.get_wavelength() + pos = Position(mu=mu, chi=chi, phi=phi, nu=nu) + hkl = self.dc.hkl.get_hkl(pos, wl) + return hkl + + def get_wavelength(self): + return self.wavelength.get_current_value() + + def _set_hkl(self, h, k, l, extra_cons): + angles = self._calc_angles(h, k, l, extra_cons) + self._set_angles(*angles) + + def _set_angles(self, mu, chi, phi, nu): + ms = self.motors + t_mu = ms.mu.set_target_value(90+mu) + t_chi = ms.chi.set_target_value(chi-180) + t_phi = ms.phi.set_target_value(phi) + t_nu = ms.nu.set_target_value(180+nu) # We may need a correct offset value + # wait for all motors to arrive + tasks = (t_mu, t_chi, t_phi, t_nu) + for t in tasks: + t.wait() + +# def _set_angles(self, mu, chi, phi, nu): +# ms = self.motors +# t_mu = ms.mu.set_target_value(90-mu) +# t_chi = ms.chi.set_target_value(chi) +# t_phi = ms.phi.set_target_value(phi) +# t_nu = ms.nu.set_target_value(nu) + # wait for all motors to arrive +# tasks = (t_mu, t_chi, t_phi, t_nu) +# for t in tasks: +# t.wait() + +# def _calc_angles(self, h, k, l): +# wl = self.get_wavelength() +# pos, _virtual_angles = next(iter( +# self.dc.hkl.get_position(h, k, l, wl) +# )) +# return pos.mu, pos.chi, pos.phi, pos.nu + + def _calc_angles(self, h, k, l, extra_cons): + wl = self.get_wavelength() + pos, _virtual_angles = next(iter( + self.get_position(h, k, l, extra_cons=extra_cons) + )) + return pos.mu, pos.chi, pos.phi, pos.nu def _flatten_get_position_result(x): d0, d1 = x @@ -146,13 +205,14 @@ class QSpace1D(Adjustable): i = self._get_index() return hkl[i] - def set_target_value(self, value): + def set_target_value(self, value, extra_cons): # get all current indices hkl = self._get_hkl() + hkl = list(hkl) i = self._get_index() # insert the target value into the right spot hkl[i] = value - self._set_hkl(self, *hkl) + self._set_hkl(*hkl,extra_cons) def is_moving(self): ms = self.motors @@ -161,6 +221,13 @@ class QSpace1D(Adjustable): # some helpful things: + def get_position(self, *args, extra_cons): + wl = self.wavelength.get_current_value() + res = self.dc.hkl.get_position(*args, wl) + if extra_cons: + res = [r for r in res if extra_cons(_flatten_get_position_result(r))] + return res + def get_wavelength(self): return self.wavelength.get_current_value() @@ -179,9 +246,9 @@ class QSpace1D(Adjustable): angles = self._get_angles() return self._calc_hkl(*angles) - def _set_hkl(self, h, k, l): - angles = self._calc_angles(self, h, k, l) - self._set_angles(self, *angles) + def _set_hkl(self, h, k, l, extra_cons): + angles = self._calc_angles(h, k, l, extra_cons) + self._set_angles(*angles) def _get_angles(self): ms = self.motors @@ -208,15 +275,21 @@ class QSpace1D(Adjustable): hkl = self.dc.hkl.get_hkl(pos, wl) return hkl - def _calc_angles(self, h, k, l): +# def _calc_angles(self, h, k, l): +# wl = self.get_wavelength() +# pos, _virtual_angles = next(iter( +# self.dc.hkl.get_position(h, k, l, wl) +# )) +# return pos.mu, pos.chi, pos.phi, pos.nu + + def _calc_angles(self, h, k, l, extra_cons): wl = self.get_wavelength() pos, _virtual_angles = next(iter( - self.dc.hkl.get_position(h, k, l, wl) + self.get_position(h, k, l, extra_cons) )) return pos.mu, pos.chi, pos.phi, pos.nu - h = 6.62607015e-34 # J s c = 299792458 # m / s e = 1.60217663e-19 # C diff --git a/spreadsheet.py b/spreadsheet.py new file mode 100644 index 0000000..e7988b0 --- /dev/null +++ b/spreadsheet.py @@ -0,0 +1,94 @@ +from slic.core.adjustable import PVAdjustable, PVEnumAdjustable +from slic.core.device import SimpleDevice +from slic.utils import as_shortcut + + +class PVStringAdjustable(PVAdjustable): + def get_current_value(self): + return self.pvs.readback.get(as_string=True).strip() + + + +n_unds = [ + 6, 7, 8, 9, 10, 11, 12, 13, # 14 is the CHIC + 15, 16, 17, 18, 19, 20, 21, 22 +] + +undulator_info = {} +for i in n_unds: + undulator_info[f"energy{i}"] = PVAdjustable(f"SATUN{i:02}-UIND030:FELPHOTENE", internal=True) + undulator_info[f"polarisation{i}"] = PVEnumAdjustable(f"SATUN{i:02}-UIND030:POL-SET", internal=True) + + + +overview = SimpleDevice("Furka Overview", + + + FELrepRate = PVAdjustable("SWISSFEL-STATUS:Bunch-2-Appl-Freq-RB", internal=True), + Diffr2TRY = PVAdjustable("SATES30-ARES:MOT_2TRY.VAL", internal=True), + DiffrDRY = PVAdjustable("SATES30-ARES:MOT_DRY.VAL", internal=True), + DiffrTX = PVAdjustable("SATES30-ARES:MOT_STX.VAL", internal=True), + DiffrTY = PVAdjustable("SATES30-ARES:MOT_STY.VAL", internal=True), + DiffrTZ = PVAdjustable("SATES30-ARES:MOT_STZ.VAL", internal=True), + DiffrRX = PVAdjustable("SATES30-ARES:MOT_SRX.VAL", internal=True), + DiffrRY = PVAdjustable("SATES30-ARES:MOT_SRY.VAL", internal=True), + DiffrRZ = PVAdjustable("SATES30-ARES:MOT_SRZ.VAL", internal=True), + + + + + att64 = PVStringAdjustable("SATFE10-OATT064:MOT2TRANS.VALD", internal=True), + att65 = PVStringAdjustable("SATFE10-OATT065:MOT2TRANS.VALD", internal=True), + + photonEnergy = PVAdjustable("SATUN:FELPHOTENE", internal=True), + + **undulator_info +) + + + +spreadsheet_line = [ + "timeStamp", "run name", "File name", "comments", "static/scan", "start", "stop", "step size", "shots", "Sample", + "ppressChamb3", + "photonEnergy", + "pulse_energy", + "FELrepRate", + "att64", + "att65", + "energy6", + "energy7", + "energy8", + "energy9", + "energy10", + "energy11", + "energy12", + "energy13", + "energy14", + "energy15", + "energy16", + "energy17", + "energy18", + "energy19", + "energy20", + "energy21", + "energy22", +] + + + +@as_shortcut +def print_overview(): + print(overview) + +@as_shortcut +def print_line_for_spreadsheet(): + ov = overview.__dict__ + def get(i): + if i in ov: + return str(ov[i].get()) + return "" + res = [get(i) for i in spreadsheet_line] + res = ",".join(res) + print(res) + + diff --git a/tt_lib.py b/tt_lib.py new file mode 100644 index 0000000..f072466 --- /dev/null +++ b/tt_lib.py @@ -0,0 +1,60 @@ +def tt_off_acq(shots): + import numpy as np + from epics import caget, caput, cainfo + import time + data = caget('SATES31-CAMS187-RIXS1:FPICTURE') + x_size = int(caget('SATES31-CAMS187-RIXS1:CAMROI_X_END')-caget('SATES31-CAMS187-RIXS1:CAMROI_X_START')+1) + y_size = int(len(data)/x_size) + ave = [] + + for i in range(shots): + data = caget('SATES31-CAMS187-RIXS1:FPICTURE') + ROI = [data[j:j+x_size] for j in range(0,int(len(data)),x_size)] + ROI = np.transpose(ROI) + x_prof = [] + for j in range(len(ROI)): + x_prof.append(np.sum(ROI[j])) + ave.append(x_prof) + ave = np.nanmean(ave,axis=0) + return (ave) + +def tt_live(off,sleep=0.1): + import numpy as np + from epics import caget, caput, cainfo + from matplotlib import pyplot as plt + import time + + data = caget('SATES31-CAMS187-RIXS1:FPICTURE') + x_size = int(caget('SATES31-CAMS187-RIXS1:CAMROI_X_END')-caget('SATES31-CAMS187-RIXS1:CAMROI_X_START')+1) + y_size = int(len(data)/x_size) + + xx = np.arange(1,x_size+1,1) + ROI = [data[i:i+x_size] for i in range(0,int(len(data)),x_size)] + ROI = np.transpose(ROI) + x_prof = [] + for i in range(len(ROI)): + x_prof.append(np.sum(ROI[i])) + pp = (np.array(x_prof)/np.array(off)-1)*100 + + plt.ion() + fig = plt.figure() + ax = fig.subplots(nrows=1,ncols=1) + tt, = ax.plot(xx,pp) + + plt.title('timing-tool live x profile in ROI',fontsize=20) + plt.xlabel('pixel',fontsize=16) + plt.ylabel('(on-off)/off [%]',fontsize=16) + + for _ in iter(int,1): + data = caget('SATES31-CAMS187-RIXS1:FPICTURE') + ROI = [data[i:i+x_size] for i in range(0,int(len(data)),x_size)] + ROI = np.transpose(ROI) + x_prof = [] + for i in range(len(ROI)): + x_prof.append(np.sum(ROI[i])) + pp = (np.array(x_prof)/np.array(off)-1)*100 + tt.set_ydata(np.array(pp)) + fig.canvas.draw() + fig.canvas.flush_events() + time.sleep(sleep) +