From b6369e53ea0ec7b505ea9951760b9b3d146375db Mon Sep 17 00:00:00 2001
From: Federico Felici <federico.felici@epfl.ch>
Date: Wed, 10 Jun 2020 17:15:24 +0200
Subject: [PATCH] Upgrade/cleanup mainly to SCDclass_expcode and related things

---
 code/classes/SCD.m                     |  6 ++
 code/classes/SCDclass_algo.m           |  6 +-
 code/classes/SCDclass_expcode.m        | 94 ++++++++++++++------------
 code/classes/SCDclass_mdswgsigsingle.m | 40 +++++------
 tests/test_expcodes.m                  | 15 ++--
 5 files changed, 83 insertions(+), 78 deletions(-)

diff --git a/code/classes/SCD.m b/code/classes/SCD.m
index af7ff65..a3f919f 100644
--- a/code/classes/SCD.m
+++ b/code/classes/SCD.m
@@ -20,6 +20,12 @@ classdef SCD
    SCDconf_setSIMconf; % set conf for simulation
   end
   
+  function H=setup(expcode)
+    % load and setup
+    H=SCD.load(expcode);
+    H.setup;
+  end
+  
   function H=init(expcode,shot)
     assert(nargin==2,'must supply 2 inputs to init(expcode,shot)')
     H=SCD.load(expcode);
diff --git a/code/classes/SCDclass_algo.m b/code/classes/SCDclass_algo.m
index 596e898..fab4af6 100644
--- a/code/classes/SCDclass_algo.m
+++ b/code/classes/SCDclass_algo.m
@@ -251,7 +251,7 @@ classdef SCDclass_algo
        end
        
        
-       function callinits(obj,shot)
+       function callinits(obj)
          % call initialization functions that set fixed parameters
           if ~isempty(obj.stdinits)
               for ii=1:numel(obj.stdinits)
@@ -269,9 +269,7 @@ classdef SCDclass_algo
                     initcmd=sprintf('%s(obj);', initfunction);
                     [value{1:nout}] = eval(initcmd);
                   elseif isa(initfunction,'function_handle')
-                    if nargin(initfunction)==2
-                      argins = {obj,shot};
-                    elseif nargin(initfunction)==1
+                    if nargin(initfunction)==1
                       argins={obj};
                     elseif nargin(initfunction)==0
                       argins = {};
diff --git a/code/classes/SCDclass_expcode.m b/code/classes/SCDclass_expcode.m
index 8855980..3bf3c93 100644
--- a/code/classes/SCDclass_expcode.m
+++ b/code/classes/SCDclass_expcode.m
@@ -352,7 +352,8 @@ classdef SCDclass_expcode
             nodestr=sprintf('node%02d',inode);
             obj.nodes(inode).varalgo(icpu) = varalgo;
             obj.nodes(inode).wrapper{icpu} = wrappername;
-            obj.nodes(inode).cpuactive(icpu) = 1;
+            obj.nodes(inode).cpuactive(icpu) = true;
+            obj.nodes(inode).active = true;
             %% save in wrapper list
                 
             tempwrapper=cell(10,1);
@@ -555,6 +556,7 @@ classdef SCDclass_expcode
         function actualizewavegens(obj,shot)
             obj.mdscontainer.modeltoactualize=obj.modeltoactualize;
             obj.mdscontainer.actualizewavegens(shot);
+        end
         
         function printinits(obj)
            if(~isempty(obj.stdinits))
@@ -564,7 +566,7 @@ classdef SCDclass_expcode
            end
         end
        
-        function callinits(obj,~)
+        function callinits(obj)
           if(~isempty(obj.algoobjlist))
               for ii=1:numel(obj.algoobjlist)
                  if nargin==1
@@ -657,12 +659,8 @@ classdef SCDclass_expcode
               nodeinfo=obj.nodes(inode);
               for icpu = 1:nodeinfo.ncpu
                 if nodeinfo.cpuactive(icpu)
-                  if inode~=1
                   compileslx_list = [compileslx_list,...
                     SCDclass_expcode.getslxname(inode,icpu)]; %#ok<AGROW>
-                  else
-                    warning('Do not compile node %d thread %d since this is just a dummy',inode,icpu);
-                  end
                 end
               end
             end
@@ -704,9 +702,11 @@ classdef SCDclass_expcode
    
     methods (Access = private)
         
-        function obj=printlog(obj,str)
+        function obj=printlog(obj,str,varargin)
+          % printlog, allows sprintf()-like expressions
             if obj.loadverbose==1
