Commit cb10ba2b authored by Simone Liuzzo's avatar Simone Liuzzo
Browse files

recovered +hdb from matutil

parent e7bef8da
function varargout = dataset(self,s1,s2,varargin)
%DATASET Return a HDB dataset
%
%[DATA1,DATA2,...]=DATASET(T1,T2,SIGNAL1,SIGNAL2,...)
%
%T1: Start time, as a date string or date number
%T2: End time, as a date string or date number
%SIGNALn: String identifying the signal (ex.: 'sr/d-ct/1/current')
%
%DATAn: HDB dataset
%See also: extract
t1=self.datim(s1);
t2=self.datim(s2);
nout=nargin-3;
tic;
[data,~]=self.getdata(t1,t1,t2,varargin{:}); toc
if nargout==nout
varargout=data;
else
varargout={cat(2,data{:})};
end
end
\ No newline at end of file
function varargout = extract(self,s1,s2,varargin)
%EXTRACT Extract data from HDB
%
%[DATA1,DATA2,...]=EXTRACT(T1,T2,SIGNAL1,SIGNAL2,...)
%
%T1: Start time, as a date string or date number
%T2: End time, as a date string or date number
%SIGNALn: String identifying the signal (ex.: 'sr/d-ct/1/current')
%
%DATAn: hdb.series containing the data
%
%DATA=EXTRACT(T1,T2,SIGNAL1,SIGNAL2,...)
%
%DATA 1xN array of hdb.series containing the data
%
%[...]=EXTRACT(T1,T2,INTERVAL,...)
% Resample the data at the given interval [s]
%
%See also: hdb.series
t1=self.datim(s1);
t2=self.datim(s2);
if isnumeric(varargin{1}) % With resampling
interval=varargin{1};
dt=seconds(120);
range=0:interval:seconds(t2-t1);
nout=nargin-4;
tic
[data,siginfos]=self.getdata(t1,t1-dt,t2+dt,varargin{2:end}); toc
out=cellfun(@samp,data,siginfos,'UniformOutput',false); toc
else % No resampling
nout=nargin-3;
tic;
[data,siginfos]=self.getdata(t1,t1,t2,varargin{:}); toc
out=cellfun(@hdb.reader.process,data,siginfos,'UniformOutput',false); toc
end
if nargout==nout
varargout=out;
else
varargout={cat(2,out{:})};
end
function ts=samp(dataset,siginfo)
u=hdb.reader.process(dataset,siginfo);
try
ts=u.resample(range);
catch
warning('Hdb:NotEnoughdata','Cannot resample because there are less that 2 data points');
ts=[];
end
end
end
\ No newline at end of file
function val=process(dataset,siginfo,varargin)
%PROCESS Process a HDB dataset into a matlab time series
%
%H=PROCESS(DATASET,SIGINFO)
persistent epoch sel
if isempty(epoch)
epoch=datetime(0,'ConvertFrom','posixtime','TimeZone','local');
end
if isempty(sel)
sel=hdb.typeinit();
end
t0=seconds(siginfo.StartDate-epoch);
sz=dataset.size();
typinfo=sel(dataset.getType()+1);
[defval,~]=getoption(varargin,'Default',typinfo.vini);
k=typinfo.dclass(0);
if typinfo.isarray % Array
t=NaN(sz,1);
r=cell(typinfo.dsize,sz);
for i=1:sz
hdbdata=dataset.get(i-1);
t(i)=hdbdata.getDataTime();
if ~hdbdata.hasFailed()
r{1,i}=reshape(typinfo.dclass(hdbdata.getValue()),1,[]);
if typinfo.dsize == 2
r{2,i}=reshape(typinfo.dclass(hdbdata.getWriteValue()),1,[]);
end
end
end
if isnumeric(k)
try
missing=cellfun(@isempty,r);
tz=size(r{find(~missing,1)});
r(missing)={defval*ones(tz)};
val=hdb.series(cat(1,r{:}),1.0E-6*t-t0,'Name',siginfo.Label);
catch err
disp(err);
val=hdb.cellseries(r',1.0E-6*t-t0,'Name',siginfo.Label);
end
else
val=hdb.cellseries(r',1.0E-6*t-t0,'Name',siginfo.Label);
end
elseif isfloat(k)
t=double(dataset.getDataTimeArray());
if typinfo.dsize == 2
r=[dataset.getValueAsDoubleArray() dataset.getWriteValueAsDoubleArray()];
else
r=dataset.getValueAsDoubleArray();
end
val=hdb.series(typinfo.dclass(r),1.0E-6*t-t0,'Name',siginfo.Label);
else
dataset.setInvalidValueForInteger(defval)
t=double(dataset.getDataTimeArray());
if typinfo.dsize == 2
r=[dataset.getValueAsLongArray() dataset.getWriteValueAsLongArray()];
else
r=dataset.getValueAsLongArray();
end
val=hdb.series(typinfo.dclass(r),1.0E-6*t-t0,'Name',siginfo.Label);
end
val.TimeInfo.StartDate=datenum(siginfo.StartDate);
if (sz==0) || (seconds(val.Time(end)-val.Time(1)) < days(2))
val.TimeInfo.Format='HH:MM';
else
val.TimeInfo.Format='dd/mm';
end
val.TimeInfo.Units='seconds';
val.DataInfo.Units=siginfo.Units;
val.DataInfo.Interpolation=typinfo.interp;
val.SignalInfo=rmfield(siginfo,{'Units','StartDate'});
end
%hdb.reader: HDB reader object
%
%A hdb.reader object connects to hdb ('ORACLE') or hdb++ ('CASSANDRA')
%and allows data extraction?
%
%Constructor:
%hdb.reader(hdb_type)
%
%Methods:
%attributes Return the list of available signals
%extract Extract data from HDB into a hdb.series
%dataset Return a HDB dataset
%getinfo Get a signal configuration
%getfullname Get the fully qualified signal name
%
%See also: hdb.series
classdef reader < handle
properties (Access=private, Hidden)
protocol
end
properties (Hidden)
rdr
end
methods (Static, Access=private)
val=process(dataset,siginfo)
function dt = datim(inpt)
%Generate a datetime object from string or datenum
if ischar(inpt)
dt=tcheck(inpt);
elseif isnumeric(inpt)
dt=datetime(inpt,'ConvertFrom','datenum','TimeZone','local');
else
dt=inpt;
dt.TimeZone='local';
end
dt.Format='dd/MM/yyyy HH:mm:ss';
function dt=tcheck(inpt)
try
dt=datetime(inpt,'InputFormat','dd/MM/yyyy HH:mm:ss','TimeZone','local');
return
catch
end
try
dt=datetime(inpt,'InputFormat','dd/MM/yyyy','TimeZone','local');
return
catch
end
dt=datetime(inpt,'TimeZone','local');
end
end
end
methods
function this=reader(type)
%READER(HDB_TYPE)
%
%HDB_TYPE: Can be 'ORACLE' or 'CASSANDRA'
if nargin < 1
type='CASSANDRA';
end
hhh=org.tango.jhdb.Hdb();
switch type
case 'CASSANDRA'
hhh.connectCassandra({'hdbr1','hdbr2','hdbr3'},'hdb','','');
this.protocol={'userhost','//orion','domain','.esrf.fr','port',':10000'};
case 'ORACLE'
hhh.connectOracle()
this.protocol={'userhost','//aries'};
end
this.rdr=hhh.getReader();
this.rdr.setExtraPointLookupPeriod(3600*24);
this.rdr.enableExtraPoint();
end
varargout = extract(this,s1,s2,varargin)
varargout = dataset(this,s1,s2,varargin)
function attrs = attributes(this)
%Return the list of available attributes
%
%ATTR_LIST=ATTRIBUTES()
attrs=cell(this.rdr.getAttributeList());
end
function [signame,siginfo,param]=getinfo(this,signal)
%Get signal configuration from HDB
%[SIGNAME,SIGINFO,SIGPARAMS]=GETINFO(SIGNAL)
%SIGNAME: Fully qualified signal name
%SIGINFO: org.tango.jhdb.HdbSigInfo
%SIGPARAMS: org.tango.jhdb.HdbSigParam
signame=this.getfullname(signal);
siginfo=this.rdr.getSigInfo(signame);
try
param=this.rdr.getLastParam(signame);
catch err
if isa(err,'matlab.exception.JavaException') && ...
isa(err.ExceptionObject,'org.tango.jhdb.HdbFailed')
warning('Hdb:Param','No configuration data for signal %s',signal);
param=org.tango.jhdb.HdbSigParam();
param.label=java.lang.String(signal);
param.unit=java.lang.String('');
param.format=java.lang.String('%7.3f');
param.display_unit=1;
else
rethrow(err);
end
end
end
function sign=getfullname(this,signal)
%get the fully qualified signal name
cs=urlsplit(signal,'scheme','tango:',this.protocol{:});
sign=strcat(cs.scheme,cs.userhost,cs.domain,cs.port,'/',cs.path);
end
end
methods (Access=protected, Hidden)
function [datasets,siginfos] = getdata(this,t0,t1,t2,varargin)
%Get raw data from HDB
%[DATASETS,SIGINFOS]=GETDATA(T0,T1,T2,SIGNAL1,SIGNAL2,...)
[signames,siginfos]=cellfun(@(s) this.getsigtype(t0,s),varargin,'UniformOutput',false);
datasets=cell(this.rdr.getData(signames,char(t1),char(t2),0))';
end
function [signame,siginfo] = getsigtype(this,t0,signal)
%Get signal properties from HDB
%[SIGNAME,SIGINFO]=GETSIGTYPE(T0,SIGNAL)
[signame,sinfo,param]=this.getinfo(signal);
siginfo.Name=signal;
siginfo.Type=char(org.tango.jhdb.HdbSigInfo.typeStr(sinfo.type+1));
siginfo.StartDate=t0;
siginfo.Label=char(param.label);
siginfo.Units=char(param.unit);
if any(sinfo.type == [41 42]) % Special case for scalar "State" variables
siginfo.Format='%s';
else
siginfo.Format=[char(param.format) ' ' siginfo.Units];
end
if isfinite(param.display_unit)
siginfo.DisplayUnit=param.display_unit;
else
siginfo.DisplayUnit=1;
end
try % While info missing in parameters
attrinfo=tango.Attribute(signal).attrinfo;
siginfo.YLim=siginfo.DisplayUnit*[attrinfo.min_value attrinfo.max_value];
catch
siginfo.YLim=[-Inf Inf];
end
end
end
end
%HDB.CELLSERIES HDB output
%HDB.CELLSERIES is used for HDB signal values which are not scalar numeric
classdef cellseries
properties
Name='unnamed'
SignalInfo=struct('DisplayUnit',1,'YLim',[-Inf Inf],'typeStr','none'); %Signal properties (unit, format...)
TimeInfo=struct()
DataInfo=struct()
end
properties
Data
Time
end
properties (Dependent=true, SetAccess=private)
StartDate % Starting date of the dataset
end
methods
function this=cellseries(d,t,varargin)
%cellseries(data,time,'optname',optval,...)
this.Data=d;
this.Time=t;
for k=1:2:length(varargin)
this.(varargin{k})=varargin{k+1};
end
end
function h1=getsamples(this,range)
%getsamples Obtain a subset of hdb.cellseries samples as another hdb.cellseries
%using a subscript/index array.
%
% TSOUT = getsamples(TSIN,I) returns a timeseries obtained from the samples
% of the timeseries TSIN corresponding to the time(s) TSIN.TIME(I).
h1=hdb.cellseries(this.Data(range,:),this.Time(range),...
'Name',this.Name,'SignalInfo',this.SignalInfo,...
'TimeInfo',this.TimeInfo,'DataInfo',this.DataInfo);
end
function v=cellstr(this)
%Cell array of strings, one line per sample
dt=this.Data;
fmt=['\t' this.SignalInfo.Format];
ct=arrayfun(@char,this.datetime,'UniformOutput',false);
cd=cellfun(@sp,dt,'UniformOutput',false);
v=[ct cd];
function strg=sp(ln)
if iscell(ln)
items=cellfun(@(v) sprintf(fmt,v),ln,'UniformOutput',false);
elseif ischar(ln)
items={sprintf(fmt,ln)};
else
items=arrayfun(@(v) sprintf(fmt,v),ln,'UniformOutput',false);
end
strg=cat(2,items{:});
strg(1)=[];
end
end
function varargout=datetime(this,varargin)
%Gives datatime values corresponding to each sample
varargout=arrayfun(@dt,this,'UniformOutput',false);
function tm=dt(h)
tm=datetime(h.TimeInfo.StartDate,'convertFrom','datenum',varargin{:})+...
seconds(h.Time);
end
end
function tm=get.StartDate(this)
tm=datetime(this.TimeInfo.StartDate,'convertFrom','datenum');
end
function this = setprop(this,propName,propVal)
this.(propName) = propVal;
end
function propval = getprop(this,propName)
propval = this.(propName);
end
end
end
function rdr=connect(type)
%HDB.CONNECT return a hdb.reader object for hdb access
%
%READER=HDB.CONNECT(TYPE)
%
%TYPE: 'ORACLE' for legacy HDB, 'CASSANDRA' for hdb++ (default: 'CASSANDRA')
%
%READER: object used for extracting datafrom HDB
%
%See also: HDB.READER, HDB.SERIES, HDB.EXTRACT
persistent reader
if nargin < 1
type='CASSANDRA';
end
if ~isfield(reader,type)
reader.(type)=hdb.reader(type);
end
rdr=reader.(type);
end
function varargout = extract(s1,s2,varargin)
%EXTRACT Extract data from HDB++ (CASSANDRA)
%
%[DATA1,DATA2,...]=HDB.EXTRACT(T1,T2,SIGNAL1,SIGNAL2,...)
%
%T1: Start time, as a date string (dd/MM/yyyy HH:mm:ss) or date number
%T2: End time, as a date string or date number
%SIGNALn: String identifying the signal (ex.: 'sr/d-ct/1/current')
%
%DATAn: hdb.series containing the data
%
%DATA=HDB.EXTRACT(T1,T2,SIGNAL1,SIGNAL2,...)
%
%DATA 1xN array of hdb.series containing the data
%
%[...]=HDB.EXTRACT(T1,T2,INTERVAL,...)
% Resample the data at the given interval [s]
%
%See also: HDB.CONNECT, HDBO.EXTRACT HDB.SERIES
[varargout{1:nargout}]=hdb.connect('CASSANDRA').extract(s1,s2,varargin{:});
end
\ No newline at end of file
%HDB.SERIES HDB series object.
%This is a timeseries object with an additional 'SignalInfo' property
%containing additional properties extracted from HDB.
%
% H = HDB.SERIES creates an empty HDB series object.
%
% H = HDB.SERIES(DATA) creates a HDB series object H using
% data DATA. By default, the time vector ranges from 0 to N-1,
% where N is the number of samples, and has an interval of 1 second. The
% default name of the TS object is 'unnamed'.
%
% H = HDB.SERIES(NAME), where NAME is a string, creates an
% empty time series object TS called NAME.
%
% H = HDB.SERIES(DATA,TIME) creates a HDB series object H
% using data DATA and time in TIME. Note: When the times
% are date strings, the TIME must be specified as a cell array of date
% strings. When the data contains three or more dimensions, the length of
% the time vector must match the size of the last data dimension
%
%Constructor:
%hdb.series(data,time,'Name',name)
%
%Methods:
%datetime Gives datatime values corresponding to each sample
%plot
%getsamples Subset obtained by using a subscript/index array on Time
%getdata Subset obtained by using a subscript/index array on Data
%
%Properties:
%SignalInfo Signal properties (label, unit, format...)
%Data Signal value (as returned by the device server)
%DisplayData Signal values scaled for display
%Time Signal time, in seconds from the start of the dataset
%StartDate Beginning of the dataset
classdef series < timeseries
properties
SignalInfo=struct('DisplayUnit',1,'YLim',[-Inf Inf],'typeStr','none'); %Signal properties (unit, format...)
end
properties (Dependent=true, SetAccess=private)
DisplayData % Data scaled for display
StartDate % Starting date of the dataset
end
methods (Access=private, Hidden)
function YL=updatelim(self,YLim)
lim=[YLim;self.SignalInfo.YLim];
YL=[min(lim(:,1)),max(lim(:,2))];
end
end
methods
function h=series(varargin)
%hdb.series(data,time,'Name',name)
h@timeseries(varargin{:});
end
function v=cellstr(self)
%Cell array of strings, one line per sample
fmt=self.SignalInfo.Format;
ct=arrayfun(@char,self.datetime,'UniformOutput',false);
cd=arrayfun(@(v) sprintf(fmt,v),self.DisplayData,'UniformOutput',false);
v=[ct cd];
end
function h=getdata(self,drange)
%Extract the selected columns from the data
h=hdb.series(self.Data(:,drange),self.Time,'Name',self.Name);
h.TimeInfo=self.TimeInfo;
h.DataInfo=self.DataInfo;
h.SignalInfo=self.SignalInfo;
end
function h=getsamples(self,range)
%getsamples Obtain a subset of hdb.series samples as another hdb.series
% using a subscript/index array.
%
% TSOUT = getsamples(TSIN,I) returns a timeseries obtained from the samples
% of the timeseries TSIN corresponding to the time(s) TSIN.TIME(I).
h=getsamples@timeseries(self,range);
h.Name=self.Name;
end
function dt=get.DisplayData(self)
dt=self.SignalInfo.DisplayUnit.*self.Data;
end
function tm=get.StartDate(self)
tm=datetime(self.TimeInfo.StartDate,'convertFrom','datenum');
end
function varargout=datetime(self,varargin)
%Gives datatime values corresponding to each sample
varargout=arrayfun(@dt,self,'UniformOutput',false);
function tm=dt(h)
tm=datetime(h.TimeInfo.StartDate,'convertFrom','datenum',varargin{:})+...
seconds(h.Time);
end
end
function varargout=plot(self,varargin)
prt=find(cellfun(@(arg) isa(arg,'char') && strcmpi(arg,'parent'),...
varargin(1:end-1)),1);
if ~isempty(prt)
ax=varargin{prt+1};
else
ax=gca;
end
nb=length(self);
hpl=plot@timeseries(self(1).SignalInfo.DisplayUnit.*self(1),...
'DisplayName',self(1).Name,varargin{:});
if ishold(ax)
YLim=self(1).updatelim(get(ax,'YLim'));
else
YLim=self(1).SignalInfo.YLim;
end
if nb>1
hold(ax,'on')
for i=2:nb
hi=self(i);
YLim=hi.updatelim(YLim);
hpl=[hpl;plot@timeseries(hi.SignalInfo.DisplayUnit.*hi,...
'DisplayName',hi.Name,varargin{:})]; %#ok<AGROW>
end
hold(ax,'off')
end
if all(isfinite(YLim))
set(ax,'YLim',YLim);
end
grid(ax,'on');
out={hpl};
varargout=out(1:nargout);
end
end
end
function zz = typeinit()
%UNTITLED5 Summary of this function goes here
% Detailed explanation goes here
import org.tango.jhdb.data.*
zoh=tsdata.interpolation('zoh');
linear=tsdata.interpolation('linear');
v={...
2, false, zoh, NaN, @double, @HdbData;... % 0 'NONE'
1, false, linear,