Inspect and Compare Data Programmatically

You can harness the capabilities of the Simulation Data Inspector from the MATLAB® command line using the Simulation Data Inspector API.

The Simulation Data Inspector organizes data in runs and signals, assigning a unique numeric identification to each run and signal. Some Simulation Data Inspector API functions use the run and signal IDs to reference data, rather than accepting the run or signal itself as an input. To access the run IDs in the workspace, you can use Simulink.sdi.getAllRunIDs or Simulink.sdi.getRunIDByIndex. You can access signal IDs through a Simulink.sdi.Run object using the Simulink.sdi.Run.getSignalIDByIndex method.

The Simulink.sdi.Run and Simulink.sdi.Signal classes provide access to your data and allow you to view and modify run and signal metadata. You can modify the Simulation Data Inspector preferences using functions like Simulink.sdi.setSubPlotLayout, Simulink.sdi.setRunNamingRule, and Simulink.sdi.setMarkersOn. To restore the Simulation Data Inspector's default settings, use Simulink.sdi.clearPreferences.

Create a Run and View the Data

This example shows how to create a run, add data to it, and then view the data in the Simulation Data Inspector.

Create Data for the Run

This example creates timeseries objects for a sine and a cosine. To visualize your data, the Simulation Data Inspector requires at least a time vector that corresponds with your data.

% Generate timeseries data
time = linspace(0, 20, 100);

sine_vals = sin(2*pi/5*time);
sine_ts = timeseries(sine_vals, time);
sine_ts.Name = 'Sine, T=5';

cos_vals = cos(2*pi/8*time);
cos_ts = timeseries(cos_vals, time);
cos_ts.Name = 'Cosine, T=8';

Create a Simulation Data Inspector Run and Add Your Data

To give the Simulation Data Inspector access to your data, use the create method and create a run. This example modifies some of the run's properties to help identify the data. You can easily view run and signal properties with the Simulation Data Inspector.

% Create a run
sinusoidsRun = Simulink.sdi.Run.create;
sinusoidsRun.Name = 'Sinusoids';
sinusoidsRun.Description = 'Sine and cosine signals with different frequencies';

% Add timeseries data to run
sinusoidsRun.add('vars', sine_ts, cos_ts);

Plot Your Data Using the Simulink.sdi.Signal Object

The getSignalByIndex method returns a Simulink.sdi.Signal object that can be used to plot the signal in the Simulation Data Inspector. You can also programmatically control aspects of the plot's appearance, such as the color and style of the line representing the signal. This example customizes the subplot layout and signal characteristics.

% Get signal, modify its properties, and change Checked property to true
sine_sig = sinusoidsRun.getSignalByIndex(1);
sine_sig.LineColor = [0 0 1];
sine_sig.LineDashed = '-.';
sine_sig.Checked = true;

% Add another subplot for the cosine signal
Simulink.sdi.setSubPlotLayout(2, 1);

% Plot the cosine signal and customize its appearance
cos_sig = sinusoidsRun.getSignalByIndex(2);
cos_sig.LineColor = [0 1 0];
cos_sig.plotOnSubPlot(2, 1, true);

% View the signal in the Simulation Data Inspector
Simulink.sdi.view

Close the Simulation Data Inspector and Save Your Data

Simulink.sdi.close('sinusoids.mat')

Compare Signals Within a Simulation Run

This example uses the slexAircraftExample model to demonstrate the comparison of the input and output signals for a control system. The example marks the signals for streaming then gets the run object for a simulation run. Signal IDs from the run object specify the signals to be compared.

% Load model slexAircraftExample and mark signals for streaming
load_system('slexAircraftExample')
Simulink.sdi.markSignalForStreaming('slexAircraftExample/Pilot',1,'on')
Simulink.sdi.markSignalForStreaming('slexAircraftExample/Aircraft Dynamics Model',4,'on')

% Simulate model slexAircraftExample
out = sim('slexAircraftExample');

% Get run IDs for most recent run
allIDs = Simulink.sdi.getAllRunIDs;
runID = allIDs(end);

% Get Run object
aircraftRun = Simulink.sdi.getRun(runID);

% Get signal IDs
signalID1 = getSignalIDByIndex(aircraftRun,1);
signalID2 = getSignalIDByIndex(aircraftRun,2);

if (isValidSignalID(aircraftRun,signalID1))
    % Change signal tolerance
    signal1 = Simulink.sdi.getSignal(signalID1);
    signal1.AbsTol = 0.1;