-               fprintf('Expcode %d, %s\n', obj.maincode, str); 
+               fprintf('Expcode %d, ', obj.maincode, str); 
+               fprintf(str,varargin{:}); fprintf('\n');
             end
         end
                  
@@ -762,7 +762,7 @@ classdef SCDclass_expcode
                nodeddsourcesok={};
                nodeddsourcesokitems=0;
                for ii=1:numel(nodeddsources)
-                  if(strcmp(nodeddsources{ii}(1:7),'SCDwrap'))
+                  if startsWith(nodeddsources{ii},'SCDwrap')
                       temp={nodeddsources{ii}, 0};
                       nodeddsourcesok=[nodeddsourcesok; temp];
                       nodeddsourcesokitems=nodeddsourcesokitems+1;
@@ -772,20 +772,17 @@ classdef SCDclass_expcode
                reqsourcesok={};
                reqsourcesokitems=0;
                for ii=1:numel(reqsources)
-                  if(strcmp(reqsources{ii}(1:7),'SCDwrap'))           
+                  if startsWith(reqsources{ii},'SCDwrap')          
                       temp={reqsources{ii}, 1};
                       reqsourcesok=[reqsourcesok; temp];
                       reqsourcesokitems=reqsourcesokitems+1;
                   else
-                      str=sprintf('Proposed wrapper data dictionary %s does not begin with SCDwrap, ignoring it.', reqsources{ii});
-                      warning(str);
-                      %obj.printlog(str);
+                      warning('Proposed wrapper data dictionary %s does not begin with SCDwrap, ignoring it.', reqsources{ii});
                   end
-                  
                end
                
                % Finding which data sources to eliminate and which to add
-               if(nodeddsourcesokitems>0 && reqsourcesokitems>0)
+               if (nodeddsourcesokitems>0 && reqsourcesokitems>0)
                   for ii=1:nodeddsourcesokitems
                      todel=1;
                      for jj=1:reqsourcesokitems
@@ -813,8 +810,7 @@ classdef SCDclass_expcode
                if(nodeddsourcesokitems>0)
                   for ii=1:nodeddsourcesokitems
                     if(nodeddsourcesok{ii,2}==1)
-                       str=sprintf('Removing wrapper data source %s from %s', char(nodeddsourcesok{ii,1}), datadictname);
-                       obj.printlog(str);
+                       obj.printlog('Removing wrapper data source %s from %s', char(nodeddsourcesok{ii,1}), datadictname);
                        removeDataSource(nodedd, char(nodeddsourcesok{ii,1}));
                     end
                   end
@@ -824,8 +820,7 @@ classdef SCDclass_expcode
                if(reqsourcesokitems>0)
                   for ii=1:reqsourcesokitems
                       if(reqsourcesok{ii,2}==1)
-                         str=sprintf('Adding wrapper data source %s to %s', char(reqsourcesok{ii,1}), datadictname); 
-                         obj.printlog(str);
+                         obj.printlog('Adding wrapper data source %s to %s', char(reqsourcesok{ii,1}), datadictname);
                          addDataSource(nodedd, char(reqsourcesok{ii,1}));
                       end
                   end
@@ -893,8 +888,7 @@ classdef SCDclass_expcode
                if(tcvddsourcesokitems>0)
                   for ii=1:tcvddsourcesokitems
                     if(tcvddsourcesok{ii,2}==1)
-                       str=sprintf('Removing algorithm data source %s', char(tcvddsourcesok{ii,1}));
-                       obj.printlog(str);
+                       obj.printlog('Removing algorithm data source %s', char(tcvddsourcesok{ii,1}));
                        removeDataSource(tcvdd, char(tcvddsourcesok{ii,1}));
                     end
                   end
@@ -904,8 +898,7 @@ classdef SCDclass_expcode
                if(reqsourcesokitems>0)
                   for ii=1:reqsourcesokitems
                       if(reqsourcesok{ii,2}==1)
-                         str=sprintf('Adding algorithm data source %s', char(reqsourcesok{ii,1})); 
-                         obj.printlog(str);
+                         obj.printlog('Adding algorithm data source %s', char(reqsourcesok{ii,1}));
                          addDataSource(tcvdd, char(reqsourcesok{ii,1}));
                       end
                   end
@@ -942,7 +935,6 @@ classdef SCDclass_expcode
                         else
                             warning('SCDclass_expcode:setupwrappers','not supported node%02d cpu',inode);
                         end
