from Create Bus Data for Models with Root-Level Bus Inputs by Mike Anthony
Convert a matrix of data into a Simulink.TsArray according to the root-level bus object definition.

CreateTsArrayFromBusObject(top_bus, data, time, varargin)
function [TSout, data_ind] = CreateTsArrayFromBusObject(top_bus, data, time, varargin)
% CreateTsArrayFromBusObject
% Mike Anthony
% Mark McBroom
% Copyright 2008-2010 The MathWorks, Inc.
% 
% [TSout,data_ind]=CreateTsArrayFromBusObject(BusObject, DataMatrix, TimeVector, StartCol(optional) )
%
% This function take a matrix of data and creates the necessary TimeSeriesArray with appropriate data types
% based on the definitions in the bus object.
%
% Inputs
% =======
% BusObject: The Bus Object variable defined in the base workspace that corresponds to the input bus
% DataMatrix: The data matrix in the base workspace with the data corresponding
%                         to the bus input. IE. if the base workspace variable is data, the input should be 'data'.
% TimeVector: A column vector of data representing the evenly spaced time corresponding to the data in the matrix. 
% StartCol: The starting column in DataMatrix. Optional.  1 will be used if not specified.  Used when function is called
%           recursively for nested buses.
%
% Outputs
% ========
% TSout: The TimeSeries or TimeSeries array structured according to the bus object containing the data in the input
%        data matrix.
% data_ind: Last column in DataMatrix that was processed
%
% Limitations
% ============
% Assumes the time vector is evenly spaced
% Assumes the data matrix is columns of variables, rows of data
% Note that this requires the time vector as a separate arguement. If the time vector is a column of the data
% matrix, some pre-processing may be required. Also note that this assumes all the signals in the bus are the
% same sample time. This function does not handle buses with multiple sample times, as this is difficult to
% express via a matrix of data.
% Assumes that if the bus element is a vector, then contiguous columns in
% the data matrix will hold data for each element of the vector.
% Assumes that if the bus element is a matrix, then contiguous columns in
% the data matrix will hold data in row major order for each element of
% the matrix.
% Only supports 1 and 2D data.

% Cell array that will hold collection of timeseries and TSArrays for this
% level of the bus.
tsVector = {};
% if last arg not specified, start at the first column in the data matrix.
if size(varargin,2) == 0
    data_ind = 1;
else
    data_ind = varargin{1};
end

for i = 1:length(top_bus.Elements)
    % Check to see if this bus element is itself a bus ( i.e. nested bus )
    % First, look to see if the element type is a workspace data object
    ElementType = top_bus.Elements(i).DataType;
    tStr = ['exist(''',ElementType,''',''var'')'];
    isDO = evalin('base',tStr);
        
    if isDO > 0
        % check to see if the type of this element is a Bus
        isBus = evalin('base',['isa(',ElementType,',''Simulink.Bus'')']);
    else
        isBus = 0;
    end
    % If this element is a bus, process recursively.
    if isBus
        bus_do = evalin('base', ElementType);
        [tsa, data_ind] = CreateTsArrayFromBusObject( bus_do, data, time, data_ind);
        % add returned tsarray to collection of tsarray/timeseries
        tsVector{end+1} = tsa; %#ok<AGROW>
    else
        name = top_bus.Elements(i).Name;
        
        % handle widths > 1.  
        dims = top_bus.Elements(i).Dimensions;
        if length(dims) > 2
            fprintf(1,'## Error.  %s is greater than 2D and not supported.\n', name);
        end
        totalWidth = 1;
        for j=1:length(dims)
            totalWidth = totalWidth * dims(j);
        end
        % cast to proper data type
        dType = top_bus.Elements(i).DataType;
        locData = eval([dType '(data(:,data_ind:data_ind+totalWidth-1))']);
        
        % For scalar data, Simulink expects a column vector with a value
        % for each time step, Tx1  For 500 time steps, size is 500x1.
        % For a vector of data, Simulink expects format of TxC.  For
        % exmaple, for a vector of size 3, the data must be 500x3.
        % However, for a matrix, data must be RxCxT.  For example, a 3x5
        % matrix with 500 timesteps would be 3x5x500.
        % Reshape the data to fit this format.
        if totalWidth > 1 && length(dims) > 1
            if dims(1) > 1 && dims(2) > 1
                time_dims = size(time);
                % reshape to match the dimensions of the bus element.
                % i.e. change from 500x15 to 500x5x3
                locData = reshape(locData, time_dims(1), dims(2), dims(1) );
                % change from 500x5x3 to 3x5x500
                locData = permute(locData,[3 2 1]);
            end
        end
        sampleTime = time(3)-time(2);
        tsVector{end+1} = CreateTimeSeries(locData, time(1), sampleTime,'Name', name,'SignalName', name ); %#ok<AGROW>
        data_ind = data_ind+totalWidth;
    end
end
TSout = CreateTsArray(tsVector{:});

Contact us at files@mathworks.com