# Lesson 3. Creating a Butterworth User Application Script

In this MATLAB example, you'll learn how to modify the Butterworth filter operator that you created in Lesson 2 to be a MATLAB standalone application. MATLAB standalone applications can be run using the MATLAB Runtime without have to install MATLAB.

MATLAB Applications are created using the MATLAB Compiler. The resulting *.exe file can be run without having MATLAB installed on the oscilloscope or PC. However, the MATLAB Runtime must be installed on the oscilloscope or PC where Infiniium is installed and the MATLAB Runtime version must be the same version as was targeted when the MATLAB Application was created.

## Procedure

1. Complete Lesson 2. The resulting Butterworth.xml and Butterworth.m files should be in Infiniium's user functions folder (\Documents\Keysight\Infiniium\User Functions).
2. Using a text editor, open the Butterworth.xml file. Change the content of the file's <Script> element from Butterworth.m to algorithm.exe. We will create algorithm.m which will be compiled into algorithm.exe.

All letters in algorithm.m must be typed in lower case. Naming the function Algorithm.m will break the script.

Butterworth.xml
Drag the mouse over this listing, enter Ctrl-C to copy, and paste it into your text editor.
<?xml version="1.0" encoding="utf-8"?> <Function xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <Script>algorithm.exe</Script> <Name>Butterworth</Name> <Abbreviation>Butter</Abbreviation> <Comments>Creates a Butterworth filter</Comments> <FunctionType>1 Source</FunctionType> <Control Name = "FilterType"> <Enumeration> <Default>low</Default> <Selection>low</Selection> <Selection>high</Selection> </Enumeration> </Control> <Control Name = "FilterOrder"> <Integer> <Min>1</Min> <Max>4</Max> <Units>None</Units> <Default>2</Default> </Integer> </Control> <Control Name = "FilterCutoff"> <Double> <Min>10e6</Min> <Max>1000e9</Max> <Resolution>1000</Resolution> <Units>Hertz</Units> <Default>7.5e9</Default> </Double> </Control> <Control Name = "IsPeriodic"> <Integer> <Min>0</Min> <Max>1</Max> <Units>None</Units> <Default>0</Default> </Integer> </Control> </Function>

3. Make a copy of the Butterworth.m script file and rename the copy algorithm.m. The name of a script file for a standalone application must always be algorithm.m.
4. Open the algorithm.m script file in MATLAB. Make the following edits to the script as shown in this listing:

1. Add the first line in the script as shown in green.
2. Add the reference `InputVars.`shown in red before every Infiniium input variable in the script. Do not forget to add the period character "." between `InputVars.` and the variable. For example, `SrcData` becomes `InputVars.SrcData`.
3. Add a structure of output variables shown in blue to the end of the script.

Script algorithm.m with Modifications
Drag the mouse over this listing, enter Ctrl-C to copy, and paste it into the MATLAB editor.
    function OutputVars = algorithm(InputVars)

    % Initialize output variables
    FiltData = []; % Output waveform
    Gain = 1.0;
    XUnits = 'Same';
    YUnits = 'Same';
    ErrorMsg = '';

    % Gather input data
    SrcData = InputVars.SrcData; % Input waveform
    XOrg = InputVars.XOrg;
    XInc = InputVars.XInc;

    % Gather user-defined controls
    N = InputVars.FilterOrder;
    Fc = InputVars.FilterCutoff;
    FType = InputVars.FilterType;
    IsPeriodic = InputVars.IsPeriodic;

    % Constant output variables
    FilterDelay = N * 0.112 / Fc;
    FilterWidth = N / Fc;

    if ~isempty(SrcData)
        % Create the filter
        Wn = 2 * XInc * Fc;
        [B,A] = butter(N, Wn, FType);
        numPts = length(SrcData);
        if IsPeriodic
            % Perform the filtering circularly using ffts.
            fftSrcData = fft(SrcData);
            h = freqz(B, A, numPts, 'whole').';
            FiltData = real(ifft(fftSrcData .* h));

            % Rotate to remove FilterDelay.
            shift = round(FilterDelay / XInc);
            FiltData = circshift(FiltData, [0, -shift]);
        else
            startIndex = ceil(FilterWidth / XInc) + 1;
            if (startIndex > numPts)
                ErrorMsg = 'Too few points. Pipeline eats up entire waveform.';
            else
                % Perform the filtering
                FiltData = filter(B, A, SrcData);

                % Remove filter delay and pipeline
                FiltData = FiltData(startIndex:end);
                leadPipeline = FilterWidth - FilterDelay;
                XOrg = XOrg + leadPipeline;
            end
        end
    end

    OutputVars = struct(...
        'FiltData', FiltData,...
        'XOrg', XOrg,...
        'XInc', XInc,...
        'Gain', Gain,...
        'FilterWidth', FilterWidth,...
        'FilterDelay', FilterDelay,...
        'XUnits', XUnits,...
        'YUnits', YUnits,...
        'ErrorMsg', ErrorMsg);

5. Create a folder to which you will save the files that will be compiled into your standalone application. The file are:

1. Move the algorithm.m script file that you created in the previous step.

2. Copy two additional files that are required when compiling a MATLAB script into a MATLAB standalone application:

   - InteropHelper.jar
   - wrapper.m

   The location of additional files to compile is:

   - From the "Demo" shortcut folder located in \My Documents\Keysight\Infiniium\User Functions
   - Directly from the folder: \Program Files\Keysight\Infiniium\Demo\
     User Functions\Demo Compiled MATLAB

Do not place the Butterworth.xml file into this folder.

6. Your folder for compiling your script should now have these files:

   - algorithm.m
   - InteropHelper.jar
   - wrapper.m

7. In MATLAB's Command Window, run the deploytool command to view the Compiler dialog box.

8. In the New Task, MATLAB COMPILER section, select Standalone Application.

9. In the Standalone DesktopApp tab, add wrapper.m as the main file, and enter Butterworth for Application Info.

10. In the Executable Details section, enter algorithm for the Executable Name, and select Standalone Application for the Application Type. algorithm will be the name given to your .exe file.

11. In the Files Required for Standalone to Run section, add the algorithm.m and InteropHelper.jar files as shown in the following picture.

12. Save your standalone application project. Then, select Build from Build and Package.

13. After the compile completes, close the MATLAB compiler and open File Explorer. MATLAB has placed the compiled files for the application in the MATLAB\algorithm\for_testing folder as shown in this picture. The executable file is algorithm.exe. Remember, that at the start of this lesson you edited the Butterworth.xml file's <Script> element to use the algorithm.exe file.

14. Copy the algorithm.exe file to Infiniium's user functions folder (\Documents\Keysight\Infiniium\User Functions).

15. On each PC or oscilloscope where you want to run your executable, perform the following steps:

    1. Install Infiniium
    2. Place the Butterworth.xml and algorithm.exe files in Infiniium's user functions folder (\Documents\Keysight\Infiniium\User Functions).
    3. Install the correct MATLAB Compiler Runtime (MCR) version.
    4. Click the button on the lower-right corner of the screen.
    5. At the top of the Functions dialog box, select the User tab and drag a single-input User operator icon into the operator construction area as shown in the following picture.
    6. Click on the user operator to open the User Operator Setup dialog box.
    7. In the dialog box, click Browse and select your XML configuration file, Butterworth.xml which points to the algorithm.exe file.
    8. In the Functions dialog box, drag a Function Color to the User Operator as shown in the following picture. This will display the output waveform of the function.

    You may have to wait a few seconds for the waveform to appear and the waring icon () to be removed.