end

if (isValidSignalID(aircraftRun,signalID1) && isValidSignalID(aircraftRun,signalID2))
    % Compare signals
    sigDiff = Simulink.sdi.compareSignals(signalID1,signalID2);

    % Check whether signal result status
    match = sigDiff.Status
end
match = 
OutOfTolerance

Compare Simulation Data Inspector Runs Programmatically

This example shows how to compare runs of simulation data and analyze the comparison results with the Simulation Data Inspector programmatic interface.

Generate Runs of Simulation Data

Simulate the model with different Desired relative slip values to create runs of simulation data to analyze with the Simulation Data Inspector programmatic interface.

% Open model
load_system('ex_sldemo_absbrake')

% Set the desired slip ratio to 0.24 and simulate
set_param('ex_sldemo_absbrake/Desired relative slip','Value','0.24')
out_1 = sim('ex_sldemo_absbrake');

% Change the desired slip ratio to 0.25 and simulate
set_param('ex_sldemo_absbrake/Desired relative slip','Value','0.25')
out_2 = sim('ex_sldemo_absbrake');

Compare Runs with a Global Tolerance

Get the run IDs for the runs you just created with the Simulink.sdi.getAllRunIDs function. Then, compare the runs using a global relative tolerance and a global time tolerance to analyze whether your data meets specifications.

% Get run IDs for last two runs
runIDs = Simulink.sdi.getAllRunIDs;
runID1 = runIDs(end - 1);
runID2 = runIDs(end);

% Compare runs
runResult = Simulink.sdi.compareRuns(runID1,runID2,'reltol',0.2,'timetol',0.5);

Create a Plot of a Comparison Result

Use the Simulink.sdi.DiffRunResult object you created in the previous step with Simulink.sdi.compareRuns to access the data for the Ww signal result to plot it in a figure.

% Plot the |Ww| signal difference
signalResult_Ww = getResultByIndex(runResult,1);
figure(1)
plot(signalResult_Ww.Diff)

Analyze Simulation Data with Signal Tolerances

You can change tolerance values on a signal-by-signal basis to evaluate the effect of a model parameter change. This example uses the slexAircraftExample model and the Simulation Data Inspector to evaluate the effect of changing the time constant for the low-pass filter following the control input.

Setup

Load the model, and mark the q, rad/sec and alpha, rad signals for logging. Then, simulate the model to create the baseline run.

% Load example model
load_system('slexAircraftExample')

% Mark the q, rad/sec and alpha, rad signals for logging
Simulink.sdi.markSignalForStreaming('slexAircraftExample/Aircraft Dynamics Model',3,'on')
Simulink.sdi.markSignalForStreaming('slexAircraftExample/Aircraft Dynamics Model',4,'on')

% Simulate system
out_1 = sim('slexAircraftExample');

Modify Model Parameter

Modify the model parameter Ts in the model workspace to change the time constant of the input low-pass filter.

% Change input filter time constant
modelWorkspace = get_param('slexAircraftExample','modelworkspace');
assignin(modelWorkspace,'Ts',1)

% Simulate again
out_2 = sim('slexAircraftExample');

Compare Runs and Inspect Results

Use the Simulink.sdi.compareRuns function to compare the data from the simulations. Then, inspect the match property of the signal result to see whether the signals fell within the default tolerance of 0.

% Get run data
runIDs = Simulink.sdi.getAllRunIDs;
runID1 = runIDs(end - 1);
runID2 = runIDs(end);

% Compare runs
diffRun1 = Simulink.sdi.compareRuns(runID1,runID2);

% Get signal result
sig1Result1 = getResultByIndex(diffRun1,1);
sig2Result1 = getResultByIndex(diffRun1,2);

% Check whether signals matched
sig1Result1.Status
ans = 
OutOfTolerance
sig2Result1.Status
ans = 
OutOfTolerance

Compare Runs with Signal Tolerances

The signals did not match within the default tolerance of 0. To further analyze the effect of the time constant change, add signal tolerances to the comparison with the baseline signal properties to determine the tolerance required for a pass. This example uses a combination of time and absolute tolerances.

% Get signal object for sigID1
run1 = Simulink.sdi.getRun(runID1);
sigID1 = getSignalIDByIndex(run1,1);
sigID2 = getSignalIDByIndex(run1,2);

sig1 = Simulink.sdi.getSignal(sigID1);
sig2 = Simulink.sdi.getSignal(sigID2);

