Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7d9286aa0d | |||
| 30cf15829a | |||
| 89b6e37a27 | |||
| 73689aadea | |||
| 7e6c72869b | |||
| c54d5baf87 | |||
| a465b9600d | |||
| c929ab5164 | |||
| f27f2fd3cf | |||
| 266235ae9d | |||
| 696e7eda26 | |||
| cd9750c406 | |||
| 0016428b6a | |||
| 529685b1e6 | |||
| 2a7379059d | |||
| 2f0327796e | |||
| f0251941ef | |||
| 7095bf44d5 | |||
| ae738a25e7 | |||
| 8e5d823804 | |||
| 99faa31190 | |||
| f4ccc0c903 | |||
| 093d4c7571 | |||
| b87f07f3b4 | |||
| 0691e4968f | |||
| 1a26e0e5f9 | |||
| 5b811c8d12 | |||
| f36274823d | |||
| 06aaa7d720 |
@@ -32,6 +32,8 @@ install:
|
||||
- export PATH="$HOME/miniconda/bin:$PATH"
|
||||
- hash -r
|
||||
- conda config --set always_yes yes --set changeps1 no
|
||||
- conda config --add channels paulscherrerinstitute
|
||||
- conda config --add channels conda-forge
|
||||
- conda config --add channels defaults
|
||||
- conda update -q --all
|
||||
- conda install conda-build anaconda-client
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
[](https://travis-ci.org/paulscherrerinstitute/eco)
|
||||
|
||||
___ _______
|
||||
/ -_) __/ _ \
|
||||
Experiment Control \__/\__/\___/
|
||||
|
||||
# Experiment Control
|
||||
Python based control environment for experiments at SwissFEL
|
||||
Python based control environment for experiments, developed at SwissFEL.
|
||||
|
||||
## Structure
|
||||
eco consists of mutiple python modules strucrured in main classes
|
||||
@@ -9,3 +15,7 @@ eco consists of mutiple python modules strucrured in main classes
|
||||
-- general definition of potentially recurring devices
|
||||
-- separated into different groups
|
||||
- configurations of multiple devices into instruments
|
||||
|
||||
|
||||
[Device representation.pdf](https://github.com/paulscherrerinstitute/eco/files/2453401/Device.representation.pdf)
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
package:
|
||||
name: eco
|
||||
version: 0.0.1
|
||||
version: 0.0.2
|
||||
#source:
|
||||
# git_tag: 0.0.14
|
||||
# git_url: git@git.psi.ch:sf_daq/bsread_python.git
|
||||
@@ -10,10 +10,6 @@ source:
|
||||
build:
|
||||
number: 1
|
||||
|
||||
channel:
|
||||
- paulscherrerinstitute
|
||||
- conda-forge
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python
|
||||
@@ -22,14 +18,14 @@ requirements:
|
||||
- python
|
||||
- elog
|
||||
- pyepics
|
||||
- bread
|
||||
- bsread
|
||||
- jungfrau_utils
|
||||
- xrayutilities
|
||||
- xraylib
|
||||
|
||||
#build:
|
||||
# entry_points:
|
||||
# - bs = bsread.bs:main
|
||||
build:
|
||||
entry_points:
|
||||
- eco = startup:main
|
||||
|
||||
about:
|
||||
# home: git@git.psi.ch:sf_daq/bsread_python.git
|
||||
|
||||
+94
-53
@@ -9,99 +9,140 @@ from threading import Thread
|
||||
|
||||
from .utilities import Acquisition
|
||||
|
||||
|
||||
class BStools:
|
||||
def __init__(self,
|
||||
default_channel_list={'listname':[]},
|
||||
default_file_path='%s',
|
||||
elog=None):
|
||||
def __init__(
|
||||
self, default_channel_list={"listname": []}, default_file_path="%s", elog=None
|
||||
):
|
||||
self._default_file_path = default_file_path
|
||||
self._default_channel_list = default_channel_list
|
||||
self._elog = elog
|
||||
|
||||
def avail(self,*args,**kwargs):
|
||||
return dispatcher.get_current_channels(*args,**kwargs)
|
||||
def avail(self, *args, **kwargs):
|
||||
return dispatcher.get_current_channels(*args, **kwargs)
|
||||
|
||||
def check_channel_list(self, printResult=True, printOnlineChannels=False):
|
||||
all_available = set([i['name'] for i in self.avail()])
|
||||
all_available = set([i["name"] for i in self.avail()])
|
||||
status = {}
|
||||
for listname in self._default_channel_list.keys():
|
||||
tch = set(self._default_channel_list[listname])
|
||||
status[listname] = {}
|
||||
status[listname]['online'] = tch.intersection(all_available)
|
||||
status[listname]['offline'] = tch.difference(all_available)
|
||||
status[listname]["online"] = tch.intersection(all_available)
|
||||
status[listname]["offline"] = tch.difference(all_available)
|
||||
if printResult:
|
||||
for listname in status.keys():
|
||||
if printOnlineChannels:
|
||||
print('#### Online Channels in {} ####'.format(listname))
|
||||
print('\n'.join(status[listname]['online']))
|
||||
print('\n')
|
||||
print('#### Offline Channels in {} ####'.format(listname))
|
||||
print('\n'.join(status[listname]['offline']))
|
||||
print("#### Online Channels in {} ####".format(listname))
|
||||
print("\n".join(status[listname]["online"]))
|
||||
print("\n")
|
||||
print("#### Offline Channels in {} ####".format(listname))
|
||||
print("\n".join(status[listname]["offline"]))
|
||||
else:
|
||||
return status
|
||||
|
||||
def cleanup_channel_list(self,listname):
|
||||
|
||||
def cleanup_channel_list(self, listname):
|
||||
status = self.check_channel_list(printResult=False)
|
||||
self._default_channel_list[listname] = \
|
||||
list(set(self._default_channel_list[listname]).difference(set(status[listname]['offline'])))
|
||||
print('#### Temporarily removed Offline Channels in {} ####'.format(listname))
|
||||
print('\n'.join(status[listname]['offline']))
|
||||
print('NB: The channels will be back after restart if they originate from a config file.')
|
||||
self._default_channel_list[listname] = list(
|
||||
set(self._default_channel_list[listname]).difference(
|
||||
set(status[listname]["offline"])
|
||||
)
|
||||
)
|
||||
print("#### Temporarily removed Offline Channels in {} ####".format(listname))
|
||||
print("\n".join(status[listname]["offline"]))
|
||||
print(
|
||||
"NB: The channels will be back after restart if they originate from a config file."
|
||||
)
|
||||
|
||||
|
||||
|
||||
def h5(self,fina=None,channel_list=None,N_pulses=None,default_path=True,queue_size=100):
|
||||
def h5(
|
||||
self,
|
||||
fina=None,
|
||||
channel_list=None,
|
||||
N_pulses=None,
|
||||
default_path=True,
|
||||
queue_size=100,
|
||||
):
|
||||
if default_path:
|
||||
fina = self._default_file_path%fina
|
||||
|
||||
fina = self._default_file_path % fina
|
||||
|
||||
if os.path.isfile(fina):
|
||||
print('!!! File %s already exists, would you like to delete it?'%fina)
|
||||
if input('(y/n)')=='y':
|
||||
print('Deleting %s .'%fina)
|
||||
print("!!! File %s already exists, would you like to delete it?" % fina)
|
||||
if input("(y/n)") == "y":
|
||||
print("Deleting %s ." % fina)
|
||||
os.remove(fina)
|
||||
else:
|
||||
return
|
||||
if not channel_list:
|
||||
print('No channels specified, using default list \'%s\' instead.'%list(self._default_channel_list.keys())[0])
|
||||
channel_list = self._default_channel_list[list(self._default_channel_list.keys())[0]]
|
||||
|
||||
print(
|
||||
"No channels specified, using default list '%s' instead."
|
||||
% list(self._default_channel_list.keys())[0]
|
||||
)
|
||||
channel_list = self._default_channel_list[
|
||||
list(self._default_channel_list.keys())[0]
|
||||
]
|
||||
|
||||
source = dispatcher.request_stream(channel_list)
|
||||
mode = zmq.SUB
|
||||
receive(source, fina, queue_size=queue_size, mode=mode, n_messages=N_pulses)
|
||||
|
||||
def db(self,channel_list=None,start_time_delta=dict(),end_time_delta=dict(),default_path=True):
|
||||
def db(
|
||||
self,
|
||||
channel_list=None,
|
||||
start_time_delta=dict(),
|
||||
end_time_delta=dict(),
|
||||
default_path=True,
|
||||
):
|
||||
if not channel_list:
|
||||
print('No channels specified, using default list \'%s\' instead.'%list(self._default_channel_list.keys())[0])
|
||||
channel_list = self._default_channel_list[list(self._default_channel_list.keys())[0]]
|
||||
print(
|
||||
"No channels specified, using default list '%s' instead."
|
||||
% list(self._default_channel_list.keys())[0]
|
||||
)
|
||||
channel_list = self._default_channel_list[
|
||||
list(self._default_channel_list.keys())[0]
|
||||
]
|
||||
now = datetime.datetime.now()
|
||||
end = now-datetime.timedelta(**end_time_delta)
|
||||
start = end-datetime.timedelta(**start_time_delta)
|
||||
return api.get_data(channels=channel_list, start=start, end=end)
|
||||
end = now - datetime.timedelta(**end_time_delta)
|
||||
start = end - datetime.timedelta(**start_time_delta)
|
||||
return api.get_data(channels=channel_list, start=start, end=end)
|
||||
|
||||
def h5_db(self,fina,channel_list=None,start_time_delta=dict(),end_time_delta=dict(),default_path=True):
|
||||
data = self.db(channel_list=None,start_time_delta=start_time_delta,end_time_delta=end_time_delta,default_path=True)
|
||||
def h5_db(
|
||||
self,
|
||||
fina,
|
||||
channel_list=None,
|
||||
start_time_delta=dict(),
|
||||
end_time_delta=dict(),
|
||||
default_path=True,
|
||||
):
|
||||
data = self.db(
|
||||
channel_list=None,
|
||||
start_time_delta=start_time_delta,
|
||||
end_time_delta=end_time_delta,
|
||||
default_path=True,
|
||||
)
|
||||
if default_path:
|
||||
fina = self._default_file_path%fina
|
||||
|
||||
fina = self._default_file_path % fina
|
||||
|
||||
if os.path.isfile(fina):
|
||||
print('!!! File %s already exists, would you like to delete it?'%fina)
|
||||
if input('(y/n)')=='y':
|
||||
print('Deleting %s .'%fina)
|
||||
print("!!! File %s already exists, would you like to delete it?" % fina)
|
||||
if input("(y/n)") == "y":
|
||||
print("Deleting %s ." % fina)
|
||||
os.remove(fina)
|
||||
else:
|
||||
return
|
||||
|
||||
data.to_hdf(fina,"/data")
|
||||
|
||||
data.to_hdf(fina, "/data")
|
||||
|
||||
def acquire(self, file_name=None, Npulses=100):
|
||||
file_name += ".h5"
|
||||
|
||||
def acquire(self,file_name=None,Npulses=100):
|
||||
file_name += '.h5'
|
||||
def acquire():
|
||||
self.h5(fina=file_name,N_pulses=Npulses)
|
||||
return Acquisition(acquire=acquire,acquisition_kwargs={'file_names':[file_name], 'Npulses':Npulses},hold=False)
|
||||
self.h5(fina=file_name, N_pulses=Npulses)
|
||||
|
||||
return Acquisition(
|
||||
acquire=acquire,
|
||||
acquisition_kwargs={"file_names": [file_name], "Npulses": Npulses},
|
||||
hold=False,
|
||||
)
|
||||
|
||||
def wait_done(self):
|
||||
self.check_running()
|
||||
self.check_still_running()
|
||||
|
||||
|
||||
|
||||
@@ -9,33 +9,50 @@ from time import sleep
|
||||
|
||||
from .utilities import Acquisition
|
||||
|
||||
|
||||
class Ioxostools:
|
||||
def __init__(self,
|
||||
default_channel_list={'listname':[]},
|
||||
default_file_path='%s',
|
||||
elog=None,
|
||||
sleeptime=0.0305,
|
||||
channel_list = None):
|
||||
def __init__(
|
||||
self,
|
||||
default_channel_list={"listname": []},
|
||||
default_file_path="%s",
|
||||
elog=None,
|
||||
sleeptime=0.0305,
|
||||
channel_list=None,
|
||||
):
|
||||
self.sleeptime = sleeptime
|
||||
self._default_file_path = default_file_path
|
||||
self._default_channel_list = default_channel_list
|
||||
self._elog = elog
|
||||
self.channels = []
|
||||
if not channel_list:
|
||||
print('No channels specified, using default list \'%s\' instead.'%list(self._default_channel_list.keys())[0])
|
||||
self.channel_list = self._default_channel_list[list(self._default_channel_list.keys())[0]]
|
||||
print(
|
||||
"No channels specified, using default list '%s' instead."
|
||||
% list(self._default_channel_list.keys())[0]
|
||||
)
|
||||
self.channel_list = self._default_channel_list[
|
||||
list(self._default_channel_list.keys())[0]
|
||||
]
|
||||
else:
|
||||
self.channel_list = channel_list
|
||||
for channel in self.channel_list:
|
||||
self.channels.append(PV(channel))
|
||||
|
||||
def h5(self,fina=None,channel_list = None, N_pulses=None,default_path=True,queue_size=100):
|
||||
def h5(
|
||||
self,
|
||||
fina=None,
|
||||
channel_list=None,
|
||||
N_pulses=None,
|
||||
default_path=True,
|
||||
queue_size=100,
|
||||
):
|
||||
channel_list = self.channel_list
|
||||
if default_path:
|
||||
fina = self._default_file_path%fina
|
||||
|
||||
fina = self._default_file_path % fina
|
||||
|
||||
if os.path.isfile(fina):
|
||||
print('!!! File %s already exists, would you like to delete it?'%fina)
|
||||
if input('(y/n)')=='y':
|
||||
print('Deleting %s .'%fina)
|
||||
print("!!! File %s already exists, would you like to delete it?" % fina)
|
||||
if input("(y/n)") == "y":
|
||||
print("Deleting %s ." % fina)
|
||||
os.remove(fina)
|
||||
else:
|
||||
return
|
||||
@@ -47,49 +64,49 @@ class Ioxostools:
|
||||
for channel in channels:
|
||||
channelval = channel.value
|
||||
if type(channelval) == np.ndarray:
|
||||
shape = (N_pulses,)+channelval.shape
|
||||
shape = (N_pulses,) + channelval.shape
|
||||
dtype = channelval.dtype
|
||||
else:
|
||||
shape = (N_pulses,)
|
||||
dtype = type(channelval)
|
||||
data.append(np.ndarray(shape, dtype = dtype))
|
||||
data.append(np.ndarray(shape, dtype=dtype))
|
||||
counters.append(0)
|
||||
|
||||
def cb_getdata(ch=None, m=0,*args, **kwargs):
|
||||
data[m][counters[m]] = kwargs['value']
|
||||
counters[m] =counters[m] + 1
|
||||
if counters[m] == N_pulses-1:
|
||||
def cb_getdata(ch=None, m=0, *args, **kwargs):
|
||||
data[m][counters[m]] = kwargs["value"]
|
||||
counters[m] = counters[m] + 1
|
||||
if counters[m] == N_pulses - 1:
|
||||
ch.clear_callbacks()
|
||||
|
||||
for (m, channel) in enumerate(channels):
|
||||
channel.add_callback(callback = cb_getdata, ch = channel, m=m)
|
||||
channel.add_callback(callback=cb_getdata, ch=channel, m=m)
|
||||
while True:
|
||||
sleep(0.01)
|
||||
if np.mean(counters) == N_pulses-1:
|
||||
if np.mean(counters) == N_pulses - 1:
|
||||
break
|
||||
|
||||
# for n in range(N_pulses):
|
||||
# channelvals = []
|
||||
|
||||
|
||||
#for n in range(N_pulses):
|
||||
# channelvals = []
|
||||
|
||||
|
||||
# sleep(self.sleeptime)
|
||||
|
||||
f = h5py.File(name = fina, mode = 'w')
|
||||
f = h5py.File(name=fina, mode="w")
|
||||
for (n, channel) in enumerate(channel_list):
|
||||
f.create_dataset(name = channel, data = data[n])
|
||||
f.create_dataset(name=channel, data=data[n])
|
||||
return data
|
||||
|
||||
def acquire(self, file_name=None, Npulses=100):
|
||||
file_name += ".h5"
|
||||
|
||||
def acquire(self,file_name=None,Npulses=100):
|
||||
file_name += '.h5'
|
||||
def acquire():
|
||||
self.h5(fina=file_name,N_pulses=Npulses)
|
||||
return Acquisition(acquire=acquire,acquisition_kwargs={'file_names':[file_name], 'Npulses':Npulses},hold=False)
|
||||
self.h5(fina=file_name, N_pulses=Npulses)
|
||||
|
||||
return Acquisition(
|
||||
acquire=acquire,
|
||||
acquisition_kwargs={"file_names": [file_name], "Npulses": Npulses},
|
||||
hold=False,
|
||||
)
|
||||
|
||||
def wait_done(self):
|
||||
self.check_running()
|
||||
self.check_still_running()
|
||||
|
||||
|
||||
|
||||
+143
-54
@@ -5,8 +5,21 @@ import numpy as np
|
||||
from time import sleep
|
||||
import traceback
|
||||
|
||||
|
||||
class ScanSimple:
|
||||
def __init__(self,adjustables,values,counterCallers,fina,Npulses=100,basepath='',scan_info_dir='',checker=None,scan_directories=False):
|
||||
def __init__(
|
||||
self,
|
||||
adjustables,
|
||||
values,
|
||||
counterCallers,
|
||||
fina,
|
||||
Npulses=100,
|
||||
basepath="",
|
||||
scan_info_dir="",
|
||||
checker=None,
|
||||
scan_directories=False,
|
||||
callbackStartStep=None,
|
||||
):
|
||||
self.Nsteps = len(values)
|
||||
self.pulses_per_step = Npulses
|
||||
self.adjustables = adjustables
|
||||
@@ -18,48 +31,53 @@ class ScanSimple:
|
||||
self.nextStep = 0
|
||||
self.basepath = basepath
|
||||
self.scan_info_dir = scan_info_dir
|
||||
self.scan_info = {'scan_parameters':
|
||||
{
|
||||
'name':[ta.name for ta in adjustables ],
|
||||
'Id':[ta.Id for ta in adjustables]
|
||||
},
|
||||
'scan_values_all':values,
|
||||
'scan_values':[],
|
||||
'scan_readbacks':[],
|
||||
'scan_files':[],
|
||||
'scan_step_info':[]}
|
||||
self.scan_info_filename = os.path.join(self.scan_info_dir,fina)
|
||||
self.scan_info_filename += '_scan_info.json'
|
||||
self.scan_info = {
|
||||
"scan_parameters": {
|
||||
"name": [ta.name for ta in adjustables],
|
||||
"Id": [ta.Id for ta in adjustables],
|
||||
},
|
||||
"scan_values_all": values,
|
||||
"scan_values": [],
|
||||
"scan_readbacks": [],
|
||||
"scan_files": [],
|
||||
"scan_step_info": [],
|
||||
}
|
||||
self.scan_info_filename = os.path.join(self.scan_info_dir, fina)
|
||||
self.scan_info_filename += "_scan_info.json"
|
||||
self._scan_directories = scan_directories
|
||||
self.checker = checker
|
||||
self.initial_values = []
|
||||
for adj in self.adjustables:
|
||||
tv = adj.get_current_value()
|
||||
self.initial_values.append(adj.get_current_value())
|
||||
print('Initial value of %s : %g'%(adj.name,tv))
|
||||
print("Initial value of %s : %g" % (adj.name, tv))
|
||||
|
||||
|
||||
def get_filename(self,stepNo,Ndigits=4):
|
||||
fina = os.path.join(self.basepath,self.fina)
|
||||
def get_filename(self, stepNo, Ndigits=4):
|
||||
fina = os.path.join(self.basepath, self.fina)
|
||||
if self._scan_directories:
|
||||
fina = os.path.join(fina,self.fina)
|
||||
fina += '_step%04d'%stepNo
|
||||
fina = os.path.join(fina, self.fina)
|
||||
fina += "_step%04d" % stepNo
|
||||
return fina
|
||||
|
||||
def doNextStep(self,step_info=None,verbose=True):
|
||||
def doNextStep(self, step_info=None, verbose=True):
|
||||
if self.checker:
|
||||
while not self.checker['checker_call'](*self.checker['args'],**self.checker['kwargs']):
|
||||
print('Condition checker is not happy, waiting for OK conditions.')
|
||||
sleep(self.checker['wait_time'])
|
||||
while not self.checker["checker_call"](
|
||||
*self.checker["args"], **self.checker["kwargs"]
|
||||
):
|
||||
print("Condition checker is not happy, waiting for OK conditions.")
|
||||
sleep(self.checker["wait_time"])
|
||||
|
||||
if not len(self.values_todo)>0:
|
||||
if not len(self.values_todo) > 0:
|
||||
return False
|
||||
values_step = self.values_todo[0]
|
||||
if verbose:
|
||||
print('Starting scan step %d of %d'%(self.nextStep+1,len(self.values_todo)+len(self.values_done)))
|
||||
print(
|
||||
"Starting scan step %d of %d"
|
||||
% (self.nextStep + 1, len(self.values_todo) + len(self.values_done))
|
||||
)
|
||||
ms = []
|
||||
fina = self.get_filename(self.nextStep)
|
||||
for adj,tv in zip(self.adjustables,values_step):
|
||||
for adj, tv in zip(self.adjustables, values_step):
|
||||
ms.append(adj.changeTo(tv))
|
||||
for tm in ms:
|
||||
tm.wait()
|
||||
@@ -67,19 +85,21 @@ class ScanSimple:
|
||||
for adj in self.adjustables:
|
||||
readbacks_step.append(adj.get_current_value())
|
||||
if verbose:
|
||||
print('Moved variables, now starting acquisition')
|
||||
print("Moved variables, now starting acquisition")
|
||||
filenames = []
|
||||
acs = []
|
||||
for ctr in self.counterCallers:
|
||||
acq = ctr.acquire(file_name=fina,Npulses=self.pulses_per_step)
|
||||
acq = ctr.acquire(file_name=fina, Npulses=self.pulses_per_step)
|
||||
filenames.extend(acq.file_names)
|
||||
acs.append(acq)
|
||||
for ta in acs:
|
||||
ta.wait()
|
||||
if verbose:
|
||||
print('Done with acquisition')
|
||||
print("Done with acquisition")
|
||||
if self.checker:
|
||||
if not self.checker['checker_call'](*self.checker['args'],**self.checker['kwargs']):
|
||||
if not self.checker["checker_call"](
|
||||
*self.checker["args"], **self.checker["kwargs"]
|
||||
):
|
||||
return True
|
||||
if callable(step_info):
|
||||
tstepinfo = step_info()
|
||||
@@ -87,20 +107,24 @@ class ScanSimple:
|
||||
tstepinfo = step_info
|
||||
self.values_done.append(self.values_todo.pop(0))
|
||||
self.readbacks.append(readbacks_step)
|
||||
self.appendScanInfo(values_step,readbacks_step,step_files=filenames,step_info=tstepinfo)
|
||||
self.appendScanInfo(
|
||||
values_step, readbacks_step, step_files=filenames, step_info=tstepinfo
|
||||
)
|
||||
self.writeScanInfo()
|
||||
self.nextStep +=1
|
||||
self.nextStep += 1
|
||||
return True
|
||||
|
||||
def appendScanInfo(self,values_step,readbacks_step,step_files=None,step_info=None):
|
||||
self.scan_info['scan_values'].append(values_step)
|
||||
self.scan_info['scan_readbacks'].append(readbacks_step)
|
||||
self.scan_info['scan_files'].append(step_files)
|
||||
self.scan_info['scan_step_info'].append(step_info)
|
||||
def appendScanInfo(
|
||||
self, values_step, readbacks_step, step_files=None, step_info=None
|
||||
):
|
||||
self.scan_info["scan_values"].append(values_step)
|
||||
self.scan_info["scan_readbacks"].append(readbacks_step)
|
||||
self.scan_info["scan_files"].append(step_files)
|
||||
self.scan_info["scan_step_info"].append(step_info)
|
||||
|
||||
def writeScanInfo(self):
|
||||
with open(self.scan_info_filename,'w') as f:
|
||||
json.dump(self.scan_info,f,indent=4,sort_keys=True)
|
||||
with open(self.scan_info_filename, "w") as f:
|
||||
json.dump(self.scan_info, f, indent=4, sort_keys=True)
|
||||
|
||||
def scanAll(self, step_info=None):
|
||||
done = False
|
||||
@@ -116,45 +140,110 @@ class ScanSimple:
|
||||
|
||||
def changeToInitialValues(self):
|
||||
c = []
|
||||
for adj,iv in zip(self.adjustables,self.initial_values):
|
||||
for adj, iv in zip(self.adjustables, self.initial_values):
|
||||
c.append(adj.changeTo(iv))
|
||||
return c
|
||||
|
||||
|
||||
class Scans:
|
||||
def __init__(self,data_base_dir='',scan_info_dir='',default_counters=[],checker=None,scan_directories=False):
|
||||
def __init__(
|
||||
self,
|
||||
data_base_dir="",
|
||||
scan_info_dir="",
|
||||
default_counters=[],
|
||||
checker=None,
|
||||
scan_directories=False,
|
||||
):
|
||||
self.data_base_dir = data_base_dir
|
||||
self.scan_info_dir = scan_info_dir
|
||||
self._default_counters = default_counters
|
||||
self.checker = checker
|
||||
self._scan_directories = scan_directories
|
||||
|
||||
def ascan(self,adjustable,start_pos,end_pos,N_intervals,N_pulses,file_name=None,start_immediately=True, step_info = None):
|
||||
positions = np.linspace(start_pos,end_pos,N_intervals+1)
|
||||
def ascan(
|
||||
self,
|
||||
adjustable,
|
||||
start_pos,
|
||||
end_pos,
|
||||
N_intervals,
|
||||
N_pulses,
|
||||
file_name=None,
|
||||
start_immediately=True,
|
||||
step_info=None,
|
||||
):
|
||||
positions = np.linspace(start_pos, end_pos, N_intervals + 1)
|
||||
values = [[tp] for tp in positions]
|
||||
s = ScanSimple([adjustable],values,self._default_counters,file_name,Npulses=N_pulses,basepath=self.data_base_dir,scan_info_dir=self.scan_info_dir,checker=self.checker,scan_directories=self._scan_directories)
|
||||
s = ScanSimple(
|
||||
[adjustable],
|
||||
values,
|
||||
self._default_counters,
|
||||
file_name,
|
||||
Npulses=N_pulses,
|
||||
basepath=self.data_base_dir,
|
||||
scan_info_dir=self.scan_info_dir,
|
||||
checker=self.checker,
|
||||
scan_directories=self._scan_directories,
|
||||
)
|
||||
if start_immediately:
|
||||
s.scanAll(step_info=step_info)
|
||||
return s
|
||||
|
||||
def rscan(self,adjustable,start_pos,end_pos,N_intervals,N_pulses,file_name=None,start_immediately=True):
|
||||
positions = np.linspace(start_pos,end_pos,N_intervals+1)
|
||||
def rscan(
|
||||
self,
|
||||
adjustable,
|
||||
start_pos,
|
||||
end_pos,
|
||||
N_intervals,
|
||||
N_pulses,
|
||||
file_name=None,
|
||||
start_immediately=True,
|
||||
):
|
||||
positions = np.linspace(start_pos, end_pos, N_intervals + 1)
|
||||
current = adjustable.get_current_value()
|
||||
values = [[tp+current] for tp in positions]
|
||||
s = ScanSimple([adjustable],values,self._default_counters,file_name,Npulses=N_pulses,basepath=self.data_base_dir,scan_info_dir=self.scan_info_dir,checker=self.checker,scan_directories=self._scan_directories)
|
||||
values = [[tp + current] for tp in positions]
|
||||
s = ScanSimple(
|
||||
[adjustable],
|
||||
values,
|
||||
self._default_counters,
|
||||
file_name,
|
||||
Npulses=N_pulses,
|
||||
basepath=self.data_base_dir,
|
||||
scan_info_dir=self.scan_info_dir,
|
||||
checker=self.checker,
|
||||
scan_directories=self._scan_directories,
|
||||
)
|
||||
if start_immediately:
|
||||
s.scanAll()
|
||||
return s
|
||||
|
||||
def dscan(self,*args,**kwargs):
|
||||
print('Warning: dscan will be deprecated for rscan unless someone explains what it stands for in spec!')
|
||||
return self.rscan(*args,**kwargs)
|
||||
def dscan(self, *args, **kwargs):
|
||||
print(
|
||||
"Warning: dscan will be deprecated for rscan unless someone explains what it stands for in spec!"
|
||||
)
|
||||
return self.rscan(*args, **kwargs)
|
||||
|
||||
def ascanList(self,adjustable,posList,N_pulses,file_name=None,start_immediately=True, step_info = None):
|
||||
def ascanList(
|
||||
self,
|
||||
adjustable,
|
||||
posList,
|
||||
N_pulses,
|
||||
file_name=None,
|
||||
start_immediately=True,
|
||||
step_info=None,
|
||||
):
|
||||
positions = posList
|
||||
values = [[tp] for tp in positions]
|
||||
s = ScanSimple([adjustable],values,self._default_counters,file_name,Npulses=N_pulses,basepath=self.data_base_dir,scan_info_dir=self.scan_info_dir,checker=self.checker,scan_directories=self._scan_directories)
|
||||
s = ScanSimple(
|
||||
[adjustable],
|
||||
values,
|
||||
self._default_counters,
|
||||
file_name,
|
||||
Npulses=N_pulses,
|
||||
basepath=self.data_base_dir,
|
||||
scan_info_dir=self.scan_info_dir,
|
||||
checker=self.checker,
|
||||
scan_directories=self._scan_directories,
|
||||
)
|
||||
if start_immediately:
|
||||
s.scanAll(step_info=step_info)
|
||||
return s
|
||||
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
from threading import Thread
|
||||
|
||||
|
||||
class Acquisition:
|
||||
def __init__(self, parent=None, acquire=None, acquisition_kwargs = {}, hold=True, stopper=None):
|
||||
def __init__(
|
||||
self, parent=None, acquire=None, acquisition_kwargs={}, hold=True, stopper=None
|
||||
):
|
||||
self.acquisition_kwargs = acquisition_kwargs
|
||||
self.file_names = acquisition_kwargs['file_names']
|
||||
self.file_names = acquisition_kwargs["file_names"]
|
||||
self._acquire = acquire
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._acquire)
|
||||
@@ -18,12 +21,12 @@ class Acquisition:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._thread.isAlive():
|
||||
return 'acquiring'
|
||||
return "acquiring"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
class Adjustable:
|
||||
def __init__(self, f_get_value, f_change_value, f_set_value_to=None):
|
||||
|
||||
self._f_get_value = f_get_value
|
||||
self._f_change_value = f_change_value
|
||||
self._f_set_value_to = f_set_value_to
|
||||
|
||||
|
||||
def wrap_spec_convenience(obj):
|
||||
# spec-inspired convenience methods
|
||||
def mv(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
def wm(self, *args, **kwargs):
|
||||
return self.get_current_value(*args, **kwargs)
|
||||
|
||||
def mvr(self, value, *args, **kwargs):
|
||||
|
||||
if self.get_moveDone == 1:
|
||||
startvalue = self.get_current_value(readback=True, *args, **kwargs)
|
||||
else:
|
||||
startvalue = self.get_current_value(readback=False, *args, **kwargs)
|
||||
self._currentChange = self.changeTo(value + startvalue, *args, **kwargs)
|
||||
|
||||
def wait(self):
|
||||
self._currentChange.wait()
|
||||
|
||||
obj.wm = wm
|
||||
obj.mv = mv
|
||||
obj.mvr = mvr
|
||||
obj.wait = wait
|
||||
@@ -0,0 +1 @@
|
||||
from .aliases import *
|
||||
|
||||
@@ -0,0 +1,115 @@
|
||||
import os
|
||||
from pathlib import Path
|
||||
import json
|
||||
|
||||
|
||||
class Alias:
|
||||
def __init__(self, alias, channel=None, channeltype=None):
|
||||
self.alias = alias
|
||||
self.channel = channel
|
||||
self.channeltype = channeltype
|
||||
self.children = []
|
||||
|
||||
def append(self, subalias):
|
||||
assert type(subalias) is Alias, "You can only append aliases to aliases!"
|
||||
assert not (
|
||||
subalias.alias in [tc.alias for tc in self.children]
|
||||
), f"Alias {subalias.alias} exists already!"
|
||||
self.children.append(subalias)
|
||||
|
||||
def get_all(self,joiner='.'):
|
||||
aa = []
|
||||
if self.channel:
|
||||
ta = {}
|
||||
ta["alias"] = self.alias
|
||||
ta["channel"] = self.channel
|
||||
if self.channeltype:
|
||||
ta["channeltype"] = self.channeltype
|
||||
aa.append(ta)
|
||||
if self.children:
|
||||
for tc in self.children:
|
||||
taa = tc.get_all()
|
||||
for ta in taa:
|
||||
aa.append({'alias':joiner.join([self.alias,ta['alias']]),'channel':ta['channel'], 'channeltype':ta['channeltype']})
|
||||
return aa
|
||||
|
||||
# def add_children(self, *args):
|
||||
# self.children.append(find_aliases(*args))
|
||||
|
||||
|
||||
def find_aliases(*args):
|
||||
o = []
|
||||
for obj in args:
|
||||
if isinstance(obj, Alias):
|
||||
o.append(obj)
|
||||
if hasattr(obj, "alias"):
|
||||
obj = obj.alias
|
||||
return tuple(o)
|
||||
|
||||
|
||||
class Namespace:
|
||||
def __init__(self, namespace_file=None):
|
||||
path = Path(namespace_file)
|
||||
assert path.suffix == ".json", "file has no json extension"
|
||||
self._path = path
|
||||
self.name = path.stem
|
||||
self.data = None
|
||||
self._modified = False
|
||||
|
||||
def read_file(self):
|
||||
with self._path.open("r") as fp:
|
||||
self.data = json.load(fp)
|
||||
self._modified = False
|
||||
|
||||
@property
|
||||
def aliases(self):
|
||||
if not self.data:
|
||||
self.read_file()
|
||||
return [td["alias"] for td in self.data]
|
||||
|
||||
@property
|
||||
def channels(self):
|
||||
if not self.data:
|
||||
self.read_file()
|
||||
return [td["channel"] for td in self.data]
|
||||
|
||||
def update(self, alias, channel, channeltype):
|
||||
assert not alias in self.aliases, "Duplicate alias {alias} found!"
|
||||
assert not channel in self.channels, "Duplicate channel {channel} found!"
|
||||
self.data.append(
|
||||
{"alias": alias, "channel": channel, "channeltype": channeltype}
|
||||
)
|
||||
self._modified = True
|
||||
|
||||
def store(self):
|
||||
if self._modified:
|
||||
with self._path.open("w") as fp:
|
||||
json.dump(self.data, fp)
|
||||
self._modified = False
|
||||
|
||||
def get_info(self, alias=None, channel=None):
|
||||
assert alias or channel, "Either search alias or channel needs to be defined!"
|
||||
assert not(alias and channel), "Only either search alias or channel can be defined"
|
||||
if alias:
|
||||
if alias in self.aliases:
|
||||
return self.data[self.aliases.index(alias)]
|
||||
else:
|
||||
return None
|
||||
if channel:
|
||||
if channel in self.channels:
|
||||
return self.data[self.channels.index(channel)]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
|
||||
class NamespaceCollection:
|
||||
def __init__(self, alias_path=None):
|
||||
if not alias_path:
|
||||
alias_path = os.path.abspath(__file__)
|
||||
self._namespace_path = Path(alias_path).parent / "namespaces"
|
||||
else:
|
||||
self._namespace_path = Path(alias_path)
|
||||
for nsf in self._namespace_path.glob("*.json"):
|
||||
# self.__dict__[nsf.stem] = property(lambda:Namespace(nsf))
|
||||
self.__dict__[nsf.stem] = Namespace(nsf)
|
||||
@@ -1,282 +0,0 @@
|
||||
elog = {'url': 'https://elog-gfa.psi.ch/Alvra',
|
||||
'screenshot_directory': '/sf/alvra/config/screenshots'}
|
||||
|
||||
aliases = {
|
||||
# Front-End components
|
||||
'SARFE10-OPSH044' : {
|
||||
'alias' : 'shutUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Photon shutter after Undulator'},
|
||||
'SARFE10-OAPU044' : {
|
||||
'alias' : 'slitUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Slit after Undulator',
|
||||
'eco_type' : 'xoptics.slits.SlitFourBlades'},
|
||||
'SARFE10-PBIG050' : {
|
||||
'alias' : 'gasMon',
|
||||
'z_und' : 50,
|
||||
'desc' : 'Gas Monitor Intensity (PBIG)'},
|
||||
'SARFE10-PBPS053' : {
|
||||
'alias' : 'pbpsUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Intensity position monitor after Undulator (PBPS)'},
|
||||
'SARFE10-OATT053' : {
|
||||
'alias' : 'attFE',
|
||||
'z_und' : 53,
|
||||
'desc' : 'Attenuator in Front End',
|
||||
'eco_type' : 'xoptics.attenuator_aramis.AttenuatorAramis'},
|
||||
'SARFE10-PPRM053' : {
|
||||
'alias' : 'screenFE',
|
||||
'z_und' : 53,
|
||||
'desc' : 'Profile monitor after single-shot spectrometer (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SARFE10-SBST060' : {
|
||||
'alias' : 'shutFE',
|
||||
'z_und' : 60,
|
||||
'desc' : 'Photon shutter in the end of Front End'},
|
||||
# Optics hutch components
|
||||
'SARFE10-PPRM064' : {
|
||||
'alias' : 'screenOP',
|
||||
'z_und' : 64,
|
||||
'desc' : 'Profile monitor after Front End',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OOMH064' : {
|
||||
'alias' : 'mirrorAlv1',
|
||||
'z_und' : 64,
|
||||
'desc' : 'First Alvra Horizontal offset mirror (OMH064)'},
|
||||
'SAROP11-PPRM066' : {
|
||||
'alias' : 'screenMirrAlv1',
|
||||
'z_und' : 66,
|
||||
'desc' : 'Profile monitor after Alvra Mirror 1 (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OOMH076' : {
|
||||
'alias' : 'mirrorAlv2',
|
||||
'z_und' : 76,
|
||||
'desc' : 'Second Alvra Horizontal offset mirror (OMH076)'},
|
||||
'SAROP11-PPRM078' : {
|
||||
'alias' : 'screenMirrAlv2',
|
||||
'z_und' : 78,
|
||||
'desc' : 'Profile monitor after Alvra Mirror 2 (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OAPU104' : {
|
||||
'alias' : 'slitSwitch',
|
||||
'z_und' : 104,
|
||||
'desc' : 'Slit in Optics hutch after Photon switchyard and before Alvra mono',
|
||||
'eco_type' : 'xoptics.slits.SlitBlades'},
|
||||
'SAROP11-ODCM105' : {
|
||||
'alias' : 'mono',
|
||||
'z_und' : 105,
|
||||
'desc' : 'Alvra DCM Monochromator',
|
||||
'eco_type' : 'xoptics.dcm.Double_Crystal_Mono'},
|
||||
# 'ALVRA' : {
|
||||
# 'alias' : 'mono_FEL',
|
||||
# 'z_und' : 105,
|
||||
# 'desc' : 'Joint mono-FEL energy device',
|
||||
# 'eco_type' : 'xoptics.dcm.alvra_mono_FEL'},
|
||||
# 'SAROP11-PSCR106' : {
|
||||
# 'alias' : 'ProfMono',
|
||||
# 'z_und' : 106,
|
||||
# 'desc' : 'Profile Monitor after Mono (PSCR)'},
|
||||
'SAROP11-OOMV108' : {
|
||||
'alias' : 'mirrorV1',
|
||||
'z_und' : 108,
|
||||
'desc' : 'Alvra Vertical offset Mirror 1 (OMV108)'},
|
||||
# 'SAROP11-PSCR109' : {
|
||||
# 'alias' : 'ProfMirrV1',
|
||||
# 'z_und' : 109,
|
||||
# 'desc' : 'Profile Monitor after Vertical Mirror 1 (PSCR)'},
|
||||
'SAROP11-OOMV109' : {
|
||||
'alias' : 'mirrorV2',
|
||||
'z_und' : 109,
|
||||
'desc' : 'Alvra Vertical offset Mirror 2 (OMV109)'},
|
||||
'SAROP11-PPRM110' : {
|
||||
'alias' : 'screenMirrorV2',
|
||||
'z_und' : 110,
|
||||
'desc' : 'Profile monitor after Vertical Mirror 2 (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OPPI110' : {
|
||||
'alias' : 'pulsePicker',
|
||||
'z_und' : 110,
|
||||
'desc' : 'X-ray pulse picker'},
|
||||
'SAROP11-SBST114' : {
|
||||
'alias' : 'shutOpt',
|
||||
'z_und' : 114,
|
||||
'desc' : 'Shutter after Optics hutch'},
|
||||
## Experimental hutch components
|
||||
'SAROP11-PBPS117' : {
|
||||
'alias' : 'pbpsOpt',
|
||||
'z_und' : 117,
|
||||
'desc' : 'Intensity/position monitor after Optics hutch (PBPS)',
|
||||
'eco_type' : 'xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS',
|
||||
'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
'SAROP11-PPRM117' : {
|
||||
'alias' : 'screenOPEnd',
|
||||
'z_und' : 117,
|
||||
'desc' : 'Profile monitor after Optics hutch (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-PALM118' : {
|
||||
'alias' : 'DelayPALM',
|
||||
'z_und' : 118,
|
||||
'desc' : 'Timing diagnostics THz streaking (PALM)'},
|
||||
'SAROP11-PSEN119' : {
|
||||
'alias' : 'DelayPSEN',
|
||||
'z_und' : 119,
|
||||
'desc' : 'Timing diagnostics spectral encoding (PSEN)'},
|
||||
'SAROP11-OATT120' : {
|
||||
'alias' : 'attExp',
|
||||
'z_und' : 120,
|
||||
'desc' : 'Attenuator Alvra',
|
||||
'eco_type' : 'xoptics.attenuator_aramis.AttenuatorAramis'},
|
||||
'SAROP11-OAPU120' : {
|
||||
'alias' : 'slitAttExp',
|
||||
'z_und' : 120,
|
||||
'desc' : 'Slits behind attenuator',
|
||||
'eco_type' : 'xoptics.slits.SlitPosWidth'},
|
||||
'SAROP11-OLAS120' : {
|
||||
'alias' : 'refLaser',
|
||||
'z_und' : 120,
|
||||
'desc' : 'Alvra beamline reference laser before KBs (OLAS)',
|
||||
'eco_type' : 'xoptics.reflaser.RefLaser_Aramis'},
|
||||
'SAROP11-PBPS122' : {
|
||||
'alias' : 'pbpsAtt',
|
||||
'z_und' : 122,
|
||||
'desc' : 'Intensity/Position monitor after Attenuator',
|
||||
'eco_type' : 'xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS',
|
||||
'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
'SAROP11-PPRM122' : {
|
||||
'alias' : 'screenAtt',
|
||||
'z_und' : 122,
|
||||
'desc' : 'Profile monitor after Attenuator',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OKBV123' : {
|
||||
'alias' : 'kbVer',
|
||||
'z_und' : 123,
|
||||
'desc' : 'Alvra vertical KB mirror',
|
||||
'eco_type' : 'xoptics.KBver.KBver'},
|
||||
'SAROP11-OKBH124' : {
|
||||
'alias' : 'kbHor',
|
||||
'z_und' : 124,
|
||||
'desc' : 'Alvra horizontal KB mirror',
|
||||
'eco_type' : 'xoptics.KBhor.KBhor'},
|
||||
# 'SAROP11-PIPS125-1' : {
|
||||
# 'alias' : 'PIPS1',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Diode digitizer for PIPS1',
|
||||
# 'eco_type' : 'devices_general.detectors.DiodeDigitizer',
|
||||
# 'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
# 'SAROP11-PIPS125-2' : {
|
||||
# 'alias' : 'PIPS1',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Diode digitizer for PIPS2',
|
||||
# 'eco_type' : 'devices_general.detectors.DiodeDigitizer',
|
||||
# 'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
|
||||
'SARES11-XSAM125' : {
|
||||
'alias' : 'primeSample',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Sample XYZ manipulator',
|
||||
'eco_type' : 'endstations.alvra_prime.huber'},
|
||||
'SARES11-XCRY125' : {
|
||||
'alias' : 'primeCryTrans',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime von Hamos X-trans (Bragg)',
|
||||
'eco_type' : 'endstations.alvra_prime.vonHamosBragg'},
|
||||
'SARES11-XOTA125' : {
|
||||
'alias' : 'primeTable',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime optical table',
|
||||
'eco_type' : 'endstations.alvra_prime.table'},
|
||||
'SARES11-XMI125' : {
|
||||
'alias' : 'primeMicroscope',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Microscope focus and zoom',
|
||||
'eco_type' : 'endstations.alvra_prime.microscope'},
|
||||
|
||||
# 'SARES22-GPS' : {
|
||||
# 'alias' : 'Gps',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'General purpose station',
|
||||
# 'eco_type' : 'endstations.bernina_gps.GPS'},
|
||||
# 'SARES20-PROF142-M1' : {
|
||||
# 'alias' : 'Xeye',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'Mobile X-ray eye in Bernina hutch',
|
||||
# 'eco_type' : 'xdiagnostics.profile_monitors.Bernina_XEYE',
|
||||
# 'kwargs' : {'bshost':'sf-daqsync-01.psi.ch','bsport':11173},
|
||||
#
|
||||
# },
|
||||
# 'SLAAR21-LMOT' : {
|
||||
# 'alias' : 'LasExp',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Experiment laser optics',
|
||||
# 'eco_type' : 'loptics.bernina_experiment.Laser_Exp'},
|
||||
'SLAAR01-TSPL-EPL' : {
|
||||
'alias' : 'phaseShifter',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Experiment laser phase shifter (Globi)',
|
||||
'eco_type' : 'devices_general.alvratiming.PhaseShifterAramis'},
|
||||
'SLAAR11-LMOT' : {
|
||||
'alias' : 'laser',
|
||||
'z_und' : 122,
|
||||
'desc' : 'Experiment laser hardware',
|
||||
'eco_type' : 'loptics.alvra_experiment.Laser_Exp'},
|
||||
# 'SLAAR11-LMOT' : {
|
||||
# 'alias' : 'palm_eo',
|
||||
# 'z_und' : 119,
|
||||
# 'desc' : 'PALM EO-sampling delay line',
|
||||
# 'eco_type' : 'xdiagnostics.palm.eo'},
|
||||
# 'http://sf-daq-4:10000' : {
|
||||
# 'alias' : 'DetJF',
|
||||
# 'z_und' : 125,
|
||||
# 'desc' : '4.5M Jungfrau detector',
|
||||
# 'eco_type' : 'devices_general.alvradetectors.DIAClient'},
|
||||
'SARES11-V' : {
|
||||
'alias' : 'vacuum',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime vacuum system',
|
||||
'eco_type' : 'endstations.alvra_prime.vacuum'},
|
||||
'SLAAR11-LTIM01-EVR0' : {
|
||||
'alias' : 'laserShutter',
|
||||
'z_und' : 122,
|
||||
'desc' : 'Laser Shutter',
|
||||
'eco_type' : 'loptics.alvra_laser_shutter.laser_shutter'},
|
||||
# = dict(
|
||||
# alias = ''
|
||||
# z_und =
|
||||
# desc = ''},
|
||||
'SARES11-CMOV-SMA691110' : {
|
||||
'alias' : '_prism_gonio',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime laser prism gonio',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord',
|
||||
'device' : 'prism',
|
||||
'axis' : 'gonio'},
|
||||
'SARES11-CMOV-SMA691111' : {
|
||||
'alias' : '_prism_trans',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime laser prism trans',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord',
|
||||
'device' : 'prism',
|
||||
'axis' : 'trans'},
|
||||
'SARES11-CMOV-SMA691112' : {
|
||||
'alias' : '_prism_rot',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime laser prism rotation',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord',
|
||||
'device' : 'prism', # a virtual stage for eco namespace
|
||||
'axis' : 'rot'}, # a axis of this virtual stage
|
||||
'SARES11-CMOV-SMA691113' : {
|
||||
'alias' : '_xmic_gon',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime microscope mirror gonio',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord'},
|
||||
# no 'device' becauses its appended to other stage in
|
||||
# ..endstations/alvra_prime.py
|
||||
'SARES11-CMOV-SMA691114' : {
|
||||
'alias' : '_xmic_rot',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime microscope mirror rotation',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord'}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,195 +0,0 @@
|
||||
elog = {'url': 'https://elog-gfa.psi.ch/Bernina',
|
||||
'screenshot_directory': '/sf/bernina/config/screenshots'}
|
||||
|
||||
aliases = {
|
||||
'SARFE10-OPSH044' : {
|
||||
'alias' : 'ShutUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Photon shutter after Undulator'},
|
||||
'SARFE10-OAPU044' : {
|
||||
'alias' : 'SlitUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Slit after Undulator',
|
||||
'eco_type' : 'xoptics.slits.SlitFourBlades'},
|
||||
'SARFE10-PBIG050' : {
|
||||
'alias' : 'GasMon',
|
||||
'z_und' : 50,
|
||||
'desc' : 'Gas Monitor Intensity'},
|
||||
'SARFE10-PBPS053' : {
|
||||
'alias' : 'MonUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Intensity position monitor after Undulator'},
|
||||
'SARFE10-OATT053' : {
|
||||
'alias' : 'AttFE',
|
||||
'z_und' : 53,
|
||||
'desc' : 'Attenuator in Front End',
|
||||
'eco_type' : 'xoptics.attenuator_aramis.AttenuatorAramis'},
|
||||
'SARFE10-SBST060' : {
|
||||
'alias' : 'ShutFE',
|
||||
'z_und' : 60,
|
||||
'desc' : 'Photon shutter in the end of Front End'},
|
||||
'SARFE10-PPRM064' : {
|
||||
'alias' : 'ProfFE',
|
||||
'z_und' : 64,
|
||||
'desc' : 'Profile monitor after Front End',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OOMH064' : {
|
||||
'alias' : 'MirrAlv1',
|
||||
'z_und' : 64,
|
||||
'desc' : 'Horizontal mirror Alvra 1'},
|
||||
'SAROP11-PPRM066' : {
|
||||
'alias' : 'ProfMirrAlv1',
|
||||
'z_und' : 66,
|
||||
'desc' : 'Profile monitor after Alvra Mirror 1',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP21-OAPU092' : {
|
||||
'alias' : 'SlitSwitch',
|
||||
'z_und' : 92,
|
||||
'desc' : 'Slit in Optics hutch after Photon switchyard and before Bernina optics',
|
||||
'eco_type' : 'xoptics.slits.SlitBlades'},
|
||||
'SAROP21-OOMV092' : {
|
||||
'alias' : 'Mirr1',
|
||||
'z_und' : 92,
|
||||
'desc' : 'Vertical offset Mirror 1'},
|
||||
'SAROP21-PPRM094' : {
|
||||
'alias' : 'ProfMirr1',
|
||||
'z_und' : 94,
|
||||
'desc' : 'Profile monitor after Mirror 1',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP21-OOMV096' : {
|
||||
'alias' : 'Mirr2',
|
||||
'z_und' : 96,
|
||||
'desc' : 'Vertical offset mirror 2'},
|
||||
'SAROP21-PSCR097' : {
|
||||
'alias' : 'ProfMirr2',
|
||||
'z_und' : 97,
|
||||
'desc' : 'Profile Monitor after Mirror 2'},
|
||||
'SAROP21-ODCM098' : {
|
||||
'alias' : 'Mono',
|
||||
'z_und' : 98,
|
||||
'desc' : 'DCM Monochromator',
|
||||
'eco_type' : 'xoptics.dcm.Double_Crystal_Mono'},
|
||||
'SAROP21-PPRM102' : {
|
||||
'alias' : 'ProfMono',
|
||||
'z_und' : 102,
|
||||
'desc' : 'Profile monitor after Monochromator',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP21-OPPI103' : {
|
||||
'alias' : 'Pick',
|
||||
'z_und' : 103,
|
||||
'desc' : 'X-ray pulse picker'},
|
||||
'SAROP21-BST114' : {
|
||||
'alias' : 'ShutOpt',
|
||||
'z_und' : 114,
|
||||
'desc' : 'Shutter after Optics hutch'},
|
||||
'SAROP21-PBPS133' : {
|
||||
'alias' : 'MonOpt',
|
||||
'z_und' : 133,
|
||||
'desc' : 'Intensity/position monitor after Optics hutch',
|
||||
'eco_type' : 'xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS',
|
||||
'kwargs' : {'VME_crate':'SAROP21-CVME-PBPS1','link':9} },
|
||||
'SAROP21-PPRM133' : {
|
||||
'alias' : 'ProfOpt',
|
||||
'z_und' : 133,
|
||||
'desc' : 'Profile monitor after Optics hutch',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP21-PALM134' : {
|
||||
'alias' : 'TimTof',
|
||||
'z_und' : 134,
|
||||
'desc' : 'Timing diagnostics THz streaking/TOF'},
|
||||
'SAROP21-PSEN135' : {
|
||||
'alias' : 'TimRef',
|
||||
'z_und' : 135,
|
||||
'desc' : 'Timing diagnostics spectral encoding of ref. index change'},
|
||||
'SAROP21-OATT135' : {
|
||||
'alias' : 'Att',
|
||||
'z_und' : 135,
|
||||
'desc' : 'Attenuator Bernina',
|
||||
'eco_type' : 'xoptics.attenuator_aramis.AttenuatorAramis'},
|
||||
'SAROP21-OAPU136' : {
|
||||
'alias' : 'SlitAtt',
|
||||
'z_und' : 136,
|
||||
'desc' : 'Slits behind attenuator',
|
||||
'eco_type' : 'xoptics.slits.SlitPosWidth'},
|
||||
'SAROP21-OLAS136' : {
|
||||
'alias' : 'RefLaser',
|
||||
'z_und' : 136,
|
||||
'desc' : 'Bernina beamline reference laser before KBs',
|
||||
'eco_type' : 'xoptics.reflaser.RefLaser_Aramis'},
|
||||
'SAROP21-PBPS138' : {
|
||||
'alias' : 'MonAtt',
|
||||
'z_und' : 138,
|
||||
'desc' : 'Intensity/Position monitor after Attenuator',
|
||||
'eco_type' : 'xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS',
|
||||
'kwargs' : {'VME_crate':'SAROP21-CVME-PBPS2','link':9} },
|
||||
'SAROP21-PDIO138' : {
|
||||
'alias' : 'DetDio',
|
||||
'z_und' : 138,
|
||||
'desc' : 'Diode digitizer for exp data',
|
||||
'eco_type' : 'devices_general.detectors.DiodeDigitizer',
|
||||
'kwargs' : {'VME_crate':'SAROP21-CVME-PBPS2','link':9} },
|
||||
'SAROP21-PPRM138' : {
|
||||
'alias' : 'ProfAtt',
|
||||
'z_und' : 138,
|
||||
'desc' : 'Profile monitor after Attenuator',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP21-OKBV139' : {
|
||||
'alias' : 'KbVer',
|
||||
'z_und' : 139,
|
||||
'desc' : 'Vertically focusing Bernina KB mirror',
|
||||
'eco_type' : 'xoptics.KBver.KBver'},
|
||||
'SAROP21-OKBH140' : {
|
||||
'alias' : 'KbHor',
|
||||
'z_und' : 140,
|
||||
'desc' : 'Horizontally focusing Bernina KB mirror',
|
||||
'eco_type' : 'xoptics.KBhor.KBhor'},
|
||||
'SARES22-GPS' : {
|
||||
'alias' : 'Gps',
|
||||
'z_und' : 142,
|
||||
'desc' : 'General purpose station',
|
||||
'eco_type' : 'endstations.bernina_gps.GPS'},
|
||||
'SARES20-PROF142-M1' : {
|
||||
'alias' : 'Xeye',
|
||||
'z_und' : 142,
|
||||
'desc' : 'Mobile X-ray eye in Bernina hutch',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Bernina_XEYE',
|
||||
'kwargs' : {'bshost':'sf-daqsync-01.psi.ch','bsport':11173},
|
||||
},
|
||||
'SLAAR02-TSPL-EPL' : {
|
||||
'alias' : 'PhaseShifter',
|
||||
'z_und' : 142,
|
||||
'desc' : 'Experiment laser phase shifter',
|
||||
'eco_type' : 'devices_general.timing.PhaseShifterAramis'},
|
||||
'http://sf-daq-1:10000' : {
|
||||
'alias' : 'DetJF',
|
||||
'z_und' : 142,
|
||||
'desc' : '1.5M Jungfrau detector',
|
||||
'eco_type' : 'devices_general.detectors.DIAClient'},
|
||||
'SLAAR21-LMOT' : {
|
||||
'alias' : 'Las',
|
||||
'z_und' : 142,
|
||||
'desc' : 'Experiment laser optics',
|
||||
'eco_type' : 'loptics.bernina_experiment.Laser_Exp'},
|
||||
'SLAAR21-LTIM01-EVR0' : {
|
||||
'alias' : 'LaserShutter',
|
||||
'z_und' : 142,
|
||||
'desc' : 'Laser Shutter',
|
||||
'eco_type' : 'loptics.laser_shutter.laser_shutter'}
|
||||
# 'SLAAR21-LMOT' : {
|
||||
# 'alias' : 'Palm',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'Streaking arrival time monitor',
|
||||
# 'eco_type' : 'timing.palm.Palm'},
|
||||
# 'SLAAR21-LMOT' : {
|
||||
# 'alias' : 'Psen',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'Streaking arrival time monitor',
|
||||
# 'eco_type' : 'timing.psen.Psen'}
|
||||
|
||||
# = dict(
|
||||
# alias = ''
|
||||
# z_und =
|
||||
# desc = ''},
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
[{"alias": "xrd.xbase.readback", "channel": "SARES21-XRD:MOT_TX.RBV", "channeltype": "CA"}, {"alias": "xrd.xbase.user_offset", "channel": "SARES21-XRD:MOT_TX.OFF", "channeltype": "CA"}, {"alias": "xrd.ybase.readback", "channel": "SARES21-XRD:MOT_TY.RBV", "channeltype": "CA"}, {"alias": "xrd.ybase.user_offset", "channel": "SARES21-XRD:MOT_TY.OFF", "channeltype": "CA"}, {"alias": "xrd.rxbase.readback", "channel": "SARES21-XRD:MOT_RX.RBV", "channeltype": "CA"}, {"alias": "xrd.rxbase.user_offset", "channel": "SARES21-XRD:MOT_RX.OFF", "channeltype": "CA"}, {"alias": "xrd.omega.readback", "channel": "SARES21-XRD:MOT_MY_RYTH.RBV", "channeltype": "CA"}, {"alias": "xrd.omega.user_offset", "channel": "SARES21-XRD:MOT_MY_RYTH.OFF", "channeltype": "CA"}, {"alias": "xrd.gamma.readback", "channel": "SARES21-XRD:MOT_NY_RY2TH.RBV", "channeltype": "CA"}, {"alias": "xrd.gamma.user_offset", "channel": "SARES21-XRD:MOT_NY_RY2TH.OFF", "channeltype": "CA"}, {"alias": "xrd.delta.readback", "channel": "SARES21-XRD:MOT_DT_RX2TH.RBV", "channeltype": "CA"}, {"alias": "xrd.delta.user_offset", "channel": "SARES21-XRD:MOT_DT_RX2TH.OFF", "channeltype": "CA"}, {"alias": "xrd.tdet.readback", "channel": "SARES21-XRD:MOT_D_T.RBV", "channeltype": "CA"}, {"alias": "xrd.tdet.user_offset", "channel": "SARES21-XRD:MOT_D_T.OFF", "channeltype": "CA"}, {"alias": "xrd.tpol.readback", "channel": "SARES21-XRD:MOT_P_T.RBV", "channeltype": "CA"}, {"alias": "xrd.tpol.user_offset", "channel": "SARES21-XRD:MOT_P_T.OFF", "channeltype": "CA"}, {"alias": "xrd.xhl.readback", "channel": "SARES21-XRD:MOT_TBL_TX.RBV", "channeltype": "CA"}, {"alias": "xrd.xhl.user_offset", "channel": "SARES21-XRD:MOT_TBL_TX.OFF", "channeltype": "CA"}, {"alias": "xrd.zhl.readback", "channel": "SARES21-XRD:MOT_TBL_TZ.RBV", "channeltype": "CA"}, {"alias": "xrd.zhl.user_offset", "channel": "SARES21-XRD:MOT_TBL_TZ.OFF", "channeltype": "CA"}, {"alias": "xrd.yhl.readback", "channel": "SARES21-XRD:MOT_TBL_TY.RBV", "channeltype": "CA"}, {"alias": "xrd.yhl.user_offset", "channel": "SARES21-XRD:MOT_TBL_TY.OFF", "channeltype": "CA"}, {"alias": "xrd.rxhl.readback", "channel": "SARES21-XRD:MOT_TBL_RX.RBV", "channeltype": "CA"}, {"alias": "xrd.rxhl.user_offset", "channel": "SARES21-XRD:MOT_TBL_RX.OFF", "channeltype": "CA"}, {"alias": "xrd.teta.readback", "channel": "SARES21-XRD:MOT_HEX_TX.RBV", "channeltype": "CA"}, {"alias": "xrd.teta.user_offset", "channel": "SARES21-XRD:MOT_HEX_TX.OFF", "channeltype": "CA"}, {"alias": "xrd.eta.readback", "channel": "SARES21-XRD:MOT_HEX_RX.RBV", "channeltype": "CA"}, {"alias": "xrd.eta.user_offset", "channel": "SARES21-XRD:MOT_HEX_RX.OFF", "channeltype": "CA"}]
|
||||
@@ -0,0 +1 @@
|
||||
from .alvra import *
|
||||
Executable
+221
@@ -0,0 +1,221 @@
|
||||
from .config import elog as _elog_info
|
||||
from ..utilities.elog import Elog as _Elog
|
||||
from ..utilities.elog import Screenshot as _Screenshot
|
||||
from ..utilities.config import loadConfig
|
||||
from epics import PV
|
||||
import sys, os
|
||||
|
||||
|
||||
from colorama import Fore as _color
|
||||
import traceback
|
||||
import datetime
|
||||
|
||||
elog = _Elog(
|
||||
_elog_info["url"],
|
||||
user="gac-alvra",
|
||||
screenshot_directory=_elog_info["screenshot_directory"],
|
||||
)
|
||||
screenshot = _Screenshot(screenshot_directory=_elog_info["screenshot_directory"])
|
||||
# stationMessage = _stationMessage('ESA')
|
||||
|
||||
_smaractappends = []
|
||||
|
||||
########### configurations ########################
|
||||
currexp_file_path = "/sf/alvra/config/exp/current_experiment.json"
|
||||
if os.path.exists(currexp_file_path):
|
||||
exp_config = loadConfig(currexp_file_path)
|
||||
else:
|
||||
print("NB: Could not load experiment config in path %s ." % currexp_file_path)
|
||||
|
||||
########### GENERAL IMPLEMENTATIONS ##################
|
||||
from .config import aliases as _aliases
|
||||
|
||||
|
||||
def _attach_device(devDict, devId, args, kwargs):
|
||||
imp_p = devDict["eco_type"].split(sep=".")
|
||||
dev_alias = devDict["alias"]
|
||||
dev_alias = dev_alias[0].lower() + dev_alias[1:]
|
||||
eco_type_name = imp_p[-1]
|
||||
istr = "from .." + ".".join(imp_p[:-1]) + " import "
|
||||
istr += "%s as _%s" % (eco_type_name, eco_type_name)
|
||||
# print(istr)
|
||||
print(("Configuring %s " % (dev_alias)).ljust(25), end="")
|
||||
print(("(%s)" % (devId)).ljust(25), end="")
|
||||
error = None
|
||||
try:
|
||||
exec(istr)
|
||||
tdev = eval("_%s(Id='%s',*args,**kwargs)" % (eco_type_name, devId))
|
||||
tdev.name = dev_alias
|
||||
tdev._z_und = devDict["z_und"]
|
||||
globals().update([(dev_alias, tdev)])
|
||||
print((_color.GREEN + "OK" + _color.RESET).rjust(5))
|
||||
except Exception as e:
|
||||
print((_color.RED + "FAILED" + _color.RESET).rjust(5))
|
||||
error = e
|
||||
return error
|
||||
|
||||
|
||||
errors = []
|
||||
_composed = {}
|
||||
for device_Id in _aliases.keys():
|
||||
alias = _aliases[device_Id]
|
||||
if "eco_type" in alias.keys() and alias["eco_type"]:
|
||||
if "args" in alias.keys() and alias["args"]:
|
||||
args = alias["args"]
|
||||
else:
|
||||
args = tuple()
|
||||
|
||||
if "kwargs" in alias.keys() and alias["kwargs"]:
|
||||
kwargs = alias["kwargs"]
|
||||
else:
|
||||
kwargs = dict()
|
||||
|
||||
e = _attach_device(alias, device_Id, args, kwargs)
|
||||
if e:
|
||||
errors.append((alias["alias"], e))
|
||||
else:
|
||||
_device = globals()[alias["alias"][0].lower() + alias["alias"][1:]]
|
||||
if hasattr(_device, "_smaractaxes"):
|
||||
_smaractappends.append(_device)
|
||||
else:
|
||||
if (
|
||||
alias["eco_type"].endswith("SmarActRecord")
|
||||
and "device" in alias
|
||||
and "axis" in alias
|
||||
):
|
||||
if alias["device"] not in _composed:
|
||||
_composed[alias["device"]] = {}
|
||||
_composed[alias["device"]][alias["axis"]] = globals()[
|
||||
alias["alias"]
|
||||
]
|
||||
|
||||
print("Integrating SmarAct devices:")
|
||||
|
||||
for _device in _smaractappends:
|
||||
print(
|
||||
" Appending %s: %s"
|
||||
% (_device.name, ", ".join(map(str, list(_device._smaractaxes.keys()))))
|
||||
)
|
||||
for _axis in _device._smaractaxes.keys():
|
||||
setattr(_device, _axis, globals()[_device._smaractaxes[_axis]])
|
||||
|
||||
from ..devices_general.smaract import SmarActStage as _SmarActStage
|
||||
|
||||
for _key in _composed.keys():
|
||||
print(
|
||||
" Composing %s: %s" % (_key, ", ".join(map(str, list(_composed[_key].keys()))))
|
||||
)
|
||||
globals()[_key] = _SmarActStage(_composed[_key], _key)
|
||||
|
||||
if len(errors) > 0:
|
||||
print("Found errors when configuring %s" % [te[0] for te in errors])
|
||||
if input("Would you like to see error traces? (y/n)") == "y":
|
||||
for error in errors:
|
||||
print("---> Error when configuring %s" % error[0])
|
||||
traceback.print_tb(error[1].__traceback__)
|
||||
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
out = []
|
||||
with open(fina, "r") as f:
|
||||
done = False
|
||||
while not done:
|
||||
d = f.readline()
|
||||
if not d:
|
||||
done = True
|
||||
if len(d) > 0:
|
||||
if not d.isspace():
|
||||
if not d[0] == "#":
|
||||
out.append(d.strip())
|
||||
return out
|
||||
|
||||
|
||||
from ..acquisition.bs_data import BStools
|
||||
from ..acquisition import scan as _scan
|
||||
|
||||
# from ..acquisition.ioxos_data import Ioxostools
|
||||
|
||||
channellist = dict(
|
||||
alvra_channel_list=parseChannelListFile(
|
||||
"/sf/alvra/config/com/channel_lists/default_channel_list"
|
||||
)
|
||||
)
|
||||
bsdaq = BStools(default_channel_list=channellist, default_file_path="%s")
|
||||
|
||||
# channellistioxos = dict(alvra_channel_list=
|
||||
# parseChannelListFile('/sf/alvra/config/com/channel_lists/default_channel_list_ioxos'))
|
||||
# ioxosdaq = Ioxostools(default_channel_list=channellistioxos,default_file_path='%s')
|
||||
|
||||
channellistPhotonDiag = dict(
|
||||
alvra_channel_list=parseChannelListFile(
|
||||
"/sf/alvra/config/com/channel_lists/default_channel_list_PhotonDiag"
|
||||
)
|
||||
)
|
||||
bsdaqPhotonDiag = BStools(
|
||||
default_channel_list=channellistPhotonDiag, default_file_path="%s"
|
||||
)
|
||||
|
||||
from eco.devices_general.alvradetectors import DIAClient
|
||||
|
||||
bsdaqJF = DIAClient(
|
||||
"bsdaqJF",
|
||||
instrument="alvra",
|
||||
api_address="http://sf-daq-alvra:10000",
|
||||
jf_name="JF_4.5M",
|
||||
)
|
||||
|
||||
try:
|
||||
bsdaqJF.pgroup = int(exp_config["pgroup"][1:])
|
||||
except:
|
||||
print("Could not set p group in bsdaqJF !!")
|
||||
|
||||
checkerPV = PV("SARFE10-PBPG050:HAMP-INTENSITY-CAL")
|
||||
|
||||
|
||||
def checker_function(limits):
|
||||
cv = checkerPV.get()
|
||||
if cv > limits[0] and cv < limits[1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
checker = {}
|
||||
checker["checker_call"] = checker_function
|
||||
checker["args"] = [[100, 300]]
|
||||
checker["kwargs"] = {}
|
||||
checker["wait_time"] = 3
|
||||
|
||||
|
||||
# scansIoxos = _scan.Scans(data_base_dir='/sf/alvra/config/com/data/scan_data',scan_info_dir='/sf/alvra/config/com/data/scan_info',default_counters=[ioxosdaq])
|
||||
scansJF = _scan.Scans(
|
||||
data_base_dir="scan_data",
|
||||
scan_info_dir="/sf/alvra/data/%s/res/scan_info" % exp_config["pgroup"],
|
||||
default_counters=[bsdaqJF],
|
||||
checker=checker,
|
||||
scan_directories=True,
|
||||
)
|
||||
scansBsreadLocal = _scan.Scans(
|
||||
data_base_dir="/sf/alvra/config/com/data/scan_data",
|
||||
scan_info_dir="/sf/alvra/config/com/data/scan_info",
|
||||
default_counters=[bsdaq],
|
||||
)
|
||||
|
||||
scansPhotonDiag = _scan.Scans(
|
||||
data_base_dir="/sf/alvra/config/com/data/photon_diag/scan_data",
|
||||
scan_info_dir="/sf/alvra/config/com/data/photon_diag/scan_info",
|
||||
default_counters=[bsdaqPhotonDiag],
|
||||
)
|
||||
|
||||
########### ADHOC IMPLEMENTED ########################
|
||||
from ..timing.alvralasertiming import Lxt as _Lxt
|
||||
|
||||
lxt = _Lxt()
|
||||
|
||||
from ..xoptics.dcm import AlvraDCM_FEL
|
||||
|
||||
monoFEL = AlvraDCM_FEL("SAROP11-ODCM105")
|
||||
Executable
+323
@@ -0,0 +1,323 @@
|
||||
elog = {
|
||||
"url": "https://elog-gfa.psi.ch/Alvra",
|
||||
"screenshot_directory": "/sf/alvra/config/screenshots",
|
||||
}
|
||||
|
||||
aliases = {
|
||||
# Front-End components
|
||||
"SARFE10-OPSH044": {
|
||||
"alias": "shutUnd",
|
||||
"z_und": 44,
|
||||
"desc": "Photon shutter after Undulator",
|
||||
},
|
||||
"SARFE10-OAPU044": {
|
||||
"alias": "slitUnd",
|
||||
"z_und": 44,
|
||||
"desc": "Slit after Undulator",
|
||||
"eco_type": "xoptics.slits.SlitFourBlades",
|
||||
},
|
||||
"SARFE10-PBIG050": {
|
||||
"alias": "gasMon",
|
||||
"z_und": 50,
|
||||
"desc": "Gas Monitor Intensity (PBIG)",
|
||||
},
|
||||
"SARFE10-PBPS053": {
|
||||
"alias": "pbpsUnd",
|
||||
"z_und": 44,
|
||||
"desc": "Intensity position monitor after Undulator (PBPS)",
|
||||
},
|
||||
"SARFE10-OATT053": {
|
||||
"alias": "attFE",
|
||||
"z_und": 53,
|
||||
"desc": "Attenuator in Front End",
|
||||
"eco_type": "xoptics.attenuator_aramis.AttenuatorAramis",
|
||||
},
|
||||
"SARFE10-PPRM053": {
|
||||
"alias": "screenFE",
|
||||
"z_und": 53,
|
||||
"desc": "Profile monitor after single-shot spectrometer (PPRM)",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SARFE10-SBST060": {
|
||||
"alias": "shutFE",
|
||||
"z_und": 60,
|
||||
"desc": "Photon shutter in the end of Front End",
|
||||
},
|
||||
# Optics hutch components
|
||||
"SARFE10-PPRM064": {
|
||||
"alias": "screenOP",
|
||||
"z_und": 64,
|
||||
"desc": "Profile monitor after Front End",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SAROP11-OOMH064": {
|
||||
"alias": "mirrorAlv1",
|
||||
"z_und": 64,
|
||||
"desc": "First Alvra Horizontal offset mirror (OMH064)",
|
||||
},
|
||||
"SAROP11-PPRM066": {
|
||||
"alias": "screenMirrAlv1",
|
||||
"z_und": 66,
|
||||
"desc": "Profile monitor after Alvra Mirror 1 (PPRM)",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SAROP11-OOMH076": {
|
||||
"alias": "mirrorAlv2",
|
||||
"z_und": 76,
|
||||
"desc": "Second Alvra Horizontal offset mirror (OMH076)",
|
||||
},
|
||||
"SAROP11-PPRM078": {
|
||||
"alias": "screenMirrAlv2",
|
||||
"z_und": 78,
|
||||
"desc": "Profile monitor after Alvra Mirror 2 (PPRM)",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SAROP11-OAPU104": {
|
||||
"alias": "slitSwitch",
|
||||
"z_und": 104,
|
||||
"desc": "Slit in Optics hutch after Photon switchyard and before Alvra mono",
|
||||
"eco_type": "xoptics.slits.SlitBlades",
|
||||
},
|
||||
"SAROP11-ODCM105": {
|
||||
"alias": "mono",
|
||||
"z_und": 105,
|
||||
"desc": "Alvra DCM Monochromator",
|
||||
"eco_type": "xoptics.dcm.Double_Crystal_Mono",
|
||||
},
|
||||
# 'ALVRA' : {
|
||||
# 'alias' : 'mono_FEL',
|
||||
# 'z_und' : 105,
|
||||
# 'desc' : 'Joint mono-FEL energy device',
|
||||
# 'eco_type' : 'xoptics.dcm.alvra_mono_FEL'},
|
||||
# 'SAROP11-PSCR106' : {
|
||||
# 'alias' : 'ProfMono',
|
||||
# 'z_und' : 106,
|
||||
# 'desc' : 'Profile Monitor after Mono (PSCR)'},
|
||||
"SAROP11-OOMV108": {
|
||||
"alias": "mirrorV1",
|
||||
"z_und": 108,
|
||||
"desc": "Alvra Vertical offset Mirror 1 (OMV108)",
|
||||
},
|
||||
# 'SAROP11-PSCR109' : {
|
||||
# 'alias' : 'ProfMirrV1',
|
||||
# 'z_und' : 109,
|
||||
# 'desc' : 'Profile Monitor after Vertical Mirror 1 (PSCR)'},
|
||||
"SAROP11-OOMV109": {
|
||||
"alias": "mirrorV2",
|
||||
"z_und": 109,
|
||||
"desc": "Alvra Vertical offset Mirror 2 (OMV109)",
|
||||
},
|
||||
"SAROP11-PPRM110": {
|
||||
"alias": "screenMirrorV2",
|
||||
"z_und": 110,
|
||||
"desc": "Profile monitor after Vertical Mirror 2 (PPRM)",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SAROP11-OPPI110": {
|
||||
"alias": "pulsePicker",
|
||||
"z_und": 110,
|
||||
"desc": "X-ray pulse picker",
|
||||
},
|
||||
"SAROP11-SBST114": {
|
||||
"alias": "shutOpt",
|
||||
"z_und": 114,
|
||||
"desc": "Shutter after Optics hutch",
|
||||
},
|
||||
## Experimental hutch components
|
||||
"SAROP11-PBPS117": {
|
||||
"alias": "pbpsOpt",
|
||||
"z_und": 117,
|
||||
"desc": "Intensity/position monitor after Optics hutch (PBPS)",
|
||||
"eco_type": "xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS",
|
||||
"kwargs": {"VME_crate": "SAROP11-CVME-PBPS1", "link": 9},
|
||||
},
|
||||
"SAROP11-PPRM117": {
|
||||
"alias": "screenOPEnd",
|
||||
"z_und": 117,
|
||||
"desc": "Profile monitor after Optics hutch (PPRM)",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SAROP11-PALM118": {
|
||||
"alias": "DelayPALM",
|
||||
"z_und": 118,
|
||||
"desc": "Timing diagnostics THz streaking (PALM)",
|
||||
},
|
||||
"SAROP11-PSEN119": {
|
||||
"alias": "DelayPSEN",
|
||||
"z_und": 119,
|
||||
"desc": "Timing diagnostics spectral encoding (PSEN)",
|
||||
},
|
||||
"SAROP11-OATT120": {
|
||||
"alias": "attExp",
|
||||
"z_und": 120,
|
||||
"desc": "Attenuator Alvra",
|
||||
"eco_type": "xoptics.attenuator_aramis.AttenuatorAramis",
|
||||
},
|
||||
"SAROP11-OAPU120": {
|
||||
"alias": "slitAttExp",
|
||||
"z_und": 120,
|
||||
"desc": "Slits behind attenuator",
|
||||
"eco_type": "xoptics.slits.SlitPosWidth",
|
||||
},
|
||||
"SAROP11-OLAS120": {
|
||||
"alias": "refLaser",
|
||||
"z_und": 120,
|
||||
"desc": "Alvra beamline reference laser before KBs (OLAS)",
|
||||
"eco_type": "xoptics.reflaser.RefLaser_Aramis",
|
||||
},
|
||||
"SAROP11-PBPS122": {
|
||||
"alias": "pbpsAtt",
|
||||
"z_und": 122,
|
||||
"desc": "Intensity/Position monitor after Attenuator",
|
||||
"eco_type": "xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS",
|
||||
"kwargs": {"VME_crate": "SAROP11-CVME-PBPS1", "link": 9},
|
||||
},
|
||||
"SAROP11-PPRM122": {
|
||||
"alias": "screenAtt",
|
||||
"z_und": 122,
|
||||
"desc": "Profile monitor after Attenuator",
|
||||
"eco_type": "xdiagnostics.profile_monitors.Pprm",
|
||||
},
|
||||
"SAROP11-OKBV123": {
|
||||
"alias": "kbVer",
|
||||
"z_und": 123,
|
||||
"desc": "Alvra vertical KB mirror",
|
||||
"eco_type": "xoptics.KBver.KBver",
|
||||
},
|
||||
"SAROP11-OKBH124": {
|
||||
"alias": "kbHor",
|
||||
"z_und": 124,
|
||||
"desc": "Alvra horizontal KB mirror",
|
||||
"eco_type": "xoptics.KBhor.KBhor",
|
||||
},
|
||||
# 'SAROP11-PIPS125-1' : {
|
||||
# 'alias' : 'PIPS1',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Diode digitizer for PIPS1',
|
||||
# 'eco_type' : 'devices_general.detectors.DiodeDigitizer',
|
||||
# 'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
# 'SAROP11-PIPS125-2' : {
|
||||
# 'alias' : 'PIPS1',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Diode digitizer for PIPS2',
|
||||
# 'eco_type' : 'devices_general.detectors.DiodeDigitizer',
|
||||
# 'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
"SARES11-XSAM125": {
|
||||
"alias": "primeSample",
|
||||
"z_und": 127,
|
||||
"desc": "Sample XYZ manipulator",
|
||||
"eco_type": "endstations.alvra_prime.huber",
|
||||
},
|
||||
"SARES11-XCRY125": {
|
||||
"alias": "primeCryTrans",
|
||||
"z_und": 127,
|
||||
"desc": "Prime von Hamos X-trans (Bragg)",
|
||||
"eco_type": "endstations.alvra_prime.vonHamosBragg",
|
||||
},
|
||||
"SARES11-XOTA125": {
|
||||
"alias": "primeTable",
|
||||
"z_und": 127,
|
||||
"desc": "Prime optical table",
|
||||
"eco_type": "endstations.alvra_prime.table",
|
||||
},
|
||||
"SARES11-XMI125": {
|
||||
"alias": "primeMicroscope",
|
||||
"z_und": 127,
|
||||
"desc": "Microscope focus and zoom",
|
||||
"eco_type": "endstations.alvra_prime.microscope",
|
||||
},
|
||||
# 'SARES22-GPS' : {
|
||||
# 'alias' : 'Gps',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'General purpose station',
|
||||
# 'eco_type' : 'endstations.bernina_gps.GPS'},
|
||||
# 'SARES20-PROF142-M1' : {
|
||||
# 'alias' : 'Xeye',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'Mobile X-ray eye in Bernina hutch',
|
||||
# 'eco_type' : 'xdiagnostics.profile_monitors.Bernina_XEYE',
|
||||
# 'kwargs' : {'bshost':'sf-daqsync-01.psi.ch','bsport':11173},
|
||||
#
|
||||
# },
|
||||
# 'SLAAR21-LMOT' : {
|
||||
# 'alias' : 'LasExp',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Experiment laser optics',
|
||||
# 'eco_type' : 'loptics.bernina_experiment.Laser_Exp'},
|
||||
"SLAAR01-TSPL-EPL": {
|
||||
"alias": "phaseShifter",
|
||||
"z_und": 127,
|
||||
"desc": "Experiment laser phase shifter (Globi)",
|
||||
"eco_type": "devices_general.alvratiming.PhaseShifterAramis",
|
||||
},
|
||||
"SLAAR11-LMOT": {
|
||||
"alias": "laser",
|
||||
"z_und": 122,
|
||||
"desc": "Experiment laser hardware",
|
||||
"eco_type": "loptics.alvra_experiment.Laser_Exp",
|
||||
},
|
||||
# 'SLAAR11-LMOT' : {
|
||||
# 'alias' : 'palm_eo',
|
||||
# 'z_und' : 119,
|
||||
# 'desc' : 'PALM EO-sampling delay line',
|
||||
# 'eco_type' : 'xdiagnostics.palm.eo'},
|
||||
# 'http://sf-daq-4:10000' : {
|
||||
# 'alias' : 'DetJF',
|
||||
# 'z_und' : 125,
|
||||
# 'desc' : '4.5M Jungfrau detector',
|
||||
# 'eco_type' : 'devices_general.alvradetectors.DIAClient'},
|
||||
"SARES11-V": {
|
||||
"alias": "vacuum",
|
||||
"z_und": 127,
|
||||
"desc": "Prime vacuum system",
|
||||
"eco_type": "endstations.alvra_prime.vacuum",
|
||||
},
|
||||
"SLAAR11-LTIM01-EVR0": {
|
||||
"alias": "laserShutter",
|
||||
"z_und": 122,
|
||||
"desc": "Laser Shutter",
|
||||
"eco_type": "loptics.alvra_laser_shutter.laser_shutter",
|
||||
},
|
||||
# = dict(
|
||||
# alias = ''
|
||||
# z_und =
|
||||
# desc = ''},
|
||||
"SARES11-CMOV-SMA691110": {
|
||||
"alias": "_prism_gonio",
|
||||
"z_und": 127,
|
||||
"desc": "Prime laser prism gonio",
|
||||
"eco_type": "devices_general.smaract.SmarActRecord",
|
||||
"device": "prism",
|
||||
"axis": "gonio",
|
||||
},
|
||||
"SARES11-CMOV-SMA691111": {
|
||||
"alias": "_prism_trans",
|
||||
"z_und": 127,
|
||||
"desc": "Prime laser prism trans",
|
||||
"eco_type": "devices_general.smaract.SmarActRecord",
|
||||
"device": "prism",
|
||||
"axis": "trans",
|
||||
},
|
||||
"SARES11-CMOV-SMA691112": {
|
||||
"alias": "_prism_rot",
|
||||
"z_und": 127,
|
||||
"desc": "Prime laser prism rotation",
|
||||
"eco_type": "devices_general.smaract.SmarActRecord",
|
||||
"device": "prism", # a virtual stage for eco namespace
|
||||
"axis": "rot",
|
||||
}, # a axis of this virtual stage
|
||||
"SARES11-CMOV-SMA691113": {
|
||||
"alias": "_xmic_gon",
|
||||
"z_und": 127,
|
||||
"desc": "Prime microscope mirror gonio",
|
||||
"eco_type": "devices_general.smaract.SmarActRecord",
|
||||
},
|
||||
# no 'device' becauses its appended to other stage in
|
||||
# ..endstations/alvra_prime.py
|
||||
"SARES11-CMOV-SMA691114": {
|
||||
"alias": "_xmic_rot",
|
||||
"z_und": 127,
|
||||
"desc": "Prime microscope mirror rotation",
|
||||
"eco_type": "devices_general.smaract.SmarActRecord",
|
||||
},
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
from .bernina import *
|
||||
@@ -0,0 +1,22 @@
|
||||
from ..utilities.config import initFromConfigList
|
||||
from epics import PV
|
||||
from .config import components
|
||||
from .. import ecocnf
|
||||
from ..aliases import NamespaceCollection
|
||||
|
||||
itglobals = globals()
|
||||
|
||||
alias_namespaces = NamespaceCollection()
|
||||
|
||||
|
||||
for key, value in initFromConfigList(components, lazy=ecocnf.startup_lazy).items():
|
||||
globals()[key] = value
|
||||
|
||||
if not ecocnf.startup_lazy:
|
||||
try:
|
||||
for ta in value.alias.get_all():
|
||||
alias_namespaces.bernina.update(ta['alias'],ta['channel'],ta['channeltype'])
|
||||
except:
|
||||
pass
|
||||
alias_namespaces.bernina.store()
|
||||
|
||||
Executable
+191
@@ -0,0 +1,191 @@
|
||||
from .config import elog as _elog_info
|
||||
from ..utilities.elog import Elog as _Elog
|
||||
from ..utilities.elog import Screenshot as _Screenshot
|
||||
from ..utilities.config import loadConfig
|
||||
from epics import PV
|
||||
import sys, os
|
||||
|
||||
|
||||
from colorama import Fore as _color
|
||||
import traceback
|
||||
|
||||
elog = _Elog(
|
||||
_elog_info["url"],
|
||||
user="gac-bernina",
|
||||
screenshot_directory=_elog_info["screenshot_directory"],
|
||||
)
|
||||
screenshot = _Screenshot(screenshot_directory=_elog_info["screenshot_directory"])
|
||||
|
||||
########### configurations ########################
|
||||
currexp_file_path = "/sf/bernina/config/exp/current_experiment.json"
|
||||
if os.path.exists(currexp_file_path):
|
||||
exp_config = loadConfig(currexp_file_path)
|
||||
else:
|
||||
print("NB: Could not load experiment config in path %s ." % currexp_file_path)
|
||||
|
||||
########### GENERAL IMPLEMENTATIONS ##################
|
||||
from .config import components_old
|
||||
from ..utilities.utilities_instruments import initDeviceAliasList
|
||||
|
||||
dev, problems = initDeviceAliasList(components_old, lazy=True, verbose=True)
|
||||
|
||||
if 0:
|
||||
|
||||
def _attach_device(devDict, devId, args, kwargs):
|
||||
imp_p = devDict["eco_type"].split(sep=".")
|
||||
dev_alias = devDict["alias"]
|
||||
dev_alias = dev_alias[0].lower() + dev_alias[1:]
|
||||
eco_type_name = imp_p[-1]
|
||||
istr = "from .." + ".".join(imp_p[:-1]) + " import "
|
||||
istr += "%s as _%s" % (eco_type_name, eco_type_name)
|
||||
# print(istr)
|
||||
print(("Configuring %s " % (dev_alias)).ljust(25), end="")
|
||||
print(("(%s)" % (devId)).ljust(25), end="")
|
||||
error = None
|
||||
try:
|
||||
exec(istr)
|
||||
tdev = eval("_%s(Id='%s',*args,**kwargs)" % (eco_type_name, devId))
|
||||
tdev.name = dev_alias
|
||||
tdev._z_und = devDict["z_und"]
|
||||
globals().update([(dev_alias, tdev)])
|
||||
print((_color.GREEN + "OK" + _color.RESET).rjust(5))
|
||||
except Exception as e:
|
||||
print((_color.RED + "FAILED" + _color.RESET).rjust(5))
|
||||
print(sys.exc_info())
|
||||
error = e
|
||||
return error
|
||||
|
||||
break
|
||||
errors = []
|
||||
for device_Id in _aliases.keys():
|
||||
if "eco_type" in _aliases[device_Id].keys() and _aliases[device_Id]["eco_type"]:
|
||||
if "args" in _aliases[device_Id].keys() and _aliases[device_Id]["args"]:
|
||||
args = _aliases[device_Id]["args"]
|
||||
else:
|
||||
args = tuple()
|
||||
|
||||
if "kwargs" in _aliases[device_Id].keys() and _aliases[device_Id]["kwargs"]:
|
||||
kwargs = _aliases[device_Id]["kwargs"]
|
||||
else:
|
||||
kwargs = dict()
|
||||
|
||||
e = _attach_device(_aliases[device_Id], device_Id, args, kwargs)
|
||||
if e:
|
||||
errors.append((_aliases[device_Id]["alias"], e))
|
||||
|
||||
if len(errors) > 0:
|
||||
print("Found errors when configuring %s" % [te[0] for te in errors])
|
||||
if input("Would you like to see error traces? (y/n)") == "y":
|
||||
for error in errors:
|
||||
print("---> Error when configuring %s" % error[0])
|
||||
traceback.print_tb(error[1].__traceback__)
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
out = []
|
||||
with open(fina, "r") as f:
|
||||
done = False
|
||||
while not done:
|
||||
d = f.readline()
|
||||
if not d:
|
||||
done = True
|
||||
if len(d) > 0:
|
||||
if not d.isspace():
|
||||
if not d[0] == "#":
|
||||
out.append(d.strip())
|
||||
return out
|
||||
|
||||
from ..acquisition.bs_data import BStools
|
||||
from ..acquisition import scan as _scan
|
||||
from ..acquisition.ioxos_data import Ioxostools
|
||||
|
||||
channellist = dict(
|
||||
bernina_channel_list=parseChannelListFile(
|
||||
"/sf/bernina/config/channel_lists/default_channel_list"
|
||||
)
|
||||
)
|
||||
bsdaq = BStools(default_channel_list=channellist, default_file_path="%s")
|
||||
|
||||
channellistioxos = dict(
|
||||
bernina_channel_list=parseChannelListFile(
|
||||
"/sf/bernina/config/channel_lists/default_channel_list_ioxos"
|
||||
)
|
||||
)
|
||||
ioxosdaq = Ioxostools(default_channel_list=channellistioxos, default_file_path="%s")
|
||||
|
||||
# from eco.devices_general.detectors import JF_BS_writer
|
||||
# bsdaqJF = JF_BS_writer('bsdaqJF') d
|
||||
from eco.devices_general.detectors import DIAClient
|
||||
|
||||
bsdaqJF = DIAClient(
|
||||
"bsdaqJF", instrument="bernina", api_address="http://sf-daq-1:10000"
|
||||
)
|
||||
|
||||
try:
|
||||
bsdaqJF.pgroup = int(exp_config["pgroup"][1:])
|
||||
except:
|
||||
print("Could not set p group in bsdaqJF !!")
|
||||
|
||||
checkerPV = PV("SARFE10-PBPG050:HAMP-INTENSITY-CAL")
|
||||
|
||||
def checker_function(limits):
|
||||
cv = checkerPV.get()
|
||||
if cv > limits[0] and cv < limits[1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
checker = {}
|
||||
checker["checker_call"] = checker_function
|
||||
checker["args"] = [[100, 700]]
|
||||
checker["kwargs"] = {}
|
||||
checker["wait_time"] = 3
|
||||
|
||||
scansIoxos = _scan.Scans(
|
||||
data_base_dir="/sf/bernina/config/com/data/scan_data",
|
||||
scan_info_dir="/sf/bernina/config/com/data/scan_info",
|
||||
default_counters=[ioxosdaq],
|
||||
)
|
||||
scansJF = _scan.Scans(
|
||||
data_base_dir="scan_data",
|
||||
scan_info_dir="/sf/bernina/data/%s/res/scan_info" % exp_config["pgroup"],
|
||||
default_counters=[bsdaqJF],
|
||||
checker=checker,
|
||||
scan_directories=True,
|
||||
)
|
||||
scansBsreadLocal = _scan.Scans(
|
||||
data_base_dir="/sf/bernina/config/com/data/scan_data",
|
||||
scan_info_dir="/sf/bernina/config/com/data/scan_info",
|
||||
default_counters=[bsdaq],
|
||||
)
|
||||
|
||||
########### ADHOC IMPLEMENTED ########################
|
||||
bsdaqJF.gain_file = "/sf/bernina/data/p16582/res/gains_I0.h5"
|
||||
try:
|
||||
import glob
|
||||
|
||||
path = "/sf/bernina/data/p17295/res/JF_pedestal/pedestal_*_res.h5"
|
||||
list_of_files = glob.glob(
|
||||
"/sf/bernina/data/p17295/res/JF_pedestal/pedestal_*_res.h5"
|
||||
)
|
||||
latest_file = max(list_of_files, key=os.path.getctime)
|
||||
bsdaqJF.pede_file = latest_file
|
||||
except (Exception, ArithmeticError) as e:
|
||||
template = "An exception of type {0} occurred when trying to load lates JF files from {2}. Arguments:\n{1!r}"
|
||||
message = template.format(type(e).__name__, e.args, path)
|
||||
print(message)
|
||||
from ..timing.lasertiming import Lxt as _Lxt
|
||||
|
||||
lxt = _Lxt()
|
||||
|
||||
from ..xoptics.dcm import MonoEcolEnergy, EcolEnergy
|
||||
|
||||
monoEcol = MonoEcolEnergy("SAROP21-ODCM098")
|
||||
ecol = EcolEnergy("dummy")
|
||||
|
||||
if "eco_path" in list(exp_config.keys()):
|
||||
pass
|
||||
else:
|
||||
eco_path = "/sf/bernina/" + exp_config["pgroup"]
|
||||
Executable
+319
@@ -0,0 +1,319 @@
|
||||
# # New configuration of components:
|
||||
# components is an ordered list of
|
||||
# - name in parent package
|
||||
# - type, describing the python Class or factory function.
|
||||
# - arguments of that type args
|
||||
# - kwargs of that type
|
||||
|
||||
# # Conventions for the type
|
||||
# the call of type will try to pass a kwarg 'name' with the
|
||||
# name of the component, before only calling args and kwargs.
|
||||
# if arg or kwarg is of type eco.utilities.Component (dummy class)
|
||||
# this indicates that an earlier initialized object is used
|
||||
# (e.g. from same configuration).
|
||||
from ..utilities.config import Component, Alias, init_device, initFromConfigList
|
||||
|
||||
_eco_lazy_init = False
|
||||
|
||||
components = [
|
||||
# {
|
||||
# 'name' : 'device_alias_name',
|
||||
# 'type' : 'package.module.submodule:ClassOrFactory',
|
||||
# 'args' : ['all','the','requires','args'],
|
||||
# 'kwargs': {}
|
||||
# }
|
||||
{
|
||||
"name": "elog",
|
||||
"type": "eco.utilities.elog:Elog",
|
||||
"args": ["https://elog-gfa.psi.ch/Bernina"],
|
||||
"kwargs": {
|
||||
"user": "gac-bernina",
|
||||
"screenshot_directory": "/sf/bernina/config/screenshots",
|
||||
},
|
||||
},
|
||||
{
|
||||
"name": "screenshot",
|
||||
"type": "eco.utilities.elog:Screenshot",
|
||||
"args": [],
|
||||
"kwargs": {"screenshot_directory": "/sf/bernina/config/screenshots"},
|
||||
},
|
||||
{
|
||||
"name": "slitUnd",
|
||||
"type": "eco.xoptics.slits:SlitFourBlades",
|
||||
"args": ["SARFE10-OAPU044"],
|
||||
"kwargs": {},
|
||||
"desc": "Slit after Undulator",
|
||||
},
|
||||
{
|
||||
"name": "attFE",
|
||||
"type": "eco.xoptics.attenuator_aramis:AttenuatorAramis",
|
||||
"args": ["SARFE10-OATT053"],
|
||||
"kwargs": {},
|
||||
"desc": "Attenuator in Front End",
|
||||
},
|
||||
{
|
||||
"name": "profFE",
|
||||
"args": ["SARFE10-PPRM064"],
|
||||
"kwargs": {},
|
||||
"z_und": 64,
|
||||
"desc": "Profile monitor after Front End",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Pprm",
|
||||
},
|
||||
{
|
||||
"name": "profMirrAlv1",
|
||||
"args": ["SAROP11-PPRM066"],
|
||||
"kwargs": {},
|
||||
"z_und": 66,
|
||||
"desc": "Profile monitor after Alvra Mirror 1",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Pprm",
|
||||
},
|
||||
{
|
||||
"name": "slitSwitch",
|
||||
"z_und": 92,
|
||||
"desc": "Slit in Optics hutch after Photon switchyard and before Bernina optics",
|
||||
"type": "eco.xoptics.slits:SlitBlades",
|
||||
"args": ["SAROP21-OAPU092"],
|
||||
"kwargs": {},
|
||||
},
|
||||
{
|
||||
"name": "profMirr1",
|
||||
"args": ["SAROP21-PPRM094"],
|
||||
"kwargs": {},
|
||||
"z_und": 94,
|
||||
"desc": "Profile monitor after Mirror 1",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Pprm",
|
||||
},
|
||||
{
|
||||
"name": "mono",
|
||||
"args": ["SAROP21-ODCM098"],
|
||||
"kwargs": {},
|
||||
"z_und": 98,
|
||||
"desc": "DCM Monochromator",
|
||||
"type": "eco.xoptics.dcm:Double_Crystal_Mono",
|
||||
},
|
||||
{
|
||||
"name": "profMono",
|
||||
"args": ["SAROP21-PPRM102"],
|
||||
"kwargs": {},
|
||||
"z_und": 102,
|
||||
"desc": "Profile monitor after Monochromator",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Pprm",
|
||||
},
|
||||
{
|
||||
"name": "monOpt",
|
||||
"z_und": 133,
|
||||
"desc": "Intensity/position monitor after Optics hutch",
|
||||
"type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS",
|
||||
"args": ["SAROP21-PBPS133"],
|
||||
"kwargs": {"VME_crate": "SAROP21-CVME-PBPS1", "link": 9},
|
||||
},
|
||||
{
|
||||
"name": "profOpt",
|
||||
"args": ["SAROP21-PPRM133"],
|
||||
"kwargs": {},
|
||||
"z_und": 133,
|
||||
"desc": "Profile monitor after Optics hutch",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Pprm",
|
||||
},
|
||||
{
|
||||
"name": "att",
|
||||
"args": ["SAROP21-OATT135"],
|
||||
"kwargs": {},
|
||||
"z_und": 135,
|
||||
"desc": "Attenuator Bernina",
|
||||
"type": "eco.xoptics.attenuator_aramis:AttenuatorAramis",
|
||||
},
|
||||
{
|
||||
"name": "refLaser",
|
||||
"args": ["SAROP21-OLAS136"],
|
||||
"kwargs": {},
|
||||
"z_und": 136,
|
||||
"desc": "Bernina beamline reference laser before KBs",
|
||||
"type": "eco.xoptics.reflaser:RefLaser_Aramis",
|
||||
},
|
||||
{
|
||||
"name": "slitAtt",
|
||||
"args": ["SAROP21-OAPU136"],
|
||||
"kwargs": {},
|
||||
"z_und": 136,
|
||||
"desc": "Slits behind attenuator",
|
||||
"type": "eco.xoptics.slits:SlitPosWidth",
|
||||
},
|
||||
{
|
||||
"name": "monAtt",
|
||||
"args": ["SAROP21-PBPS138"],
|
||||
"z_und": 138,
|
||||
"desc": "Intensity/Position monitor after Attenuator",
|
||||
"type": "eco.xdiagnostics.intensity_monitors:SolidTargetDetectorPBPS",
|
||||
"kwargs": {"VME_crate": "SAROP21-CVME-PBPS2", "link": 9},
|
||||
},
|
||||
{
|
||||
"name": "detDio",
|
||||
"args": ["SAROP21-PDIO138"],
|
||||
"z_und": 138,
|
||||
"desc": "Diode digitizer for exp data",
|
||||
"type": "eco.devices_general.detectors:DiodeDigitizer",
|
||||
"kwargs": {"VME_crate": "SAROP21-CVME-PBPS2", "link": 9},
|
||||
},
|
||||
{
|
||||
"name": "profAtt",
|
||||
"args": ["SAROP21-PPRM138"],
|
||||
"kwargs": {},
|
||||
"z_und": 138,
|
||||
"desc": "Profile monitor after Attenuator",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Pprm",
|
||||
},
|
||||
{
|
||||
"name": "kbVer",
|
||||
"args": ["SAROP21-OKBV139"],
|
||||
"z_und": 139,
|
||||
"desc": "Vertically focusing Bernina KB mirror",
|
||||
"type": "eco.xoptics.KBver:KBver",
|
||||
"kwargs": {},
|
||||
},
|
||||
{
|
||||
"args": ["SAROP21-OKBH140"],
|
||||
"name": "kbHor",
|
||||
"z_und": 140,
|
||||
"desc": "Horizontally focusing Bernina KB mirror",
|
||||
"type": "eco.xoptics.KBhor:KBhor",
|
||||
"kwargs": {},
|
||||
},
|
||||
# {
|
||||
# 'args' : ['SARES22-GPS'],
|
||||
# 'name' : 'gps',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'General purpose station',
|
||||
# 'type' : 'eco.endstations.bernina_gps:GPS',
|
||||
# 'kwargs': {}
|
||||
# },
|
||||
{
|
||||
"args": [],
|
||||
"name": "xrd",
|
||||
"z_und": 142,
|
||||
"desc": "Xray diffractometer",
|
||||
"type": "eco.endstations.bernina_diffractometers:XRD",
|
||||
"kwargs": {'Id':"SARES21-XRD"},
|
||||
},
|
||||
{
|
||||
"args": ["SARES20-PROF142-M1"],
|
||||
"name": "xeye",
|
||||
"z_und": 142,
|
||||
"desc": "Mobile X-ray eye in Bernina hutch",
|
||||
"type": "eco.xdiagnostics.profile_monitors:Bernina_XEYE",
|
||||
"kwargs": {"bshost": "sf-daqsync-01.psi.ch", "bsport": 11173},
|
||||
},
|
||||
{
|
||||
"args": ["SLAAR02-TSPL-EPL"],
|
||||
"name": "phaseShifter",
|
||||
"z_und": 142,
|
||||
"desc": "Experiment laser phase shifter",
|
||||
"type": "eco.devices_general.timing:PhaseShifterAramis",
|
||||
"kwargs": {},
|
||||
},
|
||||
{
|
||||
"args": ["SLAAR21-LMOT"],
|
||||
"name": "las",
|
||||
"z_und": 142,
|
||||
"desc": "Experiment laser optics",
|
||||
"type": "eco.loptics.bernina_experiment:Laser_Exp",
|
||||
"kwargs": {},
|
||||
},
|
||||
{
|
||||
"args": ["SLAAR21-LTIM01-EVR0"],
|
||||
"name": "laserShutter",
|
||||
"z_und": 142,
|
||||
"desc": "Laser Shutter",
|
||||
"type": "eco.loptics.laser_shutter:laser_shutter",
|
||||
"kwargs": {},
|
||||
},
|
||||
{
|
||||
"args": ["/sf/bernina/config/channel_lists/default_channel_list_ioxos"],
|
||||
"name": "ioxos_channel_list",
|
||||
"desc": "ioxos channel list",
|
||||
"type": "eco.utilities.config:parseChannelListFile",
|
||||
"kwargs": {},
|
||||
},
|
||||
{
|
||||
"args": [],
|
||||
"name": "ioxosdaq",
|
||||
"z_und": 142,
|
||||
"desc": "ioxos acquisition",
|
||||
"type": "eco.acquisition.ioxos_data:Ioxostools",
|
||||
"kwargs": {"channel_list": Component("ioxos_channel_list")},
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
components_old = {
|
||||
"SARFE10-OPSH044": {
|
||||
"alias": "ShutUnd",
|
||||
"z_und": 44,
|
||||
"desc": "Photon shutter after Undulator",
|
||||
},
|
||||
"SARFE10-PBIG050": {
|
||||
"alias": "GasMon",
|
||||
"z_und": 50,
|
||||
"desc": "Gas Monitor Intensity",
|
||||
},
|
||||
"SARFE10-PBPS053": {
|
||||
"alias": "MonUnd",
|
||||
"z_und": 44,
|
||||
"desc": "Intensity position monitor after Undulator",
|
||||
},
|
||||
"SARFE10-SBST060": {
|
||||
"alias": "ShutFE",
|
||||
"z_und": 60,
|
||||
"desc": "Photon shutter in the end of Front End",
|
||||
},
|
||||
"SAROP11-OOMH064": {
|
||||
"alias": "MirrAlv1",
|
||||
"z_und": 64,
|
||||
"desc": "Horizontal mirror Alvra 1",
|
||||
},
|
||||
"SAROP21-OOMV092": {
|
||||
"alias": "Mirr1",
|
||||
"z_und": 92,
|
||||
"desc": "Vertical offset Mirror 1",
|
||||
},
|
||||
"SAROP21-OOMV096": {
|
||||
"alias": "Mirr2",
|
||||
"z_und": 96,
|
||||
"desc": "Vertical offset mirror 2",
|
||||
},
|
||||
"SAROP21-PSCR097": {
|
||||
"alias": "ProfMirr2",
|
||||
"z_und": 97,
|
||||
"desc": "Profile Monitor after Mirror 2",
|
||||
},
|
||||
"SAROP21-OPPI103": {"alias": "Pick", "z_und": 103, "desc": "X-ray pulse picker"},
|
||||
"SAROP21-BST114": {
|
||||
"alias": "ShutOpt",
|
||||
"z_und": 114,
|
||||
"desc": "Shutter after Optics hutch",
|
||||
},
|
||||
"SAROP21-PALM134": {
|
||||
"alias": "TimTof",
|
||||
"z_und": 134,
|
||||
"desc": "Timing diagnostics THz streaking/TOF",
|
||||
},
|
||||
"SAROP21-PSEN135": {
|
||||
"alias": "TimRef",
|
||||
"z_und": 135,
|
||||
"desc": "Timing diagnostics spectral encoding of ref. index change",
|
||||
}
|
||||
# 'SLAAR21-LMOT' : {
|
||||
# 'alias' : 'Palm',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'Streaking arrival time monitor',
|
||||
# 'eco_type' : 'timing.palm.Palm'},
|
||||
# 'SLAAR21-LMOT' : {
|
||||
# 'alias' : 'Psen',
|
||||
# 'z_und' : 142,
|
||||
# 'desc' : 'Streaking arrival time monitor',
|
||||
# 'eco_type' : 'timing.psen.Psen'}
|
||||
# = dict(
|
||||
# alias = ''
|
||||
# z_und =
|
||||
# desc = ''},
|
||||
}
|
||||
@@ -5,11 +5,12 @@ from .utilities import Changer
|
||||
|
||||
|
||||
def _keywordChecker(kw_key_list_tups):
|
||||
for tkw,tkey,tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s"%(tkw,tlist)
|
||||
for tkw, tkey, tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s" % (tkw, tlist)
|
||||
|
||||
|
||||
class ValueRdback:
|
||||
def __init__(self,pv_value, pv_readback, name=None, elog=None):
|
||||
def __init__(self, pv_value, pv_readback, name=None, elog=None):
|
||||
self.Id = pvname
|
||||
self._PV_value = PV(pv_value)
|
||||
self._PV_readback = PV(pv_readback)
|
||||
@@ -17,67 +18,67 @@ class ValueRdback:
|
||||
self.name = name
|
||||
self._currentChange = None
|
||||
|
||||
|
||||
# Conventional methods and properties for all Adjustable objects
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
""" Adjustable convention"""
|
||||
|
||||
def changer(value):
|
||||
self._status = self._motor.move(\
|
||||
value, ignore_limits=(not check),
|
||||
wait=True)
|
||||
self._status = self._motor.move(value, ignore_limits=(not check), wait=True)
|
||||
self._status_message = _status_messages[self._status]
|
||||
if not self._status==0:
|
||||
if not self._status == 0:
|
||||
print(self._status_message)
|
||||
|
||||
# changer = lambda value: self._motor.move(\
|
||||
# value, ignore_limits=(not check),
|
||||
# wait=True)
|
||||
# changer = lambda value: self._motor.move(\
|
||||
# value, ignore_limits=(not check),
|
||||
# wait=True)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=self._motor.stop)
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=self._motor.stop,
|
||||
)
|
||||
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
try:
|
||||
self._currentChange.stop()
|
||||
self._currentChange.stop()
|
||||
except:
|
||||
self._motor.stop()
|
||||
self._motor.stop()
|
||||
pass
|
||||
|
||||
|
||||
def get_current_value(self):
|
||||
""" Adjustable convention"""
|
||||
return self._PV_readback.get()
|
||||
|
||||
def set_current_value(self,value):
|
||||
def set_current_value(self, value):
|
||||
""" Adjustable convention"""
|
||||
print('not implemented: depends on a defined offset')
|
||||
print("not implemented: depends on a defined offset")
|
||||
|
||||
def get_precision(self):
|
||||
""" Adjustable convention"""
|
||||
if isinstance(self._precision,PV):
|
||||
if isinstance(self._precision, PV):
|
||||
return self._precision.get()
|
||||
else:
|
||||
return self._precision
|
||||
|
||||
def set_precision(self,value):
|
||||
def set_precision(self, value):
|
||||
""" Adjustable convention"""
|
||||
if isinstance(self._precision,PV):
|
||||
if isinstance(self._precision, PV):
|
||||
self._precision.put(value)
|
||||
else:
|
||||
self._precision = value
|
||||
|
||||
precision = property(get_precision,set_precision)
|
||||
precision = property(get_precision, set_precision)
|
||||
|
||||
def set_speed(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def get_speed(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def set_speedMax(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
@@ -85,51 +86,45 @@ class ValueRdback:
|
||||
def get_moveDone(self):
|
||||
""" Adjustable convention"""
|
||||
""" 0: moving 1: move done"""
|
||||
return PV(str(self.Id+".DMOV")).value
|
||||
|
||||
def set_limits(self, values, posType='user', relative_to_present=False):
|
||||
return PV(str(self.Id + ".DMOV")).value
|
||||
|
||||
def set_limits(self, values, posType="user", relative_to_present=False):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
ll_name, hl_name = 'LLM', 'HLM'
|
||||
if posType is 'dial':
|
||||
ll_name, hl_name = 'DLLM', 'DHLM'
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
ll_name, hl_name = "LLM", "HLM"
|
||||
if posType is "dial":
|
||||
ll_name, hl_name = "DLLM", "DHLM"
|
||||
if relative_to_present:
|
||||
v = self.get_current_value(posType=posType)
|
||||
values = [v-values[0],v-values[1]]
|
||||
self._motor.put(ll_name,values[0])
|
||||
self._motor.put(hl_name,values[1])
|
||||
values = [v - values[0], v - values[1]]
|
||||
self._motor.put(ll_name, values[0])
|
||||
self._motor.put(hl_name, values[1])
|
||||
|
||||
def get_limits(self, posType='user'):
|
||||
def get_limits(self, posType="user"):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
ll_name, hl_name = 'LLM', 'HLM'
|
||||
if posType is 'dial':
|
||||
ll_name, hl_name = 'DLLM', 'DHLM'
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
ll_name, hl_name = "LLM", "HLM"
|
||||
if posType is "dial":
|
||||
ll_name, hl_name = "DLLM", "DHLM"
|
||||
return self._motor.get(ll_name), self._motor.get(hl_name)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# return string with motor value as variable representation
|
||||
def __str__(self):
|
||||
return "Motor is at %s"%self.wm()
|
||||
|
||||
return "Motor is at %s" % self.wm()
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __call__(self,value):
|
||||
def __call__(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
|
||||
|
||||
|
||||
class ChangerOld:
|
||||
def __init__(self, target=None, parent=None, mover=None, hold=True, stopper=None):
|
||||
self.target = target
|
||||
self._mover = mover
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._mover,args=(target,))
|
||||
self._thread = Thread(target=self._mover, args=(target,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
@@ -141,14 +136,12 @@ class ChangerOld:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._isAlive:
|
||||
return 'changing'
|
||||
return "changing"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -16,19 +16,21 @@ from ..acquisition.utilities import Acquisition
|
||||
|
||||
try:
|
||||
import sys, os
|
||||
|
||||
tpath = os.path.dirname(__file__)
|
||||
sys.path.insert(0,os.path.join(tpath,'../../detector_integration_api'))
|
||||
#ask Leo(2018.03.14):
|
||||
#sys.path.insert(0,os.path.join(tpath,'../../jungfrau_utils'))
|
||||
sys.path.insert(0, os.path.join(tpath, "../../detector_integration_api"))
|
||||
# ask Leo(2018.03.14):
|
||||
# sys.path.insert(0,os.path.join(tpath,'../../jungfrau_utils'))
|
||||
from detector_integration_api import DetectorIntegrationClient
|
||||
except:
|
||||
print('NB: detector integration could not be imported!')
|
||||
|
||||
print("NB: detector integration could not be imported!")
|
||||
|
||||
|
||||
_cameraArrayTypes = ["monochrome", "rgb"]
|
||||
|
||||
_cameraArrayTypes = ['monochrome','rgb']
|
||||
|
||||
class CameraCA:
|
||||
def __init__(self, pvname, cameraArrayType='monochrome',elog=None):
|
||||
def __init__(self, pvname, cameraArrayType="monochrome", elog=None):
|
||||
self.Id = pvname
|
||||
self.isBS = False
|
||||
self.px_height = None
|
||||
@@ -37,41 +39,43 @@ class CameraCA:
|
||||
|
||||
def get_px_height(self):
|
||||
if not self.px_height:
|
||||
self.px_height = caget(self.Id + ':HEIGHT')
|
||||
self.px_height = caget(self.Id + ":HEIGHT")
|
||||
return self.px_height
|
||||
|
||||
def get_px_width(self):
|
||||
if not self.px_width:
|
||||
self.px_width = caget(self.Id + ':WIDTH')
|
||||
self.px_width = caget(self.Id + ":WIDTH")
|
||||
return self.px_width
|
||||
|
||||
def get_data(self):
|
||||
w = self.get_px_width()
|
||||
h = self.get_px_height()
|
||||
numpix = int(caget(self.Id+':FPICTURE.NORD'))
|
||||
i = caget(self.Id+':FPICTURE', count=numpix)
|
||||
return i.reshape(h,w)
|
||||
numpix = int(caget(self.Id + ":FPICTURE.NORD"))
|
||||
i = caget(self.Id + ":FPICTURE", count=numpix)
|
||||
return i.reshape(h, w)
|
||||
|
||||
def record_images(self,fina,N_images,sleeptime=0.2):
|
||||
with h5py.File(fina,'w') as f:
|
||||
def record_images(self, fina, N_images, sleeptime=0.2):
|
||||
with h5py.File(fina, "w") as f:
|
||||
d = []
|
||||
for n in range(N_images):
|
||||
d.append(self.get_data())
|
||||
sleep(sleeptime)
|
||||
f['images'] = np.asarray(d)
|
||||
f["images"] = np.asarray(d)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
def gui(self, guiType="xdm"):
|
||||
""" Adjustable convention"""
|
||||
cmd = ['caqtdm','-macro']
|
||||
cmd = ["caqtdm", "-macro"]
|
||||
|
||||
cmd.append('\"NAME=%s,CAMNAME=%s\"'%(self.Id, self.Id))
|
||||
cmd.append('/sf/controls/config/qt/Camera/CameraMiniView.ui')
|
||||
return subprocess.Popen(' '.join(cmd),shell=True)
|
||||
cmd.append('"NAME=%s,CAMNAME=%s"' % (self.Id, self.Id))
|
||||
cmd.append("/sf/controls/config/qt/Camera/CameraMiniView.ui")
|
||||
return subprocess.Popen(" ".join(cmd), shell=True)
|
||||
|
||||
|
||||
# /sf/controls/config/qt/Camera/CameraMiniView.ui" with macro "NAME=SAROP21-PPRM138,CAMNAME=SAROP21-PPRM138
|
||||
|
||||
#/sf/controls/config/qt/Camera/CameraMiniView.ui" with macro "NAME=SAROP21-PPRM138,CAMNAME=SAROP21-PPRM138
|
||||
|
||||
class CameraBS:
|
||||
def __init__(self,host=None,port=None,elog=None):
|
||||
def __init__(self, host=None, port=None, elog=None):
|
||||
self._stream_host = host
|
||||
self._stream_port = port
|
||||
|
||||
@@ -80,40 +84,48 @@ class CameraBS:
|
||||
if self._instance_id not in client.get_server_info()["active_instances"]:
|
||||
raise ValueError("Requested pipeline is not running.")
|
||||
|
||||
def get_images(self,N_images):
|
||||
def get_images(self, N_images):
|
||||
data = []
|
||||
with source(host=self._stream_host, port=self._stream_port, mode=SUB) as input_stream:
|
||||
with source(
|
||||
host=self._stream_host, port=self._stream_port, mode=SUB
|
||||
) as input_stream:
|
||||
input_stream.connect()
|
||||
|
||||
|
||||
for n in range(N_images):
|
||||
data.append(input_stream.receive().data.data['image'].value)
|
||||
data.append(input_stream.receive().data.data["image"].value)
|
||||
return data
|
||||
|
||||
def record_images(self,fina,N_images,dsetname='images'):
|
||||
def record_images(self, fina, N_images, dsetname="images"):
|
||||
ds = None
|
||||
with h5py.File(fina,'w') as f:
|
||||
with source(host=self._stream_host, port=self._stream_port, mode=SUB) as input_stream:
|
||||
with h5py.File(fina, "w") as f:
|
||||
with source(
|
||||
host=self._stream_host, port=self._stream_port, mode=SUB
|
||||
) as input_stream:
|
||||
|
||||
input_stream.connect()
|
||||
|
||||
|
||||
for n in range(N_images):
|
||||
image = input_stream.receive().data.data['image'].value
|
||||
image = input_stream.receive().data.data["image"].value
|
||||
if not ds:
|
||||
ds = f.create_dataset(dsetname,dtype=image.dtype, shape=(N_images,)+image.shape)
|
||||
ds[n,:,:] = image
|
||||
ds = f.create_dataset(
|
||||
dsetname, dtype=image.dtype, shape=(N_images,) + image.shape
|
||||
)
|
||||
ds[n, :, :] = image
|
||||
|
||||
|
||||
class FeDigitizer:
|
||||
def __init__(self,Id,elog=None):
|
||||
def __init__(self, Id, elog=None):
|
||||
self.Id = Id
|
||||
self.gain = EnumWrapper(Id+'-WD-gain')
|
||||
self._bias = PV(Id+'-HV_SET')
|
||||
self.gain = EnumWrapper(Id + "-WD-gain")
|
||||
self._bias = PV(Id + "-HV_SET")
|
||||
self.channels = [
|
||||
Id+'-BG-DATA',
|
||||
Id+'-BG-DRS_TC',
|
||||
Id+'-BG-PULSEID-valid',
|
||||
Id+'-DATA',
|
||||
Id+'-DRS_TC',
|
||||
Id+'-PULSEID-valid']
|
||||
Id + "-BG-DATA",
|
||||
Id + "-BG-DRS_TC",
|
||||
Id + "-BG-PULSEID-valid",
|
||||
Id + "-DATA",
|
||||
Id + "-DRS_TC",
|
||||
Id + "-PULSEID-valid",
|
||||
]
|
||||
|
||||
def set_bias(self, value):
|
||||
self._bias.put(value)
|
||||
@@ -121,17 +133,13 @@ class FeDigitizer:
|
||||
def get_bias(self):
|
||||
return self._bias.value
|
||||
|
||||
|
||||
class DiodeDigitizer:
|
||||
def __init__(self,Id,VME_crate=None,link=None,
|
||||
ch_0=7,ch_1=8, elog=None):
|
||||
def __init__(self, Id, VME_crate=None, link=None, ch_0=7, ch_1=8, elog=None):
|
||||
self.Id = Id
|
||||
if VME_crate:
|
||||
self.diode_0 = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_0))
|
||||
self.diode_1 = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_1))
|
||||
|
||||
|
||||
|
||||
|
||||
self.diode_0 = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_0))
|
||||
self.diode_1 = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_1))
|
||||
|
||||
|
||||
# class JF:
|
||||
@@ -142,21 +150,21 @@ class DiodeDigitizer:
|
||||
# self.Id = Id
|
||||
# self.api_address = self.Id
|
||||
# self.client = DetectorIntegrationClient(self.Id)
|
||||
#
|
||||
#
|
||||
# def reset(self):
|
||||
# self.client.reset()
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def get_status(self):
|
||||
# status = self.client.get_status()
|
||||
# return status
|
||||
#
|
||||
#
|
||||
# def get_config(self):
|
||||
# config = self.client.get_config()
|
||||
# return config
|
||||
#
|
||||
#
|
||||
# def set_config(self, pedestal_fname = '/sf/alvra/data/res/p16581/pedestal_20171210_1628_res.h5/', fname = "/sf/alvra/data/raw/p16581/JF.h5", N = 1000):
|
||||
#
|
||||
#
|
||||
# self.reset()
|
||||
# self.detector_config = {
|
||||
# "timing": "trigger",
|
||||
@@ -164,15 +172,15 @@ class DiodeDigitizer:
|
||||
# "delay" : 0.001992, # this is the magic aldo number
|
||||
# "frames" : 1,
|
||||
# "cycles": N}
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# self.writer_config = {
|
||||
# "output_file": fname,
|
||||
# "process_uid": 16581,
|
||||
# "process_gid": 16581,
|
||||
# "dataset_name": "jungfrau/data",
|
||||
# "n_messages": N}
|
||||
#
|
||||
#
|
||||
# self.backend_config = {
|
||||
# "n_frames": N,
|
||||
# "gain_corrections_filename": "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
@@ -180,18 +188,18 @@ class DiodeDigitizer:
|
||||
# "pede_corrections_filename": pedestal_fname,
|
||||
# "pede_corrections_dataset": "gains",
|
||||
# "activate_corrections_preview": True}
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# DetectorIntegrationClient.set_config(self,self.writer_config, self.backend_config, self.detector_config)
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def record(self,file_name,Npulses):
|
||||
# self.detector_config.update(dict(cycles=Npulses))
|
||||
# self.writer_config.update(dict(output_file=file_name))
|
||||
# self.reset()
|
||||
# DetectorIntegrationClient.set_config(self,self.writer_config, self.backend_config, self.detector_config)
|
||||
# self.client.start()
|
||||
#
|
||||
#
|
||||
# def check_running(self,time_interval=.5):
|
||||
# cfg = self.get_config()
|
||||
# running = False
|
||||
@@ -201,7 +209,7 @@ class DiodeDigitizer:
|
||||
# break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
#
|
||||
#
|
||||
# def check_still_running(self,time_interval=.5):
|
||||
# cfg = self.get_config()
|
||||
# running = True
|
||||
@@ -211,23 +219,23 @@ class DiodeDigitizer:
|
||||
# break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
#
|
||||
#
|
||||
# def start(self):
|
||||
# self.client.start()
|
||||
# print("start acquisition")
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def stop(self):
|
||||
# self.client.stop()
|
||||
# print("stop acquisition")
|
||||
# print("stop acquisition")
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def config_and_start_test(self):
|
||||
# self.reset()
|
||||
# self.set_config()
|
||||
# self.start()
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def acquire(self,file_name=None,Npulses=100):
|
||||
# file_name += '_JF4p5M.h5'
|
||||
# def acquire():
|
||||
@@ -238,18 +246,16 @@ class DiodeDigitizer:
|
||||
# self.client.start()
|
||||
# self.check_running()
|
||||
# self.check_still_running()
|
||||
#
|
||||
#
|
||||
# return Acquisition(acquire=acquire,acquisition_kwargs={'file_names':[file_name], 'Npulses':Npulses},hold=False)
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
#
|
||||
# def wait_done(self):
|
||||
# self.check_running()
|
||||
# self.check_still_running()
|
||||
|
||||
|
||||
|
||||
|
||||
# def parseChannelListFile(fina):
|
||||
# out = []
|
||||
# with open(fina,'r') as f:
|
||||
@@ -267,7 +273,7 @@ class DiodeDigitizer:
|
||||
|
||||
# class DIAClient:
|
||||
# def __init__(self, Id, api_address = "http://sf-daq-2:10000"):
|
||||
# self._api_address = api_address
|
||||
# self._api_address = api_address
|
||||
# self.client = DetectorIntegrationClient(api_address)
|
||||
# print("\nDetector Integration API on %s" % api_address)
|
||||
# # No pgroup by default
|
||||
@@ -277,11 +283,11 @@ class DiodeDigitizer:
|
||||
# self.pede_file = ""
|
||||
# self.gain_file = ""
|
||||
# self.update_config()
|
||||
#
|
||||
#
|
||||
# def update_config(self, ):
|
||||
# self.writer_config = {
|
||||
# "output_file": "/sf/alvra/data/raw/p%d/test_data.h5" % self.pgroup,
|
||||
# "user_id": self.pgroup,
|
||||
# "output_file": "/sf/alvra/data/raw/p%d/test_data.h5" % self.pgroup,
|
||||
# "user_id": self.pgroup,
|
||||
# "n_frames": self.n_frames,
|
||||
# "general/user": str(self.pgroup),
|
||||
# "general/process": __name__,
|
||||
@@ -289,43 +295,43 @@ class DiodeDigitizer:
|
||||
# "general/instrument": self.jf_name,
|
||||
# # "general/correction": "test"
|
||||
# }
|
||||
#
|
||||
#
|
||||
# self.backend_config = {
|
||||
# "n_frames": self.n_frames,
|
||||
# "bit_depth": 16,
|
||||
# "gain_corrections_filename": self.gain_file, # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
# #"gain_corrections_dataset": "gains",
|
||||
# #"pede_corrections_filename": "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
# #"pede_corrections_dataset": "gains",
|
||||
# #"pede_mask_dataset": "pixel_mask",
|
||||
# "n_frames": self.n_frames,
|
||||
# "bit_depth": 16,
|
||||
# "gain_corrections_filename": self.gain_file, # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
# #"gain_corrections_dataset": "gains",
|
||||
# #"pede_corrections_filename": "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
# #"pede_corrections_dataset": "gains",
|
||||
# #"pede_mask_dataset": "pixel_mask",
|
||||
# #"activate_corrections_preview": True,
|
||||
# "is_HG0": True
|
||||
# }
|
||||
#
|
||||
#
|
||||
# if self.pede_file != "":
|
||||
# self.backend_config["gain_corrections_filename"] = self.gain_file # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
# self.backend_config["gain_corrections_filename"] = self.gain_file # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
# self.backend_config["gain_corrections_dataset"] = "gains"
|
||||
# self.backend_config["pede_corrections_filename"] = self.pede_file # "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
# self.backend_config["pede_corrections_filename"] = self.pede_file # "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
# self.backend_config["pede_corrections_dataset"] = "gains"
|
||||
# self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
# self.backend_config["activate_corrections_preview"] = True
|
||||
#
|
||||
#
|
||||
# self.detector_config = {
|
||||
# "timing": "trigger",
|
||||
# "exptime": 0.000005,
|
||||
# "timing": "trigger",
|
||||
# "exptime": 0.000005,
|
||||
# "cycles": self.n_frames,
|
||||
# #"delay" : 0.001992,
|
||||
# "frames" : 1,
|
||||
# "dr": 16,
|
||||
# }
|
||||
#
|
||||
#
|
||||
# # Not needed anymore?
|
||||
# #default_channels_list = parseChannelListFile(
|
||||
# # '/sf/alvra/config/com/channel_lists/default_channel_list')
|
||||
#
|
||||
#
|
||||
# self.bsread_config = {
|
||||
# 'output_file': '/sf/alvra/data/raw/p%d/test_bsread.h5' % self.pgroup,
|
||||
# 'user_id': self.pgroup,
|
||||
# 'output_file': '/sf/alvra/data/raw/p%d/test_bsread.h5' % self.pgroup,
|
||||
# 'user_id': self.pgroup,
|
||||
# "general/user": str(self.pgroup),
|
||||
# "general/process": __name__,
|
||||
# "general/created": str(datetime.now()),
|
||||
@@ -334,29 +340,29 @@ class DiodeDigitizer:
|
||||
# #'channels': default_channels_list
|
||||
# }
|
||||
# # self.default_channels_list = jungfrau_utils.load_default_channel_list()
|
||||
#
|
||||
#
|
||||
# def reset(self):
|
||||
# self.client.reset()
|
||||
# #pass
|
||||
#
|
||||
#
|
||||
# def get_status(self):
|
||||
# return self.client.get_status()
|
||||
#
|
||||
#
|
||||
# def get_config(self):
|
||||
# config = self.client.get_config()
|
||||
# return config
|
||||
#
|
||||
#
|
||||
# def set_pgroup(self, pgroup):
|
||||
# self.pgroup = pgroup
|
||||
# self.update_config()
|
||||
#
|
||||
#
|
||||
# def set_bs_channels(self, ):
|
||||
# print("Please update /sf/alvra/config/com/channel_lists/default_channel_list and restart all services on the DAQ server")
|
||||
#
|
||||
#
|
||||
# def set_config(self):
|
||||
# self.reset()
|
||||
# self.client.set_config({"writer": self.writer_config, "backend": self.backend_config, "detector": self.detector_config, "bsread": self.bsread_config})
|
||||
#
|
||||
#
|
||||
# def check_still_running(self, time_interval=.5):
|
||||
# cfg = self.get_config()
|
||||
# running = True
|
||||
@@ -369,45 +375,45 @@ class DiodeDigitizer:
|
||||
# # break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
#
|
||||
#
|
||||
# def take_pedestal(self, n_frames, analyze=True, n_bad_modules=0, update_config=True):
|
||||
# import jungfrau_utils as ju
|
||||
# directory = '/sf/alvra/data/raw/p%d/' % self.pgroup
|
||||
# filename = "pedestal_%s.h5" % datetime.now().strftime("%Y%m%d_%H%M")
|
||||
# ju.jungfrau_run_pedestals.run(self._api_address, filename, directory, self.pgroup, 0.1, self.detector_config["exptime"],
|
||||
# ju.jungfrau_run_pedestals.run(self._api_address, filename, directory, self.pgroup, 0.1, self.detector_config["exptime"],
|
||||
# n_frames, 1, analyze, n_bad_modules)
|
||||
#
|
||||
#
|
||||
# if update_config:
|
||||
# self.pede_file = filename.replace("raw/", "res/").replace(".h5", "_res.h5")
|
||||
# print("Pedestal file updated to %s" % self.pede_file)
|
||||
# return self.pede_file
|
||||
#
|
||||
#
|
||||
# def start(self):
|
||||
# self.client.start()
|
||||
# print("start acquisition")
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def stop(self):
|
||||
# self.client.stop()
|
||||
# print("stop acquisition")
|
||||
# print("stop acquisition")
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def config_and_start_test(self):
|
||||
# self.reset()
|
||||
# self.set_config()
|
||||
# self.start()
|
||||
# pass
|
||||
#
|
||||
#
|
||||
# def wait_for_status(self,*args,**kwargs):
|
||||
# return self.client.wait_for_status(*args,**kwargs)
|
||||
#
|
||||
#
|
||||
# def acquire(self, file_name=None, Npulses=100, JF_factor=1, bsread_padding=0):
|
||||
# """
|
||||
# JF_factor?
|
||||
# bsread_padding?
|
||||
# """
|
||||
# file_rootdir = '/sf/alvra/data/raw/p%d/' % self.pgroup
|
||||
#
|
||||
#
|
||||
# if file_name is None:
|
||||
# print("Not saving any data, as file_name is not set")
|
||||
# file_name_JF = "/dev/null"
|
||||
@@ -415,10 +421,10 @@ class DiodeDigitizer:
|
||||
# else:
|
||||
# file_name_JF = file_rootdir +file_name + '_JF4p5M.h5'
|
||||
# file_name_bsread = file_rootdir + file_name + '.h5'
|
||||
#
|
||||
#
|
||||
# if self.pgroup == 0:
|
||||
# raise ValuepError("Please use set_pgroup() to set a pgroup value.")
|
||||
#
|
||||
#
|
||||
# def acquire():
|
||||
# self.n_frames = Npulses * JF_factor
|
||||
# self.update_config()
|
||||
@@ -434,13 +440,13 @@ class DiodeDigitizer:
|
||||
# 'output_file':file_name_bsread,
|
||||
# # 'Npulses': Npulses + bsread_padding
|
||||
# })
|
||||
#
|
||||
#
|
||||
# self.reset()
|
||||
# self.set_config()
|
||||
# print(self.get_config())
|
||||
# self.client.start()
|
||||
# done = False
|
||||
#
|
||||
#
|
||||
# while not done:
|
||||
# stat = self.get_status()
|
||||
# if stat['status'] =='IntegrationStatus.FINISHED':
|
||||
@@ -452,17 +458,18 @@ class DiodeDigitizer:
|
||||
# if stat['status'] == 'IntegrationStatus.DETECTOR_STOPPED':
|
||||
# done = True
|
||||
# sleep(.1)
|
||||
#
|
||||
#
|
||||
# return Acquisition(acquire=acquire, acquisition_kwargs={'file_names': [file_name_bsread, file_name_JF], 'Npulses': Npulses},hold=False)
|
||||
#
|
||||
#
|
||||
# def wait_done(self):
|
||||
# self.check_running()
|
||||
# self.check_still_running()
|
||||
|
||||
|
||||
class DIAClient:
|
||||
def __init__(self, Id, instrument=None, api_address = None, jf_name=None):
|
||||
def __init__(self, Id, instrument=None, api_address=None, jf_name=None):
|
||||
self.Id = Id
|
||||
self._api_address = api_address
|
||||
self._api_address = api_address
|
||||
self.client = DetectorIntegrationClient(api_address)
|
||||
print("\nDetector Integration API on %s" % api_address)
|
||||
# No pgroup by default
|
||||
@@ -476,11 +483,11 @@ class DIAClient:
|
||||
print("ERROR: please configure the instrument parameter in DIAClient")
|
||||
self.update_config()
|
||||
|
||||
|
||||
def update_config(self, ):
|
||||
def update_config(self,):
|
||||
self.writer_config = {
|
||||
"output_file": "/sf/%s/data/p%d/raw/test_data.h5" % (self.instrument, self.pgroup),
|
||||
"user_id": self.pgroup,
|
||||
"output_file": "/sf/%s/data/p%d/raw/test_data.h5"
|
||||
% (self.instrument, self.pgroup),
|
||||
"user_id": self.pgroup,
|
||||
"n_frames": self.n_frames,
|
||||
"general/user": str(self.pgroup),
|
||||
"general/process": __name__,
|
||||
@@ -490,22 +497,30 @@ class DIAClient:
|
||||
}
|
||||
|
||||
self.backend_config = {
|
||||
"n_frames": self.n_frames,
|
||||
"bit_depth": 16,
|
||||
"gain_corrections_filename": self.gain_file, # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
#"gain_corrections_dataset": "gains",
|
||||
#"pede_corrections_filename": "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
#"pede_corrections_dataset": "gains",
|
||||
#"pede_mask_dataset": "pixel_mask",
|
||||
#"activate_corrections_preview": True,
|
||||
"n_frames": self.n_frames,
|
||||
"bit_depth": 16,
|
||||
"gain_corrections_filename": self.gain_file, # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
# "gain_corrections_dataset": "gains",
|
||||
# "pede_corrections_filename": "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
# "pede_corrections_dataset": "gains",
|
||||
# "pede_mask_dataset": "pixel_mask",
|
||||
# "activate_corrections_preview": True,
|
||||
# FIXME: HARDCODED!!!
|
||||
"is_HG0": False
|
||||
"is_HG0": False,
|
||||
}
|
||||
|
||||
if self.pede_file != "":
|
||||
self.backend_config["gain_corrections_filename"] = self.gain_file # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
self.backend_config[
|
||||
"gain_corrections_filename"
|
||||
] = (
|
||||
self.gain_file
|
||||
) # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
self.backend_config["gain_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_corrections_filename"] = self.pede_file # "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
self.backend_config[
|
||||
"pede_corrections_filename"
|
||||
] = (
|
||||
self.pede_file
|
||||
) # "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
self.backend_config["pede_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["activate_corrections_preview"] = True
|
||||
@@ -518,22 +533,22 @@ class DIAClient:
|
||||
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
|
||||
# FIXME: HARDCODED
|
||||
"exptime": 0.000005,
|
||||
# FIXME: HARDCODED
|
||||
"exptime": 0.000005,
|
||||
"cycles": self.n_frames,
|
||||
#"delay" : 0.001992,
|
||||
"frames" : 1,
|
||||
# "delay" : 0.001992,
|
||||
"frames": 1,
|
||||
"dr": 16,
|
||||
}
|
||||
|
||||
|
||||
# Not needed anymore?
|
||||
#default_channels_list = parseChannelListFile(
|
||||
# default_channels_list = parseChannelListFile(
|
||||
# '/sf/alvra/config/com/channel_lists/default_channel_list')
|
||||
|
||||
self.bsread_config = {
|
||||
'output_file': '/sf/%s/data/p%d/raw/test_bsread.h5' % (self.instrument, self.pgroup),
|
||||
'user_id': self.pgroup,
|
||||
"output_file": "/sf/%s/data/p%d/raw/test_bsread.h5"
|
||||
% (self.instrument, self.pgroup),
|
||||
"user_id": self.pgroup,
|
||||
"general/user": str(self.pgroup),
|
||||
"general/process": __name__,
|
||||
"general/created": str(datetime.now()),
|
||||
@@ -541,11 +556,12 @@ class DIAClient:
|
||||
#'Npulses':100,
|
||||
#'channels': default_channels_list
|
||||
}
|
||||
# self.default_channels_list = jungfrau_utils.load_default_channel_list()
|
||||
|
||||
# self.default_channels_list = jungfrau_utils.load_default_channel_list()
|
||||
|
||||
def reset(self):
|
||||
self.client.reset()
|
||||
#pass
|
||||
# pass
|
||||
|
||||
def get_status(self):
|
||||
return self.client.get_status()
|
||||
@@ -558,47 +574,76 @@ class DIAClient:
|
||||
self.pgroup = pgroup
|
||||
self.update_config()
|
||||
|
||||
def set_bs_channels(self, ):
|
||||
print("Please update /sf/%s/config/com/channel_lists/default_channel_list and restart all services on the DAQ server" % self.instrument)
|
||||
def set_bs_channels(self,):
|
||||
print(
|
||||
"Please update /sf/%s/config/com/channel_lists/default_channel_list and restart all services on the DAQ server"
|
||||
% self.instrument
|
||||
)
|
||||
|
||||
def set_config(self):
|
||||
self.reset()
|
||||
self.client.set_config({"writer": self.writer_config, "backend": self.backend_config, "detector": self.detector_config, "bsread": self.bsread_config})
|
||||
|
||||
def check_still_running(self, time_interval=.5):
|
||||
self.client.set_config(
|
||||
{
|
||||
"writer": self.writer_config,
|
||||
"backend": self.backend_config,
|
||||
"detector": self.detector_config,
|
||||
"bsread": self.bsread_config,
|
||||
}
|
||||
)
|
||||
|
||||
def check_still_running(self, time_interval=0.5):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while running:
|
||||
if not self.get_status()['status'][-7:] == 'RUNNING':
|
||||
if not self.get_status()["status"][-7:] == "RUNNING":
|
||||
running = False
|
||||
break
|
||||
# elif not self.get_status()['status'][-20:]=='BSREAD_STILL_RUNNING':
|
||||
# running = False
|
||||
# break
|
||||
# elif not self.get_status()['status'][-20:]=='BSREAD_STILL_RUNNING':
|
||||
# running = False
|
||||
# break
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def take_pedestal(self, n_frames, analyze=True, n_bad_modules=0, update_config=True):
|
||||
from jungfrau_utils.scripts.jungfrau_run_pedestals import run as jungfrau_utils_run
|
||||
directory = '/sf/%s/data/p%d/raw' % (self.instrument, self.pgroup)
|
||||
|
||||
def take_pedestal(
|
||||
self, n_frames, analyze=True, n_bad_modules=0, update_config=True
|
||||
):
|
||||
from jungfrau_utils.scripts.jungfrau_run_pedestals import (
|
||||
run as jungfrau_utils_run,
|
||||
)
|
||||
|
||||
directory = "/sf/%s/data/p%d/raw" % (self.instrument, self.pgroup)
|
||||
if not os.path.exists(directory):
|
||||
print("Directory %s not existing, creating it" % directory)
|
||||
os.makedirs(directory)
|
||||
|
||||
|
||||
res_dir = directory.replace("/raw/", "/res/")
|
||||
if not os.path.exists(res_dir):
|
||||
print("Directory %s not existing, creating it" % res_dir)
|
||||
os.makedirs(res_dir)
|
||||
filename = "pedestal_%s.h5" % datetime.now().strftime("%Y%m%d_%H%M")
|
||||
period = 0.02 # for 25 Hz this is 0.04, for 10 Hz this 0.1
|
||||
jungfrau_utils_run(self._api_address, filename, directory, self.pgroup, period, self.detector_config["exptime"],
|
||||
n_frames, 1, analyze, n_bad_modules, self.instrument, self.jf_name)
|
||||
period = 0.02 # for 25 Hz this is 0.04, for 10 Hz this 0.1
|
||||
jungfrau_utils_run(
|
||||
self._api_address,
|
||||
filename,
|
||||
directory,
|
||||
self.pgroup,
|
||||
period,
|
||||
self.detector_config["exptime"],
|
||||
n_frames,
|
||||
1,
|
||||
analyze,
|
||||
n_bad_modules,
|
||||
self.instrument,
|
||||
self.jf_name,
|
||||
)
|
||||
|
||||
if update_config:
|
||||
self.pede_file = (directory + filename).replace("raw/", "res/").replace(".h5", "_res.h5")
|
||||
self.pede_file = (
|
||||
(directory + filename).replace("raw/", "res/").replace(".h5", "_res.h5")
|
||||
)
|
||||
print("Pedestal file updated to %s" % self.pede_file)
|
||||
return self.pede_file
|
||||
|
||||
|
||||
def start(self):
|
||||
self.client.start()
|
||||
print("start acquisition")
|
||||
@@ -606,7 +651,7 @@ class DIAClient:
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
print("stop acquisition")
|
||||
print("stop acquisition")
|
||||
pass
|
||||
|
||||
def config_and_start_test(self):
|
||||
@@ -615,25 +660,25 @@ class DIAClient:
|
||||
self.start()
|
||||
pass
|
||||
|
||||
def wait_for_status(self,*args,**kwargs):
|
||||
return self.client.wait_for_status(*args,**kwargs)
|
||||
def wait_for_status(self, *args, **kwargs):
|
||||
return self.client.wait_for_status(*args, **kwargs)
|
||||
|
||||
def acquire(self, file_name=None, Npulses=100, JF_factor=1, bsread_padding=0):
|
||||
"""
|
||||
JF_factor?
|
||||
bsread_padding?
|
||||
"""
|
||||
file_rootdir = '/sf/%s/data/p%d/raw/' % (self.instrument, self.pgroup)
|
||||
|
||||
file_rootdir = "/sf/%s/data/p%d/raw/" % (self.instrument, self.pgroup)
|
||||
|
||||
if file_name is None:
|
||||
# FIXME /dev/null crashes the data taking (h5py can't close /dev/null and crashes)
|
||||
print("Not saving any data, as file_name is not set")
|
||||
file_name_JF = file_rootdir + "DelMe" + '_JF4p5M.h5'
|
||||
file_name_bsread = file_rootdir + "DelMe" + '.h5'
|
||||
file_name_JF = file_rootdir + "DelMe" + "_JF4p5M.h5"
|
||||
file_name_bsread = file_rootdir + "DelMe" + ".h5"
|
||||
else:
|
||||
# FIXME hardcoded
|
||||
file_name_JF = file_rootdir + file_name + '_JF4p5M.h5'
|
||||
file_name_bsread = file_rootdir + file_name + '.h5'
|
||||
file_name_JF = file_rootdir + file_name + "_JF4p5M.h5"
|
||||
file_name_bsread = file_rootdir + file_name + ".h5"
|
||||
|
||||
if self.pgroup == 0:
|
||||
raise ValueError("Please use set_pgroup() to set a pgroup value.")
|
||||
@@ -641,38 +686,49 @@ class DIAClient:
|
||||
def acquire():
|
||||
self.n_frames = Npulses * JF_factor
|
||||
self.update_config()
|
||||
#self.detector_config.update({
|
||||
# self.detector_config.update({
|
||||
# 'cycles': n_frames})
|
||||
self.writer_config.update({
|
||||
'output_file': file_name_JF,
|
||||
# 'n_messages': n_frames
|
||||
})
|
||||
#self.backend_config.update({
|
||||
self.writer_config.update(
|
||||
{
|
||||
"output_file": file_name_JF,
|
||||
# 'n_messages': n_frames
|
||||
}
|
||||
)
|
||||
# self.backend_config.update({
|
||||
# 'n_frames': n_frames})
|
||||
self.bsread_config.update({
|
||||
'output_file':file_name_bsread,
|
||||
# 'Npulses': Npulses + bsread_padding
|
||||
})
|
||||
|
||||
self.bsread_config.update(
|
||||
{
|
||||
"output_file": file_name_bsread,
|
||||
# 'Npulses': Npulses + bsread_padding
|
||||
}
|
||||
)
|
||||
|
||||
self.reset()
|
||||
self.set_config()
|
||||
#print(self.get_config())
|
||||
# print(self.get_config())
|
||||
self.client.start()
|
||||
done = False
|
||||
|
||||
while not done:
|
||||
stat = self.get_status()
|
||||
if stat['status'] =='IntegrationStatus.FINISHED':
|
||||
if stat["status"] == "IntegrationStatus.FINISHED":
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
if stat["status"] == "IntegrationStatus.BSREAD_STILL_RUNNING":
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
if stat["status"] == "IntegrationStatus.INITIALIZED":
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.DETECTOR_STOPPED':
|
||||
if stat["status"] == "IntegrationStatus.DETECTOR_STOPPED":
|
||||
done = True
|
||||
sleep(.1)
|
||||
sleep(0.1)
|
||||
|
||||
return Acquisition(acquire=acquire, acquisition_kwargs={'file_names': [file_name_bsread, file_name_JF], 'Npulses': Npulses},hold=False)
|
||||
return Acquisition(
|
||||
acquire=acquire,
|
||||
acquisition_kwargs={
|
||||
"file_names": [file_name_bsread, file_name_JF],
|
||||
"Npulses": Npulses,
|
||||
},
|
||||
hold=False,
|
||||
)
|
||||
|
||||
def wait_done(self):
|
||||
self.check_running()
|
||||
|
||||
+104
-103
@@ -5,24 +5,25 @@ import time
|
||||
from threading import Thread
|
||||
|
||||
_basefolder = "/sf/alvra/config/lasertiming"
|
||||
_posTypes = ['user','dial','raw']
|
||||
_posTypes = ["user", "dial", "raw"]
|
||||
|
||||
def timeToStr(value,n=12):
|
||||
|
||||
def timeToStr(value, n=12):
|
||||
fmt = "%%+.%df" % n
|
||||
value = fmt%value
|
||||
#print(value)
|
||||
value = fmt % value
|
||||
# print(value)
|
||||
idx_point = value.find(".")
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value)-idx_point)//3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point+1+3*n:idx_point+1+3*(n+1)]
|
||||
#print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value) - idx_point) // 3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point + 1 + 3 * n : idx_point + 1 + 3 * (n + 1)]
|
||||
# print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
return ret_str
|
||||
|
||||
|
||||
|
||||
class Storage(object):
|
||||
def __init__(self,pvname):
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
def __init__(self, pvname):
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self.pvname = pvname
|
||||
self.last_read_time = -1
|
||||
|
||||
@@ -38,155 +39,153 @@ class Storage(object):
|
||||
lmod = self.last_modified_time
|
||||
if os.path.isfile(self._filename):
|
||||
# need to read again ?
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time :
|
||||
#print("actually reading")
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time:
|
||||
# print("actually reading")
|
||||
value = float(np.loadtxt(self._filename))
|
||||
self.last_read_time = lmod
|
||||
self.last_read = value
|
||||
else:
|
||||
value = self.last_read
|
||||
else:
|
||||
print("could not read",self._filename)
|
||||
print("could not read", self._filename)
|
||||
value = 0
|
||||
return value
|
||||
|
||||
def store(self,value):
|
||||
with open(self._filename,"w") as f:
|
||||
f.write("# %s\n"%time.asctime())
|
||||
f.write("%.15f"%value)
|
||||
|
||||
def store(self, value):
|
||||
with open(self._filename, "w") as f:
|
||||
f.write("# %s\n" % time.asctime())
|
||||
f.write("%.15f" % value)
|
||||
|
||||
|
||||
class Pockels_trigger(PV):
|
||||
""" this class is needed to store the offset in files and read in s """
|
||||
def __init__(self,pv_basename):
|
||||
|
||||
def __init__(self, pv_basename):
|
||||
pvname = pv_basename + "-RB"
|
||||
PV.__init__(self,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._storage = Storage(pvname)
|
||||
PV.__init__(self, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._storage = Storage(pvname)
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def get_dial(self):
|
||||
return super().get()*1e-6
|
||||
return super().get() * 1e-6
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self,value):
|
||||
def move(self, value):
|
||||
dial = value + self.offset
|
||||
self._pv_setvalue.put(dial*1e6)
|
||||
self._pv_setvalue.put(dial * 1e6)
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=12 )
|
||||
user = timeToStr( self.get(),n=12 )
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s"%(self.pvname,user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=12)
|
||||
user = timeToStr(self.get(), n=12)
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s" % (self.pvname, user, dial)
|
||||
|
||||
|
||||
class Phase_shifter(PV):
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
def __init__(self,pv_basename="SLAAR01-TSPL-EPL"):
|
||||
pvname = pv_basename+":CURR_DELTA_T"
|
||||
PV.__init__(self,pvname)
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
|
||||
def __init__(self, pv_basename="SLAAR01-TSPL-EPL"):
|
||||
pvname = pv_basename + ":CURR_DELTA_T"
|
||||
PV.__init__(self, pvname)
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
|
||||
def get_dial(self):
|
||||
return super().get()*1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
|
||||
def move(self,value):
|
||||
dial = value + self.offset
|
||||
dial_ps = dial*1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
self._pv_execute.put(1)
|
||||
while( np.abs(self.get()-value) > 100e-15 ): time.sleep(0.2)
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
def get_dial(self):
|
||||
return super().get() * 1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self, value):
|
||||
dial = value + self.offset
|
||||
dial_ps = dial * 1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
self._pv_execute.put(1)
|
||||
while np.abs(self.get() - value) > 100e-15:
|
||||
time.sleep(0.2)
|
||||
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=15 )
|
||||
user = timeToStr( self.get(),n=15 )
|
||||
return "Phase Shifter: user,dial = %s , %s"%(user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=15)
|
||||
user = timeToStr(self.get(), n=15)
|
||||
return "Phase Shifter: user,dial = %s , %s" % (user, dial)
|
||||
|
||||
|
||||
#_pockels_in = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
|
||||
#_pockels_out = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul3-Delay")
|
||||
#_phase_shifter = Phase_shifter("SLAAR01-TSPL-EPL")
|
||||
# _pockels_in = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
|
||||
# _pockels_out = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul3-Delay")
|
||||
# _phase_shifter = Phase_shifter("SLAAR01-TSPL-EPL")
|
||||
|
||||
|
||||
class PhaseShifterAramis:
|
||||
def __init__(self,Id,name=None,elog=None):
|
||||
def __init__(self, Id, name=None, elog=None):
|
||||
self.Id = Id
|
||||
self._pshifter = Phase_shifter(Id)
|
||||
self._elog = elog
|
||||
self.name = name
|
||||
|
||||
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
""" Adjustable convention"""
|
||||
|
||||
mover = lambda value: self._pshifter.move(\
|
||||
value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
mover=mover,
|
||||
hold=hold,
|
||||
stopper=None)
|
||||
mover = lambda value: self._pshifter.move(value)
|
||||
return Changer(target=value, parent=self, mover=mover, hold=hold, stopper=None)
|
||||
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
|
||||
def get_current_value(self,posType='user',readback=True):
|
||||
def get_current_value(self, posType="user", readback=True):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
if posType == 'user':
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
if posType == "user":
|
||||
return self._pshifter.get()
|
||||
if posType == 'dial':
|
||||
if posType == "dial":
|
||||
return self._pshifter.get_dial()
|
||||
|
||||
def set_current_value(self,value,posType='user'):
|
||||
def set_current_value(self, value, posType="user"):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
if posType == 'user':
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
if posType == "user":
|
||||
return self._motor.set(value)
|
||||
|
||||
|
||||
class Changer:
|
||||
def __init__(self, target=None, parent=None, mover=None, hold=True, stopper=None):
|
||||
self.target = target
|
||||
self._mover = mover
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._mover,args=(target,))
|
||||
self._thread = Thread(target=self._mover, args=(target,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
@@ -198,15 +197,17 @@ class Changer:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._isAlive:
|
||||
return 'changing'
|
||||
return "changing"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
def _keywordChecker(kw_key_list_tups):
|
||||
for tkw,tkey,tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s"%(tkw,tlist)
|
||||
for tkw, tkey, tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s" % (tkw, tlist)
|
||||
|
||||
@@ -3,64 +3,62 @@ from epics import PV
|
||||
|
||||
|
||||
_status_messages = {
|
||||
-13 : 'invalid value (cannot convert to float). Move not attempted.',
|
||||
-12 : 'target value outside soft limits. Move not attempted.',
|
||||
-11 : 'drive PV is not connected: Move not attempted.',
|
||||
-8 : 'move started, but timed-out.',
|
||||
-7 : 'move started, timed-out, but appears done.',
|
||||
-5 : 'move started, unexpected return value from PV.put()',
|
||||
-4 : 'move-with-wait finished, soft limit violation seen',
|
||||
-3 : 'move-with-wait finished, hard limit violation seen',
|
||||
0 : 'move-with-wait finish OK.',
|
||||
0 : 'move-without-wait executed, not comfirmed',
|
||||
1 : 'move-without-wait executed, move confirmed' ,
|
||||
3 : 'move-without-wait finished, hard limit violation seen',
|
||||
4 : 'move-without-wait finished, soft limit violation seen',
|
||||
}
|
||||
-13: "invalid value (cannot convert to float). Move not attempted.",
|
||||
-12: "target value outside soft limits. Move not attempted.",
|
||||
-11: "drive PV is not connected: Move not attempted.",
|
||||
-8: "move started, but timed-out.",
|
||||
-7: "move started, timed-out, but appears done.",
|
||||
-5: "move started, unexpected return value from PV.put()",
|
||||
-4: "move-with-wait finished, soft limit violation seen",
|
||||
-3: "move-with-wait finished, hard limit violation seen",
|
||||
0: "move-with-wait finish OK.",
|
||||
0: "move-without-wait executed, not comfirmed",
|
||||
1: "move-without-wait executed, move confirmed",
|
||||
3: "move-without-wait finished, hard limit violation seen",
|
||||
4: "move-without-wait finished, soft limit violation seen",
|
||||
}
|
||||
|
||||
|
||||
class DelayStage:
|
||||
def __init__(self,stage):
|
||||
def __init__(self, stage):
|
||||
self._stage = stage
|
||||
self.delay_stage_offset =0.
|
||||
self.delay_stage_offset = 0.0
|
||||
self.name = self._stage.name
|
||||
self.Id = self._stage.Id
|
||||
self._elog = self._stage._elog
|
||||
|
||||
def delay_to_motor(self,delay):
|
||||
motor_pos = delay/2./3.33333333*1e12
|
||||
def delay_to_motor(self, delay):
|
||||
motor_pos = delay / 2.0 / 3.33333333 * 1e12
|
||||
return motor_pos
|
||||
|
||||
def get_current_value(self):
|
||||
""" Adjustable convention"""
|
||||
motor_pos = self._stage.get_current_value()
|
||||
motor_pos -= self.delay_stage_offset
|
||||
delay = motor_pos*2.*3.33333333*1e-12
|
||||
delay = motor_pos * 2.0 * 3.33333333 * 1e-12
|
||||
return delay
|
||||
|
||||
def set_current_value(self, value):
|
||||
motor_pos = self.delay_to_motor(value) + self.delay_stage_offset
|
||||
self._stage.set_current_value(motor_pos)
|
||||
return (value, motor_pos)
|
||||
return (value, motor_pos)
|
||||
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
value = self.delay_to_motor(value) + self.delay_stage_offset
|
||||
delay = (value - self.delay_stage_offset)*2.*3.33333333*1e-12
|
||||
delay = (value - self.delay_stage_offset) * 2.0 * 3.33333333 * 1e-12
|
||||
return self._stage.changeTo(value, hold, check)
|
||||
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
def gui(self, guiType="xdm"):
|
||||
return self._stage.gui()
|
||||
|
||||
|
||||
# spec-inspired convenience methods
|
||||
def mv(self,value):
|
||||
def mv(self, value):
|
||||
self._stage._currentChange = self.changeTo(value)
|
||||
|
||||
def wm(self,*args,**kwargs):
|
||||
return self.get_current_value(*args,**kwargs)
|
||||
def wm(self, *args, **kwargs):
|
||||
return self.get_current_value(*args, **kwargs)
|
||||
|
||||
def mvr(self,value,*args,**kwargs):
|
||||
def mvr(self, value, *args, **kwargs):
|
||||
motor_pos = self.delay_to_motor(value)
|
||||
self._stage.mvr(motor_pos)
|
||||
|
||||
@@ -70,20 +68,17 @@ class DelayStage:
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
try:
|
||||
self._stage._currentChange.stop()
|
||||
self._stage._currentChange.stop()
|
||||
except:
|
||||
self._stage.stop()
|
||||
self._stage.stop()
|
||||
pass
|
||||
|
||||
|
||||
|
||||
# return string with motor value as variable representation
|
||||
def __str__(self):
|
||||
return "Motor is at %s"%self.wm()
|
||||
|
||||
return "Motor is at %s" % self.wm()
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __call__(self,value):
|
||||
def __call__(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
|
||||
+185
-122
@@ -16,19 +16,21 @@ from ..acquisition.utilities import Acquisition
|
||||
|
||||
try:
|
||||
import sys, os
|
||||
|
||||
tpath = os.path.dirname(__file__)
|
||||
sys.path.insert(0,os.path.join(tpath,'../../detector_integration_api'))
|
||||
#ask Leo(2018.03.14):
|
||||
#sys.path.insert(0,os.path.join(tpath,'../../jungfrau_utils'))
|
||||
sys.path.insert(0, os.path.join(tpath, "../../detector_integration_api"))
|
||||
# ask Leo(2018.03.14):
|
||||
# sys.path.insert(0,os.path.join(tpath,'../../jungfrau_utils'))
|
||||
from detector_integration_api import DetectorIntegrationClient
|
||||
except:
|
||||
print('NB: detector integration could not be imported!')
|
||||
print("NB: detector integration could not be imported!")
|
||||
|
||||
|
||||
_cameraArrayTypes = ['monochrome','rgb']
|
||||
_cameraArrayTypes = ["monochrome", "rgb"]
|
||||
|
||||
|
||||
class CameraCA:
|
||||
def __init__(self, pvname, cameraArrayType='monochrome',elog=None):
|
||||
def __init__(self, pvname, cameraArrayType="monochrome", elog=None):
|
||||
self.Id = pvname
|
||||
self.isBS = False
|
||||
self.px_height = None
|
||||
@@ -37,41 +39,43 @@ class CameraCA:
|
||||
|
||||
def get_px_height(self):
|
||||
if not self.px_height:
|
||||
self.px_height = caget(self.Id + ':HEIGHT')
|
||||
self.px_height = caget(self.Id + ":HEIGHT")
|
||||
return self.px_height
|
||||
|
||||
def get_px_width(self):
|
||||
if not self.px_width:
|
||||
self.px_width = caget(self.Id + ':WIDTH')
|
||||
self.px_width = caget(self.Id + ":WIDTH")
|
||||
return self.px_width
|
||||
|
||||
def get_data(self):
|
||||
w = self.get_px_width()
|
||||
h = self.get_px_height()
|
||||
numpix = int(caget(self.Id+':FPICTURE.NORD'))
|
||||
i = caget(self.Id+':FPICTURE', count=numpix)
|
||||
return i.reshape(h,w)
|
||||
numpix = int(caget(self.Id + ":FPICTURE.NORD"))
|
||||
i = caget(self.Id + ":FPICTURE", count=numpix)
|
||||
return i.reshape(h, w)
|
||||
|
||||
def record_images(self,fina,N_images,sleeptime=0.2):
|
||||
with h5py.File(fina,'w') as f:
|
||||
def record_images(self, fina, N_images, sleeptime=0.2):
|
||||
with h5py.File(fina, "w") as f:
|
||||
d = []
|
||||
for n in range(N_images):
|
||||
d.append(self.get_data())
|
||||
sleep(sleeptime)
|
||||
f['images'] = np.asarray(d)
|
||||
f["images"] = np.asarray(d)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
def gui(self, guiType="xdm"):
|
||||
""" Adjustable convention"""
|
||||
cmd = ['caqtdm','-macro']
|
||||
cmd = ["caqtdm", "-macro"]
|
||||
|
||||
cmd.append('\"NAME=%s,CAMNAME=%s\"'%(self.Id, self.Id))
|
||||
cmd.append('/sf/controls/config/qt/Camera/CameraMiniView.ui')
|
||||
return subprocess.Popen(' '.join(cmd),shell=True)
|
||||
cmd.append('"NAME=%s,CAMNAME=%s"' % (self.Id, self.Id))
|
||||
cmd.append("/sf/controls/config/qt/Camera/CameraMiniView.ui")
|
||||
return subprocess.Popen(" ".join(cmd), shell=True)
|
||||
|
||||
|
||||
# /sf/controls/config/qt/Camera/CameraMiniView.ui" with macro "NAME=SAROP21-PPRM138,CAMNAME=SAROP21-PPRM138
|
||||
|
||||
#/sf/controls/config/qt/Camera/CameraMiniView.ui" with macro "NAME=SAROP21-PPRM138,CAMNAME=SAROP21-PPRM138
|
||||
|
||||
class CameraBS:
|
||||
def __init__(self,host=None,port=None,elog=None):
|
||||
def __init__(self, host=None, port=None, elog=None):
|
||||
self._stream_host = host
|
||||
self._stream_port = port
|
||||
|
||||
@@ -80,40 +84,48 @@ class CameraBS:
|
||||
if self._instance_id not in client.get_server_info()["active_instances"]:
|
||||
raise ValueError("Requested pipeline is not running.")
|
||||
|
||||
def get_images(self,N_images):
|
||||
def get_images(self, N_images):
|
||||
data = []
|
||||
with source(host=self._stream_host, port=self._stream_port, mode=SUB) as input_stream:
|
||||
with source(
|
||||
host=self._stream_host, port=self._stream_port, mode=SUB
|
||||
) as input_stream:
|
||||
input_stream.connect()
|
||||
|
||||
|
||||
for n in range(N_images):
|
||||
data.append(input_stream.receive().data.data['image'].value)
|
||||
data.append(input_stream.receive().data.data["image"].value)
|
||||
return data
|
||||
|
||||
def record_images(self,fina,N_images,dsetname='images'):
|
||||
def record_images(self, fina, N_images, dsetname="images"):
|
||||
ds = None
|
||||
with h5py.File(fina,'w') as f:
|
||||
with source(host=self._stream_host, port=self._stream_port, mode=SUB) as input_stream:
|
||||
with h5py.File(fina, "w") as f:
|
||||
with source(
|
||||
host=self._stream_host, port=self._stream_port, mode=SUB
|
||||
) as input_stream:
|
||||
|
||||
input_stream.connect()
|
||||
|
||||
|
||||
for n in range(N_images):
|
||||
image = input_stream.receive().data.data['image'].value
|
||||
image = input_stream.receive().data.data["image"].value
|
||||
if not ds:
|
||||
ds = f.create_dataset(dsetname,dtype=image.dtype, shape=(N_images,)+image.shape)
|
||||
ds[n,:,:] = image
|
||||
ds = f.create_dataset(
|
||||
dsetname, dtype=image.dtype, shape=(N_images,) + image.shape
|
||||
)
|
||||
ds[n, :, :] = image
|
||||
|
||||
|
||||
class FeDigitizer:
|
||||
def __init__(self,Id,elog=None):
|
||||
def __init__(self, Id, elog=None):
|
||||
self.Id = Id
|
||||
self.gain = EnumWrapper(Id+'-WD-gain')
|
||||
self._bias = PV(Id+'-HV_SET')
|
||||
self.gain = EnumWrapper(Id + "-WD-gain")
|
||||
self._bias = PV(Id + "-HV_SET")
|
||||
self.channels = [
|
||||
Id+'-BG-DATA',
|
||||
Id+'-BG-DRS_TC',
|
||||
Id+'-BG-PULSEID-valid',
|
||||
Id+'-DATA',
|
||||
Id+'-DRS_TC',
|
||||
Id+'-PULSEID-valid']
|
||||
Id + "-BG-DATA",
|
||||
Id + "-BG-DRS_TC",
|
||||
Id + "-BG-PULSEID-valid",
|
||||
Id + "-DATA",
|
||||
Id + "-DRS_TC",
|
||||
Id + "-PULSEID-valid",
|
||||
]
|
||||
|
||||
def set_bias(self, value):
|
||||
self._bias.put(value)
|
||||
@@ -121,20 +133,25 @@ class FeDigitizer:
|
||||
def get_bias(self):
|
||||
return self._bias.value
|
||||
|
||||
|
||||
class DiodeDigitizer:
|
||||
def __init__(self,Id,VME_crate=None,link=None,
|
||||
ch_0=7,ch_1=8, elog=None):
|
||||
def __init__(self, Id, VME_crate=None, link=None, ch_0=7, ch_1=8, elog=None):
|
||||
self.Id = Id
|
||||
if VME_crate:
|
||||
self.diode_0 = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_0))
|
||||
self.diode_1 = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_1))
|
||||
|
||||
|
||||
self.diode_0 = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_0))
|
||||
self.diode_1 = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_1))
|
||||
|
||||
|
||||
class DIAClient:
|
||||
def __init__(self, Id, instrument=None, api_address = "http://sf-daq-2:10000", jf_name="JF_1.5M"):
|
||||
def __init__(
|
||||
self,
|
||||
Id,
|
||||
instrument=None,
|
||||
api_address="http://sf-daq-2:10000",
|
||||
jf_name="JF_1.5M",
|
||||
):
|
||||
self.Id = Id
|
||||
self._api_address = api_address
|
||||
self._api_address = api_address
|
||||
self.client = DetectorIntegrationClient(api_address)
|
||||
print("\nDetector Integration API on %s" % api_address)
|
||||
# No pgroup by default
|
||||
@@ -148,11 +165,11 @@ class DIAClient:
|
||||
print("ERROR: please configure the instrument parameter in DIAClient")
|
||||
self.update_config()
|
||||
|
||||
|
||||
def update_config(self, ):
|
||||
def update_config(self,):
|
||||
self.writer_config = {
|
||||
"output_file": "/sf/%s/data/p%d/raw/test_data.h5" % (self.instrument, self.pgroup),
|
||||
"user_id": self.pgroup,
|
||||
"output_file": "/sf/%s/data/p%d/raw/test_data.h5"
|
||||
% (self.instrument, self.pgroup),
|
||||
"user_id": self.pgroup,
|
||||
"n_frames": self.n_frames,
|
||||
"general/user": str(self.pgroup),
|
||||
"general/process": __name__,
|
||||
@@ -162,22 +179,30 @@ class DIAClient:
|
||||
}
|
||||
|
||||
self.backend_config = {
|
||||
"n_frames": self.n_frames,
|
||||
"bit_depth": 16,
|
||||
"gain_corrections_filename": self.gain_file, # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
#"gain_corrections_dataset": "gains",
|
||||
#"pede_corrections_filename": "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
#"pede_corrections_dataset": "gains",
|
||||
#"pede_mask_dataset": "pixel_mask",
|
||||
#"activate_corrections_preview": True,
|
||||
"n_frames": self.n_frames,
|
||||
"bit_depth": 16,
|
||||
"gain_corrections_filename": self.gain_file, # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
# "gain_corrections_dataset": "gains",
|
||||
# "pede_corrections_filename": "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
# "pede_corrections_dataset": "gains",
|
||||
# "pede_mask_dataset": "pixel_mask",
|
||||
# "activate_corrections_preview": True,
|
||||
# FIXME: HARDCODED!!!
|
||||
"is_HG0": False
|
||||
"is_HG0": False,
|
||||
}
|
||||
|
||||
if self.pede_file != "":
|
||||
self.backend_config["gain_corrections_filename"] = self.gain_file # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
self.backend_config[
|
||||
"gain_corrections_filename"
|
||||
] = (
|
||||
self.gain_file
|
||||
) # "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
self.backend_config["gain_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_corrections_filename"] = self.pede_file # "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
self.backend_config[
|
||||
"pede_corrections_filename"
|
||||
] = (
|
||||
self.pede_file
|
||||
) # "/sf/alvra/data/res/p%d/pedestal_20171210_1628_res.h5" % self.pgroup,
|
||||
self.backend_config["pede_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["activate_corrections_preview"] = True
|
||||
@@ -190,22 +215,22 @@ class DIAClient:
|
||||
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
|
||||
# FIXME: HARDCODED
|
||||
"exptime": 0.000010,
|
||||
"exptime": 0.000010,
|
||||
"cycles": self.n_frames,
|
||||
#"delay" : 0.001992,
|
||||
"frames" : 1,
|
||||
# "delay" : 0.001992,
|
||||
"frames": 1,
|
||||
"dr": 16,
|
||||
}
|
||||
|
||||
|
||||
# Not needed anymore?
|
||||
#default_channels_list = parseChannelListFile(
|
||||
# default_channels_list = parseChannelListFile(
|
||||
# '/sf/alvra/config/com/channel_lists/default_channel_list')
|
||||
|
||||
self.bsread_config = {
|
||||
'output_file': '/sf/%s/data/p%d/raw/test_bsread.h5' % (self.instrument, self.pgroup),
|
||||
'user_id': self.pgroup,
|
||||
"output_file": "/sf/%s/data/p%d/raw/test_bsread.h5"
|
||||
% (self.instrument, self.pgroup),
|
||||
"user_id": self.pgroup,
|
||||
"general/user": str(self.pgroup),
|
||||
"general/process": __name__,
|
||||
"general/created": str(datetime.now()),
|
||||
@@ -213,11 +238,12 @@ class DIAClient:
|
||||
#'Npulses':100,
|
||||
#'channels': default_channels_list
|
||||
}
|
||||
# self.default_channels_list = jungfrau_utils.load_default_channel_list()
|
||||
|
||||
# self.default_channels_list = jungfrau_utils.load_default_channel_list()
|
||||
|
||||
def reset(self):
|
||||
self.client.reset()
|
||||
#pass
|
||||
# pass
|
||||
|
||||
def get_status(self):
|
||||
return self.client.get_status()
|
||||
@@ -230,47 +256,76 @@ class DIAClient:
|
||||
self.pgroup = pgroup
|
||||
self.update_config()
|
||||
|
||||
def set_bs_channels(self, ):
|
||||
print("Please update /sf/%s/config/com/channel_lists/default_channel_list and restart all services on the DAQ server" % self.instrument)
|
||||
def set_bs_channels(self,):
|
||||
print(
|
||||
"Please update /sf/%s/config/com/channel_lists/default_channel_list and restart all services on the DAQ server"
|
||||
% self.instrument
|
||||
)
|
||||
|
||||
def set_config(self):
|
||||
self.reset()
|
||||
self.client.set_config({"writer": self.writer_config, "backend": self.backend_config, "detector": self.detector_config, "bsread": self.bsread_config})
|
||||
|
||||
def check_still_running(self, time_interval=.5):
|
||||
self.client.set_config(
|
||||
{
|
||||
"writer": self.writer_config,
|
||||
"backend": self.backend_config,
|
||||
"detector": self.detector_config,
|
||||
"bsread": self.bsread_config,
|
||||
}
|
||||
)
|
||||
|
||||
def check_still_running(self, time_interval=0.5):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while running:
|
||||
if not self.get_status()['status'][-7:] == 'RUNNING':
|
||||
if not self.get_status()["status"][-7:] == "RUNNING":
|
||||
running = False
|
||||
break
|
||||
# elif not self.get_status()['status'][-20:]=='BSREAD_STILL_RUNNING':
|
||||
# running = False
|
||||
# break
|
||||
# elif not self.get_status()['status'][-20:]=='BSREAD_STILL_RUNNING':
|
||||
# running = False
|
||||
# break
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def take_pedestal(self, n_frames, analyze=True, n_bad_modules=0, update_config=True):
|
||||
from jungfrau_utils.scripts.jungfrau_run_pedestals import run as jungfrau_utils_run
|
||||
directory = '/sf/%s/data/p%d/raw/JF_pedestal/' % (self.instrument, self.pgroup)
|
||||
|
||||
def take_pedestal(
|
||||
self, n_frames, analyze=True, n_bad_modules=0, update_config=True
|
||||
):
|
||||
from jungfrau_utils.scripts.jungfrau_run_pedestals import (
|
||||
run as jungfrau_utils_run,
|
||||
)
|
||||
|
||||
directory = "/sf/%s/data/p%d/raw/JF_pedestal/" % (self.instrument, self.pgroup)
|
||||
if not os.path.exists(directory):
|
||||
print("Directory %s not existing, creating it" % directory)
|
||||
os.makedirs(directory)
|
||||
|
||||
|
||||
res_dir = directory.replace("/raw/", "/res/")
|
||||
if not os.path.exists(res_dir):
|
||||
print("Directory %s not existing, creating it" % res_dir)
|
||||
os.makedirs(res_dir)
|
||||
filename = "pedestal_%s.h5" % datetime.now().strftime("%Y%m%d_%H%M")
|
||||
period = 0.04
|
||||
jungfrau_utils_run(self._api_address, filename, directory, self.pgroup, period, self.detector_config["exptime"],
|
||||
n_frames, 1, analyze, n_bad_modules, self.instrument, self.jf_name)
|
||||
jungfrau_utils_run(
|
||||
self._api_address,
|
||||
filename,
|
||||
directory,
|
||||
self.pgroup,
|
||||
period,
|
||||
self.detector_config["exptime"],
|
||||
n_frames,
|
||||
1,
|
||||
analyze,
|
||||
n_bad_modules,
|
||||
self.instrument,
|
||||
self.jf_name,
|
||||
)
|
||||
|
||||
if update_config:
|
||||
self.pede_file = (directory + filename).replace("raw/", "res/").replace(".h5", "_res.h5")
|
||||
self.pede_file = (
|
||||
(directory + filename).replace("raw/", "res/").replace(".h5", "_res.h5")
|
||||
)
|
||||
print("Pedestal file updated to %s" % self.pede_file)
|
||||
return self.pede_file
|
||||
|
||||
|
||||
def start(self):
|
||||
self.client.start()
|
||||
print("start acquisition")
|
||||
@@ -278,7 +333,7 @@ class DIAClient:
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
print("stop acquisition")
|
||||
print("stop acquisition")
|
||||
pass
|
||||
|
||||
def config_and_start_test(self):
|
||||
@@ -287,25 +342,25 @@ class DIAClient:
|
||||
self.start()
|
||||
pass
|
||||
|
||||
def wait_for_status(self,*args,**kwargs):
|
||||
return self.client.wait_for_status(*args,**kwargs)
|
||||
def wait_for_status(self, *args, **kwargs):
|
||||
return self.client.wait_for_status(*args, **kwargs)
|
||||
|
||||
def acquire(self, file_name=None, Npulses=100, JF_factor=1, bsread_padding=0):
|
||||
"""
|
||||
JF_factor?
|
||||
bsread_padding?
|
||||
"""
|
||||
file_rootdir = '/sf/%s/data/p%d/raw/' % (self.instrument, self.pgroup)
|
||||
|
||||
file_rootdir = "/sf/%s/data/p%d/raw/" % (self.instrument, self.pgroup)
|
||||
|
||||
if file_name is None:
|
||||
# FIXME /dev/null crashes the data taking (h5py can't close /dev/null and crashes)
|
||||
print("Not saving any data, as file_name is not set")
|
||||
file_name_JF = file_rootdir + "DelMe" + '_JF1p5M.h5'
|
||||
file_name_bsread = file_rootdir + "DelMe" + '.h5'
|
||||
file_name_JF = file_rootdir + "DelMe" + "_JF1p5M.h5"
|
||||
file_name_bsread = file_rootdir + "DelMe" + ".h5"
|
||||
else:
|
||||
# FIXME hardcoded
|
||||
file_name_JF = file_rootdir + file_name + '_JF1p5M.h5'
|
||||
file_name_bsread = file_rootdir + file_name + '.h5'
|
||||
file_name_JF = file_rootdir + file_name + "_JF1p5M.h5"
|
||||
file_name_bsread = file_rootdir + file_name + ".h5"
|
||||
|
||||
if self.pgroup == 0:
|
||||
raise ValueError("Please use set_pgroup() to set a pgroup value.")
|
||||
@@ -313,42 +368,50 @@ class DIAClient:
|
||||
def acquire():
|
||||
self.n_frames = Npulses * JF_factor
|
||||
self.update_config()
|
||||
#self.detector_config.update({
|
||||
# self.detector_config.update({
|
||||
# 'cycles': n_frames})
|
||||
self.writer_config.update({
|
||||
'output_file': file_name_JF,
|
||||
# 'n_messages': n_frames
|
||||
})
|
||||
#self.backend_config.update({
|
||||
self.writer_config.update(
|
||||
{
|
||||
"output_file": file_name_JF,
|
||||
# 'n_messages': n_frames
|
||||
}
|
||||
)
|
||||
# self.backend_config.update({
|
||||
# 'n_frames': n_frames})
|
||||
self.bsread_config.update({
|
||||
'output_file':file_name_bsread,
|
||||
# 'Npulses': Npulses + bsread_padding
|
||||
})
|
||||
|
||||
self.bsread_config.update(
|
||||
{
|
||||
"output_file": file_name_bsread,
|
||||
# 'Npulses': Npulses + bsread_padding
|
||||
}
|
||||
)
|
||||
|
||||
self.reset()
|
||||
self.set_config()
|
||||
#print(self.get_config())
|
||||
# print(self.get_config())
|
||||
self.client.start()
|
||||
done = False
|
||||
|
||||
while not done:
|
||||
stat = self.get_status()
|
||||
if stat['status'] =='IntegrationStatus.FINISHED':
|
||||
if stat["status"] == "IntegrationStatus.FINISHED":
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
if stat["status"] == "IntegrationStatus.BSREAD_STILL_RUNNING":
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
if stat["status"] == "IntegrationStatus.INITIALIZED":
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.DETECTOR_STOPPED':
|
||||
if stat["status"] == "IntegrationStatus.DETECTOR_STOPPED":
|
||||
done = True
|
||||
sleep(.1)
|
||||
sleep(0.1)
|
||||
|
||||
return Acquisition(acquire=acquire, acquisition_kwargs={'file_names': [file_name_bsread, file_name_JF], 'Npulses': Npulses},hold=False)
|
||||
return Acquisition(
|
||||
acquire=acquire,
|
||||
acquisition_kwargs={
|
||||
"file_names": [file_name_bsread, file_name_JF],
|
||||
"Npulses": Npulses,
|
||||
},
|
||||
hold=False,
|
||||
)
|
||||
|
||||
def wait_done(self):
|
||||
self.check_running()
|
||||
self.check_still_running()
|
||||
|
||||
|
||||
|
||||
|
||||
+104
-100
@@ -3,92 +3,102 @@ import subprocess
|
||||
from threading import Thread
|
||||
from epics import PV
|
||||
from .utilities import Changer
|
||||
from ..aliases import Alias
|
||||
|
||||
_MotorRocordStandardProperties = \
|
||||
{}
|
||||
_posTypes = ['user','dial','raw']
|
||||
_guiTypes = ['xdm']
|
||||
_MotorRocordStandardProperties = {}
|
||||
_posTypes = ["user", "dial", "raw"]
|
||||
_guiTypes = ["xdm"]
|
||||
|
||||
|
||||
_status_messages = {
|
||||
-13 : 'invalid value (cannot convert to float). Move not attempted.',
|
||||
-12 : 'target value outside soft limits. Move not attempted.',
|
||||
-11 : 'drive PV is not connected: Move not attempted.',
|
||||
-8 : 'move started, but timed-out.',
|
||||
-7 : 'move started, timed-out, but appears done.',
|
||||
-5 : 'move started, unexpected return value from PV.put()',
|
||||
-4 : 'move-with-wait finished, soft limit violation seen',
|
||||
-3 : 'move-with-wait finished, hard limit violation seen',
|
||||
0 : 'move-with-wait finish OK.',
|
||||
0 : 'move-without-wait executed, not comfirmed',
|
||||
1 : 'move-without-wait executed, move confirmed' ,
|
||||
3 : 'move-without-wait finished, hard limit violation seen',
|
||||
4 : 'move-without-wait finished, soft limit violation seen',
|
||||
-13: "invalid value (cannot convert to float). Move not attempted.",
|
||||
-12: "target value outside soft limits. Move not attempted.",
|
||||
-11: "drive PV is not connected: Move not attempted.",
|
||||
-8: "move started, but timed-out.",
|
||||
-7: "move started, timed-out, but appears done.",
|
||||
-5: "move started, unexpected return value from PV.put()",
|
||||
-4: "move-with-wait finished, soft limit violation seen",
|
||||
-3: "move-with-wait finished, hard limit violation seen",
|
||||
0: "move-with-wait finish OK.",
|
||||
0: "move-without-wait executed, not comfirmed",
|
||||
1: "move-without-wait executed, move confirmed",
|
||||
3: "move-without-wait finished, hard limit violation seen",
|
||||
4: "move-without-wait finished, soft limit violation seen",
|
||||
}
|
||||
|
||||
|
||||
def _keywordChecker(kw_key_list_tups):
|
||||
for tkw,tkey,tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s"%(tkw,tlist)
|
||||
for tkw, tkey, tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s" % (tkw, tlist)
|
||||
|
||||
|
||||
class MotorRecord:
|
||||
def __init__(self,pvname, name=None, elog=None):
|
||||
def __init__(
|
||||
self,
|
||||
pvname,
|
||||
name=None,
|
||||
elog=None,
|
||||
alias_fields={"readback": "RBV", "user_offset": "OFF"},
|
||||
):
|
||||
self.Id = pvname
|
||||
self._motor = _Motor(pvname)
|
||||
self._elog = elog
|
||||
self.name = name
|
||||
self.alias = Alias(name)
|
||||
for an, af in alias_fields.items():
|
||||
self.alias.append(
|
||||
Alias(an, channel=".".join([pvname, af]), channeltype="CA")
|
||||
)
|
||||
self._currentChange = None
|
||||
|
||||
|
||||
# Conventional methods and properties for all Adjustable objects
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
""" Adjustable convention"""
|
||||
|
||||
def changer(value):
|
||||
self._status = self._motor.move(\
|
||||
value, ignore_limits=(not check),
|
||||
wait=True)
|
||||
self._status = self._motor.move(value, ignore_limits=(not check), wait=True)
|
||||
self._status_message = _status_messages[self._status]
|
||||
if not self._status==0:
|
||||
if not self._status == 0:
|
||||
print(self._status_message)
|
||||
|
||||
# changer = lambda value: self._motor.move(\
|
||||
# value, ignore_limits=(not check),
|
||||
# wait=True)
|
||||
# changer = lambda value: self._motor.move(\
|
||||
# value, ignore_limits=(not check),
|
||||
# wait=True)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=self._motor.stop)
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=self._motor.stop,
|
||||
)
|
||||
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
try:
|
||||
self._currentChange.stop()
|
||||
self._currentChange.stop()
|
||||
except:
|
||||
self._motor.stop()
|
||||
self._motor.stop()
|
||||
pass
|
||||
|
||||
|
||||
def get_current_value(self,posType='user',readback=True):
|
||||
def get_current_value(self, posType="user", readback=True):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
if posType == 'user':
|
||||
return self._motor.get_position( readback=readback)
|
||||
if posType == 'dial':
|
||||
return self._motor.get_position( readback=readback, dial=True)
|
||||
if posType == 'raw':
|
||||
return self._motor.get_position( readback=readback, raw=True)
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
if posType == "user":
|
||||
return self._motor.get_position(readback=readback)
|
||||
if posType == "dial":
|
||||
return self._motor.get_position(readback=readback, dial=True)
|
||||
if posType == "raw":
|
||||
return self._motor.get_position(readback=readback, raw=True)
|
||||
|
||||
def set_current_value(self,value,posType='user'):
|
||||
def set_current_value(self, value, posType="user"):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
if posType == 'user':
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
if posType == "user":
|
||||
return self._motor.set_position(value)
|
||||
if posType == 'dial':
|
||||
return self._motor.set_position(value,dial=True)
|
||||
if posType == 'raw':
|
||||
return self._motor.set_position(value,raw=True)
|
||||
if posType == "dial":
|
||||
return self._motor.set_position(value, dial=True)
|
||||
if posType == "raw":
|
||||
return self._motor.set_position(value, raw=True)
|
||||
|
||||
def get_precision(self):
|
||||
""" Adjustable convention"""
|
||||
@@ -98,14 +108,16 @@ class MotorRecord:
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
precision = property(get_precision,set_precision)
|
||||
precision = property(get_precision, set_precision)
|
||||
|
||||
def set_speed(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def get_speed(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def set_speedMax(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
@@ -113,81 +125,75 @@ class MotorRecord:
|
||||
def get_moveDone(self):
|
||||
""" Adjustable convention"""
|
||||
""" 0: moving 1: move done"""
|
||||
return PV(str(self.Id+".DMOV")).value
|
||||
|
||||
return PV(str(self.Id + ".DMOV")).value
|
||||
|
||||
def set_limits(self, values, posType='user', relative_to_present=False):
|
||||
def set_limits(self, values, posType="user", relative_to_present=False):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
ll_name, hl_name = 'LLM', 'HLM'
|
||||
if posType is 'dial':
|
||||
ll_name, hl_name = 'DLLM', 'DHLM'
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
ll_name, hl_name = "LLM", "HLM"
|
||||
if posType is "dial":
|
||||
ll_name, hl_name = "DLLM", "DHLM"
|
||||
if relative_to_present:
|
||||
v = self.get_current_value(posType=posType)
|
||||
values = [v+values[0],v+values[1]]
|
||||
self._motor.put(ll_name,values[0])
|
||||
self._motor.put(hl_name,values[1])
|
||||
values = [v + values[0], v + values[1]]
|
||||
self._motor.put(ll_name, values[0])
|
||||
self._motor.put(hl_name, values[1])
|
||||
|
||||
def get_limits(self, posType='user'):
|
||||
def get_limits(self, posType="user"):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
ll_name, hl_name = 'LLM', 'HLM'
|
||||
if posType is 'dial':
|
||||
ll_name, hl_name = 'DLLM', 'DHLM'
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
ll_name, hl_name = "LLM", "HLM"
|
||||
if posType is "dial":
|
||||
ll_name, hl_name = "DLLM", "DHLM"
|
||||
return self._motor.get(ll_name), self._motor.get(hl_name)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
def gui(self, guiType="xdm"):
|
||||
""" Adjustable convention"""
|
||||
cmd = ['caqtdm','-macro']
|
||||
|
||||
cmd.append('\"P=%s:,M=%s\"'%tuple(self.Id.split(':')))
|
||||
#cmd.append('/sf/common/config/qt/motorx_more.ui')
|
||||
cmd.append('motorx_more.ui')
|
||||
#os.system(' '.join(cmd))
|
||||
return subprocess.Popen(' '.join(cmd),shell=True)
|
||||
|
||||
|
||||
|
||||
cmd = ["caqtdm", "-macro"]
|
||||
|
||||
cmd.append('"P=%s:,M=%s"' % tuple(self.Id.split(":")))
|
||||
# cmd.append('/sf/common/config/qt/motorx_more.ui')
|
||||
cmd.append("motorx_more.ui")
|
||||
# os.system(' '.join(cmd))
|
||||
return subprocess.Popen(" ".join(cmd), shell=True)
|
||||
|
||||
# epics motor record specific methods
|
||||
|
||||
|
||||
# spec-inspired convenience methods
|
||||
def mv(self,value):
|
||||
def mv(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
def wm(self,*args,**kwargs):
|
||||
return self.get_current_value(*args,**kwargs)
|
||||
def mvr(self,value,*args,**kwargs):
|
||||
|
||||
if(self.get_moveDone == 1):
|
||||
startvalue = self.get_current_value(readback=True,*args,**kwargs)
|
||||
def wm(self, *args, **kwargs):
|
||||
return self.get_current_value(*args, **kwargs)
|
||||
|
||||
def mvr(self, value, *args, **kwargs):
|
||||
|
||||
if self.get_moveDone == 1:
|
||||
startvalue = self.get_current_value(readback=True, *args, **kwargs)
|
||||
else:
|
||||
startvalue = self.get_current_value(readback=False,*args,**kwargs)
|
||||
self._currentChange = self.changeTo(value+startvalue,*args,**kwargs)
|
||||
startvalue = self.get_current_value(readback=False, *args, **kwargs)
|
||||
self._currentChange = self.changeTo(value + startvalue, *args, **kwargs)
|
||||
|
||||
def wait(self):
|
||||
self._currentChange.wait()
|
||||
|
||||
|
||||
# return string with motor value as variable representation
|
||||
def __str__(self):
|
||||
return "Motor is at %s"%self.wm()
|
||||
|
||||
return "Motor is at %s" % self.wm()
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __call__(self,value):
|
||||
def __call__(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
|
||||
|
||||
|
||||
class ChangerOld:
|
||||
def __init__(self, target=None, parent=None, mover=None, hold=True, stopper=None):
|
||||
self.target = target
|
||||
self._mover = mover
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._mover,args=(target,))
|
||||
self._thread = Thread(target=self._mover, args=(target,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
@@ -199,14 +205,12 @@ class ChangerOld:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._isAlive:
|
||||
return 'changing'
|
||||
return "changing"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
|
||||
|
||||
+132
-110
@@ -5,91 +5,105 @@ import time
|
||||
from ..eco_epics import device
|
||||
from ..eco_epics.device import Device
|
||||
|
||||
_guiTypes = ['xdm']
|
||||
_guiTypes = ["xdm"]
|
||||
|
||||
|
||||
def _keywordChecker(kw_key_list_tups):
|
||||
for tkw,tkey,tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s"%(tkw,tlist)
|
||||
for tkw, tkey, tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s" % (tkw, tlist)
|
||||
|
||||
|
||||
class SmarActException(Exception):
|
||||
""" raised to indicate a problem with a smartact"""
|
||||
|
||||
def __init__(self, msg, *args):
|
||||
Exception.__init__(self, *args)
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return str(self.msg)
|
||||
|
||||
return str(self.msg)
|
||||
|
||||
|
||||
class SmarAct(Device):
|
||||
_extras = {'disabled':'_able.VAL', }
|
||||
_init_list = ('VAL', 'DESC', 'RTYP')
|
||||
_nonpvs = ('_prefix', '_pvs', '_delim', '_init', '_init_list', '_alias', '_extras')
|
||||
_extras = {"disabled": "_able.VAL"}
|
||||
_init_list = ("VAL", "DESC", "RTYP")
|
||||
_nonpvs = ("_prefix", "_pvs", "_delim", "_init", "_init_list", "_alias", "_extras")
|
||||
|
||||
def __init__(self, name=None, timeout=3.0, record=None):
|
||||
if name is None:
|
||||
raise SmarActException("must supply SmarAct name")
|
||||
|
||||
if name.endswith('.VAL'):
|
||||
if name.endswith(".VAL"):
|
||||
name = name[:-4]
|
||||
if name.endswith('.'):
|
||||
if name.endswith("."):
|
||||
name = name[:-1]
|
||||
|
||||
self._prefix = name
|
||||
self._record = record
|
||||
self._callbacks = {}
|
||||
|
||||
device.Device.__init__(self, name, delim='.',
|
||||
attrs=self._init_list,
|
||||
timeout=timeout)
|
||||
|
||||
device.Device.__init__(
|
||||
self, name, delim=".", attrs=self._init_list, timeout=timeout
|
||||
)
|
||||
|
||||
|
||||
# for key, val in self._extras.items():
|
||||
# pvname = "%s%s" % (name, val)
|
||||
# self.add_pv(pvname, attr=key)
|
||||
|
||||
# self.put('disabled', 0)
|
||||
|
||||
# self.put('disabled', 0)
|
||||
|
||||
|
||||
class SmarActRecord:
|
||||
def __init__(self,Id, name=None, elog=None):
|
||||
def __init__(self, Id, name=None, elog=None):
|
||||
self.Id = Id
|
||||
self._drive = SmarAct(Id+':DRIVE')
|
||||
self._rbv = SmarAct(Id+':MOTRBV')
|
||||
self._hlm = SmarAct(Id+':HLM')
|
||||
self._llm = SmarAct(Id+':LLM')
|
||||
self._status = SmarAct(Id+':STATUS')
|
||||
self._set_pos = SmarAct(Id+':SET_POS')
|
||||
self._stop = SmarAct(Id+':STOP')
|
||||
self._hold = SmarAct(Id+':HOLD')
|
||||
self._twv = SmarAct(Id+':TWV')
|
||||
self._drive = SmarAct(Id + ":DRIVE")
|
||||
self._rbv = SmarAct(Id + ":MOTRBV")
|
||||
self._hlm = SmarAct(Id + ":HLM")
|
||||
self._llm = SmarAct(Id + ":LLM")
|
||||
self._status = SmarAct(Id + ":STATUS")
|
||||
self._set_pos = SmarAct(Id + ":SET_POS")
|
||||
self._stop = SmarAct(Id + ":STOP")
|
||||
self._hold = SmarAct(Id + ":HOLD")
|
||||
self._twv = SmarAct(Id + ":TWV")
|
||||
self._elog = elog
|
||||
self.name = name
|
||||
self.units = self._drive.get('EGU')
|
||||
self.units = self._drive.get("EGU")
|
||||
|
||||
# Conventional methods and properties for all Adjustable objects
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
""" Adjustable convention"""
|
||||
|
||||
mover = lambda value: self.move(\
|
||||
value, ignore_limits=(not check),
|
||||
wait=True)
|
||||
mover = lambda value: self.move(value, ignore_limits=(not check), wait=True)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
mover=mover,
|
||||
hold=hold,
|
||||
stopper=self._stop.put('PROC', 1))
|
||||
target=value,
|
||||
parent=self,
|
||||
mover=mover,
|
||||
hold=hold,
|
||||
stopper=self._stop.put("PROC", 1),
|
||||
)
|
||||
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
try:
|
||||
self._currentChange.stop()
|
||||
self._currentChange.stop()
|
||||
except:
|
||||
self._stop.put('VAL',1)
|
||||
self._stop.put("VAL", 1)
|
||||
pass
|
||||
|
||||
def within_limits(self, val):
|
||||
""" returns whether a value for a motor is within drive limits"""
|
||||
return (val <= self._hlm.get('VAL') and val >= self._llm.get('VAL'))
|
||||
return val <= self._hlm.get("VAL") and val >= self._llm.get("VAL")
|
||||
|
||||
def move(self, val, relative=False, wait=False, timeout=300.0, ignore_limits=False, confirm_move=False):
|
||||
def move(
|
||||
self,
|
||||
val,
|
||||
relative=False,
|
||||
wait=False,
|
||||
timeout=300.0,
|
||||
ignore_limits=False,
|
||||
confirm_move=False,
|
||||
):
|
||||
""" moves smaract drive to position
|
||||
|
||||
arguments:
|
||||
@@ -118,56 +132,60 @@ class SmarActRecord:
|
||||
|
||||
"""
|
||||
NONFLOAT, OUTSIDE_LIMITS, UNCONNECTED = -13, -12, -11
|
||||
TIMEOUT = -8
|
||||
UNKNOWN_ERROR = -5
|
||||
DONE_OK = 0
|
||||
MOVE_BEGUN, MOVE_BEGUN_CONFIRMED = 0, 1
|
||||
TIMEOUT = -8
|
||||
UNKNOWN_ERROR = -5
|
||||
DONE_OK = 0
|
||||
MOVE_BEGUN, MOVE_BEGUN_CONFIRMED = 0, 1
|
||||
try:
|
||||
val = float(val)
|
||||
except TypeError:
|
||||
return NONFLOAT
|
||||
|
||||
if relative:
|
||||
val += self._drive.get('VAL')
|
||||
val += self._drive.get("VAL")
|
||||
|
||||
# Check for limit violations
|
||||
if not ignore_limits:
|
||||
if not self.within_limits(val):
|
||||
return OUTSIDE_LIMITS
|
||||
|
||||
stat = self._drive.put('VAL', val, wait=wait, timeout=timeout)
|
||||
stat = self._drive.put("VAL", val, wait=wait, timeout=timeout)
|
||||
if stat is None:
|
||||
return UNCONNECTED
|
||||
|
||||
|
||||
if wait and stat == -1:
|
||||
return TIMEOUT
|
||||
|
||||
if 1 == stat:
|
||||
s0 = self._status.get('VAL')
|
||||
s0 = self._status.get("VAL")
|
||||
s1 = s0
|
||||
t0 = time.time()
|
||||
t1 = t0 + min(10.0, timeout) # should be moving by now
|
||||
thold = self._hold.get('VAL') * 0.001 + t0
|
||||
t1 = t0 + min(10.0, timeout) # should be moving by now
|
||||
thold = self._hold.get("VAL") * 0.001 + t0
|
||||
tout = t0 + timeout
|
||||
if wait or confirm_move:
|
||||
while time.time() <= thold and s1 == 3:
|
||||
ca.poll(evt=1.e-2)
|
||||
s1 = self._status.get('VAL')
|
||||
ca.poll(evt=1.0e-2)
|
||||
s1 = self._status.get("VAL")
|
||||
while time.time() <= t1 and s1 == 0:
|
||||
ca.poll(evt=1.e-2)
|
||||
s1 = self._status.get('VAL')
|
||||
ca.poll(evt=1.0e-2)
|
||||
s1 = self._status.get("VAL")
|
||||
if s1 == 4:
|
||||
if wait:
|
||||
while time.time() <= tout and s1 == 4:
|
||||
ca.poll(evt=1.e-2)
|
||||
s1 = self._status.get('VAL')
|
||||
ca.poll(evt=1.0e-2)
|
||||
s1 = self._status.get("VAL")
|
||||
if s1 == 3 or s1 == 4:
|
||||
if time.time() > tout:
|
||||
return TIMEOUT
|
||||
else:
|
||||
twv = abs(self._twv.get('VAL'))
|
||||
while s1==3 and time.time()<=tout and abs(self._rbv.get('VAL')-val)>=twv:
|
||||
ca.poll(evt=1.e-2)
|
||||
twv = abs(self._twv.get("VAL"))
|
||||
while (
|
||||
s1 == 3
|
||||
and time.time() <= tout
|
||||
and abs(self._rbv.get("VAL") - val) >= twv
|
||||
):
|
||||
ca.poll(evt=1.0e-2)
|
||||
return DONE_OK
|
||||
else:
|
||||
return MOVE_BEGUN_CONFIRMED
|
||||
@@ -179,14 +197,14 @@ class SmarActRecord:
|
||||
return MOVE_BEGUN
|
||||
return UNKNOWN_ERROR
|
||||
|
||||
def get_current_value(self,readback=True):
|
||||
def get_current_value(self, readback=True):
|
||||
if readback:
|
||||
return self._rbv.get('VAL')
|
||||
else :
|
||||
return self._drive.get('VAL')
|
||||
return self._rbv.get("VAL")
|
||||
else:
|
||||
return self._drive.get("VAL")
|
||||
|
||||
def set_current_value(self,value):
|
||||
return self._set_pos.put('VAL',value)
|
||||
def set_current_value(self, value):
|
||||
return self._set_pos.put("VAL", value)
|
||||
|
||||
def get_precision(self):
|
||||
""" Adjustable convention"""
|
||||
@@ -196,106 +214,114 @@ class SmarActRecord:
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
precision = property(get_precision,set_precision)
|
||||
precision = property(get_precision, set_precision)
|
||||
|
||||
def set_speed(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def get_speed(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def set_speedMax(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
def get_moveDone(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
pass
|
||||
|
||||
def set_limits(self, values, posType='user', relative_to_present=False):
|
||||
def set_limits(self, values, posType="user", relative_to_present=False):
|
||||
""" Adjustable convention"""
|
||||
if relative_to_present:
|
||||
v = self.get_current_value()
|
||||
values = [v-values[0],v-values[1]]
|
||||
self._llm.put('VAL',values[0])
|
||||
self._hlm.put('VAL',values[1])
|
||||
values = [v - values[0], v - values[1]]
|
||||
self._llm.put("VAL", values[0])
|
||||
self._hlm.put("VAL", values[1])
|
||||
|
||||
def get_limits(self, posType='user'):
|
||||
def get_limits(self, posType="user"):
|
||||
""" Adjustable convention"""
|
||||
return self._llm.get('VAL'), self._hlm.get('VAL')
|
||||
return self._llm.get("VAL"), self._hlm.get("VAL")
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
def gui(self, guiType="xdm"):
|
||||
""" Adjustable convention"""
|
||||
cmd = ['caqtdm','-macro']
|
||||
cmd = ["caqtdm", "-macro"]
|
||||
|
||||
for i in range(len(self.Id)-1):
|
||||
if self.Id[-i-1].isnumeric() is False:
|
||||
for i in range(len(self.Id) - 1):
|
||||
if self.Id[-i - 1].isnumeric() is False:
|
||||
M = self.Id[-i:]
|
||||
P = self.Id[:-i]
|
||||
print(P, M)
|
||||
break
|
||||
|
||||
cmd.append('\"P=%s,M=%s\"'%(P, M))
|
||||
# #cmd.append('/sf/common/config/qt/motorx_more.ui')
|
||||
cmd.append('ESB_MX_SMARACT_mot_exp.ui')
|
||||
# #os.system(' '.join(cmd))
|
||||
return subprocess.Popen(' '.join(cmd),shell=True)
|
||||
|
||||
cmd.append('"P=%s,M=%s"' % (P, M))
|
||||
# #cmd.append('/sf/common/config/qt/motorx_more.ui')
|
||||
cmd.append("ESB_MX_SMARACT_mot_exp.ui")
|
||||
# #os.system(' '.join(cmd))
|
||||
return subprocess.Popen(" ".join(cmd), shell=True)
|
||||
|
||||
|
||||
def mv(self,value):
|
||||
def mv(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
def wm(self,*args,**kwargs):
|
||||
return self.get_current_value(*args,**kwargs)
|
||||
def mvr(self,value,*args,**kwargs):
|
||||
|
||||
if(self.get_moveDone == 1):
|
||||
startvalue = self.get_current_value(readback=True,*args,**kwargs)
|
||||
def wm(self, *args, **kwargs):
|
||||
return self.get_current_value(*args, **kwargs)
|
||||
|
||||
def mvr(self, value, *args, **kwargs):
|
||||
|
||||
if self.get_moveDone == 1:
|
||||
startvalue = self.get_current_value(readback=True, *args, **kwargs)
|
||||
else:
|
||||
startvalue = self.get_current_value(readback=False,*args,**kwargs)
|
||||
self._currentChange = self.changeTo(value+startvalue,*args,**kwargs)
|
||||
startvalue = self.get_current_value(readback=False, *args, **kwargs)
|
||||
self._currentChange = self.changeTo(value + startvalue, *args, **kwargs)
|
||||
|
||||
def wait(self):
|
||||
self._currentChange.wait()
|
||||
|
||||
|
||||
# return string with motor value as variable representation
|
||||
def __str__(self):
|
||||
return "SmarAct is at %s"%(self.wm())
|
||||
#return "SmarAct is at %s %s"%(self.wm(),self.units)
|
||||
|
||||
return "SmarAct is at %s" % (self.wm())
|
||||
# return "SmarAct is at %s %s"%(self.wm(),self.units)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __call__(self,value):
|
||||
def __call__(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
|
||||
class SmarActDevice(SmarActRecord):
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
SmarActRecord.__init__(self, Id)
|
||||
|
||||
|
||||
# self.Id = Id
|
||||
#
|
||||
# self.x = SmarActRecord(Id+':DRIVE')
|
||||
|
||||
|
||||
class SmarActStage:
|
||||
def __init__(self, axes, name):
|
||||
self._keys = axes.keys()
|
||||
for axis in self._keys:
|
||||
self.__dict__[axis] = axes[axis]
|
||||
self.name = name
|
||||
|
||||
|
||||
def __str__(self):
|
||||
return "SmarAct positions\n%s" % "\n".join(["%s: %s"%(key,self.__dict__[key].wm()) for key in self._keys])
|
||||
|
||||
return "SmarAct positions\n%s" % "\n".join(
|
||||
["%s: %s" % (key, self.__dict__[key].wm()) for key in self._keys]
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return str({key:self.__dict__[key].wm() for key in self._keys})
|
||||
return str({key: self.__dict__[key].wm() for key in self._keys})
|
||||
|
||||
|
||||
class Changer:
|
||||
def __init__(self, target=None, parent=None, mover=None, hold=True, stopper=None):
|
||||
self.target = target
|
||||
self._mover = mover
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._mover,args=(target,))
|
||||
self._thread = Thread(target=self._mover, args=(target,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
@@ -307,16 +333,12 @@ class Changer:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._isAlive:
|
||||
return 'changing'
|
||||
return "changing"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
+104
-103
@@ -5,24 +5,25 @@ import time
|
||||
from threading import Thread
|
||||
|
||||
_basefolder = "/sf/bernina/config/com/data/src/lasertiming"
|
||||
_posTypes = ['user','dial','raw']
|
||||
_posTypes = ["user", "dial", "raw"]
|
||||
|
||||
def timeToStr(value,n=12):
|
||||
|
||||
def timeToStr(value, n=12):
|
||||
fmt = "%%+.%df" % n
|
||||
value = fmt%value
|
||||
#print(value)
|
||||
value = fmt % value
|
||||
# print(value)
|
||||
idx_point = value.find(".")
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value)-idx_point)//3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point+1+3*n:idx_point+1+3*(n+1)]
|
||||
#print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value) - idx_point) // 3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point + 1 + 3 * n : idx_point + 1 + 3 * (n + 1)]
|
||||
# print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
return ret_str
|
||||
|
||||
|
||||
|
||||
class Storage(object):
|
||||
def __init__(self,pvname):
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
def __init__(self, pvname):
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self.pvname = pvname
|
||||
self.last_read_time = -1
|
||||
|
||||
@@ -38,155 +39,153 @@ class Storage(object):
|
||||
lmod = self.last_modified_time
|
||||
if os.path.isfile(self._filename):
|
||||
# need to read again ?
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time :
|
||||
#print("actually reading")
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time:
|
||||
# print("actually reading")
|
||||
value = float(np.loadtxt(self._filename))
|
||||
self.last_read_time = lmod
|
||||
self.last_read = value
|
||||
else:
|
||||
value = self.last_read
|
||||
else:
|
||||
print("could not read",self._filename)
|
||||
print("could not read", self._filename)
|
||||
value = 0
|
||||
return value
|
||||
|
||||
def store(self,value):
|
||||
with open(self._filename,"w") as f:
|
||||
f.write("# %s\n"%time.asctime())
|
||||
f.write("%.15f"%value)
|
||||
|
||||
def store(self, value):
|
||||
with open(self._filename, "w") as f:
|
||||
f.write("# %s\n" % time.asctime())
|
||||
f.write("%.15f" % value)
|
||||
|
||||
|
||||
class Pockels_trigger(PV):
|
||||
""" this class is needed to store the offset in files and read in s """
|
||||
def __init__(self,pv_basename):
|
||||
|
||||
def __init__(self, pv_basename):
|
||||
pvname = pv_basename + "-RB"
|
||||
PV.__init__(self,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._storage = Storage(pvname)
|
||||
PV.__init__(self, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._storage = Storage(pvname)
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def get_dial(self):
|
||||
return super().get()*1e-6
|
||||
return super().get() * 1e-6
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self,value):
|
||||
def move(self, value):
|
||||
dial = value + self.offset
|
||||
self._pv_setvalue.put(dial*1e6)
|
||||
self._pv_setvalue.put(dial * 1e6)
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=12 )
|
||||
user = timeToStr( self.get(),n=12 )
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s"%(self.pvname,user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=12)
|
||||
user = timeToStr(self.get(), n=12)
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s" % (self.pvname, user, dial)
|
||||
|
||||
|
||||
class Phase_shifter(PV):
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
def __init__(self,pv_basename="SLAAR01-TSPL-EPL"):
|
||||
pvname = pv_basename+":CURR_DELTA_T"
|
||||
PV.__init__(self,pvname)
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
|
||||
def __init__(self, pv_basename="SLAAR01-TSPL-EPL"):
|
||||
pvname = pv_basename + ":CURR_DELTA_T"
|
||||
PV.__init__(self, pvname)
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
|
||||
def get_dial(self):
|
||||
return super().get()*1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
|
||||
def move(self,value):
|
||||
dial = value + self.offset
|
||||
dial_ps = dial*1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
self._pv_execute.put(1)
|
||||
while( np.abs(self.get()-value) > 100e-15 ): time.sleep(0.2)
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
def get_dial(self):
|
||||
return super().get() * 1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self, value):
|
||||
dial = value + self.offset
|
||||
dial_ps = dial * 1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
self._pv_execute.put(1)
|
||||
while np.abs(self.get() - value) > 100e-15:
|
||||
time.sleep(0.2)
|
||||
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=15 )
|
||||
user = timeToStr( self.get(),n=15 )
|
||||
return "Phase Shifter: user,dial = %s , %s"%(user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=15)
|
||||
user = timeToStr(self.get(), n=15)
|
||||
return "Phase Shifter: user,dial = %s , %s" % (user, dial)
|
||||
|
||||
|
||||
#_pockels_in = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
|
||||
#_pockels_out = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul3-Delay")
|
||||
#_phase_shifter = Phase_shifter("SLAAR01-TSPL-EPL")
|
||||
# _pockels_in = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
|
||||
# _pockels_out = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul3-Delay")
|
||||
# _phase_shifter = Phase_shifter("SLAAR01-TSPL-EPL")
|
||||
|
||||
|
||||
class PhaseShifterAramis:
|
||||
def __init__(self,Id,name=None,elog=None):
|
||||
def __init__(self, Id, name=None, elog=None):
|
||||
self.Id = Id
|
||||
self._pshifter = Phase_shifter(Id)
|
||||
self._elog = elog
|
||||
self.name = name
|
||||
|
||||
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
""" Adjustable convention"""
|
||||
|
||||
mover = lambda value: self._pshifter.move(\
|
||||
value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
mover=mover,
|
||||
hold=hold,
|
||||
stopper=None)
|
||||
mover = lambda value: self._pshifter.move(value)
|
||||
return Changer(target=value, parent=self, mover=mover, hold=hold, stopper=None)
|
||||
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
pass
|
||||
|
||||
|
||||
def get_current_value(self,posType='user',readback=True):
|
||||
def get_current_value(self, posType="user", readback=True):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
if posType == 'user':
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
if posType == "user":
|
||||
return self._pshifter.get()
|
||||
if posType == 'dial':
|
||||
if posType == "dial":
|
||||
return self._pshifter.get_dial()
|
||||
|
||||
def set_current_value(self,value,posType='user'):
|
||||
def set_current_value(self, value, posType="user"):
|
||||
""" Adjustable convention"""
|
||||
_keywordChecker([('posType',posType,_posTypes)])
|
||||
if posType == 'user':
|
||||
_keywordChecker([("posType", posType, _posTypes)])
|
||||
if posType == "user":
|
||||
return self._motor.set(value)
|
||||
|
||||
|
||||
class Changer:
|
||||
def __init__(self, target=None, parent=None, mover=None, hold=True, stopper=None):
|
||||
self.target = target
|
||||
self._mover = mover
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._mover,args=(target,))
|
||||
self._thread = Thread(target=self._mover, args=(target,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
@@ -198,15 +197,17 @@ class Changer:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._isAlive:
|
||||
return 'changing'
|
||||
return "changing"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
def _keywordChecker(kw_key_list_tups):
|
||||
for tkw,tkey,tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s"%(tkw,tlist)
|
||||
for tkw, tkey, tlist in kw_key_list_tups:
|
||||
assert tkey in tlist, "Keyword %s should be one of %s" % (tkw, tlist)
|
||||
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
from ..devices_general.utilities import Changer
|
||||
from epics import PV
|
||||
|
||||
|
||||
_status_messages = {
|
||||
-13: "invalid value (cannot convert to float). Move not attempted.",
|
||||
-12: "target value outside soft limits. Move not attempted.",
|
||||
-11: "drive PV is not connected: Move not attempted.",
|
||||
-8: "move started, but timed-out.",
|
||||
-7: "move started, timed-out, but appears done.",
|
||||
-5: "move started, unexpected return value from PV.put()",
|
||||
-4: "move-with-wait finished, soft limit violation seen",
|
||||
-3: "move-with-wait finished, hard limit violation seen",
|
||||
0: "move-with-wait finish OK.",
|
||||
0: "move-without-wait executed, not comfirmed",
|
||||
1: "move-without-wait executed, move confirmed",
|
||||
3: "move-without-wait finished, hard limit violation seen",
|
||||
4: "move-without-wait finished, soft limit violation seen",
|
||||
}
|
||||
|
||||
|
||||
class User_to_motor:
|
||||
def __init__(self, stage, conversion_conv, offset):
|
||||
self.conv = conversion_conv
|
||||
self._stage = stage
|
||||
self.offset = offset
|
||||
self.name = self._stage.name
|
||||
self.Id = self._stage.Id
|
||||
self._elog = self._stage._elog
|
||||
|
||||
def user_to_motor(self, user):
|
||||
motor_pos = user / self.conv
|
||||
return motor_pos
|
||||
|
||||
def get_current_value(self):
|
||||
""" Adjustable convention"""
|
||||
motor_pos = self._stage.get_current_value()
|
||||
motor_pos -= self.offset
|
||||
user = motor_pos * self.conv
|
||||
return user
|
||||
|
||||
def set_current_value(self, value):
|
||||
motor_pos = self.user_to_motor(value) + self.offset
|
||||
self._stage.set_current_value(motor_pos)
|
||||
return (value, motor_pos)
|
||||
|
||||
def changeTo(self, value, hold=False, check=True):
|
||||
value = self.user_to_motor(value) + self.offset
|
||||
user = (value - self.offset) * self.conv
|
||||
return self._stage.changeTo(value, hold, check)
|
||||
|
||||
def gui(self, guiType="xdm"):
|
||||
return self._stage.gui()
|
||||
|
||||
# spec-inspired convenience methods
|
||||
def mv(self, value):
|
||||
self._stage._currentChange = self.changeTo(value)
|
||||
|
||||
def wm(self, *args, **kwargs):
|
||||
return self.get_current_value(*args, **kwargs)
|
||||
|
||||
def mvr(self, value, *args, **kwargs):
|
||||
motor_pos = self.user_to_motor(value)
|
||||
self._stage.mvr(motor_pos)
|
||||
|
||||
def wait(self):
|
||||
self._stage._currentChange.wait()
|
||||
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
try:
|
||||
self._stage._currentChange.stop()
|
||||
except:
|
||||
self._stage.stop()
|
||||
pass
|
||||
|
||||
# return string with motor value as variable representation
|
||||
def __str__(self):
|
||||
return "Motor is at %s" % self.wm()
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __call__(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
@@ -6,7 +6,7 @@ class Changer:
|
||||
self.target = target
|
||||
self._changer = changer
|
||||
self._stopper = stopper
|
||||
self._thread = Thread(target=self._changer,args=(target,))
|
||||
self._thread = Thread(target=self._changer, args=(target,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
@@ -18,11 +18,12 @@ class Changer:
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
return "waiting"
|
||||
else:
|
||||
if self._thread.isAlive:
|
||||
return 'changing'
|
||||
return "changing"
|
||||
else:
|
||||
return 'done'
|
||||
return "done"
|
||||
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
+59
-53
@@ -6,10 +6,11 @@
|
||||
basic device object defined
|
||||
"""
|
||||
from epics.ca import poll
|
||||
from epics.pv import get_pv
|
||||
from epics.pv import get_pv
|
||||
import time
|
||||
|
||||
no_attrs = ['_ipython_display_']
|
||||
no_attrs = ["_ipython_display_"]
|
||||
|
||||
|
||||
class Device(object):
|
||||
"""A simple collection of related PVs, sharing a common prefix
|
||||
@@ -101,16 +102,24 @@ class Device(object):
|
||||
"""
|
||||
|
||||
_prefix = None
|
||||
_delim = ''
|
||||
_delim = ""
|
||||
_pvs = {}
|
||||
_init = False
|
||||
_aliases = {}
|
||||
_mutable = True
|
||||
_nonpvs = ('_prefix', '_pvs', '_delim', '_init', '_aliases',
|
||||
'_mutable', '_nonpvs')
|
||||
def __init__(self, prefix='', attrs=None,
|
||||
nonpvs=None, delim='', timeout=None,
|
||||
mutable=True, aliases={}, with_poll=True):
|
||||
_nonpvs = ("_prefix", "_pvs", "_delim", "_init", "_aliases", "_mutable", "_nonpvs")
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
prefix="",
|
||||
attrs=None,
|
||||
nonpvs=None,
|
||||
delim="",
|
||||
timeout=None,
|
||||
mutable=True,
|
||||
aliases={},
|
||||
with_poll=True,
|
||||
):
|
||||
|
||||
self._nonpvs = list(self._nonpvs)
|
||||
self._delim = delim
|
||||
@@ -125,14 +134,12 @@ class Device(object):
|
||||
|
||||
if attrs is not None:
|
||||
for attr in attrs:
|
||||
self.PV(attr, connect=False,
|
||||
connection_timeout=timeout)
|
||||
self.PV(attr, connect=False, connection_timeout=timeout)
|
||||
|
||||
if aliases:
|
||||
for attr in aliases.values():
|
||||
if attrs is None or attr not in attrs:
|
||||
self.PV(attr, connect=False,
|
||||
connection_timeout=timeout)
|
||||
self.PV(attr, connect=False, connection_timeout=timeout)
|
||||
|
||||
if with_poll:
|
||||
poll()
|
||||
@@ -181,8 +188,7 @@ class Device(object):
|
||||
up to a supplied timeout value"""
|
||||
thispv = self.PV(attr)
|
||||
thispv.wait_for_connection()
|
||||
return thispv.put(value, wait=wait, use_complete=use_complete,
|
||||
timeout=timeout)
|
||||
return thispv.put(value, wait=wait, use_complete=use_complete, timeout=timeout)
|
||||
|
||||
def get(self, attr, as_string=False, count=None):
|
||||
"""get an attribute value,
|
||||
@@ -195,15 +201,14 @@ class Device(object):
|
||||
out = {}
|
||||
for key in self._pvs:
|
||||
out[key] = self._pvs[key].get()
|
||||
if (self._pvs[key].count > 1 and
|
||||
'char' == self._pvs[key].type):
|
||||
if self._pvs[key].count > 1 and "char" == self._pvs[key].type:
|
||||
out[key] = self._pvs[key].get(as_string=True)
|
||||
return out
|
||||
|
||||
def restore_state(self, state):
|
||||
"""restore a dictionary of the values, as saved from save_state"""
|
||||
for key, val in state.items():
|
||||
if key in self._pvs and 'write' in self._pvs[key].access:
|
||||
if key in self._pvs and "write" in self._pvs[key].access:
|
||||
self._pvs[key].put(val)
|
||||
|
||||
def write_state(self, fname, state=None):
|
||||
@@ -213,43 +218,44 @@ class Device(object):
|
||||
Note that this only writes data for PVs with write-access, and count=1 (except CHAR """
|
||||
if state is None:
|
||||
state = self.save_state()
|
||||
out = ["#Device Saved State for %s, prefx='%s': %s\n" % (self.__class__.__name__,
|
||||
self._prefix, time.ctime())]
|
||||
out = [
|
||||
"#Device Saved State for %s, prefx='%s': %s\n"
|
||||
% (self.__class__.__name__, self._prefix, time.ctime())
|
||||
]
|
||||
for key in sorted(state.keys()):
|
||||
if (key in self._pvs and
|
||||
'write' in self._pvs[key].access and
|
||||
(1 == self._pvs[key].count or
|
||||
'char' == self._pvs[key].type)):
|
||||
if (
|
||||
key in self._pvs
|
||||
and "write" in self._pvs[key].access
|
||||
and (1 == self._pvs[key].count or "char" == self._pvs[key].type)
|
||||
):
|
||||
out.append("%s %s\n" % (key, state[key]))
|
||||
fout = open(fname, 'w')
|
||||
fout = open(fname, "w")
|
||||
fout.writelines(out)
|
||||
fout.close()
|
||||
|
||||
|
||||
def read_state(self, fname, restore=False):
|
||||
"""read state from file, optionally restore it"""
|
||||
finp = open(fname, 'r')
|
||||
finp = open(fname, "r")
|
||||
textlines = finp.readlines()
|
||||
finp.close()
|
||||
state = {}
|
||||
for line in textlines:
|
||||
if line.startswith('#'):
|
||||
if line.startswith("#"):
|
||||
continue
|
||||
key, strval = line[:-1].split(' ', 1)
|
||||
key, strval = line[:-1].split(" ", 1)
|
||||
if key in self._pvs:
|
||||
dtype = self._pvs[key].type
|
||||
count = self._pvs[key].count
|
||||
val = strval
|
||||
if dtype in ('double', 'float'):
|
||||
if dtype in ("double", "float"):
|
||||
val = float(val)
|
||||
elif dtype in ('int', 'long', 'short', 'enum'):
|
||||
elif dtype in ("int", "long", "short", "enum"):
|
||||
val = int(val)
|
||||
state[key] = val
|
||||
if restore:
|
||||
self.restore_state(state)
|
||||
return state
|
||||
|
||||
|
||||
def get_all(self):
|
||||
"""return a dictionary of the values of all
|
||||
current attributes"""
|
||||
@@ -266,7 +272,6 @@ class Device(object):
|
||||
"""remove a callback function to an attribute PV"""
|
||||
self.PV(attr).remove_callback(index=index)
|
||||
|
||||
|
||||
def __getattr__(self, attr):
|
||||
if attr in self._aliases:
|
||||
attr = self._aliases[attr]
|
||||
@@ -275,13 +280,12 @@ class Device(object):
|
||||
return self.get(attr)
|
||||
elif attr in self.__dict__:
|
||||
return self.__dict__[attr]
|
||||
elif self._init and self._mutable and not attr.startswith('__'):
|
||||
elif self._init and self._mutable and not attr.startswith("__"):
|
||||
pv = self.PV(attr, connect=True)
|
||||
if pv.connected:
|
||||
return pv.get()
|
||||
|
||||
raise AttributeError('%s has no attribute %s' % (self.__class__.__name__,
|
||||
attr))
|
||||
raise AttributeError("%s has no attribute %s" % (self.__class__.__name__, attr))
|
||||
|
||||
def __setattr__(self, attr, val):
|
||||
if attr in self._aliases:
|
||||
@@ -291,37 +295,39 @@ class Device(object):
|
||||
self.__dict__[attr] = val
|
||||
elif attr in self._pvs:
|
||||
self.put(attr, val)
|
||||
elif self._init and self._mutable and not attr.startswith('__'):
|
||||
elif self._init and self._mutable and not attr.startswith("__"):
|
||||
try:
|
||||
self.PV(attr)
|
||||
self.put(attr, val)
|
||||
except:
|
||||
raise AttributeError('%s has no attribute %s' % (self.__class__.__name__,
|
||||
attr))
|
||||
raise AttributeError(
|
||||
"%s has no attribute %s" % (self.__class__.__name__, attr)
|
||||
)
|
||||
elif attr in self.__dict__:
|
||||
self.__dict__[attr] = val
|
||||
elif self._init:
|
||||
raise AttributeError('%s has no attribute %s' % (self.__class__.__name__,
|
||||
attr))
|
||||
raise AttributeError(
|
||||
"%s has no attribute %s" % (self.__class__.__name__, attr)
|
||||
)
|
||||
|
||||
# def __dir__(self):
|
||||
# # there's no cleaner method to do this until Python 3.3
|
||||
# all_attrs = set(list(self._aliases.keys()) + list(self._pvs.keys()) +
|
||||
# list(self._nonpvs) +
|
||||
# list(self.__dict__.keys()) + dir(Device))
|
||||
# return list(sorted(all_attrs))
|
||||
# def __dir__(self):
|
||||
# # there's no cleaner method to do this until Python 3.3
|
||||
# all_attrs = set(list(self._aliases.keys()) + list(self._pvs.keys()) +
|
||||
# list(self._nonpvs) +
|
||||
# list(self.__dict__.keys()) + dir(Device))
|
||||
# return list(sorted(all_attrs))
|
||||
|
||||
def __repr__(self):
|
||||
"string representation"
|
||||
pref = self._prefix
|
||||
if pref.endswith('.'):
|
||||
if pref.endswith("."):
|
||||
pref = pref[:-1]
|
||||
return "<Device '%s' %i attributes>" % (pref, len(self._pvs))
|
||||
|
||||
|
||||
def pv_property(attr, as_string=False, wait=False, timeout=10.0):
|
||||
return property(lambda self: \
|
||||
self.get(attr, as_string=as_string),
|
||||
lambda self,val: \
|
||||
self.put(attr, val, wait=wait, timeout=timeout),
|
||||
None, None)
|
||||
return property(
|
||||
lambda self: self.get(attr, as_string=as_string),
|
||||
lambda self, val: self.put(attr, val, wait=wait, timeout=timeout),
|
||||
None,
|
||||
None,
|
||||
)
|
||||
|
||||
+230
-192
@@ -2,7 +2,7 @@
|
||||
"""
|
||||
This module provides support for the EPICS motor record.
|
||||
"""
|
||||
#
|
||||
#
|
||||
# Author: Mark Rivers / Matt Newville
|
||||
# Created: Sept. 16, 2002
|
||||
# Modifications:
|
||||
@@ -18,13 +18,13 @@
|
||||
#
|
||||
# Jun 14, 2010 MN
|
||||
# migrated more fully to pyepics3, using epics.Device
|
||||
#
|
||||
#
|
||||
# Jan 16, 2008 MN
|
||||
# use new EpicsCA.PV put-with-user-wait
|
||||
# wait() method no longer needed
|
||||
# added MotorException and MotorLimitException
|
||||
# many fixes to use newer python constructs
|
||||
#
|
||||
#
|
||||
# Aug 19, 2004 MN
|
||||
# 1. improved setting/checking of monitors on motor attributes
|
||||
# 2. add 'RTYP' and 'DTYP' to motor parameters.
|
||||
@@ -52,22 +52,29 @@ import time
|
||||
from epics import ca
|
||||
from . import device
|
||||
|
||||
|
||||
class MotorLimitException(Exception):
|
||||
""" raised to indicate a motor limit has been reached """
|
||||
|
||||
def __init__(self, msg, *args):
|
||||
Exception.__init__(self, *args)
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return str(self.msg)
|
||||
|
||||
|
||||
class MotorException(Exception):
|
||||
""" raised to indicate a problem with a motor"""
|
||||
|
||||
def __init__(self, msg, *args):
|
||||
Exception.__init__(self, *args)
|
||||
self.msg = msg
|
||||
|
||||
def __str__(self):
|
||||
return str(self.msg)
|
||||
|
||||
|
||||
class Motor(device.Device):
|
||||
"""Epics Motor Class for pyepics3
|
||||
|
||||
@@ -125,130 +132,130 @@ class Motor(device.Device):
|
||||
p=m.set_position(10000, step=1) # Set the current position to 10000 steps
|
||||
|
||||
"""
|
||||
|
||||
# parameter name (short), PV suffix, longer description
|
||||
|
||||
#
|
||||
_extras = {
|
||||
'disabled': '_able.VAL', }
|
||||
|
||||
_extras = {"disabled": "_able.VAL"}
|
||||
|
||||
_alias = {
|
||||
'acceleration': 'ACCL',
|
||||
'back_accel': 'BACC',
|
||||
'backlash': 'BDST',
|
||||
'back_speed': 'BVEL',
|
||||
'card': 'CARD',
|
||||
'dial_high_limit': 'DHLM',
|
||||
'direction': 'DIR',
|
||||
'dial_low_limit': 'DLLM',
|
||||
'settle_time': 'DLY',
|
||||
'done_moving': 'DMOV',
|
||||
'dial_readback': 'DRBV',
|
||||
'description': 'DESC',
|
||||
'dial_drive': 'DVAL',
|
||||
'units': 'EGU',
|
||||
'encoder_step': 'ERES',
|
||||
'freeze_offset': 'FOFF',
|
||||
'move_fraction': 'FRAC',
|
||||
'hi_severity': 'HHSV',
|
||||
'hi_alarm': 'HIGH',
|
||||
'hihi_alarm': 'HIHI',
|
||||
'high_limit': 'HLM',
|
||||
'high_limit_set': 'HLS',
|
||||
'hw_limit': 'HLSV',
|
||||
'home_forward': 'HOMF',
|
||||
'home_reverse': 'HOMR',
|
||||
'high_op_range': 'HOPR',
|
||||
'high_severity': 'HSV',
|
||||
'integral_gain': 'ICOF',
|
||||
'jog_accel': 'JAR',
|
||||
'jog_forward': 'JOGF',
|
||||
'jog_reverse': 'JOGR',
|
||||
'jog_speed': 'JVEL',
|
||||
'last_dial_val': 'LDVL',
|
||||
'low_limit': 'LLM',
|
||||
'low_limit_set': 'LLS',
|
||||
'lo_severity': 'LLSV',
|
||||
'lolo_alarm': 'LOLO',
|
||||
'low_op_range': 'LOPR',
|
||||
'low_alarm': 'LOW',
|
||||
'last_rel_val': 'LRLV',
|
||||
'last_dial_drive': 'LRVL',
|
||||
'last_SPMG': 'LSPG',
|
||||
'low_severity': 'LSV',
|
||||
'last_drive': 'LVAL',
|
||||
'soft_limit': 'LVIO',
|
||||
'in_progress': 'MIP',
|
||||
'missed': 'MISS',
|
||||
'moving': 'MOVN',
|
||||
'resolution': 'MRES',
|
||||
'motor_status': 'MSTA',
|
||||
'offset': 'OFF',
|
||||
'output_mode': 'OMSL',
|
||||
'output': 'OUT',
|
||||
'prop_gain': 'PCOF',
|
||||
'precision': 'PREC',
|
||||
'readback': 'RBV',
|
||||
'retry_max': 'RTRY',
|
||||
'retry_count': 'RCNT',
|
||||
'retry_deadband': 'RDBD',
|
||||
'dial_difference': 'RDIF',
|
||||
'raw_encoder_pos': 'REP',
|
||||
'raw_high_limit': 'RHLS',
|
||||
'raw_low_limit': 'RLLS',
|
||||
'relative_value': 'RLV',
|
||||
'raw_motor_pos': 'RMP',
|
||||
'raw_readback': 'RRBV',
|
||||
'readback_res': 'RRES',
|
||||
'raw_drive': 'RVAL',
|
||||
'dial_speed': 'RVEL',
|
||||
's_speed': 'S',
|
||||
's_back_speed': 'SBAK',
|
||||
's_base_speed': 'SBAS',
|
||||
's_max_speed': 'SMAX',
|
||||
'set': 'SET',
|
||||
'stop_go': 'SPMG',
|
||||
's_revolutions': 'SREV',
|
||||
'stop_command': 'STOP',
|
||||
't_direction': 'TDIR',
|
||||
'tweak_forward': 'TWF',
|
||||
'tweak_reverse': 'TWR',
|
||||
'tweak_val': 'TWV',
|
||||
'use_encoder': 'UEIP',
|
||||
'u_revolutions': 'UREV',
|
||||
'use_rdbl': 'URIP',
|
||||
'drive': 'VAL',
|
||||
'base_speed': 'VBAS',
|
||||
'slew_speed': 'VELO',
|
||||
'version': 'VERS',
|
||||
'max_speed': 'VMAX',
|
||||
'use_home': 'ATHM',
|
||||
'deriv_gain': 'DCOF',
|
||||
'use_torque': 'CNEN',
|
||||
'device_type': 'DTYP',
|
||||
'record_type': 'RTYP',
|
||||
'status': 'STAT'}
|
||||
|
||||
_init_list = ('VAL', 'DESC', 'RTYP', 'RBV', 'PREC', 'TWV', 'FOFF')
|
||||
_nonpvs = ('_prefix', '_pvs', '_delim', '_init', '_init_list',
|
||||
'_alias', '_extras')
|
||||
|
||||
"acceleration": "ACCL",
|
||||
"back_accel": "BACC",
|
||||
"backlash": "BDST",
|
||||
"back_speed": "BVEL",
|
||||
"card": "CARD",
|
||||
"dial_high_limit": "DHLM",
|
||||
"direction": "DIR",
|
||||
"dial_low_limit": "DLLM",
|
||||
"settle_time": "DLY",
|
||||
"done_moving": "DMOV",
|
||||
"dial_readback": "DRBV",
|
||||
"description": "DESC",
|
||||
"dial_drive": "DVAL",
|
||||
"units": "EGU",
|
||||
"encoder_step": "ERES",
|
||||
"freeze_offset": "FOFF",
|
||||
"move_fraction": "FRAC",
|
||||
"hi_severity": "HHSV",
|
||||
"hi_alarm": "HIGH",
|
||||
"hihi_alarm": "HIHI",
|
||||
"high_limit": "HLM",
|
||||
"high_limit_set": "HLS",
|
||||
"hw_limit": "HLSV",
|
||||
"home_forward": "HOMF",
|
||||
"home_reverse": "HOMR",
|
||||
"high_op_range": "HOPR",
|
||||
"high_severity": "HSV",
|
||||
"integral_gain": "ICOF",
|
||||
"jog_accel": "JAR",
|
||||
"jog_forward": "JOGF",
|
||||
"jog_reverse": "JOGR",
|
||||
"jog_speed": "JVEL",
|
||||
"last_dial_val": "LDVL",
|
||||
"low_limit": "LLM",
|
||||
"low_limit_set": "LLS",
|
||||
"lo_severity": "LLSV",
|
||||
"lolo_alarm": "LOLO",
|
||||
"low_op_range": "LOPR",
|
||||
"low_alarm": "LOW",
|
||||
"last_rel_val": "LRLV",
|
||||
"last_dial_drive": "LRVL",
|
||||
"last_SPMG": "LSPG",
|
||||
"low_severity": "LSV",
|
||||
"last_drive": "LVAL",
|
||||
"soft_limit": "LVIO",
|
||||
"in_progress": "MIP",
|
||||
"missed": "MISS",
|
||||
"moving": "MOVN",
|
||||
"resolution": "MRES",
|
||||
"motor_status": "MSTA",
|
||||
"offset": "OFF",
|
||||
"output_mode": "OMSL",
|
||||
"output": "OUT",
|
||||
"prop_gain": "PCOF",
|
||||
"precision": "PREC",
|
||||
"readback": "RBV",
|
||||
"retry_max": "RTRY",
|
||||
"retry_count": "RCNT",
|
||||
"retry_deadband": "RDBD",
|
||||
"dial_difference": "RDIF",
|
||||
"raw_encoder_pos": "REP",
|
||||
"raw_high_limit": "RHLS",
|
||||
"raw_low_limit": "RLLS",
|
||||
"relative_value": "RLV",
|
||||
"raw_motor_pos": "RMP",
|
||||
"raw_readback": "RRBV",
|
||||
"readback_res": "RRES",
|
||||
"raw_drive": "RVAL",
|
||||
"dial_speed": "RVEL",
|
||||
"s_speed": "S",
|
||||
"s_back_speed": "SBAK",
|
||||
"s_base_speed": "SBAS",
|
||||
"s_max_speed": "SMAX",
|
||||
"set": "SET",
|
||||
"stop_go": "SPMG",
|
||||
"s_revolutions": "SREV",
|
||||
"stop_command": "STOP",
|
||||
"t_direction": "TDIR",
|
||||
"tweak_forward": "TWF",
|
||||
"tweak_reverse": "TWR",
|
||||
"tweak_val": "TWV",
|
||||
"use_encoder": "UEIP",
|
||||
"u_revolutions": "UREV",
|
||||
"use_rdbl": "URIP",
|
||||
"drive": "VAL",
|
||||
"base_speed": "VBAS",
|
||||
"slew_speed": "VELO",
|
||||
"version": "VERS",
|
||||
"max_speed": "VMAX",
|
||||
"use_home": "ATHM",
|
||||
"deriv_gain": "DCOF",
|
||||
"use_torque": "CNEN",
|
||||
"device_type": "DTYP",
|
||||
"record_type": "RTYP",
|
||||
"status": "STAT",
|
||||
}
|
||||
|
||||
_init_list = ("VAL", "DESC", "RTYP", "RBV", "PREC", "TWV", "FOFF")
|
||||
_nonpvs = ("_prefix", "_pvs", "_delim", "_init", "_init_list", "_alias", "_extras")
|
||||
|
||||
def __init__(self, name=None, timeout=3.0):
|
||||
if name is None:
|
||||
raise MotorException("must supply motor name")
|
||||
|
||||
if name.endswith('.VAL'):
|
||||
if name.endswith(".VAL"):
|
||||
name = name[:-4]
|
||||
if name.endswith('.'):
|
||||
if name.endswith("."):
|
||||
name = name[:-1]
|
||||
|
||||
self._prefix = name
|
||||
device.Device.__init__(self, name, delim='.',
|
||||
attrs=self._init_list,
|
||||
timeout=timeout)
|
||||
device.Device.__init__(
|
||||
self, name, delim=".", attrs=self._init_list, timeout=timeout
|
||||
)
|
||||
|
||||
# make sure this is really a motor!
|
||||
rectype = self.get('RTYP')
|
||||
if rectype != 'motor':
|
||||
# make sure this is really a motor!
|
||||
rectype = self.get("RTYP")
|
||||
if rectype != "motor":
|
||||
raise MotorException("%s is not an Epics Motor" % name)
|
||||
|
||||
for key, val in self._extras.items():
|
||||
@@ -259,7 +266,7 @@ class Motor(device.Device):
|
||||
self._callbacks = {}
|
||||
|
||||
def __repr__(self):
|
||||
return "<epics.Motor: %s: '%s'>" % (self._prefix, self.DESC)
|
||||
return "<epics.Motor: %s: '%s'>" % (self._prefix, self.DESC)
|
||||
|
||||
def __str__(self):
|
||||
return self.__repr__()
|
||||
@@ -270,7 +277,7 @@ class Motor(device.Device):
|
||||
attr = self._alias[attr]
|
||||
if attr in self._pvs:
|
||||
return self.get(attr)
|
||||
if not attr.startswith('__'):
|
||||
if not attr.startswith("__"):
|
||||
pv = self.PV(attr, connect=True)
|
||||
if not pv.connected:
|
||||
raise MotorException("EpicsMotor has no attribute %s" % attr)
|
||||
@@ -278,19 +285,28 @@ class Motor(device.Device):
|
||||
|
||||
else:
|
||||
return self._pvs[attr]
|
||||
|
||||
|
||||
def __setattr__(self, attr, val):
|
||||
# print 'SET ATTR ', attr, val
|
||||
if attr in ('name', '_prefix', '_pvs', '_delim', '_init',
|
||||
'_alias', '_nonpvs', '_extra', '_callbacks'):
|
||||
if attr in (
|
||||
"name",
|
||||
"_prefix",
|
||||
"_pvs",
|
||||
"_delim",
|
||||
"_init",
|
||||
"_alias",
|
||||
"_nonpvs",
|
||||
"_extra",
|
||||
"_callbacks",
|
||||
):
|
||||
self.__dict__[attr] = val
|
||||
return
|
||||
return
|
||||
if attr in self._alias:
|
||||
attr = self._alias[attr]
|
||||
if attr in self._pvs:
|
||||
return self.put(attr, val)
|
||||
elif attr in self.__dict__:
|
||||
self.__dict__[attr] = val
|
||||
elif attr in self.__dict__:
|
||||
self.__dict__[attr] = val
|
||||
elif self._init:
|
||||
try:
|
||||
self.PV(attr)
|
||||
@@ -302,24 +318,35 @@ class Motor(device.Device):
|
||||
""" check motor limits:
|
||||
returns None if no limits are violated
|
||||
raises expection if a limit is violated"""
|
||||
for field, msg in (('LVIO', 'Soft limit violation'),
|
||||
('HLS', 'High hard limit violation'),
|
||||
('LLS', 'Low hard limit violation')):
|
||||
for field, msg in (
|
||||
("LVIO", "Soft limit violation"),
|
||||
("HLS", "High hard limit violation"),
|
||||
("LLS", "Low hard limit violation"),
|
||||
):
|
||||
if self.get(field) != 0:
|
||||
raise MotorLimitException(msg)
|
||||
return
|
||||
|
||||
|
||||
def within_limits(self, val, dial=False):
|
||||
""" returns whether a value for a motor is within drive limits
|
||||
with dial=True dial limits are used (default is user limits)"""
|
||||
ll_name, hl_name = 'LLM', 'HLM'
|
||||
ll_name, hl_name = "LLM", "HLM"
|
||||
if dial:
|
||||
ll_name, hl_name = 'DLLM', 'DHLM'
|
||||
return (val <= self.get(hl_name) and val >= self.get(ll_name))
|
||||
ll_name, hl_name = "DLLM", "DHLM"
|
||||
return val <= self.get(hl_name) and val >= self.get(ll_name)
|
||||
|
||||
def move(self, val=None, relative=False, wait=False, timeout=300.0,
|
||||
dial=False, step=False, raw=False,
|
||||
ignore_limits=False, confirm_move=False):
|
||||
def move(
|
||||
self,
|
||||
val=None,
|
||||
relative=False,
|
||||
wait=False,
|
||||
timeout=300.0,
|
||||
dial=False,
|
||||
step=False,
|
||||
raw=False,
|
||||
ignore_limits=False,
|
||||
confirm_move=False,
|
||||
):
|
||||
""" moves motor drive to position
|
||||
|
||||
arguments:
|
||||
@@ -353,22 +380,22 @@ class Motor(device.Device):
|
||||
step = step or raw
|
||||
|
||||
NONFLOAT, OUTSIDE_LIMITS, UNCONNECTED = -13, -12, -11
|
||||
TIMEOUT, TIMEOUT_BUTDONE = -8, -7
|
||||
UNKNOWN_ERROR = -5
|
||||
DONEW_SOFTLIM, DONEW_HARDLIM = -4, -3
|
||||
DONE_OK = 0
|
||||
MOVE_BEGUN, MOVE_BEGUN_CONFIRMED = 0, 1
|
||||
NOWAIT_SOFTLIM, NOWAIT_HARDLIM = 4, 3
|
||||
TIMEOUT, TIMEOUT_BUTDONE = -8, -7
|
||||
UNKNOWN_ERROR = -5
|
||||
DONEW_SOFTLIM, DONEW_HARDLIM = -4, -3
|
||||
DONE_OK = 0
|
||||
MOVE_BEGUN, MOVE_BEGUN_CONFIRMED = 0, 1
|
||||
NOWAIT_SOFTLIM, NOWAIT_HARDLIM = 4, 3
|
||||
try:
|
||||
val = float(val)
|
||||
except TypeError:
|
||||
return NONFLOAT
|
||||
|
||||
drv, rbv = ('VAL', 'RBV')
|
||||
drv, rbv = ("VAL", "RBV")
|
||||
if dial:
|
||||
drv, rbv = ('DVAL', 'DRBV')
|
||||
drv, rbv = ("DVAL", "DRBV")
|
||||
elif step:
|
||||
drv, rbv = ('RVAL', 'RRBV')
|
||||
drv, rbv = ("RVAL", "RRBV")
|
||||
|
||||
if relative:
|
||||
val += self.get(drv)
|
||||
@@ -381,38 +408,38 @@ class Motor(device.Device):
|
||||
stat = self.put(drv, val, wait=wait, timeout=timeout)
|
||||
if stat is None:
|
||||
return UNCONNECTED
|
||||
|
||||
if wait and stat == -1: # move started, exceeded timeout
|
||||
if self.get('DMOV') == 0:
|
||||
|
||||
if wait and stat == -1: # move started, exceeded timeout
|
||||
if self.get("DMOV") == 0:
|
||||
return TIMEOUT
|
||||
return TIMEOUT_BUTDONE
|
||||
if 1 == stat:
|
||||
if wait: # ... and finished OK
|
||||
if 1 == self.get('LVIO'):
|
||||
if 1 == self.get("LVIO"):
|
||||
return DONEW_SOFTLIM
|
||||
elif 1 == self.get('HLS') or 1 == self.get('LLS'):
|
||||
elif 1 == self.get("HLS") or 1 == self.get("LLS"):
|
||||
return DONEW_HARDLIM
|
||||
return DONE_OK
|
||||
else:
|
||||
if 1 == self.get('LVIO') or confirm_move:
|
||||
ca.poll(evt=1.e-2)
|
||||
if 1 == self.get("LVIO") or confirm_move:
|
||||
ca.poll(evt=1.0e-2)
|
||||
moving = False
|
||||
if confirm_move:
|
||||
t0 = time.time()
|
||||
while self.get('MOVN')==0:
|
||||
ca.poll(evt=1.e-3)
|
||||
if time.time() - t0 > 0.25: break
|
||||
if 1 == self.get('MOVN'):
|
||||
while self.get("MOVN") == 0:
|
||||
ca.poll(evt=1.0e-3)
|
||||
if time.time() - t0 > 0.25:
|
||||
break
|
||||
if 1 == self.get("MOVN"):
|
||||
return MOVE_BEGUN_CONFIRMED
|
||||
elif 1 == self.get('LVIO'):
|
||||
elif 1 == self.get("LVIO"):
|
||||
return NOWAIT_SOFTLIM
|
||||
elif 1 == self.get('HLS') or 1 == self.get('LLS'):
|
||||
elif 1 == self.get("HLS") or 1 == self.get("LLS"):
|
||||
return NOWAIT_HARDLIM
|
||||
else:
|
||||
return MOVE_BEGUN
|
||||
return UNKNOWN_ERROR
|
||||
|
||||
|
||||
def get_position(self, dial=False, readback=False, step=False, raw=False):
|
||||
"""
|
||||
Returns the target or readback motor position in user, dial or step
|
||||
@@ -443,16 +470,16 @@ class Motor(device.Device):
|
||||
p=m.get_position(dial=True) # Read the target position in dial coordinates
|
||||
p=m.get_position(readback=True, step=True) # Read the actual position in steps
|
||||
"""
|
||||
pos, rbv = ('VAL','RBV')
|
||||
pos, rbv = ("VAL", "RBV")
|
||||
if dial:
|
||||
pos, rbv = ('DVAL', 'DRBV')
|
||||
pos, rbv = ("DVAL", "DRBV")
|
||||
elif step or raw:
|
||||
pos, rbv = ('RVAL', 'RRBV')
|
||||
pos, rbv = ("RVAL", "RRBV")
|
||||
if readback:
|
||||
pos = rbv
|
||||
return self.get(pos)
|
||||
|
||||
def tweak(self, direction='foreward', wait=False, timeout=300.0):
|
||||
|
||||
def tweak(self, direction="foreward", wait=False, timeout=300.0):
|
||||
""" move the motor by the tweak_val
|
||||
|
||||
takes optional args:
|
||||
@@ -461,11 +488,11 @@ class Motor(device.Device):
|
||||
wait wait for move to complete before returning (T/F) [F]
|
||||
timeout max time for move to complete (in seconds) [300]
|
||||
"""
|
||||
|
||||
ifield = 'TWF'
|
||||
if direction.startswith('rev') or direction.startswith('back'):
|
||||
ifield = 'TWR'
|
||||
|
||||
|
||||
ifield = "TWF"
|
||||
if direction.startswith("rev") or direction.startswith("back"):
|
||||
ifield = "TWR"
|
||||
|
||||
stat = self.put(ifield, 1, wait=wait, timeout=timeout)
|
||||
ret = stat
|
||||
if stat == 1:
|
||||
@@ -478,7 +505,6 @@ class Motor(device.Device):
|
||||
ret = -1
|
||||
return ret
|
||||
|
||||
|
||||
def set_position(self, position, dial=False, step=False, raw=False):
|
||||
"""
|
||||
Sets the motor position in user, dial or step coordinates.
|
||||
@@ -507,25 +533,25 @@ class Motor(device.Device):
|
||||
"""
|
||||
|
||||
# Put the motor in "SET" mode
|
||||
self.put('SET', 1)
|
||||
self.put("SET", 1)
|
||||
|
||||
# determine which drive value to use
|
||||
drv = 'VAL'
|
||||
drv = "VAL"
|
||||
if dial:
|
||||
drv = 'DVAL'
|
||||
drv = "DVAL"
|
||||
elif step or raw:
|
||||
drv = 'RVAL'
|
||||
drv = "RVAL"
|
||||
|
||||
self.put(drv, position)
|
||||
|
||||
|
||||
# Put the motor back in "Use" mode
|
||||
self.put('SET', 0)
|
||||
|
||||
self.put("SET", 0)
|
||||
|
||||
def get_pv(self, attr):
|
||||
"return PV for a field"
|
||||
return self.PV(attr)
|
||||
|
||||
def clear_callback(self, attr='drive'):
|
||||
def clear_callback(self, attr="drive"):
|
||||
"clears callback for attribute"
|
||||
try:
|
||||
index = self._callbacks.get(attr, None)
|
||||
@@ -534,11 +560,11 @@ class Motor(device.Device):
|
||||
except:
|
||||
self.PV(attr).clear_callbacks()
|
||||
|
||||
def set_callback(self, attr='VAL', callback=None, kws=None):
|
||||
def set_callback(self, attr="VAL", callback=None, kws=None):
|
||||
"define a callback for an attribute"
|
||||
self.get(attr)
|
||||
kw_args = {}
|
||||
kw_args['motor_field'] = attr
|
||||
kw_args["motor_field"] = attr
|
||||
if kws is not None:
|
||||
kw_args.update(kws)
|
||||
|
||||
@@ -557,7 +583,7 @@ class Motor(device.Device):
|
||||
def stop(self):
|
||||
"stop motor as soon as possible"
|
||||
self.STOP = 1
|
||||
|
||||
|
||||
def make_step_list(self, minstep=0.0, maxstep=None, decades=10):
|
||||
""" create a reasonable list of motor steps, as for a dropdown menu
|
||||
The list is based on motor range Mand precision"""
|
||||
@@ -566,28 +592,39 @@ class Motor(device.Device):
|
||||
maxstep = 0.6 * abs(self.HLM - self.LLM)
|
||||
steplist = []
|
||||
for i in range(decades):
|
||||
for step in [j* 10**(i - self.PREC) for j in (1, 2, 5)]:
|
||||
if (step <= maxstep and step > 0.98*minstep):
|
||||
for step in [j * 10 ** (i - self.PREC) for j in (1, 2, 5)]:
|
||||
if step <= maxstep and step > 0.98 * minstep:
|
||||
steplist.append(step)
|
||||
return steplist
|
||||
|
||||
|
||||
def get_info(self):
|
||||
"return information, current field values"
|
||||
out = {}
|
||||
for attr in ('DESC', 'VAL', 'RBV', 'PREC', 'VELO', 'STAT',
|
||||
'SET', 'TWV','LLM', 'HLM', 'SPMG'):
|
||||
for attr in (
|
||||
"DESC",
|
||||
"VAL",
|
||||
"RBV",
|
||||
"PREC",
|
||||
"VELO",
|
||||
"STAT",
|
||||
"SET",
|
||||
"TWV",
|
||||
"LLM",
|
||||
"HLM",
|
||||
"SPMG",
|
||||
):
|
||||
out[attr] = self.get(attr, as_string=True)
|
||||
return out
|
||||
|
||||
|
||||
def show_info(self):
|
||||
" show basic motor settings "
|
||||
ca.poll()
|
||||
out = []
|
||||
out.append(repr(self))
|
||||
out.append( "--------------------------------------")
|
||||
out.append("--------------------------------------")
|
||||
for nam, val in self.get_info().items():
|
||||
if len(nam) < 16:
|
||||
nam = "%s%s" % (nam, ' '*(16-len(nam)))
|
||||
nam = "%s%s" % (nam, " " * (16 - len(nam)))
|
||||
out.append("%s = %s" % (nam, val))
|
||||
out.append("--------------------------------------")
|
||||
ca.write("\n".join(out))
|
||||
@@ -600,23 +637,24 @@ class Motor(device.Device):
|
||||
add("# field value PV name")
|
||||
add("#------------------------------------------------------------")
|
||||
ca.poll()
|
||||
klist = list( self._alias.keys())
|
||||
klist = list(self._alias.keys())
|
||||
klist.sort()
|
||||
for attr in klist:
|
||||
suff = self._alias[attr]
|
||||
# pvn = self._alias[attr]
|
||||
label = attr + ' '*(18-min(18, len(attr)))
|
||||
label = attr + " " * (18 - min(18, len(attr)))
|
||||
value = self.get(suff, as_string=True)
|
||||
pvname = self.PV(suff).pvname
|
||||
pvname = self.PV(suff).pvname
|
||||
if value is None:
|
||||
value = 'Not Connected??'
|
||||
value = value + ' '*(18-min(18, len(value)))
|
||||
value = "Not Connected??"
|
||||
value = value + " " * (18 - min(18, len(value)))
|
||||
# print " %s %s %s" % (label, value, pvname)
|
||||
add(" %s %s %s" % (label, value, pvname))
|
||||
|
||||
|
||||
ca.write("\n".join(out))
|
||||
|
||||
if (__name__ == '__main__'):
|
||||
|
||||
if __name__ == "__main__":
|
||||
for arg in sys.argv[1:]:
|
||||
m = Motor(arg)
|
||||
m.show_info()
|
||||
|
||||
@@ -1,26 +1,26 @@
|
||||
from epics import PV
|
||||
from epics import PV
|
||||
|
||||
|
||||
class EnumWrapper:
|
||||
def __init__(self,pvname,elog=None):
|
||||
def __init__(self, pvname, elog=None):
|
||||
self._elog = elog
|
||||
self._pv = PV(pvname)
|
||||
self.names = self._pv.enum_strs
|
||||
#print(self.names)
|
||||
#if self.names:
|
||||
self.setters = \
|
||||
Positioner(\
|
||||
[(nam,lambda:self.set(nam))
|
||||
for nam in self.names])
|
||||
# print(self.names)
|
||||
# if self.names:
|
||||
self.setters = Positioner([(nam, lambda: self.set(nam)) for nam in self.names])
|
||||
|
||||
def set(self,target):
|
||||
def set(self, target):
|
||||
if type(target) is str:
|
||||
assert target in self.names,\
|
||||
"set value need to be one of \n %s"%self.names
|
||||
assert target in self.names, (
|
||||
"set value need to be one of \n %s" % self.names
|
||||
)
|
||||
self._pv.put(self.names.index(target))
|
||||
elif type(target) is int:
|
||||
assert target>=0, 'set integer needs to be positive'
|
||||
assert target<len(self.names)
|
||||
assert target >= 0, "set integer needs to be positive"
|
||||
assert target < len(self.names)
|
||||
self._pv.put(target)
|
||||
|
||||
def get(self):
|
||||
return self._pv.get()
|
||||
|
||||
@@ -31,19 +31,18 @@ class EnumWrapper:
|
||||
return self.get_name()
|
||||
|
||||
|
||||
|
||||
class MonitorAccumulator:
|
||||
def __init__(self,pv,attr=None,keywords=['value','timestamp']):
|
||||
def __init__(self, pv, attr=None, keywords=["value", "timestamp"]):
|
||||
self.pv = pv
|
||||
self.attr = attr
|
||||
self.values = []
|
||||
self.keywords = keywords
|
||||
|
||||
def _accumulate(self,**kwargs):
|
||||
def _accumulate(self, **kwargs):
|
||||
self.values.append([kwargs[kw] for kw in self.keywords])
|
||||
|
||||
def accumulate(self):
|
||||
self.pv.add_callback(self._accumulate,self.attr)
|
||||
self.pv.add_callback(self._accumulate, self.attr)
|
||||
|
||||
def stop(self):
|
||||
self.pv.remove_callbacks(self.attr)
|
||||
@@ -54,17 +53,12 @@ class MonitorAccumulator:
|
||||
self.values = []
|
||||
self.accumulate()
|
||||
return d
|
||||
|
||||
|
||||
|
||||
|
||||
class Positioner:
|
||||
def __init__(self,list_of_name_func_tuples):
|
||||
for name,func in list_of_name_func_tuples:
|
||||
tname = name.replace(' ','_')\
|
||||
.replace('.','p')
|
||||
def __init__(self, list_of_name_func_tuples):
|
||||
for name, func in list_of_name_func_tuples:
|
||||
tname = name.replace(" ", "_").replace(".", "p")
|
||||
if tname[0].isnumeric():
|
||||
tname = 'v'+tname
|
||||
tname = "v" + tname
|
||||
self.__dict__[tname] = func
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
startup_lazy = False
|
||||
|
||||
scopes = [
|
||||
{"name": "Alvra", "facility": "SwissFEL", "module": "alvra"},
|
||||
{"name": "Bernina", "facility": "SwissFEL", "module": "bernina"},
|
||||
]
|
||||
+132
-90
@@ -1,129 +1,171 @@
|
||||
import sys
|
||||
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class huber:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
### Huber sample stages ###
|
||||
self.x = MotorRecord(Id+':MOTOR_X1')
|
||||
self.y = MotorRecord(Id+':MOTOR_Y1')
|
||||
self.z = MotorRecord(Id+':MOTOR_Z1')
|
||||
self.x = MotorRecord(Id + ":MOTOR_X1")
|
||||
self.y = MotorRecord(Id + ":MOTOR_Y1")
|
||||
self.z = MotorRecord(Id + ":MOTOR_Z1")
|
||||
|
||||
def __str__(self):
|
||||
return "Huber Sample Stage %s\nx: %s mm\ny: %s mm\nz: %s mm" \
|
||||
%(self.Id, self.x.wm(),self.y.wm(),self.z.wm())
|
||||
return "Huber Sample Stage %s\nx: %s mm\ny: %s mm\nz: %s mm" % (
|
||||
self.Id,
|
||||
self.x.wm(),
|
||||
self.y.wm(),
|
||||
self.z.wm(),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "{'X': %s, 'Y': %s, 'Z': %s}"%(self.x.wm(),self.y.wm(),self.z.wm())
|
||||
return "{'X': %s, 'Y': %s, 'Z': %s}" % (self.x.wm(), self.y.wm(), self.z.wm())
|
||||
|
||||
|
||||
class vonHamosBragg:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
|
||||
### Owis linear stages ###
|
||||
self.cry1 = MotorRecord(Id+':CRY_1')
|
||||
self.cry2 = MotorRecord(Id+':CRY_2')
|
||||
self.cry1 = MotorRecord(Id + ":CRY_1")
|
||||
self.cry2 = MotorRecord(Id + ":CRY_2")
|
||||
|
||||
def __str__(self):
|
||||
return "von Hamos positions\nCrystal 1: %s mm\nCrystal 2: %s mm" \
|
||||
% (self.cry1.wm(),self.cry2.wm())
|
||||
return "von Hamos positions\nCrystal 1: %s mm\nCrystal 2: %s mm" % (
|
||||
self.cry1.wm(),
|
||||
self.cry2.wm(),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "{'Crystal 1': %s, 'Crystal 2': %s}" % (self.cry1.wm(),self.cry2.wm())
|
||||
return "{'Crystal 1': %s, 'Crystal 2': %s}" % (self.cry1.wm(), self.cry2.wm())
|
||||
|
||||
|
||||
class table:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
### ADC optical table ###
|
||||
self.x1 = MotorRecord(Id+':MOTOR_X1')
|
||||
self.y1 = MotorRecord(Id+':MOTOR_Y1')
|
||||
self.y2 = MotorRecord(Id+':MOTOR_Y2')
|
||||
self.y3 = MotorRecord(Id+':MOTOR_Y3')
|
||||
self.z1 = MotorRecord(Id+':MOTOR_Z1')
|
||||
self.z2 = MotorRecord(Id+':MOTOR_Z2')
|
||||
self.x = MotorRecord(Id+':W_X')
|
||||
self.y = MotorRecord(Id+':W_Y')
|
||||
self.z = MotorRecord(Id+':W_Z')
|
||||
self.pitch = MotorRecord(Id+':W_RX')
|
||||
self.yaw = MotorRecord(Id+':W_RY')
|
||||
self.pitch = MotorRecord(Id+':W_RX')
|
||||
self.modeSP = PV(Id+':MODE_SP')
|
||||
self.status = PV(Id+':SS_STATUS')
|
||||
|
||||
self.x1 = MotorRecord(Id + ":MOTOR_X1")
|
||||
self.y1 = MotorRecord(Id + ":MOTOR_Y1")
|
||||
self.y2 = MotorRecord(Id + ":MOTOR_Y2")
|
||||
self.y3 = MotorRecord(Id + ":MOTOR_Y3")
|
||||
self.z1 = MotorRecord(Id + ":MOTOR_Z1")
|
||||
self.z2 = MotorRecord(Id + ":MOTOR_Z2")
|
||||
self.x = MotorRecord(Id + ":W_X")
|
||||
self.y = MotorRecord(Id + ":W_Y")
|
||||
self.z = MotorRecord(Id + ":W_Z")
|
||||
self.pitch = MotorRecord(Id + ":W_RX")
|
||||
self.yaw = MotorRecord(Id + ":W_RY")
|
||||
self.pitch = MotorRecord(Id + ":W_RX")
|
||||
self.modeSP = PV(Id + ":MODE_SP")
|
||||
self.status = PV(Id + ":SS_STATUS")
|
||||
|
||||
def __str__(self):
|
||||
return "Prime Table position\nx: %s mm\ny: %s mm\nz: %s\npitch: %s mrad\nyaw: %s mrad\nmode SP: %s \nstatus: %s" \
|
||||
% (self.x.wm(),self.y.wm(),self.z.wm(),self.pitch.wm(),self.yaw.wm(),self.modeSP.get(as_string=True),self.status.get())
|
||||
return (
|
||||
"Prime Table position\nx: %s mm\ny: %s mm\nz: %s\npitch: %s mrad\nyaw: %s mrad\nmode SP: %s \nstatus: %s"
|
||||
% (
|
||||
self.x.wm(),
|
||||
self.y.wm(),
|
||||
self.z.wm(),
|
||||
self.pitch.wm(),
|
||||
self.yaw.wm(),
|
||||
self.modeSP.get(as_string=True),
|
||||
self.status.get(),
|
||||
)
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "{'x': %s, 'y': %s,'z': %s,'pitch': %s, 'yaw': %s, 'mode set point': %s,'status': %s}" \
|
||||
% (self.x,self.y,self.z,self.pitch,self.yaw,self.modeSP.get(as_string=True),self.status.get())
|
||||
return (
|
||||
"{'x': %s, 'y': %s,'z': %s,'pitch': %s, 'yaw': %s, 'mode set point': %s,'status': %s}"
|
||||
% (
|
||||
self.x,
|
||||
self.y,
|
||||
self.z,
|
||||
self.pitch,
|
||||
self.yaw,
|
||||
self.modeSP.get(as_string=True),
|
||||
self.status.get(),
|
||||
)
|
||||
)
|
||||
|
||||
|
||||
class microscope:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
|
||||
### Microscope motors ###
|
||||
self.focus = MotorRecord(Id+':FOCUS')
|
||||
self.zoom = MotorRecord(Id+':ZOOM')
|
||||
self.focus = MotorRecord(Id + ":FOCUS")
|
||||
self.zoom = MotorRecord(Id + ":ZOOM")
|
||||
self._smaractaxes = {
|
||||
'gonio': '_xmic_gon', # will become self.gonio
|
||||
'rot': '_xmic_rot'} # """ self.rot
|
||||
"gonio": "_xmic_gon", # will become self.gonio
|
||||
"rot": "_xmic_rot",
|
||||
} # """ self.rot
|
||||
|
||||
def __str__(self):
|
||||
return "Microscope positions\nfocus: %s\nzoom: %s\ngonio: %s\nrot: %s"\
|
||||
% (self.focus.wm(),self.zoom.wm(),self.gonio.wm(),self.rot.wm())
|
||||
|
||||
return "Microscope positions\nfocus: %s\nzoom: %s\ngonio: %s\nrot: %s" % (
|
||||
self.focus.wm(),
|
||||
self.zoom.wm(),
|
||||
self.gonio.wm(),
|
||||
self.rot.wm(),
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return "{'Focus': %s, 'Zoom': %s, 'Gonio': %s, 'Rot': %s}"\
|
||||
% (self.focus.wm(),self.zoom.wm(),self.gonio.wm(),self.rot.wm())
|
||||
|
||||
return "{'Focus': %s, 'Zoom': %s, 'Gonio': %s, 'Rot': %s}" % (
|
||||
self.focus.wm(),
|
||||
self.zoom.wm(),
|
||||
self.gonio.wm(),
|
||||
self.rot.wm(),
|
||||
)
|
||||
|
||||
|
||||
# prism (as a SmarAct-only stage) is defined purely in ../aliases/alvra.py
|
||||
|
||||
|
||||
|
||||
class vacuum:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
# Vacuum PVs for Prime chamber
|
||||
self.spectrometerP = PV(Id + 'MFR125-600:PRESSURE')
|
||||
self.intermediateP = PV(Id + 'MCP125-510:PRESSURE')
|
||||
self.sampleP = PV(Id + 'MCP125-410:PRESSURE')
|
||||
self.pDiff = PV('SARES11-EVSP-010:DIFFERENT')
|
||||
self.regulationStatus = PV('SARES11-EVGA-STM010:ACTIV_MODE')
|
||||
self.spectrometerTurbo = PV(Id + 'PTM125-600:HZ')
|
||||
self.intermediateTurbo = PV(Id + 'PTM125-400:HZ')
|
||||
self.sampleTurbo = PV(Id + 'PTM125-500:HZ')
|
||||
self.KBvalve = PV(Id + 'VPG124-230:PLC_OPEN')
|
||||
|
||||
def __str__(self):
|
||||
valve = self.KBvalve.get()
|
||||
if valve == 0:
|
||||
valveStr = "KB valve closed"
|
||||
else:
|
||||
valveStr = "KB valve open"
|
||||
currSpecP = self.spectrometerP.get()
|
||||
currInterP = self.intermediateP.get()
|
||||
currSamP = self.sampleP.get()
|
||||
currPDiff = self.pDiff.get()
|
||||
regStatusStr = self.regulationStatus.get(as_string=True)
|
||||
currSpecTurbo = self.spectrometerTurbo.get()
|
||||
currInterTurbo = self.intermediateTurbo.get()
|
||||
currSamTurbo = self.sampleTurbo.get()
|
||||
|
||||
s = '**Prime chamber vacuum status**\n\n'
|
||||
s += 'Regulation mode: %s\n'%regStatusStr
|
||||
s += '%s\n'%valveStr
|
||||
s += 'Spectrometer pressure: %.3g mbar\n'%currSpecP
|
||||
s += 'Spectrometer Turbo pump: %s Hz\n'%currSpecTurbo
|
||||
s += 'Intermediate pressure: %.3g mbar\n'%currInterP
|
||||
s += 'Intermediate Turbo pump: %s Hz\n'%currInterTurbo
|
||||
s += 'Sample pressure: %.3g mbar\n'%currSamP
|
||||
s += 'Sample Turbo pump: %s Hz\n'%currSamTurbo
|
||||
s += 'Intermediate/Sample pressure difference: %.3g mbar\n'%currPDiff
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
# Vacuum PVs for Prime chamber
|
||||
self.spectrometerP = PV(Id + "MFR125-600:PRESSURE")
|
||||
self.intermediateP = PV(Id + "MCP125-510:PRESSURE")
|
||||
self.sampleP = PV(Id + "MCP125-410:PRESSURE")
|
||||
self.pDiff = PV("SARES11-EVSP-010:DIFFERENT")
|
||||
self.regulationStatus = PV("SARES11-EVGA-STM010:ACTIV_MODE")
|
||||
self.spectrometerTurbo = PV(Id + "PTM125-600:HZ")
|
||||
self.intermediateTurbo = PV(Id + "PTM125-400:HZ")
|
||||
self.sampleTurbo = PV(Id + "PTM125-500:HZ")
|
||||
self.KBvalve = PV(Id + "VPG124-230:PLC_OPEN")
|
||||
|
||||
def __str__(self):
|
||||
valve = self.KBvalve.get()
|
||||
if valve == 0:
|
||||
valveStr = "KB valve closed"
|
||||
else:
|
||||
valveStr = "KB valve open"
|
||||
currSpecP = self.spectrometerP.get()
|
||||
currInterP = self.intermediateP.get()
|
||||
currSamP = self.sampleP.get()
|
||||
currPDiff = self.pDiff.get()
|
||||
regStatusStr = self.regulationStatus.get(as_string=True)
|
||||
currSpecTurbo = self.spectrometerTurbo.get()
|
||||
currInterTurbo = self.intermediateTurbo.get()
|
||||
currSamTurbo = self.sampleTurbo.get()
|
||||
|
||||
s = "**Prime chamber vacuum status**\n\n"
|
||||
s += "Regulation mode: %s\n" % regStatusStr
|
||||
s += "%s\n" % valveStr
|
||||
s += "Spectrometer pressure: %.3g mbar\n" % currSpecP
|
||||
s += "Spectrometer Turbo pump: %s Hz\n" % currSpecTurbo
|
||||
s += "Intermediate pressure: %.3g mbar\n" % currInterP
|
||||
s += "Intermediate Turbo pump: %s Hz\n" % currInterTurbo
|
||||
s += "Sample pressure: %.3g mbar\n" % currSamP
|
||||
s += "Sample Turbo pump: %s Hz\n" % currSamTurbo
|
||||
s += "Intermediate/Sample pressure difference: %.3g mbar\n" % currPDiff
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
@@ -1,35 +1,32 @@
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class XTG:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
|
||||
### sample smaract motors ###
|
||||
self.sx = SmarActRecord(Id+':TRX3')
|
||||
self.sy = SmarActRecord(Id+':TRY3')
|
||||
|
||||
self.sx = SmarActRecord(Id + ":TRX3")
|
||||
self.sy = SmarActRecord(Id + ":TRY3")
|
||||
|
||||
### grating 1 motors ###
|
||||
self.g1x = SmarActRecord(Id+':TRX1')
|
||||
self.g1y = SmarActRecord(Id+':TRY1')
|
||||
self.g1z = SmarActRecord(Id+':TRZ1')
|
||||
self.g1x = SmarActRecord(Id + ":TRX1")
|
||||
self.g1y = SmarActRecord(Id + ":TRY1")
|
||||
self.g1z = SmarActRecord(Id + ":TRZ1")
|
||||
### grating 2 motors ###
|
||||
self.g2x = SmarActRecord(Id+':TRX2')
|
||||
self.g2y = SmarActRecord(Id+':TRY2')
|
||||
self.g2z = SmarActRecord(Id+':TRZ2')
|
||||
self.g2x = SmarActRecord(Id + ":TRX2")
|
||||
self.g2y = SmarActRecord(Id + ":TRY2")
|
||||
self.g2z = SmarActRecord(Id + ":TRZ2")
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****SmarAct motor positions******\n'
|
||||
ostr = "*****SmarAct motor positions******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
@@ -0,0 +1,91 @@
|
||||
import sys
|
||||
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
from ..aliases import Alias
|
||||
|
||||
|
||||
def addMotorRecordToSelf(self,name=None, Id=None):
|
||||
self.__dict__[name] = MotorRecord(Id, name=name)
|
||||
self.alias.append(self.__dict__[name].alias)
|
||||
|
||||
|
||||
class XRD:
|
||||
def __init__(self, name=None, Id=None, configuration=[]):
|
||||
"""X-ray diffractometer platform in AiwssFEL Bernina.\
|
||||
<configuration> : list of elements mounted on
|
||||
the plaform, options are kappa, nutable, hlgonio, polana"""
|
||||
self.Id = Id
|
||||
self.name = name
|
||||
self.alias = Alias(name)
|
||||
|
||||
|
||||
### motors base platform ###
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TX", name="xbase")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TY", name="ybase")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_RX", name="rxbase")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_MY_RYTH", name="omega")
|
||||
|
||||
|
||||
### motors XRD detector arm ###
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_NY_RY2TH", name="gamma")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_DT_RX2TH", name="delta")
|
||||
|
||||
### motors XRD area detector branch ###
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_D_T", name="tdet")
|
||||
|
||||
### motors XRD polarisation analyzer branch ###
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_P_T", name="tpol")
|
||||
#missing: slits of flight tube
|
||||
|
||||
### motors heavy load goniometer ###
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TBL_TX", name="xhl")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TBL_TZ", name="zhl")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TBL_TY", name="yhl")
|
||||
try:
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TBL_RX", name="rxhl")
|
||||
except:
|
||||
print("XRD.rxhl not found")
|
||||
pass
|
||||
try:
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_TBL_RY", name="rzhl")
|
||||
except:
|
||||
print("XRD.rzhl not found")
|
||||
pass
|
||||
|
||||
### motors nu table ###
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_HEX_TX", name="teta")
|
||||
addMotorRecordToSelf(self, Id=Id + ":MOT_HEX_RX", name="eta")
|
||||
|
||||
### motors PI hexapod ###
|
||||
self.hex_x = PV("SARES20-HEX_PI:POSI-X")
|
||||
self.hex_y = PV("SARES20-HEX_PI:POSI-Y")
|
||||
self.hex_z = PV("SARES20-HEX_PI:POSI-Z")
|
||||
self.hex_u = PV("SARES20-HEX_PI:POSI-U")
|
||||
self.hex_v = PV("SARES20-HEX_PI:POSI-V")
|
||||
self.hex_w = PV("SARES20-HEX_PI:POSI-W")
|
||||
|
||||
def __repr__(self):
|
||||
s = "**Heavy Load**\n"
|
||||
motors = "xmu mu tth xbase ybase".split()
|
||||
for motor in motors:
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
|
||||
s += " - xhl %.4f\n" % (self.xhl.wm())
|
||||
s += " - yhl %.4f\n" % (self.yhl.wm())
|
||||
s += " - zhl %.4f\n" % (self.zhl.wm())
|
||||
s += " - th %.4f\n" % (self.th.wm())
|
||||
s += "\n"
|
||||
|
||||
s += "**Gonio**\n"
|
||||
motors = "xmu mu tth delta det_z cam_z xbase ybase".split()
|
||||
for motor in motors:
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
s += "\n"
|
||||
|
||||
s += "**Hexapod**\n"
|
||||
motors = "x y z u v w".split()
|
||||
for motor in motors:
|
||||
s += " - hex_%s %.4f\n" % (motor, getattr(self, "hex_" + motor).get())
|
||||
return s
|
||||
@@ -1,35 +1,36 @@
|
||||
import sys
|
||||
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class GPS:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
|
||||
### motors heavy load gps table ###
|
||||
self.xhl = MotorRecord(Id+':MOT_TBL_TX')
|
||||
self.zhl = MotorRecord(Id+':MOT_TBL_TZ')
|
||||
self.yhl = MotorRecord(Id+':MOT_TBL_TY')
|
||||
self.th = MotorRecord(Id+':MOT_MY_RYTH')
|
||||
self.xhl = MotorRecord(Id + ":MOT_TBL_TX")
|
||||
self.zhl = MotorRecord(Id + ":MOT_TBL_TZ")
|
||||
self.yhl = MotorRecord(Id + ":MOT_TBL_TY")
|
||||
self.th = MotorRecord(Id + ":MOT_MY_RYTH")
|
||||
try:
|
||||
self.rxhl = MotorRecord(Id+':MOT_TBL_RX')
|
||||
self.rxhl = MotorRecord(Id + ":MOT_TBL_RX")
|
||||
except:
|
||||
print ('GPS.pitch not found')
|
||||
print("GPS.pitch not found")
|
||||
pass
|
||||
try:
|
||||
self.ryhl = MotorRecord(Id+':MOT_TBL_RY')
|
||||
self.ryhl = MotorRecord(Id + ":MOT_TBL_RY")
|
||||
except:
|
||||
print ('GPS.roll not found')
|
||||
print("GPS.roll not found")
|
||||
pass
|
||||
|
||||
### motors heavy load gonio base ###
|
||||
self.xmu = MotorRecord(Id+':MOT_HEX_TX')
|
||||
self.mu = MotorRecord(Id+':MOT_HEX_RX')
|
||||
self.tth = MotorRecord(Id+':MOT_NY_RY2TH')
|
||||
self.xbase = MotorRecord(Id+':MOT_TX')
|
||||
self.ybase = MotorRecord(Id+':MOT_TY')
|
||||
self.xmu = MotorRecord(Id + ":MOT_HEX_TX")
|
||||
self.mu = MotorRecord(Id + ":MOT_HEX_RX")
|
||||
self.tth = MotorRecord(Id + ":MOT_NY_RY2TH")
|
||||
self.xbase = MotorRecord(Id + ":MOT_TX")
|
||||
self.ybase = MotorRecord(Id + ":MOT_TY")
|
||||
|
||||
self.hex_x = PV("SARES20-HEX_PI:POSI-X")
|
||||
self.hex_y = PV("SARES20-HEX_PI:POSI-Y")
|
||||
@@ -42,23 +43,22 @@ class GPS:
|
||||
s = "**Heavy Load**\n"
|
||||
motors = "xmu mu tth xbase ybase".split()
|
||||
for motor in motors:
|
||||
s+= " - %s %.4f\n"%(motor,getattr(self,motor).wm())
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
|
||||
s+= " - HLX %.4f\n"%(self.xhl.wm())
|
||||
s+= " - HLY %.4f\n"%(self.yhl.wm())
|
||||
s+= " - HLZ %.4f\n"%(self.zhl.wm())
|
||||
s+= " - HLTheta %.4f\n"%(self.th.wm())
|
||||
s+= "\n"
|
||||
s += " - HLX %.4f\n" % (self.xhl.wm())
|
||||
s += " - HLY %.4f\n" % (self.yhl.wm())
|
||||
s += " - HLZ %.4f\n" % (self.zhl.wm())
|
||||
s += " - HLTheta %.4f\n" % (self.th.wm())
|
||||
s += "\n"
|
||||
|
||||
s+= "**Gonio**\n"
|
||||
s += "**Gonio**\n"
|
||||
motors = "xmu mu tth xbase ybase".split()
|
||||
for motor in motors:
|
||||
s+= " - %s %.4f\n"%(motor,getattr(self,motor).wm())
|
||||
s+= "\n"
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
s += "\n"
|
||||
|
||||
s+= "**Hexapod**\n"
|
||||
s += "**Hexapod**\n"
|
||||
motors = "x y z u v w".split()
|
||||
for motor in motors:
|
||||
s+= " - hex_%s %.4f\n"%(motor,getattr(self,"hex_"+motor).get())
|
||||
s += " - hex_%s %.4f\n" % (motor, getattr(self, "hex_" + motor).get())
|
||||
return s
|
||||
|
||||
|
||||
Executable
+69
@@ -0,0 +1,69 @@
|
||||
import sys
|
||||
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class XRD:
|
||||
def __init__(self, Id, alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
### motors heavy load table ###
|
||||
self.xhl = MotorRecord(Id + ":MOT_TBL_TX")
|
||||
self.zhl = MotorRecord(Id + ":MOT_TBL_TZ")
|
||||
self.yhl = MotorRecord(Id + ":MOT_TBL_TY")
|
||||
self.th = MotorRecord(Id + ":MOT_MY_RYTH")
|
||||
try:
|
||||
self.rxhl = MotorRecord(Id + ":MOT_TBL_RX")
|
||||
except:
|
||||
print("GPS.pitch not found")
|
||||
pass
|
||||
try:
|
||||
self.ryhl = MotorRecord(Id + ":MOT_TBL_RY")
|
||||
except:
|
||||
print("GPS.roll not found")
|
||||
pass
|
||||
|
||||
### motors heavy load gonio base ###
|
||||
self.xmu = MotorRecord(Id + ":MOT_HEX_TX")
|
||||
self.mu = MotorRecord(Id + ":MOT_HEX_RX")
|
||||
self.tth = MotorRecord(Id + ":MOT_NY_RY2TH")
|
||||
self.xbase = MotorRecord(Id + ":MOT_TX")
|
||||
self.ybase = MotorRecord(Id + ":MOT_TY")
|
||||
|
||||
self.hex_x = PV("SARES20-HEX_PI:POSI-X")
|
||||
self.hex_y = PV("SARES20-HEX_PI:POSI-Y")
|
||||
self.hex_z = PV("SARES20-HEX_PI:POSI-Z")
|
||||
self.hex_u = PV("SARES20-HEX_PI:POSI-U")
|
||||
self.hex_v = PV("SARES20-HEX_PI:POSI-V")
|
||||
self.hex_w = PV("SARES20-HEX_PI:POSI-W")
|
||||
|
||||
### motors XRD arm ###
|
||||
self.delta = MotorRecord(Id + ":MOT_DT_RX2TH")
|
||||
self.det_z = MotorRecord(Id + ":MOT_D_T")
|
||||
self.cam_z = MotorRecord(Id + ":MOT_P_T")
|
||||
|
||||
def __repr__(self):
|
||||
s = "**Heavy Load**\n"
|
||||
motors = "xmu mu tth xbase ybase".split()
|
||||
for motor in motors:
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
|
||||
s += " - xhl %.4f\n" % (self.xhl.wm())
|
||||
s += " - yhl %.4f\n" % (self.yhl.wm())
|
||||
s += " - zhl %.4f\n" % (self.zhl.wm())
|
||||
s += " - th %.4f\n" % (self.th.wm())
|
||||
s += "\n"
|
||||
|
||||
s += "**Gonio**\n"
|
||||
motors = "xmu mu tth delta det_z cam_z xbase ybase".split()
|
||||
for motor in motors:
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
s += "\n"
|
||||
|
||||
s += "**Hexapod**\n"
|
||||
motors = "x y z u v w".split()
|
||||
for motor in motors:
|
||||
s += " - hex_%s %.4f\n" % (motor, getattr(self, "hex_" + motor).get())
|
||||
return s
|
||||
@@ -0,0 +1,85 @@
|
||||
import sys
|
||||
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
from ..aliases import Alias
|
||||
|
||||
|
||||
class XRD:
|
||||
def __init__(self, name=None, Id=None, configuration=[]):
|
||||
"""X-ray diffractometer platform in AiwssFEL Bernina.\
|
||||
<configuration> : list of elements mounted on
|
||||
the plaform, options are kappa, nutable, hlgonio, polana"""
|
||||
self.Id = Id
|
||||
self.name = name
|
||||
self.alias = Alias(name)
|
||||
|
||||
|
||||
### motors base platform ###
|
||||
self.xbase = MotorRecord(Id + ":MOT_TX", name="xbase")
|
||||
self.ybase = MotorRecord(Id + ":MOT_TY", name="ybase")
|
||||
self.rxbase = MotorRecord(Id + ":MOT_RX", name="rxbase")
|
||||
self.omega = MotorRecord(Id + ":MOT_MY_RYTH", name="omega")
|
||||
|
||||
### motors XRD detector arm ###
|
||||
self.gamma = MotorRecord(Id + ":MOT_NY_RY2TH", name="gam")
|
||||
self.delta = MotorRecord(Id + ":MOT_DT_RX2TH", name="del")
|
||||
|
||||
### motors XRD area detector branch ###
|
||||
self.tdet = MotorRecord(Id + ":MOT_D_T", name="tdet")
|
||||
|
||||
### motors XRD polarisation analyzer branch ###
|
||||
self.tpol = MotorRecord(Id + ":MOT_P_T", name="tpol")
|
||||
#missing: slits of flight tube
|
||||
|
||||
### motors heavy load goniometer ###
|
||||
self.xhl = MotorRecord(Id + ":MOT_TBL_TX", name="xhl")
|
||||
self.zhl = MotorRecord(Id + ":MOT_TBL_TZ", name="zhl")
|
||||
self.yhl = MotorRecord(Id + ":MOT_TBL_TY", name="yhl")
|
||||
try:
|
||||
self.rxhl = MotorRecord(Id + ":MOT_TBL_RX", name="rxhl")
|
||||
except:
|
||||
print("GPS.pitch not found")
|
||||
pass
|
||||
try:
|
||||
self.ryhl = MotorRecord(Id + ":MOT_TBL_RY", name="rxhl")
|
||||
except:
|
||||
print("GPS.roll not found")
|
||||
pass
|
||||
|
||||
### motors nu table ###
|
||||
self.tnu = MotorRecord(Id + ":MOT_HEX_TX", name="tnu")
|
||||
self.nu = MotorRecord(Id + ":MOT_HEX_RX", name="nu")
|
||||
|
||||
### motors PI hexapod ###
|
||||
self.hex_x = PV("SARES20-HEX_PI:POSI-X")
|
||||
self.hex_y = PV("SARES20-HEX_PI:POSI-Y")
|
||||
self.hex_z = PV("SARES20-HEX_PI:POSI-Z")
|
||||
self.hex_u = PV("SARES20-HEX_PI:POSI-U")
|
||||
self.hex_v = PV("SARES20-HEX_PI:POSI-V")
|
||||
self.hex_w = PV("SARES20-HEX_PI:POSI-W")
|
||||
|
||||
def __repr__(self):
|
||||
s = "**Heavy Load**\n"
|
||||
motors = "xmu mu tth xbase ybase".split()
|
||||
for motor in motors:
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
|
||||
s += " - xhl %.4f\n" % (self.xhl.wm())
|
||||
s += " - yhl %.4f\n" % (self.yhl.wm())
|
||||
s += " - zhl %.4f\n" % (self.zhl.wm())
|
||||
s += " - th %.4f\n" % (self.th.wm())
|
||||
s += "\n"
|
||||
|
||||
s += "**Gonio**\n"
|
||||
motors = "xmu mu tth delta det_z cam_z xbase ybase".split()
|
||||
for motor in motors:
|
||||
s += " - %s %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
s += "\n"
|
||||
|
||||
s += "**Hexapod**\n"
|
||||
motors = "x y z u v w".split()
|
||||
for motor in motors:
|
||||
s += " - hex_%s %.4f\n" % (motor, getattr(self, "hex_" + motor).get())
|
||||
return s
|
||||
+13
-18
@@ -1,20 +1,15 @@
|
||||
|
||||
|
||||
class Hexapod_PI:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
self.x,self.y,self.z = [ValueRdback(
|
||||
self.id + f':SET-POSI-{i}',
|
||||
self.id + f':POSI-{i}') \
|
||||
for i in 'XYZ']
|
||||
self.dx,self.dy,self.dz = [ValueRdback(
|
||||
self.id + f':SET-POSI-{i}',
|
||||
self.id + f':POSI-{i}') \
|
||||
for i in 'UVW']
|
||||
self._piv_x,self._piv_y,self._piv_z = [ValueRdback(
|
||||
self.id + f':SET-PIVOT-{i}',
|
||||
self.id + f':PIVOT-R-{i}') \
|
||||
for i in 'RST']
|
||||
|
||||
|
||||
|
||||
self.x, self.y, self.z = [
|
||||
ValueRdback(self.id + f":SET-POSI-{i}", self.id + f":POSI-{i}")
|
||||
for i in "XYZ"
|
||||
]
|
||||
self.dx, self.dy, self.dz = [
|
||||
ValueRdback(self.id + f":SET-POSI-{i}", self.id + f":POSI-{i}")
|
||||
for i in "UVW"
|
||||
]
|
||||
self._piv_x, self._piv_y, self._piv_z = [
|
||||
ValueRdback(self.id + f":SET-PIVOT-{i}", self.id + f":PIVOT-R-{i}")
|
||||
for i in "RST"
|
||||
]
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
|
||||
from ..aliases.alvra import elog as _elog_info
|
||||
from ..utilities.elog import Elog as _Elog
|
||||
from ..utilities.elog import Screenshot as _Screenshot
|
||||
from ..utilities.config import loadConfig
|
||||
from epics import PV
|
||||
import sys,os
|
||||
|
||||
|
||||
from colorama import Fore as _color
|
||||
import traceback
|
||||
import datetime
|
||||
|
||||
elog = _Elog(_elog_info['url'],user='gac-alvra',screenshot_directory=_elog_info['screenshot_directory'])
|
||||
screenshot = _Screenshot(screenshot_directory=_elog_info['screenshot_directory'])
|
||||
#stationMessage = _stationMessage('ESA')
|
||||
|
||||
_smaractappends = []
|
||||
|
||||
########### configurations ########################
|
||||
currexp_file_path = '/sf/alvra/config/exp/current_experiment.json'
|
||||
if os.path.exists(currexp_file_path):
|
||||
exp_config = loadConfig(currexp_file_path)
|
||||
else:
|
||||
print('NB: Could not load experiment config in path %s .'%currexp_file_path)
|
||||
|
||||
########### GENERAL IMPLEMENTATIONS ##################
|
||||
from ..aliases.alvra import aliases as _aliases
|
||||
def _attach_device(devDict,devId,args,kwargs):
|
||||
imp_p = devDict['eco_type'].split(sep='.')
|
||||
dev_alias = devDict['alias']
|
||||
dev_alias = dev_alias[0].lower() + dev_alias[1:]
|
||||
eco_type_name = imp_p[-1]
|
||||
istr = 'from ..'+'.'.join(imp_p[:-1])+' import '
|
||||
istr += '%s as _%s'%(eco_type_name,eco_type_name)
|
||||
#print(istr)
|
||||
print(('Configuring %s '%(dev_alias)).ljust(25), end='')
|
||||
print(('(%s)'%(devId)).ljust(25), end='')
|
||||
error = None
|
||||
try:
|
||||
exec(istr)
|
||||
tdev = eval('_%s(Id=\'%s\',*args,**kwargs)'%(eco_type_name,devId))
|
||||
tdev.name = dev_alias
|
||||
tdev._z_und = devDict['z_und']
|
||||
globals().update([(dev_alias,tdev)])
|
||||
print((_color.GREEN+'OK'+_color.RESET).rjust(5))
|
||||
except Exception as e:
|
||||
print((_color.RED+'FAILED'+_color.RESET).rjust(5))
|
||||
error = e
|
||||
return error
|
||||
|
||||
errors = []
|
||||
_composed = {}
|
||||
for device_Id in _aliases.keys():
|
||||
alias = _aliases[device_Id]
|
||||
if 'eco_type' in alias.keys() \
|
||||
and alias['eco_type']:
|
||||
if 'args' in alias.keys() \
|
||||
and alias['args']:
|
||||
args = alias['args']
|
||||
else:
|
||||
args = tuple()
|
||||
|
||||
if 'kwargs' in alias.keys() \
|
||||
and alias['kwargs']:
|
||||
kwargs = alias['kwargs']
|
||||
else:
|
||||
kwargs = dict()
|
||||
|
||||
e = _attach_device(alias,device_Id,args,kwargs)
|
||||
if e:
|
||||
errors.append((alias['alias'],e))
|
||||
else:
|
||||
_device = globals()[alias['alias'][0].lower()+alias['alias'][1:]]
|
||||
if hasattr(_device, '_smaractaxes'):
|
||||
_smaractappends.append(_device)
|
||||
else:
|
||||
if alias['eco_type'].endswith('SmarActRecord') \
|
||||
and 'device' in alias and 'axis' in alias:
|
||||
if alias['device'] not in _composed:
|
||||
_composed[alias['device']] = {}
|
||||
_composed[alias['device']][alias['axis']] = globals()[alias['alias']]
|
||||
|
||||
print('Integrating SmarAct devices:')
|
||||
|
||||
for _device in _smaractappends:
|
||||
print(" Appending %s: %s" \
|
||||
%(_device.name,', '.join(map(str, list(_device._smaractaxes.keys())))))
|
||||
for _axis in _device._smaractaxes.keys():
|
||||
setattr(_device, _axis, globals()[_device._smaractaxes[_axis]])
|
||||
|
||||
from ..devices_general.smaract import SmarActStage as _SmarActStage
|
||||
for _key in _composed.keys():
|
||||
print(' Composing %s: %s'%(_key,', '.join(map(str, list(_composed[_key].keys())))))
|
||||
globals()[_key] = _SmarActStage(_composed[_key], _key)
|
||||
|
||||
if len(errors)>0:
|
||||
print('Found errors when configuring %s'%[te[0] for te in errors])
|
||||
if input('Would you like to see error traces? (y/n)')=='y':
|
||||
for error in errors:
|
||||
print('---> Error when configuring %s'%error[0])
|
||||
traceback.print_tb(error[1].__traceback__)
|
||||
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
out = []
|
||||
with open(fina,'r') as f:
|
||||
done = False
|
||||
while not done:
|
||||
d = f.readline()
|
||||
if not d:
|
||||
done=True
|
||||
if len(d)>0:
|
||||
if not d.isspace():
|
||||
if not d[0]=='#':
|
||||
out.append(d.strip())
|
||||
return out
|
||||
|
||||
|
||||
from ..acquisition.bs_data import BStools
|
||||
from ..acquisition import scan as _scan
|
||||
#from ..acquisition.ioxos_data import Ioxostools
|
||||
|
||||
channellist = dict(alvra_channel_list=
|
||||
parseChannelListFile('/sf/alvra/config/com/channel_lists/default_channel_list'))
|
||||
bsdaq = BStools(default_channel_list=channellist,default_file_path='%s')
|
||||
|
||||
#channellistioxos = dict(alvra_channel_list=
|
||||
# parseChannelListFile('/sf/alvra/config/com/channel_lists/default_channel_list_ioxos'))
|
||||
#ioxosdaq = Ioxostools(default_channel_list=channellistioxos,default_file_path='%s')
|
||||
|
||||
channellistPhotonDiag = dict(alvra_channel_list=
|
||||
parseChannelListFile('/sf/alvra/config/com/channel_lists/default_channel_list_PhotonDiag'))
|
||||
bsdaqPhotonDiag = BStools(default_channel_list=channellistPhotonDiag,default_file_path='%s')
|
||||
|
||||
from eco.devices_general.alvradetectors import DIAClient
|
||||
bsdaqJF = DIAClient('bsdaqJF', instrument="alvra", api_address = "http://sf-daq-alvra:10000", jf_name="JF_4.5M")
|
||||
|
||||
try:
|
||||
bsdaqJF.pgroup = int(exp_config['pgroup'][1:])
|
||||
except:
|
||||
print('Could not set p group in bsdaqJF !!')
|
||||
|
||||
checkerPV=PV('SARFE10-PBPG050:HAMP-INTENSITY-CAL')
|
||||
|
||||
def checker_function(limits):
|
||||
cv = checkerPV.get()
|
||||
if cv>limits[0] and cv<limits[1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
checker = {}
|
||||
checker['checker_call'] = checker_function
|
||||
checker['args'] = [[100,300]]
|
||||
checker['kwargs'] = {}
|
||||
checker['wait_time'] = 3
|
||||
|
||||
|
||||
#scansIoxos = _scan.Scans(data_base_dir='/sf/alvra/config/com/data/scan_data',scan_info_dir='/sf/alvra/config/com/data/scan_info',default_counters=[ioxosdaq])
|
||||
scansJF = _scan.Scans(data_base_dir='scan_data',scan_info_dir='/sf/alvra/data/%s/res/scan_info'%exp_config['pgroup'],default_counters=[bsdaqJF],checker=checker,scan_directories=True)
|
||||
scansBsreadLocal = _scan.Scans(data_base_dir='/sf/alvra/config/com/data/scan_data',scan_info_dir='/sf/alvra/config/com/data/scan_info',default_counters=[bsdaq])
|
||||
|
||||
scansPhotonDiag = _scan.Scans(data_base_dir='/sf/alvra/config/com/data/photon_diag/scan_data',scan_info_dir='/sf/alvra/config/com/data/photon_diag/scan_info',default_counters=[bsdaqPhotonDiag])
|
||||
|
||||
########### ADHOC IMPLEMENTED ########################
|
||||
from ..timing.alvralasertiming import Lxt as _Lxt
|
||||
lxt = _Lxt()
|
||||
|
||||
from ..xoptics.dcm import AlvraDCM_FEL
|
||||
monoFEL = AlvraDCM_FEL('SAROP11-ODCM105')
|
||||
@@ -1,167 +0,0 @@
|
||||
|
||||
from ..aliases.bernina import elog as _elog_info
|
||||
from ..utilities.elog import Elog as _Elog
|
||||
from ..utilities.elog import Screenshot as _Screenshot
|
||||
from ..utilities.config import loadConfig
|
||||
from epics import PV
|
||||
import sys,os
|
||||
|
||||
|
||||
from colorama import Fore as _color
|
||||
import traceback
|
||||
|
||||
elog = _Elog(_elog_info['url'],user='gac-bernina',screenshot_directory=_elog_info['screenshot_directory'])
|
||||
screenshot = _Screenshot(screenshot_directory=_elog_info['screenshot_directory'])
|
||||
|
||||
########### configurations ########################
|
||||
currexp_file_path = '/sf/bernina/config/exp/current_experiment.json'
|
||||
if os.path.exists(currexp_file_path):
|
||||
exp_config = loadConfig(currexp_file_path)
|
||||
else:
|
||||
print('NB: Could not load experiment config in path %s .'%currexp_file_path)
|
||||
|
||||
########### GENERAL IMPLEMENTATIONS ##################
|
||||
from ..aliases.bernina import aliases as _aliases
|
||||
def _attach_device(devDict,devId,args,kwargs):
|
||||
imp_p = devDict['eco_type'].split(sep='.')
|
||||
dev_alias = devDict['alias']
|
||||
dev_alias = dev_alias[0].lower() + dev_alias[1:]
|
||||
eco_type_name = imp_p[-1]
|
||||
istr = 'from ..'+'.'.join(imp_p[:-1])+' import '
|
||||
istr += '%s as _%s'%(eco_type_name,eco_type_name)
|
||||
#print(istr)
|
||||
print(('Configuring %s '%(dev_alias)).ljust(25), end='')
|
||||
print(('(%s)'%(devId)).ljust(25), end='')
|
||||
error = None
|
||||
try:
|
||||
exec(istr)
|
||||
tdev = eval('_%s(Id=\'%s\',*args,**kwargs)'%(eco_type_name,devId))
|
||||
tdev.name = dev_alias
|
||||
tdev._z_und = devDict['z_und']
|
||||
globals().update([(dev_alias,tdev)])
|
||||
print((_color.GREEN+'OK'+_color.RESET).rjust(5))
|
||||
except Exception as e:
|
||||
print((_color.RED+'FAILED'+_color.RESET).rjust(5))
|
||||
print(sys.exc_info())
|
||||
error = e
|
||||
return error
|
||||
|
||||
errors = []
|
||||
for device_Id in _aliases.keys():
|
||||
if 'eco_type' in _aliases[device_Id].keys() \
|
||||
and _aliases[device_Id]['eco_type']:
|
||||
if 'args' in _aliases[device_Id].keys() \
|
||||
and _aliases[device_Id]['args']:
|
||||
args = _aliases[device_Id]['args']
|
||||
else:
|
||||
args = tuple()
|
||||
|
||||
if 'kwargs' in _aliases[device_Id].keys() \
|
||||
and _aliases[device_Id]['kwargs']:
|
||||
kwargs = _aliases[device_Id]['kwargs']
|
||||
else:
|
||||
kwargs = dict()
|
||||
|
||||
e = _attach_device(_aliases[device_Id],device_Id,args,kwargs)
|
||||
if e: errors.append((_aliases[device_Id]['alias'],e))
|
||||
|
||||
if len(errors)>0:
|
||||
print('Found errors when configuring %s'%[te[0] for te in errors])
|
||||
if input('Would you like to see error traces? (y/n)')=='y':
|
||||
for error in errors:
|
||||
print('---> Error when configuring %s'%error[0])
|
||||
traceback.print_tb(error[1].__traceback__)
|
||||
|
||||
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
out = []
|
||||
with open(fina,'r') as f:
|
||||
done = False
|
||||
while not done:
|
||||
d = f.readline()
|
||||
if not d:
|
||||
done=True
|
||||
if len(d)>0:
|
||||
if not d.isspace():
|
||||
if not d[0]=='#':
|
||||
out.append(d.strip())
|
||||
return out
|
||||
|
||||
|
||||
from ..acquisition.bs_data import BStools
|
||||
from ..acquisition import scan as _scan
|
||||
from ..acquisition.ioxos_data import Ioxostools
|
||||
|
||||
channellist = dict(bernina_channel_list=
|
||||
parseChannelListFile('/sf/bernina/config/channel_lists/default_channel_list'))
|
||||
bsdaq = BStools(default_channel_list=channellist,default_file_path='%s')
|
||||
|
||||
channellistioxos = dict(bernina_channel_list=
|
||||
parseChannelListFile('/sf/bernina/config/channel_lists/default_channel_list_ioxos'))
|
||||
ioxosdaq = Ioxostools(default_channel_list=channellistioxos,default_file_path='%s')
|
||||
|
||||
|
||||
#from eco.devices_general.detectors import JF_BS_writer
|
||||
#bsdaqJF = JF_BS_writer('bsdaqJF') d
|
||||
from eco.devices_general.detectors import DIAClient
|
||||
bsdaqJF = DIAClient('bsdaqJF', instrument="bernina", api_address = "http://sf-daq-1:10000")
|
||||
|
||||
try:
|
||||
bsdaqJF.pgroup = int(exp_config['pgroup'][1:])
|
||||
except:
|
||||
print('Could not set p group in bsdaqJF !!')
|
||||
|
||||
checkerPV=PV('SARFE10-PBPG050:HAMP-INTENSITY-CAL')
|
||||
|
||||
def checker_function(limits):
|
||||
cv = checkerPV.get()
|
||||
if cv>limits[0] and cv<limits[1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
checker = {}
|
||||
checker['checker_call'] = checker_function
|
||||
checker['args'] = [[100,700]]
|
||||
checker['kwargs'] = {}
|
||||
checker['wait_time'] = 3
|
||||
|
||||
|
||||
scansIoxos = _scan.Scans(data_base_dir='/sf/bernina/config/com/data/scan_data',scan_info_dir='/sf/bernina/config/com/data/scan_info',default_counters=[ioxosdaq])
|
||||
scansJF = _scan.Scans(data_base_dir='scan_data',scan_info_dir='/sf/bernina/data/%s/res/scan_info'%exp_config['pgroup'],default_counters=[bsdaqJF],checker=checker,scan_directories=True)
|
||||
scansBsreadLocal = _scan.Scans(data_base_dir='/sf/bernina/config/com/data/scan_data',scan_info_dir='/sf/bernina/config/com/data/scan_info',default_counters=[bsdaq])
|
||||
|
||||
|
||||
|
||||
########### ADHOC IMPLEMENTED ########################
|
||||
bsdaqJF.gain_file = "/sf/bernina/data/p16582/res/gains_I0.h5"
|
||||
try:
|
||||
import glob
|
||||
path = '/sf/bernina/data/p17295/res/JF_pedestal/pedestal_*_res.h5'
|
||||
list_of_files = glob.glob('/sf/bernina/data/p17295/res/JF_pedestal/pedestal_*_res.h5')
|
||||
latest_file = max(list_of_files, key=os.path.getctime)
|
||||
bsdaqJF.pede_file = latest_file
|
||||
except (Exception, ArithmeticError) as e:
|
||||
template = "An exception of type {0} occurred when trying to load lates JF files from {2}. Arguments:\n{1!r}"
|
||||
message = template.format(type(e).__name__, e.args, path)
|
||||
print (message)
|
||||
from ..timing.lasertiming import Lxt as _Lxt
|
||||
|
||||
lxt = _Lxt()
|
||||
|
||||
|
||||
from ..xoptics.dcm import MonoEcolEnergy, EcolEnergy
|
||||
monoEcol = MonoEcolEnergy('SAROP21-ODCM098')
|
||||
ecol = EcolEnergy('dummy')
|
||||
|
||||
|
||||
|
||||
if 'eco_path' in list(exp_config.keys()):
|
||||
pass
|
||||
else:
|
||||
eco_path = '/sf/bernina/'+ exp_config['pgroup']
|
||||
@@ -1,114 +0,0 @@
|
||||
|
||||
from ..aliases.bernina import elog as _elog_info
|
||||
from ..utilities.elog import Elog as _Elog
|
||||
from ..utilities.elog import Screenshot as _Screenshot
|
||||
from ..utilities.config import loadConfig
|
||||
from epics import PV
|
||||
import sys,os
|
||||
|
||||
from colorama import Fore as _color
|
||||
import traceback
|
||||
|
||||
elog = _Elog(_elog_info['url'],user='gac-bernina',screenshot_directory=_elog_info['screenshot_directory'])
|
||||
screenshot = _Screenshot(screenshot_directory=_elog_info['screenshot_directory'])
|
||||
|
||||
########### configurations ########################
|
||||
currexp_file_path = '/sf/bernina/config/current_experiment.json'
|
||||
if os.path.exists(currexp_file_path):
|
||||
exp_config = loadConfig(currexp_file_path)
|
||||
else:
|
||||
print('NB: Could not load experiment config in path %s .'%currexp_file_path)
|
||||
|
||||
########### GENERAL IMPLEMENTATIONS ##################
|
||||
from ..aliases.bernina import aliases as _aliases
|
||||
from .utilities_instruments import initDeviceAliasList
|
||||
|
||||
_devices,_problems = initDeviceAliasList(_aliases,verbose=True,lazy=True)
|
||||
for tdev_id,talias,tdev in _devices:
|
||||
globals().update([(talias,tdev)])
|
||||
|
||||
|
||||
if _problems:
|
||||
print('Found errors when configuring %s'%[te[1] for te in _problems])
|
||||
if input('Would you like to see error traces? (y/n)')=='y':
|
||||
for error in _problems:
|
||||
print('---> Error when configuring %s (%s)'%(error[0],error[1]))
|
||||
print(error[2])
|
||||
|
||||
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
out = []
|
||||
with open(fina,'r') as f:
|
||||
done = False
|
||||
while not done:
|
||||
d = f.readline()
|
||||
if not d:
|
||||
done=True
|
||||
if len(d)>0:
|
||||
if not d.isspace():
|
||||
if not d[0]=='#':
|
||||
out.append(d.strip())
|
||||
return out
|
||||
|
||||
|
||||
from ..acquisition.bs_data import BStools
|
||||
from ..acquisition import scan as _scan
|
||||
from ..acquisition.ioxos_data import Ioxostools
|
||||
|
||||
channellist = dict(bernina_channel_list=
|
||||
parseChannelListFile('/sf/bernina/config/com/channel_lists/default_channel_list'))
|
||||
bsdaq = BStools(default_channel_list=channellist,default_file_path='%s')
|
||||
|
||||
channellistioxos = dict(bernina_channel_list=
|
||||
parseChannelListFile('/sf/bernina/config/default_channels/default_channel_list_ioxos'))
|
||||
ioxosdaq = Ioxostools(default_channel_list=channellistioxos,default_file_path='%s')
|
||||
|
||||
|
||||
#from eco.devices_general.detectors import JF_BS_writer
|
||||
#bsdaqJF = JF_BS_writer('bsdaqJF') d
|
||||
from eco.devices_general.detectors import DIAClient
|
||||
bsdaqJF = DIAClient('bsdaqJF', instrument="bernina", api_address = "http://sf-daq-1:10000")
|
||||
|
||||
try:
|
||||
bsdaqJF.pgroup = int(exp_config['pgroup'][1:])
|
||||
except:
|
||||
print('Could not set p group in bsdaqJF !!')
|
||||
|
||||
checkerPV=PV('SARFE10-PBPG050:HAMP-INTENSITY-CAL')
|
||||
|
||||
def checker_function(limits):
|
||||
cv = checkerPV.get()
|
||||
if cv>limits[0] and cv<limits[1]:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
checker = {}
|
||||
checker['checker_call'] = checker_function
|
||||
checker['args'] = [[100,700]]
|
||||
checker['kwargs'] = {}
|
||||
checker['wait_time'] = 3
|
||||
|
||||
|
||||
scansIoxos = _scan.Scans(data_base_dir='/sf/bernina/config/com/data/scan_data',scan_info_dir='/sf/bernina/config/com/data/scan_info',default_counters=[ioxosdaq])
|
||||
scansJF = _scan.Scans(data_base_dir='scan_data',scan_info_dir='/sf/bernina/data/%s/res/scan_info'%exp_config['pgroup'],default_counters=[bsdaqJF],checker=checker,scan_directories=True)
|
||||
scansBsreadLocal = _scan.Scans(data_base_dir='/sf/bernina/config/com/data/scan_data',scan_info_dir='/sf/bernina/config/com/data/scan_info',default_counters=[bsdaq])
|
||||
|
||||
|
||||
|
||||
########### ADHOC IMPLEMENTED ########################
|
||||
bsdaqJF.gain_file = "/sf/bernina/config/com/data/gains_I0.h5"
|
||||
|
||||
import glob
|
||||
list_of_files = glob.glob('/sf/bernina/data/p17247/res/JF_pedestal/pedestal_*_res.h5')
|
||||
latest_file = max(list_of_files, key=os.path.getctime)
|
||||
bsdaqJF.pede_file = latest_file
|
||||
|
||||
from ..timing.lasertiming import Lxt as _Lxt
|
||||
|
||||
lxt = _Lxt()
|
||||
@@ -1,66 +0,0 @@
|
||||
import traceback
|
||||
from colorama import Fore as _color
|
||||
|
||||
try:
|
||||
from lazy_object_proxy import Proxy as LazyProxy
|
||||
except:
|
||||
print('Could not find package lazy-object-proxy for lazy initialisation of devices!')
|
||||
pass
|
||||
|
||||
def init_device(devDict,devId,args,kwargs,verbose=True):
|
||||
imp_p = devDict['eco_type'].split(sep='.')
|
||||
dev_alias = devDict['alias']
|
||||
dev_alias = dev_alias[0].lower() + dev_alias[1:]
|
||||
eco_type_name = imp_p[-1]
|
||||
istr = 'from ..'+'.'.join(imp_p[:-1])+' import '
|
||||
istr += '%s as _%s'%(eco_type_name,eco_type_name)
|
||||
#print(istr)
|
||||
if verbose:
|
||||
print(('Configuring %s '%(dev_alias)).ljust(25), end='')
|
||||
print(('(%s)'%(devId)).ljust(25), end='')
|
||||
error = None
|
||||
try:
|
||||
exec(istr)
|
||||
tdev = eval('_%s(Id=\'%s\',*args,**kwargs)'%(eco_type_name,devId))
|
||||
tdev.name = dev_alias
|
||||
tdev._z_und = devDict['z_und']
|
||||
if verbose:
|
||||
print((_color.GREEN+'OK'+_color.RESET).rjust(5))
|
||||
return tdev
|
||||
except Exception as expt:
|
||||
#tb = traceback.format_exc()
|
||||
if verbose:
|
||||
print((_color.RED+'FAILED'+_color.RESET).rjust(5))
|
||||
#print(sys.exc_info())
|
||||
raise expt
|
||||
|
||||
|
||||
def initDeviceAliasList(aliases,lazy=False,verbose=True):
|
||||
devices = []
|
||||
problems = []
|
||||
for device_Id in aliases.keys():
|
||||
alias = aliases[device_Id]['alias']
|
||||
alias = alias[0].lower() + alias[1:]
|
||||
if 'eco_type' in aliases[device_Id].keys() \
|
||||
and aliases[device_Id]['eco_type']:
|
||||
if 'args' in aliases[device_Id].keys() \
|
||||
and aliases[device_Id]['args']:
|
||||
args = aliases[device_Id]['args']
|
||||
else:
|
||||
args = tuple()
|
||||
|
||||
if 'kwargs' in aliases[device_Id].keys() \
|
||||
and aliases[device_Id]['kwargs']:
|
||||
kwargs = aliases[device_Id]['kwargs']
|
||||
else:
|
||||
kwargs = dict()
|
||||
try:
|
||||
if lazy:
|
||||
dev = LazyProxy(lambda:init_device(aliases[device_Id],device_Id,args,kwargs,verbose=verbose))
|
||||
else:
|
||||
dev = init_device(aliases[device_Id],device_Id,args,kwargs,verbose=verbose)
|
||||
devices.append((device_Id,alias,dev))
|
||||
except:
|
||||
problems.append((device_Id,alias,traceback.format_exc()))
|
||||
return devices, problems
|
||||
|
||||
@@ -3,117 +3,115 @@ from ..devices_general.smaract import SmarActRecord
|
||||
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
#from ..devices_general.user_to_motor import User_to_motor
|
||||
|
||||
# from ..devices_general.user_to_motor import User_to_motor
|
||||
|
||||
|
||||
class Laser_Exp:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
# try:
|
||||
# self.lensx = MotorRecord('SARES20-EXP:MOT_DIODE')
|
||||
# except:
|
||||
# print('No owis lens x motor')
|
||||
# pass
|
||||
|
||||
# Waveplate and Delay stage
|
||||
self.wp = MotorRecord(Id + "-M442:MOT")
|
||||
|
||||
# try:
|
||||
# self.lensx = MotorRecord('SARES20-EXP:MOT_DIODE')
|
||||
# except:
|
||||
# print('No owis lens x motor')
|
||||
# pass
|
||||
|
||||
#Waveplate and Delay stage
|
||||
self.wp = MotorRecord(Id+'-M442:MOT')
|
||||
|
||||
self.pump_delay = MotorRecord(self.Id+'-M451:MOTOR_1')
|
||||
self.pump_delay = MotorRecord(self.Id + "-M451:MOTOR_1")
|
||||
self.pump_delayTime = DelayStage(self.pump_delay)
|
||||
|
||||
#LAM delay stage
|
||||
self.lam_delay = SmarActRecord('SLAAR11-LMTS-LAM11')
|
||||
# LAM delay stage
|
||||
self.lam_delay = SmarActRecord("SLAAR11-LMTS-LAM11")
|
||||
self.lam_delayTime = DelayStage(self.lam_delay)
|
||||
#
|
||||
# self._lam_delayStg = MotorRecord(self.Id+'-M548:MOT')
|
||||
# self.lam_delay = DelayStage(self._lam_delayStg)
|
||||
#
|
||||
# self._lam_delayStg = MotorRecord(self.Id+'-M548:MOT')
|
||||
# self.lam_delay = DelayStage(self._lam_delayStg)
|
||||
|
||||
#PALM delay stages
|
||||
self.palm_delay = MotorRecord(self.Id+'-M423:MOT')
|
||||
# PALM delay stages
|
||||
self.palm_delay = MotorRecord(self.Id + "-M423:MOT")
|
||||
self.palm_delayTime = DelayStage(self.palm_delay)
|
||||
|
||||
self.palmEO_delay = MotorRecord(self.Id+'-M422:MOT')
|
||||
|
||||
self.palmEO_delay = MotorRecord(self.Id + "-M422:MOT")
|
||||
self.palmEO_delayTime = DelayStage(self.palmEO_delay)
|
||||
|
||||
#PSEN delay stage
|
||||
self.psen_delay = MotorRecord(self.Id+'-M424:MOT')
|
||||
# PSEN delay stage
|
||||
self.psen_delay = MotorRecord(self.Id + "-M424:MOT")
|
||||
self.psen_delayTime = DelayStage(self.psen_delay)
|
||||
|
||||
#Experimental compressor delay stage
|
||||
self.compressorExp_delay = MotorRecord(self.Id+'-M431:MOT')
|
||||
|
||||
#Experimental compressor delay stage
|
||||
self.compressorDiag_delay = MotorRecord(self.Id+'-M421:MOT')
|
||||
|
||||
#Pump A/C delay stage
|
||||
self.pump_autocorr_delay = MotorRecord(self.Id+'-M444:MOT')
|
||||
|
||||
# Experimental compressor delay stage
|
||||
self.compressorExp_delay = MotorRecord(self.Id + "-M431:MOT")
|
||||
|
||||
# Experimental compressor delay stage
|
||||
self.compressorDiag_delay = MotorRecord(self.Id + "-M421:MOT")
|
||||
|
||||
# Pump A/C delay stage
|
||||
self.pump_autocorr_delay = MotorRecord(self.Id + "-M444:MOT")
|
||||
self.psen_autocorr_delayTime = DelayStage(self.pump_autocorr_delay)
|
||||
|
||||
#Experiment-FEL timing delay stage
|
||||
self.pump_toFEL_delay = MotorRecord(self.Id+'-M441:MOT')
|
||||
|
||||
# Experiment-FEL timing delay stage
|
||||
self.pump_toFEL_delay = MotorRecord(self.Id + "-M441:MOT")
|
||||
self.pump_toFEL_delayTime = DelayStage(self.pump_toFEL_delay)
|
||||
|
||||
#SmarAct ID
|
||||
# self.IdSA = 'SARES23'
|
||||
# SmarAct ID
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
# try:
|
||||
# self.eos_rot = SmarActRecord(self.IdSA+'-ESB18')
|
||||
# except:
|
||||
# print('No Smaract EOSrot')
|
||||
# pass
|
||||
# self.IdSA = 'SARES23'
|
||||
|
||||
# try:
|
||||
# self.eos_gonio = SmarActRecord(self.IdSA+'-ESB3')
|
||||
# except:
|
||||
# print('No Smaract EOSGonio')
|
||||
# pass
|
||||
### Mirrors used in the expeirment ###
|
||||
# try:
|
||||
# self.eos_rot = SmarActRecord(self.IdSA+'-ESB18')
|
||||
# except:
|
||||
# print('No Smaract EOSrot')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self._pump_rot = SmarActRecord(self.IdSA+'-ESB16')
|
||||
# self.pump_rot = User_to_motor(self._pump_rot,180./35.7,0.)
|
||||
# except:
|
||||
# print('No Smaract THzrot')
|
||||
# pass
|
||||
# try:
|
||||
# self.eos_gonio = SmarActRecord(self.IdSA+'-ESB3')
|
||||
# except:
|
||||
# print('No Smaract EOSGonio')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self.pump_gonio = SmarActRecord(self.IdSA+'-ESB2')
|
||||
# except:
|
||||
# print('No Smaract THzGonio')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self.pump_x = SmarActRecord(self.IdSA+'-ESB1')
|
||||
# except:
|
||||
# print('No Smaract THzZ')
|
||||
# pass
|
||||
# try:
|
||||
# self._pump_rot = SmarActRecord(self.IdSA+'-ESB16')
|
||||
# self.pump_rot = User_to_motor(self._pump_rot,180./35.7,0.)
|
||||
# except:
|
||||
# print('No Smaract THzrot')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self.par_x = SmarActRecord(self.IdSA+'-ESB5')
|
||||
# except:
|
||||
# print('No Smaract ParX')
|
||||
# pass
|
||||
# try:
|
||||
# self.par_z = SmarActRecord(self.IdSA+'-ESB4')
|
||||
# except:
|
||||
# print('No Smaract ParZ')
|
||||
# pass
|
||||
# try:
|
||||
# self.pump_gonio = SmarActRecord(self.IdSA+'-ESB2')
|
||||
# except:
|
||||
# print('No Smaract THzGonio')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self.pump_x = SmarActRecord(self.IdSA+'-ESB1')
|
||||
# except:
|
||||
# print('No Smaract THzZ')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self.par_x = SmarActRecord(self.IdSA+'-ESB5')
|
||||
# except:
|
||||
# print('No Smaract ParX')
|
||||
# pass
|
||||
# try:
|
||||
# self.par_z = SmarActRecord(self.IdSA+'-ESB4')
|
||||
# except:
|
||||
# print('No Smaract ParZ')
|
||||
# pass
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****Laser motor positions*****\n'
|
||||
ostr = "*****Laser motor positions*****\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
|
||||
#def pos(self):
|
||||
# def pos(self):
|
||||
# s = []
|
||||
# for i in sorted(self.__dict__.keys()):
|
||||
# s.append[i]
|
||||
@@ -123,4 +121,3 @@ class Laser_Exp:
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
@@ -1,29 +1,29 @@
|
||||
from epics import caput, caget
|
||||
|
||||
|
||||
class laser_shutter:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_status()
|
||||
|
||||
def get_status(self):
|
||||
Id = self.Id
|
||||
status = caget(Id+":FrontUnivOut5-Ena-SP")
|
||||
if status == 0:
|
||||
return 'open'
|
||||
elif status == 1:
|
||||
return 'close'
|
||||
else:
|
||||
return "unknown"
|
||||
def __repr__(self):
|
||||
return self.get_status()
|
||||
|
||||
def open(self):
|
||||
caput(self.Id+":FrontUnivOut5_SOURCE",3)
|
||||
caput(self.Id+":FrontUnivOut5_SOURCE2",4)
|
||||
caput(self.Id+":FrontUnivOut5-Ena-SP",0)
|
||||
def get_status(self):
|
||||
Id = self.Id
|
||||
status = caget(Id + ":FrontUnivOut5-Ena-SP")
|
||||
if status == 0:
|
||||
return "open"
|
||||
elif status == 1:
|
||||
return "close"
|
||||
else:
|
||||
return "unknown"
|
||||
|
||||
def close(self):
|
||||
caput(self.Id+":FrontUnivOut5_SOURCE",3)
|
||||
caput(self.Id+":FrontUnivOut5_SOURCE2",4)
|
||||
caput(self.Id+":FrontUnivOut5-Ena-SP",1)
|
||||
|
||||
def open(self):
|
||||
caput(self.Id + ":FrontUnivOut5_SOURCE", 3)
|
||||
caput(self.Id + ":FrontUnivOut5_SOURCE2", 4)
|
||||
caput(self.Id + ":FrontUnivOut5-Ena-SP", 0)
|
||||
|
||||
def close(self):
|
||||
caput(self.Id + ":FrontUnivOut5_SOURCE", 3)
|
||||
caput(self.Id + ":FrontUnivOut5_SOURCE2", 4)
|
||||
caput(self.Id + ":FrontUnivOut5-Ena-SP", 1)
|
||||
|
||||
@@ -5,98 +5,94 @@ from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
from ..devices_general.user_to_motor import User_to_motor
|
||||
|
||||
|
||||
class Laser_Exp:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
|
||||
|
||||
try:
|
||||
self.lensx = MotorRecord('SARES20-EXP:MOT_DIODE')
|
||||
self.lensx = MotorRecord("SARES20-EXP:MOT_DIODE")
|
||||
except:
|
||||
print('No owis lens x motor')
|
||||
print("No owis lens x motor")
|
||||
pass
|
||||
|
||||
#Waveplate and Delay stage
|
||||
self.wp = MotorRecord(Id+'-M534:MOT')
|
||||
|
||||
self._pump_delayStg = MotorRecord(self.Id+'-M521:MOTOR_1')
|
||||
|
||||
# Waveplate and Delay stage
|
||||
self.wp = MotorRecord(Id + "-M534:MOT")
|
||||
|
||||
self._pump_delayStg = MotorRecord(self.Id + "-M521:MOTOR_1")
|
||||
self.pump_delay = DelayStage(self._pump_delayStg)
|
||||
|
||||
#LAM delay stages
|
||||
self._lam_delayStg_Smar = SmarActRecord('SLAAR21-LMTS-LAM11')
|
||||
# LAM delay stages
|
||||
self._lam_delayStg_Smar = SmarActRecord("SLAAR21-LMTS-LAM11")
|
||||
self.lam_delay_Smar = DelayStage(self._lam_delayStg_Smar)
|
||||
|
||||
self._lam_delayStg = MotorRecord(self.Id+'-M548:MOT')
|
||||
self._lam_delayStg = MotorRecord(self.Id + "-M548:MOT")
|
||||
self.lam_delay = DelayStage(self._lam_delayStg)
|
||||
|
||||
#PALM delay stages
|
||||
self._palm_delayStg = MotorRecord(self.Id+'-M552:MOT')
|
||||
# PALM delay stages
|
||||
self._palm_delayStg = MotorRecord(self.Id + "-M552:MOT")
|
||||
self.palm_delay = DelayStage(self._palm_delayStg)
|
||||
|
||||
#PSEN delay stages
|
||||
#self._psen_delayStg = MotorRecord(self.Id+'')
|
||||
#self.psen_delay = DelayStage(self._pump_delayStg)
|
||||
# PSEN delay stages
|
||||
# self._psen_delayStg = MotorRecord(self.Id+'')
|
||||
# self.psen_delay = DelayStage(self._pump_delayStg)
|
||||
|
||||
#SmarAct ID
|
||||
self.IdSA = 'SARES23'
|
||||
# SmarAct ID
|
||||
self.IdSA = "SARES23"
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
try:
|
||||
self.eos_rot = SmarActRecord(self.IdSA+'-ESB18')
|
||||
self.eos_rot = SmarActRecord(self.IdSA + "-ESB18")
|
||||
except:
|
||||
print('No Smaract EOSrot')
|
||||
print("No Smaract EOSrot")
|
||||
pass
|
||||
|
||||
try:
|
||||
self.eos_gonio = SmarActRecord(self.IdSA+'-ESB3')
|
||||
self.eos_gonio = SmarActRecord(self.IdSA + "-ESB3")
|
||||
except:
|
||||
print('No Smaract EOSGonio')
|
||||
print("No Smaract EOSGonio")
|
||||
pass
|
||||
|
||||
try:
|
||||
self._pump_rot = SmarActRecord(self.IdSA+'-ESB16')
|
||||
self.pump_rot = User_to_motor(self._pump_rot,180./35.7,0.)
|
||||
self._pump_rot = SmarActRecord(self.IdSA + "-ESB16")
|
||||
self.pump_rot = User_to_motor(self._pump_rot, 180.0 / 35.7, 0.0)
|
||||
except:
|
||||
print('No Smaract THzrot')
|
||||
print("No Smaract THzrot")
|
||||
pass
|
||||
|
||||
try:
|
||||
self.pump_gonio = SmarActRecord(self.IdSA+'-ESB2')
|
||||
self.pump_gonio = SmarActRecord(self.IdSA + "-ESB2")
|
||||
except:
|
||||
print('No Smaract THzGonio')
|
||||
pass
|
||||
|
||||
try:
|
||||
self.pump_x = SmarActRecord(self.IdSA+'-ESB1')
|
||||
except:
|
||||
print('No Smaract THzZ')
|
||||
print("No Smaract THzGonio")
|
||||
pass
|
||||
|
||||
try:
|
||||
self.par_x = SmarActRecord(self.IdSA+'-ESB5')
|
||||
self.pump_x = SmarActRecord(self.IdSA + "-ESB1")
|
||||
except:
|
||||
print('No Smaract ParX')
|
||||
pass
|
||||
try:
|
||||
self.par_z = SmarActRecord(self.IdSA+'-ESB4')
|
||||
except:
|
||||
print('No Smaract ParZ')
|
||||
print("No Smaract THzZ")
|
||||
pass
|
||||
|
||||
try:
|
||||
self.par_x = SmarActRecord(self.IdSA + "-ESB5")
|
||||
except:
|
||||
print("No Smaract ParX")
|
||||
pass
|
||||
try:
|
||||
self.par_z = SmarActRecord(self.IdSA + "-ESB4")
|
||||
except:
|
||||
print("No Smaract ParZ")
|
||||
pass
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****SmarAct motor positions******\n'
|
||||
ostr = "*****SmarAct motor positions******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
|
||||
#def pos(self):
|
||||
# def pos(self):
|
||||
# s = []
|
||||
# for i in sorted(self.__dict__.keys()):
|
||||
# s.append[i]
|
||||
@@ -106,4 +102,3 @@ class Laser_Exp:
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class SmaractTower:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
try:
|
||||
self.x = SmarActRecord(Id+'-ESB1')
|
||||
self.x = SmarActRecord(Id + "-ESB1")
|
||||
except:
|
||||
print('No Smaract x linear stage')
|
||||
print("No Smaract x linear stage")
|
||||
pass
|
||||
|
||||
try:
|
||||
self.gonio = SmarActRecord(Id+'-ESB2')
|
||||
self.gonio = SmarActRecord(Id + "-ESB2")
|
||||
except:
|
||||
print('No Smaract Gonio')
|
||||
print("No Smaract Gonio")
|
||||
pass
|
||||
|
||||
|
||||
|
||||
@@ -1,24 +1,25 @@
|
||||
from epics import caput, caget
|
||||
|
||||
|
||||
class laser_shutter:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_status()
|
||||
|
||||
|
||||
def get_status(self):
|
||||
Id = self.Id
|
||||
status = caget(Id+":FrontUnivOut3_SOURCE")
|
||||
status = caget(Id + ":FrontUnivOut3_SOURCE")
|
||||
if status == 4:
|
||||
return 'open'
|
||||
return "open"
|
||||
elif status == 3:
|
||||
return 'close'
|
||||
return "close"
|
||||
else:
|
||||
return "unknown"
|
||||
|
||||
def open(self):
|
||||
caput(self.Id+":FrontUnivOut3_SOURCE",4)
|
||||
caput(self.Id + ":FrontUnivOut3_SOURCE", 4)
|
||||
|
||||
def close(self):
|
||||
caput(self.Id+":FrontUnivOut3_SOURCE",3)
|
||||
caput(self.Id + ":FrontUnivOut3_SOURCE", 3)
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class Laser_Exp:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
try:
|
||||
self.phi = MotorRecord(Id+'-M517:MOT')
|
||||
self.phi = MotorRecord(Id + "-M517:MOT")
|
||||
except:
|
||||
print('No Standa steering phi mirror')
|
||||
print("No Standa steering phi mirror")
|
||||
pass
|
||||
try:
|
||||
self.th = MotorRecord(Id+'-M518:MOT')
|
||||
self.th = MotorRecord(Id + "-M518:MOT")
|
||||
except:
|
||||
print('No Standa steering theta mirror')
|
||||
print("No Standa steering theta mirror")
|
||||
pass
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
#/bin/bash
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description='Experiment control startup script')
|
||||
parser.add_argument('instrument', metavar='inst', type=str, nargs=1,
|
||||
help='import instrument configuration upon startup')
|
||||
|
||||
args = parser.parse_args()
|
||||
+131
-123
@@ -7,44 +7,46 @@ from ..devices_general.utilities import Changer
|
||||
|
||||
_basefolder = "/sf/alvra/config/lasertiming"
|
||||
|
||||
def timeToStr(value,n=12):
|
||||
|
||||
def timeToStr(value, n=12):
|
||||
fmt = "%%+.%df" % n
|
||||
value = fmt%value
|
||||
#print(value)
|
||||
value = fmt % value
|
||||
# print(value)
|
||||
idx_point = value.find(".")
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value)-idx_point)//3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point+1+3*n:idx_point+1+3*(n+1)]
|
||||
#print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value) - idx_point) // 3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point + 1 + 3 * n : idx_point + 1 + 3 * (n + 1)]
|
||||
# print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
return ret_str
|
||||
|
||||
def niceTimeToStr(delay,fmt="%+.0f"):
|
||||
a_delay = abs(delay)
|
||||
if a_delay >= 1:
|
||||
ret = fmt % delay + "s"
|
||||
elif 1e-3 <= a_delay < 1:
|
||||
ret = fmt % (delay*1e3) + "ms"
|
||||
elif 1e-6 <= a_delay < 1e-3:
|
||||
ret = fmt % (delay*1e6) + "us"
|
||||
elif 1e-9 <= a_delay < 1e-6:
|
||||
ret = fmt % (delay*1e9) + "ns"
|
||||
elif 1e-12 <= a_delay < 1e-9:
|
||||
ret = fmt % (delay*1e12) + "ps"
|
||||
elif 1e-15 <= a_delay < 1e-12:
|
||||
ret = fmt % (delay*1e12) + "fs"
|
||||
elif 1e-18 <= a_delay < 1e-15:
|
||||
ret = fmt % (delay*1e12) + "as"
|
||||
elif a_delay < 1e-18:
|
||||
ret = "0s"
|
||||
else:
|
||||
ret = str(delay) +"s"
|
||||
return ret
|
||||
|
||||
|
||||
def niceTimeToStr(delay, fmt="%+.0f"):
|
||||
a_delay = abs(delay)
|
||||
if a_delay >= 1:
|
||||
ret = fmt % delay + "s"
|
||||
elif 1e-3 <= a_delay < 1:
|
||||
ret = fmt % (delay * 1e3) + "ms"
|
||||
elif 1e-6 <= a_delay < 1e-3:
|
||||
ret = fmt % (delay * 1e6) + "us"
|
||||
elif 1e-9 <= a_delay < 1e-6:
|
||||
ret = fmt % (delay * 1e9) + "ns"
|
||||
elif 1e-12 <= a_delay < 1e-9:
|
||||
ret = fmt % (delay * 1e12) + "ps"
|
||||
elif 1e-15 <= a_delay < 1e-12:
|
||||
ret = fmt % (delay * 1e12) + "fs"
|
||||
elif 1e-18 <= a_delay < 1e-15:
|
||||
ret = fmt % (delay * 1e12) + "as"
|
||||
elif a_delay < 1e-18:
|
||||
ret = "0s"
|
||||
else:
|
||||
ret = str(delay) + "s"
|
||||
return ret
|
||||
|
||||
|
||||
class Storage(object):
|
||||
def __init__(self,pvname):
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
def __init__(self, pvname):
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self.pvname = pvname
|
||||
self.last_read_time = -1
|
||||
|
||||
@@ -60,141 +62,151 @@ class Storage(object):
|
||||
lmod = self.last_modified_time
|
||||
if os.path.isfile(self._filename):
|
||||
# need to read again ?
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time :
|
||||
#print("actually reading")
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time:
|
||||
# print("actually reading")
|
||||
value = float(np.loadtxt(self._filename))
|
||||
self.last_read_time = lmod
|
||||
self.last_read = value
|
||||
else:
|
||||
value = self.last_read
|
||||
else:
|
||||
print("could not read",self._filename)
|
||||
print("could not read", self._filename)
|
||||
value = 0
|
||||
return value
|
||||
|
||||
def store(self,value):
|
||||
with open(self._filename,"w") as f:
|
||||
f.write("# %s\n"%time.asctime())
|
||||
f.write("%.15f"%value)
|
||||
|
||||
def store(self, value):
|
||||
with open(self._filename, "w") as f:
|
||||
f.write("# %s\n" % time.asctime())
|
||||
f.write("%.15f" % value)
|
||||
|
||||
|
||||
class Pockels_trigger(PV):
|
||||
""" this class is needed to store the offset in files and read in s """
|
||||
def __init__(self,pv_basename):
|
||||
|
||||
def __init__(self, pv_basename):
|
||||
pvname = pv_basename + "-RB"
|
||||
PV.__init__(self,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._storage = Storage(pvname)
|
||||
PV.__init__(self, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._storage = Storage(pvname)
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def get_dial(self):
|
||||
return np.round(super().get()*1e-6,9)
|
||||
return np.round(super().get() * 1e-6, 9)
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self,value):
|
||||
def move(self, value):
|
||||
dial = value + self.offset
|
||||
self._pv_setvalue.put(dial*1e6)
|
||||
self._pv_setvalue.put(dial * 1e6)
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=12 )
|
||||
user = timeToStr( self.get(),n=12 )
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s"%(self.pvname,user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=12)
|
||||
user = timeToStr(self.get(), n=12)
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s" % (self.pvname, user, dial)
|
||||
|
||||
|
||||
_OSCILLATOR_PERIOD = 1 / 71.368704e6
|
||||
|
||||
_OSCILLATOR_PERIOD = 1/71.368704e6
|
||||
|
||||
class Phase_shifter(PV):
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
def __init__(self,pv_basename="SLAAR01-TSPL-EPL",dial_max=14.0056e-9,precision=100e-15):
|
||||
pvname = pv_basename+":CURR_DELTA_T"
|
||||
PV.__init__(self,pvname)
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
self.dial_max = dial_max
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
|
||||
def __init__(
|
||||
self, pv_basename="SLAAR01-TSPL-EPL", dial_max=14.0056e-9, precision=100e-15
|
||||
):
|
||||
pvname = pv_basename + ":CURR_DELTA_T"
|
||||
PV.__init__(self, pvname)
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
self.dial_max = dial_max
|
||||
self.retry = precision
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
|
||||
def get_dial(self):
|
||||
return super().get()*1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
|
||||
def move(self,value,accuracy=None):
|
||||
if accuracy is None: accuracy = self.retry
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def get_dial(self):
|
||||
return super().get() * 1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self, value, accuracy=None):
|
||||
if accuracy is None:
|
||||
accuracy = self.retry
|
||||
dial = value + self.offset
|
||||
dial = np.mod(dial,_OSCILLATOR_PERIOD)
|
||||
if dial > self.dial_max: dial = self.dial_max
|
||||
dial_ps = dial*1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
dial = np.mod(dial, _OSCILLATOR_PERIOD)
|
||||
if dial > self.dial_max:
|
||||
dial = self.dial_max
|
||||
dial_ps = dial * 1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
self._pv_execute.put(1)
|
||||
#print(accuracy)
|
||||
while( np.abs(self.get_dial()-dial) > accuracy ):
|
||||
#print(np.abs(self.get_dial()-dial))
|
||||
# print(accuracy)
|
||||
while np.abs(self.get_dial() - dial) > accuracy:
|
||||
# print(np.abs(self.get_dial()-dial))
|
||||
time.sleep(0.2)
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
newoffset = np.mod(newoffset,_OSCILLATOR_PERIOD)
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
newoffset = np.mod(newoffset, _OSCILLATOR_PERIOD)
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=15 )
|
||||
user = timeToStr( self.get(),n=15 )
|
||||
return "Phase Shifter: user,dial = %s , %s"%(user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=15)
|
||||
user = timeToStr(self.get(), n=15)
|
||||
return "Phase Shifter: user,dial = %s , %s" % (user, dial)
|
||||
|
||||
|
||||
_slicer_gate = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
|
||||
_slicer_gate = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul2-Delay")
|
||||
_sdg1 = Pockels_trigger("SLAAR-LTIM01-EVR0:Pul3-Delay")
|
||||
_phase_shifter = Phase_shifter("SLAAR01-TSPL-EPL")
|
||||
|
||||
|
||||
_POCKELS_CELL_RESOLUTION = 7e-9
|
||||
|
||||
|
||||
class Lxt(object):
|
||||
def __init__(self):
|
||||
self.sdg1 = _sdg1
|
||||
self.slicer_gate = _slicer_gate
|
||||
self.slicer_gate = _slicer_gate
|
||||
self.phase_shifter = _phase_shifter
|
||||
self.Id = 'SLAAR01-TSPL-EPL'
|
||||
self.name = 'lxt'
|
||||
self.Id = "SLAAR01-TSPL-EPL"
|
||||
self.name = "lxt"
|
||||
self.elog = None
|
||||
|
||||
def move_sdg(self,value):
|
||||
def move_sdg(self, value):
|
||||
self.sdg1.move(value)
|
||||
|
||||
def move(self,value,accuracy=None):
|
||||
def move(self, value, accuracy=None):
|
||||
self.sdg1.move(-value)
|
||||
self.slicer_gate.move(-value)
|
||||
self.phase_shifter.move(value,accuracy=accuracy)
|
||||
self.phase_shifter.move(value, accuracy=accuracy)
|
||||
|
||||
def set(self,value):
|
||||
def set(self, value):
|
||||
self.phase_shifter.set(value)
|
||||
self.sdg1.set(-value)
|
||||
|
||||
@@ -204,32 +216,28 @@ class Lxt(object):
|
||||
phase_shifter = self.phase_shifter.get()
|
||||
sdg1_delay = self.sdg1.get()
|
||||
|
||||
idx_pulse = (sdg1_delay+phase_shifter)/_OSCILLATOR_PERIOD
|
||||
idx_pulse = (sdg1_delay + phase_shifter) / _OSCILLATOR_PERIOD
|
||||
|
||||
delay = int(idx_pulse)*_OSCILLATOR_PERIOD - phase_shifter
|
||||
delay = int(idx_pulse) * _OSCILLATOR_PERIOD - phase_shifter
|
||||
return -delay
|
||||
|
||||
|
||||
def changeTo(self, value, hold=False):
|
||||
""" Adjustable convention"""
|
||||
|
||||
changer = lambda value: self.move(\
|
||||
value)
|
||||
changer = lambda value: self.move(value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=None)
|
||||
|
||||
target=value, parent=self, changer=changer, hold=hold, stopper=None
|
||||
)
|
||||
|
||||
def get_current_value(self):
|
||||
return self.get()
|
||||
|
||||
def set_current_value(self,value):
|
||||
def set_current_value(self, value):
|
||||
self.set(value)
|
||||
|
||||
def __repr__(self):
|
||||
delay = niceTimeToStr(lxt.get())
|
||||
return "delay = %s"%(delay)
|
||||
return "delay = %s" % (delay)
|
||||
|
||||
|
||||
lxt = Lxt()
|
||||
|
||||
+144
-130
@@ -7,45 +7,48 @@ from ..devices_general.utilities import Changer
|
||||
|
||||
_basefolder = "/sf/bernina/config/src/python/eco/timing"
|
||||
|
||||
def timeToStr(value,n=12):
|
||||
|
||||
def timeToStr(value, n=12):
|
||||
fmt = "%%+.%df" % n
|
||||
value = fmt%value
|
||||
#print(value)
|
||||
value = fmt % value
|
||||
# print(value)
|
||||
idx_point = value.find(".")
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value)-idx_point)//3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point+1+3*n:idx_point+1+3*(n+1)]
|
||||
#print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
ret_str = value[:idx_point] + " ."
|
||||
ngroups = (len(value) - idx_point) // 3
|
||||
for n in range(ngroups):
|
||||
ret_str += " %s" % value[idx_point + 1 + 3 * n : idx_point + 1 + 3 * (n + 1)]
|
||||
# print(idx_point+1+3*n,idx_point+1*3*(n-1),ret_str)
|
||||
return ret_str
|
||||
|
||||
def niceTimeToStr(delay,fmt="%+.0f"):
|
||||
a_delay = abs(delay)
|
||||
if a_delay >= 1:
|
||||
ret = fmt % delay + "s"
|
||||
elif 1e-3 <= a_delay < 1:
|
||||
ret = fmt % (delay*1e3) + "ms"
|
||||
elif 1e-6 <= a_delay < 1e-3:
|
||||
ret = fmt % (delay*1e6) + "us"
|
||||
elif 1e-9 <= a_delay < 1e-6:
|
||||
ret = fmt % (delay*1e9) + "ns"
|
||||
elif 1e-12 <= a_delay < 1e-9:
|
||||
ret = fmt % (delay*1e12) + "ps"
|
||||
elif 1e-15 <= a_delay < 1e-12:
|
||||
ret = fmt % (delay*1e12) + "fs"
|
||||
elif 1e-18 <= a_delay < 1e-15:
|
||||
ret = fmt % (delay*1e12) + "as"
|
||||
elif a_delay < 1e-18:
|
||||
ret = "0s"
|
||||
else:
|
||||
ret = str(delay) +"s"
|
||||
return ret
|
||||
|
||||
|
||||
def niceTimeToStr(delay, fmt="%+.0f"):
|
||||
a_delay = abs(delay)
|
||||
if a_delay >= 1:
|
||||
ret = fmt % delay + "s"
|
||||
elif 1e-3 <= a_delay < 1:
|
||||
ret = fmt % (delay * 1e3) + "ms"
|
||||
elif 1e-6 <= a_delay < 1e-3:
|
||||
ret = fmt % (delay * 1e6) + "us"
|
||||
elif 1e-9 <= a_delay < 1e-6:
|
||||
ret = fmt % (delay * 1e9) + "ns"
|
||||
elif 1e-12 <= a_delay < 1e-9:
|
||||
ret = fmt % (delay * 1e12) + "ps"
|
||||
elif 1e-15 <= a_delay < 1e-12:
|
||||
ret = fmt % (delay * 1e12) + "fs"
|
||||
elif 1e-18 <= a_delay < 1e-15:
|
||||
ret = fmt % (delay * 1e12) + "as"
|
||||
elif a_delay < 1e-18:
|
||||
ret = "0s"
|
||||
else:
|
||||
ret = str(delay) + "s"
|
||||
return ret
|
||||
|
||||
|
||||
class Storage(object):
|
||||
""" this class is needed to store the offset in files and read in s """
|
||||
def __init__(self,pvname):
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
|
||||
def __init__(self, pvname):
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self.pvname = pvname
|
||||
self.last_read_time = -1
|
||||
|
||||
@@ -61,152 +64,167 @@ class Storage(object):
|
||||
lmod = self.last_modified_time
|
||||
if os.path.isfile(self._filename):
|
||||
# need to read again ?
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time :
|
||||
#print("actually reading")
|
||||
if self.last_read_time == -1 or lmod > self.last_read_time:
|
||||
# print("actually reading")
|
||||
value = float(np.loadtxt(self._filename))
|
||||
self.last_read_time = lmod
|
||||
self.last_read = value
|
||||
else:
|
||||
value = self.last_read
|
||||
else:
|
||||
print("could not read",self._filename)
|
||||
print("could not read", self._filename)
|
||||
value = 0
|
||||
return value
|
||||
|
||||
def store(self,value):
|
||||
with open(self._filename,"w") as f:
|
||||
f.write("# %s\n"%time.asctime())
|
||||
f.write("%.15f"%value)
|
||||
|
||||
def store(self, value):
|
||||
with open(self._filename, "w") as f:
|
||||
f.write("# %s\n" % time.asctime())
|
||||
f.write("%.15f" % value)
|
||||
|
||||
|
||||
class Pockels_trigger(PV):
|
||||
def __init__(self, pv_get, pv_set, pv_offset_get=None):
|
||||
pvname = pv_get
|
||||
PV.__init__(self,pvname)
|
||||
PV.__init__(self, pvname)
|
||||
self._pv_offset_get = PV(pv_offset_get)
|
||||
self._pv_setvalue = PV(pv_set)
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._storage = Storage(pvname)
|
||||
self._pv_setvalue = PV(pv_set)
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._storage = Storage(pvname)
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def get_dial(self):
|
||||
return np.round(super().get()*1e-6,9)+self._pv_offset_get.get()*1e-9 - 7.41e-9
|
||||
return (
|
||||
np.round(super().get() * 1e-6, 9)
|
||||
+ self._pv_offset_get.get() * 1e-9
|
||||
- 7.41e-9
|
||||
)
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self,value):
|
||||
def move(self, value):
|
||||
dial = value + self.offset
|
||||
self._pv_setvalue.put(dial*1e6)
|
||||
self._pv_setvalue.put(dial * 1e6)
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=12 )
|
||||
user = timeToStr( self.get(),n=12 )
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s"%(self.pvname,user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=12)
|
||||
user = timeToStr(self.get(), n=12)
|
||||
return "Pockel Trigger PV: %s user , dial = %s, %s" % (self.pvname, user, dial)
|
||||
|
||||
|
||||
_OSCILLATOR_PERIOD = 1 / 71.368704e6
|
||||
|
||||
_OSCILLATOR_PERIOD = 1/71.368704e6
|
||||
|
||||
class Phase_shifter(PV):
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
def __init__(self,pv_basename="SLAAR02-TSPL-EPL",dial_max=14.0056e-9,precision=100e-15):
|
||||
pvname = pv_basename+":CURR_DELTA_T"
|
||||
PV.__init__(self,pvname)
|
||||
self._filename = os.path.join(_basefolder,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
self.dial_max = dial_max
|
||||
""" this class is needed to store the offset in files and read in ps """
|
||||
|
||||
def __init__(
|
||||
self, pv_basename="SLAAR02-TSPL-EPL", dial_max=14.0056e-9, precision=100e-15
|
||||
):
|
||||
pvname = pv_basename + ":CURR_DELTA_T"
|
||||
PV.__init__(self, pvname)
|
||||
self._filename = os.path.join(_basefolder, pvname)
|
||||
self._pv_setvalue = PV(pv_basename + ":NEW_DELTA_T")
|
||||
self._pv_execute = PV(pv_basename + ":SET_NEW_PHASE.PROC")
|
||||
self._storage = Storage(pvname)
|
||||
self.dial_max = dial_max
|
||||
self.retry = precision
|
||||
|
||||
@property
|
||||
def offset(self): return self._storage.value
|
||||
|
||||
|
||||
def get_dial(self):
|
||||
return super().get()*1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial()-self.offset
|
||||
|
||||
def store(self,value=None):
|
||||
if value == None: value = self.get_dial()
|
||||
self._storage.store( value )
|
||||
|
||||
def move(self,value,accuracy=None):
|
||||
if accuracy is None: accuracy = self.retry
|
||||
def offset(self):
|
||||
return self._storage.value
|
||||
|
||||
def get_dial(self):
|
||||
return super().get() * 1e-12
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
return self.get_dial() - self.offset
|
||||
|
||||
def store(self, value=None):
|
||||
if value == None:
|
||||
value = self.get_dial()
|
||||
self._storage.store(value)
|
||||
|
||||
def move(self, value, accuracy=None):
|
||||
if accuracy is None:
|
||||
accuracy = self.retry
|
||||
dial = value + self.offset
|
||||
dial = np.mod(dial,_OSCILLATOR_PERIOD)
|
||||
if dial > self.dial_max: dial = self.dial_max
|
||||
dial_ps = dial*1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
dial = np.mod(dial, _OSCILLATOR_PERIOD)
|
||||
if dial > self.dial_max:
|
||||
dial = self.dial_max
|
||||
dial_ps = dial * 1e12
|
||||
self._pv_setvalue.put(dial_ps)
|
||||
time.sleep(0.1)
|
||||
self._pv_execute.put(1)
|
||||
#print(accuracy)
|
||||
while( np.abs(self.get_dial()-dial) > accuracy ):
|
||||
#print(np.abs(self.get_dial()-dial))
|
||||
# print(accuracy)
|
||||
while np.abs(self.get_dial() - dial) > accuracy:
|
||||
# print(np.abs(self.get_dial()-dial))
|
||||
time.sleep(0.2)
|
||||
|
||||
def set(self,value):
|
||||
newoffset = self.get_dial()-value
|
||||
newoffset = np.mod(newoffset,_OSCILLATOR_PERIOD)
|
||||
def set(self, value):
|
||||
newoffset = self.get_dial() - value
|
||||
newoffset = np.mod(newoffset, _OSCILLATOR_PERIOD)
|
||||
self.store(newoffset)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
dial = timeToStr( self.get_dial(),n=15 )
|
||||
user = timeToStr( self.get(),n=15 )
|
||||
return "Phase Shifter: user,dial = %s , %s"%(user,dial)
|
||||
dial = timeToStr(self.get_dial(), n=15)
|
||||
user = timeToStr(self.get(), n=15)
|
||||
return "Phase Shifter: user,dial = %s , %s" % (user, dial)
|
||||
|
||||
|
||||
_slicer_gate = Pockels_trigger(
|
||||
"SLAAR-LTIM02-EVR0:Pul3-Delay-RB",
|
||||
"SLAAR-LTIM02-EVR0:Pul3_NEW_DELAY",
|
||||
pv_offset_get="SLAAR-LTIM02-EVR0:UnivDlyModule1-Delay1-RB")
|
||||
_slicer_gate = Pockels_trigger(
|
||||
"SLAAR-LTIM02-EVR0:Pul3-Delay-RB",
|
||||
"SLAAR-LTIM02-EVR0:Pul3_NEW_DELAY",
|
||||
pv_offset_get="SLAAR-LTIM02-EVR0:UnivDlyModule1-Delay1-RB",
|
||||
)
|
||||
|
||||
_sdg1 = Pockels_trigger(
|
||||
"SLAAR-LTIM02-EVR0:Pul2-Delay-RB",
|
||||
"SLAAR-LTIM02-EVR0:Pul2_NEW_DELAY",
|
||||
pv_offset_get="SLAAR-LTIM02-EVR0:UnivDlyModule1-Delay0-RB")
|
||||
"SLAAR-LTIM02-EVR0:Pul2-Delay-RB",
|
||||
"SLAAR-LTIM02-EVR0:Pul2_NEW_DELAY",
|
||||
pv_offset_get="SLAAR-LTIM02-EVR0:UnivDlyModule1-Delay0-RB",
|
||||
)
|
||||
|
||||
_phase_shifter = Phase_shifter("SLAAR02-TSPL-EPL")
|
||||
|
||||
|
||||
_POCKELS_CELL_RESOLUTION = 7e-9
|
||||
|
||||
|
||||
class Lxt(object):
|
||||
def __init__(self,accuracy_poly=[100e-15,1e-7]):
|
||||
def __init__(self, accuracy_poly=[100e-15, 1e-7]):
|
||||
self.sdg1 = _sdg1
|
||||
self.slicer_gate = _slicer_gate
|
||||
self.slicer_gate = _slicer_gate
|
||||
self.phase_shifter = _phase_shifter
|
||||
self.Id = 'SLAAR02-TSPL-EPL'
|
||||
self.name = 'lxt'
|
||||
self.Id = "SLAAR02-TSPL-EPL"
|
||||
self.name = "lxt"
|
||||
self.elog = None
|
||||
self.accuracy_poly = accuracy_poly
|
||||
|
||||
def move_sdg(self,value):
|
||||
def move_sdg(self, value):
|
||||
self.sdg1.move(value)
|
||||
|
||||
def move(self,value,accuracy=None):
|
||||
def move(self, value, accuracy=None):
|
||||
self.sdg1.move(-value)
|
||||
self.slicer_gate.move(-value)
|
||||
if not accuracy:
|
||||
accuracy = np.abs(value)*self.accuracy_poly[1]+self.accuracy_poly[0]
|
||||
self.phase_shifter.move(value,accuracy=accuracy)
|
||||
accuracy = np.abs(value) * self.accuracy_poly[1] + self.accuracy_poly[0]
|
||||
self.phase_shifter.move(value, accuracy=accuracy)
|
||||
|
||||
def set(self,value):
|
||||
def set(self, value):
|
||||
self.phase_shifter.set(value)
|
||||
self.slicer_gate.set(-value)
|
||||
self.sdg1.set(-value)
|
||||
@@ -217,32 +235,28 @@ class Lxt(object):
|
||||
phase_shifter = self.phase_shifter.get()
|
||||
sdg1_delay = self.sdg1.get()
|
||||
|
||||
idx_pulse = (sdg1_delay+phase_shifter)/_OSCILLATOR_PERIOD
|
||||
idx_pulse = (sdg1_delay + phase_shifter) / _OSCILLATOR_PERIOD
|
||||
|
||||
delay = int(idx_pulse)*_OSCILLATOR_PERIOD - phase_shifter
|
||||
delay = int(idx_pulse) * _OSCILLATOR_PERIOD - phase_shifter
|
||||
return -delay
|
||||
|
||||
|
||||
def changeTo(self, value, hold=False):
|
||||
""" Adjustable convention"""
|
||||
|
||||
changer = lambda value: self.move(\
|
||||
value)
|
||||
changer = lambda value: self.move(value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=None)
|
||||
|
||||
target=value, parent=self, changer=changer, hold=hold, stopper=None
|
||||
)
|
||||
|
||||
def get_current_value(self):
|
||||
return self.get()
|
||||
|
||||
def set_current_value(self,value):
|
||||
def set_current_value(self, value):
|
||||
self.set(value)
|
||||
|
||||
def __repr__(self):
|
||||
delay = niceTimeToStr(lxt.get())
|
||||
return "delay = %s"%(delay)
|
||||
return "delay = %s" % (delay)
|
||||
|
||||
|
||||
lxt = Lxt()
|
||||
|
||||
+8
-10
@@ -3,24 +3,22 @@ from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
|
||||
class Palm:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self._delayStg = MotorRecord(self.Id+'-M552:MOT')
|
||||
|
||||
self._delayStg = MotorRecord(self.Id + "-M552:MOT")
|
||||
self.delay = DelayStage(self._delayStg)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****Palm motor positions******\n'
|
||||
ostr = "*****Palm motor positions******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
+8
-10
@@ -3,24 +3,22 @@ from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
|
||||
class Psen:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self._delayStg = MotorRecord(self.Id+'-M561:MOT')
|
||||
|
||||
self._delayStg = MotorRecord(self.Id + "-M561:MOT")
|
||||
self.delay = DelayStage(self._delayStg)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****PSEN motor positions******\n'
|
||||
ostr = "*****PSEN motor positions******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
+22
-26
@@ -1,39 +1,35 @@
|
||||
import numpy as np
|
||||
from matplotlib import pylab as plt
|
||||
|
||||
def readTraceTextfile(fina,numbers=None):
|
||||
|
||||
def readTraceTextfile(fina, numbers=None):
|
||||
if not numbers is None:
|
||||
d = [readTraceTextfile(fina%number) for number in numbers]
|
||||
d = [readTraceTextfile(fina % number) for number in numbers]
|
||||
else:
|
||||
d = np.loadtxt(fina, skiprows=5, delimiter=',')
|
||||
d = np.loadtxt(fina, skiprows=5, delimiter=",")
|
||||
return d
|
||||
|
||||
def getRiseTime(t,s,lims=[.1,.9]):
|
||||
|
||||
def getRiseTime(t, s, lims=[0.1, 0.9]):
|
||||
lims = np.asarray(lims)
|
||||
t = np.asarray(t)
|
||||
s = np.asarray(s)
|
||||
sel = t>0
|
||||
mxind = np.min((np.diff(s[sel])<0).nonzero()[0])
|
||||
sel = t > 0
|
||||
mxind = np.min((np.diff(s[sel]) < 0).nonzero()[0])
|
||||
mxind = sel.nonzero()[0][mxind]
|
||||
sel = t<=0
|
||||
mnind = np.max((np.diff(s[sel])<0).nonzero()[0])
|
||||
mnind = sel.nonzero()[0][mnind]+1
|
||||
crosspty = lims*(s[mxind]-s[mnind])+s[mnind]
|
||||
crossptx = np.interp(crosspty, s[mnind:mxind+1],t[mnind:mxind+1])
|
||||
return float(np.round(np.diff(crossptx),decimals=13)),[crossptx,crosspty]
|
||||
sel = t <= 0
|
||||
mnind = np.max((np.diff(s[sel]) < 0).nonzero()[0])
|
||||
mnind = sel.nonzero()[0][mnind] + 1
|
||||
crosspty = lims * (s[mxind] - s[mnind]) + s[mnind]
|
||||
crossptx = np.interp(crosspty, s[mnind : mxind + 1], t[mnind : mxind + 1])
|
||||
return float(np.round(np.diff(crossptx), decimals=13)), [crossptx, crosspty]
|
||||
|
||||
def plotTrace(fina='./scope2_testdata_2017-02-21/C2Trace00003txt'):
|
||||
t,s = readTraceTextfile(fina).T
|
||||
rt,crossers = getRiseTime(t,s)
|
||||
|
||||
def plotTrace(fina="./scope2_testdata_2017-02-21/C2Trace00003txt"):
|
||||
t, s = readTraceTextfile(fina).T
|
||||
rt, crossers = getRiseTime(t, s)
|
||||
ax = plt.gca()
|
||||
ax.plot(t,s,'.-',label='rise time = %3g (fwhm)'%rt)
|
||||
ax.plot(crossers[0],crossers[1],'xr')
|
||||
ax.set_xlabel('Time / s')
|
||||
ax.set_ylabel('Amplitude / V')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ax.plot(t, s, ".-", label="rise time = %3g (fwhm)" % rt)
|
||||
ax.plot(crossers[0], crossers[1], "xr")
|
||||
ax.set_xlabel("Time / s")
|
||||
ax.set_ylabel("Amplitude / V")
|
||||
|
||||
+88
-4
@@ -1,9 +1,93 @@
|
||||
import json
|
||||
import importlib
|
||||
import sys
|
||||
from colorama import Fore as _color
|
||||
from functools import partial
|
||||
from .lazy_proxy import Proxy
|
||||
from ..aliases import Alias
|
||||
|
||||
|
||||
class Component:
|
||||
def __init__(self, namestring):
|
||||
self.name = namestring
|
||||
|
||||
|
||||
def init_name_obj(obj, args, kwargs, name=None):
|
||||
try:
|
||||
return obj(*args, **kwargs, name=name)
|
||||
except TypeError:
|
||||
return obj(*args, **kwargs)
|
||||
|
||||
|
||||
def init_device(type_string, name, args=[], kwargs={}, verbose=True, lazy=True):
|
||||
if verbose:
|
||||
print(("Configuring %s " % (name)).ljust(25), end="")
|
||||
sys.stdout.flush()
|
||||
imp_p, type_name = type_string.split(sep=":")
|
||||
imp_p = imp_p.split(sep=".")
|
||||
if verbose:
|
||||
print(("(%s)" % (type_name)).ljust(25), end="")
|
||||
sys.stdout.flush()
|
||||
try:
|
||||
tg = importlib.import_module(".".join(imp_p)).__dict__[type_name]
|
||||
|
||||
if lazy:
|
||||
tdev = Proxy(partial(init_name_obj, tg, args, kwargs, name=name))
|
||||
if verbose:
|
||||
print((_color.YELLOW + "LAZY" + _color.RESET).rjust(5))
|
||||
sys.stdout.flush()
|
||||
else:
|
||||
tdev = init_name_obj(tg, args, kwargs, name=name)
|
||||
if verbose:
|
||||
print((_color.GREEN + "OK" + _color.RESET).rjust(5))
|
||||
sys.stdout.flush()
|
||||
return tdev
|
||||
except Exception as expt:
|
||||
# tb = traceback.format_exc()
|
||||
if verbose:
|
||||
print((_color.RED + "FAILED" + _color.RESET).rjust(5))
|
||||
# print(sys.exc_info())
|
||||
raise expt
|
||||
|
||||
|
||||
def initFromConfigList(config_list, lazy=False):
|
||||
op = {}
|
||||
for td in config_list:
|
||||
args = [op[ta.name] if isinstance(ta, Component) else ta for ta in td["args"]]
|
||||
kwargs = {
|
||||
tkwk: op[tkwv.name] if isinstance(tkwv, Component) else tkwv
|
||||
for tkwk, tkwv in td["kwargs"].items()
|
||||
}
|
||||
op[td["name"]] = init_device(td["type"], td["name"], args, kwargs, lazy=lazy)
|
||||
return op
|
||||
|
||||
|
||||
class Exp:
|
||||
def __init__(self,module):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def loadConfig(fina):
|
||||
with open(fina,'r') as f:
|
||||
with open(fina, "r") as f:
|
||||
return json.load(f)
|
||||
|
||||
def writeConfig(fina,obj):
|
||||
with open(fina,'w') as f:
|
||||
json.dump(obj,f)
|
||||
|
||||
def writeConfig(fina, obj):
|
||||
with open(fina, "w") as f:
|
||||
json.dump(obj, f)
|
||||
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
out = []
|
||||
with open(fina, "r") as f:
|
||||
done = False
|
||||
while not done:
|
||||
d = f.readline()
|
||||
if not d:
|
||||
done = True
|
||||
if len(d) > 0:
|
||||
if not d.isspace():
|
||||
if not d[0] == "#":
|
||||
out.append(d.strip())
|
||||
return out
|
||||
|
||||
+42
-46
@@ -3,83 +3,79 @@ from getpass import getuser as _getuser
|
||||
from getpass import getpass as _getpass
|
||||
import os, datetime, subprocess
|
||||
|
||||
def getDefaultElogInstance(url,**kwargs):
|
||||
|
||||
def getDefaultElogInstance(url, **kwargs):
|
||||
from pathlib import Path
|
||||
|
||||
home = str(Path.home())
|
||||
if not ('user' in kwargs.keys()):
|
||||
if not ("user" in kwargs.keys()):
|
||||
kwargs.update(dict(user=_getuser()))
|
||||
|
||||
if not ('password' in kwargs.keys()):
|
||||
if not ("password" in kwargs.keys()):
|
||||
try:
|
||||
with open(os.path.join(home,'.elog_psi'),'r') as f:
|
||||
with open(os.path.join(home, ".elog_psi"), "r") as f:
|
||||
_pw = f.read().strip()
|
||||
except:
|
||||
print('Enter elog password for user: %s'%kwargs['user'])
|
||||
print("Enter elog password for user: %s" % kwargs["user"])
|
||||
_pw = _getpass()
|
||||
kwargs.update(dict(password=_pw))
|
||||
|
||||
return _elog_ha.open(url,**kwargs),kwargs['user']
|
||||
return _elog_ha.open(url, **kwargs), kwargs["user"]
|
||||
|
||||
|
||||
class Elog:
|
||||
def __init__(self,url,screenshot_directory='',**kwargs):
|
||||
self._log,self.user = getDefaultElogInstance(url,**kwargs)
|
||||
def __init__(self, url, screenshot_directory="", **kwargs):
|
||||
self._log, self.user = getDefaultElogInstance(url, **kwargs)
|
||||
self._screenshot = Screenshot(screenshot_directory)
|
||||
self.read = self._log.read
|
||||
|
||||
def post(self,*args,**kwargs):
|
||||
def post(self, *args, **kwargs):
|
||||
"""
|
||||
"""
|
||||
if not ('Author' in kwargs):
|
||||
kwargs['Author'] = self.user
|
||||
return self._log.post(*args,**kwargs)
|
||||
if not ("Author" in kwargs):
|
||||
kwargs["Author"] = self.user
|
||||
return self._log.post(*args, **kwargs)
|
||||
|
||||
def screenshot(self,message='', window=False, desktop=False, delay=3, **kwargs):
|
||||
def screenshot(self, message="", window=False, desktop=False, delay=3, **kwargs):
|
||||
filepath = self._screenshot.shoot()[0]
|
||||
kwargs.update({'attachments':[filepath]})
|
||||
self.post(message,**kwargs)
|
||||
kwargs.update({"attachments": [filepath]})
|
||||
self.post(message, **kwargs)
|
||||
|
||||
|
||||
class Screenshot:
|
||||
def __init__(self,screenshot_directory='',**kwargs):
|
||||
def __init__(self, screenshot_directory="", **kwargs):
|
||||
self._screenshot_directory = screenshot_directory
|
||||
if not ('user' in kwargs.keys()):
|
||||
self.user=_getuser()
|
||||
if not ("user" in kwargs.keys()):
|
||||
self.user = _getuser()
|
||||
else:
|
||||
self.user = kwargs['user']
|
||||
self.user = kwargs["user"]
|
||||
|
||||
def show_directory(self):
|
||||
|
||||
p = subprocess.Popen(['nautilus',self._screenshot_directory],
|
||||
stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
p = subprocess.Popen(
|
||||
["nautilus", self._screenshot_directory],
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
)
|
||||
|
||||
def shoot(self,message='', window=False, desktop=False, delay=3, **kwargs):
|
||||
cmd = ['gnome-screenshot']
|
||||
def shoot(self, message="", window=False, desktop=False, delay=3, **kwargs):
|
||||
cmd = ["gnome-screenshot"]
|
||||
if window:
|
||||
cmd.append('-w')
|
||||
cmd.append('--delay=%d'%delay)
|
||||
cmd.append("-w")
|
||||
cmd.append("--delay=%d" % delay)
|
||||
elif desktop:
|
||||
cmd.append('--delay=%d'%delay)
|
||||
cmd.append("--delay=%d" % delay)
|
||||
else:
|
||||
cmd.append('-a')
|
||||
cmd.append("-a")
|
||||
tim = datetime.datetime.now()
|
||||
fina = '%s-%s-%s_%s-%s-%s'%tim.timetuple()[:6]
|
||||
if 'Author' in kwargs.keys():
|
||||
fina+='_%s'%user
|
||||
fina = "%s-%s-%s_%s-%s-%s" % tim.timetuple()[:6]
|
||||
if "Author" in kwargs.keys():
|
||||
fina += "_%s" % user
|
||||
else:
|
||||
fina+='_%s'%self.user
|
||||
fina+='.png'
|
||||
filepath = os.path.join(self._screenshot_directory,fina)
|
||||
cmd.append('--file')
|
||||
fina += "_%s" % self.user
|
||||
fina += ".png"
|
||||
filepath = os.path.join(self._screenshot_directory, fina)
|
||||
cmd.append("--file")
|
||||
cmd.append(filepath)
|
||||
p = subprocess.call(cmd,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
|
||||
return filepath,p
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
p = subprocess.call(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
|
||||
return filepath, p
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
from .slots import Proxy
|
||||
@@ -0,0 +1,9 @@
|
||||
import sys
|
||||
|
||||
PY2 = sys.version_info[0] == 2
|
||||
PY3 = sys.version_info[0] == 3
|
||||
|
||||
|
||||
def with_metaclass(meta, *bases):
|
||||
"""Create a base class with a metaclass."""
|
||||
return meta("NewBase", bases, {})
|
||||
@@ -0,0 +1,423 @@
|
||||
import operator
|
||||
|
||||
from .compat import PY2
|
||||
from .compat import PY3
|
||||
from .compat import with_metaclass
|
||||
from .utils import identity
|
||||
|
||||
|
||||
class _ProxyMethods(object):
|
||||
# We use properties to override the values of __module__ and
|
||||
# __doc__. If we add these in ObjectProxy, the derived class
|
||||
# __dict__ will still be setup to have string variants of these
|
||||
# attributes and the rules of descriptors means that they appear to
|
||||
# take precedence over the properties in the base class. To avoid
|
||||
# that, we copy the properties into the derived class type itself
|
||||
# via a meta class. In that way the properties will always take
|
||||
# precedence.
|
||||
|
||||
@property
|
||||
def __module__(self):
|
||||
return self.__wrapped__.__module__
|
||||
|
||||
@__module__.setter
|
||||
def __module__(self, value):
|
||||
self.__wrapped__.__module__ = value
|
||||
|
||||
@property
|
||||
def __doc__(self):
|
||||
return self.__wrapped__.__doc__
|
||||
|
||||
@__doc__.setter
|
||||
def __doc__(self, value):
|
||||
self.__wrapped__.__doc__ = value
|
||||
|
||||
# We similar use a property for __dict__. We need __dict__ to be
|
||||
# explicit to ensure that vars() works as expected.
|
||||
|
||||
@property
|
||||
def __dict__(self):
|
||||
return self.__wrapped__.__dict__
|
||||
|
||||
# Need to also propagate the special __weakref__ attribute for case
|
||||
# where decorating classes which will define this. If do not define
|
||||
# it and use a function like inspect.getmembers() on a decorator
|
||||
# class it will fail. This can't be in the derived classes.
|
||||
|
||||
@property
|
||||
def __weakref__(self):
|
||||
return self.__wrapped__.__weakref__
|
||||
|
||||
|
||||
class _ProxyMetaType(type):
|
||||
def __new__(cls, name, bases, dictionary):
|
||||
# Copy our special properties into the class so that they
|
||||
# always take precedence over attributes of the same name added
|
||||
# during construction of a derived class. This is to save
|
||||
# duplicating the implementation for them in all derived classes.
|
||||
|
||||
dictionary.update(vars(_ProxyMethods))
|
||||
|
||||
return type.__new__(cls, name, bases, dictionary)
|
||||
|
||||
|
||||
class Proxy(with_metaclass(_ProxyMetaType)):
|
||||
"""
|
||||
A proxy implementation in pure Python, using slots. You can subclass this to add
|
||||
local methods or attributes, or enable __dict__.
|
||||
|
||||
The most important internals:
|
||||
|
||||
* ``__factory__`` is the callback that "materializes" the object we proxy to.
|
||||
* ``__target__`` will contain the object we proxy to, once it's "materialized".
|
||||
* ``__wrapped__`` is a property that does either:
|
||||
|
||||
* return ``__target__`` if it's set.
|
||||
* calls ``__factory__``, saves result to ``__target__`` and returns said result.
|
||||
"""
|
||||
|
||||
__slots__ = "__target__", "__factory__"
|
||||
|
||||
def __init__(self, factory):
|
||||
object.__setattr__(self, "__factory__", factory)
|
||||
|
||||
@property
|
||||
def __wrapped__(
|
||||
self,
|
||||
__getattr__=object.__getattribute__,
|
||||
__setattr__=object.__setattr__,
|
||||
__delattr__=object.__delattr__,
|
||||
):
|
||||
try:
|
||||
return __getattr__(self, "__target__")
|
||||
except AttributeError:
|
||||
try:
|
||||
factory = __getattr__(self, "__factory__")
|
||||
except AttributeError:
|
||||
raise ValueError("Proxy hasn't been initiated: __factory__ is missing.")
|
||||
target = factory()
|
||||
__setattr__(self, "__target__", target)
|
||||
return target
|
||||
|
||||
@__wrapped__.deleter
|
||||
def __wrapped__(self, __delattr__=object.__delattr__):
|
||||
__delattr__(self, "__target__")
|
||||
|
||||
@__wrapped__.setter
|
||||
def __wrapped__(self, target, __setattr__=object.__setattr__):
|
||||
__setattr__(self, "__target__", target)
|
||||
|
||||
@property
|
||||
def __name__(self):
|
||||
return self.__wrapped__.__name__
|
||||
|
||||
@__name__.setter
|
||||
def __name__(self, value):
|
||||
self.__wrapped__.__name__ = value
|
||||
|
||||
@property
|
||||
def __class__(self):
|
||||
return self.__wrapped__.__class__
|
||||
|
||||
@__class__.setter
|
||||
def __class__(self, value):
|
||||
self.__wrapped__.__class__ = value
|
||||
|
||||
@property
|
||||
def __annotations__(self):
|
||||
return self.__wrapped__.__anotations__
|
||||
|
||||
@__annotations__.setter
|
||||
def __annotations__(self, value):
|
||||
self.__wrapped__.__annotations__ = value
|
||||
|
||||
def __dir__(self):
|
||||
return dir(self.__wrapped__)
|
||||
|
||||
def __str__(self):
|
||||
return str(self.__wrapped__)
|
||||
|
||||
if PY3:
|
||||
|
||||
def __bytes__(self):
|
||||
return bytes(self.__wrapped__)
|
||||
|
||||
def __repr__(self, __getattr__=object.__getattribute__):
|
||||
try:
|
||||
target = __getattr__(self, "__target__")
|
||||
except AttributeError:
|
||||
return "<%s at 0x%x with factory %r>" % (
|
||||
type(self).__name__,
|
||||
id(self),
|
||||
self.__factory__,
|
||||
)
|
||||
else:
|
||||
# return '<%s at 0x%x wrapping %r at 0x%x with factory %r>' % (
|
||||
# type(self).__name__, id(self),
|
||||
# target, id(target),
|
||||
# self.__factory__
|
||||
# )
|
||||
return "%r" % (target)
|
||||
|
||||
def __reversed__(self):
|
||||
return reversed(self.__wrapped__)
|
||||
|
||||
if PY3:
|
||||
|
||||
def __round__(self):
|
||||
return round(self.__wrapped__)
|
||||
|
||||
def __lt__(self, other):
|
||||
return self.__wrapped__ < other
|
||||
|
||||
def __le__(self, other):
|
||||
return self.__wrapped__ <= other
|
||||
|
||||
def __eq__(self, other):
|
||||
return self.__wrapped__ == other
|
||||
|
||||
def __ne__(self, other):
|
||||
return self.__wrapped__ != other
|
||||
|
||||
def __gt__(self, other):
|
||||
return self.__wrapped__ > other
|
||||
|
||||
def __ge__(self, other):
|
||||
return self.__wrapped__ >= other
|
||||
|
||||
def __hash__(self):
|
||||
return hash(self.__wrapped__)
|
||||
|
||||
def __nonzero__(self):
|
||||
return bool(self.__wrapped__)
|
||||
|
||||
def __bool__(self):
|
||||
return bool(self.__wrapped__)
|
||||
|
||||
def __setattr__(self, name, value, __setattr__=object.__setattr__):
|
||||
if hasattr(type(self), name):
|
||||
__setattr__(self, name, value)
|
||||
else:
|
||||
setattr(self.__wrapped__, name, value)
|
||||
|
||||
def __getattr__(self, name):
|
||||
if name in ("__wrapped__", "__factory__"):
|
||||
raise AttributeError(name)
|
||||
else:
|
||||
return getattr(self.__wrapped__, name)
|
||||
|
||||
def __delattr__(self, name, __delattr__=object.__delattr__):
|
||||
if hasattr(type(self), name):
|
||||
__delattr__(self, name)
|
||||
else:
|
||||
delattr(self.__wrapped__, name)
|
||||
|
||||
def __add__(self, other):
|
||||
return self.__wrapped__ + other
|
||||
|
||||
def __sub__(self, other):
|
||||
return self.__wrapped__ - other
|
||||
|
||||
def __mul__(self, other):
|
||||
return self.__wrapped__ * other
|
||||
|
||||
def __div__(self, other):
|
||||
return operator.div(self.__wrapped__, other)
|
||||
|
||||
def __truediv__(self, other):
|
||||
return operator.truediv(self.__wrapped__, other)
|
||||
|
||||
def __floordiv__(self, other):
|
||||
return self.__wrapped__ // other
|
||||
|
||||
def __mod__(self, other):
|
||||
return self.__wrapped__ ^ other
|
||||
|
||||
def __divmod__(self, other):
|
||||
return divmod(self.__wrapped__, other)
|
||||
|
||||
def __pow__(self, other, *args):
|
||||
return pow(self.__wrapped__, other, *args)
|
||||
|
||||
def __lshift__(self, other):
|
||||
return self.__wrapped__ << other
|
||||
|
||||
def __rshift__(self, other):
|
||||
return self.__wrapped__ >> other
|
||||
|
||||
def __and__(self, other):
|
||||
return self.__wrapped__ & other
|
||||
|
||||
def __xor__(self, other):
|
||||
return self.__wrapped__ ^ other
|
||||
|
||||
def __or__(self, other):
|
||||
return self.__wrapped__ | other
|
||||
|
||||
def __radd__(self, other):
|
||||
return other + self.__wrapped__
|
||||
|
||||
def __rsub__(self, other):
|
||||
return other - self.__wrapped__
|
||||
|
||||
def __rmul__(self, other):
|
||||
return other * self.__wrapped__
|
||||
|
||||
def __rdiv__(self, other):
|
||||
return operator.div(other, self.__wrapped__)
|
||||
|
||||
def __rtruediv__(self, other):
|
||||
return operator.truediv(other, self.__wrapped__)
|
||||
|
||||
def __rfloordiv__(self, other):
|
||||
return other // self.__wrapped__
|
||||
|
||||
def __rmod__(self, other):
|
||||
return other % self.__wrapped__
|
||||
|
||||
def __rdivmod__(self, other):
|
||||
return divmod(other, self.__wrapped__)
|
||||
|
||||
def __rpow__(self, other, *args):
|
||||
return pow(other, self.__wrapped__, *args)
|
||||
|
||||
def __rlshift__(self, other):
|
||||
return other << self.__wrapped__
|
||||
|
||||
def __rrshift__(self, other):
|
||||
return other >> self.__wrapped__
|
||||
|
||||
def __rand__(self, other):
|
||||
return other & self.__wrapped__
|
||||
|
||||
def __rxor__(self, other):
|
||||
return other ^ self.__wrapped__
|
||||
|
||||
def __ror__(self, other):
|
||||
return other | self.__wrapped__
|
||||
|
||||
def __iadd__(self, other):
|
||||
self.__wrapped__ += other
|
||||
return self
|
||||
|
||||
def __isub__(self, other):
|
||||
self.__wrapped__ -= other
|
||||
return self
|
||||
|
||||
def __imul__(self, other):
|
||||
self.__wrapped__ *= other
|
||||
return self
|
||||
|
||||
def __idiv__(self, other):
|
||||
self.__wrapped__ = operator.idiv(self.__wrapped__, other)
|
||||
return self
|
||||
|
||||
def __itruediv__(self, other):
|
||||
self.__wrapped__ = operator.itruediv(self.__wrapped__, other)
|
||||
return self
|
||||
|
||||
def __ifloordiv__(self, other):
|
||||
self.__wrapped__ //= other
|
||||
return self
|
||||
|
||||
def __imod__(self, other):
|
||||
self.__wrapped__ %= other
|
||||
return self
|
||||
|
||||
def __ipow__(self, other):
|
||||
self.__wrapped__ **= other
|
||||
return self
|
||||
|
||||
def __ilshift__(self, other):
|
||||
self.__wrapped__ <<= other
|
||||
return self
|
||||
|
||||
def __irshift__(self, other):
|
||||
self.__wrapped__ >>= other
|
||||
return self
|
||||
|
||||
def __iand__(self, other):
|
||||
self.__wrapped__ &= other
|
||||
return self
|
||||
|
||||
def __ixor__(self, other):
|
||||
self.__wrapped__ ^= other
|
||||
return self
|
||||
|
||||
def __ior__(self, other):
|
||||
self.__wrapped__ |= other
|
||||
return self
|
||||
|
||||
def __neg__(self):
|
||||
return -self.__wrapped__
|
||||
|
||||
def __pos__(self):
|
||||
return +self.__wrapped__
|
||||
|
||||
def __abs__(self):
|
||||
return abs(self.__wrapped__)
|
||||
|
||||
def __invert__(self):
|
||||
return ~self.__wrapped__
|
||||
|
||||
def __int__(self):
|
||||
return int(self.__wrapped__)
|
||||
|
||||
if PY2:
|
||||
|
||||
def __long__(self):
|
||||
return long(self.__wrapped__) # flake8: noqa
|
||||
|
||||
def __float__(self):
|
||||
return float(self.__wrapped__)
|
||||
|
||||
def __oct__(self):
|
||||
return oct(self.__wrapped__)
|
||||
|
||||
def __hex__(self):
|
||||
return hex(self.__wrapped__)
|
||||
|
||||
def __index__(self):
|
||||
return operator.index(self.__wrapped__)
|
||||
|
||||
def __len__(self):
|
||||
return len(self.__wrapped__)
|
||||
|
||||
def __contains__(self, value):
|
||||
return value in self.__wrapped__
|
||||
|
||||
def __getitem__(self, key):
|
||||
return self.__wrapped__[key]
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.__wrapped__[key] = value
|
||||
|
||||
def __delitem__(self, key):
|
||||
del self.__wrapped__[key]
|
||||
|
||||
def __getslice__(self, i, j):
|
||||
return self.__wrapped__[i:j]
|
||||
|
||||
def __setslice__(self, i, j, value):
|
||||
self.__wrapped__[i:j] = value
|
||||
|
||||
def __delslice__(self, i, j):
|
||||
del self.__wrapped__[i:j]
|
||||
|
||||
def __enter__(self):
|
||||
return self.__wrapped__.__enter__()
|
||||
|
||||
def __exit__(self, *args, **kwargs):
|
||||
return self.__wrapped__.__exit__(*args, **kwargs)
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.__wrapped__)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
return self.__wrapped__(*args, **kwargs)
|
||||
|
||||
def __reduce__(self):
|
||||
return identity, (self.__wrapped__,)
|
||||
|
||||
def __reduce_ex__(self, protocol):
|
||||
return identity, (self.__wrapped__,)
|
||||
@@ -0,0 +1,13 @@
|
||||
def identity(obj):
|
||||
return obj
|
||||
|
||||
|
||||
class cached_property(object):
|
||||
def __init__(self, func):
|
||||
self.func = func
|
||||
|
||||
def __get__(self, obj, cls):
|
||||
if obj is None:
|
||||
return self
|
||||
value = obj.__dict__[self.func.__name__] = self.func(obj)
|
||||
return value
|
||||
+19
-15
@@ -2,19 +2,23 @@
|
||||
from epics import PV
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
|
||||
class stationMessage:
|
||||
def __init__(self,station):
|
||||
self._BL = station
|
||||
|
||||
def post(self,message):
|
||||
stationStr = self._BL
|
||||
msg=message
|
||||
date_formatted=datetime.datetime.strftime(datetime.datetime.now(), "%a %d-%b-%Y %H:%M:%S")
|
||||
mscroll=PV('SF-OP:'+str(stationStr)+'-MSG:OP-MSCROLL.PROC')
|
||||
mscroll.value=1
|
||||
msg1=PV('SF-OP:'+str(stationStr)+'-MSG:OP-MSG1')
|
||||
msg1.value = msg.encode()
|
||||
date1=PV('SF-OP:'+str(stationStr)+'-MSG:OP-DATE1')
|
||||
date1.value = date_formatted.encode()
|
||||
msg1.disconnect()
|
||||
date1.disconnect()
|
||||
def __init__(self, station):
|
||||
self._BL = station
|
||||
|
||||
def post(self, message):
|
||||
stationStr = self._BL
|
||||
msg = message
|
||||
date_formatted = datetime.datetime.strftime(
|
||||
datetime.datetime.now(), "%a %d-%b-%Y %H:%M:%S"
|
||||
)
|
||||
mscroll = PV("SF-OP:" + str(stationStr) + "-MSG:OP-MSCROLL.PROC")
|
||||
mscroll.value = 1
|
||||
msg1 = PV("SF-OP:" + str(stationStr) + "-MSG:OP-MSG1")
|
||||
msg1.value = msg.encode()
|
||||
date1 = PV("SF-OP:" + str(stationStr) + "-MSG:OP-DATE1")
|
||||
date1.value = date_formatted.encode()
|
||||
msg1.disconnect()
|
||||
date1.disconnect()
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
import matplotlib.pyplot as plt
|
||||
|
||||
|
||||
def identifyContrastplotData(x,y,i):
|
||||
assert i.ndim==2, "Intensity data needs to be 2 dimensional!"
|
||||
assert x.ndim==y.ndim, "please provide x and y plotting coordinate in same dimension"
|
||||
|
||||
|
||||
|
||||
def identifyContrastplotData(x, y, i):
|
||||
assert i.ndim == 2, "Intensity data needs to be 2 dimensional!"
|
||||
assert (
|
||||
x.ndim == y.ndim
|
||||
), "please provide x and y plotting coordinate in same dimension"
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
import traceback
|
||||
from colorama import Fore as _color
|
||||
from importlib import import_module
|
||||
import copy
|
||||
|
||||
try:
|
||||
from lazy_object_proxy import Proxy as LazyProxy
|
||||
except:
|
||||
print(
|
||||
"Could not find package lazy-object-proxy for lazy initialisation of devices!"
|
||||
)
|
||||
pass
|
||||
|
||||
|
||||
def init_device(devDict, devId, args, kwargs, verbose=True):
|
||||
imp_p = devDict["eco_type"].split(sep=".")
|
||||
dev_alias = devDict["alias"]
|
||||
dev_alias = dev_alias[0].lower() + dev_alias[1:]
|
||||
eco_type_name = imp_p[-1]
|
||||
istr = "from .." + ".".join(imp_p[:-1]) + " import "
|
||||
istr += "%s as _%s" % (eco_type_name, eco_type_name)
|
||||
# print(istr)
|
||||
if verbose:
|
||||
print(("Configuring %s " % (dev_alias)).ljust(25), end="")
|
||||
print(("(%s)" % (devId)).ljust(25), end="")
|
||||
error = None
|
||||
try:
|
||||
exec(istr)
|
||||
tdev = eval("_%s(Id='%s',*args,**kwargs)" % (eco_type_name, devId))
|
||||
tdev.name = dev_alias
|
||||
tdev._z_und = devDict["z_und"]
|
||||
if verbose:
|
||||
print((_color.GREEN + "OK" + _color.RESET).rjust(5))
|
||||
return tdev
|
||||
except Exception as expt:
|
||||
# tb = traceback.format_exc()
|
||||
if verbose:
|
||||
print((_color.RED + "FAILED" + _color.RESET).rjust(5))
|
||||
# print(sys.exc_info())
|
||||
raise expt
|
||||
|
||||
|
||||
def initDeviceAliasList(aliases, lazy=False, verbose=True):
|
||||
devices = {}
|
||||
problems = {}
|
||||
for device_Id in aliases.keys():
|
||||
alias = aliases[device_Id]["alias"]
|
||||
alias = alias[0].lower() + alias[1:]
|
||||
if "eco_type" in aliases[device_Id].keys() and aliases[device_Id]["eco_type"]:
|
||||
if "args" in aliases[device_Id].keys() and aliases[device_Id]["args"]:
|
||||
args = aliases[device_Id]["args"]
|
||||
else:
|
||||
args = tuple()
|
||||
|
||||
if "kwargs" in aliases[device_Id].keys() and aliases[device_Id]["kwargs"]:
|
||||
kwargs = aliases[device_Id]["kwargs"]
|
||||
else:
|
||||
kwargs = dict()
|
||||
try:
|
||||
devices[alias] = {}
|
||||
devices[alias]["device_Id"] = device_Id
|
||||
if lazy:
|
||||
devices[alias]["factory"] = lambda: init_device(
|
||||
aliases[device_Id], device_Id, args, kwargs, verbose=verbose
|
||||
)
|
||||
dev = LazyProxy(devices[alias]["factory"])
|
||||
else:
|
||||
dev = init_device(
|
||||
aliases[device_Id], device_Id, args, kwargs, verbose=verbose
|
||||
)
|
||||
devices[alias]["instance"] = dev
|
||||
except:
|
||||
device.pop(alias)
|
||||
problems[alias] = {}
|
||||
problems[alias]["device_Id"] = device_Id
|
||||
problems[alias]["trace"] = traceback.format_exc()
|
||||
return devices, problems
|
||||
@@ -1,2 +1 @@
|
||||
from . import materials
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,110 @@
|
||||
import xrayutilities as xu
|
||||
from . import consts as _consts
|
||||
from scipy.constants import torr, bar, k, N_A, R
|
||||
import numpy as np
|
||||
|
||||
# This module holds relevant materials of the
|
||||
# xrayutilities materials class,
|
||||
|
||||
|
||||
class MaterialCollection:
|
||||
""" Dummy class collections of materials (dict-like)."""
|
||||
|
||||
def __init__(self, **entries):
|
||||
self.__dict__.update(entries)
|
||||
|
||||
def __setitem__(self, key, value):
|
||||
self.__dict__.update({key: value})
|
||||
|
||||
|
||||
_amorphous = dict()
|
||||
_crystal = dict()
|
||||
_gas = dict()
|
||||
|
||||
amorphous = MaterialCollection()
|
||||
crystal = MaterialCollection()
|
||||
gas = MaterialCollection()
|
||||
|
||||
|
||||
def _get_transmission(self, d, E="config"):
|
||||
""" calculate the transmittion after thickness d (in m) of material at energy E (in eV)."""
|
||||
return np.exp(-d * 1e6 / self.absorption_length(E))
|
||||
|
||||
|
||||
xu.materials.Material.transmission = _get_transmission
|
||||
|
||||
|
||||
crystal["Si"] = xu.materials.Si
|
||||
crystal["Ge"] = xu.materials.Ge
|
||||
crystal["GaAs"] = xu.materials.GaAs
|
||||
crystal["Al"] = xu.materials.Al
|
||||
crystal["Diamond"] = xu.materials.C
|
||||
crystal["Be"] = xu.materials.material.Crystal(
|
||||
"Be",
|
||||
xu.materials.spacegrouplattice.SGLattice(
|
||||
194, 2.2858, 3.5843, atoms=[xu.materials.elements.Be], pos=["2c"]
|
||||
),
|
||||
)
|
||||
|
||||
amorphous["B4C"] = xu.materials.material.Amorphous("B4C", 2520, [("B", 4), ("C", 1)])
|
||||
amorphous["Mo"] = xu.materials.material.Amorphous("Mo", 10220, [("Mo", 1)])
|
||||
amorphous["polyimide"] = xu.materials.material.Amorphous(
|
||||
"polyimide", 1430, [("C", 22), ("H", 10), ("N", 2), ("O", 5)]
|
||||
)
|
||||
amorphous["mylar"] = xu.materials.material.Amorphous(
|
||||
"mylar", 1400, [("C", 10), ("H", 8), ("O", 4)]
|
||||
)
|
||||
amorphous["polycarbonate"] = xu.materials.material.Amorphous(
|
||||
"polycarbonate", 1200, [("C", 16), ("H", 14), ("O", 3)]
|
||||
)
|
||||
amorphous["Si3N4"] = xu.materials.material.Amorphous(
|
||||
"Silicon nitride", 3440, [("Si", 3), ("N", 4)]
|
||||
)
|
||||
amorphous["air"] = xu.materials.material.Amorphous(
|
||||
"air", 1000, [("N", 1.562), ("O", 0.42), ("C", 0.0003), ("Ar", 0.0094)]
|
||||
)
|
||||
|
||||
|
||||
# more useful values and constants
|
||||
# elementName = DummyClassDict(_consts.elementName)
|
||||
# meltPoint = DummyClassDict(_consts.meltPoint)
|
||||
# density = DummyClassDict(_consts.Density)
|
||||
|
||||
|
||||
class Gas(xu.materials.material.Amorphous):
|
||||
def __init__(
|
||||
self, name, pressure=bar, temperature=295, molecule_size=1, atoms=None, cij=None
|
||||
):
|
||||
"""pressure in Pascal, temperature in Kelvin"""
|
||||
self.pressure = pressure
|
||||
self.temperature = temperature
|
||||
self.molecule_size = molecule_size
|
||||
super(Gas, self).__init__(name, 0, atoms=atoms, cij=cij)
|
||||
|
||||
def _getdensity(self):
|
||||
"""
|
||||
calculates the mass density of an material from the atomic composition and the average molecule size (ideal gas).
|
||||
|
||||
Returns
|
||||
-------
|
||||
mass density in kg/m^3
|
||||
"""
|
||||
num_dens = self.pressure / k / self.temperature
|
||||
return self._get_composition_mass() * num_dens * self.molecule_size
|
||||
|
||||
density = property(_getdensity)
|
||||
|
||||
def _get_composition_mass(self):
|
||||
w = 0
|
||||
for atom, occ in self.base:
|
||||
w += atom.weight * occ
|
||||
return w
|
||||
|
||||
|
||||
gas["air"] = Gas(
|
||||
"air",
|
||||
molecule_size=1.9917,
|
||||
atoms=[("N", 1.562), ("O", 0.42), ("C", 0.0003), ("Ar", 0.0094)],
|
||||
)
|
||||
gas["He"] = Gas("He", molecule_size=1, atoms=[("He", 1)])
|
||||
gas["N"] = Gas("He", molecule_size=2, atoms=[("N", 1)])
|
||||
@@ -0,0 +1,44 @@
|
||||
import xrayutilities as xu
|
||||
import xraylib as xl
|
||||
import numpy as np
|
||||
from . import materials
|
||||
|
||||
|
||||
def getKBMirrorLayer():
|
||||
subst = xu.simpack.Layer(materials.crystal.Si, np.inf)
|
||||
highZ = xu.simpack.Layer(materials.amorphous.Mo, 200)
|
||||
lowZ = xu.simpack.Layer(materials.amorphous.B4C, 150)
|
||||
return subst + highZ + lowZ
|
||||
|
||||
|
||||
def calcReflectivity(
|
||||
mirror=getKBMirrorLayer(),
|
||||
energys=np.linspace(2000, 12000, 200),
|
||||
alphais=np.linspace(0, 3, 200),
|
||||
sample_width=500,
|
||||
**kwargs
|
||||
):
|
||||
Refl = []
|
||||
for E in energys:
|
||||
m = xu.simpack.SpecularReflectivityModel(mirror, energy=E, **kwargs)
|
||||
Refl.append(m.simulate(alphais))
|
||||
|
||||
return np.asarray(Refl), energys, alphais
|
||||
|
||||
|
||||
def absorptionEdge(element, edge=None):
|
||||
if type(element) is str:
|
||||
element = xl.SymbolToAtomicNumber(element)
|
||||
shells = ["K", "L1", "L2", "L3", "M1", "M2", "M3", "M4", "M5"]
|
||||
if edge is not None:
|
||||
shell_ind = shells.index(edge)
|
||||
return xl.EdgeEnergy(element, shell_ind)
|
||||
else:
|
||||
shell_inds = range(8)
|
||||
print("Absorption edges %s" % xl.AtomicNumberToSymbol(element))
|
||||
for shell_ind in shell_inds:
|
||||
print(
|
||||
" "
|
||||
+ shells[shell_ind].ljust(3)
|
||||
+ " = %7.1f eV" % (xl.EdgeEnergy(element, shell_ind) * 1000)
|
||||
)
|
||||
@@ -46,33 +46,37 @@ def cartesian(arrays, out=None):
|
||||
out = np.zeros([n, len(arrays)], dtype=dtype)
|
||||
|
||||
m = n / arrays[0].size
|
||||
out[:,0] = np.repeat(arrays[0], m)
|
||||
out[:, 0] = np.repeat(arrays[0], m)
|
||||
if arrays[1:]:
|
||||
cartesian(arrays[1:], out=out[0:m,1:])
|
||||
cartesian(arrays[1:], out=out[0:m, 1:])
|
||||
for j in range(1, arrays[0].size):
|
||||
out[j*m:(j+1)*m,1:] = out[0:m,1:]
|
||||
out[j * m : (j + 1) * m, 1:] = out[0:m, 1:]
|
||||
return out
|
||||
|
||||
|
||||
def E2lam(energy):
|
||||
"""energy in eV, lambda in Ångstrøm"""
|
||||
return constants.h*constants.c/constants.e / energy *1e10
|
||||
return constants.h * constants.c / constants.e / energy * 1e10
|
||||
|
||||
def QE2theta(Q,energy):
|
||||
|
||||
def QE2theta(Q, energy):
|
||||
"""Q in Å**(-1), energy in eV, theta in radians"""
|
||||
return np.arcsin(E2lam(energy)/4/np.pi*Q)
|
||||
return np.arcsin(E2lam(energy) / 4 / np.pi * Q)
|
||||
|
||||
|
||||
def absorptionEdge(element,edge=None):
|
||||
def absorptionEdge(element, edge=None):
|
||||
if type(element) is str:
|
||||
element = xl.SymbolToAtomicNumber(element)
|
||||
shells = ['K','L1','L2','L3','M1','M2','M3','M4','M5']
|
||||
shells = ["K", "L1", "L2", "L3", "M1", "M2", "M3", "M4", "M5"]
|
||||
if edge is not None:
|
||||
shell_ind = shells.index(edge)
|
||||
return xl.EdgeEnergy(element,shell_ind)
|
||||
return xl.EdgeEnergy(element, shell_ind)
|
||||
else:
|
||||
shell_inds = range(8)
|
||||
print('Absorption edges %s'%xl.AtomicNumberToSymbol(element))
|
||||
print("Absorption edges %s" % xl.AtomicNumberToSymbol(element))
|
||||
for shell_ind in shell_inds:
|
||||
print(' '\
|
||||
+shells[shell_ind].ljust(3)\
|
||||
+' = %7.1f eV'%(xl.EdgeEnergy(element,shell_ind)*1000))
|
||||
print(
|
||||
" "
|
||||
+ shells[shell_ind].ljust(3)
|
||||
+ " = %7.1f eV" % (xl.EdgeEnergy(element, shell_ind) * 1000)
|
||||
)
|
||||
@@ -2,53 +2,62 @@ from ..devices_general.motors import MotorRecord
|
||||
from ..eco_epics.utilities_epics import EnumWrapper
|
||||
from ..devices_general.detectors import FeDigitizer
|
||||
|
||||
|
||||
class GasDetector:
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
class SolidTargetDetectorPBPS:
|
||||
def __init__(self,Id,VME_crate=None,link=None,
|
||||
ch_up=12,ch_down=13,ch_left=15,ch_right=14,
|
||||
elog=None):
|
||||
def __init__(
|
||||
self,
|
||||
Id,
|
||||
VME_crate=None,
|
||||
link=None,
|
||||
ch_up=12,
|
||||
ch_down=13,
|
||||
ch_left=15,
|
||||
ch_right=14,
|
||||
elog=None,
|
||||
):
|
||||
self.Id = Id
|
||||
self.x_diode = MotorRecord(Id+':MOTOR_X1',elog=elog)
|
||||
self.y_diode = MotorRecord(Id+':MOTOR_Y1',elog=elog)
|
||||
self.y_target = MotorRecord(Id+':MOTOR_PROBE',elog=elog)
|
||||
self.target = EnumWrapper(Id+':PROBE_SP',elog=elog)
|
||||
self.x_diode = MotorRecord(Id + ":MOTOR_X1", elog=elog)
|
||||
self.y_diode = MotorRecord(Id + ":MOTOR_Y1", elog=elog)
|
||||
self.y_target = MotorRecord(Id + ":MOTOR_PROBE", elog=elog)
|
||||
self.target = EnumWrapper(Id + ":PROBE_SP", elog=elog)
|
||||
if VME_crate:
|
||||
self.diode_up = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_up))
|
||||
self.diode_down = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_down))
|
||||
self.diode_left = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_left))
|
||||
self.diode_right = FeDigitizer('%s:Lnk%dCh%d'%(VME_crate,link,ch_right))
|
||||
self.diode_up = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_up))
|
||||
self.diode_down = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_down))
|
||||
self.diode_left = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_left))
|
||||
self.diode_right = FeDigitizer("%s:Lnk%dCh%d" % (VME_crate, link, ch_right))
|
||||
|
||||
def __repr__(self):
|
||||
s = "**Intensity monitor**\n\n"
|
||||
|
||||
s+= "Target: " + (self.target.get_name()) + "\n\n"
|
||||
s += "Target: " + (self.target.get_name()) + "\n\n"
|
||||
|
||||
s+= "**Bias voltage**\n"
|
||||
s+= " - Diode up: %.4f\n" %(self.diode_up.get_bias())
|
||||
s+= " - Diode down: %.4f\n" %(self.diode_down.get_bias())
|
||||
s+= " - Diode left: %.4f\n" %(self.diode_left.get_bias())
|
||||
s+= " - Diode right: %.4f\n" %(self.diode_right.get_bias())
|
||||
s+= "\n"
|
||||
s += "**Bias voltage**\n"
|
||||
s += " - Diode up: %.4f\n" % (self.diode_up.get_bias())
|
||||
s += " - Diode down: %.4f\n" % (self.diode_down.get_bias())
|
||||
s += " - Diode left: %.4f\n" % (self.diode_left.get_bias())
|
||||
s += " - Diode right: %.4f\n" % (self.diode_right.get_bias())
|
||||
s += "\n"
|
||||
|
||||
s+= "**Gain**\n"
|
||||
s+= " - Diode up: %i\n" %(self.diode_up.gain.get())
|
||||
s+= " - Diode down: %i\n" %(self.diode_down.gain.get())
|
||||
s+= " - Diode left: %i\n" %(self.diode_left.gain.get())
|
||||
s+= " - Diode right: %i\n" %(self.diode_right.gain.get())
|
||||
s += "**Gain**\n"
|
||||
s += " - Diode up: %i\n" % (self.diode_up.gain.get())
|
||||
s += " - Diode down: %i\n" % (self.diode_down.gain.get())
|
||||
s += " - Diode left: %i\n" % (self.diode_left.gain.get())
|
||||
s += " - Diode right: %i\n" % (self.diode_right.gain.get())
|
||||
return s
|
||||
|
||||
|
||||
def set_gains(self,value):
|
||||
def set_gains(self, value):
|
||||
try:
|
||||
self.diode_up.gain.set(value)
|
||||
self.diode_down.gain.set(value)
|
||||
self.diode_left.gain.set(value)
|
||||
self.diode_right.gain.set(value)
|
||||
except:
|
||||
print('No diodes configured, can not change any gain!')
|
||||
print("No diodes configured, can not change any gain!")
|
||||
|
||||
def get_available_gains(self):
|
||||
try:
|
||||
@@ -56,30 +65,31 @@ class SolidTargetDetectorPBPS:
|
||||
nd = self.diode_down.gain.names
|
||||
nl = self.diode_left.gain.names
|
||||
nr = self.diode_right.gain.names
|
||||
assert nu==nd==nl==nr , 'NB: the gain options of the four diodes are not equal!!!'
|
||||
assert (
|
||||
nu == nd == nl == nr
|
||||
), "NB: the gain options of the four diodes are not equal!!!"
|
||||
return nu
|
||||
except:
|
||||
print('No diodes configured, can not change any gain!')
|
||||
print("No diodes configured, can not change any gain!")
|
||||
|
||||
def get_gains(self):
|
||||
try:
|
||||
gains = dict()
|
||||
gains['up'] = (self.diode_up.gain.get_name(),self.diode_up.gain.get())
|
||||
gains['down'] = (self.diode_down.gain.get_name(),self.diode_down.gain.get())
|
||||
gains['left'] = (self.diode_left.gain.get_name(),self.diode_left.gain.get())
|
||||
gains['right'] = (self.diode_right.gain.get_name(),self.diode_right.gain.get())
|
||||
gains["up"] = (self.diode_up.gain.get_name(), self.diode_up.gain.get())
|
||||
gains["down"] = (
|
||||
self.diode_down.gain.get_name(),
|
||||
self.diode_down.gain.get(),
|
||||
)
|
||||
gains["left"] = (
|
||||
self.diode_left.gain.get_name(),
|
||||
self.diode_left.gain.get(),
|
||||
)
|
||||
gains["right"] = (
|
||||
self.diode_right.gain.get_name(),
|
||||
self.diode_right.gain.get(),
|
||||
)
|
||||
return gains
|
||||
except:
|
||||
print('No diodes configured, can not change any gain!')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#SAROP21-CVME-PBPS:Lnk10Ch15-WD-gain
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
print("No diodes configured, can not change any gain!")
|
||||
|
||||
# SAROP21-CVME-PBPS:Lnk10Ch15-WD-gain
|
||||
|
||||
+21
-22
@@ -3,46 +3,45 @@ from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
|
||||
class palm:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self.delay = MotorRecord(self.Id+'-M423:MOT')
|
||||
|
||||
self.delay = MotorRecord(self.Id + "-M423:MOT")
|
||||
self.delayTime = DelayStage(self.delay)
|
||||
|
||||
# self.delay2 = MotorRecord(self.Id+'-M422:MOT')
|
||||
# self.delayTime2 = DelayStage(self.delay)
|
||||
|
||||
# self.delay2 = MotorRecord(self.Id+'-M422:MOT')
|
||||
# self.delayTime2 = DelayStage(self.delay)
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '***** PALM motor positions ******\n'
|
||||
ostr = "***** PALM motor positions ******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
|
||||
class eo:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self.delay = MotorRecord(self.Id+'-M422:MOT')
|
||||
|
||||
self.delay = MotorRecord(self.Id + "-M422:MOT")
|
||||
self.delayTime = DelayStage(self.delay)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '***** PALM EO sampling motor positions ******\n'
|
||||
ostr = "***** PALM EO sampling motor positions ******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
@@ -1,38 +1,45 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from ..devices_general.detectors import CameraCA,CameraBS
|
||||
#from ..devices_general.epics_wrappers import EnumSelector
|
||||
from ..devices_general.detectors import CameraCA, CameraBS
|
||||
|
||||
# from ..devices_general.epics_wrappers import EnumSelector
|
||||
from epics import PV
|
||||
from ..eco_epics.utilities_epics import EnumWrapper
|
||||
|
||||
class Pprm:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
self.targetY = MotorRecord(Id+':MOTOR_PROBE')
|
||||
self.cam = CameraCA(Id)
|
||||
self._led = PV(self.Id+':LED')
|
||||
self.target = EnumWrapper(self.Id+':PROBE_SP')
|
||||
|
||||
def illuminate(self,value=None):
|
||||
class Pprm:
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
self.targetY = MotorRecord(Id + ":MOTOR_PROBE")
|
||||
self.cam = CameraCA(Id)
|
||||
self._led = PV(self.Id + ":LED")
|
||||
self.target = EnumWrapper(self.Id + ":PROBE_SP")
|
||||
|
||||
def movein(self,target=1):
|
||||
self.target.set(target)
|
||||
|
||||
def moveout(self,target=0):
|
||||
self.target.set(target)
|
||||
|
||||
def illuminate(self, value=None):
|
||||
if value:
|
||||
self._led.put(value)
|
||||
else:
|
||||
self._led.put(
|
||||
not self.get_illumination_state())
|
||||
self._led.put(not self.get_illumination_state())
|
||||
|
||||
def get_illumination_state(self):
|
||||
return bool(self._led.get())
|
||||
|
||||
def __repr__(self):
|
||||
s = "**Profile Monitor**\n"
|
||||
s+= "Target: %s" %(self.target.get_name())
|
||||
s += "Target: %s" % (self.target.get_name())
|
||||
return s
|
||||
|
||||
|
||||
class Bernina_XEYE:
|
||||
def __init__(self,Id,bshost=None,bsport=None):
|
||||
def __init__(self, Id, bshost=None, bsport=None):
|
||||
self.Id = Id
|
||||
try:
|
||||
self.zoom = MotorRecord('SARES20-EXP:MOT_ZOOM.VAL')
|
||||
self.zoom = MotorRecord("SARES20-EXP:MOT_ZOOM.VAL")
|
||||
except:
|
||||
print("X-Ray eye zoom motor not found")
|
||||
pass
|
||||
@@ -43,10 +50,11 @@ class Bernina_XEYE:
|
||||
pass
|
||||
|
||||
if bshost:
|
||||
self.camBS = CameraBS(host=bshost,port=bsport)
|
||||
# self._led = PV(self.Id+':LED')
|
||||
self.camBS = CameraBS(host=bshost, port=bsport)
|
||||
|
||||
|
||||
# self._led = PV(self.Id+':LED')
|
||||
|
||||
|
||||
# def illuminate(self,value=None):
|
||||
# if value:
|
||||
@@ -58,11 +66,3 @@ class Bernina_XEYE:
|
||||
# def get_illumination_state(self):
|
||||
# return bool(self._led.get())
|
||||
#
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -3,24 +3,22 @@ from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
|
||||
class psen:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self.delay = MotorRecord(self.Id+'-M424:MOT')
|
||||
|
||||
self.delay = MotorRecord(self.Id + "-M424:MOT")
|
||||
self.delayTime = DelayStage(self.delay)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****PSEN motor positions******\n'
|
||||
ostr = "*****PSEN motor positions******\n"
|
||||
|
||||
for tkey,item in self.__dict__.items():
|
||||
if hasattr(item,'get_current_value'):
|
||||
for tkey, item in self.__dict__.items():
|
||||
if hasattr(item, "get_current_value"):
|
||||
pos = item.get_current_value()
|
||||
ostr += ' ' + tkey.ljust(10) + ' : % 14g\n'%pos
|
||||
ostr += " " + tkey.ljust(10) + " : % 14g\n" % pos
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
|
||||
+18
-19
@@ -1,39 +1,38 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class KBhor:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self.x = MotorRecord(Id+':W_X')
|
||||
self.y = MotorRecord(Id+':W_Y')
|
||||
self.pitch = MotorRecord(Id+':W_RY')
|
||||
self.roll = MotorRecord(Id+':W_RZ')
|
||||
self.yaw = MotorRecord(Id+':W_RX')
|
||||
self.bend1 = MotorRecord(Id+':BU')
|
||||
self.bend2 = MotorRecord(Id+':BD')
|
||||
|
||||
self.mode = PV(Id[:11]+':MODE').enum_strs[PV(Id[:11]+':MODE').value]
|
||||
self.x = MotorRecord(Id + ":W_X")
|
||||
self.y = MotorRecord(Id + ":W_Y")
|
||||
self.pitch = MotorRecord(Id + ":W_RY")
|
||||
self.roll = MotorRecord(Id + ":W_RZ")
|
||||
self.yaw = MotorRecord(Id + ":W_RX")
|
||||
self.bend1 = MotorRecord(Id + ":BU")
|
||||
self.bend2 = MotorRecord(Id + ":BD")
|
||||
|
||||
self.mode = PV(Id[:11] + ":MODE").enum_strs[PV(Id[:11] + ":MODE").value]
|
||||
|
||||
#### actual motors ###
|
||||
self._Y1 = MotorRecord(Id+':TY1')
|
||||
self._Y2 = MotorRecord(Id+':TY2')
|
||||
self._Y3 = MotorRecord(Id+':TY3')
|
||||
self._X1 = MotorRecord(Id+':TX1')
|
||||
self._X2 = MotorRecord(Id+':TX2')
|
||||
|
||||
self._Y1 = MotorRecord(Id + ":TY1")
|
||||
self._Y2 = MotorRecord(Id + ":TY2")
|
||||
self._Y3 = MotorRecord(Id + ":TY3")
|
||||
self._X1 = MotorRecord(Id + ":TX1")
|
||||
self._X2 = MotorRecord(Id + ":TX2")
|
||||
|
||||
def __str__(self):
|
||||
s = "**Horizontal KB mirror**\n"
|
||||
motors = "bend1 bend2 pitch roll yaw x y".split()
|
||||
for motor in motors:
|
||||
s+= " - %s = %.4f\n" %(motor, getattr(self,motor).wm())
|
||||
s += " - %s = %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
s += "\n**Stages**\n"
|
||||
stages = "_Y1 _Y2 _Y3 _X1 _X2".split()
|
||||
for stage in stages:
|
||||
s+= " - %s = %.4f\n" %(stage, getattr(self,stage).wm())
|
||||
s += " - %s = %.4f\n" % (stage, getattr(self, stage).wm())
|
||||
return s
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
+18
-17
@@ -1,37 +1,38 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class KBver:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self.x = MotorRecord(Id+':W_X')
|
||||
self.y = MotorRecord(Id+':W_Y')
|
||||
self.pitch = MotorRecord(Id+':W_RX')
|
||||
self.roll = MotorRecord(Id+':W_RZ')
|
||||
self.yaw = MotorRecord(Id+':W_RY')
|
||||
self.bend1 = MotorRecord(Id+':BU')
|
||||
self.bend2 = MotorRecord(Id+':BD')
|
||||
self.x = MotorRecord(Id + ":W_X")
|
||||
self.y = MotorRecord(Id + ":W_Y")
|
||||
self.pitch = MotorRecord(Id + ":W_RX")
|
||||
self.roll = MotorRecord(Id + ":W_RZ")
|
||||
self.yaw = MotorRecord(Id + ":W_RY")
|
||||
self.bend1 = MotorRecord(Id + ":BU")
|
||||
self.bend2 = MotorRecord(Id + ":BD")
|
||||
|
||||
self.mode = PV(Id[:11]+':MODE').enum_strs[PV(Id[:11]+':MODE').value]
|
||||
self.mode = PV(Id[:11] + ":MODE").enum_strs[PV(Id[:11] + ":MODE").value]
|
||||
|
||||
#### actual motors ###
|
||||
self._Y1 = MotorRecord(Id+':TY1')
|
||||
self._Y2 = MotorRecord(Id+':TY2')
|
||||
self._Y3 = MotorRecord(Id+':TY3')
|
||||
self._X1 = MotorRecord(Id+':TX1')
|
||||
self._X2 = MotorRecord(Id+':TX2')
|
||||
self._Y1 = MotorRecord(Id + ":TY1")
|
||||
self._Y2 = MotorRecord(Id + ":TY2")
|
||||
self._Y3 = MotorRecord(Id + ":TY3")
|
||||
self._X1 = MotorRecord(Id + ":TX1")
|
||||
self._X2 = MotorRecord(Id + ":TX2")
|
||||
|
||||
def __str__(self):
|
||||
s = "**Vertical KB mirror**\n"
|
||||
motors = "bend1 bend2 pitch roll yaw x y".split()
|
||||
for motor in motors:
|
||||
s+= " - %s = %.4f\n" %(motor, getattr(self,motor).wm())
|
||||
s += " - %s = %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
s += "\n**Stages**\n"
|
||||
stages = "_Y1 _Y2 _Y3 _X1 _X2".split()
|
||||
for stage in stages:
|
||||
s+= " - %s = %.4f\n" %(stage, getattr(self,stage).wm())
|
||||
s += " - %s = %.4f\n" % (stage, getattr(self, stage).wm())
|
||||
return s
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
@@ -1,48 +1,51 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class AttenuatorAramis:
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
self._pv_status_str = PV(self.Id+':MOT2TRANS.VALD')
|
||||
self._pv_status_int = PV(self.Id+':IDX_RB')
|
||||
self._pv_status_str = PV(self.Id + ":MOT2TRANS.VALD")
|
||||
self._pv_status_int = PV(self.Id + ":IDX_RB")
|
||||
pass
|
||||
|
||||
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
def __str__(self):
|
||||
pass
|
||||
|
||||
def __status__(self):
|
||||
pass
|
||||
def updateE(self,energy = None):
|
||||
|
||||
def updateE(self, energy=None):
|
||||
if energy == None:
|
||||
energy = PV("SARUN03-UIND030:FELPHOTENE").value
|
||||
energy = energy *1000
|
||||
PV(self.Id+":ENERGY").put(energy)
|
||||
print("Set energy to %s eV"%energy)
|
||||
energy = energy * 1000
|
||||
PV(self.Id + ":ENERGY").put(energy)
|
||||
print("Set energy to %s eV" % energy)
|
||||
return
|
||||
|
||||
def set_transmission(self,value,energy=None):
|
||||
def set_transmission(self, value, energy=None):
|
||||
self.updateE(energy)
|
||||
PV(self.Id+":3RD_HARM_SP").put(0)
|
||||
PV(self.Id+":TRANS_SP").put(value)
|
||||
PV(self.Id + ":3RD_HARM_SP").put(0)
|
||||
PV(self.Id + ":TRANS_SP").put(value)
|
||||
pass
|
||||
|
||||
def set_transmission_third_harmonic(self,value,energy=None):
|
||||
def set_transmission_third_harmonic(self, value, energy=None):
|
||||
self.updateE(energy)
|
||||
PV(self.Id+":3RD_HARM_SP").put(1)
|
||||
PV(self.Id+":TRANS_SP").put(value)
|
||||
PV(self.Id + ":3RD_HARM_SP").put(1)
|
||||
PV(self.Id + ":TRANS_SP").put(value)
|
||||
pass
|
||||
|
||||
def setE(self):
|
||||
pass
|
||||
|
||||
def get_transmission(self):
|
||||
tFun = PV(self.Id+":TRANS_RB").value
|
||||
tTHG = PV(self.Id+":TRANS3EDHARM_RB").value
|
||||
print("Transmission Fundamental: %s THG: %s"%(tFun, tTHG))
|
||||
return tFun,tTHG
|
||||
tFun = PV(self.Id + ":TRANS_RB").value
|
||||
tTHG = PV(self.Id + ":TRANS3EDHARM_RB").value
|
||||
print("Transmission Fundamental: %s THG: %s" % (tFun, tTHG))
|
||||
return tFun, tTHG
|
||||
|
||||
def get_status(self):
|
||||
s_str = self._pv_status_str.get(as_string=True)
|
||||
@@ -51,17 +54,11 @@ class AttenuatorAramis:
|
||||
|
||||
def __repr__(self):
|
||||
t = self.get_transmission()
|
||||
s = '1st harm. transmission = %g\n'%t[0]
|
||||
s += '3rd harm. transmission = %g\n'%t[1]
|
||||
s += 'Targets in beam:\n'
|
||||
s += '%s'%self.get_status()[0]
|
||||
s = "1st harm. transmission = %g\n" % t[0]
|
||||
s += "3rd harm. transmission = %g\n" % t[1]
|
||||
s += "Targets in beam:\n"
|
||||
s += "%s" % self.get_status()[0]
|
||||
return s
|
||||
|
||||
def __call__(self,*args,**kwargs):
|
||||
self.set_transmission(*args,**kwargs)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
self.set_transmission(*args, **kwargs)
|
||||
|
||||
+165
-154
@@ -4,89 +4,96 @@ from ..devices_general.utilities import Changer
|
||||
from time import sleep
|
||||
import numpy as np
|
||||
|
||||
class Double_Crystal_Mono:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
self.theta = MotorRecord(Id+':RX12')
|
||||
self.x = MotorRecord(Id+':TX12')
|
||||
self.gap = MotorRecord(Id+':T2')
|
||||
self.roll1 = MotorRecord(Id+':RZ1')
|
||||
self.roll2 = MotorRecord(Id+':RZ2')
|
||||
self.pitch2 = MotorRecord(Id+':RX2')
|
||||
|
||||
self.energy_rbk = PV(Id+':ENERGY')
|
||||
self.energy_sp = PV(Id+':ENERGY_SP')
|
||||
self.moving = PV(Id+':MOVING')
|
||||
self._stop = PV(Id +':STOP.PROC')
|
||||
|
||||
def move_and_wait(self,value,checktime=.01,precision=.5):
|
||||
class Double_Crystal_Mono:
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
self.theta = MotorRecord(Id + ":RX12")
|
||||
self.x = MotorRecord(Id + ":TX12")
|
||||
self.gap = MotorRecord(Id + ":T2")
|
||||
self.roll1 = MotorRecord(Id + ":RZ1")
|
||||
self.roll2 = MotorRecord(Id + ":RZ2")
|
||||
self.pitch2 = MotorRecord(Id + ":RX2")
|
||||
|
||||
self.energy_rbk = PV(Id + ":ENERGY")
|
||||
self.energy_sp = PV(Id + ":ENERGY_SP")
|
||||
self.moving = PV(Id + ":MOVING")
|
||||
self._stop = PV(Id + ":STOP.PROC")
|
||||
|
||||
def move_and_wait(self, value, checktime=0.01, precision=0.5):
|
||||
self.energy_sp.put(value)
|
||||
while abs(self.wait_for_valid_value()-value)>precision:
|
||||
while abs(self.wait_for_valid_value() - value) > precision:
|
||||
sleep(checktime)
|
||||
|
||||
def changeTo(self,value,hold=False):
|
||||
def changeTo(self, value, hold=False):
|
||||
changer = lambda value: self.move_and_wait(value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=self.stop)
|
||||
|
||||
target=value, parent=self, changer=changer, hold=hold, stopper=self.stop
|
||||
)
|
||||
|
||||
def stop(self):
|
||||
self._stop.put(1)
|
||||
self._stop.put(1)
|
||||
|
||||
def get_current_value(self):
|
||||
currentenergy = self.energy_rbk.get()
|
||||
return currentenergy
|
||||
currentenergy = self.energy_rbk.get()
|
||||
return currentenergy
|
||||
|
||||
def wait_for_valid_value(self):
|
||||
tval = np.nan
|
||||
while not np.isfinite(tval):
|
||||
tval = self.energy_rbk.get()
|
||||
return(tval)
|
||||
|
||||
def set_current_value(self,value):
|
||||
self.energy_sp.put(value)
|
||||
|
||||
def get_moveDone(self):
|
||||
inmotion = int(self.moving.get())
|
||||
return inmotion
|
||||
|
||||
# spec-inspired convenience methods
|
||||
def mv(self,value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
def wm(self,*args,**kwargs):
|
||||
return self.get_current_value(*args,**kwargs)
|
||||
def mvr(self,value,*args,**kwargs):
|
||||
return tval
|
||||
|
||||
if(self.get_moveDone == 1):
|
||||
startvalue = self.get_current_value(*args,**kwargs)
|
||||
def set_current_value(self, value):
|
||||
self.energy_sp.put(value)
|
||||
|
||||
def get_moveDone(self):
|
||||
inmotion = int(self.moving.get())
|
||||
return inmotion
|
||||
|
||||
# spec-inspired convenience methods
|
||||
def mv(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
def wm(self, *args, **kwargs):
|
||||
return self.get_current_value(*args, **kwargs)
|
||||
|
||||
def mvr(self, value, *args, **kwargs):
|
||||
|
||||
if self.get_moveDone == 1:
|
||||
startvalue = self.get_current_value(*args, **kwargs)
|
||||
else:
|
||||
startvalue = self.get_current_value(*args,**kwargs)
|
||||
self._currentChange = self.changeTo(value+startvalue,*args,**kwargs)
|
||||
startvalue = self.get_current_value(*args, **kwargs)
|
||||
self._currentChange = self.changeTo(value + startvalue, *args, **kwargs)
|
||||
|
||||
def wait(self):
|
||||
self._currentChange.wait()
|
||||
|
||||
|
||||
def __str__(self):
|
||||
s = "**Double crystal monochromator**\n\n"
|
||||
motors = "theta gap x roll1 roll2 pitch2".split()
|
||||
for motor in motors:
|
||||
s+= " - %s = %.4f\n" %(motor, getattr(self,motor).wm())
|
||||
s += " - %s = %.4f\n" % (motor, getattr(self, motor).wm())
|
||||
pvs = "energy_rbk".split()
|
||||
for pv in pvs:
|
||||
s+= " - %s = %.4f\n" %(pv, getattr(self,pv).value)
|
||||
s += " - %s = %.4f\n" % (pv, getattr(self, pv).value)
|
||||
return s
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __call__(self,value):
|
||||
def __call__(self, value):
|
||||
self._currentChange = self.changeTo(value)
|
||||
|
||||
|
||||
class EcolEnergy:
|
||||
def __init__(self,Id, val='SARCL02-MBND100:P-SET',rb='SARCL02-MBND100:P-READ' ,dmov='SFB_BEAM_ENERGY_ECOL:SUM-ERROR-OK'):
|
||||
def __init__(
|
||||
self,
|
||||
Id,
|
||||
val="SARCL02-MBND100:P-SET",
|
||||
rb="SARCL02-MBND100:P-READ",
|
||||
dmov="SFB_BEAM_ENERGY_ECOL:SUM-ERROR-OK",
|
||||
):
|
||||
self.Id = Id
|
||||
self.setter = PV(val)
|
||||
self.readback = PV(rb)
|
||||
@@ -96,143 +103,147 @@ class EcolEnergy:
|
||||
def get_current_value(self):
|
||||
return self.readback.get()
|
||||
|
||||
def move_and_wait(self,value,checktime=.01,precision=2):
|
||||
def move_and_wait(self, value, checktime=0.01, precision=2):
|
||||
curr = self.setter.get()
|
||||
while abs(curr-value)>0.1:
|
||||
while abs(curr - value) > 0.1:
|
||||
curr = self.setter.get()
|
||||
self.setter.put(curr + np.sign(value-curr)*.1)
|
||||
self.setter.put(curr + np.sign(value - curr) * 0.1)
|
||||
sleep(0.3)
|
||||
|
||||
self.setter.put(value)
|
||||
while abs(self.get_current_value() - value)>precision:
|
||||
while abs(self.get_current_value() - value) > precision:
|
||||
sleep(checktime)
|
||||
while not self.dmov.get():
|
||||
#print(self.dmov.get())
|
||||
# print(self.dmov.get())
|
||||
sleep(checktime)
|
||||
|
||||
def changeTo(self,value,hold=False):
|
||||
|
||||
def changeTo(self, value, hold=False):
|
||||
changer = lambda value: self.move_and_wait(value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=None)
|
||||
target=value, parent=self, changer=changer, hold=hold, stopper=None
|
||||
)
|
||||
|
||||
|
||||
class MonoEcolEnergy:
|
||||
def __init__(self,Id):
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
self.name = 'energy_collimator'
|
||||
self.name = "energy_collimator"
|
||||
self.dcm = Double_Crystal_Mono(Id)
|
||||
self.ecol = EcolEnergy('ecol_dummy')
|
||||
self.ecol = EcolEnergy("ecol_dummy")
|
||||
self.offset = None
|
||||
self.MeVperEV = 0.78333
|
||||
|
||||
|
||||
def get_current_value(self):
|
||||
return self.dcm.get_current_value()
|
||||
|
||||
def move_and_wait(self,value):
|
||||
ch = [self.dcm.changeTo(value),
|
||||
self.ecol.changeTo(self.calcEcol(value))]
|
||||
def move_and_wait(self, value):
|
||||
ch = [self.dcm.changeTo(value), self.ecol.changeTo(self.calcEcol(value))]
|
||||
for tc in ch:
|
||||
tc.wait()
|
||||
|
||||
def changeTo(self,value,hold=False):
|
||||
def changeTo(self, value, hold=False):
|
||||
changer = lambda value: self.move_and_wait(value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=self.dcm.stop)
|
||||
target=value, parent=self, changer=changer, hold=hold, stopper=self.dcm.stop
|
||||
)
|
||||
|
||||
def alignOffsets(self):
|
||||
mrb = self.dcm.get_current_value()
|
||||
erb = self.ecol.get_current_value()
|
||||
self.offset = {'dcm':mrb, 'ecol':erb}
|
||||
self.offset = {"dcm": mrb, "ecol": erb}
|
||||
|
||||
def calcEcol(self,eV):
|
||||
return (eV-self.offset['dcm'])*self.MeVperEV + self.offset['ecol']
|
||||
def calcEcol(self, eV):
|
||||
return (eV - self.offset["dcm"]) * self.MeVperEV + self.offset["ecol"]
|
||||
|
||||
|
||||
class AlvraDCM_FEL:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
self.name = 'Alvra DCM monochromator coupled to FEL beam'
|
||||
# self.IOCstatus = PV('ALVRA:running') # bool 0 running, 1 not running
|
||||
self._FELcoupling = PV('SGE-OP2E-ARAMIS:MODE_SP') # string "Off" or "e-beam"
|
||||
self._setEnergy = PV('SAROP11-ARAMIS:ENERGY_SP_USER') # float eV
|
||||
self._getEnergy = PV('SAROP11-ARAMIS:ENERGY') # float eV
|
||||
self.ebeamEnergy = PV('SARCL02-MBND100:P-READ') # float MeV/c
|
||||
# self.ebeamEnergySP = PV('ALVRA:Energy_SP') # float MeV
|
||||
self.dcmStop = PV('SAROP11-ODCM105:STOP.PROC') # stop the DCM motors
|
||||
self.dcmMoving = PV('SAROP11-ODCM105:MOVING') # DCM moving field
|
||||
self._energyChanging = PV('SGE-OP2E-ARAMIS:MOVING') # PV telling you something related to the energy is changing
|
||||
self._alvraMode = PV('SAROP11-ARAMIS:MODE') # string Aramis SAROP11 mode
|
||||
self.ebeamOK = PV('SFB_BEAM_ENERGY_ECOL:SUM-ERROR-OK') # is ebeam no longer changing
|
||||
self.photCalib1 = PV('SGE-OP2E-ARAMIS:PH2E_X1') # photon energy calibration low calibration point
|
||||
self.photCalib2 = PV('SGE-OP2E-ARAMIS:PH2E_X2') # photon energy calibration high calibration point
|
||||
self.ebeamCalib1 = PV('SGE-OP2E-ARAMIS:PH2E_Y1') # electron energy calibration low calibration point
|
||||
self.ebeamCalib2 = PV('SGE-OP2E-ARAMIS:PH2E_Y2') # electron energy calibration high calibration point
|
||||
|
||||
def __str__(self):
|
||||
# ioc = self.IOCstatus.get()
|
||||
# if ioc == 0:
|
||||
# iocStr = "Soft IOC running"
|
||||
# else:
|
||||
# iocStr = "Soft IOC not running"
|
||||
FELcouplingStr = self._FELcoupling.get(as_string=True)
|
||||
alvraModeStr = self._alvraMode.get(as_string=True)
|
||||
currEnergy = self._getEnergy.get()
|
||||
currebeamEnergy = self.ebeamEnergy.get()
|
||||
photCalib1Str = self.photCalib1.get()
|
||||
photCalib2Str = self.photCalib2.get()
|
||||
ebeamCalib1Str = self.ebeamCalib1.get()
|
||||
ebeamCalib2Str = self.ebeamCalib2.get()
|
||||
|
||||
s = '**Alvra DCM-FEL status**\n\n'
|
||||
# print('%s'%iocStr)
|
||||
# print('FEL coupling %s'%FELcouplingStr)
|
||||
# print('Alvra beamline mode %s'%alvraModeStr)
|
||||
# print('Photon energy (eV) %'%currEnergy)
|
||||
# s += '%s\n'%iocStr
|
||||
s += 'FEL coupling: %s\n'%FELcouplingStr
|
||||
s += 'Alvra beamline mode: %s\n'%alvraModeStr
|
||||
s += 'Photon energy: %.2f eV\n'%currEnergy
|
||||
s += 'Electron energy: %.2f MeV\n'%currebeamEnergy
|
||||
s += 'Calibration set points:\n'
|
||||
s += 'Low: Photon %.2f keV, Electron %.2f MeV\n'%(photCalib1Str, ebeamCalib1Str)
|
||||
s += 'High: Photon %.2f keV, Electron %.2f MeV\n'%(photCalib2Str, ebeamCalib2Str)
|
||||
return s
|
||||
|
||||
def get_current_value(self):
|
||||
return self._getEnergy.get()
|
||||
|
||||
def move_and_wait(self,value,checktime=.1,precision=0.5):
|
||||
self._FELcoupling.put(1) # ensure the FEL coupling is turned on
|
||||
self._setEnergy.put(value)
|
||||
# while self.ebeamOK.get()==0:
|
||||
# sleep(checktime)
|
||||
# while abs(self.ebeamEnergy.get()-self.ebeamEnergySP.get())>precision:
|
||||
# sleep(checktime)
|
||||
# while self.dcmMoving.get()==1:
|
||||
# sleep(checktime)
|
||||
while self._energyChanging == 1:
|
||||
sleep(checktime)
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
self.name = "Alvra DCM monochromator coupled to FEL beam"
|
||||
# self.IOCstatus = PV('ALVRA:running') # bool 0 running, 1 not running
|
||||
self._FELcoupling = PV("SGE-OP2E-ARAMIS:MODE_SP") # string "Off" or "e-beam"
|
||||
self._setEnergy = PV("SAROP11-ARAMIS:ENERGY_SP_USER") # float eV
|
||||
self._getEnergy = PV("SAROP11-ARAMIS:ENERGY") # float eV
|
||||
self.ebeamEnergy = PV("SARCL02-MBND100:P-READ") # float MeV/c
|
||||
# self.ebeamEnergySP = PV('ALVRA:Energy_SP') # float MeV
|
||||
self.dcmStop = PV("SAROP11-ODCM105:STOP.PROC") # stop the DCM motors
|
||||
self.dcmMoving = PV("SAROP11-ODCM105:MOVING") # DCM moving field
|
||||
self._energyChanging = PV(
|
||||
"SGE-OP2E-ARAMIS:MOVING"
|
||||
) # PV telling you something related to the energy is changing
|
||||
self._alvraMode = PV("SAROP11-ARAMIS:MODE") # string Aramis SAROP11 mode
|
||||
self.ebeamOK = PV(
|
||||
"SFB_BEAM_ENERGY_ECOL:SUM-ERROR-OK"
|
||||
) # is ebeam no longer changing
|
||||
self.photCalib1 = PV(
|
||||
"SGE-OP2E-ARAMIS:PH2E_X1"
|
||||
) # photon energy calibration low calibration point
|
||||
self.photCalib2 = PV(
|
||||
"SGE-OP2E-ARAMIS:PH2E_X2"
|
||||
) # photon energy calibration high calibration point
|
||||
self.ebeamCalib1 = PV(
|
||||
"SGE-OP2E-ARAMIS:PH2E_Y1"
|
||||
) # electron energy calibration low calibration point
|
||||
self.ebeamCalib2 = PV(
|
||||
"SGE-OP2E-ARAMIS:PH2E_Y2"
|
||||
) # electron energy calibration high calibration point
|
||||
|
||||
def changeTo(self,value,hold=False):
|
||||
changer = lambda value: self.move_and_wait(value)
|
||||
return Changer(
|
||||
target=value,
|
||||
parent=self,
|
||||
changer=changer,
|
||||
hold=hold,
|
||||
stopper=None)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
def __str__(self):
|
||||
# ioc = self.IOCstatus.get()
|
||||
# if ioc == 0:
|
||||
# iocStr = "Soft IOC running"
|
||||
# else:
|
||||
# iocStr = "Soft IOC not running"
|
||||
FELcouplingStr = self._FELcoupling.get(as_string=True)
|
||||
alvraModeStr = self._alvraMode.get(as_string=True)
|
||||
currEnergy = self._getEnergy.get()
|
||||
currebeamEnergy = self.ebeamEnergy.get()
|
||||
photCalib1Str = self.photCalib1.get()
|
||||
photCalib2Str = self.photCalib2.get()
|
||||
ebeamCalib1Str = self.ebeamCalib1.get()
|
||||
ebeamCalib2Str = self.ebeamCalib2.get()
|
||||
|
||||
s = "**Alvra DCM-FEL status**\n\n"
|
||||
# print('%s'%iocStr)
|
||||
# print('FEL coupling %s'%FELcouplingStr)
|
||||
# print('Alvra beamline mode %s'%alvraModeStr)
|
||||
# print('Photon energy (eV) %'%currEnergy)
|
||||
# s += '%s\n'%iocStr
|
||||
s += "FEL coupling: %s\n" % FELcouplingStr
|
||||
s += "Alvra beamline mode: %s\n" % alvraModeStr
|
||||
s += "Photon energy: %.2f eV\n" % currEnergy
|
||||
s += "Electron energy: %.2f MeV\n" % currebeamEnergy
|
||||
s += "Calibration set points:\n"
|
||||
s += "Low: Photon %.2f keV, Electron %.2f MeV\n" % (
|
||||
photCalib1Str,
|
||||
ebeamCalib1Str,
|
||||
)
|
||||
s += "High: Photon %.2f keV, Electron %.2f MeV\n" % (
|
||||
photCalib2Str,
|
||||
ebeamCalib2Str,
|
||||
)
|
||||
return s
|
||||
|
||||
def get_current_value(self):
|
||||
return self._getEnergy.get()
|
||||
|
||||
def move_and_wait(self, value, checktime=0.1, precision=0.5):
|
||||
self._FELcoupling.put(1) # ensure the FEL coupling is turned on
|
||||
self._setEnergy.put(value)
|
||||
# while self.ebeamOK.get()==0:
|
||||
# sleep(checktime)
|
||||
# while abs(self.ebeamEnergy.get()-self.ebeamEnergySP.get())>precision:
|
||||
# sleep(checktime)
|
||||
# while self.dcmMoving.get()==1:
|
||||
# sleep(checktime)
|
||||
while self._energyChanging == 1:
|
||||
sleep(checktime)
|
||||
|
||||
def changeTo(self, value, hold=False):
|
||||
changer = lambda value: self.move_and_wait(value)
|
||||
return Changer(
|
||||
target=value, parent=self, changer=changer, hold=hold, stopper=None
|
||||
)
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
@@ -1,14 +1,12 @@
|
||||
class OffsetMirror:
|
||||
def __init__(self,Id,deflection='up',elog=None):
|
||||
def __init__(self, Id, deflection="up", elog=None):
|
||||
self.elog = elog
|
||||
self.deflection = deflection
|
||||
if deflection is 'up':
|
||||
self.x
|
||||
if deflection is "up":
|
||||
self.x
|
||||
|
||||
def out(self):
|
||||
pass
|
||||
|
||||
def move_in(self):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
+17
-15
@@ -3,15 +3,15 @@ from ..devices_general.utilities import Changer
|
||||
from time import sleep
|
||||
import numpy as np
|
||||
|
||||
class Pulse_Picker:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
self._start = PV(Id+':seq0Ctrl-Start-I')
|
||||
self._stop = PV(Id+':seq0Ctrl-Stop-I')
|
||||
self._cycles = PV(Id+':seq0Ctrl-Cycles-I')
|
||||
|
||||
|
||||
class Pulse_Picker:
|
||||
def __init__(self, Id):
|
||||
self.Id = Id
|
||||
|
||||
self._start = PV(Id + ":seq0Ctrl-Start-I")
|
||||
self._stop = PV(Id + ":seq0Ctrl-Stop-I")
|
||||
self._cycles = PV(Id + ":seq0Ctrl-Cycles-I")
|
||||
|
||||
def stop(self):
|
||||
self._stop.put(0)
|
||||
print("Stopped Pulse Picker")
|
||||
@@ -23,26 +23,28 @@ class Pulse_Picker:
|
||||
def cycles(self, n):
|
||||
self._cycles.put(n)
|
||||
|
||||
def scan(self, adj, targetlist, sleeptime = 0.1):
|
||||
def scan(self, adj, targetlist, sleeptime=0.1):
|
||||
self.stop()
|
||||
for target in targetlist:
|
||||
changer = adj.changeTo(target)
|
||||
changer.wait()
|
||||
print('Adjustable position {}'.format(adj.get_current_value()))
|
||||
print("Adjustable position {}".format(adj.get_current_value()))
|
||||
self.start()
|
||||
sleep(sleeptime)
|
||||
self.stop()
|
||||
print('done')
|
||||
print("done")
|
||||
|
||||
def scan2(self, adj1,adj2, targetlist1, targetlist2, sleeptime = 0.1):
|
||||
def scan2(self, adj1, adj2, targetlist1, targetlist2, sleeptime=0.1):
|
||||
self.stop()
|
||||
for n in range(len(targetlist1)):
|
||||
changer1 = adj1.changeTo(targetlist1[n])
|
||||
changer2 = adj2.changeTo(targetlist2[n])
|
||||
changer2.wait()
|
||||
print('Adjustable 1 position {}'.format(adj1.get_current_value()), 'Adjustable 2 position {}'.format(adj2.get_current_value()))
|
||||
print(
|
||||
"Adjustable 1 position {}".format(adj1.get_current_value()),
|
||||
"Adjustable 2 position {}".format(adj2.get_current_value()),
|
||||
)
|
||||
self.start()
|
||||
sleep(sleeptime)
|
||||
self.stop()
|
||||
print('done')
|
||||
|
||||
print("done")
|
||||
|
||||
+13
-14
@@ -1,6 +1,7 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
|
||||
class RefLaser_Aramis:
|
||||
def __init__(self, Id, elog=None, name=None, inpos=-18.818, outpos=-5):
|
||||
self.Id = Id
|
||||
@@ -8,44 +9,42 @@ class RefLaser_Aramis:
|
||||
self.name = name
|
||||
self._inpos = inpos
|
||||
self._outpos = outpos
|
||||
self.mirrmotor = MotorRecord(self.Id+':MOTOR_1')
|
||||
self.mirrmotor = MotorRecord(self.Id + ":MOTOR_1")
|
||||
|
||||
|
||||
def __call__(self,*args,**kwargs):
|
||||
self.set(*args,**kwargs)
|
||||
def __call__(self, *args, **kwargs):
|
||||
self.set(*args, **kwargs)
|
||||
|
||||
def __str__(self):
|
||||
status = self.get_status()
|
||||
if status:
|
||||
return "Reflaser is In."
|
||||
elif status==False:
|
||||
elif status == False:
|
||||
return "Reflaser is Out."
|
||||
elif status==None:
|
||||
return "Reflaser status not defined."
|
||||
elif status == None:
|
||||
return "Reflaser status not defined."
|
||||
|
||||
def get_status(self):
|
||||
v = self.mirrmotor.get_current_value()
|
||||
if abs(v - self._inpos) < .2:
|
||||
if abs(v - self._inpos) < 0.2:
|
||||
isin = True
|
||||
elif abs(v - self._outpos) < .2:
|
||||
elif abs(v - self._outpos) < 0.2:
|
||||
isin = False
|
||||
else:
|
||||
isin = None
|
||||
return isin
|
||||
|
||||
def set(self,value):
|
||||
def set(self, value):
|
||||
if type(value) is str:
|
||||
if value.lower()=='in':
|
||||
if value.lower() == "in":
|
||||
value = True
|
||||
elif value.lower()=='out':
|
||||
elif value.lower() == "out":
|
||||
value = False
|
||||
else:
|
||||
print('String %s not recognized!'%value)
|
||||
print("String %s not recognized!" % value)
|
||||
if value:
|
||||
self.mirrmotor.changeTo(self._inpos)
|
||||
else:
|
||||
self.mirrmotor.changeTo(self._outpos)
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
+104
-86
@@ -1,155 +1,173 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
|
||||
|
||||
class SlitBlades:
|
||||
def __init__(self,Id,name=None,elog=None):
|
||||
def __init__(self, Id, name=None, elog=None):
|
||||
self.Id = Id
|
||||
self.name = name
|
||||
self._x1 = MotorRecord(Id+':MOTOR_X1')
|
||||
self._x2 = MotorRecord(Id+':MOTOR_X2')
|
||||
self._y1 = MotorRecord(Id+':MOTOR_Y1')
|
||||
self._y2 = MotorRecord(Id+':MOTOR_Y2')
|
||||
self._x1 = MotorRecord(Id + ":MOTOR_X1")
|
||||
self._x2 = MotorRecord(Id + ":MOTOR_X2")
|
||||
self._y1 = MotorRecord(Id + ":MOTOR_Y1")
|
||||
self._y2 = MotorRecord(Id + ":MOTOR_Y2")
|
||||
|
||||
def get_hg(self):
|
||||
return self._x2.get_current_value()-self._x1.get_current_value()
|
||||
return self._x2.get_current_value() - self._x1.get_current_value()
|
||||
|
||||
def get_vg(self):
|
||||
return self._y2.get_current_value()-self._y1.get_current_value()
|
||||
return self._y2.get_current_value() - self._y1.get_current_value()
|
||||
|
||||
def get_ho(self):
|
||||
return (self._x1.get_current_value()+self._x2.get_current_value())/2
|
||||
return (self._x1.get_current_value() + self._x2.get_current_value()) / 2
|
||||
|
||||
def get_vo(self):
|
||||
return (self._y1.get_current_value()+self._y2.get_current_value())/2
|
||||
def set_hg(self,value):
|
||||
return (self._y1.get_current_value() + self._y2.get_current_value()) / 2
|
||||
|
||||
def set_hg(self, value):
|
||||
ho = self.get_ho()
|
||||
c1 = self._x1.changeTo(ho-value/2)
|
||||
c2 = self._x2.changeTo(ho+value/2)
|
||||
return c1,c2
|
||||
def set_vg(self,value):
|
||||
c1 = self._x1.changeTo(ho - value / 2)
|
||||
c2 = self._x2.changeTo(ho + value / 2)
|
||||
return c1, c2
|
||||
|
||||
def set_vg(self, value):
|
||||
vo = self.get_vo()
|
||||
c1 = self._y1.changeTo(vo-value/2)
|
||||
c2 = self._y2.changeTo(vo+value/2)
|
||||
return c1,c2
|
||||
c1 = self._y1.changeTo(vo - value / 2)
|
||||
c2 = self._y2.changeTo(vo + value / 2)
|
||||
return c1, c2
|
||||
|
||||
def set_ho(self,value):
|
||||
def set_ho(self, value):
|
||||
hg = self.get_hg()
|
||||
c1 = self._x1.changeTo(value-hg/2)
|
||||
c2 = self._x2.changeTo(value+hg/2)
|
||||
return c1,c2
|
||||
def set_vo(self,value):
|
||||
vg = self.get_vg()
|
||||
c1 = self._y1.changeTo(value-vg/2)
|
||||
c2 = self._y2.changeTo(value+vg/2)
|
||||
return c1,c2
|
||||
c1 = self._x1.changeTo(value - hg / 2)
|
||||
c2 = self._x2.changeTo(value + hg / 2)
|
||||
return c1, c2
|
||||
|
||||
def __call__(self,width,height):
|
||||
def set_vo(self, value):
|
||||
vg = self.get_vg()
|
||||
c1 = self._y1.changeTo(value - vg / 2)
|
||||
c2 = self._y2.changeTo(value + vg / 2)
|
||||
return c1, c2
|
||||
|
||||
def __call__(self, width, height):
|
||||
self.set_hg(width)
|
||||
self.set_vg(height)
|
||||
|
||||
def __repr__(self):
|
||||
string1 = 'gap: (%g,%g) mm'%(self.get_hg(),self.get_vg())
|
||||
string2 = 'pos: (%g,%g) mm'%(self.get_ho(),self.get_vo())
|
||||
return '\n'.join((string1,string2))
|
||||
string1 = "gap: (%g,%g) mm" % (self.get_hg(), self.get_vg())
|
||||
string2 = "pos: (%g,%g) mm" % (self.get_ho(), self.get_vo())
|
||||
return "\n".join((string1, string2))
|
||||
|
||||
|
||||
class SlitFourBlades:
|
||||
def __init__(self,Id,name=None,elog=None):
|
||||
def __init__(self, Id, name=None, elog=None):
|
||||
self.Id = Id
|
||||
self.name = name
|
||||
self._ax1 = MotorRecord(Id+':MOTOR_AX1')
|
||||
self._ax2 = MotorRecord(Id+':MOTOR_AX2')
|
||||
self._ay1 = MotorRecord(Id+':MOTOR_AY1')
|
||||
self._ay2 = MotorRecord(Id+':MOTOR_AY2')
|
||||
self._bx1 = MotorRecord(Id+':MOTOR_BX1')
|
||||
self._bx2 = MotorRecord(Id+':MOTOR_BX2')
|
||||
self._by1 = MotorRecord(Id+':MOTOR_BY1')
|
||||
self._by2 = MotorRecord(Id+':MOTOR_BY2')
|
||||
self._ax1 = MotorRecord(Id + ":MOTOR_AX1")
|
||||
self._ax2 = MotorRecord(Id + ":MOTOR_AX2")
|
||||
self._ay1 = MotorRecord(Id + ":MOTOR_AY1")
|
||||
self._ay2 = MotorRecord(Id + ":MOTOR_AY2")
|
||||
self._bx1 = MotorRecord(Id + ":MOTOR_BX1")
|
||||
self._bx2 = MotorRecord(Id + ":MOTOR_BX2")
|
||||
self._by1 = MotorRecord(Id + ":MOTOR_BY1")
|
||||
self._by2 = MotorRecord(Id + ":MOTOR_BY2")
|
||||
|
||||
def get_hg(self):
|
||||
return self._ax2.get_current_value()-self._ax1.get_current_value()
|
||||
return self._ax2.get_current_value() - self._ax1.get_current_value()
|
||||
|
||||
def get_vg(self):
|
||||
return self._ay2.get_current_value()-self._ay1.get_current_value()
|
||||
return self._ay2.get_current_value() - self._ay1.get_current_value()
|
||||
|
||||
def get_ho(self):
|
||||
return (self._ax1.get_current_value()+self._ax2.get_current_value())/2
|
||||
return (self._ax1.get_current_value() + self._ax2.get_current_value()) / 2
|
||||
|
||||
def get_vo(self):
|
||||
return (self._ay1.get_current_value()+self._ay2.get_current_value())/2
|
||||
def set_hg(self,value):
|
||||
return (self._ay1.get_current_value() + self._ay2.get_current_value()) / 2
|
||||
|
||||
def set_hg(self, value):
|
||||
ho = self.get_ho()
|
||||
c1 = self._ax1.changeTo(ho-value/2)
|
||||
c2 = self._ax2.changeTo(ho+value/2)
|
||||
c3 = self._bx1.changeTo(ho-value/2)
|
||||
c4 = self._bx2.changeTo(ho+value/2)
|
||||
return c1,c2,c3,c4
|
||||
def set_vg(self,value):
|
||||
c1 = self._ax1.changeTo(ho - value / 2)
|
||||
c2 = self._ax2.changeTo(ho + value / 2)
|
||||
c3 = self._bx1.changeTo(ho - value / 2)
|
||||
c4 = self._bx2.changeTo(ho + value / 2)
|
||||
return c1, c2, c3, c4
|
||||
|
||||
def set_vg(self, value):
|
||||
vo = self.get_vo()
|
||||
c1 = self._ay1.changeTo(vo-value/2)
|
||||
c2 = self._ay2.changeTo(vo+value/2)
|
||||
c3 = self._by1.changeTo(vo-value/2)
|
||||
c4 = self._by2.changeTo(vo+value/2)
|
||||
return c1,c2,c3,c4
|
||||
c1 = self._ay1.changeTo(vo - value / 2)
|
||||
c2 = self._ay2.changeTo(vo + value / 2)
|
||||
c3 = self._by1.changeTo(vo - value / 2)
|
||||
c4 = self._by2.changeTo(vo + value / 2)
|
||||
return c1, c2, c3, c4
|
||||
|
||||
def set_ho(self,value):
|
||||
def set_ho(self, value):
|
||||
hg = self.get_hg()
|
||||
c1 = self._ax1.changeTo(value-hg/2)
|
||||
c2 = self._ax2.changeTo(value+hg/2)
|
||||
c3 = self._bx1.changeTo(value-hg/2)
|
||||
c4 = self._bx2.changeTo(value+hg/2)
|
||||
return c1,c2,c3,c4
|
||||
def set_vo(self,value):
|
||||
vg = self.get_vg()
|
||||
c1 = self._ay1.changeTo(value-vg/2)
|
||||
c2 = self._ay2.changeTo(value+vg/2)
|
||||
c3 = self._by1.changeTo(value-vg/2)
|
||||
c4 = self._by2.changeTo(value+vg/2)
|
||||
return c1,c2,c3,c4
|
||||
c1 = self._ax1.changeTo(value - hg / 2)
|
||||
c2 = self._ax2.changeTo(value + hg / 2)
|
||||
c3 = self._bx1.changeTo(value - hg / 2)
|
||||
c4 = self._bx2.changeTo(value + hg / 2)
|
||||
return c1, c2, c3, c4
|
||||
|
||||
def __call__(self,width,height):
|
||||
def set_vo(self, value):
|
||||
vg = self.get_vg()
|
||||
c1 = self._ay1.changeTo(value - vg / 2)
|
||||
c2 = self._ay2.changeTo(value + vg / 2)
|
||||
c3 = self._by1.changeTo(value - vg / 2)
|
||||
c4 = self._by2.changeTo(value + vg / 2)
|
||||
return c1, c2, c3, c4
|
||||
|
||||
def __call__(self, width, height):
|
||||
self.set_hg(width)
|
||||
self.set_vg(height)
|
||||
|
||||
def __str__(self):
|
||||
string1 = 'gap: (%g,%g) mm'%(self.get_hg(),self.get_vg())
|
||||
string2 = 'pos: (%g,%g) mm'%(self.get_ho(),self.get_vo())
|
||||
return '\n'.join((string1,string2))
|
||||
string1 = "gap: (%g,%g) mm" % (self.get_hg(), self.get_vg())
|
||||
string2 = "pos: (%g,%g) mm" % (self.get_ho(), self.get_vo())
|
||||
return "\n".join((string1, string2))
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
|
||||
|
||||
class SlitPosWidth:
|
||||
def __init__(self,Id,name=None,elog=None):
|
||||
def __init__(self, Id, name=None, elog=None):
|
||||
self.Id = Id
|
||||
self.name = name
|
||||
self._xoffs = MotorRecord(Id+':MOTOR_X')
|
||||
self._yoffs = MotorRecord(Id+':MOTOR_Y')
|
||||
self._xgap = MotorRecord(Id+':MOTOR_W')
|
||||
self._ygap = MotorRecord(Id+':MOTOR_H')
|
||||
self._xoffs = MotorRecord(Id + ":MOTOR_X")
|
||||
self._yoffs = MotorRecord(Id + ":MOTOR_Y")
|
||||
self._xgap = MotorRecord(Id + ":MOTOR_W")
|
||||
self._ygap = MotorRecord(Id + ":MOTOR_H")
|
||||
|
||||
def get_hg(self):
|
||||
return self._xgap.get_current_value()
|
||||
|
||||
def get_vg(self):
|
||||
return self._ygap.get_current_value()
|
||||
|
||||
def get_ho(self):
|
||||
return self._xoffs.get_current_value()
|
||||
|
||||
def get_vo(self):
|
||||
return self._yoffs.get_current_value()
|
||||
def set_hg(self,value):
|
||||
|
||||
def set_hg(self, value):
|
||||
c = self._xgap.changeTo(value)
|
||||
return c
|
||||
def set_vg(self,value):
|
||||
|
||||
def set_vg(self, value):
|
||||
c = self._ygap.changeTo(value)
|
||||
return c
|
||||
|
||||
def set_ho(self,value):
|
||||
def set_ho(self, value):
|
||||
c = self._xoffs.changeTo(value)
|
||||
return c
|
||||
def set_vo(self,value):
|
||||
|
||||
def set_vo(self, value):
|
||||
c = self._yoffs.changeTo(value)
|
||||
return c
|
||||
|
||||
def __call__(self,width,height):
|
||||
def __call__(self, width, height):
|
||||
self.set_hg(width)
|
||||
self.set_vg(height)
|
||||
|
||||
def __repr__(self):
|
||||
string1 = 'gap: (%g,%g) mm'%(self.get_hg(),self.get_vg())
|
||||
string2 = 'pos: (%g,%g) mm'%(self.get_ho(),self.get_vo())
|
||||
return '\n'.join((string1,string2))
|
||||
string1 = "gap: (%g,%g) mm" % (self.get_hg(), self.get_vg())
|
||||
string2 = "pos: (%g,%g) mm" % (self.get_ho(), self.get_vo())
|
||||
return "\n".join((string1, string2))
|
||||
|
||||
-1124
File diff suppressed because it is too large
Load Diff
@@ -1,90 +0,0 @@
|
||||
import xrayutilities as xu
|
||||
from . import consts as _consts
|
||||
from scipy.constants import torr,bar,k,N_A,R
|
||||
import numpy as np
|
||||
|
||||
# This module holds relevant materials of the
|
||||
# xrayutilities materials class,
|
||||
|
||||
class MaterialCollection:
|
||||
""" Dummy class collections of materials (dict-like)."""
|
||||
def __init__(self, **entries):
|
||||
self.__dict__.update(entries)
|
||||
def __setitem__(self,key,value):
|
||||
self.__dict__.update({key:value})
|
||||
|
||||
_amorphous = dict()
|
||||
_crystal = dict()
|
||||
_gas = dict()
|
||||
|
||||
amorphous = MaterialCollection()
|
||||
crystal = MaterialCollection()
|
||||
gas = MaterialCollection()
|
||||
|
||||
def _get_transmission(self,d,E='config'):
|
||||
""" calculate the transmittion after thickness d (in m) of material at energy E (in eV)."""
|
||||
return np.exp(-d*1e6/self.absorption_length(E))
|
||||
|
||||
xu.materials.Material.transmission = _get_transmission
|
||||
|
||||
|
||||
crystal['Si'] = xu.materials.Si
|
||||
crystal['Ge'] = xu.materials.Ge
|
||||
crystal['GaAs'] = xu.materials.GaAs
|
||||
crystal['Al'] = xu.materials.Al
|
||||
crystal['Diamond'] = xu.materials.C
|
||||
crystal['Be'] = xu.materials.material.Crystal("Be", \
|
||||
xu.materials.spacegrouplattice.SGLattice(\
|
||||
194, 2.2858, 3.5843, atoms=[xu.materials.elements.Be, ], \
|
||||
pos=['2c', ]))
|
||||
|
||||
amorphous['B4C'] = xu.materials.material.Amorphous('B4C',2520,[('B',4),('C',1)])
|
||||
amorphous['Mo'] = xu.materials.material.Amorphous('Mo',10220,[('Mo',1)])
|
||||
amorphous['polyimide'] = xu.materials.material.Amorphous('polyimide',1430,[('C',22),('H',10),('N',2),('O',5)])
|
||||
amorphous['mylar'] = xu.materials.material.Amorphous('mylar',1400,[('C',10),('H',8),('O',4)])
|
||||
amorphous['polycarbonate'] = xu.materials.material.Amorphous('polycarbonate',1200,[('C',16),('H',14),('O',3)])
|
||||
amorphous['Si3N4'] = xu.materials.material.Amorphous('Silicon nitride',3440,[('Si',3),('N',4)])
|
||||
amorphous['air'] = xu.materials.material.Amorphous('air',1000,[('N',1.562),('O',.42),('C',.0003),('Ar',.0094)])
|
||||
|
||||
|
||||
# more useful values and constants
|
||||
#elementName = DummyClassDict(_consts.elementName)
|
||||
#meltPoint = DummyClassDict(_consts.meltPoint)
|
||||
#density = DummyClassDict(_consts.Density)
|
||||
|
||||
class Gas(xu.materials.material.Amorphous):
|
||||
def __init__(self,name, pressure=bar, temperature=295, molecule_size=1, atoms=None, cij=None):
|
||||
"""pressure in Pascal, temperature in Kelvin"""
|
||||
self.pressure = pressure
|
||||
self.temperature = temperature
|
||||
self.molecule_size = molecule_size
|
||||
super(Gas,self).__init__(name,0,atoms=atoms,cij=cij)
|
||||
|
||||
|
||||
def _getdensity(self):
|
||||
"""
|
||||
calculates the mass density of an material from the atomic composition and the average molecule size (ideal gas).
|
||||
|
||||
Returns
|
||||
-------
|
||||
mass density in kg/m^3
|
||||
"""
|
||||
num_dens = self.pressure/k/self.temperature
|
||||
return self._get_composition_mass()*num_dens*self.molecule_size
|
||||
density = property(_getdensity)
|
||||
|
||||
def _get_composition_mass(self):
|
||||
w = 0
|
||||
for atom,occ in self.base:
|
||||
w += atom.weight * occ
|
||||
return w
|
||||
|
||||
gas['air'] = Gas('air',molecule_size=1.9917,atoms=[('N',1.562),('O',.42),('C',.0003),('Ar',.0094)])
|
||||
gas['He'] = Gas('He',molecule_size=1,atoms=[('He',1)])
|
||||
gas['N'] = Gas('He',molecule_size=2,atoms=[('N',1)])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
import xrayutilities as xu
|
||||
import xraylib as xl
|
||||
import numpy as np
|
||||
from . import materials
|
||||
|
||||
def getKBMirrorLayer():
|
||||
subst = xu.simpack.Layer(materials.crystal.Si, np.inf)
|
||||
highZ = xu.simpack.Layer(materials.amorphous.Mo,200)
|
||||
lowZ = xu.simpack.Layer(materials.amorphous.B4C,150)
|
||||
return subst+highZ+lowZ
|
||||
|
||||
def calcReflectivity(mirror=getKBMirrorLayer(),energys=np.linspace(2000,12000,200),
|
||||
alphais=np.linspace(0,3,200),sample_width=500,**kwargs):
|
||||
Refl = []
|
||||
for E in energys:
|
||||
m = xu.simpack.SpecularReflectivityModel(mirror,energy=E,**kwargs)
|
||||
Refl.append(m.simulate(alphais))
|
||||
|
||||
return np.asarray(Refl),energys,alphais
|
||||
|
||||
def absorptionEdge(element,edge=None):
|
||||
if type(element) is str:
|
||||
element = xl.SymbolToAtomicNumber(element)
|
||||
shells = ['K','L1','L2','L3','M1','M2','M3','M4','M5']
|
||||
if edge is not None:
|
||||
shell_ind = shells.index(edge)
|
||||
return xl.EdgeEnergy(element,shell_ind)
|
||||
else:
|
||||
shell_inds = range(8)
|
||||
print('Absorption edges %s'%xl.AtomicNumberToSymbol(element))
|
||||
for shell_ind in shell_inds:
|
||||
print(' '\
|
||||
+shells[shell_ind].ljust(3)\
|
||||
+' = %7.1f eV'%(xl.EdgeEnergy(element,shell_ind)*1000))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,14 +7,13 @@ VERSION = (0, 0, 1)
|
||||
VERSION_STR = ".".join([str(x) for x in VERSION])
|
||||
|
||||
setup(
|
||||
name='eco',
|
||||
name="eco",
|
||||
version=VERSION_STR,
|
||||
description="Eco ...",
|
||||
long_description="Eco ../",
|
||||
author='Paul Scherrer Institute',
|
||||
author_email='@psi.ch',
|
||||
url='https://github.com/paulscherrerinstitute/eco',
|
||||
author="Paul Scherrer Institute",
|
||||
author_email="@psi.ch",
|
||||
url="https://github.com/paulscherrerinstitute/eco",
|
||||
packages=find_packages(),
|
||||
requires=['numpy', 'xrayutilities', 'xraylib'],
|
||||
|
||||
requires=["numpy", "xrayutilities", "xraylib"],
|
||||
)
|
||||
|
||||
+87
@@ -0,0 +1,87 @@
|
||||
from eco import ecocnf
|
||||
|
||||
|
||||
def main():
|
||||
import argparse
|
||||
|
||||
parser = argparse.ArgumentParser(description="eco startup utility")
|
||||
|
||||
parser.add_argument(
|
||||
"-s",
|
||||
"--scope",
|
||||
type=str,
|
||||
default=None,
|
||||
help="scope name, usually instrument or beamline",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-a",
|
||||
"--scopes_available",
|
||||
action="store_true",
|
||||
default=False,
|
||||
help="print available scopes.",
|
||||
)
|
||||
parser.add_argument(
|
||||
"-l", "--lazy", action="store_true", default=False, help="lazy initialisation"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--shell", type=bool, default=True, help="open eco in ipython shell"
|
||||
)
|
||||
parser.add_argument(
|
||||
"--pylab", type=bool, default=True, help="open ipython shell in pylab mode"
|
||||
)
|
||||
|
||||
arguments = parser.parse_args()
|
||||
|
||||
scope = arguments.scope
|
||||
# scope = 'bernina'
|
||||
|
||||
if arguments.scopes_available:
|
||||
print("{:<15s}{:<15s}{:<15s}".format("module", "name", "facility"))
|
||||
for ts in ecocnf.scopes:
|
||||
print(
|
||||
" {:<14s} {:<14s} {:<14s}".format(
|
||||
ts["module"], ts["name"], ts["facility"]
|
||||
)
|
||||
)
|
||||
|
||||
return
|
||||
|
||||
print(
|
||||
" ___ _______\n / -_) __/ _ \ \n Experiment Control \__/\__/\___/ \n\n"
|
||||
)
|
||||
|
||||
if scope:
|
||||
# import importlib
|
||||
# eco = importlib.import_module('eco')
|
||||
# mdl = importlib.import_module(scope,package=eco)
|
||||
# mdl = importlib.import_module('eco.bernina')
|
||||
if arguments.lazy:
|
||||
ecocnf.startup_lazy = True
|
||||
exec(f"import eco.{scope} as {scope}")
|
||||
# exec(f'{scope}.init(lazy=ecocnf.startup_lazy)')
|
||||
exec(f"from eco.{scope} import *")
|
||||
# is there an __all__? if so respect it
|
||||
# if "__all__" in mdl.__dict__:
|
||||
# names = mdl.__dict__["__all__"]
|
||||
# else:
|
||||
# otherwise we import all names that don't begin with _
|
||||
# names = [x for x in mdl.__dict__ if not x.startswith("_")]
|
||||
# now drag them in
|
||||
# globals().update({k: getattr(mdl, k) for k in names})
|
||||
|
||||
if arguments.shell:
|
||||
if arguments.pylab:
|
||||
import matplotlib.pyplot as plt
|
||||
from IPython.terminal.embed import InteractiveShellEmbed
|
||||
|
||||
shell = InteractiveShellEmbed()
|
||||
shell.enable_matplotlib()
|
||||
shell()
|
||||
else:
|
||||
from IPython import embed
|
||||
|
||||
embed()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user