#+STYLE: * Downloading data with =Python= and loading them into =octave= The data recorded from 4 electrodes result from a preprocessing briefly described in the main text and are stored as signed integer coded on 4 Bytes. They must be mutiplied by 0.12715626 on channels 1 and 4 and by 0.01271439 on channels 2 and 3 to get voltage in \mu V. They are sampled at 500 Hz and 600 second are stored. We will here then dowload the data from our web repository using [[http://www.python.org/][python]]. To this end we start by defining a =list= containing the file namse under which we want to store the data on our hard-drive: #+srcname: dN #+begin_src python :session *Python* :exports code :results value pp dN=["SpinalCordMouseEmbryo_CH"+str(i)+".dat" for i in range(1,5)] dN #+end_src #+results: dN : ['SpinalCordMouseEmbryo_CH1.dat', : 'SpinalCordMouseEmbryo_CH2.dat', : 'SpinalCordMouseEmbryo_CH3.dat', : 'SpinalCordMouseEmbryo_CH4.dat'] After loading the =urllib= library we can proceed and download the data: #+srcname: download-data #+begin_src python :session *Python* :exports code :results silent import urllib reposName = "http://www.biomedicale.univ-paris5.fr/physcerv/C_Pouzat/Data_folder/" for n in dN:urllib.urlretrieve(reposName+n,n) #+end_src We then load the data in an [[http://www.gnu.org/software/octave/][octave]] session (that's the occasion to make use of the [[http://orgmode.org/worg/org-contrib/babel/intro.html#meta-programming-language][meta-programming language]] capabilities of =org-mode= -- a variable created by =python=, =dN=, is going to be used directly in =octave=): #+srcname: load-to-octave #+begin_src octave :session *octave* :exports code :results silent :var fN=dN nSamples = 500 * 600; Data_raw = zeros(nSamples,4); i2v = [0.12715626 0.01271439 0.01271439 0.12715626]; for i=1:4 fid=fopen(fN(i,:),"r"); [C,n]=fread(fid,nSamples,"int32"); fclose(fid); Data_raw(:,i)=C*i2v(i); end #+end_src The time derivatives of the measurements are simply obtained using a difference equation whose precision is o(\delta^{2}): \[ f'(x) = (f(x+\delta) - f(x-\delta))/(2 \delta) \] #+srcname: Data-derivative #+begin_src octave :session *octave* :exports code :results silent Data_derivative = zeros(nSamples,4); for i=1:4 Data_derivative(2:(nSamples-1),i)=(Data_raw(3:nSamples,i)-Data_raw(1:(nSamples-2),i))*500/2/1000; end #+end_src Here the unit of =Data_derivative= is \mu V / ms. * LFP detection We are going to detect minima on each channel whose amplitudes are below a /user set/ multiple of the channel standard deviation. We start by computing this quantity for each of the two versions of the data we might choose to work with, ``raw'' of ``derivative'': #+srcname: SD #+begin_src octave :session *octave* :exports code :results silent SD_raw = std(Data_raw); SD_derivative = std(Data_derivative); #+end_src Here SD_ raw and SD_ derivative are /vectors/ with as many elements as Data_ raw and Data_ derivative have columns, that is, as many elements as recording channels. We are going to use a threshold of 4 times the standard deviation on each channel: #+srcname: factor #+begin_src octave :session *octave* :exports code :results silent factor=4; #+end_src A inquiring reader could easily make another choice like using a threshold of 3.5: #+srcname: threshold-on-derivative2 #+begin_src octave :session *octave* :exports code :results output :eval never factor=3.5; #+end_src As explained in the main text we /decided/ to identify events as minima exceeding (in absolute value) a threshold on 3 channels simultaneously. To this end we define a variable, =activeElecNumber=, which contains our number of required active channels. The value of this variable can easily be changed: #+srcname: activeElecNumber #+begin_src octave :session *octave* :exports code :results silent activeElecNumber=3; #+end_src The detection can now proceed: #+srcname: detect-LFP #+begin_src octave :session *octave* :exports code :results silent Times=(1:size(Data_derivative)(1))/500; timeLFP=Times(sum(Data_derivative ./ (ones(nSamples,1) * SD_derivative) < -factor,2) >= 3); #+end_src We decide moreover to keep only detected events which are more than 100 ms apart. When ``too close'' events are found, the second one is discarded. This elimination is done recursively starting with the second event: #+srcname: timeLFP #+begin_src octave :session *octave* :exports code :results silent timeLFP2=timeLFP; nbLFP=length(timeLFP); last=1; new=2; while (new <= nbLFP) tDiff=timeLFP(new)-timeLFP2(last); if tDiff >= 0.1 last=last+1; timeLFP2(last)=timeLFP(new); end new=new+1; end timeLFP=timeLFP2(1:last); #+end_src We can now produce our summary figure with: #+begin_src octave :session *octave* :exports code :results silent Dd_range=(max(Data_derivative(:))-min(Data_derivative(:))); Data_derivativeN = Data_derivative ./ Dd_range; Data_derivativeN_min=min(Data_derivativeN(:)); Data_derivativeN=Data_derivativeN - Data_derivativeN_min; Data_derivativeN=Data_derivativeN - (ones(nSamples,1) * [0 1 2 3]); thresh=-factor*SD_derivative/Dd_range - Data_derivativeN_min - [0 1 2 3]; lwr=0-Data_derivativeN_min - [0 1 2 3]; upr=2 ./ Dd_range - Data_derivativeN_min - [0 1 2 3]; figure( 1, "visible" , "off" ); plot(Times,Data_derivativeN,'k'); hold on; plot([0 600],[thresh(1) thresh(1)],'r'); plot([0 600],[thresh(2) thresh(2)],'r'); plot([0 600],[thresh(3) thresh(3)],'r'); plot([0 600],[thresh(4) thresh(4)],'r'); scatter(timeLFP,-3+0*(1:length(timeLFP)),"+"); hold off; set(gca(),"visible","off"); print -dpng detectionOnDerivativeData.png; #+end_src #+caption: *Detection of LFP activity on the first time-derivative of the data.* The derivative are drawn in black (site 1 is at the top and site 4 at the bottom). Detection threshold set at -4 times the =SD= of each trace appear as red horizontal lines. Detected events are marked as blue crosses at the bottom of the graph. #+ATTR_HTML: width=800 height=800 [[file:detectionOnDerivativeData.png]]