Skip to content
124 changes: 124 additions & 0 deletions Figure Handlers/PowerSpectrumFigureHandler.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
% Copyright (c) 2012 Howard Hughes Medical Institute.
% All rights reserved.
% Use is subject to Janelia Farm Research Campus Software Copyright 1.1 license terms.
% http://license.janelia.org/license/jfrc_copyright_1_1.html

classdef PowerSpectrumFigureHandler < FigureHandler

properties (Constant)
figureType = 'Power Spectrum'
end

properties
meanPlots % array of structures to store the properties of each class of epoch.
meanParamNames
end

methods

function obj = PowerSpectrumFigureHandler(protocolPlugin, varargin)
obj = obj@FigureHandler(protocolPlugin);

xlabel(obj.axesHandle(), 'sec');
set(obj.axesHandle(), 'XTickMode', 'auto');

obj.resetPlots();

ip = inputParser;
ip.addParamValue('GroupByParams', {}, @(x)iscell(x) || ischar(x));
ip.parse(varargin{:});

if iscell(ip.Results.GroupByParams)
obj.meanParamNames = ip.Results.GroupByParams;
else
obj.meanParamNames = {ip.Results.GroupByParams};
end
end


function handleCurrentEpoch(obj)
[responseData, sampleRate, units] = obj.protocolPlugin.response();
responseData = fft(responseData);
responseData = responseData.*conj(responseData);

% Get the parameters for this "class" of epoch.
% An epoch class is defined by a set of parameter values.
if isempty(obj.meanParamNames)
% Automatically detect the set of parameters.
epochParams = obj.protocolPlugin.epochSpecificParameters();
else
% The protocol has specified which parameters to use.
for i = 1:length(obj.meanParamNames)
epochParams.(obj.meanParamNames{i}) = obj.protocolPlugin.epoch.ProtocolParameters.Item(obj.meanParamNames{i});
end
end

% Check if we have existing data for this class of epoch.
meanPlot = struct([]);
for i = 1:numel(obj.meanPlots)
if isequal(obj.meanPlots(i).params, epochParams)
meanPlot = obj.meanPlots(i);
break;
end
end

if isempty(meanPlot)
% This is the first epoch of this class to be plotted.
meanPlot = {};
meanPlot.params = epochParams;
meanPlot.data = responseData;
meanPlot.sampleRate = sampleRate;
meanPlot.units = [units,'^2'];
meanPlot.count = 1;
hold(obj.axesHandle(), 'on');
meanPlot.plotHandle = loglog(obj.axesHandle(), (1:length(meanPlot.data)/2) * sampleRate, meanPlot.data(1:length(meanPlot.data)/2));
obj.meanPlots(end + 1) = meanPlot;
else
% This class of epoch has been seen before, add the current response to the mean.
% TODO: Adjust response data to the same sample rate and unit as previous epochs if needed.
% TODO: if the length of data is varying then the mean will not be correct beyond the min length.
meanPlot.data = (meanPlot.data * meanPlot.count + responseData) / (meanPlot.count + 1);
meanPlot.count = meanPlot.count + 1;
set(meanPlot.plotHandle, 'XData', (1:length(meanPlot.data)/2) * sampleRate, ...
'YData', meanPlot.data);
obj.meanPlots(i) = meanPlot;
end

% Update the y axis with the units of the response.
ylabel(obj.axesHandle(), [units,'^2']);

if isempty(epochParams)
titleString = 'All epochs grouped together.';
else
paramNames = fieldnames(epochParams);
titleString = ['Grouped by ' humanReadableParameterName(paramNames{1})];
for i = 2:length(paramNames) - 1
titleString = [titleString ', ' humanReadableParameterName(paramNames{i})];
end
if length(paramNames) > 1
titleString = [titleString ' and ' humanReadableParameterName(paramNames{end})];
end
end
title(obj.axesHandle(), titleString);
end


function clearFigure(obj)
obj.resetPlots();

clearFigure@FigureHandler(obj);
end


function resetPlots(obj)
obj.meanPlots = struct('params', {}, ... % The params that define this class of epochs.
'data', {}, ... % The mean of all responses of this class.
'sampleRate', {}, ... % The sampling rate of the mean response.
'units', {}, ... % The units of the mean response.
'count', {}, ... % The number of responses used to calculate the mean reponse.
'plotHandle', {}); % The handle of the plot for the mean response of this class.
end

end

end
37 changes: 0 additions & 37 deletions Protocols/Grid/allcombs.m

This file was deleted.

37 changes: 0 additions & 37 deletions Protocols/HotspotsDS/allcombs.m

This file was deleted.

