Main Content

Inspect and Compare Data Programmatically

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

The Simulation Data Inspector organizes data in runs and signals, assigning a unique numeric identifier to each run and signal. The Simulink.sdi.Run and Simulink.sdi.Signal objects allow you to access to your data and view and modify run and signal metadata. When you interact with the Simulation Data Inspector programmatically, some functions require Signal or Run objects as inputs, while others use signal or run IDs. To access the run IDs in the workspace, you can use the Simulink.sdi.getAllRunIDs or Simulink.sdi.getRunIDByIndex function. You can access signal IDs through a Simulink.sdi.Run object using the getSignalIDByIndex method.

You can modify the Simulation Data Inspector preferences using functions like Simulink.sdi.setSubPlotLayout, Simulink.sdi.setRunNamingRule, and Simulink.sdi.setVisualization. To restore the Simulation Data Inspector default settings, use Simulink.sdi.clearPreferences.

Create Run and View Data

Create a run, add data to it, and then view the data in the Simulation Data Inspector.

Create Data for Run

Create two timeseries objects to contain data for a sine signal and a cosine signal. Give each timeseries object a descriptive name.

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 Run and Add Data

Use the Simulink.sdi.view function to open the Simulation Data Inspector.

Simulink.sdi.view

To import data into the Simulation Data Inspector from the workspace, create a Simulink.sdi.Run object using the Simulink.sdi.Run.create function. Add information about the run to its metadata using the Name and Description properties of the Run object.

sinusoidsRun = Simulink.sdi.Run.create;
sinusoidsRun.Name = "Sinusoids";
sinusoidsRun.Description = "Sine and cosine signals with different frequencies";

Use the add function to add the data you created in the workspace to the empty run.

add(sinusoidsRun,"vars",sine_ts,cos_ts);

Plot Data in Simulation Data Inspector

Use the getSignalByIndex function to access Simulink.sdi.Signal objects that contain the signal data. You can use the Simulink.sdi.Signal object properties to specify the line style and color for the signal and plot the signal in the Simulation Data Inspector. Specify the LineColor and LineDashed properties for each signal.

sine_sig = getSignalByIndex(sinusoidsRun,1);
sine_sig.LineColor = [0 0 1];
sine_sig.LineDashed = "-.";

cos_sig = sinusoidsRun.getSignalByIndex(2);
cos_sig.LineColor = [1 0 0];
cos_sig.LineDashed = "--";

Use the Simulink.sdi.setSubPlotLayout function to configure a 2-by-1 subplot layout in the Simulation Data Inspector plotting area. Then, use the plotOnSubplot function to plot the sine signal on the top subplot and the cosine signal on the lower subplot.

Simulink.sdi.setSubPlotLayout(2,1);

plotOnSubPlot(sine_sig,1,1,true);
plotOnSubPlot(cos_sig,2,1,true);

The sine wave and cosine wave signals are plotted in the Simulation Data Inspector. Two subplots align vertically. In the upper subplot, the Sine, T=5 signal is plotted in blue with a dash-dotted line style. In the lower subplot, Cosine, T=8 signal is plotted in red with a dashed line style.

Close Simulation Data Inspector and Save Data

When you finish inspecting the plotted signal data, you can close the Simulation Data Inspector and save the session to an MLDATX file.

Simulink.sdi.close("sinusoids.mldatx")

Compare Two Signals in the Same Run

You can use the Simulation Data Inspector programmatic interface to compare signals within a single run. This example compares the input and output signals of an aircraft longitudinal flight controller.

Load the Simulation Data Inspector session file that contains the flight control data.

Simulink.sdi.load("AircraftExample.mldatx");

To access the latest run, use the Simulink.sdi.Run.getLatest function.

aircraftRun = Simulink.sdi.Run.getLatest;

Use the Simulink.sdi.getSignalsByName function to access the Stick signal, which represents the input to the controller, and the alpha, rad signal, which represents the output.

stick = getSignalsByName(aircraftRun,"Stick");
alpha = getSignalsByName(aircraftRun,"alpha, rad");

Use the signal IDs to compare the Stick and alpha, rad signals using the Simulink.sdi.compareSignals function. The Stick signal is the baseline. The alpha, rad signal is the signal to compare against the baseline.

comparisonResults = Simulink.sdi.compareSignals(stick.ID,alpha.ID);
match = comparisonResults.Status
match = 
  ComparisonSignalStatus enumeration

    OutOfTolerance

The comparison result is out of tolerance. You can use the Simulink.sdi.view function to open the Simulation Data Inspector to view and analyze the comparison results.

Simulink.sdi.view

Comparison of the stick and alpha, rad signals

You can specify time and magnitude tolerance values to use for the comparison. Comparisons use tolerance values specified for the baseline signal in the comparison. To account for the phase shift, set a time tolerance of 1 on the Stick signal. To account for magnitude differences, set an absolute tolerance value of 0.1 on the Stick signal.

stick.TimeTol = 1;
stick.AbsTol = 0.1;

