Skip to content
Snippets Groups Projects
SCDclass_algo.m 12.5 KiB
Newer Older
classdef SCDclass_algo
    %SCD algorithm handling object
    %   The class holds all information and 
    %   methods for handling a Simulink
    %   algorithm
Federico Felici's avatar
Federico Felici committed
     
    properties (Access = private)
       modelname         % Name of the model
       mdscontainer      % Container class for MDS+ interface objects
       taskcontainer     % Container class for init and term tasks
       exportedtps       % List of tunable parameters variable to be exported
       datadictionary    % Name of the used data dictionary
       stdinits          % Standard inits scripts for fixed parameters
       timing            % Timing info structure
    end
        
    methods
        function obj=SCDclass_algo(name)
            % Empty algorithm constructor
            
            obj.modelname=name;
            obj.mdscontainer = SCDclass_mdsobjcontainer;
            obj.taskcontainer = SCDclass_taskcontainer;
            obj.exportedtps = {};
            obj.stdinits = {};
            obj.datadictionary = '';           
            obj.timing.t_start=0;
            obj.timing.t_stop=1;
            obj.timing.dt=1e-3;
            
            % Standard data dictionary equal to algorithm name, 
            % overriddable by the setter method
            obj=obj.setdatadictionary([name '.sldd']);
        end

        %% Print infos
        
        function printinfo(obj)
           fprintf('*****************************************************\n');
           fprintf('* SCD algorithm: ''%s''\n',obj.modelname); 
           fprintf('*****************************************************\n');           
           if(~isempty(obj.datadictionary))
               fprintf('* Data dictionary:\n  %s\n',obj.datadictionary);
           else
               fprintf('* Data dictionary:\n  base workspace\n');
           end
           if numel(obj.exportedtps)>0
               fprintf('* Tunable params structs:\n');
               for ii=1:numel(obj.exportedtps)
                   fprintf('  %s\n',obj.exportedtps{ii});
               end
           end
           fprintf('* Tunable params objects:\n')
           obj.printparameters;
           fprintf('* Wavegen objects:\n');
           obj.printwavegens;
           fprintf('* Tasks objects:\n');
           obj.printtasks;
           fprintf('* Fixed parameters inits:\n');
           obj.printinits;
           fprintf('*****************************************************\n');                      
        end

        %% Setup

        function setup(obj)
          obj.buildworkspacetpstruct;
        end
        %% General purpose getters
        
        function out = getname(obj)
            out=obj.modelname;
        end

        function out = getmdscontainer(obj)
            out=obj.mdscontainer;
        end
            
        function out = gettaskcontainer(obj)
            out=obj.taskcontainer;
        end
        
        function out = gettiming(obj)
            out=obj.timing;
        end
        
        function out = getinits(obj)
            out=obj.stdinits;
        end
        
        %% Data dictionary setter and getter
        
        function obj = setdatadictionary(obj, datadict)
            obj.datadictionary=datadict;
        end
        
        function out = getdatadictionary(obj)
            out = obj.datadictionary;
        end
        
        function out = opendatadictionarydesigndata(obj)
          ddname  = obj.getdatadictionary;
          dict = Simulink.data.dictionary.open(ddname);
          out=getSection(dict, 'Design Data');
        end
                
        %% Tunable parameters structures handling functions
        
        function out = getexportedtps(obj)
            out = obj.exportedtps;
        end     
        
        function obj = addtunparamstruct(obj, structname)
            if(~ismember(structname, obj.exportedtps))
                obj.exportedtps{end+1}=structname;
            else
                error('SCDclass_algo:addtunparamsstruct','Tunable parameter struct already present, cannot add!');
            end            
        end      
        
        function obj = settemplatetp(obj,TP)
          % sets default tunable parameter structure in data dictionary
          if ~isa(TP,'Simulink.Parameter')
            assert(isstruct(TP),'TP must be a structure');
            P = Simulink.Parameter;
            P.Value = TP;
          else
            P = TP;
          end
          DD = obj.opendatadictionarydesigndata;
          tmplname = sprintf('%s_tp_tmpl',obj.getname);
          if DD.exist(tmplname) 
            DD.deleteEntry(tmplname); fprintf('deleted previous entry, '); 
          end
          fprintf('added new %s\n',tmplname);
          DD.addEntry(tmplname,P)
        end
        
        function obj = buildworkspacetpstruct(obj)
            % this funtion builds a workspace structures containing
            % replicas of all tunable parameters structurea in the data
            % dictionaries, this structure is the one actually used 
            % for loading simulation wavegen data
            % It is better not to use directly data dictionaries structures
            % to avoid flooding dds with big sim data sets (and
            % consequently the SCD SVN itself
           
            if(isempty(obj.datadictionary))
                warning('SCDclass_algo:buildworkspacetpstruct','Methods ignored for this object, data dictionary isn''t configured');
                return;
            end
                
            dd=SCDconf_getdatadict(obj.datadictionary);
            
            for ii=1:numel(obj.exportedtps)
                simstructnamedd=sprintf('%s_tmpl',char(obj.exportedtps(ii)));
                simstructnamews=char(obj.exportedtps(ii));
                simstruct=dd.getEntry(simstructnamedd).getValue;
                assignstr=sprintf('%s=temp;',simstructnamews);
                assignin('base','temp',simstruct);
                evalin('base',assignstr);
            end
            
            evalin('base','clear temp;');            
        end
        
        %% MDS container methods forwarders
        
        function obj = addparameter(obj, param)
            obj.mdscontainer=obj.mdscontainer.addparameter(param);
            obj.mdscontainer=obj.mdscontainer.bindlastparameter(obj.modelname, obj.datadictionary, obj.exportedtps);        
        end
        
        function obj = printparameters(obj)
            obj.mdscontainer=obj.mdscontainer.printparameters;
        end
        
        function obj = actualizeparameters(obj, shot)
            obj.mdscontainer=obj.mdscontainer.actualizeparameters(shot);
        end
        
        function obj = addwavegen(obj, wavegen)
            obj.mdscontainer=obj.mdscontainer.addwavegen(wavegen);
            obj.mdscontainer=obj.mdscontainer.bindlastwavegen(obj.modelname, obj.datadictionary, obj.timing);
        end
        
        function obj = printwavegens(obj)
            obj.mdscontainer=obj.mdscontainer.printwavegens;
        end
        
        function obj = actualizewavegens(obj, shot)
            obj.mdscontainer=obj.mdscontainer.actualizewavegens(shot);
        end
        
        function obj = cleanwavegens(obj)
            obj.mdscontainer=obj.mdscontainer.cleanwavegens;
        end
        
        %function obj = bindparameters(obj)
        %    obj.mdscontainer=obj.mdscontainer.bindparameters(obj.modelname, obj.datadictionary, obj.exportedtps);        
        %end
        
        % This method has only sense in the expcode context
        %function obj = buildworkspacesimstruct(obj)
        %    obj.mdscontainer=obj.mdscontainer.buildworkspacesimstruct;
        %end

        
        %% Task container methods forwarders
        function obj = addtask(obj, task)
            obj.taskcontainer=obj.taskcontainer.addtask(task);
            obj.taskcontainer=obj.taskcontainer.bindlasttask(obj.modelname, obj.datadictionary);
        end
        
        function obj = printtasks(obj)
            obj.taskcontainer=obj.taskcontainer.printtasks;
        end
         
       %% Wavegen timing structure setters
%        function obj = setwavegentimingsources(obj, tstart, dt, tstop)
%            assert(ischar(tstart), 'SCDclass_algo.setwavegentimingsources first parameter must be a char array');
%            assert(ischar(dt), 'SCDclass_algo.setwavegentimingsources first parameter must be a char array');
%            assert(ischar(tstop), 'SCDclass_algo.setwavegentimingsources first parameter must be a char array');
%            
%            obj.wavegentiming.t_start=tstart;
%            obj.wavegentiming.dt=dt;
%            obj.wavegentiming.t_stop=tstop;
%        end
       
       %% Timing information
       function obj = settiming(obj, t_start, dt, t_stop)
           obj.timing.t_start=t_start;
           obj.timing.dt=dt;
           obj.timing.t_stop=t_stop;
       end
       
       %% Fixed inits
       function obj = addfpinitfcn(obj, fcnname, targetstruct,targetworkspace)
          if nargin<3
            targetstruct = ''; 
          end
          if nargin<4
            targetworkspace = 'global'; % default: global workspace (assigninGlobal)
          end
          
          if ~iscell(targetstruct) && ~isempty(targetstruct)
            targetstruct = {targetstruct};
          end
         
           if(~isempty(obj.stdinits))
               for ii=1:numel(obj.stdinits)
                   if ~isempty(targetstruct) && contains(obj.stdinits{ii}{2},targetstruct)
                       warning('SCDclass_algo:addfpinitfcn','A function defining the structure %s has already been added, ignoring.\d',targetstruct)
                       return
           % FF question to CG: why is this a cell and not a struct?
           temp=cell(10,1);
           temp{1}=fcnname;
           temp{2}=targetstruct;
           temp{3}=targetworkspace;
           obj.stdinits{end+1}=temp;
       end
       
       function printinits(obj)
           if(~isempty(obj.stdinits))
               for ii=1:numel(obj.stdinits)
                   fprintf('%s -> %s in workspace %s \n',char(obj.stdinits{ii}{1}),char(obj.stdinits{ii}{2}{1}),char(obj.stdinits{ii}{3}));
         % call initialization functions that set fixed parameters
          if ~isempty(obj.stdinits)
              for ii=1:numel(obj.stdinits)
                  initfunction = obj.stdinits{ii}{1};
                  targetnames = obj.stdinits{ii}{2};
                  workspace = obj.stdinits{ii}{3};
                  
                  nout = numel(targetnames);
                  
                  fprintf('Calling init function ''%s'', assigning its output to ''%s'' ...\n',...
                    char(initfunction),cell2mat(targetnames));

                  if ischar(initfunction)
                    initcmd=sprintf('%s(obj);', initfunction);
                    [value{1:nout}] = eval(initcmd);
                  elseif isa(initfunction,'function_handle')
                      argins={obj};
                    elseif nargin(initfunction)==0
                      argins = {};
                    else
                      error('unexpected number of input arguments for function %s',func2str(initfunction));
                    end
                    [value{1:nout}] = initfunction(argins{:}); % function has an input argument
                  else
                    error('initfunction must be a string or a function handle')
                  end
                  % assigns in base workspace or datadictionary depending
                  % on target workspace
                  for iout = 1:nout
                    % cycle over number of output arguments of the function
                    val = value{iout};
                    target = targetnames{iout};
                    if strcmp(workspace,'global')
                      Simulink.data.assigninGlobal(obj.modelname, target, val);
                    elseif strcmp(workspace,'base')
                      assignin('base',target,val)
                    end
                  end
       function compile(obj)
         try
           eval(sprintf('%s([],[],[],''compile'')',obj.modelname));
         catch
           eval(sprintf('%s([],[],[],''term'')',obj.modelname));
         end
         eval(sprintf('%s([],[],[],''term'')',obj.modelname));
         
       end
       
       function sim(obj)
         sim(obj.modelname);
       end
       
       function open(obj)
         open(obj.modelname)
       end