diff --git a/__pycache__/bs_channels.cpython-39.pyc b/__pycache__/bs_channels.cpython-39.pyc index 19c418d..358350d 100644 Binary files a/__pycache__/bs_channels.cpython-39.pyc and b/__pycache__/bs_channels.cpython-39.pyc differ diff --git a/__pycache__/cristallina.cpython-39.pyc b/__pycache__/cristallina.cpython-39.pyc index 893d221..21c3a82 100644 Binary files a/__pycache__/cristallina.cpython-39.pyc and b/__pycache__/cristallina.cpython-39.pyc differ diff --git a/__pycache__/pv_channels.cpython-39.pyc b/__pycache__/pv_channels.cpython-39.pyc index e56c060..2d6f2c7 100644 Binary files a/__pycache__/pv_channels.cpython-39.pyc and b/__pycache__/pv_channels.cpython-39.pyc differ diff --git a/__pycache__/smaract.cpython-39.pyc b/__pycache__/smaract.cpython-39.pyc index 44110f3..d424705 100644 Binary files a/__pycache__/smaract.cpython-39.pyc and b/__pycache__/smaract.cpython-39.pyc differ diff --git a/__pycache__/smaract_device_def.cpython-39.pyc b/__pycache__/smaract_device_def.cpython-39.pyc index 2843c3c..5fd3d1b 100644 Binary files a/__pycache__/smaract_device_def.cpython-39.pyc and b/__pycache__/smaract_device_def.cpython-39.pyc differ diff --git a/__pycache__/standa.cpython-39.pyc b/__pycache__/standa.cpython-39.pyc new file mode 100644 index 0000000..4e732df Binary files /dev/null and b/__pycache__/standa.cpython-39.pyc differ diff --git a/__pycache__/undulator.cpython-39.pyc b/__pycache__/undulator.cpython-39.pyc index eb44717..bd1681d 100644 Binary files a/__pycache__/undulator.cpython-39.pyc and b/__pycache__/undulator.cpython-39.pyc differ diff --git a/bs_channels.py b/bs_channels.py index 421784e..bfefefa 100644 --- a/bs_channels.py +++ b/bs_channels.py @@ -13,7 +13,7 @@ detectors = [ camera_channels = [ # "SARES30-CAMS156-PCO1:FPICTURE", # PCO edge camera for the wavefront analysis (from Alvra) # "SARES30-CAMS156-SMX-OAV:FPICTURE", # SwissMX OAV camera picture - # "SARES30-CAMS156-XE:FPICTURE", # X-ray eye + "SARES30-CAMS156-XE:FPICTURE", # X-ray eye ] #################### @@ -25,6 +25,78 @@ channels_gas_monitor = [ "SARFE10-PBIG050-EVR0:CALCI", # good for correlations with total beam intensity "SARFE10-PBPG050:HAMP-INTENSITY-CAL", ] +# RF phases and amplitudes +channels_RF = [ + "SINSB01-RLLE-DSP:PHASE-VS", + "SINSB02-RLLE-DSP:PHASE-VS", + "SINSB03-RLLE-DSP:PHASE-VS", + "SINSB04-RLLE-DSP:PHASE-VS", + "SINXB01-RLLE-DSP:PHASE-VS", + "SINDI01-RLLE-DSP:PHASE-VS", + "S10CB01-RLLE-DSP:PHASE-VS", + "S10CB02-RLLE-DSP:PHASE-VS", + "S10CB03-RLLE-DSP:PHASE-VS", + "S10CB04-RLLE-DSP:PHASE-VS", + "S10CB05-RLLE-DSP:PHASE-VS", + "S10CB06-RLLE-DSP:PHASE-VS", + "S10CB07-RLLE-DSP:PHASE-VS", + "S10CB08-RLLE-DSP:PHASE-VS", + "S10CB09-RLLE-DSP:PHASE-VS", + "S20CB01-RLLE-DSP:PHASE-VS", + "S20CB02-RLLE-DSP:PHASE-VS", + "S20CB03-RLLE-DSP:PHASE-VS", + "S20CB04-RLLE-DSP:PHASE-VS", + "S30CB01-RLLE-DSP:PHASE-VS", + "S30CB02-RLLE-DSP:PHASE-VS", + "S30CB03-RLLE-DSP:PHASE-VS", + "S30CB04-RLLE-DSP:PHASE-VS", + "S30CB05-RLLE-DSP:PHASE-VS", + "S30CB06-RLLE-DSP:PHASE-VS", + "S30CB07-RLLE-DSP:PHASE-VS", + "S30CB08-RLLE-DSP:PHASE-VS", + "S30CB09-RLLE-DSP:PHASE-VS", + "S30CB10-RLLE-DSP:PHASE-VS", + "S30CB11-RLLE-DSP:PHASE-VS", + "S30CB12-RLLE-DSP:PHASE-VS", + "S30CB13-RLLE-DSP:PHASE-VS", + "S30CB14-RLLE-DSP:PHASE-VS", + "SINEG01-RLLE-DSP:AMPLT-VS", + "SINSB01-RLLE-DSP:AMPLT-VS", + "SINSB02-RLLE-DSP:AMPLT-VS", + "SINSB03-RLLE-DSP:AMPLT-VS", + "SINSB04-RLLE-DSP:AMPLT-VS", + "SINXB01-RLLE-DSP:AMPLT-VS", + "SINDI01-RLLE-DSP:AMPLT-VS", + "S10CB01-RLLE-DSP:AMPLT-VS", + "S10CB02-RLLE-DSP:AMPLT-VS", + "S10CB03-RLLE-DSP:AMPLT-VS", + "S10CB04-RLLE-DSP:AMPLT-VS", + "S10CB05-RLLE-DSP:AMPLT-VS", + "S10CB06-RLLE-DSP:AMPLT-VS", + "S10CB07-RLLE-DSP:AMPLT-VS", + "S10CB08-RLLE-DSP:AMPLT-VS", + "S10CB09-RLLE-DSP:AMPLT-VS", + "S20CB01-RLLE-DSP:AMPLT-VS", + "S20CB02-RLLE-DSP:AMPLT-VS", + "S20CB03-RLLE-DSP:AMPLT-VS", + "S20CB04-RLLE-DSP:AMPLT-VS", + "S30CB01-RLLE-DSP:AMPLT-VS", + "S30CB02-RLLE-DSP:AMPLT-VS", + "S30CB03-RLLE-DSP:AMPLT-VS", + "S30CB04-RLLE-DSP:AMPLT-VS", + "S30CB05-RLLE-DSP:AMPLT-VS", + "S30CB06-RLLE-DSP:AMPLT-VS", + "S30CB07-RLLE-DSP:AMPLT-VS", + "S30CB08-RLLE-DSP:AMPLT-VS", + "S30CB09-RLLE-DSP:AMPLT-VS", + "S30CB10-RLLE-DSP:AMPLT-VS", + "S30CB11-RLLE-DSP:AMPLT-VS", + "S30CB12-RLLE-DSP:AMPLT-VS", + "S30CB13-RLLE-DSP:AMPLT-VS", + "S30CB14-RLLE-DSP:AMPLT-VS", +] + +channels_Xeye = ['SARES30-CAMS156-XE:intensity'] ###################### # PBPS053 @@ -44,17 +116,23 @@ channels_PSSS059=[ "SARFE10-PSSS059:SPECT-COM", "SARFE10-PSSS059:SPECT-RES", "SARFE10-PSSS059:SPECT-RMS", - "SARFE10-PSSS059:SPECTRUM_Y_SUM" + "SARFE10-PSSS059:SPECTRUM_Y_SUM", "SARFE10-PSSS059:SPECTRUM_X", "SARFE10-PSSS059:SPECTRUM_Y", - # "SARFE10-PSSS059:FPICTURE", - # "SARFE10-PSSS059:FIT_ERR", + #"SARFE10-PSSS059:FPICTURE", + "SARFE10-PSSS059:FIT_ERR", "SARFE10-PSSS059:processing_parameters", - # "SARFE10-PSSS059:SPECTRUM_AVG_CENTER", - # "SARFE10-PSSS059:SPECTRUM_AVG_FWHM", - # "SARFE10-PSSS059:SPECTRUM_AVG_Y", + "SARFE10-PSSS059:SPECTRUM_AVG_CENTER", + "SARFE10-PSSS059:SPECTRUM_AVG_FWHM", + "SARFE10-PSSS059:SPECTRUM_AVG_Y", ] +################################### +## Bernina channels +# Beam position monitor PBPS113 +channels_Bernina=[ + #"SAROP21-PBPS103:INTENSITY", +] ################################### # Beam position monitor PBPS113 channels_PBPS113 = [ @@ -64,10 +142,28 @@ channels_PBPS113 = [ "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD1", "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD2", "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD3", - # "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD4", + "SAROP31-PBPS113:Lnk9Ch0-PP_VAL_PD4", "SAROP31-PBPS113:XPOS", "SAROP31-PBPS113:YPOS", ] +channels_PBPS113_waveforms = [ + "SAROP31-PBPS113:Lnk9Ch0-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch1-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch2-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch3-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch4-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch5-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch6-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch7-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch8-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch9-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch10-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch11-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch12-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch13-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch14-WF-DATA", + "SAROP31-PBPS113:Lnk9Ch15-WF-DATA", +] #################### # Profile monitor PPRM113 (from _proc process) @@ -94,17 +190,35 @@ channels_PPRM113 = [ ########################### # Beam position monitor PBPS149 -channel_PBPS149 = [ +channels_PBPS149 = [ "SAROP31-PBPS149:INTENSITY", "SAROP31-PBPS149:INTENSITY_UJ", "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD0", "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD1", "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD2", "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD3", - # "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD4", + "SAROP31-PBPS149:Lnk9Ch0-PP_VAL_PD4", "SAROP31-PBPS149:XPOS", "SAROP31-PBPS149:YPOS", ] +channels_PBPS149_waveforms = [ + "SAROP31-PBPS149:Lnk9Ch0-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch1-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch2-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch3-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch4-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch5-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch6-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch7-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch8-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch9-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch10-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch11-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch12-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch13-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch14-WF-DATA", + "SAROP31-PBPS149:Lnk9Ch15-WF-DATA", +] ####################### # Profile monitor PPRM150 (from _proc process) @@ -156,12 +270,16 @@ channels_other = [ bs_channels = ( camera_channels + channels_gas_monitor - + channels_PBPS053 + + channels_RF + + channels_Xeye + channels_PBPS053 + channels_PSSS059 + #+ channels_Bernina + channels_PBPS113 + # + channels_PBPS113_waveforms + channels_PPRM113 - + channel_PBPS149 + + channels_PBPS149 + # + channels_PBPS149_waveforms + channels_PPRM150 + channels_EVR # + channels_digitizer diff --git a/cristallina.py b/cristallina.py index 3681729..85a5b7b 100644 --- a/cristallina.py +++ b/cristallina.py @@ -5,15 +5,16 @@ logger = logging.getLogger("slic") logger.setLevel(logging.INFO) logger.info("Loading started.") +# create file handler which logs +fh = logging.FileHandler('/sf/cristallina/applications/slic/cristallina/log/cristallina.log') +fh.setLevel(logging.DEBUG) +logger.addHandler(fh) + from time import sleep -from datetime import datetime - -import numpy as np - +import sys import os os.chdir('/sf/cristallina/applications/slic/cristallina') -# from tqdm import trange from epics import PV from alignment_laser import AlignmentLaser @@ -22,18 +23,16 @@ from slic.core.adjustable import Adjustable, PVAdjustable, DummyAdjustable from slic.core.acquisition import SFAcquisition, PVAcquisition from slic.core.condition import PVCondition from slic.core.scanner import Scanner -from slic.core.device.simpledevice import SimpleDevice from slic.devices.xdiagnostics.intensitymonitor import IntensityMonitorPBPS from slic.devices.general.motor import Motor -from slic.devices.general.shutter import Shutter from slic.devices.xoptics.pulsepicker import PulsePicker from slic.utils import devices, Marker, as_shortcut from slic.utils import Channels, Config, Elog, Screenshot, PV from slic.core.acquisition.fakeacquisition import FakeAcquisition from slic.devices.timing.events import CTASequencer -from bs_channels import detectors, bs_channels +from bs_channels import detectors, bs_channels, camera_channels from pv_channels import pvs from spreadsheet import overview from channels_minimal import detectors_min, channels_min, pvs_min @@ -42,17 +41,15 @@ from pp_shutter import PP_Shutter # DEVICES -## example devices and adjustables -from cool_motor import MyNewCoolThing - -cool_motor = MyNewCoolThing("cool_motor") - dummy = DummyAdjustable(units="au") -## Attenuators +# Attenuators from slic.devices.xoptics.aramis_attenuator import Attenuator from knife_edge import KnifeEdge +from standa import standa +standa = standa +Newport_large = Motor("SARES30-MOBI1:MOT_5") attenuator = Attenuator("SAROP31-OATA150", description="Cristallina attenuator OATA150") front_end_attenuator = Attenuator("SARFE10-OATT053", description="Front end attenuator OATT053") cta = CTASequencer("SAR-CCTA-ESC") @@ -85,27 +82,25 @@ import undulator undulators = undulator.Undulators() # Shutter -shutter = PP_Shutter("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP",name="Cristallina pulse picker shutter") # Shutter buttton when using the pulse picker +shutter = PP_Shutter("SARES30-LTIM01-EVR0:RearUniv0-Ena-SP", name="Cristallina pulse picker shutter") # Shutter buttton when using the pulse picker pulsepicker = PulsePicker("SAROP31-OPPI151","SARES30-LTIM01-EVR0:Pul3", name="Cristallina X-ray pulse picker OPPI151") # Alignmnet laser -alaser = AlignmentLaser("SAROP31-OLAS147:MOTOR_1",name="Cristallina alignment laser OLAS147") +alaser = AlignmentLaser("SAROP31-OLAS147:MOTOR_1", name="Cristallina alignment laser OLAS147") ## Slits from slic.devices.xoptics import slits ## Smaract & attocube stages -from smaract_device_def import smaract +from smaract_device_def import smaract_Juraj, smaract_mini_XYZ from attocube_device_def import attocube # KBs -from slic.devices.xoptics.kb import KBBase,KBHor,KBVer - +from slic.devices.xoptics.kb import KBHor,KBVer kbHor = KBHor( "SAROP31-OKBH154", description="Cristallina horizontal KB mirror" ) - kbVer = KBVer( "SAROP31-OKBV153", description="Cristallina vertical KB mirror" @@ -122,7 +117,10 @@ instrument = "cristallina" # pgroup = "p20557" # CrQ PMS commisioning 1 # pgroup = "p20509" # CrQ commissoing DilSc1 # pgroup = "p20519" # beamline commissioning 2 -pgroup = "p20841" # CrQ PMS commisioning 2 (Jan 2023) +# pgroup = "p20840" # Cr beamline commisioning (Jan-Feb 2023) +# pgroup = "p20841" # CrQ PMS commisioning 2 (Jan 2023) +pgroup = "p20993" # CrQ commissoing DilSc2 (March 2023) + # pgroup = "p19150" # Scratch # pgroup = "p19152" # Scratch @@ -141,7 +139,7 @@ daq = SFAcquisition( # scan = Scanner(scan_info_dir=f"/sf/{instrument}/data/{pgroup}/res/scan_info", default_acquisitions=[daq], condition=None) # Run the scan only when gas monitor value larger than 10uJ (and smaller than 2000uJ): -check_intensity_gas_monitor = PVCondition("SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US", vmin=10, vmax=2000, wait_time=0.5, required_fraction=0.8) # required fraction defines ammount of data recorded to save the step and move on to the next one +check_intensity_gas_monitor = PVCondition("SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-US", vmin=0.1, vmax=2000, wait_time=0.5, required_fraction=0.8) # required fraction defines ammount of data recorded to save the step and move on to the next one scan = Scanner(default_acquisitions=[daq],condition = check_intensity_gas_monitor) gui = GUI(scan, show_goto=True, show_spec=True) @@ -172,6 +170,7 @@ def pulse(run_comment=None): # Data retrieval does not allow empty list, so creating a new variable if detectors == [] or detectors == None: + used_detectors = {} else: used_detectors = detectors @@ -182,7 +181,7 @@ def pulse(run_comment=None): run_number = sf_daq_client.retrieve_data_from_buffer(pgroup=pgroup, user_tag=run_comment, camera_channels=[], bsread_channels=bs_channels, epics_channels=pvs, detectors=used_detectors, - start_pulseid=start_PID-90, stop_pulseid=start_PID+20, + start_pulseid=start_PID-10, stop_pulseid=start_PID+210, rate_multiplicator=1, ) print('\n') diff --git a/log/cristallina.log b/log/cristallina.log new file mode 100644 index 0000000..bf045d8 Binary files /dev/null and b/log/cristallina.log differ diff --git a/measurement_scripts/DilSc_meander_scripts.py b/measurement_scripts/DilSc_meander_scripts.py new file mode 100644 index 0000000..78d8481 --- /dev/null +++ b/measurement_scripts/DilSc_meander_scripts.py @@ -0,0 +1,65 @@ +from cristallina import pgroup,cta,detectors,camera_channels,bs_channels,pvs,logger +import subprocess +from time import sleep +from slic.utils import PV + +########################## Measurements scripts for the DilSc runs with meander devices + +CTA_sequence_start_PID = PV("SAR-CCTA-ESC:seq0Ctrl-StartedAt-O") + +def get_last_run_number(): + with open(f'/sf/cristallina/data/{pgroup}/raw/run_info/LAST_RUN') as f: + lines = f.readlines() + return int(lines[0]) + +def dil_run(run_comment=None, duration=70, seconds_before=5, seconds_after=0, Hz100=False,test=False): + last_rn = get_last_run_number() + + # Start ZH_DAQ + subprocess.Popen(['/sf/cristallina/applications/devices/zhinst/record.sh', f'{last_rn+1}', f'{duration + seconds_before + seconds_after}']) + sleep(6) # approximate startup time to start the ZHinstruments lockin acquisition + + sleep(seconds_before) + + # Start the CTA sequence + cta.cta_client.start() + + # Open shutter + if Hz100: + shutter.open() + + # Wait until done + sleep(duration) + + # Close shutter + if Hz100: + shutter.close() + + # Ask for the first pid in the sequence + CTA_start_PID = int(CTA_sequence_start_PID.get()) + + # Calculate PIDs that we want to download + start_PID = CTA_start_PID - seconds_before*100 + end_PID = CTA_start_PID + duration*100 + + # Data retrieval does not allow empty list, so creating a new variable + if detectors == [] or detectors == None: + used_detectors = {} + else: + used_detectors = {"JF16T03V01":{}} + + # Wait time added so that the data arrives in the databuffer. If sf_daq_client asks too soon, usually PV data does not get saved. + sleep(15) + + if test is not True: + # TODO: change to SFAcquisition.retrieve(...) from slic + # Ask the DAQ client to download the data + run_number = sf_daq_client.retrieve_data_from_buffer(pgroup=pgroup, user_tag=run_comment, + camera_channels=camera_channels, bsread_channels=bs_channels, epics_channels=pvs, + detectors=used_detectors, + start_pulseid=start_PID, stop_pulseid=end_PID, + rate_multiplicator=1, + ) + print('\n') + # print(f' Sequence done.\n Run {run_number} created. \n First PID in the CTA sequence: {start_PID}\n') + logger.info(f' Sequence done.\n Run {run_number} created. \n First PID in the CTA sequence: {start_PID}\n') \ No newline at end of file diff --git a/measurement_scripts/__pycache__/DilSc_meander_scripts.cpython-39.pyc b/measurement_scripts/__pycache__/DilSc_meander_scripts.cpython-39.pyc new file mode 100644 index 0000000..182ece3 Binary files /dev/null and b/measurement_scripts/__pycache__/DilSc_meander_scripts.cpython-39.pyc differ diff --git a/measurement_scripts/__pycache__/inprints.cpython-39.pyc b/measurement_scripts/__pycache__/inprints.cpython-39.pyc index 2900c23..efedc32 100644 Binary files a/measurement_scripts/__pycache__/inprints.cpython-39.pyc and b/measurement_scripts/__pycache__/inprints.cpython-39.pyc differ diff --git a/measurement_scripts/inprints.py b/measurement_scripts/inprints.py index cc1aebf..de1a959 100644 --- a/measurement_scripts/inprints.py +++ b/measurement_scripts/inprints.py @@ -1,17 +1,20 @@ from datetime import datetime from time import sleep, time +from tracemalloc import start import numpy as np #from epics import PV #from slic.utils import nice_arange #from slic.devices.general.motor import Motor import matplotlib.pyplot as plt import epics -from cristallina import attocube, attenuator - +from cristallina import Newport_large, attocube, attenuator +from smaract_device_def import smaract_mini_XYZ from slic.devices.xoptics.aramis_attenuator import Attenuator +from tqdm import tqdm + attenuator = Attenuator("SAROP31-OATA150", description="Cristallina attenuator OATA150") -from slic.devices.xoptics.kb import KBBase,KBHor,KBVer +from slic.devices.xoptics.kb import KBHor,KBVer kbHor = KBHor( "SAROP31-OKBH154", description="Cristallina horizontal KB mirror" @@ -23,26 +26,58 @@ kbVer = KBVer( ) do_not_move_benders = True -testing_flag = True +testing_flag = False pos = np.array([0,0]) # parameters -n_same_holes = 7 -attenuations = np.logspace(0,-6,num=7) -KBv_home = [1.5,1.7] -KBh_home = [1.6,1.8] +n_same_holes = 3 +attenuations = np.linspace(0.15,0.35,9)#np.linspace(0.1,0.35,11)#np.linspace(0.1,0.35,6)#np.logspace(-3,0,num=7) +KBv_home = [1.3 , 1.6] +KBh_home = [1.4 , 1.7] # Spacings -between_same_shots = 100 +between_same_shots = 150 between_attenuations = 150 -between_KB_settings = 500 -KBvs = [[1,2],[1,3],[1,2],[1,3],[1,2]] -KBhs = [[1,2],[1,2],[1,2],[1,3],[1,2]] +between_KB_settings = 500#500 + +### 23.02 +def kb_settings_list(best,step,no_steps): + for i in range(no_steps): + if i == 0: + l=[] + l.append([best[0]+i*step,best[1]]) + for i in range(no_steps): + if i == 0: + pass + l.append([best[0],best[1]+i*step]) + return l + +KBvs = kb_settings_list([1.595,1.874],0.05,3) +KBhs = kb_settings_list([1.799000,2.100000],0.05,3) + +### 24.02 +def kb_settings_list_new(best,step,no_steps_one_way): + l=[] + first = np.array(best) - np.array([step*no_steps_one_way,step*no_steps_one_way]) + for i in range(no_steps_one_way*2+1): + l.append([first[0]+i*step,first[1]+i*step]) + return l +KBvs = kb_settings_list_new([1.595,1.874],0.0075,3) +KBhs = kb_settings_list_new([1.799000,2.100000],0.0075,3) + # Time estimates for total time calculation (time in seconds) t_kb_change = 30 -t_shot = 5 -t_atten_change = 20 +t_shot = 4 +t_atten_change = 10 + +# Choose motor stage (set true for smaract_stage_xyz, false if attocubes) +smaract_stage = True +# Change to mm from um if smaract stage selected +if smaract_stage: + between_same_shots = between_same_shots/1000 + between_attenuations = between_attenuations/1000 + between_KB_settings = between_KB_settings/1000 def shoot(pos=pos,testing=testing_flag): if testing: @@ -50,7 +85,8 @@ def shoot(pos=pos,testing=testing_flag): return pos else: print(f'Shot at: {pos}') - #epics.caput("SAR-CCTA-ESC:seq0Ctrl-Start-I",1) + sleep(2) + epics.caput("SAR-CCTA-ESC:seq0Ctrl-Start-I",1) pass def change_benders(bender_1,bender_2,KB = None,do_not_move_benders = do_not_move_benders): @@ -65,11 +101,12 @@ def change_benders(bender_1,bender_2,KB = None,do_not_move_benders = do_not_move kbHor.bend1.set_target_value(KBh_home[0]).wait() sleep(1) kbHor.bend2.set_target_value(KBh_home[1]).wait() + sleep(1) else: kbVer.bend1.set_target_value(KBv_home[0]).wait() sleep(1) kbVer.bend2.set_target_value(KBv_home[1]).wait() - + sleep(1) if do_not_move_benders: print(f'Bender 1 to: {bender_1}') @@ -82,10 +119,12 @@ def change_benders(bender_1,bender_2,KB = None,do_not_move_benders = do_not_move kbHor.bend1.set_target_value(bender_1).wait() sleep(1) kbHor.bend2.set_target_value(bender_2).wait() + sleep(1) else: kbVer.bend1.set_target_value(bender_1).wait() sleep(1) kbVer.bend2.set_target_value(bender_2).wait() + sleep(1) def check_KB_value(KB): @@ -105,7 +144,10 @@ def move_x_rel(distance,testing=testing_flag,pos=pos): pos = pos + np.array([distance,0]) return pos else: - attocube.X.set_target_value(distance, relative=True).wait() + if smaract_stage: + smaract_mini_XYZ.x.mvr(distance).wait() + else: + attocube.X.set_target_value(distance, relative=True).wait() pos = pos + np.array([distance,0]) return pos @@ -114,7 +156,10 @@ def move_y_rel(distance,testing=testing_flag,pos=pos): pos = pos + np.array([0,distance]) return pos else: - attocube.Y.set_target_value(distance, relative=True).wait() + if smaract_stage: + smaract_mini_XYZ.y.mvr(distance).wait() + else: + attocube.Y.set_target_value(distance, relative=True).wait() pos = pos + np.array([0,distance]) return pos @@ -123,65 +168,89 @@ def move_x(value,testing=testing_flag,pos=pos): pos[0]=value return pos else: - attocube.X.set_target_value(value, relative=False).wait() + if smaract_stage: + smaract_mini_XYZ.x.mv(value).wait() + else: + attocube.X.set_target_value(value, relative=False).wait() + return [value,pos[1]] def move_y(value,testing=testing_flag,pos=pos): if testing == True: pos[1]=value return pos else: - attocube.Y.set_target_value(value, relative=False).wait() - + if smaract_stage: + smaract_mini_XYZ.y.mv(value).wait() + else: + attocube.Y.set_target_value(value, relative=False).wait() + return [pos[0],value] def move(target_pos,testing=True,pos=pos): if testing == True: - pos = target_pos - return pos + pass else: - attocube.X.set_target_value(target_pos[0]).wait() - attocube.Y.set_target_value(target_pos[1]).wait() + if smaract_stage: + smaract_mini_XYZ.x.mv(target_pos[0]).wait() + smaract_mini_XYZ.y.mv(target_pos[1]).wait() + else: + attocube.X.set_target_value(target_pos[0]).wait() + attocube.Y.set_target_value(target_pos[1]).wait() + pos = target_pos + return pos - -def make_attenuations(attenuations,testing=testing_flag,pos=pos): +def get_original_position(testing=testing_flag): if testing == True: original_position = pos else: - original_position = [attocube.X.get_current_value(),attocube.Y.get_current_value()] + if smaract_stage: + original_position = [smaract_mini_XYZ.x.get_current_value(),smaract_mini_XYZ.y.get_current_value()] + else: + original_position = [attocube.X.get_current_value(),attocube.Y.get_current_value()] + return original_position + +def set_attenuation(value): + attenuator.set_transmission(value) + sleep(1) + while attenuator.motors.any_is_moving(): + sleep(1) + return value + +def make_attenuations(attenuations,testing=testing_flag,pos=pos): + original_position = get_original_position(testing=testing) # Make all attenuations for attenuation in attenuations: print(f'Setting attenuation to: {attenuation}') - if testing_flag != True: - attenuator.trans1st(attenuation).wait() + if testing: + print('Testing: no attenuator change') + else: + set_attenuation(attenuation) print('Making same shots') - make_same_shots(n_same_holes,pos=pos) + make_same_shots(n_same_holes,pos=pos,testing=testing) pos = move_y_rel(between_attenuations,pos=pos,testing=testing) # Return back to where you started if testing == True: pos = original_position else: - attocube.X.set_target_value(original_position, relative=False) + pos = move(original_position, testing=testing) return pos def make_same_shots(n_same_holes,testing=testing_flag,pos=pos): - if testing == True: - original_position = pos - else: - original_position = [attocube.X.get_current_value(),attocube.Y.get_current_value()] + original_position = get_original_position(testing=testing) # Make holes for shot in range(n_same_holes): sleep(1) - shoot(pos=pos) + shoot(pos=pos,testing=testing) pos = move_x_rel(between_same_shots,pos=pos,testing=testing) # Return back to where you started - move(original_position) + move(original_position,testing=testing) def estimate_total_time(KBhs=KBhs,KBvs=KBvs,attenuations=attenuations,n_same_holes=n_same_holes,t_kb_change=t_kb_change,t_atten_change=t_atten_change,t_shot=t_shot): - total_time = len(KBhs)*len(KBvs)*(t_kb_change+len(attenuations)*(t_atten_change+n_same_holes*t_shot) ) + total_time = len(KBhs)*len(KBvs)*( t_kb_change+len(attenuations)*(t_atten_change+n_same_holes*t_shot) ) print(f'Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours') return total_time @@ -189,41 +258,59 @@ def estimate_total_time(KBhs=KBhs,KBvs=KBvs,attenuations=attenuations,n_same_hol if testing_flag == True: starting_x_pos = pos[0] else: - starting_x_pos = attocube.X.get_current_value() + if smaract_stage: + starting_x_pos = smaract_mini_XYZ.x.get_current_value() + else: + starting_x_pos = attocube.X.get_current_value() - -def make_everything(KBvs,KBhs,attenuations,n_same_holes,testing=testing_flag,pos=pos): - # The actual loop to make inprints - for i,KBv in enumerate(KBvs): - change_benders(KBv[0],KBv[1],KB = 'v') +def make_everything(KBvs,KBhs,attenuations,n_same_holes,testing=testing_flag,pos=pos,do_not_move_benders=True): + # The loop to make inprints + for i,KBv in enumerate(tqdm(KBvs)): + change_benders(KBv[0],KBv[1],KB = 'v',do_not_move_benders=do_not_move_benders) for ind,KBh in enumerate(KBhs): change_benders(KBh[0],KBh[1],KB = 'h') print(f'Progress so far: KBv loop: {i+1}/{len(KBvs)}. KBh loop:{ind+1}/{len(KBhs)}') - make_attenuations(attenuations,pos=pos) + make_attenuations(attenuations,pos=pos,testing=testing) print(f'Moving to a new KBh setting') # Move to the last shot of the same shot + the spacing between KB settings - pos = move_x_rel(between_KB_settings+between_same_shots*(n_same_holes-1),pos=pos) + pos = move_x_rel(between_KB_settings+between_same_shots*(n_same_holes-1),pos=pos,testing=testing) print('KBh set done, returning to starting_x_pos') # Move to the last shot of the same shot + the spacing between KB settings - pos = move_x(starting_x_pos,pos=pos) + pos = move_x(starting_x_pos,pos=pos,testing=testing) print('#################################################################################') print('Moving to a new KBv setting') # Move to the last shot of the same shot + the spacing between KB settings - pos = move_y_rel(between_KB_settings+between_attenuations*(len(attenuations)-1),pos=pos) + pos = move_y_rel(between_KB_settings+between_attenuations*(len(attenuations)-1),pos=pos,testing=testing) print('Inprints are done') - print(f'Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours') + set_attenuation(1e-6) + status_pv = PV('SF-OP:ESC-MSG:STATUS') + status_pv.put(0) + + # print(f'Total time estimate: {(total_time/60):.1f} minutes or {(total_time/60/60):.1f} hours') # To do: # Fix movement of the attocubes in real time # Load lut files into the controller and check that x is x and y is y +def make_z_scan(z_list,n_same_holes,attenuations,vertical_spacing=0.150): + original_position = get_original_position(testing=False) + for attenuation in attenuations: + set_attenuation(attenuation) + for z in z_list: + Newport_large.mv(z).wait() + sleep(1) + make_same_shots(n_same_holes,testing=False) + move_y_rel(vertical_spacing,testing=False) + move(original_position,testing=False) + sleep(1) + move_x_rel(1,testing=False) diff --git a/pv_channels.py b/pv_channels.py index 1ec1e9b..37ead36 100644 --- a/pv_channels.py +++ b/pv_channels.py @@ -11,6 +11,75 @@ pvs_machine = [ "SARUN:FELPHOTENE.VAL", # Predicted photon energy from machine settings "SARFE10-PBPG050:PHOTON-ENERGY-PER-PULSE-AVG.VAL" # Average pulse energy from the gas detector ] +pvs_RF = [ + "SINSB01-RSYS:GET-VSUM-PHASE-OFFSET", + "SINSB02-RSYS:GET-VSUM-PHASE-OFFSET", + "SINSB03-RSYS:GET-VSUM-PHASE-OFFSET", + "SINSB04-RSYS:GET-VSUM-PHASE-OFFSET", + "SINXB01-RSYS:GET-VSUM-PHASE-OFFSET", + "SINDI01-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB01-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB02-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB03-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB04-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB06-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB05-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB07-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB08-RSYS:GET-VSUM-PHASE-OFFSET", + "S10CB09-RSYS:GET-VSUM-PHASE-OFFSET", + "S20CB01-RSYS:GET-VSUM-PHASE-OFFSET", + "S20CB02-RSYS:GET-VSUM-PHASE-OFFSET", + "S20CB03-RSYS:GET-VSUM-PHASE-OFFSET", + "S20CB04-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB01-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB02-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB03-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB04-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB05-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB06-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB07-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB08-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB09-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB10-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB11-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB12-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB13-RSYS:GET-VSUM-PHASE-OFFSET", + "S30CB14-RSYS:GET-VSUM-PHASE-OFFSET", + "SINEG01-RSYS:GET-VSUM-AMPLT-SCALE", + "SINSB01-RSYS:GET-VSUM-AMPLT-SCALE", + "SINSB02-RSYS:GET-VSUM-AMPLT-SCALE", + "SINSB03-RSYS:GET-VSUM-AMPLT-SCALE", + "SINSB04-RSYS:GET-VSUM-AMPLT-SCALE", + "SINXB01-RSYS:GET-VSUM-AMPLT-SCALE", + "SINDI01-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB01-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB02-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB03-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB04-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB05-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB06-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB07-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB08-RSYS:GET-VSUM-AMPLT-SCALE", + "S10CB09-RSYS:GET-VSUM-AMPLT-SCALE", + "S20CB01-RSYS:GET-VSUM-AMPLT-SCALE", + "S20CB02-RSYS:GET-VSUM-AMPLT-SCALE", + "S20CB03-RSYS:GET-VSUM-AMPLT-SCALE", + "S20CB04-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB01-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB02-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB03-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB04-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB05-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB06-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB07-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB08-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB09-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB10-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB11-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB12-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB13-RSYS:GET-VSUM-AMPLT-SCALE", + "S30CB14-RSYS:GET-VSUM-AMPLT-SCALE", +] ####################### # Undulator gap @@ -158,7 +227,6 @@ pvs_PBPS113 = [ "SAROP31-PBPS113:MOTOR_X1.RBV", "SAROP31-PBPS113:MOTOR_Y1.RBV", "SAROP31-PBPS113:MOTOR_PROBE.RBV", - "" ] ################### @@ -334,6 +402,7 @@ pvs_smaract_juraj = [ pvs = ( pvs_machine + + pvs_RF + pvs_undulator + pvs_gas_monitor + pvs_OAPU044 @@ -361,6 +430,8 @@ pvs = ( + pvs_OKBH154 + pvs_standa + pvs_smaract_xyz +) + + # + pvs_attocube # + pvs_smaract_juraj -) \ No newline at end of file diff --git a/smaract.py b/smaract.py index fb14c21..94f2464 100644 --- a/smaract.py +++ b/smaract.py @@ -62,7 +62,7 @@ class SmarActAxis(Adjustable): self.config = SimpleNamespace( tolerance = tolerance, ) - + self.pvs = SimpleNamespace( drive = PV(ID + ":DRIVE"), readback = PV(ID + ":MOTRBV"), @@ -76,7 +76,6 @@ class SmarActAxis(Adjustable): units = PV(ID + ":DRIVE.EGU") ) - @property def units(self): units = self._units diff --git a/smaract_device_def.py b/smaract_device_def.py index 6572002..1cc7455 100644 --- a/smaract_device_def.py +++ b/smaract_device_def.py @@ -1,10 +1,22 @@ # from slic.devices.general.smaract import SmarActStage from smaract import SmarActStage +from slic.core.device.simpledevice import SimpleDevice +from slic.devices.general.motor import Motor + # this currently uses a modified SmarActStage module # otherwise the wait times are not working correctly. -smaract = SmarActStage("SARES30-XSMA156", +smaract_z = Motor("SARES30-MCS2750:MOT_1") +smaract_x = Motor("SARES30-MCS2750:MOT_2") +smaract_y = Motor("SARES30-MCS2750:MOT_3") + + +smaract_mini_XYZ = SimpleDevice("XYZ smaract stage (mini)", x=smaract_x, y=smaract_y, z=smaract_z) + + + +smaract_Juraj = SmarActStage("SARES30-XSMA156", X='SARES30-XSMA156:X', Y='SARES30-XSMA156:Y', Z='SARES30-XSMA156:Z', @@ -12,3 +24,9 @@ smaract = SmarActStage("SARES30-XSMA156", Rx='SARES30-XSMA156:Rx', Rz='SARES30-XSMA156:Rz', ) + +# smaract_mini_XYZ = SmarActStage("SARES30-MCS2750", +# X='SARES30-MCS2750:MOT_1', +# Y='SARES30-MCS2750:MOT_2', +# Z='SARES30-MCS2750:MOT_3', +# ) \ No newline at end of file diff --git a/standa.py b/standa.py new file mode 100644 index 0000000..59189a1 --- /dev/null +++ b/standa.py @@ -0,0 +1,7 @@ +from slic.core.device.simpledevice import SimpleDevice +from slic.devices.general.motor import Motor + +standa_z = Motor("SARES30-MOBI1:MOT_1") +standa_x = Motor("SARES30-MOBI1:MOT_2") + +standa = SimpleDevice("Standa X-ray eye base motors", x=standa_x, z=standa_z) diff --git a/undulator.py b/undulator.py index 340413e..01795f8 100644 --- a/undulator.py +++ b/undulator.py @@ -19,17 +19,19 @@ N_UNDS = list(range(3, 15+1)) # energy_offset = 20.37839 # Cristallina without calibration -energy_offset = 0.0 +energy_offset = 26 + # move the PSSS motor according to the energy # TODO: improve this hack PSSS_MOVE = False -def set_PSSS_energy(energy:float): +def set_PSSS_energy(energy : float): """ When scanning the energy with the undulator we adjust the spectrometer to follow. """ - print("Adjusting PSSS") + energy = energy - energy_offset + print(f"Adjusting PSSS to {energy}") PSSS_energy_PV_name = 'SARFE10-PSSS059:ENERGY' PSSS_energy_PV = PV(PSSS_energy_PV_name) PSSS_energy_PV.put(energy, wait=True)