added new files
This commit is contained in:
@ -12,7 +12,6 @@ class BSCAcquisition(Acquisition):
|
||||
def _acquire(self, filename, channels=None, data_base_dir=None, scan_info=None, n_pulses=100, **kwargs):
|
||||
|
||||
|
||||
print('*** Reading out the cache ****')
|
||||
queue =channels[0] # abusing interface since BSAcquisition assume a list of channels
|
||||
|
||||
# allocating space
|
||||
@ -29,7 +28,6 @@ class BSCAcquisition(Acquisition):
|
||||
for chn in chns:
|
||||
data[chn]['data'][i] = msg[chn]
|
||||
data['pulse_id'][i]=msg['pid']
|
||||
print(msg['pid'])
|
||||
# write out the data file
|
||||
hid = h5py.File(filename,'w')
|
||||
hid.create_dataset('pulse_id', data = data['pulse_id'])
|
||||
|
33
interface/doocs.py
Normal file
33
interface/doocs.py
Normal file
@ -0,0 +1,33 @@
|
||||
import subprocess
|
||||
|
||||
|
||||
def doocsread(mystr):
|
||||
""" mystr input can be a string or a list """
|
||||
if isinstance(mystr, list): # it's a list
|
||||
readCmd = ' '.join(mystr)
|
||||
else:
|
||||
readCmd = mystr
|
||||
cmd = ['doocsget', '-c', readCmd]
|
||||
MyOut = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout, stderr = MyOut.communicate()
|
||||
if b'result->error()' in stdout.split():
|
||||
print('ERROR: reading error')
|
||||
print(mystr)
|
||||
return
|
||||
result = [element.decode('utf-8') for element in stdout.split()]
|
||||
if len(result) == 1: # one element only
|
||||
try:
|
||||
return float(result[0])
|
||||
except Exception as e:
|
||||
return result[0]
|
||||
else:
|
||||
try:
|
||||
return [float(x) for x in result]
|
||||
except Exception as e:
|
||||
return result
|
||||
|
||||
|
||||
def doocswrite(mystr, target):
|
||||
cmd = ['doocsput', '-c', mystr, '-d', str(target)]
|
||||
MyOut = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
|
||||
stdout, stderr = MyOut.communicate()
|
153
interface/magnet.py
Normal file
153
interface/magnet.py
Normal file
@ -0,0 +1,153 @@
|
||||
from time import sleep
|
||||
from epics import PV,caget_many, caput_many
|
||||
import numpy as np
|
||||
from threading import Thread
|
||||
from time import sleep
|
||||
|
||||
#from onlinemodel.interface import SwissFELMagnet
|
||||
|
||||
class Magnet:
|
||||
|
||||
def __init__(self, beamline = 'ARAMIS',debug=False, signal = None, cal = None):
|
||||
self.beamline = beamline
|
||||
self.debug=debug
|
||||
self.signal = signal
|
||||
self.progress = None
|
||||
# self.cal = SwissFELMagnet()
|
||||
# getting the array
|
||||
temp = np.sort(np.array(list(range(0, 11)) + [0.5, 1.5]))[::-1]
|
||||
temp2 = -1. * temp
|
||||
cyclingCurrents = np.ones(len(temp) * 2) * 0.
|
||||
cyclingCurrents[::2] = temp
|
||||
cyclingCurrents[1::2] = temp2
|
||||
self.currents = cyclingCurrents[:-1]
|
||||
self.cyclingPause = 3
|
||||
self.pvcor = []
|
||||
self.abort = False
|
||||
|
||||
def doAbort(self):
|
||||
self.abort = True
|
||||
|
||||
def setMagnetI(self,maglist,vals):
|
||||
if self.debug:
|
||||
for i,ele in enumerate(maglist):
|
||||
print('DEBUG: Setting %s to: %f A' % (ele,vals[i]))
|
||||
return
|
||||
caput_many(maglist,vals)
|
||||
|
||||
def setMagnets(self,maglist,magbd,erg):
|
||||
for mag in maglist.keys():
|
||||
Itar = self.cal.QuadrupoleKL2I(magbd[mag],maglist[mag],erg*1e6)
|
||||
pv = PV('%s:I-SET' % mag)
|
||||
if not Itar is None:
|
||||
if self.debug:
|
||||
self.signal.emit('DEBUG: Setting %s to %f' % (pv.pvname,Itar))
|
||||
else:
|
||||
pv.value = Itar
|
||||
|
||||
def scaleMagnets(self,maglist,magbg,EProfCur,EProfTar):
|
||||
# get current from magnets
|
||||
for i,mag in enumerate(maglist):
|
||||
if 'SAR' in mag:
|
||||
ecur = EProfCur[-1]
|
||||
etar = EProfTar[-1]
|
||||
elif 'S30' in mag:
|
||||
idx = int(mag[5:7])
|
||||
if idx >= len(EProfCur):
|
||||
ecur = EProfCur[-1]
|
||||
etar = EProfTar[-1]
|
||||
else:
|
||||
ecur = EProfCur[idx]
|
||||
etar = EProfTar[idx]
|
||||
if 'MQUA' in mag:
|
||||
pv = PV('%s:I-SET' % mag)
|
||||
valmag = pv.value
|
||||
strength = self.cal.QuadrupoleI2KL(magbg[i],valmag,ecur*1e6)
|
||||
Itar = self.cal.QuadrupoleKL2I(magbg[i],strength,etar*1e6)
|
||||
elif 'MSEX' in mag:
|
||||
pv = PV('%s:I-SET' % mag)
|
||||
valmag = pv.value
|
||||
strength = self.cal.SextupoleI2KL(magbg[i],valmag,ecur*1e6)
|
||||
Itar = self.cal.SextupoleKL2I(magbg[i],strength,etar*1e6)
|
||||
elif 'MBND' in mag:
|
||||
pv = PV('%s:P-SET' % mag)
|
||||
valmag=pv.value
|
||||
strength = pv.value
|
||||
Itar = valmag-EProfCur[-1]+etar
|
||||
else:
|
||||
strength = 0
|
||||
if not Itar is None:
|
||||
if self.debug:
|
||||
self.signal.emit('DEBUG: Setting %s to %f' % (pv.pvname,Itar))
|
||||
else:
|
||||
pv.value = Itar
|
||||
|
||||
def cycleCorrector(self,QuadList=[],progress=None,done = None):
|
||||
self.progress = progress
|
||||
self.done = done # signal to indicate end of thread
|
||||
self.pvcor = [PV(ele.replace('MQUA','MCRX')) for ele in QuadList]+[PV(ele.replace('MQUA','MCRY')) for ele in QuadList]
|
||||
self.abort = False
|
||||
Thread(name='CycleCor',target=self.TcycleCorrector).start() # starting thread which starts and monitors actual thread
|
||||
|
||||
def TcycleCorrector(self):
|
||||
self.running = True
|
||||
istep = 0
|
||||
nstep = len(self.currents)
|
||||
while self.running:
|
||||
if self.progress:
|
||||
self.progress.emit(istep,nstep)
|
||||
if self.signal:
|
||||
self.signal.emit('Setting corrector current to %5.1f A' % self.currents[istep])
|
||||
if self.debug:
|
||||
print('DEBUG: Setting Corrector Magnets to:',self.currents[istep])
|
||||
else:
|
||||
for pv in self.pvcor:
|
||||
pv.value = cyclingCurrents[istep]
|
||||
sleep(self.cyclingPause)
|
||||
istep+=1
|
||||
if istep == nstep or self.abort:
|
||||
self.running = False
|
||||
if self.progress:
|
||||
self.progress.emit(nstep,nstep)
|
||||
if self.done:
|
||||
self.done.emit(not self.abort)
|
||||
|
||||
|
||||
|
||||
def cycleMagnets(self,maglist, progress = None, done = None):
|
||||
if len(maglist) == 0:
|
||||
done.emit(True)
|
||||
return -1
|
||||
self.progress = progress
|
||||
self.done = done # signal to indicate end of thread
|
||||
state = caget_many(['%s:CYCLE-STATE' % mag for mag in maglist])
|
||||
magcyc = [mag for i,mag in enumerate(maglist) if not state[i] == 2]
|
||||
time = caget_many(['%s:CYCLE-PROGFULL' % mag for mag in magcyc])
|
||||
if len(time) == 0:
|
||||
done.emit(True)
|
||||
return -1 # no cycling needed
|
||||
imax = np.argmax(time)
|
||||
self.tcyc = time[imax]
|
||||
print('Cycling Time:',self.tcyc,'sec for magnet',magcyc[imax])
|
||||
if self.debug:
|
||||
print('DEBUG: Cycle-SET magnets')
|
||||
else:
|
||||
caput_many(['%s:CYCLE' % mag for mag in magcyc],[2]*len(magcyc))
|
||||
self.abort = False
|
||||
Thread(name='CycleMag',target=self.TcycleMagnets).start()
|
||||
return self.tcyc
|
||||
|
||||
def TcycleMagnets(self):
|
||||
self.running = True
|
||||
tcur = 0
|
||||
while self.running:
|
||||
sleep(1)
|
||||
tcur += 1
|
||||
if self.progress:
|
||||
self.progress.emit(tcur,self.tcyc)
|
||||
if tcur >= self.tcyc or self.abort:
|
||||
self.running = False
|
||||
if self.progress:
|
||||
self.progress.emit(self.tcyc,self.tcyc)
|
||||
if self.done:
|
||||
self.done.emit(not self.abort)
|
112
interface/reprate.py
Normal file
112
interface/reprate.py
Normal file
@ -0,0 +1,112 @@
|
||||
from time import sleep
|
||||
from epics import PV
|
||||
import numpy as np
|
||||
|
||||
class RepRate:
|
||||
def __init__(self, beamline = 'ARAMIS',debug=False):
|
||||
self.beamline = beamline
|
||||
self.debug=debug
|
||||
self.pv={}
|
||||
self.pv['BeamDelayAR'] = PV('SIN-TIMAST-TMA:Bunch-1-OnDelay-Sel')
|
||||
self.pv['BeamDelayAT'] = PV('SIN-TIMAST-TMA:Bunch-2-OnDelay-Sel')
|
||||
self.pv['RFDelay'] = PV('SIN-TIMAST-TMA:Beam-RF-OnDelay-Sel')
|
||||
self.pv['StopperAR'] = PV('SARMA02-MBNP100:REQUEST')
|
||||
self.pv['StopperAT'] = PV('SATMA01-MBNP100:REQUEST')
|
||||
self.pv['StopperAROut'] = PV('SARMA02-MBNP100:PLC_MOV_OUT')
|
||||
self.pv['StopperATOut'] = PV('SATMA01-MBNP100:PLC_NOV_OUT')
|
||||
self.pv['BeamRRAR'] = PV('SIN-TIMAST-TMA:Bunch-1-Freq-Sel')
|
||||
self.pv['BeamRRAT'] = PV('SIN-TIMAST-TMA:Bunch-2-Freq-Sel')
|
||||
self.pv['applyTiming'] = PV('SIN-TIMAST-TMA:Beam-Apply-Cmd.PROC')
|
||||
self.rrReal = np.array([100., 50., 33.3, 25., 16.6, 12.5, 10., 8.3, 5., 2.5, 1.])
|
||||
self.rrId = np.arange(0, 11)
|
||||
|
||||
|
||||
def setStopper(self,doinsert):
|
||||
if self.beamline == 'ARAMIS':
|
||||
pv = self.pv['StopperAR']
|
||||
else:
|
||||
pv = self.pv['StopperAT']
|
||||
if self.debug:
|
||||
print('DEBUG: Setting beam stopper to:',doinsert)
|
||||
return
|
||||
if doinsert:
|
||||
pv.value = 1
|
||||
else:
|
||||
pv.value = 0
|
||||
|
||||
def isStopperOpen(self):
|
||||
if self.beamline == 'ARAMIS':
|
||||
return self.pv['StopperAROut']
|
||||
else:
|
||||
return self.pv['StopperATOut']
|
||||
|
||||
|
||||
def stopSF(self):
|
||||
if self.debug:
|
||||
print('DEBUG: Stopping Machine disabled')
|
||||
return
|
||||
if self.beamline == 'ARAMIS':
|
||||
self.pv['BeamDelayAR'].value = 1
|
||||
self.pv['BeamDelayAT'].value = 1
|
||||
sleep(0.1)
|
||||
self.pv['RFDelay'].value =1
|
||||
sleep(0.1)
|
||||
self.pv['applyTiming'].value = 1
|
||||
|
||||
def getRR(self):
|
||||
if self.beamline == 'ARAMIS':
|
||||
return self.rrReal[self.pv['BeamRRAR'].value]
|
||||
else:
|
||||
return self.rrReal[self.pv['BeamRRAT'].value]
|
||||
|
||||
|
||||
def setRR(self,rr=1.):
|
||||
"""
|
||||
Possible RR as of 14/01/2020
|
||||
0 100.00 Hz
|
||||
1 50.00 Hz
|
||||
2 33.33 Hz
|
||||
3 25.00 Hz
|
||||
4 16.66 Hz
|
||||
5 12.50 Hz
|
||||
6 10.00 Hz
|
||||
7 8.33 Hz
|
||||
8 5.00 Hz
|
||||
9 2.50 Hz
|
||||
10 1.00 Hz
|
||||
11 Bunch Off
|
||||
"""
|
||||
|
||||
findRR = abs(self.rrReal - rr) < 0.1
|
||||
if findRR.sum(): # at least one rr is matching
|
||||
rrSel = self.rrId[np.argmax(findRR)]
|
||||
else:
|
||||
print('Requested rep. rate %.3f is not available' % rr)
|
||||
return
|
||||
|
||||
if self.debug:
|
||||
print('DEBUG: Setting beam rate to %d (%f Hz)' % (rrSel,rr))
|
||||
return
|
||||
|
||||
|
||||
if self.beamline == 'ARAMIS':
|
||||
self.pv['BeamRRAR'].value = rrSel
|
||||
sleep(0.1)
|
||||
self.pv['BeamDelayAR'].value = 0 # 0 on beam, 1 on delay
|
||||
rrAT = self.pv['BeamRRAT'].value
|
||||
if rrAT < rrSel: # reduce athos at least to same rep rate as Aramis
|
||||
self.pv['BeamRRAT'].value = rrSel
|
||||
sleep(0.1)
|
||||
self.pv['BeamDelayAT'].value = 0 # 0 on beam, 1 on delay
|
||||
else:
|
||||
self.pv['BeamRRAT'].value = rrSel
|
||||
sleep(0.1)
|
||||
self.pv['BeamDelayAT'].value = 0 # 0 on beam, 1 on delay
|
||||
|
||||
sleep(0.1)
|
||||
if rrSel == 11:
|
||||
self.pv['RFDelay'].value =1
|
||||
else:
|
||||
self.pv['RFDelay'].value = 0
|
||||
sleep(0.1)
|
||||
self.pv['applyTiming'].value = 1
|
60
interface/rf.py
Normal file
60
interface/rf.py
Normal file
@ -0,0 +1,60 @@
|
||||
from epics import PV,caput_many
|
||||
import numpy as np
|
||||
|
||||
class RF:
|
||||
def __init__(self, beamline = 'ARAMIS',debug=False, signal = None):
|
||||
self.beamline = beamline
|
||||
self.debug=debug
|
||||
self.signal = signal
|
||||
if self.beamline == 'ARAMIS':
|
||||
self.stations = ['S30CB%2.2d' % d for d in range(1,14)]
|
||||
self.RFamp = [PV('%s-RSYS:SET-ACC-VOLT' % station) for station in self.stations]
|
||||
self.RFphs = [PV('%s-RSYS:SET-BEAM-PHASE' % station) for station in self.stations]
|
||||
self.RFon = [PV('%s-RSYS:REQUIRED-OP' % station) for station in self.stations]
|
||||
self.ErgRange = [PV('SATSY01-MBND200:P-SET'),PV('SARCL02-MBND100:P-SET')]
|
||||
self.EGain = PV('S30:SET-E-GAIN-OP')
|
||||
self.EPhase= PV('S30:SET-BEAM-PHASE-OP')
|
||||
self.Ns = 13
|
||||
else:
|
||||
self.EGain = ['S20:SET-E-GAIN-OP']
|
||||
self.Ns = 0
|
||||
|
||||
def energyProfile(self):
|
||||
if self.Ns == 0:
|
||||
return np.array([0,0])
|
||||
valAmp = [pv.value for pv in self.RFamp]
|
||||
valPhs = [pv.value for pv in self.RFphs]
|
||||
valOn = [pv.value for pv in self.RFon]
|
||||
valErg = [pv.value for pv in self.ErgRange]
|
||||
|
||||
prof = np.zeros((self.Ns+1))
|
||||
prof[0] = valErg[0]
|
||||
for i in range(self.Ns):
|
||||
dE = 0
|
||||
if valOn[i] == 1:
|
||||
dE = valAmp[i]*np.sin(np.pi*valPhs[i]/180.)
|
||||
prof[i+1] = prof[i]+dE
|
||||
prof = np.array(prof)
|
||||
Egain = prof - prof[0]
|
||||
scl = (valErg[1]-valErg[0])/np.max(Egain)
|
||||
prof = Egain*scl+valErg[0]
|
||||
return prof
|
||||
|
||||
def changeEnergyGain(self,dE):
|
||||
if self.debug:
|
||||
print('DEBUG: Changing energy gain of linac by:',dE)
|
||||
return
|
||||
self.EGain.value = dE
|
||||
if dE > 0:
|
||||
self.EPhase.value = 90.
|
||||
else:
|
||||
self.EPhase.value = -90.
|
||||
|
||||
def setRF(self,chns,vals):
|
||||
if self.debug:
|
||||
for i,ele in enumerate(chns):
|
||||
print('DEBUG: RF-Settings %s: %f' % (ele,vals[i]))
|
||||
return
|
||||
caput_many(chns,vals)
|
||||
|
||||
|
38
util/simplecapture.py
Normal file
38
util/simplecapture.py
Normal file
@ -0,0 +1,38 @@
|
||||
import numpy as np
|
||||
|
||||
from bstrd import BSCache
|
||||
|
||||
class SimpleCapture:
|
||||
def __init__(self):
|
||||
self.chn=None
|
||||
self.bs = BSCache(100000,100000) # 1000 second time out, capazity for 1000 second.
|
||||
self.abort=False
|
||||
|
||||
def terminate(self):
|
||||
self.bs.stop()
|
||||
self.bs.pt.running.clear()
|
||||
|
||||
def stop(self):
|
||||
self.abort=True
|
||||
|
||||
def initChannels(self,channels):
|
||||
self.chn=channels
|
||||
self.bs.get_vars(channels)
|
||||
|
||||
def acquire(self,N=1,reprate=-1,stop=False):
|
||||
self.abort=False
|
||||
data = np.zeros((N,len(self.chn)))
|
||||
pid = np.zeros((N))
|
||||
self.bs.flush()
|
||||
idx = 0
|
||||
while idx<N and not self.abort:
|
||||
rec=self.bs.__next__()
|
||||
pid[idx] = rec['pid']
|
||||
data[idx,:] = np.array([rec[ch] for ch in self.chn])
|
||||
idx += 1
|
||||
ret={}
|
||||
for i,ch in enumerate(self.chn):
|
||||
ret[ch]=data[:,i]
|
||||
ret['pid'] = pid
|
||||
|
||||
return ret
|
Reference in New Issue
Block a user