Skip to content

Commit c395b51

Browse files
committed
Added includeFlag for FilterRecordings to use that column from recording database, findMRCs fixes integration units and ensures nReps/distance will work even if other output params are added in between, multiple columns and usability for tau export to Igor for AntVPost_voltage attenuation script, IdAnalysis fixes roundVel using correct column, FreqAnalysis fixes column
1 parent 5751558 commit c395b51

9 files changed

Lines changed: 852 additions & 69 deletions

File tree

Analysis/SK/AnalyzePatchData.m

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,12 +60,13 @@
6060
cellDist = [40 200];
6161
resistCutoff = '<250';
6262
extFilterFreq = 2.5;
63+
includeFlag = 1;
6364

6465
anteriorDistCells = FilterRecordings(ephysData, ephysMetaData,...
6566
'strain', strainList, 'internal', internalList, ...
6667
'stimLocation', stimPosition, 'wormPrep', wormPrep, ...
6768
'cellStimDistUm',cellDist, 'RsM', resistCutoff, ...
68-
'stimFilterFrequencykHz', extFilterFreq);
69+
'stimFilterFrequencykHz', extFilterFreq, 'included', 1);
6970

7071
clear cellDist strainList internalList cellTypeList stimPosition resistCutoff ans wormPrep;
7172

