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

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