Using MATLAB in a task type

MATLAB can be used in a task type if Core.Host.Matlab is installed.

For example Example.Matlab.PlotXY uses MATLAB to fit a curve:

The main script.py contains the boilerplate XamFlow input and output handling, and uses runutil.run() to execute a MATLAB script:

import xfworkerutil
import runutil

import os


worker = xfworkerutil.XFWorkerJob()

inputs = worker.job['inputs']

# Download input files
table_path = worker.download_input_file(inputs['table'])

plot_path = worker.create_related_path(table_path, '_plot.png')

# Run Matlab script

def run_matlab_script(name, *args, **kwargs):
    function_parameters =  ','.join(args)
    runutil.run("Matlab", [
            "matlab.exe",
            "-nosplash",
            "-noFigureWindows",
            "-nodesktop",
            "-wait",
            "-r", f"{name}({function_parameters}),quit force",
        ], **kwargs)

matlab_script_dir = os.path.dirname(os.path.realpath(__file__))

compiled = False # See readme.txt

if compiled:
    #cwd = matlab_script_dir
    cwd = None
    runutil.run("Compiled Matlab script", [
            os.path.join(matlab_script_dir, r"plot_csv_compiled.exe"),
            str(table_path),
            str(plot_path),
        ], cwd=cwd)
else:
    run_matlab_script("plot_csv", f"'{table_path}'", f"'{plot_path}'", cwd=matlab_script_dir)

# Upload output files
worker.upload_output_file(plot_path)

# Save outputs
outputs = {
    "plot": worker.create_output_bitmap(plot_path.name),
}
worker.finish(outputs)

The plot_csv.m script contains the MATLAB commands:

function [] = plot_csv(csv_path, plot_path)

% Open CSV-file (skip one row and one column)
table = csvread(csv_path, 1, 1)

x = table(:, 1)
y = table(:, 2)

% Plot data
fig = figure()

% `fit` requires the "Curve Fitting Toolbox"!
% Alternative without trendline: scatter(x, y)
plot(fit(x, y, 'poly1'), x, y)

% Save plot
saveas(fig, plot_path)

exit

end

Octave

Similarly Octave can be used in a task type if Core.Host.Octave is installed.

For example in Example.Octave.PlotXY the main script.py contains the boilerplate XamFlow input and output handling, and uses runutil.run() to execute an Octave script:

import xfworkerutil
import runutil

import os


worker = xfworkerutil.XFWorkerJob()

inputs = worker.job['inputs']

# Download input files
table_path = worker.download_input_file(inputs['table'])

plot_path = worker.create_related_path(table_path, '_plot.png')

# Run Octave script
def run_octave_script(scriptname, *args, **kwargs):
    runutil.run("Octave", [
            "octave-cli.exe",
            "--no-gui",
            "--no-window-system",
            scriptname,
        ] + list(args), **kwargs)

octave_script_dir = os.path.dirname(os.path.realpath(__file__))
run_octave_script("plot_csv.m", str(table_path), str(plot_path), cwd=octave_script_dir)

# Upload output files
worker.upload_output_file(plot_path)

# Save outputs
outputs = {
    "plot": worker.create_output_bitmap(plot_path.name),
}
worker.finish(outputs)

The plot_csv.m script contains the Octave commands:

arg_list = argv ();
csv_path = arg_list{1}
plot_path = arg_list{2}

% Open CSV-file (skip one row and one column)
table = csvread(csv_path, 1, 1)

x = table(:, 1)
y = table(:, 2)

% Fit line
order = 1;
p = polyfit (x, y, order);
tx = linspace (min(x), max(x), 101)
ty = polyval (p, tx);

% Plot data
fig = figure()
plot (tx, ty, '-', x, y, 's')

% Save plot
saveas(fig, plot_path)