
How to compute and display scalp potentials from EEG recordings
Created on July 7 at 12:34 pm - by: admin
EEG researchers commonly create spatial maps of the electrical activity acros the scalp. Data are interpolated or triangulated from a discrete number of electrode placements distributed across the scalp (generally greater than 32 sites) often in fixed/standardized positions (see, e.g., http://www.ant-neuro.com/products/waveguard_original).
To do this, electrode coordinates, either as {x, y, z} triplets or in spherical coordinates are needed and can be obtained from the manufacturer of electrode caps (e.g., https://www.egi.com/knowledge-center/item/71-sensor-position-files-for-visualizing-data-in-third-party-software).
Theoretical analysis typically involves modeling the head as a perfect sphere. The mapping of the electrode coordinates to the surface of a sphere can be accomplished with the following function:
Function scaleToSpherical(inWave) Wave inWave // offset the coordinates to the origin: MatrixOP/o/free wave0c=subtractMean(inWave,1) // compute the distance of electrodes from the origin: MatrixOP/O/free rawRad=sqrt(magsqr(col(wave0c,0))+magsqr(col(wave0c,1))+magsqr(col(wave0c,2))) // rescale the distance to a radius of 1: MatrixOP/O centeredNormalized=scalerows(wave0c,rec(rawRad)) End
Figure 1:Initial electrode positions relative to the surface of a sphere.
Figure 2: Normalized electrode coordinates on the surface of a sphere.
Using the normalized set of coordinates we can triangulate the data on the surface of a sphere using the SphericalTriangulate operation.
SphericalTriangulate centeredNormalized // this creates M_TriangulationData
Following the triangulation we can use the wave M_TriangulationData combined with the EEG data to interpolate the potentials at any point on the sphere. In order to display the resulting interpolation in Gizmo we start by creating a parametric surface representing the sphere.
Function makeParametricSphere(pointsx,pointsy) Variable pointsx,pointsy Variable i,j,rad Make/O/N=(pointsx,pointsy,3) parametricW Variable anglePhi,angleTheta Variable dPhi,dTheta dPhi=2*pi/(pointsx-1) dTheta=pi/(pointsy-1) Variable xx,yy,zz Variable sig for(j=0;j<pointsy;j+=1) angleTheta=j*dTheta zz=sin(angleTheta) if(angleTheta>pi/2) sig=-1 else sig=1 endif for(i=0;i<pointsx;i+=1) anglePhi=i*dPhi xx=zz*cos(anglePhi) yy=zz*sin(anglePhi) parametricW[i][j][0]=xx parametricW[i][j][1]=yy parametricW[i][j][2]=sig*sqrt(1-xx*xx-yy*yy) endfor endfor End
To complete the interpolation we need to construct one more wave: dataPointsWave. This wave has 4-columns consisting of the electrode coordinates in the first three columns and the potentials measured by each electrode at some fixed time t0 in the fourth column:
Variable nRows=DimSize(centeredNormalized,0) Make/O/D/N=(nRows,4) dataPointsWave dataPointsWave[][0,2]=centeredNormalized dataPointsWave[][3]=electrodePotentials[p]
The interpolation is computed by:
SphericalInterpolate M_TriangulationData,dataPointsWave,sphereData
The resulting interpolation is stored in the wave W_SphericalInterpolation where each row contains the scalar potential interpolated for the corresponding XYZ location in the wave sphereData. To display these values on the parametric surface we need to construct a color wave
Function createParametricColorWave(pWave,interpWave,reverseCTAB) Wave pWave,interpWave Variable reverseCTAB // set to 1 to reverse; 0 otherwise // the color wave must match the parametric surface: Variable rows=dimsize(pwave,0) Variable cols=dimSize(pWave,1) // Create the parametric color wave: Make/O/N=(rows,cols,4) pWaveColor=1 // find the range of values for scaling: Variable mmax=WaveMax(interpWave) Variable mmin=WaveMin(interpWave) // optionally replace the colortable here: ColorTab2Wave rainbow256 Wave M_Colors // not all colortables have the same number of colors: Variable nTableCols=DimSize(M_Colors,0)-1 if(reverseCTAB) MatrixOP/o/free aa=col(M_Colors,0) WaveTransform/o flip aa MatrixOP/O M_Colors=setCol(M_Colors,0,aa) MatrixOP/o/free aa=col(M_Colors,1) WaveTransform/o flip aa MatrixOP/O M_Colors=setCol(M_Colors,1,aa) MatrixOP/o/free aa=col(M_Colors,2) WaveTransform/o flip aa MatrixOP/O M_Colors=setCol(M_Colors,2,aa) endif MatrixOP/O M_Colors=fp32(M_Colors/65535) Variable nor=nTableCols/(mmax-mmin) Variable i, np=rows*cols,index,rr,cc for(i=0;i<np;i+=1) index=trunc((interpWave[i]-mmin)*nor) rr=mod(i,rows) cc=trunc(i/rows) pWaveColor[rr][cc][0]=M_Colors[index][0] pWaveColor[rr][cc][1]=M_Colors[index][1] pWaveColor[rr][cc][2]=M_Colors[index][2] endfor End
An example of this approach is illustrated in a cross-lingustic speech discrimination study at the following webpage:
Valerie L. Shafer, Ph.D.
vshafer@gc.cuny.edu
Professor and Deputy Executive Officer
Ph.D. Program in Speech-Language-Hearing Sciences
The Graduate Center, CUNY
365 Fifth Avenue, NY, NY 10016


Forum

Support

Gallery
Igor Pro 10
Learn More
Igor XOP Toolkit
Learn More
Igor NIDAQ Tools MX
Learn More