Skip to content

Commit f6bb9d4

Browse files
authored
Merge pull request #2 from rstoneback/enu_ecef_bugfix
Bugfix for ENU and ECEF vector rotation
2 parents 483e4a9 + 74ba453 commit f6bb9d4

3 files changed

Lines changed: 157 additions & 11 deletions

File tree

pysatMagVect/_core.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -211,9 +211,9 @@ def enu_to_ecef_vector(east, north, up, glat, glong):
211211
rlat = np.radians(glat)
212212
rlon = np.radians(glong)
213213

214-
x = -east*np.sin(rlat) - north*np.cos(rlat)*np.sin(rlon) + up*np.cos(rlat)*np.cos(rlon)
215-
y = east*np.cos(rlat) - north*np.sin(rlat)*np.sin(rlon) + up*np.sin(rlat)*np.cos(rlon)
216-
z = north*np.cos(rlon) + up*np.sin(rlon)
214+
x = -east*np.sin(rlon) - north*np.cos(rlon)*np.sin(rlat) + up*np.cos(rlon)*np.cos(rlat)
215+
y = east*np.cos(rlon) - north*np.sin(rlon)*np.sin(rlat) + up*np.sin(rlon)*np.cos(rlat)
216+
z = north*np.cos(rlat) + up*np.sin(rlat)
217217

218218
return x, y, z
219219

@@ -248,9 +248,9 @@ def ecef_to_enu_vector(x, y, z, glat, glong):
248248
rlat = np.radians(glat)
249249
rlon = np.radians(glong)
250250

251-
east = -x*np.sin(rlat) + y*np.cos(rlat)
252-
north = -x*np.cos(rlat)*np.sin(rlon) - y*np.sin(rlat)*np.sin(rlon) + z*np.cos(rlon)
253-
up = x*np.cos(rlat)*np.cos(rlon) + y*np.sin(rlat)*np.cos(rlon)+ z*np.sin(rlon)
251+
east = -x*np.sin(rlon) + y*np.cos(rlon)
252+
north = -x*np.cos(rlon)*np.sin(rlat) - y*np.sin(rlon)*np.sin(rlat) + z*np.cos(rlat)
253+
up = x*np.cos(rlon)*np.cos(rlat) + y*np.sin(rlon)*np.cos(rlat)+ z*np.sin(rlat)
254254

255255
return east, north, up
256256

pysatMagVect/tests/test_core.py

Lines changed: 150 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from nose.tools import assert_raises, raises
22
import nose.tools
3+
from nose.tools import assert_almost_equals as asseq
34

45