Lines changed: 308 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,308 @@
1+
% Tau vs distance curves for anterior vs. posterior
2+
3+
% Running all the way through allows user to pull out tau data from steps,
4+
% export to Igor, fit a Boltzmann there, re-import and normalize and export
5+
% back to Igor for final plotting and fitting.
6+
7+
% Unlike AntVsPost_VoltageAttenuation, this does not correct the current or
8+
% charge for voltage errors based on distance, and was used for non-current
9+
% data.
10+
11+
%%Import data and metadata
12+
ephysData = ImportPatchData('incl',1);
13+
projects = {'FAT';'SYM'};
14+
ephysData = FilterProjectData(ephysData, projects);
15+
clear projects;
16+
17+
ephysMetaData = ImportMetaData(); %Recording Database.xlsx
18+
attenuationData = ImportMetaData(); %AttenuationCalcs.xlsx
19+
20+
%% Analyze capacity transient for C, Rs, and tau
21+
22+
ephysData = CtAnalysis(ephysData);
23+
24+
clear lastfit;
25+
26+
%% Select recordings that match parameters based on metadata
27+
28+
strainList = {'TU2769'};
29+
internalList = {'IC2'};
30+
stimPosition = {'posterior'};
31+
32+
wormPrep = {'dissected'};
33+
cellDist = [40 90]; % stimulus/cell distance in um
34+
resistCutoff = '<250'; % Rs < 250 MOhm
35+
extFilterFreq = 2.5; % frequency of low-pass filter for stimulus command
36+
includeFlag = 1;
37+
38+
posteriorDistCells = FilterRecordings(ephysData, ephysMetaData,...
39+
'strain', strainList, 'internal', internalList, ...
40+
'stimLocation', stimPosition, 'wormPrep', wormPrep, ...
41+
'cellStimDistUm',cellDist, 'RsM', resistCutoff, ...
42+
'stimFilterFrequencykHz', extFilterFreq, 'included', includeFlag);
43+
44+
stimPosition = {'anterior'};
45+
46+
anteriorDistCells = FilterRecordings(ephysData, ephysMetaData,...
47+
'strain', strainList, 'internal', internalList, ...
48+
'stimLocation', stimPosition, 'wormPrep', wormPrep, ...
49+
'cellStimDistUm',cellDist, 'RsM', resistCutoff, ...
50+
'stimFilterFrequencykHz', extFilterFreq, 'included',includeFlag);
51+
52+
53+
clear cellDist strainList internalList cellTypeList stimPosition resistCutoff ans wormPrep excludeCells;
54+
55+
% This results in a file with three columns: cell ID, series, and sweeps
56+
% that have been approved for analysis use.
57+
58+
%% Visual/manual exclusion of bad sweeps
59+
% This is mainly based on excluding sweeps with leak > 10pA, but also
60+
% sweeps where the recording was lost partway through or some unexpected
61+
% source of noise was clearly at play.
62+
63+
protList ={'WC_Probe';'WC_ProbeSmall';'WC_ProbeLarge';'NoPrePulse'};
64+
matchType = 'full';
65+
66+
ExcludeSweeps(ephysData, protList, anteriorDistCells, 'matchType', matchType);
67+
ExcludeSweeps(ephysData, protList, posteriorDistCells, 'matchType', matchType);
68+
69+
%% Find MRCs
70+
% antAllSteps.xlsx and postAllSteps.xlsx from 180810
71+
protList ={'WC_Probe';'NoPre'};
72+
matchType = 'first';
73+
74+
sortSweeps = {'magnitude','magnitude','magnitude','magnitude'};
75+
76+
anteriorMRCs = IdAnalysis(ephysData,protList,anteriorDistCells,'num','matchType',matchType, ...
77+
'tauType','thalfmax', 'sortSweepsBy', sortSweeps, 'integrateCurrent',1 , ...
78+
'recParameters', ephysMetaData,'sepByStimDistance',1);
79+
80+
posteriorMRCs = IdAnalysis(ephysData,protList,posteriorDistCells,'num','matchType',matchType, ...
81+
'tauType','thalfmax', 'sortSweepsBy', sortSweeps, 'integrateCurrent',1 , ...
82+
'recParameters', ephysMetaData,'sepByStimDistance',1);
83+
84+
clear protList sortSweeps matchType
85+
86+
%% Pull out and combine relevant data for plot
87+
88+
% Voltage attenuation data comes from the length constant fitting done in
89+
% Igor, which gives a voltage attenuation factor at the location of the
90+
% stimulus site for each recording, based on the calculated length
91+
% constant.
92+
93+
% Grab the current at the selected step size (e.g., 10um) for each
94+
% recording, grab the cell-stimulus distance for that recording, and match
95+
% the recording name against the voltage attenuation table to find the
96+
% attenuation factor for that recording.
97+
whichMRCs = anteriorMRCs;
98+
thisAtt = attenuationData(:,[2 8 10]);
99+
distCol = 12;
100+
peakCol = 8; % 8 for tau act, 9 for tau decay
101+
distVPeak = [];
102+
stepSize = 10;
103+
104+
for iCell = 1:size(whichMRCs,1)
105+
thisCell = whichMRCs{iCell,3};
106+
whichStep = round(thisCell(:,1)) == stepSize;
107+
if any(whichStep)
108+
thisName = whichMRCs{iCell,1};
109+
hasAtt = strcmp(thisName,thisAtt(:,1));
110+
111+
if any(hasAtt) && thisAtt{hasAtt,2}
112+
distVPeak(iCell,:) = [thisCell(whichStep,[distCol peakCol]) thisAtt{hasAtt,3}];
113+
else
114+
distVPeak(iCell,:) = [thisCell(whichStep,[distCol peakCol]) nan];
115+
end
116+
117+
end
118+
119+
end
120+
121+
distVPeak_Ant = distVPeak;
122+
123+
whichMRCs = posteriorMRCs;
124+
distVPeak = [];
125+
126+
127+
for iCell = 1:size(whichMRCs,1)
128+
thisCell = whichMRCs{iCell,3};
129+
whichStep = round(thisCell(:,1)) == stepSize;
130+
if any(whichStep)
131+
thisName = whichMRCs{iCell,1};
132+
hasAtt = strcmp(thisName,thisAtt(:,1));
133+
134+
if any(hasAtt)
135+
distVPeak(iCell,:) = [thisCell(whichStep,[distCol peakCol]) thisAtt{hasAtt,2}];
136+
else
137+
distVPeak(iCell,:) = [thisCell(whichStep,[distCol peakCol]) nan];
138+
end
139+
140+
end
141+
142+
end
143+
144+
distVPeak_Post = distVPeak;
145+
146+
clear a iCell thisCell whichMRCs whichStep thisName hasAtt distVPeak
147+
148+
%% Export for Igor fitting of Boltzmann to each recording
149+
150+
% This is the same as in AntVPost_VoltageAttenuation_180803 except it
151+
% doesn't apply any attenuation correction. Useful for pulling out the taus
152+
153+
eachSize = [0.5 1 1.5 3 4 5 6 7 8 9 10 11 12]';
154+
distLimits = [40 90];
155+
% limit to same average distance for anterior and posterior
156+
157+
whichMRCs = anteriorMRCs;
158+
thisAtt = attenuationData(:,[2 8 10]);
159+
thisName = cell(0);
160+
ant_Out = cell(length(eachSize)+1,size(whichMRCs,1));
161+
162+
for iCell = 1:size(whichMRCs,1)
163+
thisCell = whichMRCs{iCell,3};
164+
thisDist = mean(thisCell(:,distCol)); % check if cell distance is in range
165+
if thisDist <= distLimits(2) && thisDist >= distLimits(1)
166+
thisName{iCell,1} = whichMRCs{iCell,1}; %name
167+
thisName{iCell,2} = thisDist;
168+
ant_Out{1,iCell} = thisName{iCell,1};
169+
Iact = [];
170+
171+
for iSize = 1:length(eachSize)
172+
stepSize = eachSize(iSize);
173+
whichStep = round(thisCell(:,1)*2)/2 == stepSize; %round to nearest 0.5
174+
if any(whichStep)
175+
176+
Iact(iSize,1) = thisCell(whichStep,peakCol);
177+
else
178+
Iact(iSize,1) = nan;
179+
end
180+
end
181+
ant_Out(2:length(eachSize)+1,iCell) = num2cell(Iact);
182+
end
183+
end
184+
ant_Name = [{'Anterior', 'Ant_Dist'}; thisName];
185+
ant_Out = ant_Out(:,~cellfun(@isempty, ant_Out(1,:))); % clear out empty waves (where dist didn't match)
186+
ant_Name = ant_Name(~cellfun(@isempty, ant_Name(:,1)),:);
187+
188+
ant_Out = [[{'stepSize'};num2cell(eachSize)] ant_Out]; % append stepSize wave
189+
190+
thisName = cell(0);
191+
whichMRCs = posteriorMRCs;
192+
post_Out = cell(length(eachSize)+1,size(whichMRCs,1));
193+
194+
for iCell = 1:size(whichMRCs,1)
195+
thisCell = whichMRCs{iCell,3};
196+
thisDist = mean(thisCell(:,distCol)); % check if cell distance is in range
197+
if thisDist <= distLimits(2) && thisDist >= distLimits(1)
198+
thisName{iCell,1} = whichMRCs{iCell,1}; %name
199+
thisName{iCell,2} = thisDist; %distance
200+
post_Out{1,iCell} = thisName{iCell,1};
201+
Iact = [];
202+
203+
for iSize = 1:length(eachSize)
204+
stepSize = eachSize(iSize);
205+
whichStep = round(thisCell(:,1)*2)/2 == stepSize; %round to nearest 0.5
206+
if any(whichStep)
207+
Iact(iSize,1) = thisCell(whichStep,peakCol);
208+
else
209+
Iact(iSize,1) = nan;
210+
end
211+
end
212+
post_Out(2:length(eachSize)+1,iCell) = num2cell(Iact);
213+
end
214+
end
215+
216+
post_Name = [{'Posterior', 'Post_Dist'}; thisName];
217+
post_Out = post_Out(:,~cellfun(@isempty, post_Out(1,:)));
218+
post_Name = post_Name(~cellfun(@isempty, post_Name(:,1)),:);
219+
220+
% Set the filename
221+
fname = 'PatchData/taus_antVpost_distLim(180911).xls';
222+
223+
xlswrite(fname,ant_Out,'antAct');
224+
xlswrite(fname,post_Out,'postAct');
225+
xlswrite(fname,ant_Name,'antActStats');
226+
xlswrite(fname,post_Name,'postActStats');
227+
228+
229+
clear iCell thisCell Iact whichMRCs whichStep hasAtt thisAtt Vc Ena thisName
230+
231+
232+
%% Renormalize
233+
234+
% The point of the remaining code is to grab the data from Igor or from an Excel
235+
% sheet after fitting individual I-d curves to get max/delta/xhalf from the
236+
% Boltzmann fit, then normalize each I-d curve to its predicted max, and
237+
% export back into an Igor-readable format for plotting.
238+
239+
% From AttCorrectedID_Curve.m
240+
241+
% From Igor, export the entire Igor file as a csv
242+
%% Import fits from Igor table
243+
244+
fitStats = ImportMetaData(); %AttCorrectedI-D_fitstats.xlsx
245+
fitHeaders = fitStats(1,:);
246+
fitStats = fitStats(2:end,:);
247+
248+
%% Get names and match up stats
249+
antStats = fitStats(:,cell2mat(cellfun(@(x) ~isempty(regexp(x,'Ant')), fitHeaders,'un',0)));
250+
postStats = fitStats(:,cell2mat(cellfun(@(x) ~isempty(regexp(x,'Post')), fitHeaders,'un',0)));
251+
antMaxIdx = find(~cellfun(@isempty,(regexp(fitHeaders(:,cell2mat(cellfun(@(x) ~isempty(regexp(x,'Ant')), fitHeaders,'un',0))),'[mM]ax'))));
252+
postMaxIdx = find(~cellfun(@isempty,(regexp(fitHeaders(:,cell2mat(cellfun(@(x) ~isempty(regexp(x,'Post')), fitHeaders,'un',0))),'[mM]ax'))));
253+
antStats = antStats(cellfun(@(x) ~isnumeric(x), antStats(:,1)),:);
254+
postStats = postStats(cellfun(@(x) ~isnumeric(x), postStats(:,1)),:);
255+
256+
% this gives five columns: name, delta, distance, max, xhalf
257+
258+
% straight up taking the fits and recoloring them here won't work because
259+
% Igor fits are all 200 points long but the X wave
260+
% is calculated, and is different length for each (i.e., some curves have
261+
% X values from 0.5 to 11, some from 3 to 10, etc., and those ranges
262+
% determine what the x values are for each fit separately).
263+
264+
% instead, I'm just going to do the normalization here and send the waves
265+
% back to Igor, where I can average them like the other I-dCellFits
266+
267+
%%
268+
eachSize = fitStats(:,cell2mat(cellfun(@(x) ~isempty(regexp(x,'stepSize')), fitHeaders,'un',0)));
269+
eachSize = eachSize(cellfun(@(x) isnumeric(x) && ~isnan(x),eachSize));
270+
271+
whichSide = antStats;
272+
thisCell = whichSide(:,1);
273+
thisDataNorm = cell(0);
274+
275+
for i = 1:size(whichSide,1)
276+
thisMax = whichSide{i,antMaxIdx};
277+
whichData = cell2mat(cellfun(@(x) ~isempty(regexp(x,sprintf('^(?!fit).*%s',thisCell{i}))),fitHeaders,'un',0));
278+
thisData = fitStats(1:length(eachSize),whichData);
279+
thisData(cellfun(@isempty,thisData))={nan};
280+
thisDataNorm(:,i) = cellfun(@(x) x./thisMax, thisData,'un',0);
281+
end
282+
283+
antNorm = thisDataNorm;
284+
antHeaders = cellfun(@(x) sprintf('%s_Norm',x),thisCell,'un',0)';
285+
286+
287+
% POSTERIOR
288+
whichSide = postStats;
289+
thisCell = whichSide(:,1);
290+
thisDataNorm = cell(0);
291+
292+
for i = 1:size(whichSide,1)
293+
thisMax = whichSide{i,postMaxIdx};
294+
whichData = cell2mat(cellfun(@(x) ~isempty(regexp(x,sprintf('^(?!fit).*%s',thisCell{i}))),fitHeaders,'un',0));
295+
thisData = fitStats(1:length(eachSize),whichData);
296+
thisData(cellfun(@isempty,thisData))={nan};
297+
thisDataNorm(:,i) = cellfun(@(x) x./thisMax, thisData,'un',0);
298+
end
299+
300+
postNorm = thisDataNorm;
301+
postHeaders = cellfun(@(x) sprintf('%s_Norm',x),thisCell,'un',0)';
302+
303+
%%
304+
305+
xlswrite(fname,antHeaders,'antNorm');
306+
xlswrite(fname,postHeaders,'postNorm');
307+
xlswrite(fname,antNorm,'antNorm','A2');
308+
xlswrite(fname,postNorm,'postNorm','A2');

0 commit comments

Comments
 (0)