Added support for adaptive orbit feedback and spectral analysis

This commit is contained in:
2023-05-31 11:57:13 +02:00
parent b82b023f33
commit f22a17852c
8 changed files with 327 additions and 437 deletions

View File

@ -2,147 +2,181 @@ import sys
import os
import datetime
import h5py
import logging
import socket
from PIL import Image
# add other classes
#sys.path.append('/sf/bd/packages/SFBD/src')
def getDatasetFileName(program='Unknown'):
year = datetime.datetime.now().strftime('%Y')
month = datetime.datetime.now().strftime('%m')
day = datetime.datetime.now().strftime('%d')
class Save:
def __init__(self, logger = None, program = 'SFBD', version = 'v1.0.0'):
path = '/sf/data/measurements/%s' % year
if not os.path.exists(path):
os.makedirs(path)
path = '%s/%s' % (path,month)
if not os.path.exists(path):
os.makedirs(path)
path = '%s/%s' % (path,day)
if not os.path.exists(path):
os.makedirs(path)
datetag = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')
filename=('%s/%s_%s' % (path, program.replace(' ','_'), datetag))
return filename
self.program = program
self.version = version
self.author ='S. Reiche'
self.filename=None
self.file = None
if logger == None:
logging.basicConfig(level=logging.INFO,
format='%(levelname)-8s %(message)s')
self.logger = logging.getLogger(self.program)
self.logger.info('Save class started at %s' % datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'))
self.logger.info('Version: %s ' % self.version)
self.logger.info('Host: %s' % socket.gethostname())
else:
self.logger = logger
def saveDataset(program,data,actuator=None,snap=None,analysis=None,figures=None):
hid,filename = openDataset(program)
if not hid:
return None
# check if scan is multiple instances of a scan
if isinstance(data,list):
for iscan,singledata in enumerate(data):
writeData(hid,singledata,iscan)
else:
writeData(hid,data,1)
# same for actuator
if isinstance(actuator,list):
for iscan,singleactuator in enumerate(actuator):
writeActuator(hid,singleactuator,iscan)
else:
writeActuator(hid,actuator,1)
# and same for analysis
if isinstance(analysis,list):
for iscan,singleana in enumerate(analysis):
writeAnalysis(hid,singleana,iscan)
else:
writeAnalysis(hid,analysis,1)
# write aux data
writeSnap(hid,snap)
hid.close()
def open(self):
year = datetime.datetime.now().strftime('%Y')
month = datetime.datetime.now().strftime('%m')
day = datetime.datetime.now().strftime('%d')
path = '/sf/data/measurements/%s' % year
if not os.path.exists(path):
os.makedirs(path)
path = '%s/%s' % (path,month)
if not os.path.exists(path):
os.makedirs(path)
path = '%s/%s' % (path,day)
if not os.path.exists(path):
os.makedirs(path)
datetag = datetime.datetime.now().strftime('%Y_%m_%d_%H_%M_%S_%f')
self.filename=('%s/%s_%s' % (path, self.program.replace(' ','_'), datetag))
self.file = h5py.File(self.filename+'.h5', "w")
# meta data header
dt = h5py.special_dtype(vlen=bytes)
dset=self.file.create_dataset('general/user',(1,),dtype=dt)
dset[0]=os.getlogin()
dset=self.file.create_dataset('general/application',(1,),dtype=dt)
dset[0]=self.program
dset=self.file.create_dataset('general/author',(1,),dtype=dt)
dset[0]=self.author
dset=self.file.create_dataset('general/version',(1,),dtype=dt)
dset[0]=self.version
dset=self.file.create_dataset('general/created',(1,),dtype=dt)
dset[0]=str(datetime.datetime.now())
writeFigure(filename,figures)
return filename
def close(self):
if self.file is not None:
self.file.close()
self.file = None
def openDataset(program):
if isinstance(program,str):
program={'Name':program,'Author':'Unknown','Version':'Unknown'}
if not isinstance(program,dict):
return None,None
if not 'Author' in program.keys():
program['Author']='Unknown'
if not 'Version' in program.keys():
program['Version']='Unknown'
filename=getDatasetFileName(program['Name'])
hid= h5py.File(filename+'.h5', "w")
# meta data header
dt = h5py.special_dtype(vlen=bytes)
dset=hid.create_dataset('general/user',(1,),dtype=dt)
dset[0]=os.getlogin()
dset=hid.create_dataset('general/application',(1,),dtype=dt)
dset[0]=program['Name']
dset=hid.create_dataset('general/author',(1,),dtype=dt)
dset[0]=program['Author']
dset=hid.create_dataset('general/version',(1,),dtype=dt)
dset[0]=program['Version']
dset=hid.create_dataset('general/created',(1,),dtype=dt)
dset[0]=str(datetime.datetime.now())
return hid,filename
def writeData(hid, data, scanrun=1):
if not 'pid' in data.keys():
return
shape = data['pid'].shape
ndim = len(shape)
nsam = shape[-1]
nrec = 0
if ndim > 1:
nrec = shape[:-1][0]
hid.create_dataset("scan_%d/method/records" % scanrun,data=[nrec])
hid.create_dataset("scan_%d/method/samples" % scanrun,data=[nsam])
hid.create_dataset("scan_%d/method/dimension" % scanrun,data=[ndim])
hid.create_dataset("scan_%d/method/reducedData" % scanrun,data=[0]) # indicating that there is at least a 2D array for scalar data
# write the sensor raw value
for ele in data.keys():
name=ele.split(':')
if len(name)>1:
dset=hid.create_dataset('scan_%d/data/%s/%s' % (scanrun, name[0], name[1]), data=data[ele])
else:
dset=hid.create_dataset('scan_%d/data/%s' % (scanrun, name[0]), data=data[ele])
dset.attrs['system'] = getDatasetSystem(name[0])
dset.attrs['units'] = 'unknown'
def writeActuator(hid,act,scanrun=1):
if not act:
return
dt = h5py.special_dtype(vlen=bytes)
dset=hid.create_dataset("scan_%d/method/type" % scanrun,(1,),dtype=dt)
nact = len(act.keys())
if nact>0:
dset[0]='Scan'
else:
dset[0]='Time Recording'
for ele in act.keys():
name=ele.split(':')
if len(name)>1:
dset=hid.create_dataset("scan_%d/method/actuators/%s/%s" % (scanrun,name[0],name[1]),data=act[ele])
else:
dset=hid.create_dataset("scan_%d/method/actuators/%s" % (scanrun,name[0]),data=act[ele])
dset.attrs['system']=getDatasetSystem(name[0])
dset.attrs['units']='unknown'
def writeSnap(hid,val):
if not val:
return
for key in val.keys():
name=key.split(':')
if len(name)>1:
dset=hid.create_dataset('experiment/%s/%s' % (name[0],name[1]),data=val[key])
else:
dset=hid.create_dataset('experiment/%s/%s' % (name[0]),data=val[key])
dset.attrs['system']=getDatasetSystem(name[0])
dset.attrs['units']='unknown'
def writeAnalysis(hid,data,scanrun=1):
if not data:
return
for key in data.keys():
name=key.split(':')
if len(name)>1:
dset=hid.create_dataset('scan_%d/analysis/%s/%s' % (scanrun, name[0], name[1]), data=data[key])
else:
dset=hid.create_dataset('scan_%d/analysis/%s/%s' % (scanrun, name[0]), data=data[key])
dset.attrs['system']='analysis'
dset.attrs['units']='unknown'
def writeFigure(filename,figs):
for i,ele in enumerate(figs):
plotname='%s_Fig%d.png' % (filename,(i+1))
im = Image.open(ele)
im.save(plotname)
return None
def writeSnap(self,val):
for key in val.keys():
name=key.split(':')
if 'value' in val[key].keys():
data=val[key]['value']
elif 'val' in val[key].keys():
data=val[key]['val']
else:
continue
dset=self.file.create_dataset('experiment/%s/%s' % (name[0],name[1]),data=[data])
dset.attrs['system']=self.getSystem(name[0])
dset.attrs['units']='unknown'
def writeAnalysis(self,data,scanrun=1):
for key1 in data.keys():
for key2 in data[key1].keys():
dset=self.file.create_dataset('scan_%d/analysis/%s/%s' % (scanrun, key1, key2),
data=data[key1][key2])
def writeData(self, data, scanrun=1):
if not 'Shot:ID' in data.keys():
return
shape = data['Shot:ID'].shape
ndim = len(shape)
nsam = shape[-1]
nrec = 0
if ndim > 1:
nrec = shape[:-1][0]
self.file.create_dataset("scan_%d/method/records" % scanrun,data=[nrec])
self.file.create_dataset("scan_%d/method/samples" % scanrun,data=[nsam])
self.file.create_dataset("scan_%d/method/dimension" % scanrun,data=[ndim])
self.file.create_dataset("scan_%d/method/reducedData" % scanrun,data=[0]) # indicating that there is at least a 2D array for scalar data
# write the sensor raw value
for ele in data.keys():
name=ele.split(':')
dset=self.file.create_dataset('scan_%d/data/%s/%s' % (scanrun, name[0], name[1]), data=data[ele])
dset.attrs['system'] = self.getSystem(name[0])
dset.attrs['units'] = 'unknown'
def writeActuator(self,act,scanrun=1):
dt = h5py.special_dtype(vlen=bytes)
dset=self.file.create_dataset("scan_%d/method/type" % scanrun,(1,),dtype=dt)
if act.isActuator:
dset[0]='Scan'
else:
dset[0]='Time Recording'
for ele in act.actuators.keys():
name=ele.split(':')
dset=self.file.create_dataset("scan_%d/method/actuators/%s/%s" % (scanrun,name[0],name[1]),data=act.actuators[ele]['val'])
dset.attrs['system']=self.getSystem(name[0])
dset.attrs['units']='unknown'
def getSystem(self,name):
if len(name) > 11:
tag=name[8:9]
fulltag=name[8:12]
else:
tag=''
fulltag=''
sys='Unknown'
if tag =='P':
sys='Photonics'
if tag =='D':
sys='Diagnostics'
if fulltag =='DSCR':
sys='Camera'
if tag == 'R':
sys='RF'
if tag == 'M':
sys='Magnets'
if tag == 'U':
sys='Undulator'
return sys
def getDatasetSystem(name):
if len(name) > 11:
tag=name[8:9]
fulltag=name[8:12]
else:
tag=''
fulltag=''
sys='Unknown'
if tag =='P':
sys='Photonics'
if tag =='D':
sys='Diagnostics'
if fulltag =='DSCR':
sys='Camera'
if tag == 'R':
sys='RF'
if tag == 'M':
sys='Magnets'
if tag == 'U':
sys='Undulator'
return sys