Difference between revisions of "AnyWave:MATLAB Batch"

From WikiMEG
Jump to: navigation, search
(1 - edit the desc.txt)
(3. Define the arguments required by your plugin)
 
(6 intermediate revisions by one user not shown)
Line 2: Line 2:
 
One of the features of AnyWave is to run some processing from the command line.<br/>
 
One of the features of AnyWave is to run some processing from the command line.<br/>
 
This is called batch processing, allowing to process many files in different locations using a script file run by the OS.<br/>
 
This is called batch processing, allowing to process many files in different locations using a script file run by the OS.<br/>
 
 
=Make my plugin runnable in command line=
 
=Make my plugin runnable in command line=
 
If you want AnyWave to handle your plugin using the command line, you must do as follow:<br/>
 
If you want AnyWave to handle your plugin using the command line, you must do as follow:<br/>
Line 16: Line 15:
 
flags = CanRunFromCommandLine:NoDataRequired<br/>
 
flags = CanRunFromCommandLine:NoDataRequired<br/>
 
This indicates that the plugin can be called from the command line but also indicates that no data file is required. (The plugin will not run on a data file.)<br/>
 
This indicates that the plugin can be called from the command line but also indicates that no data file is required. (The plugin will not run on a data file.)<br/>
 
 
== 2 - edit your MATLAB code ==
 
== 2 - edit your MATLAB code ==
 
Modify the main.m file:<br/>
 
Modify the main.m file:<br/>
Line 59: Line 57:
  
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
== 3. Define the arguments required by your plugin==
 
+
AnyWave offers a set of predefined arguments name, let's call them common arguments.<br/>
 
+
See here to view all the common arguments name to use.<br/>
=Make my plugin compatible=
+
But sometimes, you will need to use specific arguments for your plugin and you will need to let AnyWave know about them.<br/>
This is quite simple. First, you need to edit the desc.txt and add the CanRunFromCommandLine flag:<br/>
+
To inform AnyWave about the argument key it will recognize from the command line and pass them to your plugin, you need to add a json file to the folder containing your plugin.<br>
==edit desc.txt==
+
Note: you can also use the NoDataRequired if your plugin does not a file to be open in AnyWave to run.<br/>
+
In this case the flags line will be: flags = CanRunFromCommandLine:NoDataRequired<br/>
+
<syntaxhighlight lang="text">
+
name = MyPlugin
+
description = do something in MATLAB
+
category = Process:Test:MyPlugin
+
flags = CanRunFromCommandLine
+
</syntaxhighlight>
+
==JSON Files==
+
After you've modified the desc.txt you will need to create two json files and place them in your plugin folder.<br/>
+
 
+
==ui.json==
+
There are some important things to setup in ui.json file:<br/>
+
There is a key describing the input parameters of the plugin. Suppose that you want to compute something on several files, you must then set several input_keys in the json file.<br/>
+
This is done by creating the '''input_keys''' key.<br/>
+
This key will hold the names of all the other keys that must be considered as files that AnyWave will provide to our plugin when running it.<br/>
+
In our example below, there is only ONE file key, that we called input_file which is the default key name for the file argument.<br/>
+
Hence, AnyWave will bring a GUI to pick up all the files we want, and run our plugin on all those files.<br/>
+
Once you setup the FILES entries keys, you must also describe them in the file by setting two values to the corresponding key.<br/>
+
The first value is always the decorated readable name of the key that will be used to create the GUI.<br/>
+
The second value is a string. If you set "check" as the value, that will tell AnyWave to check that the file setup is a data file and not a side car file.<br/>
+
If you don't want a data file to be set, just set an empty string as the value.<br/>
+
 
+
Let's setup an example using one input file and two parameters:<br/>
+
<syntaxhighlight lang="java">
+
{
+
"input_keys" : [ "input_file"],
+
"input_file" : ["Input File", "check"],
+
"hp" : ["High Pass Filter", "double"],
+
"lp" : ["Low Pass Filter", "double"],
+
"fields_ordering" : ["hp", "lp"]
+
}
+
</syntaxhighlight>
+
'''input_keys''' : mandatory key. Here, we setup only one input file, and the key is called "input_file".<br/>
+
Then we must describe that key:
+
* "Input File" is the name used in the GUI to describe the parameter.
+
* "check" indicates that the file MUST be a data file that AnyWave can read.
+
'''fields_ordering''': mandatory key. Describe the GUI fields order. Here we set up HP before LP in the GUI.<br/>
+
 
<br/>
 
