Example 3: Reading from the database, performing additional analysis, and adding results back to the database
This is one example of how to write an analysis program that uses the database.
The task: Perform a reverse-correlation type analysis of responses to the line test stimulus.
The line test stimulus consists of brief presentations of white and black bars on the monitor. The bars all have an orientation that matches the measured preferred orientation of the cell, and the position of the bar is varied along the axis that is orthogonal to the preferred orientation.
Let's work on the example cell number 34:
mycell = celldata{34}; mycellname = cellnames{34};
1) The first step is to see which directory contains the raw data for the line test.
B = findassociate(mycell,'Line test','','')
Here we know this cell has a 'Line test'; if we were writing a function, we'd want to check to make sure that it had a line test before proceeding.
2) Next, let's load the stimulus data.
We know where the directory is now, it is in the B.data subdirectory of the pathname of the dirstruct ds (ds was created in Example 1):
g = load([getpathname(ds) filesep B.data filesep 'stims.mat'])
and this should return something like
g =
MTI2: {1x1770 cell}
start: 2.0040e+04
saveScript: [1x1 stimscript]
The field MTI2 contains the timing information for each stimulus. Let's look at the first field:
g.MTI2{1} =
preBGframes: 0
postBGframes: 0
pauseRefresh: [0 0 0 0 0 0 0 0 0 0]
frameTimes: [1x10 double]
startStopTimes: [2.0040e+04 2.0040e+04 2.0041e+04 2.0041e+04]
ds: []
df: []
stimid: 46
GammaCorrectionTable: [256x3 double]
This shows that the stimulus was presented for 10 frames, and the times of each frame's presentation is given in the field frameTimes. The onset of the stimulus (the time when the "pre stimulus" background was presented) is listed in startStopTimes(1), and the onset of when the stimulus itself was being presented is listed in startStopTimes(2). The time that the stimulus is removed from the screen is listed in startStopTimes(3), and the time that any "post background" background display was removed is given in startStopTimes(4). Times here is given in seconds since the stimulus computer booted up.
3) Next, let's load all the spikes that were fired during this stimulus.
We know the time that the stimulus started, this is g.start, and we know the time that the last stimulus turned off, this is g.MTI2{end}.startStopTimes(4). So we can read all of the spikes in this interval:
spikes = get_data(mycell,[g.start g.MTI2{end}.startStopTimes(4)]);
Just for fun, we can take a look at these spike times by plotting them:
figure
plot(spikes)
ylabel('Spike times')
xlabel('Spike number since start of Line stimulus');
We can compare this to all of the spikes that we recorded for this cell.
Try:
spikes_all = get_data(mycell,[-Inf Inf]);
You should get an error that says "data not sampled over entire requested interval". This makes sense, we didn't sample from -Inf to Inf (and of course we couldn't!). We can ask measureddata not to check the intervals at all and just give us all the spikes by passing a '2' for the third argument:
spikes_all = get_data(mycell,[-Inf Inf],2);
figure;
plot(spikes)
ylabel('Spike times');
xlabel('Spike number since start of recording');
You can see the recorded spikes, and several "steps" in Y. These "steps" correspond to the intervals between stimuli when we were not recording.
4) Now we have all the information we need to calculate the reverse correlation
Hint: Since only 1 stimulus is on the screen at a given time, you can analyze each stimulus id separately, creating a 1D response for each stimulus. Loop through the stim IDs; each stimulus presentation is a contrast step (to either 1 or -1; we'll call gray 0). Pick a time window around the stimulus to analyze, maybe [0 0.3] seconds, and create a time vector, 0:0.001:0.3, and a response vector zeros(1,length(timevector)). For each spike that occurs within 0.3 s of a stimulus event, add an image of the stimulus to the response vector with the appropriate delay. At the end, divide by the number of spikes that were within 0.3 seconds of the stimulus to get an average behavior of the cell to that stimulus.