I converted some MNE code to convert form x/y/z to eeg_topoplot coordinates.
Now the big question is, can/should this be included here in TopoPlots.jl, or somehwere else?
using CoordinateTransformations
"""
convert x/y/z electrode montage positions to spherical coordinate representation. output is a matrix
"""
function cart3d_to_spherical(x,y,z)
sph = SphericalFromCartesian().(SVector.(x,y,z))
sph = [vcat(s.r,s.θ,π/2 - s.ϕ) for s in sph]
sph = hcat(sph...)'
return sph
end
"""
Projects 3D electrode positions to a 2D layout.
Re-implementation of the MNE algorithm.
If you put sphere to
"""
function pos3D_to_layout(x,y,z;sphere=[0,0,0.])
#cart3d_to_spherical(x,y,z)
# translate to sphere origin
x .-= sphere[1]
y .-= sphere[2]
z .-= sphere[3]
# convert to spherical coordinates
sph = cart3d_to_spherical(x,y,z)
# get rid of of the radius for now
pol_a = sph[:,3]
pol_b = sph[:,2]
# use only theta & phi, convert back to cartesian coordinates
p_x = pol_a .* cos.(pol_b)
p_y = pol_a .* sin.(pol_b)
# scale by the radius
p_x .*= sph[:,1] ./(π/2)
p_y .*= sph[:,1] ./(π/2)
# move back by the sphere coordinates
p_x .+= sphere[1]
p_y .+= sphere[2]
return Point2f.(p_x,p_y)
end

(for full reproducibility)
begin
using CSV
using LinearAlgebra
using HTTP
using CoordinateTransformations
using WGLMakie
using StaticArrays
using DataFrames
end
begin
pos3d = CSV.read(download("https://raw.githubusercontent.com/lrkrol/SEREEGA/b5dec01e8b98260904906cc19c38853bfbb2ff19/leadfield/hartmut/chanlocs-hartmut-NYhead_small.xyz"),DataFrame,header=false)
rename!(pos3d,:Column1=>:ix,:Column2=>:x,:Column3=>:y,:Column4=>:z,:Column5=>:label)
# remove some whitespace in the labels
transform!(pos3d,:label=>(x->strip.(x))=>:label)
# remove some weird channels
subset!(pos3d,:label=>ByRow(l -> l ∉ ["Nk1","Nk2","Nk3","Nk4"]));
out = pos3D_to_layout(pos3d.x,pos3d.y,pos3d.z)
eeg_topoplot(1:size(out,1),pos3d.label;positions=out, interpolation=NullInterpolator(),label_text=true,enlarge=0.5)
end;
I converted some MNE code to convert form x/y/z to eeg_topoplot coordinates.
Now the big question is, can/should this be included here in TopoPlots.jl, or somehwere else?
(for full reproducibility)