diff --git a/matlab/src/classes/@MatMust/MatMust.m b/matlab/src/classes/@MatMust/MatMust.m index 9b5e1b851a075bb49f14a76ac251fe0d4fa6cb30..fc0cc6fc5291675f29dd157aa639c6b934e137c5 100644 --- a/matlab/src/classes/@MatMust/MatMust.m +++ b/matlab/src/classes/@MatMust/MatMust.m @@ -1,12 +1,6 @@ classdef MatMust < handle %MATMUST A library to get deal with ESA webmust REST API - % Follow indication in methods help. - % - % +++++++++++++++++++++++++++++++++++++ - % Creator: Carmelo Magnafico IAPS/INAF - % date: 20/06/2019 - % - % +++++++++++++++++++++++++++++++++++++ + % MATMUST embed the first properties POSToptions @@ -139,6 +133,8 @@ classdef MatMust < handle % dateStart = 'yyyy-mm-dd HH:MM:SS' format date UTC time % dateStop = 'yyyy-mm-dd HH:MM:SS' format date UTC time % 'dump','plot' optional parameter to dump and plot the data + % 'calibrated' optional parameter that specify that you want + % calibrated data % intialize data output data = []; @@ -154,7 +150,8 @@ classdef MatMust < handle return end end - + + if any(ismember(varargin,'calibrated')) calibrate = 'true'; else calibrate = 'false'; end query = ['dataproviders/',ds,'/parameters/data']; obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token}; @@ -167,7 +164,7 @@ classdef MatMust < handle 'values', (parname),... 'from', (dateStart),... 'to', (dateStop),... - 'calibrate', 'false',... + 'calibrate', calibrate,... 'mode', 'SIMPLE'}; try @@ -215,9 +212,29 @@ classdef MatMust < handle data_par = data(i).data; figure title(sprintf('%s-%s: %s -> %s\n', data(i).subsystem, data(i).type, data(i).name, data(i).description )) - plot([data_par.dateMAT], [data_par.value], '-x' ); + if strcmp(calibrate,'true') + switch class(data_par(1).calibratedValue) + case 'char' + indx = [1,find(diff([data_par.value])~=0)]+1; + ylabels = string; + ylabels([unique([data_par.value],'stable')]) = replace({data_par(indx).calibratedValue},'_',' '); + plot([data_par.dateMAT], [data_par.value], '-x' ); + set(gca,'ytick',unique([data_par.value],'sorted')) + set(gca,'yticklabel',ylabels) + if exist('dataFigShowUpdatefcn')==2 + set(datacursormode(gcf),'UpdateFcn',@dataFigShowUpdatefcn) + end + otherwise + plot([data_par.dateMAT], [data_par.calibratedValue], '-x' ); + end + else + plot([data_par.dateMAT], [data_par.value], '-x' ); + end xlabel('time'); - ylabel(data(i).unit); + if isfield(data(i), 'unit') + ylabel(data(i).unit); + end + title([data(i).description,' - ',data(i).name]); datetick('x'); grid on end @@ -226,6 +243,21 @@ classdef MatMust < handle end function t = MatMust_searchTMparFromName(obj, namequery, dataproviders, varargin) + % +++ + % MatMust_searchTMparFromName + % Search a parameter into the requested dataprovider (es. BEPICRUISE) + % MatMust_searchTMparFromName(obj, namequery, dataproviders, varargin) + % + % dataproviders = dataprovider IdName. + % namequery = The query to perform (ex. '*HGA' ) + % varargin = You can specify several options in varagin: + % ex: 'dump' -> print to screen the parameters found + % 'Description' -> Extend search in Parameters Descriptions + % 'Id' -> Extend Search in Parameter Id + % 'Unit' -> Extend Search in Unit name space + % + + if obj.loginstatus query = 'metadata/treesearch'; obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token}; @@ -233,13 +265,20 @@ classdef MatMust < handle dataproviders = char(join(dataproviders,',')); end try - response = webread([obj.url,obj.urlsub, query], 'field','name','text',namequery,'dataproviders', dataproviders ,obj.GEToptions); + optindx = strcmp(varargin,'Description')+strcmp(varargin,'Unit')+strcmp(varargin,'Id'); + if any(find(optindx)) + field = join(varargin(find(optindx)),','); + response = webread([obj.url,obj.urlsub, query], 'field',['name,',char(field)],'text',namequery,'dataproviders', dataproviders ,obj.GEToptions); + else + + response = webread([obj.url,obj.urlsub, query], 'field','name','text',namequery,'dataproviders', dataproviders ,obj.GEToptions); + end t = response ; catch ME fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message) end if nargin > 3 - if strcmp(varargin{1},'dump') + if any(find(strcmp(varargin,'dump'))) fprintf('+++++++++++++ PARAMETERS QUERY RESULT LIST +++++++++++++\n'); found = false; for i = 1:numel(t) @@ -259,7 +298,7 @@ classdef MatMust < handle end end end - function [exit] = MatMust_login(obj, varargin ) + function MatMust_login(obj, varargin ) % login % https://bepicolombo.esac.esa.int/webclient-must/mustlink/api-docs/index.html#/Authentication/login % input: @@ -317,7 +356,6 @@ classdef MatMust < handle MatMust_getUserLinkedProjects(obj); else - exit = true; disp('user already loggen in') end diff --git a/matlab/src/classes/classes/@MatMust/MatMust.m b/matlab/src/classes/classes/@MatMust/MatMust.m deleted file mode 100644 index 9b5e1b851a075bb49f14a76ac251fe0d4fa6cb30..0000000000000000000000000000000000000000 --- a/matlab/src/classes/classes/@MatMust/MatMust.m +++ /dev/null @@ -1,347 +0,0 @@ -classdef MatMust < handle - %MATMUST A library to get deal with ESA webmust REST API - % Follow indication in methods help. - % - % +++++++++++++++++++++++++++++++++++++ - % Creator: Carmelo Magnafico IAPS/INAF - % date: 20/06/2019 - % - % +++++++++++++++++++++++++++++++++++++ - - properties - POSToptions - GEToptions - loginstatus - url - urlsub - userProjects - end - - properties (SetAccess = private) - tockenfilename - tockenstruct - end - - properties (Transient) - end - - methods - function obj = MatMust(varargin) - % Initialize the values - obj.POSToptions = weboptions('RequestMethod', 'POST', 'ArrayFormat', 'json', 'Timeout',30, 'MediaType','application/json'); - obj.GEToptions = weboptions('RequestMethod', 'GET', 'ArrayFormat', 'repeating', 'Timeout',30, 'MediaType','application/x-www-form-urlencoded'); - obj.url = 'https://bepicolombo.esac.esa.int/webclient-must/'; - obj.urlsub = 'mustlink/'; - obj.tockenfilename = 'auth.json'; - obj.loginstatus = false; - - %check the url - if(nargin > 0) - if isfield(varargin{1},'url') - obj.url = varargin{1}.url; - end - end - - %check url - [~,status] = urlread(obj.url); - if ~status - error('invalid URL') - end - - if(MatMust_logincheck(obj)) - disp('++++ MATMUST initialization ++++'); - disp('++++ Access token valid. User logged in ++++'); - disp('++++++++++++++++++++++++++++++++++++++++++++'); - return - end - - end - function e = MatMust_logincheck(obj) - f = fopen(obj.tockenfilename); - e = false; - % check if user is already logged in - if f > 0 - raw = fread(f,inf); - tockenfilejson = jsondecode(char(raw)); - if isfield(tockenfilejson,'token') & isfield(tockenfilejson,'expiresAt') - if length(split(tockenfilejson.token,'.')) == 3 & datetime(datenum(tockenfilejson.expiresAt, 'yyyy-mm-dd HH:MM:SS'), 'ConvertFrom','datenum', 'TimeZone','utc') > datetime(datetime(now, 'ConvertFrom','datenum', 'TimeZone','local'), 'TimeZone','utc') - obj.loginstatus = true; - obj.tockenstruct = tockenfilejson; - MatMust_getUserLinkedProjects(obj); - e=true; - else - disp('++++ MATMUST initialization ++++'); - disp('++++ invalid or exiperd access token. User not logged in yet ++++'); - disp('++++ User login needed - use MatMust_login to access ++++'); - disp('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); - end - end - else - disp('++++ MATMUST initialization ++++'); - disp('++++ cannot find access token. User not logged ++++'); - disp('++++ User login needed - use MatMust_login to access ++++'); - disp('+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++'); - end - end - function t = MatMust_getTockenStatus(obj) - t = obj.loginresponse; - end - function t = MatMust_getUserProjects(obj) - if obj.loginstatus - query = 'usermanagement/projects'; - obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token}; - try - response = webread([obj.url,obj.urlsub, query], obj.GEToptions); - t = response ; - catch ME - fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message) - end - - end - end - function t = MatMust_getUserLinkedProjects(obj, varargin) - % Get the project to witch the logged in User belongs and have access to. - % if 'dump' option is set a screenslash is done - userInfo = MatMust_getUserInfo(obj); - obj.userProjects = userInfo.projects; - t = obj.userProjects; - if nargin > 1 - if strcmp(varargin{1},'dump') - fprintf('+++++++++++++ PROJECTS LIST +++++++++++++\n'); - for i = 1:numel(t) - fprintf('\tname: %s\n\tdescription: %s\n\tid: %i\n', t(i).name, t(i).description, t(i).id); - fprintf('+++++++++++++++++\n'); - end - end - end - end - function t = MatMust_getUserInfo(obj) - if obj.loginstatus - query = 'usermanagement/userinfo'; - obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token}; - try - response = webread([obj.url,obj.urlsub, query], obj.GEToptions); - t = response ; - catch ME - fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message) - end - end - end - function data = MatMust_getDataFromName(obj, ds, parname, dateStart, dateStop, varargin ) - % data = MatMust_getDataFromName(obj, ds, parname, dateStart, dateStop, options ) - % MatMust_getDataFromName get the data name parameter from the project name ds - % in the time interval dateStart, dateStop. - % - % inputs - % ------ - % ds = 'string' -> name of the project i.e.'BEPICRUISE' - % parname = 'string' -> a parameter name i.e. 'NCAD7EB7' - % dateStart = 'yyyy-mm-dd HH:MM:SS' format date UTC time - % dateStop = 'yyyy-mm-dd HH:MM:SS' format date UTC time - % 'dump','plot' optional parameter to dump and plot the data - - % intialize data output - data = []; - if ~(MatMust_logincheck(obj)) - return - end - - - %validate ds - if isfield(obj.userProjects,'name') - if ~any(strcmp({obj.userProjects.name},ds)) - disp('++++ Project not in Available User List, check ds name or check you access rigth ++++'); - return - end - end - - - query = ['dataproviders/',ds,'/parameters/data']; - obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token}; - - if isa(parname,'cell') - parname = char(join(parname,',')); - end - - args = {'key', 'name',... - 'values', (parname),... - 'from', (dateStart),... - 'to', (dateStop),... - 'calibrate', 'false',... - 'mode', 'SIMPLE'}; - - try - data = webread([obj.url,obj.urlsub, query], args{:} ,obj.GEToptions); - catch ME - fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message) - return - end - - %refine date string to adapt MATLAB date format - for i=1:numel(data) - data_par = data(i).data; - t = num2cell(datenum(datetime('1970-01-01', 'TimeZone','utc'))+(str2num(str2mat(data_par.date))/1000/86400)); - [data(i).data.dateMAT] = deal(t{:}); - clear t - end - - if nargin > 5 - if any(ismember(varargin,'dump')) - fprintf('+++++++++++++ DATA RESULT LIST +++++++++++++\n'); - for i=1:numel(data) - data_par = data(i).data; - fprintf('%s-%s: %s -> %s\n', data(i).subsystem, data(i).type, data(i).name, data(i).description ); - %TODO filter for several kind of dataType 'DOUBLE', - %'SIGNED_SMALL_INT', 'STRING' - switch data(i).dataType - case 'DOUBLE' - format = '%f'; - case 'SIGNED_SMALL_INT' - format = '%i'; - case 'STRING' - format = '%s'; - end - format = ['%s - ',format,'\n']; - for i = 1:numel(data_par) - fprintf(format,datestr(data_par(i).dateMAT,'yyyy-mm-dd HH:MM:SS.FFF'), data_par(i).value ); - end - - fprintf('\n++++++++++++++\n\n'); - end - fprintf('+++++++++++++++++++++++++++++++++++++++++\n'); - end - if any(ismember(varargin,'plot')) - for i=1:numel(data) - data_par = data(i).data; - figure - title(sprintf('%s-%s: %s -> %s\n', data(i).subsystem, data(i).type, data(i).name, data(i).description )) - plot([data_par.dateMAT], [data_par.value], '-x' ); - xlabel('time'); - ylabel(data(i).unit); - datetick('x'); - grid on - end - end - end - - end - function t = MatMust_searchTMparFromName(obj, namequery, dataproviders, varargin) - if obj.loginstatus - query = 'metadata/treesearch'; - obj.GEToptions.HeaderFields = {'Authorization', obj.tockenstruct.token}; - if isa(dataproviders,'cell') - dataproviders = char(join(dataproviders,',')); - end - try - response = webread([obj.url,obj.urlsub, query], 'field','name','text',namequery,'dataproviders', dataproviders ,obj.GEToptions); - t = response ; - catch ME - fprintf('+++ WARNING\n%s - %s\n', ME.identifier, ME.message) - end - if nargin > 3 - if strcmp(varargin{1},'dump') - fprintf('+++++++++++++ PARAMETERS QUERY RESULT LIST +++++++++++++\n'); - found = false; - for i = 1:numel(t) - if numel(t(i).children) > 0 - found = true; - fprintf('\n\n\t+++++++++++++ %s LIST +++++++++++++\n', t(i).type); - for j = 1:numel(t(i).children) - par = t(i).children(j); - fprintf('\ttitle: %s\n\tname: %s\n\tdescription: %s\n\tid: %s\n', par.title, par.sortingField, par.label, par.id); - fprintf(' +++++++++++++++++\n'); - end - end - end - if ~found, fprintf('++++ Nothing found ++++\n'); end - fprintf('++++++++++++++++++++++++++++++++++++++++++++++++++++++++\n'); - end - end - end - end - function [exit] = MatMust_login(obj, varargin ) - % login - % https://bepicolombo.esac.esa.int/webclient-must/mustlink/api-docs/index.html#/Authentication/login - % input: - % "username": "string", - % "password": "string", - % "maxDuration": false - % output: - % "token": "string", - % "issuer": "string", - % "subject": "string", - % "issuedAt": "string", - % "expiresAt": "string", - % "expirationDate": "yyyy-mm-ddTHH:MM:SS.FFFZ" - - if ~obj.loginstatus - % validation input - input_validation = struct('username', 'char', 'password', 'char', 'maxDuration', 'logical' ); - - exit = false; - if(nargin > 0) - inputs = varargin{1}; - e = obj.MatMust_inputvalidator(inputs, input_validation); - if ~e - exit = false; - return - else - exit = true; - end - else - exit = false; - return - end - - json_POST = inputs; - query = 'auth/login/'; - obj.tockenstruct = webwrite([obj.url,obj.urlsub, query],json_POST,obj.POSToptions); - if isfield(obj.tockenstruct,'token') - disp('+++ Succesfully logged in +++') - obj.loginstatus = true; - else - disp('+++ Error in loggin +++') - obj.loginstatus = false; - end - - - %store into a file - if obj.loginstatus - f = fopen(obj.tockenfilename, 'w'); - text = jsonencode(obj.tockenstruct); - fprintf(f,'%s',text); - fclose(f); - end - - %store the UserAvailable Projects in class Property - MatMust_getUserLinkedProjects(obj); - - else - exit = true; - disp('user already loggen in') - end - - end - function exit = MatMust_inputvalidator(obj, input, validation) - % For now, every validation_input field is treated as required - % TODO: set add a subfield required at validataion json - exit = false; - val_fields = fields(validation); - for i = 1:numel(val_fields) - val_field = validation.(val_fields{i}); - if isfield(input, val_fields{i}) - if isa(input.(val_fields{i}), val_field) - exit = true; - else - exit = false; - end - else - exit = false; - end - end - - end - end - -end -