56
import numpy as np
@@ -381,7 +382,152 @@ def test_unit_vector_plots(self):
381382
#plt.savefig('magnetic_unit_vectors_w_globe.png')
382383
#print truthiness
383384
assert np.all(truthiness)
384-
385-
386-
387-
385+
386+
387+
def test_basic_ecef_to_enu_rotations(self):
388+
# test basic transformations first
389+
# vector pointing along ecef y at 0, 0 is east
390+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 1., 0., 0., 0.)
391+
# print ('{:9f}, {:9f}, {:9f}'.format(ve, vn, vu))
392+
asseq(ve, 1.0, 6)
393+
asseq(vn, 0, 6)
394+
asseq(vu, 0, 6)
395+
# vector pointing along ecef x at 0, 0 is up
396+
ve, vn, vu = pymv.ecef_to_enu_vector(1., 0., 0., 0., 0.)
397+
asseq(ve, 0.0, 6)
398+
asseq(vn, 0.0, 6)
399+
asseq(vu, 1.0, 6)
400+
# vector pointing along ecef z at 0, 0 is north
401+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 0., 1., 0., 0.)
402+
asseq(ve, 0.0, 6)
403+
asseq(vn, 1.0, 6)
404+
asseq(vu, 0.0, 6)
405+
406+
# vector pointing along ecef x at 0, 90 long is west
407+
ve, vn, vu = pymv.ecef_to_enu_vector(1., 0., 0., 0., 90.)
408+
# print ('{:9f}, {:9f}, {:9f}'.format(ve, vn, vu))
409+
asseq(ve, -1.0, 6)
410+
asseq(vn, 0.0, 6)
411+
asseq(vu, 0.0, 6)
412+
# vector pointing along ecef y at 0, 90 long is up
413+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 1., 0., 0., 90.)
414+
asseq(ve, 0.0, 6)
415+
asseq(vn, 0.0, 6)
416+
asseq(vu, 1.0, 6)
417+
# vector pointing along ecef z at 0, 90 long is north
418+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 0., 1., 0., 90.)
419+
asseq(ve, 0.0, 6)
420+
asseq(vn, 1.0, 6)
421+
asseq(vu, 0.0, 6)
422+
423+
# vector pointing along ecef y at 0, 180 is west
424+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 1., 0., 0., 180.)
425+
asseq(ve, -1.0, 6)
426+
asseq(vn, 0.0, 6)
427+
asseq(vu, 0.0, 6)
428+
# vector pointing along ecef x at 0, 180 is down
429+
ve, vn, vu = pymv.ecef_to_enu_vector(1., 0., 0., 0., 180.)
430+
asseq(ve, 0.0, 6)
431+
asseq(vn, 0.0, 6)
432+
asseq(vu, -1.0, 6)
433+
# vector pointing along ecef z at 0, 0 is north
434+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 0., 1., 0., 180.)
435+
asseq(ve, 0.0, 6)
436+
asseq(vn, 1.0, 6)
437+
asseq(vu, 0.0, 6)
438+
439+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 1., 0., 45., 0.)
440+
# print ('{:9f}, {:9f}, {:9f}'.format(ve, vn, vu))
441+
asseq(ve, 1.0, 6)
442+
asseq(vn, 0, 6)
443+
asseq(vu, 0, 6)
444+
# vector pointing along ecef x at 0, 0 is south/up
445+
ve, vn, vu = pymv.ecef_to_enu_vector(1., 0., 0., 45., 0.)
446+
asseq(ve, 0.0, 6)
447+
asseq(vn, -np.cos(np.pi/4), 6)
448+
asseq(vu, np.cos(np.pi/4), 6)
449+
# vector pointing along ecef z at 45, 0 is north/up
450+
ve, vn, vu = pymv.ecef_to_enu_vector(0., 0., 1., 45., 0.)
451+
asseq(ve, 0.0, 6)
452+
asseq(vn, np.cos(np.pi/4), 6)
453+
asseq(vu, np.cos(np.pi/4), 6)
454+
455+
456+
def test_basic_enu_to_ecef_rotations(self):
457+
# test basic transformations first
458+
# vector pointing east at 0, 0 is along y
459+
vx, vy, vz = pymv.enu_to_ecef_vector(1., 0., 0., 0., 0.)
460+
# print ('{:9f}, {:9f}, {:9f}'.format(vx, vy, vz))
461+
asseq(vx, 0.0, 6)
462+
asseq(vy, 1.0, 6)
463+
asseq(vz, 0.0, 6)
464+
# vector pointing up at 0, 0 is along x
465+
vx, vy, vz = pymv.enu_to_ecef_vector(0., 0., 1., 0., 0.)
466+
asseq(vx, 1.0, 6)
467+
asseq(vy, 0.0, 6)
468+
asseq(vz, 0.0, 6)
469+
# vector pointing north at 0, 0 is along z
470+
vx, vy, vz = pymv.enu_to_ecef_vector(0., 1., 0., 0., 0.)
471+
asseq(vx, 0.0, 6)
472+
asseq(vy, 0.0, 6)
473+
asseq(vz, 1.0, 6)
474+
475+
# east vector at 0, 90 long points along -x
476+
vx, vy, vz = pymv.enu_to_ecef_vector(1., 0., 0., 0., 90.)
477+
# print ('{:9f}, {:9f}, {:9f}'.format(vx, vy, vz))
478+
asseq(vx, -1.0, 6)
479+
asseq(vy, 0.0, 6)
480+
asseq(vz, 0.0, 6)
481+
# vector pointing up at 0, 90 is along y
482+
vx, vy, vz = pymv.enu_to_ecef_vector(0., 0., 1., 0., 90.)
483+
asseq(vx, 0.0, 6)
484+
asseq(vy, 1.0, 6)
485+
asseq(vz, 0.0, 6)
486+
# vector pointing north at 0, 90 is along z
487+
vx, vy, vz = pymv.enu_to_ecef_vector(0., 1., 0., 0., 90.)
488+
asseq(vx, 0.0, 6)
489+
asseq(vy, 0.0, 6)
490+
asseq(vz, 1.0, 6)
491+
492+
# vector pointing east at 0, 0 is along y
493+
vx, vy, vz = pymv.enu_to_ecef_vector(1., 0., 0., 0., 180.)
494+
# print ('{:9f}, {:9f}, {:9f}'.format(vx, vy, vz))
495+
asseq(vx, 0.0, 6)
496+
asseq(vy, -1.0, 6)
497+
asseq(vz, 0.0, 6)
498+
# vector pointing up at 0, 180 is along -x
499+
vx, vy, vz = pymv.enu_to_ecef_vector(0., 0., 1., 0., 180.)
500+
asseq(vx, -1.0, 6)
501+
asseq(vy, 0.0, 6)
502+
asseq(vz, 0.0, 6)
503+
# vector pointing north at 0, 180 is along z
504+
vx, vy, vz = pymv.enu_to_ecef_vector(0., 1., 0., 0., 180.)
505+
asseq(vx, 0.0, 6)
506+
asseq(vy, 0.0, 6)
507+
asseq(vz, 1.0, 6)
508+
509+
def test_ecef_to_enu_back_to_ecef(self):
510+
511+
vx = 0.9
512+
vy = 0.1
513+
vz = np.sqrt(1. - vx**2+vy**2)
514+
515+
for lat, lon, alt in zip(omni['p_lat'], omni['p_long'], omni['p_alt']):
516+
vxx, vyy, vzz = pymv.ecef_to_enu_vector(vx, vy, vz, lat, lon)
517+
vxx, vyy, vzz = pymv.enu_to_ecef_vector(vxx, vyy, vzz, lat, lon)
518+
asseq(vx, vxx, 6)
519+
asseq(vy, vyy, 6)
520+
asseq(vz, vzz, 6)
521+
522+
def test_enu_to_ecef_back_to_enu(self):
523+
524+
vx = 0.9
525+
vy = 0.1
526+
vz = np.sqrt(1. - vx**2+vy**2)
527+
528+
for lat, lon, alt in zip(omni['p_lat'], omni['p_long'], omni['p_alt']):
529+
vxx, vyy, vzz = pymv.enu_to_ecef_vector(vx, vy, vz, lat, lon)
530+
vxx, vyy, vzz = pymv.ecef_to_enu_vector(vxx, vyy, vzz, lat, lon)
531+
asseq(vx, vxx, 6)
532+
asseq(vy, vyy, 6)
533+
asseq(vz, vzz, 6)

pysatMagVect/version.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
0.2.0
1+
0.3.0

0 commit comments

Comments
 (0)