<br/>
Between the mandatory keys, you have the other parameters:<br/>
+
The file must be named '''args.json''' and must contain at least one key called '''parameters'''.<br/>
* hp described as High Pass Filter, and "double" indicates this parameter is a double value.
+
An optional key named '''flags''' may also  be added. flags will be used as boolean arguments for the plugin.<br/>
* lp described as Low Pass Filter, and "double" indicates this parameter is a double value.
+
Example:<br/>
 
+
Others possible parameter values:<br/>
+
 
+
{| class="wikitable"
+
|-
+
! value !! description
+
|-
+
| "double"|| double precision value
+
|-
+
| "int" || integer value
+
|-
+
| "list" || indicates we want a combo list selection among predefined item.
+
|-
+
| "string" || string value
+
|-
+
| "stringList" || an array of strings.
+
|}
+
 
+
==default.json==
+
This file comes to se the default values for parameters described in ui.json.<br/>
+
So you need to define the same keys and set a default value for them.<br/>
+
In our skeleton that will be:<br/>
+
 
<syntaxhighlight lang="java">
 
<syntaxhighlight lang="java">
 
{
 
{
"input_file" : "",  
+
"parameters" : [ "eeg_file", "meg_file"],
"hp" : 0.,
+
"flags" : [ "downsample", "use_threshold"]
"lp" : 0.
+
 
}
 
}
 
</syntaxhighlight>
 
</syntaxhighlight>
 
+
Hence, AnyWave will be able to parse --eeg_file and --meg_file keys from the command line and pass them to your plugin (in the args global variable):<br/>
=GUI representation of ui.json=
+
AnyWave will also parse arguments --downsample <true|yes|false|no> and set the corresponding boolean value.<br/>
See below the GUI representation of keys inserted in the ui.json:<br/>
+
{| class="wikitable"
+
|-
+
! key !! GUI
+
|-
+
| "hp" : ["High Pass", "double"] || [[File:Json_ui_key_double.png]]
+
|-
+
| "n_iter" : ["#Iterations", "int"] || [[File:Json_ui_key_int.png]]
+
|-
+
| "modality" : ["Modality", "list"] || [[File:Json_ui_key_list.png]]
+
|-
+
| "output_prefix" : ["Output Prefix", "string"] || [[File:Json_ui_key_string.png]]
+
|}
+
 
+
'''Note''': The list type will make a combobox list selection of items. Define the possible items in default.json file:<br/>
+
"modality" : ["MEG", "EEG", "SEEG"]<br/>
+
 
+
=Example=
+
A small test plugin that takes TWO files as input:<br/>
+
* a MEG file
+
* an EEG file
+
==desc.txt==
+
<syntaxhighlight lang="text">
+
name = MAT_BATCH
+
description = TEST_BATCH
+
category = Process:TEST:MAT_BATCHING
+
flags = CanRunFromCommandLine:NoDataRequired
+
</syntaxhighlight>
+
==ui.json==
+
<syntaxhighlight lang="java">
+
{
+
"input_keys" : [ "meg_file", "eeg_file"],
+
"meg_file" : ["MEG File", "check"],
+
"eeg_file" : ["EEG File", "check"],
+
"output_file_prefix" : ["Output File Prefix", "string"],
+
"fields_ordering": [ "output_file_prefix" ]
+
}
+
</syntaxhighlight>
+
We set up two files as input (eeg_file, meg_file).<br/>
+
output_file_prefix is a string variable we will use to prefix our output filename.<br/>
+
There is only one '''field''' because meg_file and eeg_file are input files keys, so they won't appear in the left part of the GUI but in the input file part.<br/>
+
==default.json==
+
<syntaxhighlight lang="java">
+
{
+
"meg_file" : "",
+
"eeg_file" : "",
+
"output_file_prefix" : "resampled"
+
}
+
</syntaxhighlight>
+
==main.m==
+
 
<syntaxhighlight lang="matlab">
 
<syntaxhighlight lang="matlab">
 
function main(varargin)
 
function main(varargin)
global args;
+
global args;  %% DO NOT FORGET
if isdeployed
+
% init code
% STANDALONE AnyWave Plugin code
+
% ...
  global host;
+
  global port;
+
  global pid;
+
 
+
  if (nargin < 3)
+
      error('missing arguments.');
+
  end
+
  host = varargin{1};
+
  port = str2num(varargin{2});
+
  pid = str2num(varargin{3});
+
  if (nargin > 3)
+
    args = varargin{4};
+
  end
+
 
+
  assignin('base', 'host', host);
+
  assignin('base', 'port', port);
+
  assignin('base', 'pid', pid);
