fix amagnet
Change-Id: I6f1dedd5dfdd10cc828e27ea22440c35a25c2b9d Reviewed-on: https://forge.frm2.tum.de/review/16790 Tested-by: JenkinsCodeReview <bjoern_pedersen@frm2.tum.de> Reviewed-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de> Tested-by: Enrico Faulhaber <enrico.faulhaber@frm2.tum.de>
This commit is contained in:
@ -134,7 +134,7 @@ variable-rgx=[a-z_][a-zA-Z0-9_]{0,30}$
|
|||||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||||
|
|
||||||
# Good variable names which should always be accepted, separated by a comma
|
# Good variable names which should always be accepted, separated by a comma
|
||||||
good-names=i,j,k,ex,Run,_,a,b,c,d,m,n,u,v,w,x,y,z,e
|
good-names=i,j,k,ex,Run,_,a,b,c,d,m,n,u,v,w,x,y,z,e,CMDS,PARAMS,OVERRIDES,DISPATCHER,PROPERTIES
|
||||||
|
|
||||||
# Bad variable names which should always be refused, separated by a comma
|
# Bad variable names which should always be refused, separated by a comma
|
||||||
bad-names=foo,bar,baz,toto,tutu,tata
|
bad-names=foo,bar,baz,toto,tutu,tata
|
||||||
|
@ -23,7 +23,7 @@ encoding=secop
|
|||||||
|
|
||||||
[device enable]
|
[device enable]
|
||||||
class=secop_mlz.entangle.NamedDigitalOutput
|
class=secop_mlz.entangle.NamedDigitalOutput
|
||||||
tangodevice='tango://amagnet.antares.frm2:10000/box/plc/_enable'
|
tangodevice='tango://localhost:10000/box/plc/_enable'
|
||||||
value.datatype=["enum", {'On':1,'Off':0}]
|
value.datatype=["enum", {'On':1,'Off':0}]
|
||||||
target.datatype=["enum", {'On':1,'Off':0}]
|
target.datatype=["enum", {'On':1,'Off':0}]
|
||||||
.description='Enables to Output of the Powersupply'
|
.description='Enables to Output of the Powersupply'
|
||||||
@ -31,7 +31,7 @@ target.datatype=["enum", {'On':1,'Off':0}]
|
|||||||
|
|
||||||
[device polarity]
|
[device polarity]
|
||||||
class=secop_mlz.entangle.NamedDigitalOutput
|
class=secop_mlz.entangle.NamedDigitalOutput
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_polarity
|
tangodevice=tango://localhost:10000/box/plc/_polarity
|
||||||
value.datatype=["enum", {'+1':1,'0':0,'-1':-1}]
|
value.datatype=["enum", {'+1':1,'0':0,'-1':-1}]
|
||||||
target.datatype=["enum", {'+1':1,'0':0,'-1':-1}]
|
target.datatype=["enum", {'+1':1,'0':0,'-1':-1}]
|
||||||
.description=polarity (+/-) switch
|
.description=polarity (+/-) switch
|
||||||
@ -45,7 +45,7 @@ comtries=50
|
|||||||
|
|
||||||
[device symmetry]
|
[device symmetry]
|
||||||
class=secop_mlz.entangle.NamedDigitalOutput
|
class=secop_mlz.entangle.NamedDigitalOutput
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_symmetric
|
tangodevice=tango://localhost:10000/box/plc/_symmetric
|
||||||
value.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}]
|
value.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}]
|
||||||
target.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}]
|
target.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}]
|
||||||
.description=par/ser switch selecting (a)symmetric mode
|
.description=par/ser switch selecting (a)symmetric mode
|
||||||
@ -55,35 +55,35 @@ target.datatype=["enum",{'symmetric':1,'short':0, 'asymmetric':-1}]
|
|||||||
|
|
||||||
[device T1]
|
[device T1]
|
||||||
class=secop_mlz.entangle.AnalogInput
|
class=secop_mlz.entangle.AnalogInput
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t1
|
tangodevice=tango://localhost:10000/box/plc/_t1
|
||||||
.description=Temperature1 of the coils system
|
.description=Temperature1 of the coils system
|
||||||
#warnlimits=(0, 50)
|
#warnlimits=(0, 50)
|
||||||
value.unit='degC'
|
value.unit='degC'
|
||||||
|
|
||||||
[device T2]
|
[device T2]
|
||||||
class=secop_mlz.entangle.AnalogInput
|
class=secop_mlz.entangle.AnalogInput
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t2
|
tangodevice=tango://localhost:10000/box/plc/_t2
|
||||||
.description=Temperature2 of the coils system
|
.description=Temperature2 of the coils system
|
||||||
#warnlimits=(0, 50)
|
#warnlimits=(0, 50)
|
||||||
value.unit='degC'
|
value.unit='degC'
|
||||||
|
|
||||||
[device T3]
|
[device T3]
|
||||||
class=secop_mlz.entangle.AnalogInput
|
class=secop_mlz.entangle.AnalogInput
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t3
|
tangodevice=tango://localhost:10000/box/plc/_t3
|
||||||
.description=Temperature3 of the coils system
|
.description=Temperature3 of the coils system
|
||||||
#warnlimits=(0, 50)
|
#warnlimits=(0, 50)
|
||||||
value.unit='degC'
|
value.unit='degC'
|
||||||
|
|
||||||
[device T4]
|
[device T4]
|
||||||
class=secop_mlz.entangle.AnalogInput
|
class=secop_mlz.entangle.AnalogInput
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/plc/_t4
|
tangodevice=tango://localhost:10000/box/plc/_t4
|
||||||
.description=Temperature4 of the coils system
|
.description=Temperature4 of the coils system
|
||||||
#warnlimits=(0, 50)
|
#warnlimits=(0, 50)
|
||||||
value.unit='degC'
|
value.unit='degC'
|
||||||
|
|
||||||
[device currentsource]
|
[device currentsource]
|
||||||
class=secop_mlz.entangle.PowerSupply
|
class=secop_mlz.entangle.PowerSupply
|
||||||
tangodevice=tango://amagnet.antares.frm2:10000/box/lambda/curr
|
tangodevice=tango://localhost:10000/box/lambda/curr
|
||||||
.description=Device for the magnet power supply (current mode)
|
.description=Device for the magnet power supply (current mode)
|
||||||
abslimits=(0,200)
|
abslimits=(0,200)
|
||||||
speed=1
|
speed=1
|
||||||
|
@ -142,11 +142,11 @@ class OVERRIDE(object):
|
|||||||
# storage for CMDs settings (description + call signature...)
|
# storage for CMDs settings (description + call signature...)
|
||||||
class CMD(object):
|
class CMD(object):
|
||||||
|
|
||||||
def __init__(self, description, arguments=[], result=None):
|
def __init__(self, description, arguments=None, result=None):
|
||||||
# descriptive text for humans
|
# descriptive text for humans
|
||||||
self.description = description
|
self.description = description
|
||||||
# list of datatypes for arguments
|
# list of datatypes for arguments
|
||||||
self.arguments = arguments
|
self.arguments = arguments or []
|
||||||
# datatype for result
|
# datatype for result
|
||||||
self.resulttype = result
|
self.resulttype = result
|
||||||
|
|
||||||
@ -210,18 +210,16 @@ class ModuleMeta(type):
|
|||||||
if rfunc:
|
if rfunc:
|
||||||
self.log.debug("rfunc(%s): call %r" % (pname, rfunc))
|
self.log.debug("rfunc(%s): call %r" % (pname, rfunc))
|
||||||
value = rfunc(self, maxage)
|
value = rfunc(self, maxage)
|
||||||
setattr(self, pname, value)
|
|
||||||
return value
|
|
||||||
else:
|
else:
|
||||||
# return cached value
|
# return cached value
|
||||||
self.log.debug("rfunc(%s): return cached value" % pname)
|
self.log.debug("rfunc(%s): return cached value" % pname)
|
||||||
value = self.PARAMS[pname].value
|
value = self.PARAMS[pname].value
|
||||||
setattr(self, pname, value)
|
setattr(self, pname, value) # important! trigger the setter
|
||||||
return value
|
return value
|
||||||
|
|
||||||
if rfunc:
|
if rfunc:
|
||||||
wrapped_rfunc.__doc__ = rfunc.__doc__
|
wrapped_rfunc.__doc__ = rfunc.__doc__
|
||||||
if getattr(rfunc, '__wrapped__', False) == False:
|
if getattr(rfunc, '__wrapped__', False) is False:
|
||||||
setattr(newtype, 'read_' + pname, wrapped_rfunc)
|
setattr(newtype, 'read_' + pname, wrapped_rfunc)
|
||||||
wrapped_rfunc.__wrapped__ = True
|
wrapped_rfunc.__wrapped__ = True
|
||||||
|
|
||||||
@ -246,7 +244,7 @@ class ModuleMeta(type):
|
|||||||
|
|
||||||
if wfunc:
|
if wfunc:
|
||||||
wrapped_wfunc.__doc__ = wfunc.__doc__
|
wrapped_wfunc.__doc__ = wfunc.__doc__
|
||||||
if getattr(wfunc, '__wrapped__', False) == False:
|
if getattr(wfunc, '__wrapped__', False) is False:
|
||||||
setattr(newtype, 'write_' + pname, wrapped_wfunc)
|
setattr(newtype, 'write_' + pname, wrapped_wfunc)
|
||||||
wrapped_wfunc.__wrapped__ = True
|
wrapped_wfunc.__wrapped__ = True
|
||||||
|
|
||||||
@ -268,16 +266,16 @@ class ModuleMeta(type):
|
|||||||
|
|
||||||
# also collect/update information about CMD's
|
# also collect/update information about CMD's
|
||||||
setattr(newtype, 'CMDS', getattr(newtype, 'CMDS', {}))
|
setattr(newtype, 'CMDS', getattr(newtype, 'CMDS', {}))
|
||||||
for name in attrs:
|
for attrname in attrs:
|
||||||
if name.startswith('do_'):
|
if attrname.startswith('do_'):
|
||||||
if name[3:] in newtype.CMDS:
|
if attrname[3:] in newtype.CMDS:
|
||||||
continue
|
continue
|
||||||
value = getattr(newtype, name)
|
value = getattr(newtype, attrname)
|
||||||
if isinstance(value, types.MethodType):
|
if isinstance(value, types.MethodType):
|
||||||
argspec = inspect.getargspec(value)
|
argspec = inspect.getargspec(value)
|
||||||
if argspec[0] and argspec[0][0] == 'self':
|
if argspec[0] and argspec[0][0] == 'self':
|
||||||
del argspec[0][0]
|
del argspec[0][0]
|
||||||
newtype.CMDS[name[3:]] = CMD(
|
newtype.CMDS[attrname[3:]] = CMD(
|
||||||
getattr(value, '__doc__'), argspec.args,
|
getattr(value, '__doc__'), argspec.args,
|
||||||
None) # XXX: how to find resulttype?
|
None) # XXX: how to find resulttype?
|
||||||
attrs['__constructed__'] = True
|
attrs['__constructed__'] = True
|
||||||
@ -400,11 +398,11 @@ class Module(object):
|
|||||||
# only check if datatype given
|
# only check if datatype given
|
||||||
try:
|
try:
|
||||||
v = datatype.validate(v)
|
v = datatype.validate(v)
|
||||||
except (ValueError, TypeError) as e:
|
except (ValueError, TypeError):
|
||||||
self.log.exception(formatExtendedStack())
|
self.log.exception(formatExtendedStack())
|
||||||
raise
|
raise
|
||||||
raise ConfigError('Module %s: config parameter %r:\n%r' %
|
# raise ConfigError('Module %s: config parameter %r:\n%r' %
|
||||||
(self.name, k, e))
|
# (self.name, k, e))
|
||||||
setattr(self, k, v)
|
setattr(self, k, v)
|
||||||
self._requestLock = threading.RLock()
|
self._requestLock = threading.RLock()
|
||||||
|
|
||||||
@ -431,7 +429,7 @@ class Readable(Module):
|
|||||||
datatype=TupleOf(
|
datatype=TupleOf(
|
||||||
EnumType(**{
|
EnumType(**{
|
||||||
'IDLE': status.OK,
|
'IDLE': status.OK,
|
||||||
# 'BUSY': status.BUSY,
|
'BUSY': status.BUSY,
|
||||||
'WARN': status.WARN,
|
'WARN': status.WARN,
|
||||||
'UNSTABLE': status.UNSTABLE,
|
'UNSTABLE': status.UNSTABLE,
|
||||||
'ERROR': status.ERROR,
|
'ERROR': status.ERROR,
|
||||||
@ -475,7 +473,7 @@ class Readable(Module):
|
|||||||
# status was already polled above
|
# status was already polled above
|
||||||
continue
|
continue
|
||||||
if ((int(pobj.poll) < 0) and fastpoll) or (
|
if ((int(pobj.poll) < 0) and fastpoll) or (
|
||||||
0 == nr % abs(int(pobj.poll))):
|
nr % abs(int(pobj.poll))) == 0:
|
||||||
# poll always if pobj.poll is negative and fastpoll (i.e. Module is busy)
|
# poll always if pobj.poll is negative and fastpoll (i.e. Module is busy)
|
||||||
# otherwise poll every 'pobj.poll' iteration
|
# otherwise poll every 'pobj.poll' iteration
|
||||||
rfunc = getattr(self, 'read_' + pname, None)
|
rfunc = getattr(self, 'read_' + pname, None)
|
||||||
@ -511,18 +509,6 @@ class Drivable(Writable):
|
|||||||
Also status gets extended with a BUSY state indicating a running action.
|
Also status gets extended with a BUSY state indicating a running action.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
OVERRIDES = {
|
|
||||||
"status" : OVERRIDE(datatype=TupleOf(
|
|
||||||
EnumType(**{
|
|
||||||
'IDLE': status.OK,
|
|
||||||
'BUSY': status.BUSY,
|
|
||||||
'WARN': status.WARN,
|
|
||||||
'UNSTABLE': status.UNSTABLE,
|
|
||||||
'ERROR': status.ERROR,
|
|
||||||
'UNKNOWN': status.UNKNOWN
|
|
||||||
}), StringType())),
|
|
||||||
}
|
|
||||||
|
|
||||||
def do_stop(self):
|
def do_stop(self):
|
||||||
"""default implementation of the stop command
|
"""default implementation of the stop command
|
||||||
|
|
||||||
|
@ -28,12 +28,11 @@ Supporting classes for FRM2 magnets, currently only Garfield (amagnet).
|
|||||||
|
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from secop.lib import lazy_property, mkthread
|
|
||||||
from secop.lib.sequence import SequencerMixin, Step
|
from secop.lib.sequence import SequencerMixin, Step
|
||||||
from secop.protocol import status
|
from secop.protocol import status
|
||||||
from secop.datatypes import *
|
from secop.datatypes import StringType, TupleOf, FloatRange, ArrayOf, StructOf
|
||||||
from secop.errors import SECoPServerError, ConfigError, ProgrammingError, CommunicationError, HardwareError, DisabledError
|
from secop.errors import DisabledError, ConfigError
|
||||||
from secop.modules import PARAM, CMD, OVERRIDE, Readable, Drivable
|
from secop.modules import PARAM, Drivable
|
||||||
|
|
||||||
|
|
||||||
class GarfieldMagnet(SequencerMixin, Drivable):
|
class GarfieldMagnet(SequencerMixin, Drivable):
|
||||||
@ -132,7 +131,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
|
|||||||
trycurr = (maxcurr - mincurr) * ratio + mincurr
|
trycurr = (maxcurr - mincurr) * ratio + mincurr
|
||||||
self.log.debug('current for %g T is %g A', field, trycurr)
|
self.log.debug('current for %g T is %g A', field, trycurr)
|
||||||
return trycurr # interpolated
|
return trycurr # interpolated
|
||||||
raise ConfigurationError(self,
|
raise ConfigError(self,
|
||||||
'_current2field polynome not monotonic!')
|
'_current2field polynome not monotonic!')
|
||||||
|
|
||||||
def init(self):
|
def init(self):
|
||||||
@ -195,6 +194,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
|
|||||||
|
|
||||||
def _set_field_polarity(self, polarity):
|
def _set_field_polarity(self, polarity):
|
||||||
current_pol = self._get_field_polarity()
|
current_pol = self._get_field_polarity()
|
||||||
|
polarity = int(polarity)
|
||||||
if current_pol == polarity:
|
if current_pol == polarity:
|
||||||
return
|
return
|
||||||
if polarity == 0:
|
if polarity == 0:
|
||||||
@ -202,7 +202,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
|
|||||||
if current_pol == 0:
|
if current_pol == 0:
|
||||||
# safe to switch
|
# safe to switch
|
||||||
self._polswitch.write_target(
|
self._polswitch.write_target(
|
||||||
'+1' if polarity == 1 else str(polarity))
|
'+1' if polarity > 0 else str(polarity))
|
||||||
return 0
|
return 0
|
||||||
if self._currentsource.value < 0.1:
|
if self._currentsource.value < 0.1:
|
||||||
self._polswitch.write_target('0')
|
self._polswitch.write_target('0')
|
||||||
@ -222,8 +222,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
|
|||||||
if self._enable.read_status(maxage)[0] != status.OK:
|
if self._enable.read_status(maxage)[0] != status.OK:
|
||||||
return self._enable.status
|
return self._enable.status
|
||||||
if self._polswitch.value in ['0', 0]:
|
if self._polswitch.value in ['0', 0]:
|
||||||
return self._currentsource.status[
|
return status.OK, 'Shorted, ' + self._currentsource.status[1]
|
||||||
0], 'Shorted, ' + self._currentsource.status[1]
|
|
||||||
if self._symmetry.value in ['short', 0]:
|
if self._symmetry.value in ['short', 0]:
|
||||||
return self._currentsource.status[
|
return self._currentsource.status[
|
||||||
0], 'Shorted, ' + self._currentsource.status[1]
|
0], 'Shorted, ' + self._currentsource.status[1]
|
||||||
@ -236,7 +235,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
|
|||||||
|
|
||||||
wanted_current = self._field2current(abs(target))
|
wanted_current = self._field2current(abs(target))
|
||||||
wanted_polarity = -1 if target < 0 else (+1 if target else 0)
|
wanted_polarity = -1 if target < 0 else (+1 if target else 0)
|
||||||
current_polarity = self._get_field_polarity()
|
current_polarity = int(self._get_field_polarity())
|
||||||
|
|
||||||
# generate Step sequence and start it
|
# generate Step sequence and start it
|
||||||
seq = []
|
seq = []
|
||||||
@ -320,7 +319,7 @@ class GarfieldMagnet(SequencerMixin, Drivable):
|
|||||||
def _set_polarity(self, store, target):
|
def _set_polarity(self, store, target):
|
||||||
if self._polswitch.read_status(0)[0] == status.BUSY:
|
if self._polswitch.read_status(0)[0] == status.BUSY:
|
||||||
return True
|
return True
|
||||||
if self._polswitch.value == target:
|
if int(self._polswitch.value) == int(target):
|
||||||
return False # done with this step
|
return False # done with this step
|
||||||
if self._polswitch.read_value(0) != 0:
|
if self._polswitch.read_value(0) != 0:
|
||||||
self._polswitch.write_target(0)
|
self._polswitch.write_target(0)
|
||||||
|
Reference in New Issue
Block a user