-                        
                     case {2,3,4,6,7}
                         if(obj.wrapperlist{ii}{2}>=1 &&  obj.wrapperlist{ii}{2}<=4)
                             obj.nodes(inode).varalgo(obj.wrapperlist{ii}{2})=obj.wrapperlist{ii}{3};
@@ -950,10 +942,8 @@ classdef SCDclass_expcode
                         else
                             warning('SCDclass_expcode:setupwrappers','not supported node%02d cpu',inode);
                         end
-
                     otherwise
                         warning('SCDclass_expcode:setupwrappers','not supported node');
-                  
                 end
                 
             end
@@ -988,27 +978,43 @@ classdef SCDclass_expcode
         function obj = buildworkspacesimstructnode(obj,inode,dd)
           node = obj.nodes(inode);
 
-          try % get existing SCDsimdata
+          if evalin('base','exist(''SCDsimdata'',''var'')');
             SCDsimdata = evalin('base','SCDsimdata');
-          catch ME
-            if strcmp(ME.identifier,'MATLAB:UndefinedFunction')
-              SCDsimdata = struct(); % assign here if empty
-            else
-              rethrow(ME);
-            end
+          else
+            SCDsimdata = struct(); % assign here if empty
           end
           
           if node.haswavegen
             for ithread = 1:node.ncpu
               % get whatever is in data dictionary template in wrappers
               simstructname = sprintf('SCDnode%02d%02d_simdata',inode,ithread);
