⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 nextspikes.m

📁 神经元信号处理软件
💻 M
字号:
function c=nextspikes(d,outputType,varargin)% nextspikes - reads in spike data (datastream method)% c=nextspikes(datastrn,outputType,varargin) reads in spike data according 
% to outputType spike: spikes (i.e. 64-cell array with spikes on each channel)
% timevalue: times(ms)/values of raw data, eliminating overlapping spike data,
% raw data: spike data filled with zeros to desired raw data array
%
% Optional arguments: start and end time of desired data (up to now times 
% will automatically be aligned with enclosing 128ms-segment borders). If 
% no intervall is choosen, the next segment is given.

%configuration
rawdata=0;
%configuration end

if (strcmp(outputType,'raw data'))
	rawdata=1;
	outputType='timevalue';
end


if (~strcmp(d.DataType,'spike continous'))
%a=setfield(a,'DataType','spike continous');   
	error(['nextspikes up to now works only on spike continous not on ' d.DataType]);
end
if (~strcmp(outputType,'spike') & ~strcmp(outputType,'timevalue'))
	error('second argument must begin with spike, timevalue or raw data');
end

if ~(strcmp(d.fileaccess,'ole')) & (d.sweepStartPointer==0),
	evalin('base','a=setpos(a,''segment'',1)','error(''set position first with a=setpos(a...'')');
	c=0;
	warning('call last function again now (setpos war automatically called)');
	return;
end

channelSel=ones(68,1);
if size(varargin,2)==0		%no intervall choosen, just take next segement
	startSegm=min(find(d.sweepStartPointer>=ftell(d.fid)));
	endSegm	=startSegm+1;	%not to be read!
elseif size(varargin,2)>=2
   startTime=varargin{1};
   endTime	=varargin{2};
   if ~(strcmp(d.fileaccess,'ole'))
      startSegm=max(max(find(d.sweepStartTime<=startTime))-1,1); %begin 1 segment earlier and end 1 later
      endSegm	=min([find(d.sweepStartTime>endTime);length(d.sweepStartTime)])+1; %not to be read!
   end
	if size(varargin,2)==3
		channelSel=zeros(68,1);
		channelSel(varargin{3})=1;
	end
	if size(varargin,2)>3
		error('nextspikes takes 2,4 or 5 parameters');
	end
else error('nextspikes takes 2,4 or 5 parameters');
end

if (strcmp(d.fileaccess,'ole'))
   spikestream=getstreamnumber(d,'Spikes 1');
   if (spikestream > 0) & rawdata
      msPerTick=getfield(d,'MicrosecondsPerTick')/1000;
      sinfo=getfield(d,'StreamInfo');
      pre=sinfo{spikestream}.PreTrigger;
      post=sinfo{spikestream}.PostTrigger; %not used
      ce=zeros(64,(endTime-startTime+post)/msPerTick)+2048;    
      cs=nextdata(d,'streamname','Spikes 1','originorder','off','startend',[startTime endTime],'warning','off');
      for ic=1:64
         spkt=cs.spiketimes{ic};
         spkv=cs.spikevalues{ic};
         for is=1:length(spkt)
            spkstart=max(round((spkt(is)-pre-startTime)/msPerTick),1);
            ce(ic,[spkstart:spkstart+size(spkv,1)-1])=spkv(:,is)';
         end
      end
		c.spiketimes=[];
		c.spikevalues=ce;
      c.startend=[startTime endTime];
      return;
   else   
      error(['nextspikes can only return outputType raw data for OLE-Object read spikes']);
   end
end

nSegments=endSegm-startSegm;
startPointer=d.sweepStartPointer(startSegm);

tmp=d.sorterleft(d.HardwareChannelID);
sortedChannelID=[tmp setdiff([1:68],tmp)]';	%not recorded channel are appended!

nChannels=68;
c=cell(nChannels,2);	   
spikeCount=zeros(nChannels,1);
for i1=1:nChannels
	%highest rate channel defines memory use!
	maxMem=0;
	if channelSel(sortedChannelID(i1))
		maxMem=sum(d.maxSpkPerSegmPerChanl(startSegm:endSegm-1));
	end
	if (strcmp(outputType,'spike'))
		c{i1,1}=zeros(maxMem,1); 				%spiketimes
		c{i1,2}=zeros(maxMem,d.spikeSize);	%spikevalues
	else %timevalue
		c{i1,1}=zeros(maxMem*(d.spikeSize+2),1);	%times
		c{i1,2}=zeros(maxMem*(d.spikeSize+2),1);	%values
	end
end
lastSpikeEnd=ones(68,1)*d.sweepStartTime(startSegm);