Compare the signals again. This time, because of the absolute and time tolerances, the signal comparison passes.

comparisonResults = Simulink.sdi.compareSignals(stick.ID,alpha.ID);
match = comparisonResults.Status
match = 
  ComparisonSignalStatus enumeration

    WithinTolerance

Comparison of the Stick and alpha, rad signals using a time tolerance of 1 and an absolute tolerance of 0.1

Compare Runs with Global Tolerance

You can specify global tolerance values to use when comparing two simulation runs. Global tolerance values are applied to all signals within the run. This example shows how to specify global tolerance values for a run comparison and how to analyze and save the comparison results.

Load the Simulation Data Inspector session file that contains the data to compare. The session file contains data for four simulations of an aircraft longitudinal flight controller. This example compares data from two runs that use different input filter time constants.

Simulink.sdi.load("AircraftExample.mldatx");

To access the run data to compare, use the Simulink.sdi.getAllRunIDs function to get the run IDs that correspond to the last two simulation runs.

runIDs = Simulink.sdi.getAllRunIDs;
runID1 = runIDs(end - 1);
runID2 = runIDs(end);

Use the Simulink.sdi.compareRuns function to compare the runs. Specify a global relative tolerance value of 0.2 and a global time tolerance value of 0.5.

runResult = Simulink.sdi.compareRuns(runID1,runID2,"reltol",0.2,"timetol",0.5);

Check the Summary property of the returned Simulink.sdi.DiffRunResult object to see whether signals are within the tolerance values or out of tolerance.

runResult.Summary
ans = struct with fields:
       OutOfTolerance: 0
      WithinTolerance: 3
            Unaligned: 0
        UnitsMismatch: 0
                Empty: 0
             Canceled: 0
          EmptySynced: 0
     DataTypeMismatch: 0
         TimeMismatch: 0
    StartStopMismatch: 0
          Unsupported: 0

All three signal comparison results fall within the specified global tolerance.

You can save the comparison results to an MLDATX file using the saveResult function.

saveResult(runResult,"InputFilterComparison");

Analyze Simulation Data Using Signal Tolerances

You can programmatically specify signal tolerance values to use in comparisons performed using the Simulation Data Inspector. In this example, you compare data collected by simulating a model of an aircraft longitudinal flight control system. Each simulation uses a different value for the input filter time constant and logs the input and output signals. You analyze the effect of the time constant change by comparing results using the Simulation Data Inspector and signal tolerances.

First, load the session file that contains the simulation data.

Simulink.sdi.load('AircraftExample.mldatx');

The session file contains four runs. In this example, you compare data from the first two runs in the file. Access the Simulink.sdi.Run objects for the first two runs loaded from the file.

runIDs = Simulink.sdi.getAllRunIDs;
runIDTs1 = runIDs(end-3);
runIDTs2 = runIDs(end-2);

Compare the two runs without specifying any tolerances.

noTolDiffResult = Simulink.sdi.compareRuns(runIDTs1,runIDTs2);

Use the getResultByIndex function to access the comparison results for the q and alpha signals.

qResult = getResultByIndex(noTolDiffResult,1);
alphaResult = getResultByIndex(noTolDiffResult,2);

Check the Status property of each signal result to see whether the comparison result falls within or out of tolerance.

qResult.Status
ans = 
  ComparisonSignalStatus enumeration

    OutOfTolerance

alphaResult.Status
ans = 
  ComparisonSignalStatus enumeration

    OutOfTolerance

The comparison uses a value of 0 for all tolerances, so the OutOfTolerance result means the signals are not identical.

You can further analyze the effect of the time constant by specifying tolerance values for the signals. Specify the tolerances by setting the properties for the Simulink.sdi.Signal objects that correspond to the signals being compared. Comparisons use tolerances specified for the baseline signals. This example specifies a time tolerance and an absolute tolerance.

To specify a tolerance, first access the Signal objects from the baseline run.

runTs1 = Simulink.sdi.getRun(runIDTs1);
qSig = getSignalsByName(runTs1,'q, rad/sec');
alphaSig = getSignalsByName(runTs1,'alpha, rad');

For the q signal, specify an absolute tolerance of 0.1 and a time tolerance of 0.6 using the AbsTol and TimeTol properties, respectively.

qSig.AbsTol = 0.1;
qSig.TimeTol = 0.6;

For the alpha signal, specify an absolute tolerance of 0.2 and a time tolerance of 0.8.

alphaSig.AbsTol = 0.2;
alphaSig.TimeTol = 0.8;

Compare the results again. Access the results from the comparison and check the Status property for each signal.

tolDiffResult = Simulink.sdi.compareRuns(runIDTs1,runIDTs2);
qResult2 = getResultByIndex(tolDiffResult,1);
alphaResult2 = getResultByIndex(tolDiffResult,2);

qResult2.Status
ans = 
  ComparisonSignalStatus enumeration

    WithinTolerance

alphaResult2.Status
ans = 
  ComparisonSignalStatus enumeration

    WithinTolerance

See Also

Related Topics