%% Attaching Input Data to External Inputs via Custom Input Mappings
%
% This example shows how to create a custom mapping function for the Root 
% Inport Mapper tool. The Root Inport Mapper tool associates MAT-file data  
% with a specific input port, based on one of these criteria.
%
% * *Port Order*         - Maps in the order it appears in the file to the
% corresponding port number.
% * *Block Name*    - Maps by variable name to the corresponding root
% inport with the matching block name.
% * *Signal Name*   - Maps by variable name to the corresponding root
% inport with the matching signal name.
% * *Block Path*    - Maps by the BlockPath parameter to the
% corresponding root inport with the matching block path.
% * *Custom*        - Maps using a MATLAB function. 
%
% Use a custom mapping criteria when the data you are trying to map does
% not match any of the other mapping criteria.

% Copyright 2012-2018 The MathWorks, Inc.

 

%% Custom Mapping Scenario
%
% If the combination of input data and the model input
% ports does not match Port Order, Block Name, Signal Name, or Block Path
% mapping criteria, you can do one of the following: 
% 
% * Rename the input data in the MAT-file
% * Rename the input ports on the model
% * Use the custom mapping mode
% 
% This example shows how to write a custom mapping function. 
%
% The workflow described below includes
%
% * Create a MATLAB File to contain the custom mapping function
% * Declare the custom mapping function name, inputs, and outputs
% * Initialize the output for assignment of the return value
% * Define and implement your mapping algorithm
% * Validate your mapping algorithm

%% Create a New MATLAB Function File
% Create a MATLAB function file. This file will contain your custom mapping
% function. 

%% Declare Custom Mapping Function
% Declare a custom mapping function name, and specify the inputs and outputs.
% <matlab:edit('slexCustomMappingMyCustomMap.m') slexCustomMappingMyCustomMap> 
% is the custom mapping function in this example. It declares the function
% inputs and outputs as defined below.
% 
% *Inputs*
%
% * _modelName_     - String that contains the model name.
% * _signalNames_   - Cell array of strings that contain variable names of 
%                     signals to map
% * _signals_       - Cell array of signal data aligned with
%                     signalNames such that signalNames{1} is the
%                     variable name of the signal stored in signals{1}.
%
% *Outputs*
% 
% * _inputMap_      - Array or scalar of objects that result from
%                     the getRootInportMap function.
% 


%% Initialize the Output
%
% Initialize the value of the output variable inputMap.
% To do this use the |getRootInportMap| command with the empty property as shown
% in the example function <matlab:edit('slexCustomMappingMyCustomMap.m')
% slexCustomMappingMyCustomMap> or in the code snippet below. This initializes
% the output variable to empty so that a value can be assigned to the output.
%
%  inputMap = getRootInportMap('empty');

%% Define Your Custom Mapping Algorithm
% 
% Things to think about when defining your custom mapping algorithm.
% 
% * What is the criteria for mapping signals to a root-level inport , for
% example BlockName mapping matches the name of the input signal to the
% name of the root-level inport block name.
% * What information is needed to create a mapping.
% * What happens if the mapping criteria determines that there is no match between
% signal and root-level inport.
% 
% The example addresses these items by
% 
% * Using the root-level port number and signal name for mapping criteria.
% 
% * Using a utility function
% <matlab:edit('slexCustomMappingGetPortNames.m')
% slexCustomMappingGetPortNames>
%   to get root-level inport block names to provide as input along with the
%   variable|signalName| to the |getRootInportMap| function which creates
%   the mapping.
% 
% * Including a logical condition to handle the case where there is no
% match between port number and signal name.
% 

%% Implement Your Mapping Algorithm
% 
% Next, implement your mapping algorithm. 
% 
% In the <matlab:edit('slexCustomMappingMyCustomMap.m')
% slexCustomMappingMyCustomMap> implementation, the root-level inport port
% number is the mapping criteria criteria. The algorithm gets this port number
% from the root-level inport block. It then gets the numerical values
% appended to the names of the signals that are passed into the function,
% and compares the port number with the numerical values.
% 
% 
% NOTE: In addition to implementing your mapping algorithm,
% you should also include a logical statement to handle situations where a
% mapping is not possible. The example function does this by using an |if|
% statement with the |isempty| function to determine if a mapping can be made.
% 
 
%% Create the Mapping
% 
% The final step is to use the
% |getRootInportMap| function to create a custom map. The |getRootInportMap| function uses Property-Value pairs to create a custom
% map. The properties are:
% 
% * _model_         - String that represents the model name.
% * _signalName_    - String or cell of strings that contains the value of the variable name of the signal to map. 
% * _blockName_     - String or cell of strings that contains the value of the block name of the port to be mapped. 
% 
% The following code is an example of this function. This same code appears in the example function <matlab:edit('slexCustomMappingMyCustomMap.m')
% slexCustomMappingMyCustomMap>.
% 
%   inputMap = getRootInportMap(...
%                           'model',modelName,...
%                           'signalName',signalNames,...
%                           'blockName',portNames);
%   
 
%% Validate the Custom Mapping Function
% 
% To validate the custom mapping function at the command line:
% 
% # Open the model against which you want to test your function.
% # Create some input signals to support the model. 
% # Call your custom mapping function with the correct input parameters. 
% # Validate the expected input string to send to the |sim| command, or to
% place in the model configuration parameters External Input String edit
% box.
% 
% Execute the lines of code in the following example. This code uses the
% custom mapping function provided with this example. If the custom map
% function succeeds, you should see a comma-separated list of variable
% names displayed in the order of the port number to which they are
% assigned (|'port1,port2'|).
% 
%   load_system('slexAutotransRootInportsExample'); port1               =
%   timeseries(ones(10,1)*10); port2               =
%   timeseries(zeros(10,1)); inputMap            =
%   slexCustomMappingMyCustomMap('slexAutotransRootInportsExample',{'port1'
%   , 'port2'},{port1 , port2}); externalInputString =
%   getInputString(inputMap,'base');
%   close_system('slexAutotransRootInportsExample',0);
%
% If your signals are in a Simulink.SimulationData.Dataset, you can execute
% the lines of code in the following example. This code uses the custom
% mapping function provided with this example. If the custom mapping
% function succeeds, you should see a comma-separated list of variable
% names displayed in the order of the port number to which they are
% assigned (|'ds.getElement(1),port1,ds.getElement(2)'|).
%
%   load_system('slexAutotransRootInportsExample');
%   ds = Simulink.SimulationData.Dataset;
%   ds = ds.addElement( timeseries(ones(10,1)*10),'port1');
%   ds = ds.addElement( timeseries(zeros(10,1)),'port1');
%   inputMap            = slexCustomMappingMyCustomMap('slexAutotransRootInportsExample',{'ds'},{ ds });
%   externalInputString = getInputString(inputMap,'base');
%   close_system('slexAutotransRootInportsExample',0);