Commit cbeb3224 authored by Simone Liuzzo's avatar Simone Liuzzo

+cs moved to tango-matlab reository

parent 7733118c
classdef (Abstract) DevError < MException
properties
devname
end
methods (Access=protected)
function err=DevError(dname,errid,varargin)
err@MException(['Cs:' errid],varargin{:});
err.devname=dname;
end
end
methods
function errcode=double(err) %#ok<MANU>
errcode=-1;
end
function iserr=logical(err) %#ok<MANU>
iserr=true;
end
function res=lt(err,value)
res=(double(err)<value);
end
function res=gt(err,value)
res=(double(err)>value);
end
function res=le(err,value)
res=(double(err)<=value);
end
function res=ge(err,value)
res=(double(err)>=value);
end
function mess=char(err)
mess=err.message;
end
function disp(err)
disp([class(err) '(''' err.devname ''')']);
end
% Compatibility function
function mess=dverrmess(err)
mess=char(err);
end
end
end
classdef DevState < uint16
%DevState Enumeration representing device states
% (On,Off,Fault,...)
%
% Comparison operators are redefined to use a severity order,
% where "On" is minimum and "Unknown" is maximum
%
% constant state values may be declared as:
% cs.DevState.On
%
methods(Static,Abstract)
state=Get(statename)
state=Undef(varargin)
end
methods
function st=DevState(i)
st@uint16(double(i));
end
function is=severity(st)
%State severity: from On(1) to Unknown(9)
persistent conv
if isempty(conv)
conv=[1,3,5,1,5,1,4,2,8,4,1,6,7,9,... % 0:13
6,6,2,7,7,1,1,4,6,1,1,8,4,4,... % 14:27
4,4,6,6,4,4,4,7,7,7,7,4,7,4,4,4,3,2,2]; % 28:46
end
is=conv(st+1);
end
function rgb=color(st)
%RGB color representing the state
persistent cmap
if isempty(cmap)
cmap=[...
0,0.5,0;... % 1: On: green
1,1,0;... % 2: Standby: yellow
1,1,1;... % 3: Off: white
0,1,1;... % 4: Moving: cyan
1,0.5,0;... % 5: Inserted: orange
1,0.5,0;... % 6: Alarm: orange
170/255,0,1;... % 7: Disabled: magenta
1,0,0;... % 8: Fault: red
0.5,0.5,0.5... % 9: Unknown; grey
];
end
rgb=cmap(severity(st),:);
end
function h=spot(st,position,sz)
% Plots a square with the state color
if nargin<3,sz=1;end
if nargin<2,position=[0,0]; end
h=patch(position(1)+sz*[-1 1 1 -1 -1],...
position(2)+sz*[-1 -1 1 1 -1],...
st.color());
end
function res=times(st1,st2)
if ~(isscalar(st1) || isscalar(st2) || all(size(st1)==size(st2)))
error('Cs:DevState:size','Matrix dimensions must agree');
end
if isa(st1,'cs.DevState')
res=localtimes(st1,st2);
else
res=localtimes(st2,st1);
end
function res=localtimes(st1,coef)
if isnumeric(coef)
if isscalar(st1)
res=repmat(st1,size(coef));
elseif iscalar(coef)
coef=repmat(coef,size(st1));
res=st1;
end
res(~(coef==1))=st1.Undef;
else
error('Cs:DevState:arith','Impossible operation');
end
end
end
function res=mtimes(st1,st2)
[m1,n1]=size(st1);
[m2,n2]=size(st2);
if ~(isscalar(st1) || isscalar(st2) || ((n1==1)&&(m2==1)))
error('Cs:DevState:size','Matrix dimensions must agree');
end
if isa(st1,'cs.DevState')
if isnumeric(st2)
ok=(st2==1);
res=st1.Undef(m1,n2);
res(:,ok)=repmat(st1,1,sum(ok));
else
error('Cs:DevState:arith','Impossible operation');
end
else
if isnumeric(st1)
ok=(st1==1);
res=st2.Undef(m1,n2);
res(ok,:)=repmat(st2,sum(ok),1);
else
error('Cs:DevState:arith','Impossible operation');
end
end
end
function ok=lt(st1,st2)
ok=st1.severity() < st2.severity();
end
function ok=le(st1,st2)
ok=st1.severity() <= st2.severity();
end
function ok=gt(st1,st2)
ok=st1.severity() > st2.severity();
end
function ok=ge(st1,st2)
ok=st1.severity() >= st2.severity();
end
function [vmi,i]=min(x,varargin)
[~,i]=min(severity(x),varargin{:});
vmi=x(i);
end
function [vma,i]=max(x,varargin)
[~,i]=max(severity(x),varargin{:});
vma=x(i);
end
function [y,i]=sort(x,varargin)
[~,i]=sort(severity(x),varargin{:});
y=x(i);
end
end
end
classdef Device < dynamicprops
%Base class for Tango control system interface
properties(Abstract,SetAccess=private)
Name % Device name (RO)
State % State of the device (cs.DevState enumeration) (RO)
Status % Status string (RO)
end
properties(Abstract)
Timeout % Client time-out (WO)
end
methods(Abstract)
output=cmd(dev,command,input)
list=attributes(dev)
list=commands(dev)
err=error(id,reason,desc)
end
methods(Abstract,Static,Access=protected,Hidden)
st=any2state(code)
end
methods(Static)
function idx=planeid(plane,choices,inp)
%idx=planeid(plane)
% plane: h|H|x|X|1, v|V|z|Z|2
%idx: 1 for horizontal
% 2 for vertical
% error for other
%
%idx=planeid(plane,choices)
% plane: h|H|x|X|1, v|V|z|Z|2
%idx: choices(1) for horizontal
% choices(2) for vertical
% choices(3) for other, or error
if nargin < 3
inp={{'X','H'},{'Z','V'},'S'};
end
if nargin < 2
choices=[1,2];
end
idx=0;
if ischar(plane)
for i=1:length(inp)
if any(strcmpi(plane,inp{i}))
idx=i;
break;
end
end
elseif isscalar(plane) && isnumeric(plane)
idx=plane;
end
if idx <= 0 || idx > length(choices)
error('cs:plane','plane should be h|H|x|X|1 or v|V|z|Z|2');
end
if iscell(choices)
idx=choices{idx};
else
idx=choices(idx);
end
end
end
methods(Access=protected,Hidden)
function prop=addcommand(self,cmdname)
try
prop=self.addprop(cmdname);
prop.Transient=true;
self.(cmdname)=@(varargin) self.cmd(cmdname,varargin{:});
prop.SetAccess='private';
catch err
warning(err.identifier,err.message);
end
end
function prop=addattribute(self,attrname,getfunc,setfunc)
try
prop=addprop(self,attrname);
prop.Transient=true;
prop.Dependent=true;
if nargin <4
prop.SetAccess='private';
else
prop.SetMethod=setfunc;
end
prop.GetMethod=getfunc;
catch err
warning(err.identifier,err.message);
end
end
end
methods
function strname=char(self)
%Convert to character array (string)
strname=self.Name;
end
function disp(self)
%Display the device definition
disp([class(self) '(''' self.Name ''')']);
end
function ok=isState(self,varargin)
%Test the device state with one or several proposals
%ok=device.IsState(state1[,state2,...])
%state1: state to be checked (string, integer or
% cs.DevState
dstate=self.State;
ok=cellfun(@checkargs,varargin);
function ok=checkargs(arg)
if ~isa(arg,'cs.DevState')
arg=self.any2state(arg);
end
ok=(dstate==arg);
end
end
function vok=check(self,varargin)
%Send a Tango command and checks a condition
%ok=device.check(testfun,timeout)
%testfun: test function, called as testfun(dev)
%timeout: maximum time to wait for condition, may be
% {t1,t2,t3}: wait t1, start looping on testfun at
% interval t3, wait for t2 maximum
%ok: true if condition satisfied, false otherwise
%
%ok=device.check(command,testfun,timeout)
%command: command name, may be {command,argin}
if ~isempty(varargin) && isa(varargin{1},'function_handle')
[cmdargs,testfunc,tmout]=cs.getargs([{{}},varargin],{{},@(dev) true,{}});
else
[cmdargs,testfunc,tmout]=cs.getargs(varargin,{{},@(dev) true,{}});
end
if ~iscell(tmout)
tmout={[],tmout};
end
[initim,totaltim,polltim]=cs.getargs(tmout,{0,0,0.5});
if ~isempty(cmdargs)
if ~iscell(cmdargs), cmdargs={cmdargs}; end
self.cmd(cmdargs{:});
end
pause(initim);
ok=testfunc(self);
if ~ok && (totaltim>0)
for t=1:totaltim/polltim
pause(polltim);
ok=testfunc(self);
if ok, break; end
end
end
if ~ok && nargout == 0
self.error('CheckTimeout','Check Timeout','Timeout evaluating the condition').throw();
elseif nargout > 0
vok=ok;
end
end
% Compatibility function
function nm=dvname(self)
%Compatibility function: get device name
nm=self.Name;
end
end
end
function nms=allnames(varargin)
nms=decode({},varargin{:});
function res=decode(res,varargin)
for i=1:numel(varargin)
arg=varargin{i};
if ischar(arg) % char array
res=[res;cellstr(arg)]; %#ok<AGROW>
elseif iscell(arg) % cell array
res=decode(res,arg{:});
elseif isa(arg,'tango.Group')
res=[res;{arg.Name}']; %#ok<AGROW>
elseif isa(arg,'cs.Device')
res=[res;{arg.Name}']; %#ok<AGROW>
else
error('Cs:WrongDeviceName',...
['Argument must be string,cell array of strings, ',...
'cs.Device']);
end
end
end
end
function varargout=dbgprintf(level,format,varargin)
%DBGPRINTF Print debug information
% DBGPRINTF(LEVEL,FORMAT,...)
% Display the formatted message if the level is selected
%
% DBGPRINTF(PRINTFUNC)
% Use PRINTFUNC to display the messages. PRINTFUNC takes only one
% argument: the message to be displayed
%
% DBGPRINTF(MASK)
% Set the mask selecting the displayed messages
%
% DBGPRINTF()
% Revert to the default options: MASK=0, display in the command
% window
%
persistent MASK PRINTFUNC
if isempty(PRINTFUNC)
PRINTFUNC=@(message) disp(message);
dbglevel=getenv('DBGLEVEL');
if isempty(dbglevel)
setmask(0);
else
setmask(str2double(dbglevel));
end
end
if nargin < 1
setmask(0);
setmask(@(message) disp(message));
elseif nargin < 2 && nargout == 0
setmask(level);
else
ok=bitand(level,MASK) || (level==0);
if ok && nargin >= 2
PRINTFUNC(sprintf(['-%d- ' format],level, varargin{:}));
end
if nargout > 0
varargout={ok};
end
end
function setmask(msk)
if isnumeric(msk)
MASK=uint8(msk);
cs.dbgprintf(1,'Set debug level to %d',msk);
elseif isa(msk,'function_handle')
PRINTFUNC=msk;
cs.dbgprintf(1,'Set display function to %s',char(msk));
end
end
end
function varargout = getargs(args,default_values)
%GETARGS Check and expands optional argument lists
%ARGOUT=GETARGS(ARGIN,DEFAULT_VALUES)
%[ARG1,ARG2,...]=GETARGS(ARGIN,DEFAULT_VALUES)
na=min(length(default_values),length(args));
valid=~cellfun(@(arg) isempty(arg)&&isnumeric(arg),args(1:na));
default_values(valid)=args(valid);
if nargout==length(default_values)
varargout=default_values;
else
varargout{1}=default_values;
end
end
function [flag,opts] = getflag(opts,optname)
%GETFLAG Check the presence of an option in an argument list
%
%OPTION=GETFLAG(ARGS,OPTNAME)
%
%ARGS: Argument list (cell array)
%OPTNAME: Name of the desired option (string)
%
%[OPTION,NEWARGS]=GETFLAG(ARGS,OPTNAME)
% Returns the argument list after removing the processed flag
%
%Dee also GETOPTION
ok=strcmpi(optname,opts);
flag=any(ok);
opts=opts(~ok);
end
function [optval,opts] = getoption(opts,optname,defval)
%GETOPTION Extract one option from an option list ['Name',value,...]
%
%OPTVAL=GETOPTION(ARGS,OPTNAME)
% Return the value of the desired option from the argument list and
% send an exception if it is absent.
% OPTLIST: Option list (cell array or structure)
% OPTNAME: Name of the desired option
%
%
%OPTVAL=GETOPTION(ARGS,OPTNAME,OPTDEFAULT)
% Return a default value if the option is absent
% OPTDEFAULT: Default value for the option
%
%[OPTVAL,NEWARGS]=GETOPTION(...)
% Returns remaining options after removing the processed ones
%
%See also GETFLAG
if iscell(opts)
ok=[strcmpi(optname,opts(1:end-1)) false]; %option name cannot be the last argument
if any(ok)
okval=circshift(ok,[0,1]);
defval=opts{find(okval,1,'last')};
opts(ok|okval)=[];
end
elseif isstruct(opts)
if isfield(opts,optname)
defval=opts.(optname);
opts=rmfield(opts,optname);
end
end
try
optval=defval;
catch
error('getoption:missing','Option "%s" is missing',optname);
end
end
function varargout=planeid(plane,varargin)
%idx=selectplane(plane)
% plane selector: h|H|x|X|1, v|V|z|Z|2
%idx: 1 for horizontal
% 2 for vertical
% error for other
%
%[result1,result2,...]=selectplane(plane,selection1,selection2,...)
% plane selector: h|H|x|X|1, v|V|z|Z|2, v2h|V2H|3, h2v|H2V|4
%idx: selection(1) for horizontal
% selection(2) for vertical
% selection(3) for v2h
% selection(4) for h2v
%
%[...]=selectplane(...,'Choices',{choice1,choice2},...)
% Gives the possible choices for the plane selector. Each choice is a
% string or a cell array of strings
% default: {{'X','H'},{'Z','V'},'V2H','H2V'}
%
selection={{1,2}};
[choices,arguments]=getoption(varargin,'Choices',{{'x','h'},{'z','v'},'v2h','h2v'});
selection(1:length(arguments))=arguments;
nmax=min([length(choices) cellfun(@length,selection)]);
idx=0;
if ischar(plane)
for i=1:nmax
if any(strcmpi(plane,choices{i}))
idx=i;
break;
end
end
elseif isscalar(plane) && isnumeric(plane)
idx=plane;
end
if idx <= 0 || idx > nmax
error('cs:plane','plane should be %s',allchoices(choices(1:nmax)));
end
varargout=cellfun(@(arg) arg{idx},selection,'UniformOutput',false);
function res=allchoices(choices)
k=cellfun(@expand,num2cell(1:length(choices)),choices,'UniformOutput',false);
res=cat(2,k{:});
res=res(3:end);
function res=expand(i,choice)
if ischar(choice)
l={cat(2,'|',lower(choice),'|',upper(choice))};
else
l=cellfun(@(o) cat(2,'|',lower(o),'|',upper(o)),choice,'UniformOutput',false);
end
res=cat(2,', ',int2str(i),l{:});
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment