Contents
Function - Curvefit to recovery
Y = y1(:);
minY = min(Y);
Y = Y - minY;
x = 0:(length(Y)-1);
x = x*si;
x = x(:);
myalpha = max(Y);
temp = 0.63*myalpha;
temp = abs(Y-temp);
[~, tempx] = min(temp);
mybeta = 1/(x(tempx));
s = fitoptions('Mehtod','NonlinearLeastSquares','Robust','LAR',...
'Lower',[myalpha-1,0],...
'Upper',[myalpha+1,inf],...
'Startpoint',[myalpha,mybeta]);
f = fittype( @(alpha,beta,x) alpha*(1 - exp(-beta *(x))),...
'coefficients',{'alpha','beta'},'options',s );
[Curvefit, goodness] = fit(x,Y,f);
if strncmpi(makeplot,'y',1)
figure(fig); plot(Curvefit,'r--'),hold on;
plot(x, Y,'b.','markersize',12);
legend('Fit Curve', 'Data','Location','SouthEast');
xlabel('Time(seconds)','FontSize',20);
ylabel(['Amplitude (', unitsY, ')'], 'FontSize',20);
Txticks = get(gca,'XTick');
Pxticks = round(length(get(gca,'XTick'))/4);
xticks = Txticks(Pxticks);
tempytick = abs(x-xticks);
[~, tempytick] = min(tempytick);
strn1 = '$y={\alpha}\left(1-\exp({-\beta}{x})\right)$';
strn2 = sprintf('$y={%0.4f}\\left(1-\\exp({-%0.g}{x})\\right)$',Curvefit.alpha, Curvefit.beta);
strn3 = sprintf('$R^2={%0.4f}$',abs(goodness.rsquare));
strn4 = sprintf('$\\tau=\\frac{1}{\\beta}={%0.4g}\\left( seconds \\right)$',(1/Curvefit.beta));
text('Interpreter','latex','string',...
{strn1;strn2;strn3;strn4},...
'Position',[xticks,Y(tempytick)],...
'VerticalAlignment','Cap','FontSize',16)
end
end
Function - Axon binary read
start=0.0;
stop='e';
sweeps='a';
channels='a';
chunk=0.05;
machineF='ieee-le';
verbose=1;
pvpmod(varargin);
d=[];
si=[];
if ischar(stop)
if ~strcmpi(stop,'e')
error('input parameter ''stop'' must be specified as ''e'' (=end of recording) or as a scalar');
end
end
tmp=repmat(-1,1,16);
headPar={
'fFileVersionNumber',4,'float',-1;
'nOperationMode',8,'int16',-1;
'lActualAcqLength',10,'int32',-1;
'nNumPointsIgnored',14,'int16',-1;
'lActualEpisodes',16,'int32',-1;
'lFileStartTime',24,'int32',-1;
'lDataSectionPtr',40,'int32',-1;
'lSynchArrayPtr',92,'int32',-1;
'lSynchArraySize',96,'int32',-1;
'nDataFormat',100,'int16',-1;
'nADCNumChannels', 120, 'int16', -1;
'fADCSampleInterval',122,'float', -1;
'fSynchTimeUnit',130,'float',-1;
'lNumSamplesPerEpisode',138,'int32',-1;
'lPreTriggerSamples',142,'int32',-1;
'lEpisodesPerRun',146,'int32',-1;
'fADCRange', 244, 'float', -1;
'lADCResolution', 252, 'int32', -1;
'nFileStartMillisecs', 366, 'int16', -1;
'nADCPtoLChannelMap', 378, 'int16', tmp;
'nADCSamplingSeq', 410, 'int16', tmp;
'sADCChannelName',442, 'uchar', repmat(tmp,1,10);
'fADCProgrammableGain', 730, 'float', tmp;
'fInstrumentScaleFactor', 922, 'float', tmp;
'fInstrumentOffset', 986, 'float', tmp;
'fSignalGain', 1050, 'float', tmp;
'fSignalOffset', 1114, 'float', tmp;
'nTelegraphEnable',4512,'int16',tmp;
'fTelegraphAdditGain',4576,'float',tmp
};
fields={'name','offs','numType','value'};
s=cell2struct(headPar,fields,2);
numOfParams=size(s,1);
clear tmp headPar;
if ~exist(fn,'file'), error(['could not find file ' fn]); end
[fid,messg]=fopen(fn,'r',machineF);
if fid == -1,error(messg);end;
fseek(fid,0,'eof');
fileSz=ftell(fid);
fseek(fid,0,'bof');
for g=1:numOfParams,
if fseek(fid, s(g).offs,'bof')~=0,
fclose(fid);
error(['something went wrong locating ' s(g).name]);
end;
sz=length(s(g).value);
eval(['[' s(g).name ',n]=fread(fid,sz,''' s(g).numType ''');']);
if n~=sz,
fclose(fid);
error(['something went wrong reading value(s) for ' s(g).name]);
end;
end;
if lActualAcqLength<nADCNumChannels,
fclose(fid);
error('less data points than sampled channels in file');
end
recChIdx=nADCSamplingSeq(1:nADCNumChannels);
recChInd=1:length(recChIdx);
recChNames=(reshape(char(sADCChannelName),10,16))';
recChNames=recChNames(recChIdx+1,:);
chInd=[];
eflag=0;
if ischar(channels)
if strcmp(channels,'a')
chInd=recChInd;
else
fclose(fid);
error('input parameter ''channels'' must either be a cell array holding channel names or the single character ''a'' (=all channels)');
end
else
for i=1:length(channels)
tmpChInd=strmatch(channels{i},recChNames,'exact');
if ~isempty(tmpChInd)
chInd=[chInd tmpChInd];
else
eflag=1;
end
end;
end
if eflag
fclose(fid);
disp('**** available channels:');
disp(recChNames);
disp(' ');
disp('**** requested channels:');
disp(strvcat(channels));
error('at least one of the requested channels does not exist in data file (see above)');
end
fFileVersionNumber=.001*round(fFileVersionNumber*1000);
if fFileVersionNumber>=1.65
addGain=nTelegraphEnable.*fTelegraphAdditGain;
addGain(addGain==0)=1;
else
addGain=ones(size(fTelegraphAdditGain));
end
blockSz=512;
switch nDataFormat
case 0
dataSz=2;
precision='int16';
case 1
dataSz=4;
precision='float32';
otherwise
fclose(fid);
error('invalid number format');
end;
headOffset=lDataSectionPtr*blockSz+nNumPointsIgnored*dataSz;
si=fADCSampleInterval*nADCNumChannels;
if ischar(sweeps) && sweeps=='a'
nSweeps=lActualEpisodes;
sweeps=1:lActualEpisodes;
else
nSweeps=length(sweeps);
end;
switch nOperationMode
case 1
if verbose,
disp('data were acquired in event-driven variable-length mode');
end
warndlg('function abfload has not yet been thorougly tested for data in event-driven variable-length mode - please double-check that the data loaded is correct','Just a second, please');
if (lSynchArrayPtr<=0 || lSynchArraySize<=0),
fclose(fid);
error('internal variables ''lSynchArraynnn'' are zero or negative');
end
switch fSynchTimeUnit
case 0
synchArrTimeBase=1;
otherwise
synchArrTimeBase=fSynchTimeUnit;
end;
lSynchArrayPtrByte=blockSz*lSynchArrayPtr;
if lSynchArrayPtrByte+2*4*lSynchArraySize<fileSz,
fclose(fid);
error('file seems not to contain complete Synch Array Section');
end
if fseek(fid,lSynchArrayPtrByte,'bof')~=0,
fclose(fid);
error('something went wrong positioning file pointer to Synch Array Section');
end
[synchArr,n]=fread(fid,lSynchArraySize*2,'int32');
if n~=lSynchArraySize*2,
fclose(fid);
error('something went wrong reading synch array section');
end
synchArr=permute(reshape(synchArr',2,lSynchArraySize),[2 1]);
segLengthInPts=synchArr(:,2)/synchArrTimeBase;
segStartInPts=cumsum([0 (segLengthInPts(1:end-1))']*dataSz)+headOffset;
if fseek(fid,headOffset,'bof')~=0,
fclose(fid);
error('something went wrong positioning file pointer (too few data points ?)');
end
for i=1:nSweeps,
if ~isequal(nSweeps,lActualEpisodes),
fseek(fid,segStartInPts(sweeps(i)),'bof');
end;
[tmpd,n]=fread(fid,segLengthInPts(sweeps(i)),precision);
if n~=segLengthInPts(sweeps(i)),
warning(['something went wrong reading episode ' int2str(sweeps(i)) ': ' segLengthInPts(sweeps(i)) ' points should have been read, ' int2str(n) ' points actually read']);
end;
dataPtsPerChan=n/nADCNumChannels;
if rem(n,nADCNumChannels)>0,
fclose(fid);
error('number of data points in episode not OK');
end
tmpd=reshape(tmpd,nADCNumChannels,dataPtsPerChan);
tmpd=tmpd(chInd,:);
tmpd=tmpd';
if ~nDataFormat
for j=1:length(chInd),
ch=recChIdx(chInd(j))+1;
tmpd(:,j)=tmpd(:,j)/(fInstrumentScaleFactor(ch)*fSignalGain(ch)*fADCProgrammableGain(ch)*addGain(ch))...
*fADCRange/lADCResolution+fInstrumentOffset(ch)-fSignalOffset(ch);
end;
end
d{i}=tmpd;
end;
case {2,5}
if nOperationMode==2
if verbose
disp('data were acquired in event-driven fixed-length mode');
end
end
startPt=0;
dataPts=lActualAcqLength;
dataPtsPerChan=dataPts/nADCNumChannels;
if rem(dataPts,nADCNumChannels)>0,
fclose(fid);
error('number of data points not OK');
end
dataPtsPerChanPerSweep=dataPtsPerChan/lActualEpisodes;
if rem(dataPtsPerChan,lActualEpisodes)>0
fclose(fid);
error('number of data points not OK');
end
dataPtsPerSweep=dataPtsPerChanPerSweep*nADCNumChannels;
if fseek(fid,startPt*dataSz+headOffset,'bof')~=0
fclose(fid);
error('something went wrong positioning file pointer (too few data points ?)');
end
d=zeros(dataPtsPerChanPerSweep,length(chInd),nSweeps);
selectedSegStartInPts=((sweeps-1)*dataPtsPerSweep)*dataSz+headOffset;
for i=1:nSweeps,
fseek(fid,selectedSegStartInPts(i),'bof');
[tmpd,n]=fread(fid,dataPtsPerSweep,precision);
if n~=dataPtsPerSweep,
fclose(fid);
error(['something went wrong reading episode ' int2str(sweeps(i)) ': ' dataPtsPerSweep ' points should have been read, ' int2str(n) ' points actually read']);
end;
dataPtsPerChan=n/nADCNumChannels;
if rem(n,nADCNumChannels)>0
fclose(fid);
error('number of data points in episode not OK');
end;
tmpd=reshape(tmpd,nADCNumChannels,dataPtsPerChan);
tmpd=tmpd(chInd,:);
tmpd=tmpd';
if ~nDataFormat
for j=1:length(chInd),
ch=recChIdx(chInd(j))+1;
tmpd(:,j)=tmpd(:,j)/(fInstrumentScaleFactor(ch)*fSignalGain(ch)*fADCProgrammableGain(ch)*addGain(ch))...
*fADCRange/lADCResolution+fInstrumentOffset(ch)-fSignalOffset(ch);
end;
end
d(:,:,i)=tmpd;
end;
case 3
if verbose, disp('data were acquired in gap-free mode'); end
startPt=floor(1e6*start*(1/fADCSampleInterval));
startPt=floor(startPt/nADCNumChannels)*nADCNumChannels;
if ischar(stop),
dataPtsPerChan=lActualAcqLength/nADCNumChannels-floor(1e6*start/si);
dataPts=dataPtsPerChan*nADCNumChannels;
else
dataPtsPerChan=floor(1e6*(stop-start)*(1/si));
dataPts=dataPtsPerChan*nADCNumChannels;
if dataPts<=0
fclose(fid);
error('start is larger than or equal to stop');
end
end
if rem(dataPts,nADCNumChannels)>0
fclose(fid);
error('number of data points not OK');
end
if fseek(fid,startPt*dataSz+headOffset,'bof')~=0,
fclose(fid);
error('something went wrong positioning file pointer (too few data points ?)');
end
if length(chInd)==1 && nADCNumChannels>1
if fseek(fid,(chInd-1)*dataSz,'cof')~=0
fclose(fid);
error('something went wrong positioning file pointer (too few data points ?)');
end
dataPtsPerChan=dataPts/nADCNumChannels;
[d,n]=fread(fid,dataPtsPerChan,precision,dataSz*(nADCNumChannels-1));
if n~=dataPtsPerChan,
fclose(fid);
error(['something went wrong reading file (' int2str(dataPtsPerChan) ' points should have been read, ' int2str(n) ' points actually read']);
end
elseif length(chInd)/nADCNumChannels<1
d=repmat(nan,dataPtsPerChan,length(chInd));
chunkPtsPerChan=floor(chunk*2^20/8/nADCNumChannels);
chunkPts=chunkPtsPerChan*nADCNumChannels;
nChunk=floor(dataPts/chunkPts);
restPts=dataPts-nChunk*chunkPts;
restPtsPerChan=restPts/nADCNumChannels;
dix=(1:chunkPtsPerChan:dataPtsPerChan)';
dix(:,2)=dix(:,1)+chunkPtsPerChan-1;
dix(end,2)=dataPtsPerChan;
if verbose && nChunk
disp(['reading file in ' int2str(nChunk) ' chunks of ~' num2str(chunk) ' Mb']);
end
for ci=1:size(dix,1)-1
[tmpd,n]=fread(fid,chunkPts,precision);
if n~=chunkPts
fclose(fid);
error(['something went wrong reading chunk #' int2str(ci) ' (' ...
int2str(chunkPts) ' points should have been read, ' int2str(n) ' points actually read']);
end
tmpd=reshape(tmpd,nADCNumChannels,chunkPtsPerChan);
d(dix(ci,1):dix(ci,2),:)=tmpd(chInd,:)';
end
[tmpd,n]=fread(fid,restPts,precision);
if n~=restPts
fclose(fid);
error(['something went wrong reading last chunk (' ...
int2str(restPts) ' points should have been read, ' int2str(n) ' points actually read']);
end
tmpd=reshape(tmpd,nADCNumChannels,restPtsPerChan);
d(dix(end,1):dix(end,2),:)=tmpd(chInd,:)';
else
[d,n]=fread(fid,dataPts,precision);
if n~=dataPts,
fclose(fid);
error(['something went wrong reading file (' int2str(dataPts) ' points should have been read, ' int2str(n) ' points actually read']);
end;
d=reshape(d,nADCNumChannels,dataPtsPerChan);
d=d';
end
if ~nDataFormat
for j=1:length(chInd),
ch=recChIdx(chInd(j))+1;
d(:,j)=d(:,j)/(fInstrumentScaleFactor(ch)*fSignalGain(ch)*fADCProgrammableGain(ch)*addGain(ch))...
*fADCRange/lADCResolution+fInstrumentOffset(ch)-fSignalOffset(ch);
end;
end
otherwise
disp('recording mode of data must be event-driven variable-length (1), event-driven fixed-length (2) or gap-free (3) -- returning empty matrix');
d=[];
si=[];
end;
fclose(fid);
Automatic Population Spike detection
[y1, p1] = max(waveform);
waveform1 = waveform(p1:length(waveform));
[y2, m2] = min(waveform1);
M2 = [waveform(m2 + p1-1), m2 + p1-1];
wavem1m2 = waveform1(1:m2);
for k = 1:length(wavem1m2) - 1
dwavem1m2(k) = wavem1m2(k+1) - wavem1m2(k);
end
n = 1;
redge = [];
fedge = [];
dghost = dwavem1m2;
trim = floor(0.2*length(dwavem1m2));
dwavem1m2 = dwavem1m2(trim:length(dwavem1m2)-trim);
for k = 1:length(dwavem1m2) - 1
if dwavem1m2(k) < 0 && dwavem1m2(k+1) >= 0
redge(n) = k;
n = n+1;
elseif dwavem1m2(k) >= 0 && dwavem1m2(k+1) < 0
fedge(n) = k;
n = n+1;
end
end
if isempty(fedge)
tempM1pos = ceil(m2/2);
if waveform1(tempM1pos+1) - waveform1(tempM1pos) <= 0.0005
M1 = [waveform(tempM1pos + p1-1), tempM1pos + p1-1];
else
dghost(1:tempM1pos-ceil(0.25*m2)) = nan;
dghost(tempM1pos+ceil(0.25*m2):length(dghost)) = nan;
[yi, xi] = max(dghost);
M1 = [waveform(xi + p1-1), xi + p1-1];
end
else
fedge = trim + fedge;
redge = trim + redge;
if length(fedge) > 1
[ymax, xmax] = max(fedge);
fedge = fedge(xmax);
end
leftedge = fedge;
boarder = 0;
while boarder ~= 1
if wavem1m2(leftedge) == wavem1m2(leftedge-1)
leftedge = leftedge - 1;
else
boarder = 1;
end
end
rightedge = fedge;
boarder = 0;
while boarder ~= 1
if wavem1m2(rightedge) == wavem1m2(rightedge+1)
rightedge = rightedge + 1;
else
boarder = 1;
end
end
left = floor((leftedge - fedge)/2);
right = floor((rightedge - fedge)/2);
fedge = fedge + right + left;
M1 = [waveform(fedge + p1-1), fedge + p1-1];
end
[y3, m3] = max(waveform1(m2:length(waveform1)));
M3 = [waveform(m3 + p1-1 + m2-1), m3 + p1-1 + m2-1];
Modified questdlg