-              fprintf('   setting up %s\n',simstructname);
-              try
-               simstruct = dd.getEntry(simstructname).getValue;
-              catch
-                warning('%s not found in data dictionary, auto-generate from bus definition',simstructname)
-                wgbusname = sprintf('WG%02d%02dbus',inode,ithread);
-                simstruct = SCDconf_createsimdatastruct(dd,wgbusname);
+              wgbusname = sprintf('WG%02d%02dbus',inode,ithread);
+
+              fprintf('   setting up %s',simstructname);
+              if dd.exist(simstructname)
+                simstruct = dd.getEntry(simstructname).getValue;
+                mybus=dd.getEntry(wgbusname).getValue; % get from data dictionary
+                if ~isstruct(simstruct) || ~isfield(simstruct,'wavegen')
+                  fprintf('.. loaded simstruct wavegen is not compatible');
+                  regenerate = true;
+                elseif SCDconf_structbuscmp(simstruct.wavegen,mybus)
+                  fprintf('... loaded WG from data dictionary\n');
+                  regenerate=false;
+                else
+                  fprintf('... loaded WG structure from dd does not match bus definition...');
+                  regenerate=true;
+                end
+              else
+                regenerate=true;
+                fprintf('... could not find %s in data dictionary',simstructname);
+              end
+              
+              if regenerate
+                simstruct.wavegen = SCDconf_createstructfrombus(dd,wgbusname); % structure to match
+                %ddsource = dd.find('Name',wgbusname).DataSource; % dd containing bus
+                %wrapdd=Simulink.data.dictionary.open(ddsource).getSection('Design Data');
+                %wrapdd.addEntry(simstructname,simstruct)
+                fprintf('... re-generated from bus %s\n',wgbusname')
               end
               SCDsimdata.(simstructname) = simstruct;
             end
@@ -1019,7 +1025,7 @@ classdef SCDclass_expcode
           if node.hasadc
             adcbusname = sprintf('ADC%02dbus',inode);
             fprintf('   setting up %s.adc\n',simstructname);
-            SCDsimdata.(simstructname).adc = SCDconf_createsimdatastruct(dd,adcbusname);
+            SCDsimdata.(simstructname).adc = SCDconf_createstructfrombus(dd,adcbusname);
           end
           
           if node.hasethercat
@@ -1027,18 +1033,16 @@ classdef SCDclass_expcode
             ethercatbusname = 'ETHCAT1IN';
             fprintf('   setting up %s.ethercat\n',simstructname);
             SCDsimdata.(simstructname).ethercat = ...
-              SCDconf_createsimdatastruct(dd,ethercatbusname);
+              SCDconf_createstructfrombus(dd,ethercatbusname);
           end
           
           % add also RFM
           RFMbusname = 'RFMINbus';
-          SCDsimdata.rfm = SCDconf_createsimdatastruct(dd,RFMbusname);
+          SCDsimdata.rfm = SCDconf_createstructfrombus(dd,RFMbusname);
 
           % assign result in base workspace         
           assignin('base','SCDsimdata',SCDsimdata);
         end
-
-        
     end 
 
 end
diff --git a/code/classes/SCDclass_mdswgsigsingle.m b/code/classes/SCDclass_mdswgsigsingle.m
index e4cbbe7..83d400d 100644
--- a/code/classes/SCDclass_mdswgsigsingle.m
+++ b/code/classes/SCDclass_mdswgsigsingle.m
@@ -46,36 +46,32 @@ classdef SCDclass_mdswgsigsingle < SCDclass_mdswg
             end
             
             value=obj.getdata();
-                                   
-            baseparam=obj.wavegenbasestruct;
-            structparam=obj.wavegentarget;
 
-            wgentryval=evalin('base',baseparam);
+            baseparam=obj.wavegenbasestruct; % name of base workspace structure
+            structparam=obj.wavegentarget; % name of target field
+            wgentryval = evalin('base',baseparam); % structure of wavegen in base workspace
             
-            getcurrenttssize =sprintf('ddtssamples=numel(wgentryval.%s.Time);',structparam);
-            eval(getcurrenttssize);
-            if(ddtssamples~=numel(value.Time))
-                % the dd timeseries has different dims w.r.t. the signals
-                % to be loaded, we have to load the timeseries as it is
-                
-                assigncmd   =sprintf('wgentryval.%s=value;',structparam);
-                eval(assigncmd);
-            else
-                % the dd timeseries has the same size than the signals
-                % to be loaded, we can do a partial loading
-             
-                assigncmdtime    =sprintf('wgentryval.%s.Time=value.Time;',structparam);
-                assigncmddata    =sprintf('wgentryval.%s.Data(:,%d)=value.Data;',structparam,obj.destidx);
+            assert(isfield(wgentryval,structparam),...
+              'Wavegen field %s does not exist in target structure %s. ',structparam,baseparam)
             
-                eval(assigncmdtime);
-                eval(assigncmddata);
+            % assign field from wavegen entry value
+            ddtssamples=numel(wgentryval.(structparam).Time);
+            if ddtssamples~=numel(value.Time)
+              % the dd timeseries has different dims w.r.t. the signals
+              % to be loaded, we have to load the timeseries as it is
+              wgentryval.(structparam)=value;
+            else
+              % the dd timeseries has the same size than the signals
+              % to be loaded, we can do a partial loading
+              wgentryval.(structparam).Time=value.Time;
+              wgentryval.(structparam).Data(:,obj.destidx)=value.Data;
             end
             
             assignin('base','temp',wgentryval);
-            assigncmd=sprintf('%s=temp;',baseparam);            
+            assigncmd=sprintf('%s=temp;',baseparam);
             evalin('base',assigncmd);
             evalin('base','clear temp');
-                                  
+
         end
         
         function value=getdata(obj)
diff --git a/tests/test_expcodes.m b/tests/test_expcodes.m
index d67acbc..970431f 100644
--- a/tests/test_expcodes.m
+++ b/tests/test_expcodes.m
@@ -7,8 +7,7 @@ classdef test_expcodes < matlab.unittest.TestCase
   end
   
   properties(ClassSetupParameter)
-    %expcode_number = {'1','1005','1010'}; % list of expcodes to test
-    expcode_number = {'1','1005'}; % list of expcodes to test  
+    expcode = {'1','1005','1006'}; % list of expcodes to test  
   end
   
   methods(TestClassSetup)
@@ -27,10 +26,10 @@ classdef test_expcodes < matlab.unittest.TestCase
       SCDconf_setSIMconf; % set ConfigurationSettings for Simulation
     end
   
-    function setup_expcode(testCase,expcode_number)
+    function setup_expcode(testCase,expcode)
       % get this expcode object from expcode object container
-      fprintf('\n=== Testing expcode %s ===\n',expcode_number);
-      testCase.expcode_obj = getbymaincode(testCase.SCDexps,str2double(expcode_number));
+      fprintf('\n=== Testing expcode %s ===\n',expcode);
+      testCase.expcode_obj = getbymaincode(testCase.SCDexps,str2double(expcode));
     end
     
   end
@@ -92,10 +91,12 @@ classdef test_expcodes < matlab.unittest.TestCase
       end
     end
     
-    function test_expcode_compile_all(testCase)
-      testCase.expcode_obj.compile; % compile whole tcv.slx with this expcode
+    function test_expcode_sim(testCase)
+      fprintf('\n === Testing Simulink simulation of tcv.slx for expcode %d: %s === \n',testCase.expcode_obj.maincode)
+      testCase.expcode_obj.sim; % simulate whole tcv.slx with this expcode
     end
     
+    
     function test_build(testCase)
       testCase.expcode_obj.build;
     end
-- 
GitLab