%% Using Data Stores Across Multiple Models
% This example shows how to use and log local data stores. It also shows 
%  how to define, use and log global data stores to share global data among 
% referenced models.

%   Copyright 1990-2012 The MathWorks, Inc.


%% Open the Example Models
% Open the example models. The top model |sldemo_mdlref_dsm| references 
% models |sldemo_mdlref_dsm_bot| and |sldemo_mdlref_dsm_bot2|. 
% Logging of data stores is turned on for |sldemo_mdlref_dsm| on the 
% Data Import/Export pane of the Configuration Parameters dialog box.
% 
% Reference model |sldemo_mdlref_dsm_bot| amplifies the incoming signal by 
% 5 if the signal is positive or by 2 if the signal is negative and writes  
% the value of this signal to local data store |RefSignalVal|. This local 
% data store is configured to log all written values to the workspace after
% simulation. The logging parameters for this local data store are controlled
% by the *Logging* tab of the block parameters dialog.
%
% Reference model |sldemo_mdlref_dsm_bot2| sets the value of a global 
% boolean data store named |ErrorCond| to true if the value of its incoming 
% signal is outside of the range (-0.8, 0.8). The top model also monitors 
% the data store |ErrorCond| and switches between the outputs of the two 
% referenced models, depending on the value of that data store.
%
open_system('sldemo_mdlref_dsm');

%%
open_system('sldemo_mdlref_dsm_bot2');

%%
open_system('sldemo_mdlref_dsm_bot');

%%
open_system('sldemo_mdlref_dsm_bot/PositiveSS');
open_system('sldemo_mdlref_dsm_bot/NegativeSS');

%% Define a Global Data Store Using a Simulink(R) Signal Object
% To specify to Simulink that the top model and both of the referenced
% models use the same memory for the data store named |ErrorCond| in each
% model, create an instance of a |Simulink.Signal| object named |ErrorCond|
% in a workspace or data dictionary that is visible to each model. Since
% this object is visible to each model, its scope encompasses the
% individual models and implies that there is one global data store of that
% name that is shared among the models. Note that none of the three models
% contains a Data Store Memory block with a data store name of |ErrorCond|.
% If any model contained such a block, that block would define a data store
% local to the model, which would shadow the global data store.
%
% Since the object |ErrorCond| defines a global data store, it must
% explicitly define the |DataType|, |Complexity|, and |Dimensions|
% properties to non-inherited settings.  |SampleTime| and |StorageClass|
% may be left as their inherited values, or explicitly set.
%
% The example includes a MAT-file named |sldemo_mdlref_dsm_data.mat| that contains
% the |Simulink.Signal| object |ErrorCond|.  The preload function of the model
% |sldemo_mdlref_dsm| loads this MAT-file causing the object to be loaded in the
% base workspace. You can view this object by selecting the base workspace in
% the Model Explorer. You can also create this object from the
% MATLAB(R) command prompt. The following commands define the object used in
% this example:
%
%    ErrorCond = Simulink.Signal;
%    ErrorCond.Description = 'Use to signal that subsystem output is invalid';
%    ErrorCond.DataType = 'boolean';
%    ErrorCond.Complexity = 'real';
%    ErrorCond.Dimensions = 1;
%    ErrorCond.SampleTime = 0.1;
%    ErrorCond.LoggingInfo.DataLogging = true;

%% Logging a Global Data Store
% To log all the values written to the global data store, set the
% |DataLogging| property of the |LoggingInfo| property of the
% |Simulink.Signal| object. The |LoggingInfo| property also allows
% specification of other logging parameters such as decimation and maximum
% points.
%
%     Simulink.LoggingInfo (handle)
%             DataLogging: 1
%                NameMode: 0
%             LoggingName: ''
%            DecimateData: 0
%              Decimation: 2
%         LimitDataPoints: 0
%               MaxPoints: 5000

%% Simulate the Model
% Now you can simulate |sldemo_mdlref_dsm| to see the output.  The reference
% model |sldemo_mdlref_dsm_bot| writes to the data store |ErrorCond| 
% while the top model |sldemo_mdlref_dsm| reads from the data store.  
% The blue line represents the 
% input to |sldemo_mdlref_dsm_bot|; the green line represents the output of the 
% Switch block.  Note that the output switches when the magnitude of the 
% input signal falls outside of the range.

% sldemo_mdlref_util('sldemo_mdlref_dsm', 'sim');
sim('sldemo_mdlref_dsm');
assignin('base','dsmout',dsmout);
        
plot(tout, yout);
title('Simulation of model hierarchy sharing data store ErrorCond');
ylabel('Input to model block A, and output of Switch');
xlabel('Time (sec)');

%% View Logged Results
% Both the global data store |ErrorCond| and the local data store
% |RefSignalVal| are configured to log all written values after simulation.
% These logged results are stored in the base workspace in the |dsmout|
% variable.
display(dsmout);

%% 
% To access the data stored for the local data store, use the |getElement|
% function to get the correct data store element based on the name 
% |RefSignalVal|. 
%
%     >> dsmout.getElement('RefSignalVal')
display(dsmout.getElement('RefSignalVal'));

%%
% Data is stored in a |timeseries| within the |Values| field.
%
%     >> plot(dsmout.getElement('RefSignalVal').Values);
plot(dsmout.getElement('RefSignalVal').Values);

%%
% To determine which block wrote to the data store at a given time, use the
% |DSMWriters| property. This array contains a list of indices into the
% |DSMWriterBlockPaths| array.  For example, the block path of the Data Store
% Write block that wrote the 5th value to the data store can be obtained as
% follows:
%
%     >> dsm = dsmout.getElement('RefSignalVal');
%     >> dsm.DSMWriterBlockPaths(dsm.DSMWriters(5))
display(dsmout.getElement('RefSignalVal').DSMWriterBlockPaths(dsmout.getElement('RefSignalVal').DSMWriters(5)));
