Sessions
This commit is contained in:
@@ -1,34 +1,45 @@
|
||||
#Thu Feb 13 11:01:45 CET 2020
|
||||
autoSaveScanData=true
|
||||
simulation=false
|
||||
commandExecutionEvents=false
|
||||
logDaysToLive=7
|
||||
userAuthenticator=
|
||||
logLevelConsole=Off
|
||||
scanStreamerPort=-1
|
||||
parallelInitialization=false
|
||||
versionTrackingManual=true
|
||||
#Thu May 20 15:37:42 CEST 2021
|
||||
hostName=null
|
||||
userManagement=false
|
||||
instanceName=MicroXAS
|
||||
disableEmbeddedAttributes=true
|
||||
autoSaveScanData=true
|
||||
simulation=false
|
||||
dataServerPort=-1
|
||||
serverPort=8080
|
||||
hideServerMessages=false
|
||||
versionTrackingEnabled=true
|
||||
dataPath={data}/{year}_{month}/{date}/{date}{time}_{name}
|
||||
serverEnabled=false
|
||||
commandExecutionEvents=false
|
||||
logDaysToLive=7
|
||||
dataScanReleaseRecords=false
|
||||
depthDimension=0
|
||||
dataScanPreserveTypes=false
|
||||
dataScanSaveOutput=false
|
||||
logLevel=Info
|
||||
dataScanFlushRecords=true
|
||||
logPath={logs}/{date}_{time}
|
||||
dataLayout=fda
|
||||
disableDataFileLogs=false
|
||||
sessionHandling=On
|
||||
terminalEnabled=false
|
||||
notificationLevel=Off
|
||||
userAuthenticator=
|
||||
logLevelConsole=Off
|
||||
terminalPort=3579
|
||||
scanStreamerPort=-1
|
||||
dataScanSaveScript=false
|
||||
dataTransferUser=
|
||||
dataScanSaveSetpoints=false
|
||||
notifiedTasks=null
|
||||
parallelInitialization=false
|
||||
dataTransferPath=
|
||||
createSessionFiles=false
|
||||
saveConsoleSessionFiles=false
|
||||
versionTrackingLogin={context}/svcusr-hlapp_robot
|
||||
versionTrackingManual=true
|
||||
versionTrackingRemote=git@git.psi.ch\:pshell_config/x05la.git
|
||||
dataProvider=fda
|
||||
dataTransferMode=Off
|
||||
saveCommandStatistics=false
|
||||
|
||||
11
config/scicat.properties
Normal file
11
config/scicat.properties
Normal file
@@ -0,0 +1,11 @@
|
||||
#Thu May 20 14:49:07 CEST 2021
|
||||
environment=prod
|
||||
testParameters=-testenv -user slssim\:slssim
|
||||
sourceFolder=.
|
||||
prodParameters=\ -user slssim\:slssim
|
||||
devParameters=-devenv -user slssim\:slssim
|
||||
ownerGroup=
|
||||
type=raw
|
||||
parameters=-ingest -allowexistingsource -noninteractive -autoarchive
|
||||
creationLocation=/PSI
|
||||
principalInvestigator=
|
||||
3
config/session_metadata.properties
Normal file
3
config/session_metadata.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
#Thu May 20 15:32:22 CEST 2021
|
||||
Energy=Double
|
||||
Sample=String
|
||||
3
config/sessions.properties
Normal file
3
config/sessions.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
#Thu May 20 14:45:31 CEST 2021
|
||||
SessionCounter=1
|
||||
CurrentSession=1
|
||||
@@ -1,2 +1,2 @@
|
||||
#Tue Jul 28 09:52:01 CEST 2020
|
||||
#Thu May 20 14:45:13 CEST 2021
|
||||
FdaBrowser=true
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
#Thu Feb 13 10:13:17 CET 2020
|
||||
scriptPath={home}/script
|
||||
#Wed May 19 14:57:57 CEST 2021
|
||||
sessionsPath={outp}/sessions
|
||||
scriptPath={home}/script
|
||||
pluginsPath={home}/plugins
|
||||
configFileDevices={config}/devices.properties
|
||||
consoleSessionsPath={sessions}/console
|
||||
libraryPath={script}; {script}/Lib
|
||||
configFilePlugins={config}/plugins.properties
|
||||
contextPath={outp}/context
|
||||
extensionsPath={home}/extensions
|
||||
configPath={home}/config
|
||||
configFileSessions={config}/sessions.properties
|
||||
userSessionsPath={sessions}/user
|
||||
dataPath={outp}/data
|
||||
devicesPath={home}/devices
|
||||
configFileVariables={config}/variables.properties
|
||||
|
||||
1
config/tasks.properties
Normal file
1
config/tasks.properties
Normal file
@@ -0,0 +1 @@
|
||||
Tasks/DetectorsCheck=10.0
|
||||
@@ -1,2 +1,3 @@
|
||||
#Thu Feb 27 09:28:05 CET 2020
|
||||
FileSequentialNumber=20
|
||||
#Thu May 20 15:37:42 CEST 2021
|
||||
FileSequentialNumber=24
|
||||
DaySequentialNumber=0
|
||||
|
||||
515
script/Devices/Eiger.py
Normal file
515
script/Devices/Eiger.py
Normal file
@@ -0,0 +1,515 @@
|
||||
"""
|
||||
class DEigerClient provides an interface to the EIGER API
|
||||
|
||||
Author: Volker Pilipp
|
||||
Contact: support@dectris.com
|
||||
Version: 1.0
|
||||
Date: 13/11/2014
|
||||
Copyright See General Terms and Conditions (GTC) on http://www.dectris.com
|
||||
|
||||
"""
|
||||
|
||||
import base64
|
||||
import os.path
|
||||
import httplib
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
import socket
|
||||
import fnmatch
|
||||
|
||||
Version = '1.6.0'
|
||||
|
||||
class DEigerClient(object):
|
||||
"""
|
||||
class DEigerClient provides a low level interface to the EIGER API
|
||||
"""
|
||||
|
||||
def __init__(self, host = '127.0.0.1', port = 80, verbose = False, urlPrefix = None, user = None):
|
||||
"""
|
||||
Create a client object to talk to the EIGER API.
|
||||
Args:
|
||||
host: hostname of the detector computer
|
||||
port: port usually 80 (http)
|
||||
verbose: bool value
|
||||
urlPrefix: String prepended to the urls. Should be None.
|
||||
user: "username:password". Should be None.
|
||||
"""
|
||||
super(DEigerClient,self).__init__()
|
||||
self._host = host
|
||||
self._port = port
|
||||
self._version = Version
|
||||
self._verbose = verbose
|
||||
self._urlPrefix = ""
|
||||
self._user = None
|
||||
self._connectionTimeout = 900
|
||||
self._connection = httplib.HTTPConnection(self._host,self._port, timeout = self._connectionTimeout)
|
||||
|
||||
self.setUrlPrefix(urlPrefix)
|
||||
self.setUser(user)
|
||||
|
||||
def setVerbose(self,verbose):
|
||||
""" Switch verbose mode on and off.
|
||||
Args:
|
||||
verbose: bool value
|
||||
"""
|
||||
self._verbose = bool(verbose)
|
||||
|
||||
def setConnectionTimeout(self, timeout):
|
||||
"""
|
||||
If DEigerClient has not received an reply from EIGER after
|
||||
timeout seconds, the request is aborted. timeout should be at
|
||||
least as long as the triggering command takes.
|
||||
Args:
|
||||
timeout timeout in seconds
|
||||
"""
|
||||
self._connectionTimeout = timeout
|
||||
|
||||
def setUrlPrefix(self, urlPrefix):
|
||||
"""Set url prefix, which is the string that is prepended to the
|
||||
urls. There is usually no need to call the command explicitly.
|
||||
Args:
|
||||
urlPrefix: String
|
||||
"""
|
||||
if urlPrefix is None:
|
||||
self._urlPrefix = ""
|
||||
else:
|
||||
self._urlPrefix = str(urlPrefix)
|
||||
if len(self._urlPrefix) > 0 and self._urlPrefix[-1] != "/":
|
||||
self._urlPrefix += "/"
|
||||
|
||||
def setUser(self, user):
|
||||
"""
|
||||
Set username and password for basic authentication.
|
||||
There is usually no need to call the command explicitly.
|
||||
Args:
|
||||
user: String of the form username:password
|
||||
"""
|
||||
if user is None:
|
||||
self._user = None
|
||||
else:
|
||||
self._user = base64.encodestring(user).replace('\n', '')
|
||||
|
||||
|
||||
|
||||
def version(self,module = 'detector'):
|
||||
"""Get version of a api module (i.e. 'detector', 'filewriter')
|
||||
Args:
|
||||
module: 'detector' or 'filewriter'
|
||||
"""
|
||||
return self._getRequest(url = '/{0}{1}/api/version/'.format(self._urlPrefix,module))
|
||||
|
||||
def listDetectorConfigParams(self):
|
||||
"""Get list of all detector configuration parameters (param arg of configuration() and setConfiguration()).
|
||||
Convenience function, that does detectorConfig(param = 'keys')
|
||||
Returns:
|
||||
List of parameters.
|
||||
"""
|
||||
return self.detectorConfig('keys')
|
||||
|
||||
def detectorConfig(self,param = None, dataType = None):
|
||||
"""Get detector configuration parameter
|
||||
Args:
|
||||
param: query the configuration parameter param, if None get full configuration, if 'keys' get all configuration parameters.
|
||||
dataType: None (= 'native'), 'native' ( return native python object) or 'tif' (return tif data).
|
||||
Returns:
|
||||
If param is None get configuration, if param is 'keys' return list of all parameters, else return the value of
|
||||
the parameter. If dataType is 'native' a dictionary is returned that may contain the keys: value, min, max,
|
||||
allowed_values, unit, value_type and access_mode. If dataType is 'tif', tiff formated data is returned as a python
|
||||
string.
|
||||
"""
|
||||
return self._getRequest(self._url('detector','config',param),dataType)
|
||||
|
||||
def setDetectorConfig(self, param, value, dataType = None):
|
||||
"""
|
||||
Set detector configuration parameter param.
|
||||
Args:
|
||||
param: Parameter
|
||||
value: Value to set. If dataType is 'tif' value may be a string containing the tiff data or
|
||||
a file object pointing to a tiff file.
|
||||
dataType: None, 'native' or 'tif'. If None, the data type is auto determined. If 'native' value
|
||||
may be a native python object (e.g. int, float, str), if 'tif' value shell contain a
|
||||
tif file (python string or file object to tif file).
|
||||
Returns:
|
||||
List of changed parameters.
|
||||
"""
|
||||
return self._putRequest(self._url('detector','config',param), dataType, value)
|
||||
|
||||
def setDetectorConfigMultiple(self,*params):
|
||||
"""
|
||||
Convenience function that calls setDetectorConfig(param,value,dataType = None) for
|
||||
every pair param, value in *params.
|
||||
Args:
|
||||
*params: List of successive params of the form param0, value0, param1, value1, ...
|
||||
The parameters are set in the same order they appear in *params.
|
||||
Returns:
|
||||
List of changed parameters.
|
||||
"""
|
||||
changeList = []
|
||||
p = None
|
||||
for x in params:
|
||||
if p is None:
|
||||
p = x
|
||||
else:
|
||||
data = x
|
||||
changeList += self.setDetectorConfig(param = p, value = data, dataType = None)
|
||||
p = None
|
||||
return list(set(changeList))
|
||||
|
||||
def listDetectorCommands(self):
|
||||
"""
|
||||
Get list of all commands that may be sent to Eiger via command().
|
||||
Returns:
|
||||
List of commands
|
||||
"""
|
||||
return self._getRequest(self._url('detector','command','keys'))
|
||||
|
||||
def sendDetectorCommand(self, command, parameter = None):
|
||||
"""
|
||||
Send command to Eiger. The list of all available commands is obtained via listCommands().
|
||||
Args:
|
||||
command: Detector command
|
||||
parameter: Call command with parameter. If command = "trigger" a float parameter may be passed
|
||||
Returns:
|
||||
The commands 'arm' and 'trigger' return a dictionary containing 'sequence id'.
|
||||
"""
|
||||
return self._putRequest(self._url('detector','command',command), dataType = 'native', data = parameter)
|
||||
|
||||
|
||||
def detectorStatus(self, param = 'keys'):
|
||||
"""Get detector status information
|
||||
Args:
|
||||
param: query the status parameter param, if 'keys' get all status parameters.
|
||||
Returns:
|
||||
If param is None get configuration, if param is 'keys' return list of all parameters, else return dictionary
|
||||
that may contain the keys: value, value_type, unit, time, state, critical_limits, critical_values
|
||||
"""
|
||||
return self._getRequest(self._url('detector','status',parameter = param))
|
||||
|
||||
|
||||
def fileWriterConfig(self,param = 'keys'):
|
||||
"""Get filewriter configuration parameter
|
||||
Args:
|
||||
param: query the configuration parameter param, if 'keys' get all configuration parameters.
|
||||
Returns:
|
||||
If param is None get configuration, if param is 'keys' return list of all parameters, else return dictionary
|
||||
that may contain the keys: value, min, max, allowed_values, unit, value_type and access_mode
|
||||
"""
|
||||
return self._getRequest(self._url('filewriter','config',parameter = param))
|
||||
|
||||
def setFileWriterConfig(self,param,value):
|
||||
"""
|
||||
Set file writer configuration parameter param.
|
||||
Args:
|
||||
param: parameter
|
||||
value: value to set
|
||||
Returns:
|
||||
List of changed parameters.
|
||||
"""
|
||||
return self._putRequest(self._url('filewriter','config',parameter = param), dataType = 'native', data = value)
|
||||
|
||||
def sendFileWriterCommand(self, command):
|
||||
"""
|
||||
Send filewriter command to Eiger.
|
||||
Args:
|
||||
command: Command to send (up to now only "clear")
|
||||
Returns:
|
||||
Empty string
|
||||
"""
|
||||
return self._putRequest(self._url("filewriter","command",parameter = command), dataType = "native")
|
||||
|
||||
|
||||
def fileWriterStatus(self,param = 'keys'):
|
||||
"""Get filewriter status information
|
||||
Args:
|
||||
param: query the status parameter param, if 'keys' get all status parameters.
|
||||
Returns:
|
||||
If param is None get configuration, if param is 'keys' return list of all parameters, else return dictionary
|
||||
that may contain the keys: value, value_type, unit, time, state, critical_limits, critical_values
|
||||
"""
|
||||
return self._getRequest(self._url('filewriter','status',parameter = param))
|
||||
|
||||
def fileWriterFiles(self, filename = None, method = 'GET'):
|
||||
"""
|
||||
Obtain file from detector.
|
||||
Args:
|
||||
filename: Name of file on the detector side. If None return list of available files
|
||||
method: Eiger 'GET' (get the content of the file) or 'DELETE' (delete file from server)
|
||||
Returns:
|
||||
List of available files if 'filename' is None,
|
||||
else if method is 'GET' the content of the file.
|
||||
"""
|
||||
if method == 'GET':
|
||||
if filename is None:
|
||||
return self._getRequest(self._url('filewriter','files'))
|
||||
else:
|
||||
return self._getRequest(url = '/{0}data/{1}'.format(self._urlPrefix, filename), dataType = 'hdf5')
|
||||
elif method == 'DELETE':
|
||||
return self._delRequest(url = '/{0}data/{1}'.format(self._urlPrefix,filename))
|
||||
else:
|
||||
raise RuntimeError('Unknown method {0}'.format(method))
|
||||
|
||||
def fileWriterSave(self,filename,targetDir,regex = False):
|
||||
"""
|
||||
Saves filename in targetDir. If regex is True, filename is considered to be a regular expression.
|
||||
Save all files that match filename
|
||||
Args:
|
||||
filename: Name of source file, evtl. regular expression
|
||||
targetDir: Directory, where to store the files
|
||||
"""
|
||||
if regex:
|
||||
pattern = re.compile(filename)
|
||||
[ self.fileWriterSave(f,targetDir) for f in self.fileWriterFiles() if pattern.match(f) ]
|
||||
elif any([ c in filename for c in ['*','?','[',']'] ] ):
|
||||
# for f in self.fileWriterFiles():
|
||||
# self._log('DEBUG ', f, ' ', fnmatch.fnmatch(f,filename))
|
||||
[ self.fileWriterSave(f,targetDir) for f in self.fileWriterFiles() if fnmatch.fnmatch(f,filename) ]
|
||||
else:
|
||||
targetPath = os.path.join(targetDir,filename)
|
||||
with open(targetPath,'wb') as targetFile:
|
||||
self._log('Writing ', targetPath)
|
||||
self._getRequest(url = '/{0}data/{1}'.format(self._urlPrefix, filename), dataType = 'hdf5',fileId = targetFile)
|
||||
# targetFile.write(self.fileWriterFiles(filename))
|
||||
assert os.access(targetPath,os.R_OK)
|
||||
return
|
||||
|
||||
def monitorConfig(self,param = 'keys'):
|
||||
"""Get monitor configuration parameter
|
||||
Args:
|
||||
param: query the configuration parameter param, if 'keys' get all configuration parameters.
|
||||
Returns:
|
||||
If param is 'keys' return list of all parameters, else return dictionary
|
||||
that may contain the keys: value, min, max, allowed_values, unit, value_type and access_mode
|
||||
"""
|
||||
return self._getRequest(self._url('monitor','config',parameter = param))
|
||||
|
||||
def setMonitorConfig(self,param,value):
|
||||
"""
|
||||
Set monitor configuration parameter param.
|
||||
Args:
|
||||
param: parameter
|
||||
value: value to set
|
||||
Returns:
|
||||
List of changed parameters.
|
||||
"""
|
||||
return self._putRequest(self._url('monitor','config',parameter = param), dataType = 'native', data = value)
|
||||
|
||||
def monitorImages(self, param = None):
|
||||
"""
|
||||
Obtain file from detector.
|
||||
Args:
|
||||
param: Either None (return list of available frames) or "monitor" (return latest frame),
|
||||
"next" (next image from buffer) or tuple(sequence id, image id) (return specific image)
|
||||
Returns:
|
||||
List of available frames (param = None) or tiff content of image file (param = "next", "monitor", (seqId,imgId))
|
||||
"""
|
||||
if param is None:
|
||||
return self._getRequest(self._url('monitor','images',parameter = None) )
|
||||
elif param == "next":
|
||||
return self._getRequest(self._url('monitor',"images", parameter = "next"), dataType = "tif")
|
||||
elif param == "monitor":
|
||||
return self._getRequest(self._url('monitor','images',parameter = "monitor"), dataType = "tif")
|
||||
else:
|
||||
try:
|
||||
seqId = int(param[0])
|
||||
imgId = int(param[1])
|
||||
return self._getRequest(self._url('monitor',"images", parameter = "{0}/{1}".format(seqId,imgId) ), dataType = 'tif')
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
raise RuntimeError('Invalid parameter {0}'.format(param))
|
||||
|
||||
def monitorSave(self, param, path):
|
||||
"""
|
||||
Save frame to path as tiff file.
|
||||
Args:
|
||||
param: same as monitorImages()
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
data = None
|
||||
if param in ["next","monitor"]:
|
||||
data = self.monitorImages(param)
|
||||
else :
|
||||
try:
|
||||
int(param[0])
|
||||
int(param[1])
|
||||
data = self.monitorImages(param)
|
||||
except (TypeError, ValueError):
|
||||
pass
|
||||
if data is None:
|
||||
raise RuntimeError('Invalid parameter {0}'.format(param))
|
||||
else:
|
||||
with open(path,'wb') as f:
|
||||
self._log('Writing ', path)
|
||||
f.write(data)
|
||||
assert os.access(path,os.R_OK)
|
||||
return
|
||||
|
||||
def monitorStatus(self, param):
|
||||
"""Get monitor status information
|
||||
Args:
|
||||
param: query the status parameter param, if 'keys' get all status parameters.
|
||||
Returns:
|
||||
Dictionary that may contain the keys: value, value_type, unit, time, state,
|
||||
critical_limits, critical_values
|
||||
"""
|
||||
return self._getRequest(self._url('monitor','status',parameter = param))
|
||||
|
||||
def sendMonitorCommand(self, command):
|
||||
"""
|
||||
Send monitor command to Eiger.
|
||||
Args:
|
||||
command: Command to send (up to now only "clear")
|
||||
Returns:
|
||||
Empty string
|
||||
"""
|
||||
return self._putRequest(self._url("monitor","command",parameter = command), dataType = "native")
|
||||
|
||||
def streamConfig(self,param = 'keys'):
|
||||
"""Get stream configuration parameter
|
||||
Args:
|
||||
param: query the configuration parameter param, if 'keys' get all configuration parameters.
|
||||
Returns:
|
||||
If param is 'keys' return list of all parameters, else return dictionary
|
||||
that may contain the keys: value, min, max, allowed_values, unit, value_type and access_mode
|
||||
"""
|
||||
return self._getRequest(self._url('stream','config',parameter = param))
|
||||
|
||||
|
||||
def setStreamConfig(self,param,value):
|
||||
"""
|
||||
Set stream configuration parameter param.
|
||||
Args:
|
||||
param: parameter
|
||||
value: value to set
|
||||
Returns:
|
||||
List of changed parameters.
|
||||
"""
|
||||
return self._putRequest(self._url('stream','config',parameter = param), dataType = 'native', data = value)
|
||||
|
||||
def streamStatus(self, param):
|
||||
"""Get stream status information
|
||||
Args:
|
||||
param: query the status parameter param, if 'keys' get all status parameters.
|
||||
Returns:
|
||||
Dictionary that may contain the keys: value, value_type, unit, time, state,
|
||||
critical_limits, critical_values
|
||||
"""
|
||||
return self._getRequest(self._url('stream','status',parameter = param))
|
||||
|
||||
|
||||
|
||||
|
||||
#
|
||||
#
|
||||
# Private Methods
|
||||
#
|
||||
#
|
||||
|
||||
def _log(self,*args):
|
||||
if self._verbose:
|
||||
print ' '.join([ str(elem) for elem in args ])
|
||||
|
||||
def _url(self,module,task,parameter = None):
|
||||
url = "/{0}{1}/api/{2}/{3}/".format(self._urlPrefix, module, self._version, task)
|
||||
if not parameter is None:
|
||||
url += '{0}'.format(parameter)
|
||||
return url
|
||||
|
||||
def _getRequest(self,url,dataType = 'native', fileId = None):
|
||||
if dataType is None:
|
||||
dataType = 'native'
|
||||
if dataType == 'native':
|
||||
mimeType = 'application/json; charset=utf-8'
|
||||
elif dataType == 'tif':
|
||||
mimeType = 'application/tiff'
|
||||
elif dataType == 'hdf5':
|
||||
mimeType = 'application/hdf5'
|
||||
return self._request(url,'GET',mimeType, fileId = fileId)
|
||||
|
||||
def _putRequest(self,url,dataType,data = None):
|
||||
data, mimeType = self._prepareData(data,dataType)
|
||||
return self._request(url,'PUT',mimeType, data)
|
||||
|
||||
def _delRequest(self,url):
|
||||
self._request(url,'DELETE',mimeType = None)
|
||||
return None
|
||||
|
||||
def _request(self, url, method, mimeType, data = None, fileId = None):
|
||||
if data is None:
|
||||
body = ''
|
||||
else:
|
||||
body = data
|
||||
headers = {}
|
||||
if method == 'GET':
|
||||
headers['Accept'] = mimeType
|
||||
elif method == 'PUT':
|
||||
headers['Content-type'] = mimeType
|
||||
if not self._user is None:
|
||||
headers["Authorization"] = "Basic {0}".format(self._user)
|
||||
|
||||
self._log('sending request to {0}'.format(url))
|
||||
numberOfTries = 0
|
||||
response = None
|
||||
while response is None:
|
||||
try:
|
||||
self._connection.request(method,url, body = data, headers = headers)
|
||||
response = self._connection.getresponse()
|
||||
except Exception as e:
|
||||
numberOfTries += 1
|
||||
if numberOfTries == 50:
|
||||
self._log("Terminate after {0} tries\n".format(numberOfTries))
|
||||
raise e
|
||||
self._log("Failed to connect to host. Retrying\n")
|
||||
self._connection = httplib.HTTPConnection(self._host,self._port, timeout = self._connectionTimeout)
|
||||
continue
|
||||
|
||||
|
||||
status = response.status
|
||||
reason = response.reason
|
||||
if fileId is None:
|
||||
data = response.read()
|
||||
else:
|
||||
bufferSize = 8*1024
|
||||
while True:
|
||||
data = response.read(bufferSize)
|
||||
if len(data) > 0:
|
||||
fileId.write(data)
|
||||
else:
|
||||
break
|
||||
|
||||
mimeType = response.getheader('content-type','text/plain')
|
||||
self._log('Return status: ', status, reason)
|
||||
if not response.status in range(200,300):
|
||||
raise RuntimeError((reason,data))
|
||||
if 'json' in mimeType:
|
||||
return json.loads(data)
|
||||
else:
|
||||
return data
|
||||
|
||||
def _prepareData(self,data, dataType):
|
||||
if data is None:
|
||||
return '', 'text/html'
|
||||
if dataType != 'native':
|
||||
if type(data) == file:
|
||||
data = data.read()
|
||||
if dataType is None:
|
||||
mimeType = self._guessMimeType(data)
|
||||
if not mimeType is None:
|
||||
return data, mimeType
|
||||
elif dataType == 'tif':
|
||||
return data, 'application/tiff'
|
||||
mimeType = 'application/json; charset=utf-8'
|
||||
return json.dumps({'value':data}), mimeType
|
||||
|
||||
def _guessMimeType(self,data):
|
||||
if type(data) == str:
|
||||
if data.startswith('\x49\x49\x2A\x00') or data.startswith('\x4D\x4D\x00\x2A'):
|
||||
self._log('Determined mimetype: tiff')
|
||||
return 'application/tiff'
|
||||
if data.startswith('\x89\x48\x44\x46\x0d\x0a\x1a\x0a'):
|
||||
self._log('Determined mimetype: hdf5')
|
||||
return 'application/hdf5'
|
||||
return None
|
||||
|
||||
|
||||
508
script/Devices/EigerTest.py
Normal file
508
script/Devices/EigerTest.py
Normal file
@@ -0,0 +1,508 @@
|
||||
"""
|
||||
EigerTest extends the functionality of DEigerClient for convenient
|
||||
interactive work in a python shell. It should be used only for this
|
||||
intended purpose or as an example how to use DEigerClient in your own
|
||||
code. The ipython shell is highly recommended.
|
||||
|
||||
!Do NOT use this code in non-interactive scripts, python modules
|
||||
or subclasses! Kittens will die and the detector may behave erratic!
|
||||
For such purposes, please use DEigerClient or EIGER's REST API directly.
|
||||
|
||||
This code is
|
||||
- NOT official DECTRIS code but written for personal use by the author
|
||||
- NOT part of the software of EIGER detector systems.
|
||||
- NOT well tested.
|
||||
- only provided as is. Do not expect bug fixes, new features or any
|
||||
support or maintanence by DECTRIS.
|
||||
- NOT to be distributed without consent of the author!
|
||||
- not particularly well documented. Be prepared to read the code
|
||||
and simply try things out.
|
||||
|
||||
Modified: SteB
|
||||
Version: 20150131
|
||||
|
||||
Author: Marcus Mueller
|
||||
Contact: marcus.mueller@dectris.com
|
||||
Version: 20140922
|
||||
"""
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
import time, datetime
|
||||
|
||||
sys.path.insert(0,"/usr/local/dectris/python")
|
||||
from eigerclient import DEigerClient
|
||||
try:
|
||||
import dectris.albula
|
||||
from quickstart import Monitor
|
||||
MONITOR_AVAILABLE = True
|
||||
except ImportError:
|
||||
MONITOR_AVAILABLE = False
|
||||
|
||||
#############################################################
|
||||
### Configure IP and PORT of the EIGER system that you are
|
||||
### accessing with this code below.
|
||||
# DMZ system
|
||||
#~ IP = "62.12.129.162"
|
||||
#~ PORT = "4010"
|
||||
#~
|
||||
# fixed IP, direct connection
|
||||
try:
|
||||
IP = sys.argv[1]
|
||||
except:
|
||||
IP = "129.129.106.139"
|
||||
#print "IP", IP
|
||||
PORT = "80"
|
||||
|
||||
# for printing detector config and values
|
||||
LISTED_DETECTOR_PARAMS = [
|
||||
u'description',
|
||||
u'detector_number',
|
||||
u'data_collection_date',
|
||||
u'frame_time',
|
||||
u'nimages',
|
||||
u'ntrigger',
|
||||
u'trigger_mode',
|
||||
u'photon_energy',
|
||||
u'threshold_energy',
|
||||
u'element',
|
||||
u'count_time',
|
||||
u'detector_readout_time',
|
||||
u'nframes_sum',
|
||||
u'frame_count_time',
|
||||
u'frame_period',
|
||||
#u'sub_image_count_time',
|
||||
u'auto_summation',
|
||||
u'summation_nimages',
|
||||
u'bit_depth_readout',
|
||||
u'efficiency_correction_applied',
|
||||
u'flatfield_correction_applied',
|
||||
u'number_of_excluded_pixels',
|
||||
u'calibration_type',
|
||||
u'countrate_correction_applied',
|
||||
u'countrate_correction_bunch_mode',
|
||||
u'pixel_mask_applied',
|
||||
#u'pixel_mask',
|
||||
u'virtual_pixel_correction_applied',
|
||||
u'software_version',
|
||||
u'sensor_material',
|
||||
u'sensor_thickness',
|
||||
u'x_pixels_in_detector',
|
||||
u'y_pixels_in_detector',
|
||||
u'x_pixel_size',
|
||||
u'y_pixel_size',
|
||||
u'wavelength',
|
||||
u'detector_distance',
|
||||
u'beam_center_x',
|
||||
u'beam_center_y',
|
||||
u'detector_translation',
|
||||
u'detector_orientation']
|
||||
CHECK_DOWNLOAD="/tmp/check_download"
|
||||
|
||||
# for filewriter config to have data bundles of ~ 1GB
|
||||
# 16M = 20 (45MB x 20)
|
||||
# 4M = 80 (12MB x 80)
|
||||
# 1M = 320 ( ?MB x 320)
|
||||
NIMAGES_PER_FILE=10000
|
||||
|
||||
|
||||
class EigerTest(DEigerClient):
|
||||
def setEnergy(self, photon_energy, threshold_ratio=0.5):
|
||||
self.setDetectorConfig("photon_energy", photon_energy)
|
||||
self.setDetectorConfig("threshold_energy", photon_energy * threshold_ratio)
|
||||
|
||||
def setElement(self, element='Cu'):
|
||||
self.setDetectorConfig(u'element', element)
|
||||
|
||||
def imageSeries(self, expp, nimages, auto_sum=False, ff_corr=True,
|
||||
pixel_mask=True):
|
||||
self.setDetectorConfig("auto_summation", auto_sum)
|
||||
self.setDetectorConfig("frame_time", expp)
|
||||
# to avoid warm pixels in center of module
|
||||
if expp > 0.099:
|
||||
readout_time = 5.0e-04 # no simultaneous read/write
|
||||
else:
|
||||
# simultaneous read/write will give high duty cycle but also warm pixels
|
||||
readout_time = self.detectorConfig('detector_readout_time')['value']
|
||||
self.setDetectorConfig("count_time", expp - readout_time)
|
||||
self.setDetectorConfig("nimages", nimages)
|
||||
self.setDetectorConfig("flatfield_correction_applied", ff_corr)
|
||||
self.setDetectorConfig("pixel_mask_applied", pixel_mask)
|
||||
|
||||
def imageSeries2(self, expp, nimages, auto_sum=True, ff_corr=True,
|
||||
pixel_mask=True):
|
||||
self.setDetectorConfig("auto_summation", auto_sum)
|
||||
self.setDetectorConfig("frame_time", expp)
|
||||
# to avoid warm pixels in center of module
|
||||
if expp > 0.099:
|
||||
readout_time = 5.0e-04 # no simultaneous read/write
|
||||
else:
|
||||
# simultaneous read/write will give high duty cycle but also warm pixels
|
||||
readout_time = self.detectorConfig('detector_readout_time')['value']
|
||||
self.setDetectorConfig("count_time", expp - readout_time)
|
||||
self.setDetectorConfig("nimages", nimages)
|
||||
self.setDetectorConfig("ntrigger", nimages)
|
||||
self.setDetectorConfig("flatfield_correction_applied", ff_corr)
|
||||
self.setDetectorConfig("pixel_mask_applied", pixel_mask)
|
||||
# self.printConf('time|image')
|
||||
|
||||
def printConf(self, regex='', full=0):
|
||||
for param in LISTED_DETECTOR_PARAMS:
|
||||
if full:
|
||||
if re.search(regex, param):
|
||||
try:
|
||||
print str(param).ljust(35), ' = ', str(eiger.detectorConfig(param)['value']).ljust(35),' ', str(eiger.detectorConfig(param)['min']).ljust(35),' ', str(eiger.detectorConfig(param)['max']).ljust(35)
|
||||
except:
|
||||
print ""
|
||||
pass
|
||||
#print str(param).ljust(35), ' = ', str(eiger.detectorConfig(param)['value']).ljust(35)
|
||||
else:
|
||||
if eiger.search(regex, param):
|
||||
print str(param).ljust(35), ' = ', eiger.detectorConfig(param)['value']
|
||||
|
||||
|
||||
|
||||
def setFileNameBase(self, fnBase):
|
||||
self.setFileWriterConfig("name_pattern", fnBase)
|
||||
|
||||
def setImagesPerFile(self, nimages=1000):
|
||||
self.setFileWriterConfig("nimages_per_file", nimages)
|
||||
|
||||
def pHello(self, z="today"):
|
||||
print "Hello " + z
|
||||
|
||||
def printFileWriterConfig(self):
|
||||
for param in self.fileWriterConfig():
|
||||
try:
|
||||
print param, ' = ', self.fileWriterConfig(param)['value']
|
||||
except RuntimeError as e:
|
||||
print "RuntimeError accessing %s: %s" % (param, e)
|
||||
|
||||
def printFileWriterStatus(self):
|
||||
for param in self.fileWriterStatus():
|
||||
try:
|
||||
print param, ' = ', self.fileWriterStatus(param)['value']
|
||||
except RuntimeError as e:
|
||||
print "RuntimeError accessing %s: %s" % (param, e)
|
||||
|
||||
def printTempHum(self, all_data=0):
|
||||
for param in self.detectorStatus():
|
||||
if all_data:
|
||||
if re.search("temp|humidity", param):
|
||||
print (param).ljust(35), ' = ', self.detectorStatus(param)['value']
|
||||
else:
|
||||
if re.search("th0", param):
|
||||
print (param).ljust(35), ' = ', self.detectorStatus(param)['value']
|
||||
|
||||
def printFW(self):
|
||||
for param in self.detectorStatus():
|
||||
if re.search("fw", param):
|
||||
print (param).ljust(35), ' = ', self.detectorStatus(param)['value']
|
||||
|
||||
def printDetectorState(self):
|
||||
print "State: %s" % self.detectorStatus('state')['state']
|
||||
print "Error: %s" % self.detectorStatus('error')
|
||||
|
||||
def setDetConMultiple(self, **params):
|
||||
"""
|
||||
Convenience function to set a single or multiple detector
|
||||
configuration parameters in the form (parameter=value[, ...]).
|
||||
Multiple parameters are set in arbitrary order!
|
||||
You have to check the print output of this function whether
|
||||
you obtain the desired detector configuration
|
||||
"""
|
||||
for p, data in params.items():
|
||||
changeList = self.setDetectorConfig(param=p, value=data, dataType=None)
|
||||
changes = ''
|
||||
for changed_param in changeList:
|
||||
changed_value = self.detectorConfig(changed_param)['value']
|
||||
changes += '%s = %s ; ' % (changed_param, str(changed_value))
|
||||
print "Setting: %s = %s" % (p, str(data))
|
||||
print "Changing: " + changes[:-2]
|
||||
|
||||
def purgeFiles(self, force=False):
|
||||
f_list = self.fileWriterFiles()
|
||||
if not force:
|
||||
print "Files on the detector control unit:"
|
||||
#~ [print(f) for f in f_list]
|
||||
for f in f_list:
|
||||
print f
|
||||
if force == True or raw_input('Do you really want to purge all '
|
||||
'these files? \n'
|
||||
'Then enter y. ') == 'y':
|
||||
[self.fileWriterFiles(f, 'DELETE') for f in f_list]
|
||||
#~ for f in f_list:
|
||||
#~ self.fileWriterFiles(f, 'DELETE')
|
||||
else:
|
||||
print "Aborting without deleting files."
|
||||
|
||||
def startMonitor(self):
|
||||
m = None
|
||||
if not MONITOR_AVAILABLE:
|
||||
print "Monitor nor available. Check dependencies."
|
||||
print "Returning None."
|
||||
else:
|
||||
m = Monitor(self)
|
||||
m.start()
|
||||
print "Monitor started and monitor object returned."
|
||||
self._monitor = m
|
||||
return m
|
||||
|
||||
def arm(self):
|
||||
self.sendDetectorCommand(u'arm')
|
||||
|
||||
def trigger(self):
|
||||
self.sendDetectorCommand(u'trigger')
|
||||
|
||||
def disarm(self):
|
||||
self.sendDetectorCommand(u'disarm')
|
||||
|
||||
def initialize(self, element=None, energy=None):
|
||||
self.sendDetectorCommand(u'initialize')
|
||||
if element is not None and energy is not None:
|
||||
print "You cannot give element AND energy."
|
||||
elif element is not None:
|
||||
self.setElement(element)
|
||||
elif energy is not None:
|
||||
self.setEnergy(energy)
|
||||
|
||||
def exposure(self, fnBase=None):
|
||||
"""
|
||||
tvx style exposure command
|
||||
"""
|
||||
if fnBase is not None:
|
||||
self.setFileNameBase(fnBase=fnBase)
|
||||
self.setDetectorConfig('data_collection_date',
|
||||
self.fileWriterStatus('time')['value'])
|
||||
print "Arm ..."
|
||||
self.arm()
|
||||
print "Trigger ..."
|
||||
self.trigger()
|
||||
print "Disarm ..."
|
||||
time.sleep(1)
|
||||
self.disarm()
|
||||
print "DONE!"
|
||||
|
||||
def download(self, downloadpath="/tmp"):
|
||||
try:
|
||||
matching = self.fileWriterFiles()
|
||||
except:
|
||||
print "could not get file list"
|
||||
if len(matching):
|
||||
try:
|
||||
[self.fileWriterSave(i, downloadpath) for i in matching]
|
||||
except:
|
||||
print "error saveing - noting deleted"
|
||||
else:
|
||||
print "Downloaded ..."
|
||||
for i in matching:
|
||||
print i + " to " + str(downloadpath)
|
||||
[self.fileWriterFiles(i, method = 'DELETE') for i in matching]
|
||||
print "Deteted " + str(len(matching)) + " file(s)"
|
||||
|
||||
def downloadD(self, downloadpath="/tmp"):
|
||||
if not os.path.exists(downloadpath):
|
||||
os.makedirs(downloadpath)
|
||||
open(CHECK_DOWNLOAD, 'a').close()
|
||||
while os.path.exists(CHECK_DOWNLOAD):
|
||||
try:
|
||||
matching = self.fileWriterFiles()
|
||||
except:
|
||||
print "could not get file list"
|
||||
time.sleep(1)
|
||||
if len(matching)>0:
|
||||
try:
|
||||
[self.fileWriterSave(i, downloadpath) for i in matching]
|
||||
except:
|
||||
print "error saveing - noting deleted"
|
||||
else:
|
||||
print "Downloaded ..."
|
||||
for i in matching:
|
||||
print i
|
||||
[self.fileWriterFiles(i, method = 'DELETE') for i in matching]
|
||||
print "Deteted " + str(len(matching)) + " file(s)"
|
||||
|
||||
def stopDownloadD(self):
|
||||
os.remove(CHECK_DOWNLOAD)
|
||||
|
||||
|
||||
|
||||
def setup_bt_Nov_2016(self):
|
||||
"""
|
||||
setup the beamtime for operation
|
||||
"""
|
||||
self.setDetectorConfig("photon_energy", 15000)
|
||||
print "Photon energy set to: " + str(self.detectorConfig("photon_energy")["value"])
|
||||
self.setDetectorConfig("threshold_energy", 10000)
|
||||
print "Threshold energy set to: " + str(self.detectorConfig("threshold_energy")["value"])
|
||||
self.setDetectorConfig("ntrigger",1e6)
|
||||
self.setDetectorConfig("nimages", 1)
|
||||
self.setFileWriterConfig("compression_enabled",False)
|
||||
print "Compression set to: " + str(self.fileWriterConfig("compression_enabled")['value'])
|
||||
self.setFileWriterConfig("nimages_per_file",20)
|
||||
|
||||
def config_bt_Nov_2016(self,file_name="series",count_time=1):
|
||||
"""
|
||||
configure one run - set name and count time (assume that you record 1e6 triggerd images)
|
||||
"""
|
||||
readout_time = self.detectorConfig('detector_readout_time')['value']
|
||||
self.setDetectorConfig("count_time", count_time)
|
||||
self.setDetectorConfig("frame_time", count_time + readout_time)
|
||||
self.setFileWriterConfig("name_pattern", file_name + "_$id")
|
||||
print "Images with " + str(self.detectorConfig("count_time")["value"]) + " s"
|
||||
print "Named to " + str(self.fileWriterConfig("name_pattern")["value"])
|
||||
|
||||
def setup_of(self):
|
||||
"""
|
||||
setup the beamtime for operation
|
||||
"""
|
||||
self.setDetectorConfig("photon_energy", 19000)
|
||||
print "Photon energy set to: " + str(self.detectorConfig("photon_energy")["value"])
|
||||
self.setDetectorConfig("threshold_energy", 5000)
|
||||
print "Threshold energy set to: " + str(self.detectorConfig("threshold_energy")["value"])
|
||||
self.setDetectorConfig("ntrigger",1e6)
|
||||
self.setDetectorConfig("nimages", 1)
|
||||
self.setDetectorConfig("trigger_mode", 'exts')
|
||||
self.setFileWriterConfig("compression_enabled",False)
|
||||
print "Compression set to: " + str(self.fileWriterConfig("compression_enabled")['value'])
|
||||
self.setFileWriterConfig("nimages_per_file",20)
|
||||
|
||||
def setup_of_exte(self):
|
||||
"""
|
||||
setup the beamtime for operation
|
||||
"""
|
||||
self.setDetectorConfig("photon_energy", 19000)
|
||||
print "Photon energy set to: " + str(self.detectorConfig("photon_energy")["value"])
|
||||
self.setDetectorConfig("threshold_energy", 5000)
|
||||
print "Threshold energy set to: " + str(self.detectorConfig("threshold_energy")["value"])
|
||||
self.setDetectorConfig("ntrigger",1e6)
|
||||
self.setDetectorConfig("nimages", 1)
|
||||
self.setDetectorConfig("trigger_mode", 'exte')
|
||||
self.setFileWriterConfig("compression_enabled",False)
|
||||
print "Compression set to: " + str(self.fileWriterConfig("compression_enabled")['value'])
|
||||
self.setFileWriterConfig("nimages_per_file",20)
|
||||
|
||||
def setup_sg(self):
|
||||
"""
|
||||
setup the beamtime for operation
|
||||
"""
|
||||
self.setDetectorConfig("photon_energy", 19000)
|
||||
print "Photon energy set to: " + str(self.detectorConfig("photon_energy")["value"])
|
||||
self.setDetectorConfig("threshold_energy", 5000)
|
||||
print "Threshold energy set to: " + str(self.detectorConfig("threshold_energy")["value"])
|
||||
self.setDetectorConfig("ntrigger",1e6)
|
||||
self.setDetectorConfig("nimages", 1)
|
||||
self.setDetectorConfig("trigger_mode", 'ints')
|
||||
self.setFileWriterConfig("compression_enabled",False)
|
||||
print "Compression set to: " + str(self.fileWriterConfig("compression_enabled")['value'])
|
||||
self.setFileWriterConfig("nimages_per_file",20)
|
||||
|
||||
def config_filename_countime(self,file_name="series",count_time=1):
|
||||
"""
|
||||
configure one run - set name and count time (assume that you record 1e6 triggerd images)
|
||||
"""
|
||||
readout_time = self.detectorConfig('detector_readout_time')['value']
|
||||
self.setDetectorConfig("count_time", count_time)
|
||||
self.setDetectorConfig("frame_time", count_time + readout_time)
|
||||
self.setFileWriterConfig("name_pattern", file_name + "_$id")
|
||||
print "Images with " + str(self.detectorConfig("count_time")["value"]) + " s"
|
||||
print "Named to " + str(self.fileWriterConfig("name_pattern")["value"])
|
||||
|
||||
|
||||
def exp(self,frame_time=1,nimages=1,ntrigger=1000):
|
||||
"""
|
||||
tvx style exposure command
|
||||
"""
|
||||
self.setDetectorConfig("frame_time", frame_time)
|
||||
readout_time = self.detectorConfig('detector_readout_time')['value']
|
||||
self.setDetectorConfig("count_time", frame_time - readout_time)
|
||||
self.setDetectorConfig("nimages", nimages)
|
||||
self.setDetectorConfig("ntrigger",ntrigger)
|
||||
if nimages < NIMAGES_PER_FILE:
|
||||
nipf = nimages
|
||||
else:
|
||||
nipf = NIMAGES_PER_FILE
|
||||
self.setFileWriterConfig("nimages_per_file",nipf+1)
|
||||
|
||||
print "Arm ..."
|
||||
self.arm()
|
||||
print "Trigger ..."
|
||||
print(datetime.datetime.now().strftime("%H:%M:%S.%f"))
|
||||
self.trigger()
|
||||
print(datetime.datetime.now().strftime("%H:%M:%S.%f"))
|
||||
print "Disarm ..."
|
||||
time.sleep(1)
|
||||
self.disarm()
|
||||
print "DONE!"
|
||||
self.printConf('time|image')
|
||||
|
||||
def hdf_file_check(self):
|
||||
"""
|
||||
tvx style exposure command
|
||||
"""
|
||||
self.setDetectorConfig("omega_range_average",0.1)
|
||||
self.setDetectorConfig("frame_time", 1)
|
||||
readout_time = self.detectorConfig('detector_readout_time')['value']
|
||||
self.setDetectorConfig("count_time", 1 - readout_time)
|
||||
self.setDetectorConfig("nimages", 1)
|
||||
self.setDetectorConfig("ntrigger",1)
|
||||
|
||||
self.setFileWriterConfig("nimages_per_file",1+1)
|
||||
|
||||
print "Arm ..."
|
||||
self.arm()
|
||||
print "Trigger ..."
|
||||
self.trigger()
|
||||
print "Disarm ..."
|
||||
time.sleep(1)
|
||||
self.disarm()
|
||||
print "DONE!"
|
||||
self.printConf('time|image')
|
||||
|
||||
def testLoop(self, nloops, purge=True, **kwargs):
|
||||
print "#" * 72 + "\nRunning test loop with %d series.\n" % nloops
|
||||
self.imageSeries(**kwargs)
|
||||
print "-" * 72
|
||||
for n in range(nloops):
|
||||
print "Running series %d" % (n + 1)
|
||||
self.exposure()
|
||||
if purge:
|
||||
print "Purging files."
|
||||
time.sleep(1)
|
||||
self.purgeFiles(force=True)
|
||||
print "-" * 72
|
||||
print "Finished %d series." % nloops
|
||||
print "#" * 72 + "\n"
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print "EIGER test client - running at " + str(IP)
|
||||
eiger = EigerTest(host=IP, port=PORT, verbose=False)
|
||||
state_now = eiger.detectorStatus("state")["value"]
|
||||
print "Detector: " + eiger.detectorStatus("state")["value"]
|
||||
if state_now is "na":
|
||||
print "!!! initalize by typing: eiger.initialize() !!!"
|
||||
print ""
|
||||
eiger.printTempHum()
|
||||
|
||||
|
||||
|
||||
|
||||
#~ e.setDetectorConfig('auto_summation', False)
|
||||
#~ e.setDetectorConfig('countrate_correction_applied', True)
|
||||
#~ e.setDetectorConfig('element', 'Cu')
|
||||
|
||||
#~ e.sendDetectorCommand(u'initialize')
|
||||
#~ e.setEnergy(12400)
|
||||
#~ e.imageSeries(expp=0.2, nimages=5)
|
||||
#~ e.printTempHum()
|
||||
# ~ e.setImagesPerFile(100)
|
||||
#~ e.printDetectorConfig()
|
||||
#~ e.printFileWriterConfig()
|
||||
#~ print "Exposure ..."
|
||||
#~ e.exposure(fnBase='test')
|
||||
#~ print "... done"
|
||||
#~ e.fileWriterSave(filename='test*', targetDir=os.path.curdir)
|
||||
|
||||
|
||||
16
script/Tasks/DetectorsCheck.py
Normal file
16
script/Tasks/DetectorsCheck.py
Normal file
@@ -0,0 +1,16 @@
|
||||
#print "Detectors Check"
|
||||
|
||||
|
||||
for name, info in DETECTORS.items():
|
||||
path = info["path"]
|
||||
try:
|
||||
#print path,
|
||||
caget_str(path)
|
||||
info["enabled"] = True
|
||||
#print " ok"
|
||||
except:
|
||||
info["enabled"] = False
|
||||
#print " error"
|
||||
|
||||
|
||||
|
||||
@@ -21,6 +21,12 @@ crlogic_config["class"] = "ch.psi.pshell.crlogic.CrlogicScan"
|
||||
|
||||
run("CPython/wrapper")
|
||||
|
||||
DETECTORS={ \
|
||||
'Eiger4m': {"path":"X05LA-ES1-EIGER1:cam1:FilePath", "enabled": False}, \
|
||||
'XRayEye': {"path":"X05LA-ES2-GIGE01:TIFF1:FilePath", "enabled": False} \
|
||||
}
|
||||
|
||||
|
||||
###################################################################################################
|
||||
# EPICS utilities
|
||||
###################################################################################################
|
||||
@@ -45,3 +51,34 @@ def run_fda(file_name, arguments={}):
|
||||
Run FDA loop
|
||||
"""
|
||||
ProcessorFDA().execute(file_name,arguments)
|
||||
|
||||
###################################################################################################
|
||||
# System callbaks
|
||||
###################################################################################################
|
||||
|
||||
|
||||
def on_command_started(info):
|
||||
pass
|
||||
|
||||
def on_command_finished(info):
|
||||
pass
|
||||
|
||||
def on_change_data_path(path):
|
||||
if path is not None:
|
||||
print "Data path: " + str(path)
|
||||
raw_data_folder = path + "/raw_data"
|
||||
os.makedirs(raw_data_folder)
|
||||
#with open(raw_data_folder + "/test.txt", "w") as f:
|
||||
# f.write("Success")
|
||||
for name, info in DETECTORS.items():
|
||||
log(name + " enabled = " + str(info["enabled"]))
|
||||
if info["enabled"]:
|
||||
channel_path = info["path"]
|
||||
caput_str(channel_path, raw_data_folder + "/" + name)
|
||||
|
||||
|
||||
def on_session_started(id):
|
||||
pass
|
||||
|
||||
def on_session_finished(id):
|
||||
pass
|
||||
|
||||
Reference in New Issue
Block a user