Compare commits
129 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a26e0e5f9 | |||
| 5b811c8d12 | |||
| f36274823d | |||
| 06aaa7d720 | |||
| aa3021f9ea | |||
| 678823a07d | |||
| 641b31687d | |||
| 258815db7f | |||
| 07e028ed20 | |||
| 343573f888 | |||
| 8c4e6416b7 | |||
| 537d009a9c | |||
| f5fd14c693 | |||
| fb9d52d654 | |||
| c6c67cbf0e | |||
| d2d62bedf1 | |||
| 9f67070370 | |||
| 5bfb89c1ac | |||
| 5013df7444 | |||
| 70935efb94 | |||
| f4c11c6c24 | |||
| 748d247c29 | |||
| 213d191265 | |||
| fb5139ebac | |||
| e26d048b50 | |||
| 9c907b56fd | |||
| 388984f6d0 | |||
| 19565a6112 | |||
| b6d835d561 | |||
| 82325f07e0 | |||
| 64a3a54d59 | |||
| c52f9c907c | |||
| 31e5b329a0 | |||
| 1642f8cbbb | |||
| 97682acecc | |||
| 8f138ad2e5 | |||
| 8f043c9078 | |||
| 3ea9b6ec12 | |||
| 27c06df1f9 | |||
| 9f6c6fc29b | |||
| 9eeeb8d059 | |||
| 8a44dc9ac2 | |||
| bff609285a | |||
| c4cb79212b | |||
| 0e87ddf2bc | |||
| 589e4131c2 | |||
| c7628f1d7c | |||
| a0b1b01c4f | |||
| 2e4c2369a5 | |||
| 2d9eabf3a2 | |||
| 7f22d9a8b4 | |||
| aff2d5dd2f | |||
| 46266bd01e | |||
| b5d31a8fb0 | |||
| 3e9509e5e8 | |||
| b319e9cce2 | |||
| 6f07ede5d4 | |||
| d281a11855 | |||
| 48f6474bf0 | |||
| a6ee22c0e9 | |||
| ab6f32b549 | |||
| 8ffe75084b | |||
| f131243eee | |||
| c37e4bec8f | |||
| d2a6f2f2e4 | |||
| 32a854da21 | |||
| 23759b4697 | |||
| dc688e8e39 | |||
| e397b1fab3 | |||
| 2c13fdbf61 | |||
| 3bad22759d | |||
| e7ff72772f | |||
| 062c7d528f | |||
| 89b4ddb6c1 | |||
| 20637b42b4 | |||
| b8515abc5c | |||
| 0affd0a847 | |||
| 71d3e11e45 | |||
| 8932d1b401 | |||
| fe8a27edcd | |||
| c2f095d581 | |||
| a5d14ca59e | |||
| b22e1f7987 | |||
| 8d70442edb | |||
| 41bf08598b | |||
| 49cb67e306 | |||
| a4c0c25db0 | |||
| 96f9661393 | |||
| a5769daf2c | |||
| 63eca76e2c | |||
| 8e3741b2d0 | |||
| 07a67ad393 | |||
| bbe8015e72 | |||
| dd00baea97 | |||
| 8070e75232 | |||
| 4d4a53efdc | |||
| a2ec145ea5 | |||
| e5d3f11408 | |||
| 679be5eb41 | |||
| 285a9487ea | |||
| cc49644d42 | |||
| 5f4a093feb | |||
| 3d9db20088 | |||
| eff354bc78 | |||
| 937f38e453 | |||
| 757e8a846d | |||
| 8c5f7cc51d | |||
| 067d8a01b2 | |||
| ea40a55cdd | |||
| db85e12e82 | |||
| fc319575f9 | |||
| e91b076bbc | |||
| b4c223a473 | |||
| 2fa5cfd1eb | |||
| f07012825f | |||
| 8bdbe814ea | |||
| e1a7f853d5 | |||
| ec5c10a859 | |||
| 9f98c7a402 | |||
| 0e336911bf | |||
| e76774a6db | |||
| ce3405a5fe | |||
| 022bf783ba | |||
| 9fc3734350 | |||
| 99a8184f1f | |||
| b85084b891 | |||
| 3013fc4296 | |||
| 3edbcb3ebf | |||
| 9872e00b43 |
BIN
Binary file not shown.
@@ -4,3 +4,4 @@ __pycache__/
|
||||
|
||||
\.DS_Store
|
||||
.DS_Store
|
||||
.idea
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
sudo: false
|
||||
|
||||
language: cpp
|
||||
|
||||
matrix:
|
||||
include:
|
||||
- os: linux
|
||||
env: CONDA_PY=3.5
|
||||
- os: linux
|
||||
env: CONDA_PY=3.6
|
||||
- os: osx
|
||||
env: CONDA_PY=3.5
|
||||
- os: osx
|
||||
env: CONDA_PY=3.6
|
||||
|
||||
install:
|
||||
# Set the anaconda environment
|
||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
||||
if [[ "$CONDA_PY" == "2.7" ]]; then
|
||||
curl https://repo.continuum.io/miniconda/Miniconda2-latest-MacOSX-x86_64.sh -o miniconda.sh;
|
||||
else
|
||||
curl https://repo.continuum.io/miniconda/Miniconda3-latest-MacOSX-x86_64.sh -o miniconda.sh;
|
||||
fi;
|
||||
else
|
||||
if [[ "$CONDA_PY" == "2.7" ]]; then
|
||||
curl https://repo.continuum.io/miniconda/Miniconda2-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
else
|
||||
wget https://repo.continuum.io/miniconda/Miniconda3-latest-Linux-x86_64.sh -O miniconda.sh;
|
||||
fi
|
||||
fi
|
||||
- bash miniconda.sh -b -p $HOME/miniconda
|
||||
- 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
|
||||
# build
|
||||
- conda build conda-recipe
|
||||
|
||||
script:
|
||||
- echo "No test scripts to be run!"
|
||||
|
||||
deploy:
|
||||
provider: script
|
||||
script: find $HOME/miniconda/conda-bld/${TRAVIS_OS_NAME}-64 -name "*.tar.bz2" -exec anaconda -t $CONDA_TOKEN upload {} \;
|
||||
on:
|
||||
tags: true
|
||||
@@ -1,3 +1,5 @@
|
||||
[](https://travis-ci.org/paulscherrerinstitute/eco)
|
||||
|
||||
# Experiment Control
|
||||
Python based control environment for experiments at SwissFEL
|
||||
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
""" """
|
||||
@@ -0,0 +1,2 @@
|
||||
"%PYTHON%" setup.py install
|
||||
if errorlevel 1 exit 1
|
||||
@@ -0,0 +1 @@
|
||||
$PYTHON setup.py install # Python command to install the script
|
||||
@@ -0,0 +1,32 @@
|
||||
package:
|
||||
name: eco
|
||||
version: 0.0.1
|
||||
#source:
|
||||
# git_tag: 0.0.14
|
||||
# git_url: git@git.psi.ch:sf_daq/bsread_python.git
|
||||
source:
|
||||
path: ..
|
||||
|
||||
build:
|
||||
number: 1
|
||||
|
||||
requirements:
|
||||
build:
|
||||
- python
|
||||
- setuptools
|
||||
run:
|
||||
- python
|
||||
- elog
|
||||
- pyepics
|
||||
- bsread
|
||||
- jungfrau_utils
|
||||
- xrayutilities
|
||||
- xraylib
|
||||
|
||||
#build:
|
||||
# entry_points:
|
||||
# - bs = bsread.bs:main
|
||||
|
||||
about:
|
||||
# home: git@git.psi.ch:sf_daq/bsread_python.git
|
||||
summary: "Eco ..."
|
||||
@@ -1,417 +0,0 @@
|
||||
import numpy as np
|
||||
from epics import caget
|
||||
from epics import PV
|
||||
from ..eco_epics.utilities_epics import EnumWrapper
|
||||
|
||||
from cam_server import PipelineClient
|
||||
from cam_server.utils import get_host_port_from_stream_address
|
||||
from bsread import source, SUB
|
||||
import subprocess
|
||||
import h5py
|
||||
from time import sleep
|
||||
from threading import Thread
|
||||
|
||||
from ..acquisition.utilities import Acquisition
|
||||
|
||||
import subprocess
|
||||
|
||||
|
||||
try:
|
||||
import sys, os
|
||||
tpath = "/sf/alvra/config/jungfrau/envs/jungfrau_client/lib/python3.6/site-packages/" # os.path.dirname(__file__)
|
||||
sys.path.insert(0,os.path.join(tpath,'/jungfrau_utils'))
|
||||
|
||||
#tpath = "/sf/alvra/config/src/python"
|
||||
#sys.path.insert(0,os.path.join(tpath,'/detector_integration_api'))
|
||||
from detector_integration_api import DetectorIntegrationClient
|
||||
print("DONE")
|
||||
except:
|
||||
print('NB: JF detector integration could not be imported!')
|
||||
|
||||
|
||||
_cameraArrayTypes = ['monochrome','rgb']
|
||||
|
||||
class CameraCA:
|
||||
def __init__(self, pvname, cameraArrayType='monochrome',elog=None):
|
||||
self.Id = pvname
|
||||
self.isBS = False
|
||||
self.px_height = None
|
||||
self.px_width = None
|
||||
self.elog = elog
|
||||
|
||||
def get_px_height(self):
|
||||
if not self.px_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')
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
""" Adjustable convention"""
|
||||
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)
|
||||
|
||||
#/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):
|
||||
self._stream_host = host
|
||||
self._stream_port = port
|
||||
|
||||
def checkServer(self):
|
||||
# Check if your instance is running on the server.
|
||||
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):
|
||||
data = []
|
||||
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)
|
||||
return data
|
||||
|
||||
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:
|
||||
|
||||
input_stream.connect()
|
||||
|
||||
for n in range(N_images):
|
||||
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
|
||||
|
||||
class FeDigitizer:
|
||||
def __init__(self,Id,elog=None):
|
||||
self.Id = Id
|
||||
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']
|
||||
|
||||
def set_bias(self, value):
|
||||
self._bias.put(value)
|
||||
|
||||
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):
|
||||
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))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class JF:
|
||||
def __init__(self, Id):
|
||||
self.writer_config = ""
|
||||
self.backend_config = ""
|
||||
self.detector_config = ""
|
||||
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",
|
||||
"exptime": 0.000005,
|
||||
"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",
|
||||
"gain_corrections_dataset": "gains",
|
||||
"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
|
||||
while not running:
|
||||
if self.get_status()['status'][-7:]=='RUNNING':
|
||||
running = True
|
||||
break
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def check_still_running(self,time_interval=.5):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while running:
|
||||
if not self.get_status()['status'][-7:]=='RUNNING':
|
||||
running = False
|
||||
break
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def start(self):
|
||||
self.client.start()
|
||||
print("start acquisition")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
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():
|
||||
self.reset()
|
||||
self.detector_config.update(dict(cycles=Npulses))
|
||||
self.writer_config.update(dict(output_file=file_name))
|
||||
self.set_config(f = file_name, N = Npulses)
|
||||
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:
|
||||
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
|
||||
# JF client thing
|
||||
|
||||
class JF_BS_writer:
|
||||
def __init__(self, Id,api_address = "http://sf-daq-2:10000"):
|
||||
self._api_address = api_address
|
||||
self.client = DetectorIntegrationClient(api_address)
|
||||
print("\nJungfrau Integration API on %s" % api_address)
|
||||
self.writer_config = {
|
||||
"output_file": "/sf/alvra/data/raw/p16581/test_data.h5",
|
||||
"process_uid": 16581,
|
||||
"process_gid": 16581,
|
||||
"dataset_name": "jungfrau/data",
|
||||
"n_messages": 100
|
||||
}
|
||||
self.backend_config = {
|
||||
"n_frames": 100,
|
||||
"gain_corrections_filename": "/sf/alvra/config/jungfrau/jungfrau_4p5_gaincorrections_v0.h5",
|
||||
"gain_corrections_dataset": "gains",
|
||||
"pede_corrections_filename": "/sf/alvra/data/res/p16581/pedestal_20171210_1628_res.h5",
|
||||
"pede_corrections_dataset": "gains",
|
||||
"pede_mask_dataset": "pixel_mask",
|
||||
"activate_corrections_preview": True,
|
||||
"is_HG0": True
|
||||
}
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
"exptime": 0.000005,
|
||||
"cycles": 100,
|
||||
"delay" : 0.001992,
|
||||
"frames" : 1
|
||||
}
|
||||
|
||||
default_channels_list = parseChannelListFile(
|
||||
'/sf/alvra/config/com/channel_lists/default_channel_list')
|
||||
self.bsread_config = {
|
||||
'output_file': '/sf/alvra/data/raw/p16581/test_bsread.h5',
|
||||
'process_uid': 16581,
|
||||
'process_gid': 16581,
|
||||
'n_pulses':100,
|
||||
'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_config(self):
|
||||
self.reset()
|
||||
self.client.set_config(writer_config=self.writer_config, backend_config=self.backend_config, detector_config=self.detector_config, bsread_config=self.bsread_config)
|
||||
|
||||
# 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
|
||||
# while not running:
|
||||
# if self.get_status()['status'][-7:]=='RUNNING':
|
||||
# running = True
|
||||
# break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
|
||||
def check_still_running(self,time_interval=.5):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while 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
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def start(self):
|
||||
subprocess.check_call(["caput", "SIN-TIMAST-TMA:Evt-24-Ena-Sel", "0"])
|
||||
self.client.start()
|
||||
subprocess.check_call(["caput", "SIN-TIMAST-TMA:Evt-24-Ena-Sel", "1"])
|
||||
print("start acquisition")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
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=2,bsread_padding=50):
|
||||
file_name_JF = file_name + '_JF4p5M.h5'
|
||||
file_name_bsread = file_name+'.h5'
|
||||
def acquire():
|
||||
self.detector_config.update({
|
||||
'cycles':Npulses*JF_factor})
|
||||
self.writer_config.update({
|
||||
'output_file':file_name_JF,
|
||||
'n_messages':Npulses*JF_factor})
|
||||
self.backend_config.update({
|
||||
'n_frames':Npulses*JF_factor})
|
||||
self.bsread_config.update({
|
||||
'output_file':file_name_bsread,
|
||||
'n_pulses':Npulses+bsread_padding
|
||||
})
|
||||
|
||||
self.reset()
|
||||
self.set_config()
|
||||
self.client.start()
|
||||
done = False
|
||||
while not done:
|
||||
stat = self.get_status()
|
||||
if stat['status'] =='IntegrationStatus.FINISHED':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
done = True
|
||||
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()
|
||||
@@ -1,407 +0,0 @@
|
||||
import numpy as np
|
||||
from epics import caget
|
||||
from epics import PV
|
||||
from ..eco_epics.utilities_epics import EnumWrapper
|
||||
|
||||
from cam_server import PipelineClient
|
||||
from cam_server.utils import get_host_port_from_stream_address
|
||||
from bsread import source, SUB
|
||||
import subprocess
|
||||
import h5py
|
||||
from time import sleep
|
||||
from threading import Thread
|
||||
|
||||
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'))
|
||||
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!')
|
||||
|
||||
|
||||
_cameraArrayTypes = ['monochrome','rgb']
|
||||
|
||||
class CameraCA:
|
||||
def __init__(self, pvname, cameraArrayType='monochrome',elog=None):
|
||||
self.Id = pvname
|
||||
self.isBS = False
|
||||
self.px_height = None
|
||||
self.px_width = None
|
||||
self.elog = elog
|
||||
|
||||
def get_px_height(self):
|
||||
if not self.px_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')
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
""" Adjustable convention"""
|
||||
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)
|
||||
|
||||
#/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):
|
||||
self._stream_host = host
|
||||
self._stream_port = port
|
||||
|
||||
def checkServer(self):
|
||||
# Check if your instance is running on the server.
|
||||
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):
|
||||
data = []
|
||||
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)
|
||||
return data
|
||||
|
||||
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:
|
||||
|
||||
input_stream.connect()
|
||||
|
||||
for n in range(N_images):
|
||||
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
|
||||
|
||||
class FeDigitizer:
|
||||
def __init__(self,Id,elog=None):
|
||||
self.Id = Id
|
||||
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']
|
||||
|
||||
def set_bias(self, value):
|
||||
self._bias.put(value)
|
||||
|
||||
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):
|
||||
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))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class JF:
|
||||
def __init__(self, Id):
|
||||
self.writer_config = ""
|
||||
self.backend_config = ""
|
||||
self.detector_config = ""
|
||||
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/bernina/data/res/p16582/JF_pedestal/pedestal_20180302_1512_res.h5', fname = "/sf/bernina/data/raw/p16582/JF.h5", N = 1000):
|
||||
|
||||
self.reset()
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
"exptime": 0.00001,
|
||||
"delay" : 0.001987, # this is the magic aldo number
|
||||
"frames" : 1,
|
||||
"cycles": N}
|
||||
|
||||
|
||||
self.writer_config = {
|
||||
"output_file": fname,
|
||||
"process_uid": 16582,
|
||||
"process_gid": 16582,
|
||||
"dataset_name": "jungfrau/data",
|
||||
"n_messages": N}
|
||||
|
||||
self.backend_config = {
|
||||
"n_frames": N,
|
||||
"gain_corrections_filename": "/sf/bernina/data/res/p16582/gains_I0.h5",
|
||||
"gain_corrections_dataset": "gains",
|
||||
"pede_corrections_filename": pedestal_fname,
|
||||
"pede_corrections_dataset": "gains",
|
||||
"pede_mask_dataset" : "pixel_mask",
|
||||
"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
|
||||
while not running:
|
||||
if self.get_status()['status'][-7:]=='RUNNING':
|
||||
running = True
|
||||
break
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def check_still_running(self,time_interval=.5):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while running:
|
||||
if not self.get_status()['status'][-7:]=='RUNNING':
|
||||
running = False
|
||||
break
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def start(self):
|
||||
self.client.start()
|
||||
print("start acquisition")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
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 += '_JF1p5M.h5'
|
||||
def acquire():
|
||||
self.reset()
|
||||
self.detector_config.update(dict(cycles=Npulses))
|
||||
self.writer_config.update(dict(output_file=file_name))
|
||||
self.set_config(f = file_name, N = Npulses)
|
||||
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:
|
||||
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
|
||||
# JF client thing
|
||||
|
||||
class JF_BS_writer:
|
||||
def __init__(self, Id,api_address = "http://sf-daq-1:10000"):
|
||||
self._api_address = api_address
|
||||
self.client = DetectorIntegrationClient(api_address)
|
||||
print("\nJungfrau Integration API on %s" % api_address)
|
||||
self.writer_config = {
|
||||
"output_file": "/sf/bernina/data/raw/p16582/test_data.h5",
|
||||
"process_uid": 16582,
|
||||
"process_gid": 16582,
|
||||
"dataset_name": "jungfrau/data",
|
||||
"n_messages": 100
|
||||
}
|
||||
self.backend_config = {
|
||||
"n_frames": 100,
|
||||
"gain_corrections_filename": "/sf/bernina/data/res/p16582/gains.h5",
|
||||
"gain_corrections_dataset": "gains",
|
||||
"pede_corrections_filename": "/sf/bernina//data/res/p16582/JF_pedestal/pedestal_20171128_1048_res.h5",
|
||||
"pede_corrections_dataset": "gains",
|
||||
"activate_corrections_preview": True
|
||||
}
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
"exptime": 0.00001,
|
||||
"cycles": 100,
|
||||
"delay" : 0.00199,
|
||||
"frames" : 1
|
||||
}
|
||||
|
||||
default_channels_list = parseChannelListFile(
|
||||
'/sf/bernina/config/com/channel_lists/default_channel_list')
|
||||
self.bsread_config = {
|
||||
'output_file': '/sf/bernina/data/raw/p16582/test_bsread.h5',
|
||||
'process_uid': 16582,
|
||||
'process_gid': 16582,
|
||||
'n_pulses':100,
|
||||
'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_config(self):
|
||||
self.client.set_config(writer_config=self.writer_config, backend_config=self.backend_config, detector_config=self.detector_config, bsread_config=self.bsread_config)
|
||||
|
||||
# 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
|
||||
# while not running:
|
||||
# if self.get_status()['status'][-7:]=='RUNNING':
|
||||
# running = True
|
||||
# break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
|
||||
def check_still_running(self,time_interval=.5):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while 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
|
||||
else:
|
||||
sleep(time_interval)
|
||||
|
||||
def start(self):
|
||||
self.client.start()
|
||||
print("start acquisition")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
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=2,bsread_padding=50):
|
||||
file_name_JF = file_name + '_JF1p5M.h5'
|
||||
file_name_bsread = file_name+'.h5'
|
||||
def acquire():
|
||||
self.detector_config.update({
|
||||
'cycles':Npulses*JF_factor})
|
||||
self.writer_config.update({
|
||||
'output_file':file_name_JF,
|
||||
'n_messages':Npulses*JF_factor})
|
||||
self.backend_config.update({
|
||||
'n_frames':Npulses*JF_factor})
|
||||
self.bsread_config.update({
|
||||
'output_file':file_name_bsread,
|
||||
'n_pulses':Npulses+bsread_padding
|
||||
})
|
||||
|
||||
self.reset()
|
||||
self.set_config()
|
||||
self.client.start()
|
||||
done = False
|
||||
while not done:
|
||||
stat = self.get_status()
|
||||
if stat['status'] =='IntegrationStatus.FINISHED':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
done = True
|
||||
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()
|
||||
@@ -1,6 +0,0 @@
|
||||
from epics import Motor as _Motor_pyepics
|
||||
|
||||
class Motor:
|
||||
def __init__(PV):
|
||||
pass
|
||||
|
||||
Executable → Regular
Executable → Regular
@@ -21,6 +21,35 @@ class BStools:
|
||||
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()])
|
||||
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)
|
||||
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']))
|
||||
else:
|
||||
return status
|
||||
|
||||
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.')
|
||||
|
||||
|
||||
|
||||
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
|
||||
@@ -39,6 +68,7 @@ class BStools:
|
||||
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):
|
||||
if not channel_list:
|
||||
print('No channels specified, using default list \'%s\' instead.'%list(self._default_channel_list.keys())[0])
|
||||
@@ -6,7 +6,7 @@ from time import sleep
|
||||
import traceback
|
||||
|
||||
class ScanSimple:
|
||||
def __init__(self,adjustables,values,counterCallers,fina,Npulses=100,basepath='',scan_info_dir='',checker=None):
|
||||
def __init__(self,adjustables,values,counterCallers,fina,Npulses=100,basepath='',scan_info_dir='',checker=None,scan_directories=False):
|
||||
self.Nsteps = len(values)
|
||||
self.pulses_per_step = Npulses
|
||||
self.adjustables = adjustables
|
||||
@@ -30,6 +30,7 @@ class ScanSimple:
|
||||
'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:
|
||||
@@ -40,6 +41,8 @@ class ScanSimple:
|
||||
|
||||
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
|
||||
return fina
|
||||
|
||||
@@ -78,10 +81,13 @@ class ScanSimple:
|
||||
if self.checker:
|
||||
if not self.checker['checker_call'](*self.checker['args'],**self.checker['kwargs']):
|
||||
return True
|
||||
|
||||
if callable(step_info):
|
||||
tstepinfo = step_info()
|
||||
else:
|
||||
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=step_info)
|
||||
self.appendScanInfo(values_step,readbacks_step,step_files=filenames,step_info=tstepinfo)
|
||||
self.writeScanInfo()
|
||||
self.nextStep +=1
|
||||
return True
|
||||
@@ -96,11 +102,11 @@ class ScanSimple:
|
||||
with open(self.scan_info_filename,'w') as f:
|
||||
json.dump(self.scan_info,f,indent=4,sort_keys=True)
|
||||
|
||||
def scanAll(self):
|
||||
def scanAll(self, step_info=None):
|
||||
done = False
|
||||
try:
|
||||
while not done:
|
||||
done = not self.doNextStep()
|
||||
done = not self.doNextStep(step_info=step_info)
|
||||
except:
|
||||
tb = traceback.format_exc()
|
||||
else:
|
||||
@@ -116,25 +122,26 @@ class ScanSimple:
|
||||
|
||||
|
||||
class Scans:
|
||||
def __init__(self,data_base_dir='',scan_info_dir='',default_counters=[],checker=None):
|
||||
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):
|
||||
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)
|
||||
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()
|
||||
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)
|
||||
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)
|
||||
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
|
||||
@@ -143,11 +150,11 @@ class Scans:
|
||||
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):
|
||||
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)
|
||||
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()
|
||||
s.scanAll(step_info=step_info)
|
||||
return s
|
||||
|
||||
Executable → Regular
@@ -4,157 +4,160 @@ elog = {'url': 'https://elog-gfa.psi.ch/Alvra',
|
||||
aliases = {
|
||||
# Front-End components
|
||||
'SARFE10-OPSH044' : {
|
||||
'alias' : 'ShutUnd',
|
||||
'alias' : 'shutUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Photon shutter after Undulator'},
|
||||
'SARFE10-OAPU044' : {
|
||||
'alias' : 'SlitUnd',
|
||||
'alias' : 'slitUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Slit after Undulator',
|
||||
'eco_type' : 'xoptics.slits.SlitFourBlades'},
|
||||
'SARFE10-PBIG050' : {
|
||||
'alias' : 'GasMon',
|
||||
'alias' : 'gasMon',
|
||||
'z_und' : 50,
|
||||
'desc' : 'Gas Monitor Intensity (PBIG)'},
|
||||
'SARFE10-PBPS053' : {
|
||||
'alias' : 'MonUnd',
|
||||
'alias' : 'pbpsUnd',
|
||||
'z_und' : 44,
|
||||
'desc' : 'Intensity position monitor after Undulator (PBPS)'},
|
||||
'SARFE10-OATT053' : {
|
||||
'alias' : 'AttFE',
|
||||
'alias' : 'attFE',
|
||||
'z_und' : 53,
|
||||
'desc' : 'Attenuator in Front End',
|
||||
'eco_type' : 'xoptics.attenuator_aramis.AttenuatorAramis'},
|
||||
'SARFE10-PPRM053' : {
|
||||
'alias' : 'ProfFE',
|
||||
'alias' : 'screenFE',
|
||||
'z_und' : 53,
|
||||
'desc' : 'Profile monitor after single-shot spectrometer (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SARFE10-SBST060' : {
|
||||
'alias' : 'ShutFE',
|
||||
'alias' : 'shutFE',
|
||||
'z_und' : 60,
|
||||
'desc' : 'Photon shutter in the end of Front End'},
|
||||
# Optics hutch components
|
||||
'SARFE10-PPRM064' : {
|
||||
'alias' : 'ProfOP',
|
||||
'alias' : 'screenOP',
|
||||
'z_und' : 64,
|
||||
'desc' : 'Profile monitor after Front End',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OOMH064' : {
|
||||
'alias' : 'MirrAlv1',
|
||||
'alias' : 'mirrorAlv1',
|
||||
'z_und' : 64,
|
||||
'desc' : 'First Alvra Horizontal offset mirror (OMH064)'},
|
||||
'SAROP11-PPRM066' : {
|
||||
'alias' : 'ProfMirrAlv1',
|
||||
'alias' : 'screenMirrAlv1',
|
||||
'z_und' : 66,
|
||||
'desc' : 'Profile monitor after Alvra Mirror 1 (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OOMH076' : {
|
||||
'alias' : 'MirrAlv2',
|
||||
'alias' : 'mirrorAlv2',
|
||||
'z_und' : 76,
|
||||
'desc' : 'Second Alvra Horizontal offset mirror (OMH076)'},
|
||||
'SAROP11-PPRM078' : {
|
||||
'alias' : 'ProfMirrAlv2',
|
||||
'alias' : 'screenMirrAlv2',
|
||||
'z_und' : 78,
|
||||
'desc' : 'Profile monitor after Alvra Mirror 2 (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OAPU104' : {
|
||||
'alias' : 'SlitSwitch',
|
||||
'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',
|
||||
'alias' : 'mono',
|
||||
'z_und' : 105,
|
||||
'desc' : 'Alvra DCM Monochromator',
|
||||
'eco_type' : 'xoptics.dcm.Double_Crystal_Mono'},
|
||||
'SAROP11-PSCR106' : {
|
||||
'alias' : 'ProfMono',
|
||||
'z_und' : 106,
|
||||
'desc' : 'Profile Monitor after Mono (PSCR)'},
|
||||
# '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' : 'MirrV1',
|
||||
'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-PSCR109' : {
|
||||
# 'alias' : 'ProfMirrV1',
|
||||
# 'z_und' : 109,
|
||||
# 'desc' : 'Profile Monitor after Vertical Mirror 1 (PSCR)'},
|
||||
'SAROP11-OOMV109' : {
|
||||
'alias' : 'MirrV2',
|
||||
'alias' : 'mirrorV2',
|
||||
'z_und' : 109,
|
||||
'desc' : 'Alvra Vertical offset Mirror 2 (OMV109)'},
|
||||
'SAROP11-PPRM110' : {
|
||||
'alias' : 'ProfMirrV2',
|
||||
'alias' : 'screenMirrorV2',
|
||||
'z_und' : 110,
|
||||
'desc' : 'Profile monitor after Vertical Mirror 2 (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OPPI110' : {
|
||||
'alias' : 'Pick',
|
||||
'alias' : 'pulsePicker',
|
||||
'z_und' : 110,
|
||||
'desc' : 'X-ray pulse picker'},
|
||||
'SAROP11-SBST114' : {
|
||||
'alias' : 'ShutOpt',
|
||||
'alias' : 'shutOpt',
|
||||
'z_und' : 114,
|
||||
'desc' : 'Shutter after Optics hutch'},
|
||||
## Experimental hutch components
|
||||
## The following PBPS isn't implemented yet
|
||||
# 'SAROP11-PBPS117' : {
|
||||
# 'alias' : 'MonOpt',
|
||||
# 'z_und' : 117,
|
||||
# 'desc' : 'Intensity/position monitor after Optics hutch (PBPS)',
|
||||
# 'eco_type' : 'xdiagnostics.intensity_monitors.SolidTargetDetectorPBPS',
|
||||
# the following is the trigger for this PBPS, I've changed it to SAROP11 but this definitely isn't correct
|
||||
# 'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
'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' : 'ProfOpt',
|
||||
'alias' : 'screenOPEnd',
|
||||
'z_und' : 117,
|
||||
'desc' : 'Profile monitor after Optics hutch (PPRM)',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-PALM118' : {
|
||||
'alias' : 'TimTof',
|
||||
'alias' : 'DelayPALM',
|
||||
'z_und' : 118,
|
||||
'desc' : 'Timing diagnostics THz streaking (PALM)'},
|
||||
'SAROP11-PSEN119' : {
|
||||
'alias' : 'TimRef',
|
||||
'alias' : 'DelayPSEN',
|
||||
'z_und' : 119,
|
||||
'desc' : 'Timing diagnostics spectral encoding (PSEN)'},
|
||||
'SAROP11-OATT120' : {
|
||||
'alias' : 'Att',
|
||||
'alias' : 'attExp',
|
||||
'z_und' : 120,
|
||||
'desc' : 'Attenuator Alvra',
|
||||
'eco_type' : 'xoptics.attenuator_aramis.AttenuatorAramis'},
|
||||
'SAROP11-OAPU120' : {
|
||||
'alias' : 'SlitAtt',
|
||||
'alias' : 'slitAttExp',
|
||||
'z_und' : 120,
|
||||
'desc' : 'Slits behind attenuator',
|
||||
'eco_type' : 'xoptics.slits.SlitPosWidth'},
|
||||
'SAROP11-OLAS120' : {
|
||||
'alias' : 'RefLaser',
|
||||
'alias' : 'refLaser',
|
||||
'z_und' : 120,
|
||||
'desc' : 'Alvra beamline reference laser before KBs (OLAS)',
|
||||
'eco_type' : 'xoptics.reflaser.RefLaser_Aramis'},
|
||||
'SAROP11-PBPS122' : {
|
||||
'alias' : 'MonAtt',
|
||||
'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' : 'ProfAtt',
|
||||
'alias' : 'screenAtt',
|
||||
'z_und' : 122,
|
||||
'desc' : 'Profile monitor after Attenuator',
|
||||
'eco_type' : 'xdiagnostics.profile_monitors.Pprm'},
|
||||
'SAROP11-OKBV123' : {
|
||||
'alias' : 'KbVer',
|
||||
'alias' : 'kbVer',
|
||||
'z_und' : 123,
|
||||
'desc' : 'Alvra vertical KB mirror',
|
||||
'eco_type' : 'xoptics.KB.KB'},
|
||||
'eco_type' : 'xoptics.KBver.KBver'},
|
||||
'SAROP11-OKBH124' : {
|
||||
'alias' : 'KbHor',
|
||||
'alias' : 'kbHor',
|
||||
'z_und' : 124,
|
||||
'desc' : 'Alvra horizontal KB mirror',
|
||||
'eco_type' : 'xoptics.KB.KB'},
|
||||
'eco_type' : 'xoptics.KBhor.KBhor'},
|
||||
# 'SAROP11-PIPS125-1' : {
|
||||
# 'alias' : 'PIPS1',
|
||||
# 'z_und' : 127,
|
||||
@@ -169,22 +172,22 @@ aliases = {
|
||||
# 'kwargs' : {'VME_crate':'SAROP11-CVME-PBPS1','link':9} },
|
||||
|
||||
'SARES11-XSAM125' : {
|
||||
'alias' : 'PrimeSample',
|
||||
'alias' : 'primeSample',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Sample XYZ manipulator',
|
||||
'eco_type' : 'endstations.alvra_prime.huber'},
|
||||
'SARES11-XCRY125' : {
|
||||
'alias' : 'PrimeCryTrans',
|
||||
'alias' : 'primeCryTrans',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime von Hamos X-trans (Bragg)',
|
||||
'eco_type' : 'endstations.alvra_prime.vonHamosBragg'},
|
||||
'SARES11-XOTA125' : {
|
||||
'alias' : 'PrimeTable',
|
||||
'alias' : 'primeTable',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime optical table',
|
||||
'eco_type' : 'endstations.alvra_prime.table'},
|
||||
'SARES11-XMI125' : {
|
||||
'alias' : 'Microscope',
|
||||
'alias' : 'primeMicroscope',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Microscope focus and zoom',
|
||||
'eco_type' : 'endstations.alvra_prime.microscope'},
|
||||
@@ -208,63 +211,72 @@ aliases = {
|
||||
# 'desc' : 'Experiment laser optics',
|
||||
# 'eco_type' : 'loptics.bernina_experiment.Laser_Exp'},
|
||||
'SLAAR01-TSPL-EPL' : {
|
||||
'alias' : 'PhaseShifter',
|
||||
'alias' : 'phaseShifter',
|
||||
'z_und' : 127,
|
||||
'desc' : 'Experiment laser phase shifter',
|
||||
'desc' : 'Experiment laser phase shifter (Globi)',
|
||||
'eco_type' : 'devices_general.alvratiming.PhaseShifterAramis'},
|
||||
# 'http://sf-daq-2:10000' : {
|
||||
'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' : 127,
|
||||
# 'z_und' : 125,
|
||||
# 'desc' : '4.5M Jungfrau detector',
|
||||
# 'eco_type' : 'devices_general.alvradetectors.JF'},
|
||||
# 'SLAAR21-LTIM01-EVR0' : {
|
||||
# 'alias' : 'LaserShutter',
|
||||
# 'z_und' : 127,
|
||||
# 'desc' : 'Laser Shutter',
|
||||
# 'eco_type' : 'loptics.laser_shutter.laser_shutter'},
|
||||
# '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' : 0,
|
||||
'desc' : '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' : 0,
|
||||
'desc' : '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' : 0,
|
||||
'desc' : 'PRISM rotation',
|
||||
'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' : 0,
|
||||
'desc' : 'Mirror of the microscope, gonio',
|
||||
'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' : 0,
|
||||
'desc' : 'Mirror of the microscope, rot',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord'},
|
||||
|
||||
'SLAAR11-LMOT' : {
|
||||
'alias' : 'psen',
|
||||
'z_und' : 0,
|
||||
'desc' : 'PSEN timing system',
|
||||
'eco_type' : 'xdiagnostics.PSEN.PSEN'}
|
||||
'z_und' : 127,
|
||||
'desc' : 'Prime microscope mirror rotation',
|
||||
'eco_type' : 'devices_general.smaract.SmarActRecord'}
|
||||
}
|
||||
|
||||
|
||||
@@ -137,12 +137,12 @@ aliases = {
|
||||
'alias' : 'KbVer',
|
||||
'z_und' : 139,
|
||||
'desc' : 'Vertically focusing Bernina KB mirror',
|
||||
'eco_type' : 'xoptics.KB.KB'},
|
||||
'eco_type' : 'xoptics.KBver.KBver'},
|
||||
'SAROP21-OKBH140' : {
|
||||
'alias' : 'KbHor',
|
||||
'z_und' : 140,
|
||||
'desc' : 'Horizontally focusing Bernina KB mirror',
|
||||
'eco_type' : 'xoptics.KB.KB'},
|
||||
'eco_type' : 'xoptics.KBhor.KBhor'},
|
||||
'SARES22-GPS' : {
|
||||
'alias' : 'Gps',
|
||||
'z_und' : 142,
|
||||
@@ -154,13 +154,7 @@ aliases = {
|
||||
'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' : 'Las',
|
||||
'z_und' : 142,
|
||||
'desc' : 'Experiment laser optics',
|
||||
'eco_type' : 'loptics.bernina_experiment.Laser_Exp'},
|
||||
'SLAAR02-TSPL-EPL' : {
|
||||
'alias' : 'PhaseShifter',
|
||||
'z_und' : 142,
|
||||
@@ -170,12 +164,28 @@ aliases = {
|
||||
'alias' : 'DetJF',
|
||||
'z_und' : 142,
|
||||
'desc' : '1.5M Jungfrau detector',
|
||||
'eco_type' : 'devices_general.detectors.JF'},
|
||||
'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'},
|
||||
'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 =
|
||||
Executable → Regular
@@ -0,0 +1,154 @@
|
||||
import subprocess
|
||||
from threading import Thread
|
||||
from epics import PV
|
||||
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)
|
||||
|
||||
class ValueRdback:
|
||||
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)
|
||||
self._elog = elog
|
||||
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_message = _status_messages[self._status]
|
||||
if not self._status==0:
|
||||
print(self._status_message)
|
||||
|
||||
# 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)
|
||||
def stop(self):
|
||||
""" Adjustable convention"""
|
||||
try:
|
||||
self._currentChange.stop()
|
||||
except:
|
||||
self._motor.stop()
|
||||
pass
|
||||
|
||||
|
||||
def get_current_value(self):
|
||||
""" Adjustable convention"""
|
||||
return self._PV_readback.get()
|
||||
|
||||
def set_current_value(self,value):
|
||||
""" Adjustable convention"""
|
||||
print('not implemented: depends on a defined offset')
|
||||
|
||||
def get_precision(self):
|
||||
""" Adjustable convention"""
|
||||
if isinstance(self._precision,PV):
|
||||
return self._precision.get()
|
||||
else:
|
||||
return self._precision
|
||||
|
||||
def set_precision(self,value):
|
||||
""" Adjustable convention"""
|
||||
if isinstance(self._precision,PV):
|
||||
self._precision.put(value)
|
||||
else:
|
||||
self._precision = value
|
||||
|
||||
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"""
|
||||
""" 0: moving 1: move done"""
|
||||
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'
|
||||
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])
|
||||
|
||||
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'
|
||||
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()
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
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,))
|
||||
if not hold:
|
||||
self._thread.start()
|
||||
|
||||
def wait(self):
|
||||
self._thread.join()
|
||||
|
||||
def start(self):
|
||||
self._thread.start()
|
||||
|
||||
def status(self):
|
||||
if self._thread.ident is None:
|
||||
return 'waiting'
|
||||
else:
|
||||
if self._isAlive:
|
||||
return 'changing'
|
||||
else:
|
||||
return 'done'
|
||||
def stop(self):
|
||||
self._stopper()
|
||||
|
||||
|
||||
|
||||
Executable
+679
@@ -0,0 +1,679 @@
|
||||
import numpy as np
|
||||
from epics import caget
|
||||
from epics import PV
|
||||
from ..eco_epics.utilities_epics import EnumWrapper
|
||||
|
||||
from cam_server import PipelineClient
|
||||
from cam_server.utils import get_host_port_from_stream_address
|
||||
from bsread import source, SUB
|
||||
import subprocess
|
||||
import h5py
|
||||
from time import sleep
|
||||
from threading import Thread
|
||||
from datetime import datetime
|
||||
|
||||
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'))
|
||||
from detector_integration_api import DetectorIntegrationClient
|
||||
except:
|
||||
print('NB: detector integration could not be imported!')
|
||||
|
||||
|
||||
_cameraArrayTypes = ['monochrome','rgb']
|
||||
|
||||
class CameraCA:
|
||||
def __init__(self, pvname, cameraArrayType='monochrome',elog=None):
|
||||
self.Id = pvname
|
||||
self.isBS = False
|
||||
self.px_height = None
|
||||
self.px_width = None
|
||||
self.elog = elog
|
||||
|
||||
def get_px_height(self):
|
||||
if not self.px_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')
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
""" Adjustable convention"""
|
||||
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)
|
||||
|
||||
#/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):
|
||||
self._stream_host = host
|
||||
self._stream_port = port
|
||||
|
||||
def checkServer(self):
|
||||
# Check if your instance is running on the server.
|
||||
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):
|
||||
data = []
|
||||
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)
|
||||
return data
|
||||
|
||||
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:
|
||||
|
||||
input_stream.connect()
|
||||
|
||||
for n in range(N_images):
|
||||
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
|
||||
|
||||
class FeDigitizer:
|
||||
def __init__(self,Id,elog=None):
|
||||
self.Id = Id
|
||||
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']
|
||||
|
||||
def set_bias(self, value):
|
||||
self._bias.put(value)
|
||||
|
||||
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):
|
||||
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))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# class JF:
|
||||
# def __init__(self, Id):
|
||||
# self.writer_config = ""
|
||||
# self.backend_config = ""
|
||||
# self.detector_config = ""
|
||||
# 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",
|
||||
# "exptime": 0.000005,
|
||||
# "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",
|
||||
# "gain_corrections_dataset": "gains",
|
||||
# "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
|
||||
# while not running:
|
||||
# if self.get_status()['status'][-7:]=='RUNNING':
|
||||
# running = True
|
||||
# break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
#
|
||||
# def check_still_running(self,time_interval=.5):
|
||||
# cfg = self.get_config()
|
||||
# running = True
|
||||
# while running:
|
||||
# if not self.get_status()['status'][-7:]=='RUNNING':
|
||||
# running = False
|
||||
# break
|
||||
# else:
|
||||
# sleep(time_interval)
|
||||
#
|
||||
# def start(self):
|
||||
# self.client.start()
|
||||
# print("start acquisition")
|
||||
# pass
|
||||
#
|
||||
# def stop(self):
|
||||
# self.client.stop()
|
||||
# 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():
|
||||
# self.reset()
|
||||
# self.detector_config.update(dict(cycles=Npulses))
|
||||
# self.writer_config.update(dict(output_file=file_name))
|
||||
# self.set_config(f = file_name, N = Npulses)
|
||||
# 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:
|
||||
# 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
|
||||
|
||||
|
||||
# class DIAClient:
|
||||
# def __init__(self, Id, api_address = "http://sf-daq-2:10000"):
|
||||
# self._api_address = api_address
|
||||
# self.client = DetectorIntegrationClient(api_address)
|
||||
# print("\nDetector Integration API on %s" % api_address)
|
||||
# # No pgroup by default
|
||||
# self.pgroup = 0
|
||||
# self.n_frames = 100
|
||||
# self.jf_name = "JF 4.5M"
|
||||
# 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,
|
||||
# "n_frames": self.n_frames,
|
||||
# "general/user": str(self.pgroup),
|
||||
# "general/process": __name__,
|
||||
# "general/created": str(datetime.now()),
|
||||
# "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",
|
||||
# #"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_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_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,
|
||||
# "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,
|
||||
# "general/user": str(self.pgroup),
|
||||
# "general/process": __name__,
|
||||
# "general/created": str(datetime.now()),
|
||||
# "general/instrument": self.jf_name,
|
||||
# #'Npulses':100,
|
||||
# #'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
|
||||
# while 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
|
||||
# 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"],
|
||||
# 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")
|
||||
# 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"
|
||||
# file_name_bsread = "/dev/null"
|
||||
# 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()
|
||||
# #self.detector_config.update({
|
||||
# # 'cycles': n_frames})
|
||||
# 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.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':
|
||||
# done = True
|
||||
# if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
# done = True
|
||||
# if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
# done = True
|
||||
# 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):
|
||||
self.Id = Id
|
||||
self._api_address = api_address
|
||||
self.client = DetectorIntegrationClient(api_address)
|
||||
print("\nDetector Integration API on %s" % api_address)
|
||||
# No pgroup by default
|
||||
self.pgroup = 0
|
||||
self.n_frames = 100
|
||||
self.jf_name = jf_name
|
||||
self.pede_file = ""
|
||||
self.gain_file = ""
|
||||
self.instrument = instrument
|
||||
if instrument is None:
|
||||
print("ERROR: please configure the instrument parameter in DIAClient")
|
||||
self.update_config()
|
||||
|
||||
|
||||
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,
|
||||
"n_frames": self.n_frames,
|
||||
"general/user": str(self.pgroup),
|
||||
"general/process": __name__,
|
||||
"general/created": str(datetime.now()),
|
||||
"general/instrument": self.instrument,
|
||||
# "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",
|
||||
#"activate_corrections_preview": True,
|
||||
# FIXME: HARDCODED!!!
|
||||
"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_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_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["activate_corrections_preview"] = True
|
||||
else:
|
||||
self.backend_config["pede_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["gain_corrections_filename"] = ""
|
||||
self.backend_config["pede_corrections_filename"] = ""
|
||||
self.backend_config["activate_corrections_preview"] = False
|
||||
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
|
||||
# FIXME: HARDCODED
|
||||
"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/%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()),
|
||||
"general/instrument": self.instrument,
|
||||
#'Npulses':100,
|
||||
#'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/%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):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while 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
|
||||
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)
|
||||
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)
|
||||
|
||||
if update_config:
|
||||
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")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
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/%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'
|
||||
else:
|
||||
# FIXME hardcoded
|
||||
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.")
|
||||
|
||||
def acquire():
|
||||
self.n_frames = Npulses * JF_factor
|
||||
self.update_config()
|
||||
#self.detector_config.update({
|
||||
# 'cycles': n_frames})
|
||||
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.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':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
done = True
|
||||
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()
|
||||
Executable
+354
@@ -0,0 +1,354 @@
|
||||
import numpy as np
|
||||
from epics import caget
|
||||
from epics import PV
|
||||
from ..eco_epics.utilities_epics import EnumWrapper
|
||||
|
||||
from cam_server import PipelineClient
|
||||
from cam_server.utils import get_host_port_from_stream_address
|
||||
from bsread import source, SUB
|
||||
import subprocess
|
||||
import h5py
|
||||
from time import sleep
|
||||
from threading import Thread
|
||||
from datetime import datetime
|
||||
|
||||
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'))
|
||||
from detector_integration_api import DetectorIntegrationClient
|
||||
except:
|
||||
print('NB: detector integration could not be imported!')
|
||||
|
||||
|
||||
_cameraArrayTypes = ['monochrome','rgb']
|
||||
|
||||
class CameraCA:
|
||||
def __init__(self, pvname, cameraArrayType='monochrome',elog=None):
|
||||
self.Id = pvname
|
||||
self.isBS = False
|
||||
self.px_height = None
|
||||
self.px_width = None
|
||||
self.elog = elog
|
||||
|
||||
def get_px_height(self):
|
||||
if not self.px_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')
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
def gui(self, guiType='xdm'):
|
||||
""" Adjustable convention"""
|
||||
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)
|
||||
|
||||
#/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):
|
||||
self._stream_host = host
|
||||
self._stream_port = port
|
||||
|
||||
def checkServer(self):
|
||||
# Check if your instance is running on the server.
|
||||
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):
|
||||
data = []
|
||||
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)
|
||||
return data
|
||||
|
||||
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:
|
||||
|
||||
input_stream.connect()
|
||||
|
||||
for n in range(N_images):
|
||||
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
|
||||
|
||||
class FeDigitizer:
|
||||
def __init__(self,Id,elog=None):
|
||||
self.Id = Id
|
||||
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']
|
||||
|
||||
def set_bias(self, value):
|
||||
self._bias.put(value)
|
||||
|
||||
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):
|
||||
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))
|
||||
|
||||
|
||||
|
||||
class DIAClient:
|
||||
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.client = DetectorIntegrationClient(api_address)
|
||||
print("\nDetector Integration API on %s" % api_address)
|
||||
# No pgroup by default
|
||||
self.pgroup = 0
|
||||
self.n_frames = 100
|
||||
self.jf_name = jf_name
|
||||
self.pede_file = ""
|
||||
self.gain_file = ""
|
||||
self.instrument = instrument
|
||||
if instrument is None:
|
||||
print("ERROR: please configure the instrument parameter in DIAClient")
|
||||
self.update_config()
|
||||
|
||||
|
||||
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,
|
||||
"n_frames": self.n_frames,
|
||||
"general/user": str(self.pgroup),
|
||||
"general/process": __name__,
|
||||
"general/created": str(datetime.now()),
|
||||
"general/instrument": self.instrument,
|
||||
# "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",
|
||||
#"activate_corrections_preview": True,
|
||||
# FIXME: HARDCODED!!!
|
||||
"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_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_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["activate_corrections_preview"] = True
|
||||
else:
|
||||
self.backend_config["pede_corrections_dataset"] = "gains"
|
||||
self.backend_config["pede_mask_dataset"] = "pixel_mask"
|
||||
self.backend_config["gain_corrections_filename"] = ""
|
||||
self.backend_config["pede_corrections_filename"] = ""
|
||||
self.backend_config["activate_corrections_preview"] = False
|
||||
|
||||
self.detector_config = {
|
||||
"timing": "trigger",
|
||||
|
||||
# FIXME: HARDCODED
|
||||
"exptime": 0.000010,
|
||||
"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/%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()),
|
||||
"general/instrument": self.instrument,
|
||||
#'Npulses':100,
|
||||
#'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/%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):
|
||||
cfg = self.get_config()
|
||||
running = True
|
||||
while 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
|
||||
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)
|
||||
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)
|
||||
|
||||
if update_config:
|
||||
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")
|
||||
pass
|
||||
|
||||
def stop(self):
|
||||
self.client.stop()
|
||||
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/%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'
|
||||
else:
|
||||
# FIXME hardcoded
|
||||
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.")
|
||||
|
||||
def acquire():
|
||||
self.n_frames = Npulses * JF_factor
|
||||
self.update_config()
|
||||
#self.detector_config.update({
|
||||
# 'cycles': n_frames})
|
||||
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.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':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.BSREAD_STILL_RUNNING':
|
||||
done = True
|
||||
if stat['status'] == 'IntegrationStatus.INITIALIZED':
|
||||
done = True
|
||||
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()
|
||||
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ class MotorRecord:
|
||||
ll_name, hl_name = 'DLLM', 'DHLM'
|
||||
if relative_to_present:
|
||||
v = self.get_current_value(posType=posType)
|
||||
values = [v-values[0],v-values[1]]
|
||||
values = [v+values[0],v+values[1]]
|
||||
self._motor.put(ll_name,values[0])
|
||||
self._motor.put(hl_name,values[1])
|
||||
|
||||
@@ -224,15 +224,22 @@ class SmarActRecord:
|
||||
""" Adjustable convention"""
|
||||
return self._llm.get('VAL'), self._hlm.get('VAL')
|
||||
|
||||
# def gui(self, guiType='xdm'):
|
||||
# """ Adjustable convention"""
|
||||
# cmd = ['caqtdm','-macro']
|
||||
#
|
||||
# cmd.append('\"P=%s:,M=%s\"'%tuple(self.Id.split(':')))
|
||||
def gui(self, guiType='xdm'):
|
||||
""" Adjustable convention"""
|
||||
cmd = ['caqtdm','-macro']
|
||||
|
||||
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('motorx_more.ui')
|
||||
cmd.append('ESB_MX_SMARACT_mot_exp.ui')
|
||||
# #os.system(' '.join(cmd))
|
||||
# return subprocess.Popen(' '.join(cmd),shell=True)
|
||||
return subprocess.Popen(' '.join(cmd),shell=True)
|
||||
|
||||
|
||||
|
||||
@@ -32,6 +32,31 @@ class EnumWrapper:
|
||||
|
||||
|
||||
|
||||
class MonitorAccumulator:
|
||||
def __init__(self,pv,attr=None,keywords=['value','timestamp']):
|
||||
self.pv = pv
|
||||
self.attr = attr
|
||||
self.values = []
|
||||
self.keywords = keywords
|
||||
|
||||
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)
|
||||
|
||||
def stop(self):
|
||||
self.pv.remove_callbacks(self.attr)
|
||||
|
||||
def cycle(self):
|
||||
self.stop()
|
||||
d = self.values.copy()
|
||||
self.values = []
|
||||
self.accumulate()
|
||||
return d
|
||||
|
||||
|
||||
|
||||
|
||||
class Positioner:
|
||||
def __init__(self,list_of_name_func_tuples):
|
||||
Executable → Regular
Executable
Executable
+129
@@ -0,0 +1,129 @@
|
||||
import sys
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
class huber:
|
||||
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')
|
||||
|
||||
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())
|
||||
|
||||
def __repr__(self):
|
||||
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):
|
||||
self.Id = Id
|
||||
|
||||
### Owis linear stages ###
|
||||
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())
|
||||
|
||||
def __repr__(self):
|
||||
return "{'Crystal 1': %s, 'Crystal 2': %s}" % (self.cry1.wm(),self.cry2.wm())
|
||||
|
||||
class table:
|
||||
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')
|
||||
|
||||
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())
|
||||
|
||||
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())
|
||||
|
||||
class microscope:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
### Microscope motors ###
|
||||
self.focus = MotorRecord(Id+':FOCUS')
|
||||
self.zoom = MotorRecord(Id+':ZOOM')
|
||||
self._smaractaxes = {
|
||||
'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())
|
||||
|
||||
def __repr__(self):
|
||||
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__()
|
||||
@@ -0,0 +1,35 @@
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
|
||||
class XTG:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
|
||||
### sample smaract motors ###
|
||||
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')
|
||||
### grating 2 motors ###
|
||||
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'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
@@ -10,8 +10,8 @@ class GPS:
|
||||
|
||||
### motors heavy load gps table ###
|
||||
self.xhl = MotorRecord(Id+':MOT_TBL_TX')
|
||||
self.yhl = MotorRecord(Id+':MOT_TBL_TZ')
|
||||
self.zhl = MotorRecord(Id+':MOT_TBL_TY')
|
||||
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')
|
||||
Executable
@@ -0,0 +1,20 @@
|
||||
|
||||
|
||||
class Hexapod_PI:
|
||||
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']
|
||||
|
||||
|
||||
|
||||
Executable
@@ -2,21 +2,29 @@
|
||||
from ..aliases.alvra import elog as _elog_info
|
||||
from ..utilities.elog import Elog as _Elog
|
||||
from ..utilities.elog import Screenshot as _Screenshot
|
||||
from ..utilities.newMsgPV import stationMessage as _stationMessage
|
||||
from ..utilities.config import loadConfig
|
||||
from epics import PV
|
||||
import sys,os
|
||||
|
||||
|
||||
from colorama import Fore as _color
|
||||
import traceback
|
||||
import datetime
|
||||
import sys
|
||||
|
||||
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')
|
||||
#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='.')
|
||||
@@ -94,7 +102,7 @@ if len(errors)>0:
|
||||
traceback.print_tb(error[1].__traceback__)
|
||||
|
||||
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
@@ -114,18 +122,27 @@ def parseChannelListFile(fina):
|
||||
|
||||
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'))
|
||||
|
||||
bsdaq = BStools(default_channel_list=channellist,default_file_path='%s')
|
||||
bsdaqPhotonDiag = BStools(default_channel_list=channellistPhotonDiag,default_file_path='%s')
|
||||
|
||||
from eco.devices_general.alvradetectors import JF_BS_writer
|
||||
JF_4p5M = JF_BS_writer('JF_4p5M', api_address = "http://sf-daq-2:10000")
|
||||
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')
|
||||
|
||||
@@ -136,7 +153,6 @@ def checker_function(limits):
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
checker = {}
|
||||
checker['checker_call'] = checker_function
|
||||
checker['args'] = [[100,300]]
|
||||
@@ -144,17 +160,15 @@ checker['kwargs'] = {}
|
||||
checker['wait_time'] = 3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#CJM scansJF = _scan.Scans(data_base_dir='/sf/alvra/config/com/data/scan_data',scan_info_dir='/sf/alvra/config/com/data/scan_info',default_counters=[JF_4p5M],checker=checker)
|
||||
|
||||
|
||||
|
||||
|
||||
#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])
|
||||
from ..timing.alvralasertiming import Lxt as _Lxt
|
||||
|
||||
########### ADHOC IMPLEMENTED ########################
|
||||
from ..timing.alvralasertiming import Lxt as _Lxt
|
||||
lxt = _Lxt()
|
||||
|
||||
from ..xoptics.dcm import AlvraDCM_FEL
|
||||
monoFEL = AlvraDCM_FEL('SAROP11-ODCM105')
|
||||
@@ -2,7 +2,9 @@
|
||||
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
|
||||
@@ -11,8 +13,14 @@ 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='.')
|
||||
@@ -34,6 +42,7 @@ def _attach_device(devDict,devId,args,kwargs):
|
||||
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
|
||||
|
||||
@@ -65,6 +74,7 @@ if len(errors)>0:
|
||||
|
||||
|
||||
|
||||
########### DAQ SECTION ########################
|
||||
# configuring bs daq
|
||||
|
||||
def parseChannelListFile(fina):
|
||||
@@ -87,17 +97,23 @@ 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'))
|
||||
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/default_channels/default_channel_list_ioxos'))
|
||||
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')
|
||||
#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')
|
||||
|
||||
@@ -111,15 +127,41 @@ def checker_function(limits):
|
||||
|
||||
checker = {}
|
||||
checker['checker_call'] = checker_function
|
||||
checker['args'] = [[100,300]]
|
||||
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='/sf/bernina/config/com/data/scan_data',scan_info_dir='/sf/bernina/config/com/data/scan_info',default_counters=[bsdaqJF],checker=checker)
|
||||
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']
|
||||
@@ -0,0 +1,114 @@
|
||||
|
||||
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()
|
||||
@@ -0,0 +1,66 @@
|
||||
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
|
||||
|
||||
Executable
Executable
+126
@@ -0,0 +1,126 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
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
|
||||
|
||||
class Laser_Exp:
|
||||
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')
|
||||
|
||||
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')
|
||||
self.lam_delayTime = DelayStage(self.lam_delay)
|
||||
#
|
||||
# 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')
|
||||
self.palm_delayTime = DelayStage(self.palm_delay)
|
||||
|
||||
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')
|
||||
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')
|
||||
self.psen_autocorr_delayTime = DelayStage(self.pump_autocorr_delay)
|
||||
|
||||
#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'
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
# try:
|
||||
# self.eos_rot = SmarActRecord(self.IdSA+'-ESB18')
|
||||
# except:
|
||||
# print('No Smaract EOSrot')
|
||||
# pass
|
||||
|
||||
# try:
|
||||
# self.eos_gonio = SmarActRecord(self.IdSA+'-ESB3')
|
||||
# except:
|
||||
# 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.)
|
||||
# except:
|
||||
# print('No Smaract THzrot')
|
||||
# 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'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
|
||||
#def pos(self):
|
||||
# s = []
|
||||
# for i in sorted(self.__dict__.keys()):
|
||||
# s.append[i]
|
||||
# for n, mo^tor in enumerate (s):
|
||||
# s[n] += ': ' + str(self.__dict__[motor])
|
||||
# return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
from epics import caput, caget
|
||||
|
||||
class laser_shutter:
|
||||
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 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)
|
||||
|
||||
Executable
+109
@@ -0,0 +1,109 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
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
|
||||
|
||||
class Laser_Exp:
|
||||
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+'-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')
|
||||
self.lam_delay_Smar = DelayStage(self._lam_delayStg_Smar)
|
||||
|
||||
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')
|
||||
self.palm_delay = DelayStage(self._palm_delayStg)
|
||||
|
||||
#PSEN delay stages
|
||||
#self._psen_delayStg = MotorRecord(self.Id+'')
|
||||
#self.psen_delay = DelayStage(self._pump_delayStg)
|
||||
|
||||
#SmarAct ID
|
||||
self.IdSA = 'SARES23'
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
try:
|
||||
self.eos_rot = SmarActRecord(self.IdSA+'-ESB18')
|
||||
except:
|
||||
print('No Smaract EOSrot')
|
||||
pass
|
||||
|
||||
try:
|
||||
self.eos_gonio = SmarActRecord(self.IdSA+'-ESB3')
|
||||
except:
|
||||
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.)
|
||||
except:
|
||||
print('No Smaract THzrot')
|
||||
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 = '*****SmarAct motor positions******\n'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
|
||||
#def pos(self):
|
||||
# s = []
|
||||
# for i in sorted(self.__dict__.keys()):
|
||||
# s.append[i]
|
||||
# for n, mo^tor in enumerate (s):
|
||||
# s[n] += ': ' + str(self.__dict__[motor])
|
||||
# return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
# Sun Jun 3 20:42:08 2018
|
||||
0.001996429730000
|
||||
@@ -0,0 +1,2 @@
|
||||
# Sun Jun 3 20:42:08 2018
|
||||
0.001996429730000
|
||||
@@ -0,0 +1,2 @@
|
||||
# Sun Jun 3 20:42:08 2018
|
||||
0.000000008499738
|
||||
@@ -5,7 +5,7 @@ import time
|
||||
from ..devices_general.utilities import Changer
|
||||
|
||||
|
||||
_basefolder = "/sf/bernina/config/com/data/src/lasertiming"
|
||||
_basefolder = "/sf/bernina/config/src/python/eco/timing"
|
||||
|
||||
def timeToStr(value,n=12):
|
||||
fmt = "%%+.%df" % n
|
||||
@@ -43,6 +43,7 @@ def niceTimeToStr(delay,fmt="%+.0f"):
|
||||
|
||||
|
||||
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)
|
||||
self.pvname = pvname
|
||||
@@ -79,11 +80,11 @@ class Storage(object):
|
||||
|
||||
|
||||
class Pockels_trigger(PV):
|
||||
""" this class is needed to store the offset in files and read in s """
|
||||
def __init__(self,pv_basename):
|
||||
pvname = pv_basename + "-RB"
|
||||
def __init__(self, pv_get, pv_set, pv_offset_get=None):
|
||||
pvname = pv_get
|
||||
PV.__init__(self,pvname)
|
||||
self._pv_setvalue = PV(pv_basename + "-SP")
|
||||
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)
|
||||
|
||||
@@ -91,7 +92,7 @@ class Pockels_trigger(PV):
|
||||
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)+self._pv_offset_get.get()*1e-9 - 7.41e-9
|
||||
|
||||
def get(self):
|
||||
""" convert time to sec """
|
||||
@@ -171,8 +172,16 @@ class Phase_shifter(PV):
|
||||
return "Phase Shifter: user,dial = %s , %s"%(user,dial)
|
||||
|
||||
|
||||
_slicer_gate = Pockels_trigger("SLAAR-LTIM02-EVR0:Pul3-Delay")
|
||||
_sdg1 = Pockels_trigger("SLAAR-LTIM02-EVR0:Pul2-Delay")
|
||||
_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")
|
||||
|
||||
_phase_shifter = Phase_shifter("SLAAR02-TSPL-EPL")
|
||||
|
||||
|
||||
@@ -199,6 +208,7 @@ class Lxt(object):
|
||||
|
||||
def set(self,value):
|
||||
self.phase_shifter.set(value)
|
||||
self.slicer_gate.set(-value)
|
||||
self.sdg1.set(-value)
|
||||
|
||||
def get(self):
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
class Palm:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
self._delayStg = MotorRecord(self.Id+'-M552:MOT')
|
||||
self.delay = DelayStage(self._delayStg)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****Palm motor positions******\n'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
class Psen:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
self._delayStg = MotorRecord(self.Id+'-M561:MOT')
|
||||
self.delay = DelayStage(self._delayStg)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****PSEN motor positions******\n'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
import numpy as np
|
||||
from matplotlib import pylab as plt
|
||||
|
||||
def readTraceTextfile(fina,numbers=None):
|
||||
if not numbers is None:
|
||||
d = [readTraceTextfile(fina%number) for number in numbers]
|
||||
else:
|
||||
d = np.loadtxt(fina, skiprows=5, delimiter=',')
|
||||
return d
|
||||
|
||||
def getRiseTime(t,s,lims=[.1,.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])
|
||||
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]
|
||||
|
||||
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')
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
import json
|
||||
|
||||
def loadConfig(fina):
|
||||
with open(fina,'r') as f:
|
||||
return json.load(f)
|
||||
|
||||
def writeConfig(fina,obj):
|
||||
with open(fina,'w') as f:
|
||||
json.dump(obj,f)
|
||||
@@ -0,0 +1,9 @@
|
||||
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"
|
||||
|
||||
|
||||
|
||||
Executable
Executable
+48
@@ -0,0 +1,48 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
class palm:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
self.delay = MotorRecord(self.Id+'-M423:MOT')
|
||||
self.delayTime = 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'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
class eo:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
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'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
Executable
+26
@@ -0,0 +1,26 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from ..devices_general.delay_stage import DelayStage
|
||||
|
||||
class psen:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
self.delay = MotorRecord(self.Id+'-M424:MOT')
|
||||
self.delayTime = DelayStage(self.delay)
|
||||
|
||||
|
||||
def get_adjustable_positions_str(self):
|
||||
ostr = '*****PSEN motor positions******\n'
|
||||
|
||||
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
|
||||
return ostr
|
||||
|
||||
|
||||
def __repr__(self):
|
||||
return self.get_adjustable_positions_str()
|
||||
|
||||
Executable
+39
@@ -0,0 +1,39 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
class KBhor:
|
||||
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]
|
||||
|
||||
|
||||
#### 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')
|
||||
|
||||
|
||||
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 += "\n**Stages**\n"
|
||||
stages = "_Y1 _Y2 _Y3 _X1 _X2".split()
|
||||
for stage in stages:
|
||||
s+= " - %s = %.4f\n" %(stage, getattr(self,stage).wm())
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
@@ -1,7 +1,7 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
class KB:
|
||||
class KBver:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
|
||||
@@ -15,12 +15,23 @@ class KB:
|
||||
|
||||
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')
|
||||
|
||||
def __str__(self):
|
||||
s = "**KB mirror**\n\n"
|
||||
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())
|
||||
return "KB is %s"%self.mode.lower()
|
||||
s += "\n**Stages**\n"
|
||||
stages = "_Y1 _Y2 _Y3 _X1 _X2".split()
|
||||
for stage in stages:
|
||||
s+= " - %s = %.4f\n" %(stage, getattr(self,stage).wm())
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
Executable
+238
@@ -0,0 +1,238 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
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):
|
||||
self.energy_sp.put(value)
|
||||
while abs(self.wait_for_valid_value()-value)>precision:
|
||||
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=self.stop)
|
||||
|
||||
def stop(self):
|
||||
self._stop.put(1)
|
||||
|
||||
def get_current_value(self):
|
||||
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):
|
||||
|
||||
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)
|
||||
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())
|
||||
pvs = "energy_rbk".split()
|
||||
for pv in pvs:
|
||||
s+= " - %s = %.4f\n" %(pv, getattr(self,pv).value)
|
||||
return s
|
||||
|
||||
def __repr__(self):
|
||||
return self.__str__()
|
||||
|
||||
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'):
|
||||
self.Id = Id
|
||||
self.setter = PV(val)
|
||||
self.readback = PV(rb)
|
||||
self.dmov = PV(dmov)
|
||||
self.done = False
|
||||
|
||||
def get_current_value(self):
|
||||
return self.readback.get()
|
||||
|
||||
def move_and_wait(self,value,checktime=.01,precision=2):
|
||||
curr = self.setter.get()
|
||||
while abs(curr-value)>0.1:
|
||||
curr = self.setter.get()
|
||||
self.setter.put(curr + np.sign(value-curr)*.1)
|
||||
sleep(0.3)
|
||||
|
||||
self.setter.put(value)
|
||||
while abs(self.get_current_value() - value)>precision:
|
||||
sleep(checktime)
|
||||
while not self.dmov.get():
|
||||
#print(self.dmov.get())
|
||||
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)
|
||||
|
||||
|
||||
class MonoEcolEnergy:
|
||||
def __init__(self,Id):
|
||||
self.Id = Id
|
||||
self.name = 'energy_collimator'
|
||||
self.dcm = Double_Crystal_Mono(Id)
|
||||
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))]
|
||||
for tc in ch:
|
||||
tc.wait()
|
||||
|
||||
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)
|
||||
|
||||
def alignOffsets(self):
|
||||
mrb = self.dcm.get_current_value()
|
||||
erb = self.ecol.get_current_value()
|
||||
self.offset = {'dcm':mrb, 'ecol':erb}
|
||||
|
||||
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 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__()
|
||||
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ class OffsetMirror:
|
||||
def out(self):
|
||||
pass
|
||||
|
||||
def in(self):
|
||||
def move_in(self):
|
||||
pass
|
||||
|
||||
|
||||
Executable
+48
@@ -0,0 +1,48 @@
|
||||
from epics import PV
|
||||
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')
|
||||
|
||||
|
||||
def stop(self):
|
||||
self._stop.put(0)
|
||||
print("Stopped Pulse Picker")
|
||||
|
||||
def start(self):
|
||||
self._start.put(0)
|
||||
print("Started Pulse Picker")
|
||||
|
||||
def cycles(self, n):
|
||||
self._cycles.put(n)
|
||||
|
||||
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()))
|
||||
self.start()
|
||||
sleep(sleeptime)
|
||||
self.stop()
|
||||
print('done')
|
||||
|
||||
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()))
|
||||
self.start()
|
||||
sleep(sleeptime)
|
||||
self.stop()
|
||||
print('done')
|
||||
|
||||
@@ -44,7 +44,9 @@ class SlitBlades:
|
||||
self.set_vg(height)
|
||||
|
||||
def __repr__(self):
|
||||
return '(%s,%s) mm'%(self.get_hg(),self.get_vg())
|
||||
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:
|
||||
@@ -103,7 +105,9 @@ class SlitFourBlades:
|
||||
self.set_vg(height)
|
||||
|
||||
def __str__(self):
|
||||
return '(%g,%g) mm'%(self.get_hg(),self.get_vg())
|
||||
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__()
|
||||
@@ -146,4 +150,6 @@ class SlitPosWidth:
|
||||
self.set_vg(height)
|
||||
|
||||
def __repr__(self):
|
||||
return '(%s,%s) mm'%(self.get_hg(),self.get_vg())
|
||||
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))
|
||||
@@ -0,0 +1,2 @@
|
||||
from . import materials
|
||||
|
||||
+1124
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,90 @@
|
||||
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)])
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
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))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
import numpy as np
|
||||
from scipy import constants
|
||||
import xraylib as xl
|
||||
|
||||
|
||||
def cartesian(arrays, out=None):
|
||||
"""
|
||||
Generate a cartesian product of input arrays.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
arrays : list of array-like
|
||||
1-D arrays to form the cartesian product of.
|
||||
out : ndarray
|
||||
Array to place the cartesian product in.
|
||||
|
||||
Returns
|
||||
-------
|
||||
out : ndarray
|
||||
2-D array of shape (M, len(arrays)) containing cartesian products
|
||||
formed of input arrays.
|
||||
|
||||
Examples
|
||||
--------
|
||||
>>> cartesian(([1, 2, 3], [4, 5], [6, 7]))
|
||||
array([[1, 4, 6],
|
||||
[1, 4, 7],
|
||||
[1, 5, 6],
|
||||
[1, 5, 7],
|
||||
[2, 4, 6],
|
||||
[2, 4, 7],
|
||||
[2, 5, 6],
|
||||
[2, 5, 7],
|
||||
[3, 4, 6],
|
||||
[3, 4, 7],
|
||||
[3, 5, 6],
|
||||
[3, 5, 7]])
|
||||
|
||||
"""
|
||||
|
||||
arrays = [np.asarray(x) for x in arrays]
|
||||
dtype = arrays[0].dtype
|
||||
|
||||
n = np.prod([x.size for x in arrays])
|
||||
if out is None:
|
||||
out = np.zeros([n, len(arrays)], dtype=dtype)
|
||||
|
||||
m = n / arrays[0].size
|
||||
out[:,0] = np.repeat(arrays[0], m)
|
||||
if arrays[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:]
|
||||
return out
|
||||
|
||||
def E2lam(energy):
|
||||
"""energy in eV, lambda in Ångstrøm"""
|
||||
return constants.h*constants.c/constants.e / energy *1e10
|
||||
|
||||
def QE2theta(Q,energy):
|
||||
"""Q in Å**(-1), energy in eV, theta in radians"""
|
||||
return np.arcsin(E2lam(energy)/4/np.pi*Q)
|
||||
|
||||
|
||||
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))
|
||||
@@ -1,77 +0,0 @@
|
||||
import sys
|
||||
sys.path.append("..")
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
|
||||
class huber:
|
||||
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')
|
||||
|
||||
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())
|
||||
|
||||
def __repr__(self):
|
||||
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):
|
||||
self.Id = Id
|
||||
|
||||
### Owis linear stages ###
|
||||
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())
|
||||
|
||||
def __repr__(self):
|
||||
return "{'Crystal 1': %s, 'Crystal 2': %s}" % (self.cry1.wm(),self.cry2.wm())
|
||||
|
||||
class table:
|
||||
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')
|
||||
|
||||
def __str__(self):
|
||||
return "Table positions\nx1: %s mm\ny1: %s mm\ny2: %s\ny3: %s mm\nz1: %s mm\nz2: %s mm" \
|
||||
% (self.x1.wm(),self.y1.wm(),self.y2.wm(),self.y3.wm(),self.z1.wm(),self.z2.wm())
|
||||
|
||||
def __repr__(self):
|
||||
return "{'x1': %s, 'y1': %s,'y2': %s,'y3': %s, 'z1': %s, 'z2': %s}" \
|
||||
% (self.x1,self.y1,self.y2,self.y3,self.z1,self.z2)
|
||||
|
||||
class microscope:
|
||||
def __init__(self,Id,alias_namespace=None):
|
||||
self.Id = Id
|
||||
|
||||
### Microscope motors ###
|
||||
self.focus = MotorRecord(Id+':FOCUS')
|
||||
self.zoom = MotorRecord(Id+':ZOOM')
|
||||
self._smaractaxes = {
|
||||
'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())
|
||||
|
||||
def __repr__(self):
|
||||
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
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from ..devices_general.smaract import SmarActRecord
|
||||
from epics import PV
|
||||
from .delay_stage import DelayStage
|
||||
|
||||
class Laser_Exp:
|
||||
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+'-M533:MOT')
|
||||
|
||||
#SmarAct ID
|
||||
self.IdSA = 'SARES23'
|
||||
self._delayStg = SmarActRecord(self.IdSA+'-ESB17')
|
||||
self.eos_delay = DelayStage(self._delayStg)
|
||||
|
||||
|
||||
### Mirrors used in the expeirment ###
|
||||
try:
|
||||
self.eos_rot = SmarActRecord(self.IdSA+'-ESB18')
|
||||
except:
|
||||
print('No Smaract EOSrot')
|
||||
pass
|
||||
|
||||
try:
|
||||
self.eos_gonio = SmarActRecord(self.IdSA+'-ESB3')
|
||||
except:
|
||||
print('No Smaract EOSGonio')
|
||||
pass
|
||||
|
||||
try:
|
||||
self.thz_rot = SmarActRecord(self.IdSA+'-ESB16')
|
||||
except:
|
||||
print('No Smaract THzrot')
|
||||
pass
|
||||
|
||||
try:
|
||||
self.thz_gonio = SmarActRecord(self.IdSA+'-ESB2')
|
||||
except:
|
||||
print('No Smaract THzGonio')
|
||||
pass
|
||||
|
||||
try:
|
||||
self.thz_z = 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
|
||||
@@ -0,0 +1,20 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
VERSION = (0, 0, 1)
|
||||
VERSION_STR = ".".join([str(x) for x in VERSION])
|
||||
|
||||
setup(
|
||||
name='eco',
|
||||
version=VERSION_STR,
|
||||
description="Eco ...",
|
||||
long_description="Eco ../",
|
||||
author='Paul Scherrer Institute',
|
||||
author_email='@psi.ch',
|
||||
url='https://github.com/paulscherrerinstitute/eco',
|
||||
packages=find_packages(),
|
||||
requires=['numpy', 'xrayutilities', 'xraylib'],
|
||||
|
||||
)
|
||||
@@ -1,79 +0,0 @@
|
||||
from ..devices_general.motors import MotorRecord
|
||||
from epics import PV
|
||||
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):
|
||||
self.energy_sp.put(value)
|
||||
while abs(self.wait_for_valid_value()-value)>precision:
|
||||
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=self.stop)
|
||||
|
||||
def stop(self):
|
||||
self._stop.put(1)
|
||||
|
||||
def get_current_value(self):
|
||||
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):
|
||||
|
||||
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)
|
||||
def wait(self):
|
||||
self._currentChange.wait()
|
||||
|
||||
# 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)
|
||||
Reference in New Issue
Block a user