# Basic API Usage in MATLAB

When you start Zapit with `start_zapit` the MATLAB workspace will contain a variable called `hZP`. This serves as an API (Application Programming Interface) that allows controlling of almost all functions via the command line. For example, you can query which stimuli are loaded and whether Zapit is ready to deliver stimuli:

```matlab
% Reports "true" and is ready to present stimuli
>> hZP.isReadyToStim

ans =
  logical
   1

% The stimulus config is located here 
>> hZP.stimConfig

ans = 
  stimConfig with properties:

            configFileName: 'C:\stim_configs\uniAndBilateral_5_conditions.yml'
            laserPowerInMW: 5
      stimModulationFreqHz: 40
             stimLocations: [1×5 struct]
    offRampDownDuration_ms: 250
               chanSamples: [2500×4×5 double]
      maxStimPulseDuration: 12.2000
           blankingTime_ms: 0.3000

% The stimulus config can be queried to return the number of conditions
>> hZP.stimConfig.numConditions

ans =
     5
```

#### Presenting a stimulus

The two main commands you will need for running experiments are `sendSamples` and `stopOptoStim`. `sendSamples` is so called because it transfers stimulus waveforms to the DAQ. The following code  will send samples to the DAQ to stimulate one condition (e.g. one brain area bilaterally). It will start immediately because `hardwareTriggered` is set to `false`

```matlab
hZP.sendSamples('conditionNum', 1, 'hardwareTriggered', false);
```

Stimulation begins and continues until `stopOptoStim` is run.

```matlab
hZP.stopOptoStim
```

The `stopOptoStim` command will ramp down the laser power over a period defined in the stimulus config file. You can get help via the MATLAB command line e.g. `help hZP.sendSamples`

#### Presenting a randomly chosen stimulus

If you call `sendSamples` with the `conditionNum` undefined then a random stimulus is presented. The same stimulus will not be selected on two consecutive trials. The identity of the stimulus is returned as the first output argument of `sendSamples`

```matlab
>> stim=hZP.sendSamples('hardwareTriggered', false)

stim =
     5

>> stim=hZP.sendSamples('hardwareTriggered', false)

stim =
     3
```

A simply toy scenario sees us present a small number of stimuli at random with each having a random duration:

```matlab
numAreasToStim = length(hZP.stimConfig.stimLocations);

for ii=1:numAreasToStim
    % No stimulus condition defined so a random one chosen
    hZP.sendSamples('hardwareTriggered', false, 'verbose', true)
    pause(rand*2)
    hZP.stopOptoStim
    pause(0.3) % Because of https://github.com/Zapit-Optostim/zapit/issues/102
end
```

#### Presenting a control trial with the laser off

You can use the `laserOn` parameter to present a trial where the scanners move but the laser off:

```matlab
hZP.sendSamples('laserOn',0)
```

If the value of `laserOn` is empty then a random laser on/off state is chose. The second output argument of `sendSamples` reports this state:

```
>> [S,L]=hZP.sendSamples('laserOn',0,'hardwareTriggered', false); disp([S,L])
     3     0

>> [S,L]=hZP.sendSamples('laserOn',0,'hardwareTriggered', false); disp([S,L])
     4     0

>> [S,L]=hZP.sendSamples('laserOn',0,'hardwareTriggered', false); disp([S,L])
     2     1
```

#### Logging stimuli

In a real experiment you will want to know which stimuli were presented when. To achieve this, set an "experiment path" in Zapit, the identity of presented stimuli will be logged to a file, along with all additional relevant information such as the laser on/off state. You can either set the experiment path in the GUI or at the command line  by assigning a path to the `hZP.experimentPath` variable. If the variable is empty no logging takes place. If you run `sendSamples`with `logging` set to `false` then also no logging takes place.&#x20;

#### Precise control of stimulus timing

In the above examples stimuli started immediately because `hardwareTriggered` was always set to `false` and were terminated by `stopOptoStim`. The timing of events is therefore coarse. To present stimuli more accurately you can trigger them using a TTL line. By default you will connect port PFI0 on the Zapit NI DAQ to your trigger source. Stimulus presentation then begins when a TTL pulse is received.  The following example uses code in the `zapit\examples\externalTrigger` folder and assumes you have a second DAQ called `Dev2` with its port0/line0 connected to the Zapit PFI0 terminal

```matlab
>> auxDAQ = connectAuxDaq('Dev2'); % replace by your DAQ ID name
>> makeTTLpulse(D) % sends a TTL pulse
>> hZP.sendSamples('conditionNum', 1);

%% Nothing happens until a TTL pulse is sent

>> makeTTLpulse(D) % send a TTL pulse to start the stimulation

%% Wait a while then stop the stimulation at the command line

>> hZP.stopOptoStim
```

In the above example we tie stimulus onset to a TTL trigger. Following on from this, we can also define a fixed stimulus duration thus:

<pre class="language-matlab"><code class="lang-matlab"><strong>>> hZP.sendSamples('conditionNum', 1, 'stimDurationSeconds', 2.25);
</strong>
%% Nothing happens until a TTL pulse is sent

>> makeTTLpulse(D) % send a TTL pulse to start the stimulatio

%% A 2.25 second stimulus is presented followed by a rampdown
</code></pre>

You can also define a delay between the onset of the stimulus and the trigger:

```matlab
% Note in the following line we use abbreviated versions of the parameter 
% names and this still works.
>> hZP.sendSamples('cond', 1, 'stimDur', 2.25, 'startDelay', 0.5);

%% Nothing happens until a TTL pulse is sent

>> makeTTLpulse(D) % send a TTL pulse to start the stimulatio

%% 0.5 second delay then condition 1 is presented for  2.25 seconds then a rampdown
```

{% hint style="info" %}
If stimulus duration is known in advance, it is preferable to use the `stimDurationSeconds` input argument to the `sendSamples`method rather than a `pause` statement. The former is more accurate and has fewer failure points.&#x20;
{% endhint %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://zapit.gitbook.io/user-guide/running-experiments/matlab/basic-api-usage-in-matlab.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
