Function conventions

From OPS
Jump to: navigation, search

All CReSIS Toolbox Development Guides

Functions are names with underscores between words. For example "read_param_xls" is the function for reading parameter spreadsheets (Excel .xls documents).

For functions that operate on multiple data segments, there is a specific structure that should be followed described in Code for Multiple Segments.

The typical setup for functions in the toolbox is that each function has:

  1. A run script called "run_FUNCTION" if the function has a complicated input interface that would be hard to describe in comments only
  2. A function called "FUNCTION"
  3. Cluster Only: A function called "FUNCTION_task" that takes a single parameter structure and outputs a binary success field (and potentially other outputs) that can be matlab compiled to run on a cluster node

Run Script

The run script should have a format like:

% script run_FUNCTION
%
% Script for running FUNCTION
%
% Authors: FILL_IN_AS_NEEDED
%
% See also: run_FUNCTION.m, FUNCTION.m, FUNCTION_task.m, FILL_IN_AS_NEEDED

%% User Setup
% =====================================================================

% Only include the code dealing with param_override if the function needs to access the gRadar structure
param_override = [];

param1 = 'first parameters';
... % Additional parameters setup here

%param_override.sched.type = 'no scheduler'; % Example to override default cluster settings

%% Automated Section
% =====================================================================

% Setup param_override
global gRadar;
if exist('param_override','var')
  param_override = merge_structs(gRadar,param_override);
else
  param_override = gRadar;
end

% Pre process code (only include if necessary)

FUNCTION(param_override, param1, ...);

% Post process code (only include if necessary)

Function

The function should have an interface like this:

function [oparam,...] = FUNCTION(param, param1, ...)
% [oparam,...] = FUNCTION(param, param1, ...)
%
% FUNCTION DESCRIPTION
%
% param: gRadar-style parameter structure (only include if needed)
% param1: Scalar which specified ...
% param2: String containing ...
% param3: Structure with information about
%  .field: N by 2 double array with ...
% param4: Etc.
%
% oparam: output parameters...
%
% Example:
%  See run_FUNCTION.m for how to run this function directly.
%
% Authors: FILL_IN_AS_NEEDED
%
% See also: run_FUNCTION.m, FUNCTION.m, FUNCTION_task.m, FILL_IN_AS_NEEDED

%% Setup
% =====================================================================

...

THE CODE BELOW HERE IS ONLY REQUIRED FOR RUNNING ON THE CLUSTER:


%% Setup scheduler
% =====================================================================
if strcmpi(param.sched.type,'custom_torque')
  global ctrl; % Make this global for convenience in debugging
  ctrl = torque_new_batch(param);
  fprintf('Torque batch: %s\n', ctrl.batch_dir);
  torque_compile('FUNCTION_task.m',ctrl.sched.hidden_depend_funs,ctrl.sched.force_compile);
else
  ... Add additional cluster support here if needed
end

%% Execute tasks/jobs
% =====================================================================
fh = @FUNCTION_task;
arg{1} = task_param;
      
if strcmp(param.sched.type,'custom_torque')
  create_task_param.conforming = true;
  create_task_param.notes = sprintf('FILL_IN_AS_NEEDED', FILL_IN_AS_NEEDED);
  ctrl = torque_create_task(ctrl,fh,1,arg,create_task_param);
else
  ... Add additional cluster support here if needed
end

%% Cleanup tasks/jobs
% =====================================================================
if strcmpi(param.sched.type,'custom_torque')
  % Wait until all submitted jobs to complete
  ctrl = torque_rerun(ctrl);
  if ~all(ctrl.error_mask == 0)
    if ctrl.sched.stop_on_fail
      torque_cleanup(ctrl);
      error('Not all jobs completed, but out of retries (%s)', datestr(now));
    else
      warning('Not all jobs completed, but out of retries (%s)', datestr(now));
      keyboard;
    end
  else
    fprintf('Jobs completed (%s)\n\n', datestr(now));
  end
  torque_cleanup(ctrl);
else
  ... Add additional cluster support here if needed
end

Function Task

This function is only required for running on the cluster. The FUNCTION_task function should look like this:

function [success,oparam,...] = FUNCTION_task(param)
% [success,oparam,...] = FUNCTION_task(param)
%
% FUNCTION DESCRIPTION
%
% param: struct with parameters
%  FILL_IN_AS_NEEDED
%
% success: logical scalar (1 for success, function will throw an
%   error with an error message on failure)
% oparam: output parameters...
%
% Example:
%  Normally this function is called from run_FUNCTION.m
%
% Authors: FILL_IN_AS_NEEDED
%
% See also: run_FUNCTION.m, FUNCTION.m, FUNCTION_task.m, FILL_IN_AS_NEEDED

return 1 for success and run "error('MESSAGE')" on failure
Personal tools
Namespaces

Variants
Actions
Navigation
Tools