+
  assignin('base', 'args', args);
+
% end of STANDALONE AnyWave Plugin code
+
end
+
 
+
% we assume here that the code will always run in batch mode.
+
% To check if the plugin was called in batch mode, just check if args variable is empty or not.
+
if isempty(args)
+
  error('this plugin will only run in batch mode');
+
end
+
 
+
 
+
pathMEG = args.meg_file;
+
pathEEG = args.eeg_file;
+
infosMEG = aw_getfileinfo(pathMEG);
+
if isempty(infosMEG)
+
    error('Could not open MEG file');
+
end
+
infosEEG = aw_getfileinfo(pathEEG);
+
if isempty(infosEEG)
+
  error('Could not open EEG file');
+
end
+
 
+
cfg=[];
+
cfg.file = pathEEG;
+
markersEEG = aw_getmarkers(cfg);
+
cfg.file = pathMEG;
+
cfg.channels = { 'Trigger' };
+
markersMEG = aw_gettriggers(cfg);
+
  
cfg = [];
+
eeg = args.eeg_file;
cfg.file = pathEEG;
+
meg = args.meg_file;
cfg.filtering = 'yes';
+
cfg.start = 0;
+
cfg.duration = -1;
+
cfg.eeg_lp = infosEEG.max_sr / 3;
+
  
eegdata = aw_getdata(cfg);
+
% compute something...
assert(~isempty(eegdata));
+
disp(eegdata);
+
 
end
 
end
 
</syntaxhighlight>
 
</syntaxhighlight>

Latest revision as of 15:30, 21 April 2020

Introduction

One of the features of AnyWave is to run some processing from the command line.
This is called batch processing, allowing to process many files in different locations using a script file run by the OS.

Make my plugin runnable in command line

If you want AnyWave to handle your plugin using the command line, you must do as follow:

1 - edit the desc.txt

name = MyPlugin
description = do something in MATLAB
category = Process:Test:MyPlugin
flags = CanRunFromCommandLine

Note: we've added a line with the flags keyword. This keyword will inform AnyWave of the capabilities of your plugin.
You may combine flags using the : (the colon character). Example:
flags = CanRunFromCommandLine:NoDataRequired
This indicates that the plugin can be called from the command line but also indicates that no data file is required. (The plugin will not run on a data file.)

2 - edit your MATLAB code

Modify the main.m file:

function main(varargin)
global args;  %% IMPORTANT: this variable will hold the arguments set by the user on the command line. 
if isdeployed  % this is the code to use if you plan to Compile your plugin to distribute it.
% STANDALONE AnyWave Plugin code
   global host;   
   global port;
   global pid;
 
   if (nargin < 3) % basic argument checking
       error('missing arguments.');
  end
  host = varargin{1};
  port = str2num(varargin{2});
  pid = str2num(varargin{3});
  if (nargin > 3)
    args = varargin{4};
  end
 
  assignin('base', 'host',  host);
  assignin('base', 'port', port);
  assignin('base', 'pid', pid);
  assignin('base', 'args', args);
% end of STANDALONE AnyWave Plugin code
end
 
% we assume here that the code will always run in batch mode.
% To check if the plugin was called in batch mode, just check if args variable is empty or not.
if isempty(args)
   error('this plugin will only run in batch mode');
end
 
% code your stuff here
% use args to get the arguments:
% args is a structure containing fields named upon the arguments set by the command line.
%
% one of the common argument set by AnyWave is input_file which contains the path to the data file to process.
% so to get the file use :  file = args.input_file;

3. Define the arguments required by your plugin

AnyWave offers a set of predefined arguments name, let's call them common arguments.
See here to view all the common arguments name to use.
But sometimes, you will need to use specific arguments for your plugin and you will need to let AnyWave know about them.
To inform AnyWave about the argument key it will recognize from the command line and pass them to your plugin, you need to add a json file to the folder containing your plugin.

The file must be named args.json and must contain at least one key called parameters.
An optional key named flags may also be added. flags will be used as boolean arguments for the plugin.
Example:

{
"parameters" : [ "eeg_file", "meg_file"],
"flags" : [ "downsample", "use_threshold"]
}

Hence, AnyWave will be able to parse --eeg_file and --meg_file keys from the command line and pass them to your plugin (in the args global variable):
AnyWave will also parse arguments --downsample <true|yes|false|no> and set the corresponding boolean value.

function main(varargin)
global args;  %% DO NOT FORGET
% init code
% ...
 
eeg = args.eeg_file;
meg = args.meg_file;
 
% compute something...
end