Basic API Usage in MATLAB
Intro running experiments in a local MATLAB session
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:
% 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
hZP.sendSamples('conditionNum', 1, 'hardwareTriggered', false);
Stimulation begins and continues until stopOptoStim
is run.
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
>> 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:
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:
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.
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
>> 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:
>> hZP.sendSamples('conditionNum', 1, 'stimDurationSeconds', 2.25);
%% 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
You can also define a delay between the onset of the stimulus and the trigger:
% 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
Last updated