# Custom Stimulus Functions¶

It is possible to write your own parametric stimulus function. To do so, write a MATLAB m-file function and store it in [ScanImage® Installation Directory]\+scanimage\+mroi\+stimulusfunctions\. The function should be in the form:

```[xx,yy] = stimFunction(tt,[additional optional arguments])
```

The input and output arguments are as follows:

 tt A vector of linearly increasing times. It is commonly normalized before use in parameterized equations. xx A column vector of the same size as tt consisting of the X-component of the position for each time in tt. yy A column vector of the same size as tt consisting of the Y-component of the position for each time in tt.

The size of tt depends on the number of ROIs in the ROI Group Editor. By default, the number of points to define all the ROIs in an ROI Group is 10,000. This number is divided equally between each of the ROI. Thus, an ROI Group consisting of

• Pause function

• Logspiral function

• Pause function

• Sinesquare function

will have 2,500 points of definition per ROI.

The x and y position should range from -1 to 1. The size, location and rotation of the stimulus function is defined by the size, location, and rotation of the drawn ROI in the ROI Group Editor.

Note

the x and y components of an ROI’s location and size as well as its rotation can all be precisely defined by entering them in via the fields in the bottom right of the ROI Group Editor.

Optional arguments can be used to further parameterize the function. For instance, the log spiral function has a ‘revolutions’ parameter which is used to define the number of turns in the spiral.

## Example¶

The \+scanimage\+mroi\+stimulusfunctions\logspiral.m function can be taken as an example of stim function for creating a new function.

``` 1function [xx,yy] = logspiral(tt,varargin)
2% logarithmic spiral stimulus
3
4% the following line will be parsed by the ROI editor to present a list of
5% options. should be in the format: parameter1 (comment), parameter2 (comment)
6%% parameter options: revolutions (Number of revolutions), direction (Can be 'inward' or 'outward')
7
8%% parse inputs
9inputs = scanimage.mroi.util.parseInputs(varargin);
10
11if ~isfield(inputs,'revolutions') || isempty(inputs.revolutions)
12    inputs.revolutions = 5;
13end
14
15if ~isfield(inputs,'direction') || isempty(inputs.direction)
16    inputs.direction = 'outward';
17end
18
19if ~isfield(inputs,'a') || isempty(inputs.a)
20    inputs.a = 0;
21end
22
23tt = tt ./ tt(end); %normalize tt
24switch inputs.direction
25    case 'outward'
26        % Nothing to do
27        % tt = tt;
28    case 'inward'
29        tt = fliplr(tt);
30    otherwise
31        error('Unknown direction: %s',inputs.direction);
32end
33
34%% generate output
35if inputs.a == 0;
36    xx = tt .* sin(inputs.revolutions .* 2*pi .* tt);
37    yy = tt .* cos(inputs.revolutions .* 2*pi .* tt);
38else
39    tt = tt-max(tt);
40    xx = exp(inputs.a .* tt) .* sin(inputs.revolutions .* 2*pi .* tt);
41    yy = exp(inputs.a .* tt) .* cos(inputs.revolutions .* 2*pi .* tt);
42end
```

Note how optional arguments are parsed by the ScanImage® class scanimage.mroi.util.parseInputs(varargin) on line 9. If expected arguments are not given, they are given default values (lines 11 - 21). The parameterized equations are defined within the if-else statement in lines 35 - 42.