% Set tolerances for q, rad/sec
sig1.AbsTol = 0.1;
sig1.TimeTol = 0.6;

% Set tolerances for alpha, rad
sig2.AbsTol = 0.2;
sig2.TimeTol = 0.8;

% Run the comparison again
diffRun2 = Simulink.sdi.compareRuns(runID1,runID2);
sig1Result2 = getResultByIndex(diffRun2,1);
sig2Result2 = getResultByIndex(diffRun2,2);

% Check the result
sig1Result2.Status
ans = 
WithinTolerance
sig2Result2.Status
ans = 
WithinTolerance

Generate a Simulation Data Inspector Report Programmatically

This example shows how to create reports using the Simulation Data Inspector programmatic interface. You can create a report for plotted signals in the Inspect pane or for comparison data in the Compare pane. This example first generates data by simulating a model, then shows how to create an Inspect Signals report. To run the example exactly as shown, ensure that the Simulation Data Inspector repository starts empty with the Simulink.sdi.clear function.

Generate Data

This example generates data using model ex_sldemo_absbrake with two different desired slip ratios.

% Ensure Simulation Data Inspector is empty
Simulink.sdi.clear

% Open model
load_system('ex_sldemo_absbrake')

% Set slip ratio and simulate model
set_param('ex_sldemo_absbrake/Desired relative slip','Value','0.24')
sim('ex_sldemo_absbrake');

% Set new slip ratio and simulate model again
set_param('ex_sldemo_absbrake/Desired relative slip','Value','0.25')
sim('ex_sldemo_absbrake');

Plot Signals in the Inspect Pane

The Inspect Signals report includes all signals plotted in the graphical viewing area of the Inspect pane and all displayed metadata for the plotted signals.

% Get Simulink.sdi.Run objects
runIDs = Simulink.sdi.getAllRunIDs;
runID1 = runIDs(end-1);
runID2 = runIDs(end);

run1 = Simulink.sdi.getRun(runID1);
run2 = Simulink.sdi.getRun(runID2);

% Get Simulink.sdi.Signal objects for slp signal
run1_slp = run1.getSignalByIndex(4);
run2_slp = run2.getSignalByIndex(4);

% Plot slp signals
run1_slp.plotOnSubPlot(1, 1, true)
run2_slp.plotOnSubPlot(1, 1, true)

Create a Report of Signals Plotted in Inspect Pane

You can include more data in the report by adding more columns using the Simulation Data Inspector UI, or you can specify the information you want in the report programmatically with Name-Value pairs and the enumeration class Simulink.sdi.SignalMetaData. This example shows how to specify the data in the report programmatically.

% Specify report parameters
reportType = 'Inspect Signals';
reportName = 'Data_Report.html';


signalMetadata = [Simulink.sdi.SignalMetaData.Run, ...
    Simulink.sdi.SignalMetaData.Line, ... 
    Simulink.sdi.SignalMetaData.BlockName, ...
    Simulink.sdi.SignalMetaData.SignalName];

Simulink.sdi.report('ReportToCreate', reportType, 'ReportOutputFile', ...
    reportName, 'ColumnsToReport', signalMetadata);

Save and Restore a Set of Logged Signals

This example shows how to use the Simulink.HMI.InstrumentedSignals object to save a set of logged signals to restore after running a simulation with a different signal logging configuration.

Save the Initial Signal Logging Configuration

This example uses the sldemo_fuelsys model, which is configured to log 10 signals. Open the model and use the get_param function to get a Simulink.HMI.InstrumentedSignals object representing the signal logging configuration.

load_system sldemo_fuelsys

initSigs = get_param('sldemo_fuelsys','InstrumentedSignals');

You can save the initial signal logging configuration in a MAT-file for later use.

save initial_instSigs.mat initSigs

Remove All Logging Badges

To return to a baseline of no logged signals, you can use the set_param function to remove all logging badges from signals in your model. Then, you can easily select a different configuration of signals to log in the Simulink™ Editor or using the Simulink.sdi.markSignalForStreaming function.

set_param('sldemo_fuelsys','InstrumentedSignals',[])

Restore Saved Logging Configuration

After working with a different set of logged signals, you can restore a saved configuration using the Simulink.HMI.InstrumentedSignals object. For example, if you saved the logging configuration to a MAT-file, you can load the MAT-file contents into the workspace and use the set_param function to restore the previously saved logging configuration.

load initial_instSigs.mat

set_param('sldemo_fuelsys','InstrumentedSignals',initSigs)

See Also

Related Topics