frappy_psi.cryoltd: fixes after frappy upgrade

This commit is contained in:
l_samenv
2023-06-29 15:05:18 +02:00
committed by Markus Zolliker
parent 1da16f12c4
commit ef5f4cd2f3
2 changed files with 77 additions and 42 deletions

View File

@ -1,3 +1,8 @@
Node('flamemag.psi.ch',
'flame magnet',
interface='tcp://5000'
)
Mod('cio', Mod('cio',
'frappy_psi.cryoltd.IO', 'frappy_psi.cryoltd.IO',
'IO to cryo ltd software', 'IO to cryo ltd software',
@ -14,6 +19,7 @@ Mod('B',
'frappy_psi.cryoltd.MainField', 'frappy_psi.cryoltd.MainField',
'magnetic field', 'magnetic field',
channel='Main', channel='Main',
main='main',
constraint=80000.0, constraint=80000.0,
target=Param( target=Param(
max=35000.0, max=35000.0,
@ -27,6 +33,8 @@ Mod('B',
overshoot={'o': 1.0, 't': 180.0}, overshoot={'o': 1.0, 't': 180.0},
degauss={'s': 500.0, 'd': 30.0, 'f': 5.0, 't': 120.0}, degauss={'s': 500.0, 'd': 30.0, 'f': 5.0, 't': 120.0},
tolerance=5.0, tolerance=5.0,
wait_switch_on = 30,
wait_switch_off = 30,
wait_stable_field=180.0, wait_stable_field=180.0,
) )
@ -34,6 +42,7 @@ Mod('Bx',
'frappy_psi.cryoltd.ComponentField', 'frappy_psi.cryoltd.ComponentField',
'magnetic field x component', 'magnetic field x component',
channel='VMX', channel='VMX',
main='main',
check_against='B', check_against='B',
target=Param( target=Param(
max=200.0, max=200.0,
@ -50,6 +59,7 @@ Mod('By',
'frappy_psi.cryoltd.ComponentField', 'frappy_psi.cryoltd.ComponentField',
'magnetic field y component', 'magnetic field y component',
channel='VMY', channel='VMY',
main='main',
check_against='B', check_against='B',
target=Param( target=Param(
max=100.0, max=100.0,
@ -66,6 +76,7 @@ Mod('Bz',
'frappy_psi.cryoltd.ComponentField', 'frappy_psi.cryoltd.ComponentField',
'magnetic field z component', 'magnetic field z component',
channel='VMZ', channel='VMZ',
main='main',
check_against='B', check_against='B',
target=Param( target=Param(
max=100.0, max=100.0,
@ -82,130 +93,132 @@ Mod('compressorA',
'frappy_psi.cryoltd.Compressor', 'frappy_psi.cryoltd.Compressor',
'compressor A', 'compressor A',
channel='A', channel='A',
main='main',
) )
Mod('compressorB', Mod('compressorB',
'frappy_psi.cryoltd.Compressor', 'frappy_psi.cryoltd.Compressor',
'compressor B', 'compressor B',
channel='B', channel='B',
main='main',
) )
Mod('T_stage1_A', Mod('T_stage1_A',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='1st Stage A', channel='1st Stage A',
main='main', main='main',
) )
Mod('T_stage2_A', Mod('T_stage2_A',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='2nd Stage A', channel='2nd Stage A',
main='main', main='main',
) )
Mod('T_stage1_B', Mod('T_stage1_B',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='1st Stage B', channel='1st Stage B',
main='main', main='main',
) )
Mod('T_stage2_B', Mod('T_stage2_B',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='2nd Stage B', channel='2nd Stage B',
main='main', main='main',
) )
Mod('T_top_A', Mod('T_top_A',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Inner Magnet A (Top)', channel='Inner Magnet A (Top)',
main='main', main='main',
) )
Mod('T_bottom_A', Mod('T_bottom_A',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Inner Magnet A (Bottom)', channel='Inner Magnet A (Bottom)',
main='main', main='main',
) )
Mod('T_top_B', Mod('T_top_B',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Inner Magnet B (Top)', channel='Inner Magnet B (Top)',
main='main', main='main',
) )
Mod('T_bottom_B', Mod('T_bottom_B',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Inner Magnet B (Bottom)', channel='Inner Magnet B (Bottom)',
main='main', main='main',
) )
Mod('T_Z_shim', Mod('T_Z_shim',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Z Shim Former', channel='Z Shim Former',
main='main', main='main',
) )
Mod('T_XY_shim', Mod('T_XY_shim',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='XY Shim Former', channel='XY Shim Former',
main='main', main='main',
) )
Mod('T_XY_vector', Mod('T_XY_vector',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='XY Vector Former', channel='XY Vector Former',
main='main', main='main',
) )
Mod('T_radiation_shield', Mod('T_radiation_shield',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Radiation Shield', channel='Radiation Shield',
main='main', main='main',
) )
Mod('T_persistent_joints', Mod('T_persistent_joints',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Persistent Joints', channel='Persistent Joints',
main='main', main='main',
) )
Mod('T_outer_A', Mod('T_outer_A',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Outer Magnet A', channel='Outer Magnet A',
main='main', main='main',
) )
Mod('T_outer_B', Mod('T_outer_B',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Outer Magnet B', channel='Outer Magnet B',
main='main', main='main',
) )
Mod('T_shim_B', Mod('T_shim_B',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Z Shim Former B', channel='Z Shim Former B',
main='main', main='main',
) )
Mod('T_bore_shield', Mod('T_bore_shield',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Bore Radiation Shield', channel='Bore Radiation Shield',
main='main', main='main',
) )
Mod('T_XYZ_shim', Mod('T_XYZ_shim',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='XYZ Shim Plate', channel='XYZ Shim Plate',
main='main', main='main',
) )
Mod('T_Z_shim_switch', Mod('T_Z_shim_switch',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Z Shim Switch', channel='Z Shim Switch',
main='main', main='main',
) )
Mod('T_main_switch', Mod('T_main_switch',
'frappy_psi.cryoltd.Temperature', 'frappy_psi.cryoltd.Temperature', '',
channel='Main Coil Switch', channel='Main Coil Switch',
main='main', main='main',
) )

View File

@ -28,12 +28,12 @@ changed from the client is fixed for at least 10 seconds.
""" """
import re import re
import time import time
from math import copysign
from frappy.core import HasIO, StringIO, Readable, Drivable, Parameter, Command, \ from frappy.core import HasIO, StringIO, Readable, Drivable, Parameter, Command, \
Module, Property, Attached, Enum, IDLE, BUSY, ERROR, Done Module, Property, Attached, Enum, IDLE, BUSY, ERROR
from frappy.errors import ConfigError, BadValueError, HardwareError from frappy.errors import ConfigError, BadValueError, HardwareError
from frappy.datatypes import FloatRange, StringType, EnumType, StructOf from frappy.datatypes import FloatRange, StringType, EnumType, StructOf
from frappy.states import HasStates, status_code, Retry from frappy.states import HasStates, status_code, Retry
from frappy.features import HasTargetLimits
import frappy_psi.magfield as magfield import frappy_psi.magfield as magfield
# floating point value followed with unit # floating point value followed with unit
@ -128,7 +128,7 @@ class Main(HasIO, Module):
class Channel: class Channel:
main = Attached(Main, default='main') main = Attached(Main)
channel = Property('channel name', StringType()) channel = Property('channel name', StringType())
pollinterval = Parameter(export=False) pollinterval = Parameter(export=False)
block_until = None block_until = None
@ -199,7 +199,7 @@ PersistencyMode = Enum(
) )
class BaseMagfield(HasStates, HasTargetLimits, Channel): class BaseMagfield(HasStates, Channel):
_status_text = '' _status_text = ''
_ready_text = '' _ready_text = ''
_error_text = '' _error_text = ''
@ -214,13 +214,13 @@ class BaseMagfield(HasStates, HasTargetLimits, Channel):
dt = self.parameters['target'].datatype dt = self.parameters['target'].datatype
if dt.min < 1e-99: # make limits symmetric if dt.min < 1e-99: # make limits symmetric
dt.min = - dt.max dt.min = - dt.max
min_, max_ = self.target_limits # min_, max_ = self.target_limits
self.target_limits = [max(min_, dt.min), min(max_, dt.max)] # self.target_limits = [max(min_, dt.min), min(max_, dt.max)]
dt = self.parameters['ramp'].datatype dt = self.parameters['ramp'].datatype
if self.ramp == 0: # unconfigured: take max. if self.ramp == 0: # unconfigured: take max.
self.ramp = dt.max self.ramp = dt.max
if not isinstance(self, magfield.Magfield): if not isinstance(self, magfield.Magfield):
# add unneeded attributes, as the appear in GetAll # add unneeded attributes, as they appear in GetAll
self.switch_heater = None self.switch_heater = None
self.current = None self.current = None
@ -263,7 +263,7 @@ class BaseMagfield(HasStates, HasTargetLimits, Channel):
setpoint=('<CH>_Setpoint', self.to_gauss), setpoint=('<CH>_Setpoint', self.to_gauss),
switch_heater=('<CH>_Heater', self.cvt_switch_heater), switch_heater=('<CH>_Heater', self.cvt_switch_heater),
cs_mode=('<CH>_Persistent Mode', self.cvt_cs_mode), cs_mode=('<CH>_Persistent Mode', self.cvt_cs_mode),
approach_mode=('<CH>_Approach', self.cvt_approach_mode), # no readback: approach_mode=('<CH>_Approach', self.cvt_approach_mode),
) )
def cvt_error(self, text): def cvt_error(self, text):
@ -297,13 +297,14 @@ class BaseMagfield(HasStates, HasTargetLimits, Channel):
def write_target(self, target): def write_target(self, target):
self.reset_error() self.reset_error()
super().write_target(target) super().write_target(target)
return Done return target
def start_sweep(self, target): def start_sweep(self, target):
if self.approach_mode == self.approach_mode.OVERSHOOT: if self.approach_mode == self.approach_mode.OVERSHOOT:
o = self.overshoot['o'] sign = copysign(1, target - self.value) * copysign(1, target)
if (target - self.value) * o < 0: oval = copysign(self.overshoot['o'], sign)
self.write_overshoot(dict(self.overshoot, o=-o)) tval = self.overshoot['t']
self.sendcmd('Set:<CH>:SetOvershoot %g,%g' % (oval, tval))
self.write_ramp(self.ramp) self.write_ramp(self.ramp)
if self.hw_units == 'A': if self.hw_units == 'A':
self.sendcmd('Set:<CH>:Sweep %gA' % (target / self.A_to_G)) self.sendcmd('Set:<CH>:Sweep %gA' % (target / self.A_to_G))
@ -331,6 +332,8 @@ class BaseMagfield(HasStates, HasTargetLimits, Channel):
# wait for overshoot/degauss/cycle # wait for overshoot/degauss/cycle
sm.stabilize_start = sm.now sm.stabilize_start = sm.now
return Retry return Retry
if sm.stabilize_start is None:
sm.stabilize_start = sm.now
if sm.now - sm.stabilize_start < self.wait_stable_field: if sm.now - sm.stabilize_start < self.wait_stable_field:
return Retry return Retry
return self.end_stablilize return self.end_stablilize
@ -368,18 +371,19 @@ class BaseMagfield(HasStates, HasTargetLimits, Channel):
self.block('approach_mode') self.block('approach_mode')
return value return value
@classmethod # no readback:
def cvt_approach_mode(cls, text): # @classmethod
return cls.ApproachMode(text.upper()) # def cvt_approach_mode(cls, text):
# return cls.ApproachMode(text.upper())
overshoot = Parameter('overshoot [%] and hold time [s]', overshoot = Parameter('overshoot [%] and hold time [s]',
StructOf(o=FloatRange(-100, 100, unit='%'), t=FloatRange(0, unit='s')), StructOf(o=FloatRange(0, 100, unit='%'), t=FloatRange(0, unit='s')),
readonly=False, default=dict(o=0, t=0), readonly=False, default=dict(o=0, t=0),
group='approach_settings') group='approach_settings')
def write_overshoot(self, value): #def write_overshoot(self, value):
self.sendcmd('Set:<CH>:SetOvershoot %g,%g' % (value['o'], value['t'])) # self.sendcmd('Set:<CH>:SetOvershoot %g,%g' % (value['o'], value['t']))
return value # return value
cycle = Parameter('start value, damping factor, final value, hold time', cycle = Parameter('start value, damping factor, final value, hold time',
StructOf(s=FloatRange(-100, 100, unit='%'), StructOf(s=FloatRange(-100, 100, unit='%'),
@ -458,26 +462,36 @@ class MainField(BaseMagfield, magfield.Magfield):
def write_mode(self, mode): def write_mode(self, mode):
self.reset_error() self.reset_error()
super().write_mode(mode) # updates mode super().write_mode(mode) # updates mode
return Done return mode
@status_code('PREPARING') @status_code('PREPARING')
def start_ramp_to_field(self, sm): def start_ramp_to_field(self, sm):
self.sendcmd('Set:<CH>:SetApproach 0') # direct mode
self.start_sweep(self.value) self.start_sweep(self.value)
return self.ramp_to_field # -> stabilize_current -> start_switch_on return self.ramp_to_field # -> stabilize_current -> start_switch_on
@status_code('PREPARING') @status_code('PREPARING')
def start_switch_on(self, sm): def start_switch_on(self, sm):
self.write_cs_mode(CsMode.DRIVEN) self.write_cs_mode(CsMode.DRIVEN)
self.sendcmd('Set:<CH>:SetApproach 0') # direct mode
# self.block('switch_heater', 1, 60) # self.block('switch_heater', 1, 60)
self.start_sweep(self.value) self.start_sweep(self.value)
self.block('_ready_text', 'FALSE') self.block('_ready_text', 'FALSE')
# self.switch_on_time = sm.now # not needed? don ein update_switch_heater
return self.wait_for_switch_on # -> start_ramp_to_target -> ramp_to_target -> stabilize_field return self.wait_for_switch_on # -> start_ramp_to_target -> ramp_to_target -> stabilize_field
wait_switch_on = Parameter('minimum time to wait for opening switch')
@status_code('PREPARING') @status_code('PREPARING')
def wait_for_switch_on(self, sm): def wait_for_switch_on(self, sm):
if self.switch_on_time is None:
self.switch_on_time = sm.now
if sm.now - self.switch_on_time < self.wait_switch_on:
return Retry
if self._ready_text == 'FALSE': if self._ready_text == 'FALSE':
return Retry return Retry
self.last_target(sm.target) self._last_target = sm.target
self.sendcmd('Set:<CH>:SetApproach %d' % self.approach_mode)
return self.start_ramp_to_target return self.start_ramp_to_target
def end_stablilize(self, sm): def end_stablilize(self, sm):
@ -491,16 +505,24 @@ class MainField(BaseMagfield, magfield.Magfield):
self.write_cs_mode(CsMode.SEMIPERSISTENT) self.write_cs_mode(CsMode.SEMIPERSISTENT)
else: # PERSISTENT or DISABLED else: # PERSISTENT or DISABLED
self.write_cs_mode(CsMode.PERSISTENT) self.write_cs_mode(CsMode.PERSISTENT)
self.sendcmd('Set:<CH>:SetApproach 0') # direct mode
self.start_sweep(sm.target) self.start_sweep(sm.target)
self.block('_ready_text', 'FALSE') self.block('_ready_text', 'FALSE')
self.block('switch_heater', 1) self.block('switch_heater', 1)
self.switch_off_time = sm.now
return self.wait_for_switch_off # -> start_ramp_to_zero return self.wait_for_switch_off # -> start_ramp_to_zero
wait_switch_off = Parameter('minimum time to wait for closing switch')
@status_code('PREPARING') @status_code('PREPARING')
def wait_for_switch_off(self, sm): def wait_for_switch_off(self, sm):
if self.switch_off_time is None:
self.switch_off_time = sm.now
if sm.now - self.switch_off_time < self.wait_switch_off:
return Retry
if self.switch_heater: if self.switch_heater:
return Retry return Retry
self.last_target(sm.target) self._last_target = sm.target
if self.mode == PersistencyMode.SEMIPERSISTENT: if self.mode == PersistencyMode.SEMIPERSISTENT:
return self.final_status(IDLE, 'semipersistent') return self.final_status(IDLE, 'semipersistent')
return self.ramp_to_zero return self.ramp_to_zero