134 changes: 134 additions & 0 deletions Protocols/LEDFlash/LEDFlash.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
% Creates a single stimulus composed of mean + flash.
% Implements SymphonyProtocol
%
% Copyright (c) 2012 Howard Hughes Medical Institute.
% All rights reserved.
% Use is subject to Janelia Farm Research Campus Software Copyright 1.1 license terms.
% http://license.janelia.org/license/jfrc_copyright_1_1.html
%
% Modified by TA 9.8.12 from LED Family to create a single LED pulse protocol

classdef LEDFlash < SymphonyProtocol

properties (Constant)
identifier = 'helsinki.yliopisto.pal'
version = 1
displayName = 'LED Flash'
end

properties
stimPoints = uint16(100);
prePoints = uint16(1000);
tailPoints = uint16(4000);
stimAmplitude = 0.5;
lightMean = 0.0;
preSynapticHold = -60;
numberOfAverages = uint8(5);
interpulseInterval = 0.6;
continuousRun = false;
end

properties (Dependent = true, SetAccess = private) % these properties are inherited - i.e., not modifiable
% ampOfLastStep;
end

methods

function [stimulus, lightAmplitude] = stimulusForEpoch(obj, ~) % epoch Num is usually required
% Calculate the light amplitude for this epoch.
% phase = single(mod(epochNum - 1, obj.stepsInFamily)); % Frank's clever way to determine which flash in a family to deliver
lightAmplitude = obj.stimAmplitude; % * obj.ampStepScale ^ phase; % Frank's clever way to determine the amplitude of the flash family to deliver

% Create the stimulus
stimulus = ones(1, obj.prePoints + obj.stimPoints + obj.tailPoints) * obj.lightMean;
stimulus(obj.prePoints + 1:obj.prePoints + obj.stimPoints) = lightAmplitude;
end


function stimulus = sampleStimuli(obj) % Return a cell array
% you can only create one stimulus with this protocol TA
stimulus{1} = obj.stimulusForEpoch();
end


function prepareRig(obj)
% Call the base class method to set the DAQ sample rate.
prepareRig@SymphonyProtocol(obj);

%obj.setDeviceBackground('LED', obj.lightMean, 'V');

% if strcmp(obj.rigConfig.multiClampMode('Amplifier_Ch1'), 'IClamp')
% obj.setDeviceBackground('Amplifier_Ch1', double(obj.preSynapticHold) * 1e-12, 'A');
% else
% obj.setDeviceBackground('Amplifier_Ch1', double(obj.preSynapticHold) * 1e-3, 'V');
% end
end


function prepareRun(obj)
% Call the base class method which clears all figures.
prepareRun@SymphonyProtocol(obj);

obj.openFigure('Response');
obj.openFigure('Mean Response', 'GroupByParams', {'lightAmplitude'});
obj.openFigure('Response Statistics', 'StatsCallback', @responseStatistics);
end


function prepareEpoch(obj)
% Call the base class method which sets up default backgrounds and records responses.
prepareEpoch@SymphonyProtocol(obj);

[stimulus, lightAmplitude] = obj.stimulusForEpoch(obj.epochNum);
obj.addParameter('lightAmplitude', lightAmplitude);
%obj.addStimulus('LED', 'test-stimulus', stimulus, 'V'); %
obj.setDeviceBackground('LED', obj.lightMean, 'V');
if strcmp(obj.multiClampMode, 'VClamp')
obj.setDeviceBackground('Amplifier_Ch1', double(obj.preSynapticHold) * 1e-3, 'V');
else
obj.setDeviceBackground('Amplifier_Ch1', double(obj.preSynapticHold) * 1e-12, 'A');
end
obj.addStimulus('LED', 'LED stimulus', stimulus, 'V'); %
end


function stats = responseStatistics(obj)
r = obj.response();

% baseline mean and var
if ~isempty(r)
stats.mean = mean(r(1:obj.prePoints));
stats.var = var(r(1:obj.prePoints));
else
stats.mean = 0;
stats.var = 0;
end
end


function completeEpoch(obj)
% Call the base class method which updates the figures.
completeEpoch@SymphonyProtocol(obj);

% Pause for the inter-pulse interval.
pause on
pause(obj.interpulseInterval);
end


function keepGoing = continueRun(obj)
% First check the base class method to make sure the user hasn't paused or stopped the protocol.
keepGoing = continueRun@SymphonyProtocol(obj);

if keepGoing
keepGoing = obj.epochNum < obj.numberOfAverages;
end
end


% function amp = get.ampOfLastStep(obj) % The product of the number of steps in family, the first step amplitude, and the 'scale factor'
% amp = obj.baseLightAmplitude * obj.ampStepScale ^ (obj.stepsInFamily - 1);
% end

end
end
Loading