fseek(d.fid,startPointer,'bof');
segCount=0;
msPerT=d.MicrosecondsPerTick/1000;
while segCount<nSegments
	segCount=segCount+1;
	timebin = fread(d.fid, [1,2], 'ulong');				% Startzeit des Segments 	sweepStartTime = (timebin(2)*2^32+timebin(1))*msPerT;

	segmentsamples = fread(d.fid,1,'unsigned short');	% no. of samples in segment. 3200 (always)
																		%2 mal? warum?
	timebin = fread(d.fid, [1,2], 'ulong');				% Startzeit des Sweeps (bin鋜)	sweepStartTime = (timebin(2)*2^32+timebin(1))*msPerT;
	segmentsamples = fread(d.fid,1,'unsigned short');	% no. of samples in segment. 3200 (always)
	if segmentsamples ~= 3200
		error('unexpected data-file structure, value segmentsamples2 is not valid (~=3200)')
	end
	lokNChannel = fread(d.fid,1,'unsigned long');					% number of spike lists in segment (immer 64, je Kanal 1)
	if lokNChannel ~= 64
		error('unexpected data-file structure, value nChannels is not valid (~=64)')
	end
	for i1=1:lokNChannel													% Kanal nummer (0-63) in der ausgew鋒lten Reihenfolge, 
		%read in spike list										  also gew鋒lte Kan鋖e zuerst, dann alle nicht gew鋒lten mit Eintr鋑en von 0 Spikes!!!
		nSpikes = fread(d.fid,1,'unsigned long');			% number of spikes in list (i.e. spikes auf diesem Kanal in diesem Segment)
		for i2=1:nSpikes,											% spike number
			%read in spike:
			timebin = fread(d.fid, [1,2], 'ulong');		% Startzeit des Sweeps (bin鋜)
			spiketime = (timebin(2)*2^32+timebin(1))*msPerT;		% reformat to ms 
			ticks_pre_event  = fread(d.fid,1,'unsigned short');	%ticks pre event
			spikeSize  = fread(d.fid,1,'unsigned short');			% window size in ticks, i.e. # of samples in this trace
			tmp= fread(d.fid,[1,spikeSize],'short');	%spikevalues
			if (spikeSize/2==floor(spikeSize/2))
				pFac=0;
			else
				pFac=+1;
			end
			peak = tmp(ticks_pre_event-1+pFac:ticks_pre_event+1+pFac)-d.ZeroADValue;
			if channelSel(sortedChannelID(i1)) & ...
				(~d.BitFlipRemoveFactor | ...
							( abs(peak(2))*d.BitFlipRemoveFactor < abs(peak(1)) ...
								  & abs(peak(2))*d.BitFlipRemoveFactor < abs(peak(3)) ) )	%remove peak if very sharp
				if (strcmp(outputType,'spike'))
					spikeCount(i1)=spikeCount(i1)+1;
					c{sortedChannelID(i1),1}(spikeCount(i1))=spiketime;														%spiketimes
					c{sortedChannelID(i1),2}(spikeCount(i1),1:spikeSize)= tmp;	%spikevalues
				else %timevalue
					spkStartTick=round(((spiketime-d.sweepStartTime(startSegm))/msPerT)-ticks_pre_event+1); %round for heavens sake
					ticksSinceLast=round(((spiketime-lastSpikeEnd(i1))/msPerT)-ticks_pre_event+1); %round for heavens sake
					if ticksSinceLast>2 & spikeCount(i1)>1	 %set two adjacent zero values for drawing!
						c{sortedChannelID(i1),1}(spikeCount(i1)+1)=lastSpikeEnd(i1)+msPerT;
						c{sortedChannelID(i1),2}(spikeCount(i1)+1)=d.ZeroADValue;
						c{sortedChannelID(i1),1}(spikeCount(i1)+2)=d.sweepStartTime(startSegm)+(spkStartTick-1)*msPerT;
						c{sortedChannelID(i1),2}(spikeCount(i1)+2)=d.ZeroADValue;
						spikeCount(i1)=spikeCount(i1)+2;
					end
					if ticksSinceLast<1	
						ticksInPrevSegm=abs(ticksSinceLast)+1;
						spkStartTick=spkStartTick+ticksInPrevSegm;
						tmp=tmp(ticksInPrevSegm+1:spikeSize); %throw away overlap
						spikeSize=spikeSize-ticksInPrevSegm;
					end
					c{sortedChannelID(i1),1}(spikeCount(i1)+1:spikeCount(i1)+spikeSize)= ...
							d.sweepStartTime(startSegm)+[spkStartTick:spkStartTick+spikeSize-1]*msPerT;	%times
					c{sortedChannelID(i1),2}(spikeCount(i1)+1:spikeCount(i1)+spikeSize)= tmp;				%values
					spikeCount(i1)=spikeCount(i1)+spikeSize;
					lastSpikeEnd(i1)=c{sortedChannelID(i1),1}(spikeCount(i1));
				end
			end
		end
	end
end

for i1=1:nChannels
	c{sortedChannelID(i1),1}=c{sortedChannelID(i1),1}(1:spikeCount(i1),:); 	%spiketimes, sized as needed
	c{sortedChannelID(i1),2}=c{sortedChannelID(i1),2}(1:spikeCount(i1),:);	%spikevalues, sized as needed
end

newc.spiketimes={c{:,1}};
newc.spikevalues={c{:,2}};
newc.startend=[(startSegm-1) (endSegm-1)]*128;

if rawdata
	%fill timevalue data with zeros
	minT=startTime;
	maxT=endTime;
	maxTick=ceil((maxT-minT)*1000/d.MicrosecondsPerTick);
	val=zeros(sum(channelSel),maxTick)+d.ZeroADValue;
	count=0;
	for i1=1:nChannels
      if channelSel(i1) 
         count=count+1;
         tmpT=newc.spiketimes{i1};
         minIdx=min(find(tmpT>=minT));
         maxIdx=max(find(tmpT<(maxT-d.MicrosecondsPerTick/1000/2)));
         if ~isempty(minIdx)& ~isempty(maxIdx)
            idxT=round((tmpT-startTime)*1000/d.MicrosecondsPerTick)+1;
            idxT=idxT(minIdx:maxIdx);
            val(count,idxT)=newc.spikevalues{i1}(minIdx:maxIdx)';
         end
      end
   end
	newc.spiketimes=[];
	newc.spikevalues=val;
	newc.startend=[startTime endTime];
end

c=newc;

return;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -