Support for various app and slic wrapper
This commit is contained in:
@ -1,2 +1,4 @@
|
||||
from .adaptiveorbit import AdaptiveOrbit
|
||||
from .spectralanalysis import SpectralAnalysis
|
||||
from .hero import LaserPower,EnergyModulation
|
||||
from .dispersiontools import Dispersion
|
||||
|
@ -39,7 +39,7 @@ class AdaptiveOrbit:
|
||||
|
||||
def initBSStream(self,channels):
|
||||
print("Initializing BSstream")
|
||||
bs = BSCache()
|
||||
bs = BSCache(100000,10000) # 1 second time out, capazity for 100 second.
|
||||
bs.stop()
|
||||
for cnl in channels[1:]:
|
||||
if not is_available(cnl):
|
||||
@ -63,10 +63,8 @@ class AdaptiveOrbit:
|
||||
return pvs
|
||||
|
||||
def flush(self):
|
||||
with self.bsAR.pt.queue.mutex:
|
||||
self.bsAR.pt.queue.queue.clear()
|
||||
with self.bsAT.pt.queue.mutex:
|
||||
self.bsAT.pt.queue.queue.clear()
|
||||
self.bsAR.flush()
|
||||
self.bsAT.flush()
|
||||
|
||||
def terminate(self):
|
||||
print('Stopping BSStream Thread...')
|
||||
|
175
app/dispersiontools.py
Normal file
175
app/dispersiontools.py
Normal file
@ -0,0 +1,175 @@
|
||||
import datetime
|
||||
import re
|
||||
import numpy as np
|
||||
|
||||
from bsread import dispatcher
|
||||
import epics
|
||||
|
||||
from slic.core.adjustable import PVAdjustable
|
||||
from slic.core.acquisition import BSAcquisition
|
||||
from slic.core.scanner import Scanner
|
||||
|
||||
|
||||
def getAux(pvs=None):
|
||||
if not pvs:
|
||||
return
|
||||
ret={}
|
||||
val = epics.caget_many(pvs)
|
||||
for i,pv in enumerate(pvs):
|
||||
if val[i]: # filter out None values
|
||||
ret[pv]=float(val[i])
|
||||
epics.ca.clear_cache()
|
||||
return ret
|
||||
|
||||
|
||||
def getBSChannels(regexp):
|
||||
prog = re.compile(regexp)
|
||||
res = []
|
||||
for bs in dispatcher.get_current_channels():
|
||||
if prog.match(bs['name']):
|
||||
res.append(bs['name'])
|
||||
return res
|
||||
|
||||
|
||||
class Dispersion:
|
||||
def __init__(self, branch = 'Aramis'):
|
||||
self.scanname = 'Dispersion'
|
||||
self.branch = 'None'
|
||||
dirpath= datetime.datetime.now().strftime('/sf/data/measurements/%Y/%m/%d/slic_sfbd')
|
||||
self.scandir='%s/%s' % (dirpath,self.scanname)
|
||||
|
||||
self.setBranch()
|
||||
self.sc = None
|
||||
self.Nsteps = 2
|
||||
self.Nsamples = 1
|
||||
|
||||
|
||||
def setBranch(self,branch = 'Aramis'):
|
||||
if branch == 'Athos Dump':
|
||||
self.setupAthosDump()
|
||||
elif branch == 'Aramis':
|
||||
self.setupAramis()
|
||||
else:
|
||||
self.branch = 'None'
|
||||
|
||||
|
||||
def setupAramis(self):
|
||||
# pre-scan item
|
||||
self.pre = {}
|
||||
self.pre['SFB_BEAM_DUMP_AR:ONOFF1']={'Val':0,'InitVal':0}
|
||||
self.pre['SFB_BEAM_ENERGY_ECOL_AR:ONOFF1']={'Val':0,'InitVal':0}
|
||||
self.pre['SFB_ORBIT_S30:ONOFF1']={'Val':0,'InitVal':0}
|
||||
self.pre['SFB_ORBIT_SAR:ONOFF1']={'Val':0,'InitVal':0}
|
||||
for pv in self.pre.keys():
|
||||
self.pre[pv]['adj']=PVAdjustable(pv)
|
||||
# adjustable
|
||||
self.adjSV = 'S30:SET-E-GAIN-OP'
|
||||
self.adjRB = 'S30:GET-E-GAIN-OP'
|
||||
self.adj = PVAdjustable(self.adjSV,pvname_readback = self.adjRB, accuracy = 0.1)
|
||||
self.amp = 20 # the amplitude of the scan, which can be scaled
|
||||
# acquisition
|
||||
sensor1 = getBSChannels('SAR.*DBPM.*:[XY]1$')
|
||||
sensor2 = getBSChannels('S[23].*-RLLE-DSP:.*-VS$')
|
||||
self.sensor = sensor1+sensor2
|
||||
self.acq = [BSAcquisition("machine","sfbd", default_channels=self.sensor)]
|
||||
# auxiliar data to be read one
|
||||
self.aux=[]
|
||||
for sen in sensor2:
|
||||
if 'PHASE-VS' in sen:
|
||||
self.aux.append(sen.replace('PHASE-VS','GET-VSUM-PHASE-OFFSET').replace('RLLE-DSP','RSYS'))
|
||||
self.aux.append(sen.replace('PHASE-VS','GET-VSUM-AMPLT-SCALE').replace('RLLE-DSP','RSYS'))
|
||||
self.aux.append(sen.replace('PHASE-VS','SM-SET').replace('RLLE-DSP','RMSM'))
|
||||
self.aux.append('S10BC02-MBND100:ENERGY-OP')
|
||||
|
||||
# scanner
|
||||
self.branch='Aramis'
|
||||
self.path = '%s-%s' % (self.scanname,self.branch)
|
||||
self.scanner = Scanner(data_base_dir=self.path,scan_info_dir=self.path,
|
||||
make_scan_sub_dir=True,
|
||||
default_acquisitions=self.acq)
|
||||
|
||||
def setupAthosDump(self):
|
||||
# pre-scan item
|
||||
self.pre = {}
|
||||
self.pre['SFB_BEAM_DUMP_AT:ONOFF1']={'Val':0,'InitVal':0}
|
||||
self.pre['SFB_ORBIT_SAT:ONOFF1']={'Val':0,'InitVal':0}
|
||||
for i in range(1,5):
|
||||
self.pre['SFB_ORBIT_SAT_%2.2d:ONOFF1' % i ]={'Val':0,'InitVal':0}
|
||||
for pv in self.pre.keys():
|
||||
self.pre[pv]['adj']=PVAdjustable(pv)
|
||||
# adjustable
|
||||
self.adjSV = 'SATCB01-RSYS:SET-BEAM-PHASE'
|
||||
self.adjRB = 'SATCB01-RSYS:GET-BEAM-PHASE'
|
||||
self.adj = PVAdjustable(self.adjSV,pvname_readback = self.adjRB, accuracy = 0.1)
|
||||
self.amp = 20 # the amplitude of the scan, which can be scaled
|
||||
# acquisition
|
||||
self.sensor = ['SATBD02-DBPM010:Y2','SATBD02-DBPM040:Y2']
|
||||
self.acq = [BSAcquisition("machine","sfbd", default_channels=self.sensor)]
|
||||
# auxiliar data to be read one
|
||||
aux = ['SATCL01-MBND100:ENERGY-OP']
|
||||
# scanner
|
||||
self.branch='Athos_Dump'
|
||||
self.path = '%s-%s' % (self.scanname,self.branch)
|
||||
self.scanner = Scanner(data_base_dir=self.path,scan_info_dir=self.path,
|
||||
make_scan_sub_dir=True,
|
||||
default_acquisitions=self.acq)
|
||||
|
||||
|
||||
|
||||
|
||||
def setup(self,scl = 1, Nsteps=5, Nsamples=5):
|
||||
val = self.adj.get_current_value(readback=False)
|
||||
dval = self.amp*scl
|
||||
self.N = Nsteps
|
||||
self.Ns= Nsamples
|
||||
self.values=np.linspace(val-dval,val+dval,num=self.N)
|
||||
|
||||
|
||||
def preaction(self):
|
||||
for key in self.pre.keys():
|
||||
self.pre[key]['InitVal'] = self.pre[key]['adj'].get_current_value(readback = False)
|
||||
self.pre[key]['adj'].set_target_value(self.pre[key]['Val'])
|
||||
|
||||
def postaction(self):
|
||||
for key in self.pre.keys():
|
||||
self.pre[key]['adj'].set_target_value(self.pre[key]['InitVal'])
|
||||
|
||||
|
||||
def scan(self):
|
||||
self.sc=self.scanner.ascan_list(self.adj,self.values,
|
||||
filename=self.scanname,start_immediately = False,
|
||||
n_pulses=self.Ns,return_to_initial_values=True)
|
||||
self.preaction()
|
||||
self.sc.run()
|
||||
self.auxdata = getAux(self.aux)
|
||||
self.postaction()
|
||||
|
||||
|
||||
def stop(self):
|
||||
if self.sc is None:
|
||||
return
|
||||
self.sc.stop()
|
||||
|
||||
def running(self):
|
||||
return self.sc.running
|
||||
|
||||
def status(self):
|
||||
si = self.sc.scan_info.to_dict()
|
||||
steps = 0
|
||||
if 'scan_values' in si:
|
||||
steps=len(si['scan_values'])
|
||||
return steps,self.N
|
||||
|
||||
def info(self):
|
||||
return self.sc.scan_info.to_dict()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
111
app/hero.py
Normal file
111
app/hero.py
Normal file
@ -0,0 +1,111 @@
|
||||
import datetime
|
||||
import numpy as np
|
||||
|
||||
from slic.core.acquisition import PVAcquisition
|
||||
from slic.core.acquisition import BSAcquisition
|
||||
from slic.devices.general import motor
|
||||
from slic.core.scanner import Scanner
|
||||
from sfbd.ext import CamAcquisition
|
||||
|
||||
# some temporary wrapper
|
||||
class PollingPVAcquisition(PVAcquisition):
|
||||
def _acquire(self, *args, polling=True, **kwargs):
|
||||
return super()._acquire(*args, polling=polling, **kwargs)
|
||||
|
||||
class LaserScanBase:
|
||||
def __init__(self):
|
||||
print('Init Base Class')
|
||||
self.SV= 'SSL-LMOT-M1104:MOT'
|
||||
self.pol = motor.Motor(self.SV)
|
||||
|
||||
def stop(self):
|
||||
if self.sc is None:
|
||||
return
|
||||
self.sc.stop()
|
||||
|
||||
def running(self):
|
||||
return self.sc.running
|
||||
|
||||
def status(self):
|
||||
si = self.sc.scan_info.to_dict()
|
||||
steps = 0
|
||||
if 'scan_values' in si:
|
||||
steps=len(si['scan_values'])
|
||||
return steps,self.N
|
||||
|
||||
def info(self):
|
||||
return self.sc.scan_info.to_dict()
|
||||
|
||||
def setup(self,amax=21,Nsteps=5,Nsamples=5):
|
||||
amin = 0
|
||||
self.N = Nsteps
|
||||
self.Ns= Nsamples
|
||||
self.values=np.linspace(19,21,num=self.N) # needs a change
|
||||
|
||||
# measuring the pulse energy as a function of the controling PV. Note that the power should be limited to 300 uJ
|
||||
# thus limiting the value of the actuaor defining the lase rpulse energy in the EnergyModulaiton class.
|
||||
|
||||
class LaserPower(LaserScanBase):
|
||||
def __init__(self):
|
||||
super(LaserPower,self).__init__()
|
||||
|
||||
self.scanname = 'HEROLaserEnergy'
|
||||
dirpath= datetime.datetime.now().strftime('/sf/data/measurements/%Y/%m/%d/slic_sfbd')
|
||||
self.scandir='%s/%s' % (dirpath,self.scanname)
|
||||
|
||||
self.RB = 'SSL-LENG-SLNK1:VAL_GET'
|
||||
self.erg = PollingPVAcquisition("machine","sfbd", default_channels=[self.RB])
|
||||
|
||||
self.scanner = Scanner(data_base_dir=self.scandir,scan_info_dir=self.scandir,make_scan_sub_dir=True,
|
||||
default_acquisitions=[self.erg])
|
||||
|
||||
def scan(self):
|
||||
self.sc=self.scanner.ascan_list(self.pol,self.values,
|
||||
filename=self.scanname,start_immediately = False,
|
||||
n_pulses=self.Ns,return_to_initial_values=True)
|
||||
self.sc.run()
|
||||
|
||||
|
||||
|
||||
|
||||
# measuring the coherent emission/space charge blow-up as a function of the hero energy modulation
|
||||
|
||||
class EnergyModulation(LaserScanBase):
|
||||
def __init__(self, acq = 0):
|
||||
super(EnergyModulation,self).__init__()
|
||||
self.scanname = 'HEROEnergyModulation'
|
||||
dirpath= datetime.datetime.now().strftime('/sf/data/measurements/%Y/%m/%d/slic_sfbd')
|
||||
self.scandir='%s/%s' % (dirpath,self.scanname)
|
||||
|
||||
self.acq = acq
|
||||
if self.acq == 0:
|
||||
self.RB ='SATFE10-PEPG046-EVR0:CALCI'
|
||||
self.erg = BSAcquisition("machine","sfbd", default_channels=[self.RB])
|
||||
elif self.acq == 1:
|
||||
self.RB ='SATBD02-DBPM040:Y2'
|
||||
self.erg = BSAcquisition("machine","sfbd", default_channels=[self.RB])
|
||||
elif self.acq == 2:
|
||||
self.RB = 'SATBD01-DSCR210'
|
||||
self.erg = CamAcquisition("machine","sfbd", default_channels=[self.RB])
|
||||
self.erg.getConnection(self.RB)
|
||||
else:
|
||||
self.RB = 'SATBD02-DSCR050'
|
||||
self.erg = CamAcquisition("machine","sfbd", default_channels=[self.RB])
|
||||
self.erg.getConnection(self.RB)
|
||||
|
||||
self.scanner = Scanner(data_base_dir=self.scandir,scan_info_dir=self.scandir,make_scan_sub_dir=True,
|
||||
default_acquisitions=[self.erg])
|
||||
|
||||
def scan(self):
|
||||
self.sc=self.scanner.ascan_list(self.pol,self.values,
|
||||
filename=self.scanname,start_immediately = False,
|
||||
n_pulses=self.Ns,return_to_initial_values=True)
|
||||
self.sc.run()
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
@ -11,7 +11,7 @@ class SpectralAnalysis:
|
||||
"""
|
||||
def __init__(self):
|
||||
|
||||
self.bs = BSCache()
|
||||
self.bs = BSCache(100000,10000) # 100 second timeout, size for 100 second data taken
|
||||
self.bs.stop()
|
||||
|
||||
self.channel = ''
|
||||
@ -35,8 +35,7 @@ class SpectralAnalysis:
|
||||
self.bs.pt.running.clear() # for some reason I have to
|
||||
|
||||
def flush(self):
|
||||
with self.bs.pt.queue.mutex:
|
||||
self.bs.pt.queue.queue.clear()
|
||||
self.bs.flush()
|
||||
|
||||
def read(self):
|
||||
data=self.bs.__next__()
|
||||
|
Reference in New Issue
Block a user