Esempio n. 1
0
def test_basevectors_apex_scalar_shape():
    apex_out = Apex(date=2000, refh=300)
    ret = apex_out.basevectors_apex(60, 15, 100, precision=1e-2)
    for r in ret[:2]:
        assert r.shape == (2, )
    for r in ret[2:]:
        assert r.shape == (3, )
Esempio n. 2
0
def test_basevectors_apex_vectorization_height():
    A = Apex(date=2000, refh=0)
    f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(60, 15, [200, 400], coords='geo')
    _, _, _, _, f1_1, f2_1, _, d1_1, d2_1, d3_1, _, e1_1, e2_1, e3_1 = A._geo2apexall(60, 15, 200)
    _, _, _, _, f1_2, f2_2, _, d1_2, d2_2, d3_2, _, e1_2, e2_2, e3_2 = A._geo2apexall(60, 15, 400)

    assert_allclose(f1[:, 0], f1_1)
    assert_allclose(f2[:, 0], f2_1)
    assert_allclose(d1[:, 0], d1_1)
    assert_allclose(d2[:, 0], d2_1)
    assert_allclose(d3[:, 0], d3_1)
    assert_allclose(e1[:, 0], e1_1)
    assert_allclose(e2[:, 0], e2_1)
    assert_allclose(e3[:, 0], e3_1)

    assert_allclose(f3[:, 0], np.array([-0.088671, -0.018272, 0.993576]), rtol=1e-4)
    assert_allclose(g1[:, 0], np.array([0.903098, 0.245273, 0.085107]), rtol=1e-4)
    assert_allclose(g2[:, 0], np.array([-0.103495, 1.072078, 0.01048]), rtol=1e-4)
    assert_allclose(g3[:, 0], np.array([0, 0, 1.006465]), rtol=1e-4)

    assert_allclose(f1[:, 1], f1_2)
    assert_allclose(f2[:, 1], f2_2)
    assert_allclose(d1[:, 1], d1_2)
    assert_allclose(d2[:, 1], d2_2)
    assert_allclose(d3[:, 1], d3_2)
    assert_allclose(e1[:, 1], e1_2)
    assert_allclose(e2[:, 1], e2_2)
    assert_allclose(e3[:, 1], e3_2)

    assert_allclose(f3[:, 1], np.array([-0.085415, -0.021176, 0.989645]), rtol=1e-4)
    assert_allclose(g1[:, 1], np.array([0.902695, 0.246919, 0.083194]), rtol=1e-4)
    assert_allclose(g2[:, 1], np.array([-0.11051, 1.066094, 0.013274]), rtol=1e-4)
    assert_allclose(g3[:, 1], np.array([0, 0, 1.010463]), rtol=1e-4)
Esempio n. 3
0
def test_basevectors_apex_array():
    A = Apex(date=2000, refh=300)
    f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex([0, 30], 15, 100, coords='geo')
    _, _, _, _, f1_1, f2_1, _, d1_1, d2_1, d3_1, _, e1_1, e2_1, e3_1 = A._geo2apexall(0, 15, 100)
    _, _, _, _, f1_2, f2_2, _, d1_2, d2_2, d3_2, _, e1_2, e2_2, e3_2 = A._geo2apexall(30, 15, 100)

    assert_allclose(f1[:, 0], f1_1)
    assert_allclose(f2[:, 0], f2_1)
    assert_allclose(d1[:, 0], d1_1)
    assert_allclose(d2[:, 0], d2_1)
    assert_allclose(d3[:, 0], d3_1)
    assert_allclose(e1[:, 0], e1_1)
    assert_allclose(e2[:, 0], e2_1)
    assert_allclose(e3[:, 0], e3_1)

    assert_allclose(f3[:, 0], np.array([0.092637, -0.245951, 0.938848]), rtol=1e-4)
    assert_allclose(g1[:, 0], np.array([0.939012, 0.073416, -0.07342]), rtol=1e-4)
    assert_allclose(g2[:, 0], np.array([0.055389, 1.004155, 0.257594]), rtol=1e-4)
    assert_allclose(g3[:, 0], np.array([0, 0, 1.065135]), rtol=1e-4)

    assert_allclose(f1[:, 1], f1_2)
    assert_allclose(f2[:, 1], f2_2)
    assert_allclose(d1[:, 1], d1_2)
    assert_allclose(d2[:, 1], d2_2)
    assert_allclose(d3[:, 1], d3_2)
    assert_allclose(e1[:, 1], e1_2)
    assert_allclose(e2[:, 1], e2_2)
    assert_allclose(e3[:, 1], e3_2)

    assert_allclose(f3[:, 1], np.array([-0.036618, -0.071019, 0.861604]), rtol=1e-4)
    assert_allclose(g1[:, 1], np.array([0.844391, 0.015353, 0.037152]), rtol=1e-4)
    assert_allclose(g2[:, 1], np.array([0.050808, 1.02131, 0.086342]), rtol=1e-4)
    assert_allclose(g3[:, 1], np.array([0, 0, 1.160625]), rtol=1e-4)
Esempio n. 4
0
def test_basevectors_apex_scalar_shape():
    A = Apex(date=2000, refh=300)
    ret = A.basevectors_apex(60, 15, 100, precision=1e-2)
    for r in ret[:2]:
        assert r.shape == (2,)
    for r in ret[2:]:
        assert r.shape == (3,)
Esempio n. 5
0
def test_basevectors_apex_vectorization():
    apex_out = Apex(date=2000, refh=300)
    ret = apex_out.basevectors_apex([60, 60, 60, 60], 15, 100)
    for r in ret[:2]:
        assert r.shape == (2, 4)
    for r in ret[2:]:
        assert r.shape == (3, 4)
    ret = apex_out.basevectors_apex(60, [15, 15, 15, 15], 100)
    for r in ret[:2]:
        assert r.shape == (2, 4)
    for r in ret[2:]:
        assert r.shape == (3, 4)
    ret = apex_out.basevectors_apex(60, 15, [100, 100, 100, 100])
    for r in ret[:2]:
        assert r.shape == (2, 4)
    for r in ret[2:]:
        assert r.shape == (3, 4)
Esempio n. 6
0
def test_basevectors_apex_vectorization():
    A = Apex(date=2000, refh=300)
    ret = A.basevectors_apex([60, 60, 60, 60], 15, 100)
    for r in ret[:2]:
        assert r.shape == (2, 4)
    for r in ret[2:]:
        assert r.shape == (3, 4)
    ret = A.basevectors_apex(60, [15, 15, 15, 15], 100)
    for r in ret[:2]:
        assert r.shape == (2, 4)
    for r in ret[2:]:
        assert r.shape == (3, 4)
    ret = A.basevectors_apex(60, 15, [100, 100, 100, 100])
    for r in ret[:2]:
        assert r.shape == (2, 4)
    for r in ret[2:]:
        assert r.shape == (3, 4)
Esempio n. 7
0
def map_vec(alt):
    # calculates plasma drift velocity and electric field vectors in geodetic components at a particular altitude

    VE, E, mlat, mlon = read_vvels_file('test_vvels.h5')
    A = Apex(2019)
    f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(
        mlat, mlon, alt, coords='apex')

    VEgd = (VE[:, 0] * e1 + VE[:, 1] * e2 + VE[:, 2] * e3).T
    Egd = (E[:, 0] * d1 + E[:, 1] * e2 + E[:, 2] * e3).T

    return VEgd, Egd
Esempio n. 8
0
def test_basevectors_apex_delta():
    A = Apex(date=2000, refh=300)
    for lat in range(0, 90, 10):
        for lon in range(0, 360, 15):
            f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(lat, lon, 500)
            f = [np.append(f1, 0), np.append(f2, 0), f3]
            g = [g1, g2, g3]
            d = [d1, d2, d3]
            e = [e1, e2, e3]
            for i, j in [(i, j) for i in range(3) for j in range(3)]:
                delta = 1 if i == j else 0
                assert_allclose(np.sum(f[i]*g[j]), delta, rtol=0, atol=1e-5)
                assert_allclose(np.sum(d[i]*e[j]), delta, rtol=0, atol=1e-5)
Esempio n. 9
0
def test_basevectors_apex_invalid_scalar():
    A = Apex(date=2000, refh=10000)
    with warnings.catch_warnings(record=True) as w:
        f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(0, 0, 0)
        A.basevectors_apex(0, 0, 0)
        assert len(w) == 2
        assert issubclass(w[-1].category, UserWarning)
        assert 'set to -9999 where' in str(w[-1].message)

    invalid = [-9999, -9999, -9999]
    assert not np.allclose(f1, invalid[:2])
    assert not np.allclose(f2, invalid[:2])
    assert_allclose(f3, invalid)
    assert_allclose(g1, invalid)
    assert_allclose(g2, invalid)
    assert_allclose(g3, invalid)
    assert_allclose(d1, invalid)
    assert_allclose(d2, invalid)
    assert_allclose(d3, invalid)
    assert_allclose(e1, invalid)
    assert_allclose(e2, invalid)
    assert_allclose(e3, invalid)
Esempio n. 10
0
def test_basevectors_apex_invalid_scalar():
    A = Apex(date=2000, refh=10000)
    with warnings.catch_warnings(record=True) as w:
        (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
         e3) = A.basevectors_apex(0, 0, 0)
        A.basevectors_apex(0, 0, 0)
        assert len(w) == 2
        assert issubclass(w[-1].category, UserWarning)
        assert 'set to -9999 where' in str(w[-1].message)

    invalid = [-9999, -9999, -9999]
    assert not np.allclose(f1, invalid[:2])
    assert not np.allclose(f2, invalid[:2])
    assert_allclose(f3, invalid)
    assert_allclose(g1, invalid)
    assert_allclose(g2, invalid)
    assert_allclose(g3, invalid)
    assert_allclose(d1, invalid)
    assert_allclose(d2, invalid)
    assert_allclose(d3, invalid)
    assert_allclose(e1, invalid)
    assert_allclose(e2, invalid)
    assert_allclose(e3, invalid)
Esempio n. 11
0
def test_basevectors_apex_delta():
    apex_out = Apex(date=2000, refh=300)
    for lat in range(0, 90, 10):
        for lon in range(0, 360, 15):
            (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
             e3) = apex_out.basevectors_apex(lat, lon, 500)
            f = [np.append(f1, 0), np.append(f2, 0), f3]
            g = [g1, g2, g3]
            d = [d1, d2, d3]
            e = [e1, e2, e3]
            for i, j in [(i, j) for i in range(3) for j in range(3)]:
                delta = 1 if i == j else 0
                assert_allclose(np.sum(f[i] * g[j]), delta, rtol=0, atol=1e-5)
                assert_allclose(np.sum(d[i] * e[j]), delta, rtol=0, atol=1e-5)
Esempio n. 12
0
def test_basevectors_apex_scalar_geo():
    A = Apex(date=2000, refh=300)

    f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(60, 15, 100, coords='geo')

    _, _, _, _, f1_, f2_, _, d1_, d2_, d3_, _, e1_, e2_, e3_ = A._geo2apexall(60, 15, 100)

    assert_allclose(f1, f1_)
    assert_allclose(f2, f2_)
    assert_allclose(d1, d1_)
    assert_allclose(d2, d2_)
    assert_allclose(d3, d3_)
    assert_allclose(e1, e1_)
    assert_allclose(e2, e2_)
    assert_allclose(e3, e3_)
Esempio n. 13
0
def test_basevectors_apex_vectorization_height():
    apex_out = Apex(date=2000, refh=0)
    (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
     e3) = apex_out.basevectors_apex(60, 15, [200, 400], coords='geo')
    (_, _, _, _, f1_1, f2_1, _, d1_1, d2_1, d3_1, _, e1_1, e2_1,
     e3_1) = apex_out._geo2apexall(60, 15, 200)
    (_, _, _, _, f1_2, f2_2, _, d1_2, d2_2, d3_2, _, e1_2, e2_2,
     e3_2) = apex_out._geo2apexall(60, 15, 400)

    assert_allclose(f1[:, 0], f1_1)
    assert_allclose(f2[:, 0], f2_1)
    assert_allclose(d1[:, 0], d1_1)
    assert_allclose(d2[:, 0], d2_1)
    assert_allclose(d3[:, 0], d3_1)
    assert_allclose(e1[:, 0], e1_1)
    assert_allclose(e2[:, 0], e2_1)
    assert_allclose(e3[:, 0], e3_1)

    assert_allclose(f3[:, 0],
                    np.array([-0.088671, -0.018272, 0.993576]),
                    rtol=1e-4)
    assert_allclose(g1[:, 0],
                    np.array([0.903098, 0.245273, 0.085107]),
                    rtol=1e-4)
    assert_allclose(g2[:, 0],
                    np.array([-0.103495, 1.072078, 0.01048]),
                    rtol=1e-4)
    assert_allclose(g3[:, 0], np.array([0, 0, 1.006465]), rtol=1e-4)

    assert_allclose(f1[:, 1], f1_2)
    assert_allclose(f2[:, 1], f2_2)
    assert_allclose(d1[:, 1], d1_2)
    assert_allclose(d2[:, 1], d2_2)
    assert_allclose(d3[:, 1], d3_2)
    assert_allclose(e1[:, 1], e1_2)
    assert_allclose(e2[:, 1], e2_2)
    assert_allclose(e3[:, 1], e3_2)

    assert_allclose(f3[:, 1],
                    np.array([-0.085415, -0.021176, 0.989645]),
                    rtol=1e-4)
    assert_allclose(g1[:, 1],
                    np.array([0.902695, 0.246919, 0.083194]),
                    rtol=1e-4)
    assert_allclose(g2[:, 1],
                    np.array([-0.11051, 1.066094, 0.013274]),
                    rtol=1e-4)
    assert_allclose(g3[:, 1], np.array([0, 0, 1.010463]), rtol=1e-4)
Esempio n. 14
0
def test_basevectors_apex_array():
    apex_out = Apex(date=2000, refh=300)
    (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
     e3) = apex_out.basevectors_apex([0, 30], 15, 100, coords='geo')
    (_, _, _, _, f1_1, f2_1, _, d1_1, d2_1, d3_1, _, e1_1, e2_1,
     e3_1) = apex_out._geo2apexall(0, 15, 100)
    (_, _, _, _, f1_2, f2_2, _, d1_2, d2_2, d3_2, _, e1_2, e2_2,
     e3_2) = apex_out._geo2apexall(30, 15, 100)

    assert_allclose(f1[:, 0], f1_1)
    assert_allclose(f2[:, 0], f2_1)
    assert_allclose(d1[:, 0], d1_1)
    assert_allclose(d2[:, 0], d2_1)
    assert_allclose(d3[:, 0], d3_1)
    assert_allclose(e1[:, 0], e1_1)
    assert_allclose(e2[:, 0], e2_1)
    assert_allclose(e3[:, 0], e3_1)

    assert_allclose(f3[:, 0],
                    np.array([0.092637, -0.245951, 0.938848]),
                    rtol=1e-4)
    assert_allclose(g1[:, 0],
                    np.array([0.939012, 0.073416, -0.07342]),
                    rtol=1e-4)
    assert_allclose(g2[:, 0],
                    np.array([0.055389, 1.004155, 0.257594]),
                    rtol=1e-4)
    assert_allclose(g3[:, 0], np.array([0, 0, 1.065135]), rtol=1e-4)

    assert_allclose(f1[:, 1], f1_2)
    assert_allclose(f2[:, 1], f2_2)
    assert_allclose(d1[:, 1], d1_2)
    assert_allclose(d2[:, 1], d2_2)
    assert_allclose(d3[:, 1], d3_2)
    assert_allclose(e1[:, 1], e1_2)
    assert_allclose(e2[:, 1], e2_2)
    assert_allclose(e3[:, 1], e3_2)

    assert_allclose(f3[:, 1],
                    np.array([-0.036618, -0.071019, 0.861604]),
                    rtol=1e-4)
    assert_allclose(g1[:, 1],
                    np.array([0.844391, 0.015353, 0.037152]),
                    rtol=1e-4)
    assert_allclose(g2[:, 1],
                    np.array([0.050808, 1.02131, 0.086342]),
                    rtol=1e-4)
    assert_allclose(g3[:, 1], np.array([0, 0, 1.160625]), rtol=1e-4)
Esempio n. 15
0
def test_basevectors_apex_scalar_qd():
    A = Apex(date=2000, refh=300)

    f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(60, 15, 100, coords='qd', precision=1e-2)

    glat, glon, _ = A.qd2geo(60, 15, 100, precision=1e-2)
    _, _, _, _, f1_, f2_, _, d1_, d2_, d3_, _, e1_, e2_, e3_ = A._geo2apexall(glat, glon, 100)

    assert_allclose(f1, f1_)
    assert_allclose(f2, f2_)
    assert_allclose(d1, d1_)
    assert_allclose(d2, d2_)
    assert_allclose(d3, d3_)
    assert_allclose(e1, e1_)
    assert_allclose(e2, e2_)
    assert_allclose(e3, e3_)
Esempio n. 16
0
def test_basevectors_apex_scalar_geo():
    apex_out = Apex(date=2000, refh=300)

    (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
     e3) = apex_out.basevectors_apex(60, 15, 100, coords='geo')

    (_, _, _, _, f1_, f2_, _, d1_, d2_, d3_, _, e1_, e2_,
     e3_) = apex_out._geo2apexall(60, 15, 100)

    assert_allclose(f1, f1_)
    assert_allclose(f2, f2_)
    assert_allclose(d1, d1_)
    assert_allclose(d2, d2_)
    assert_allclose(d3, d3_)
    assert_allclose(e1, e1_)
    assert_allclose(e2, e2_)
    assert_allclose(e3, e3_)
Esempio n. 17
0
def test_basevectors_apex_scalar_qd():
    apex_out = Apex(date=2000, refh=300)

    (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
     e3) = apex_out.basevectors_apex(60, 15, 100, coords='qd', precision=1e-2)

    glat, glon, _ = apex_out.qd2geo(60, 15, 100, precision=1e-2)
    (_, _, _, _, f1_, f2_, _, d1_, d2_, d3_, _, e1_, e2_,
     e3_) = apex_out._geo2apexall(glat, glon, 100)

    assert_allclose(f1, f1_)
    assert_allclose(f2, f2_)
    assert_allclose(d1, d1_)
    assert_allclose(d2, d2_)
    assert_allclose(d3, d3_)
    assert_allclose(e1, e1_)
    assert_allclose(e2, e2_)
    assert_allclose(e3, e3_)
Esempio n. 18
0
def test_basevectors_apex_scalar():
    A = Apex(date=2000, refh=300)

    f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(0, 15, 100, coords='geo')
    _, _, _, _, f1_1, f2_1, _, d1_1, d2_1, d3_1, _, e1_1, e2_1, e3_1 = A._geo2apexall(0, 15, 100)

    assert_allclose(f1, f1_1)
    assert_allclose(f2, f2_1)
    assert_allclose(d1, d1_1)
    assert_allclose(d2, d2_1)
    assert_allclose(d3, d3_1)
    assert_allclose(e1, e1_1)
    assert_allclose(e2, e2_1)
    assert_allclose(e3, e3_1)

    assert_allclose(f3, np.array([0.092637, -0.245951, 0.938848]), rtol=1e-4)
    assert_allclose(g1, np.array([0.939012, 0.073416, -0.07342]), rtol=1e-4)
    assert_allclose(g2, np.array([0.055389, 1.004155, 0.257594]), rtol=1e-4)
    assert_allclose(g3, np.array([0, 0, 1.065135]), rtol=1e-4)
Esempio n. 19
0
def test_basevectors_apex_scalar():
    apex_out = Apex(date=2000, refh=300)

    (f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2,
     e3) = apex_out.basevectors_apex(0, 15, 100, coords='geo')
    (_, _, _, _, f1_1, f2_1, _, d1_1, d2_1, d3_1, _, e1_1, e2_1,
     e3_1) = apex_out._geo2apexall(0, 15, 100)

    assert_allclose(f1, f1_1)
    assert_allclose(f2, f2_1)
    assert_allclose(d1, d1_1)
    assert_allclose(d2, d2_1)
    assert_allclose(d3, d3_1)
    assert_allclose(e1, e1_1)
    assert_allclose(e2, e2_1)
    assert_allclose(e3, e3_1)

    assert_allclose(f3, np.array([0.092637, -0.245951, 0.938848]), rtol=1e-4)
    assert_allclose(g1, np.array([0.939012, 0.073416, -0.07342]), rtol=1e-4)
    assert_allclose(g2, np.array([0.055389, 1.004155, 0.257594]), rtol=1e-4)
    assert_allclose(g3, np.array([0, 0, 1.065135]), rtol=1e-4)
Esempio n. 20
0
def main():

    from argparse import ArgumentParser, RawDescriptionHelpFormatter

    # Build the argument parser tree
    parser = ArgumentParser()
    arg = parser.add_argument('radar', help='Radar name (PFISR or RISRN)')
    arg = parser.add_argument('vvels_config_file', help='Vvels config file.')
    args = vars(parser.parse_args())

    radar_name = args['radar']

    if radar_name == 'PFISR':
        # PFISR
        glat = np.arange(62., 71., 1.)
        glon = np.arange(200., 225., 3.)
    elif radar_name == 'RISRN':
        # RISRN
        glat = np.arange(73., 83., 1.)
        glon = np.arange(-110., -65., 4.)

    glat, glon = np.meshgrid(glat, glon)
    galt = np.full(glat.shape, 300.)
    glat = glat.flatten()
    glon = glon.flatten()
    galt = galt.flatten()
    field_coords = [glat, glon, galt]

    # generate radar object
    radar = Radar('{}_synth_config.ini'.format(radar_name.lower()))

    trueVe = []
    recstVe = []
    recsterr = []

    rotation_angle = np.arange(0., 360., 15.)

    # for theta in np.arange(0., 2.*np.pi, np.pi/10.):
    for theta in rotation_angle:

        if radar_name == 'PFISR':
            # Uniform magnetic field
            Ve1 = 500. * np.cos(theta * np.pi / 180.)
            Ve2 = 500. * np.sin(theta * np.pi / 180.)
            Ve3 = 0.
            A = Apex(2019)
            f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(
                glat, glon, galt)
            field_values = Ve1 * e1.T + Ve2 * e2.T + Ve3 * e3.T

        elif radar_name == 'RISRN':
            # Uniform field
            e = 500. * np.cos(theta * np.pi / 180.)
            n = 500. * np.sin(theta * np.pi / 180.)
            u = 0.
            vx, vy, vz = pm.enu2uvw(e, n, u, np.mean(glat), np.mean(glon))
            ve, vn, vu = pm.uvw2enu(vx, vy, vz, glat, glon)
            field_values = np.array([ve, vn, vu]).T

        # generate field object
        field = Field(apex_year=2019,
                      field_coords=field_coords,
                      field_values=field_values)

        # use field and radar objects to produce synthetic data set
        synth_data = SyntheticData(field, radar)

        # run resolvevectors algothrithm on synthetic data set
        rv = synth_data.eval_vvels(args['vvels_config_file'])

        targalt = 300.
        aidx = np.argmin(np.abs(rv.bin_galt[:, 0] - targalt))

        # convert bin locations to ECEF
        X, Y, Z = pm.geodetic2ecef(rv.bin_glat[aidx, :], rv.bin_glon[aidx, :],
                                   rv.bin_galt[aidx, :] * 1000.)
        # interpolate field to bin locations
        Vx = field.interpVx(np.array([X, Y, Z]).T)
        Vy = field.interpVy(np.array([X, Y, Z]).T)
        Vz = field.interpVz(np.array([X, Y, Z]).T)
        # convert field components to marp
        Ve, Vn, Vu = pm.uvw2enu(Vx, Vy, Vz, rv.bin_glat[aidx, :],
                                rv.bin_glon[aidx, :])
        d1, d2, d3, e1, e2, e3 = rv.marp.basevectors_marp(
            rv.bin_glat[aidx, :], rv.bin_glon[aidx, :], rv.bin_galt[aidx, :])
        Ve1 = np.einsum('...i,...i->...', np.array([Ve, Vn, Vu]).T, d1.T)
        Ve2 = np.einsum('...i,...i->...', np.array([Ve, Vn, Vu]).T, d2.T)
        Ve3 = np.einsum('...i,...i->...', np.array([Ve, Vn, Vu]).T, d3.T)

        trueVe.append(np.array([Ve1, Ve2, Ve3]).T)
        recstVe.append(rv.Velocity[0, :, :])
        recsterr.append(
            np.array([
                np.sqrt(rv.VelocityCovariance[0, :, i, i]) for i in range(3)
            ]).T)

    trueVe = np.array(trueVe)
    recstVe = np.array(recstVe)
    recsterr = np.array(recsterr)

    # form array of bin numbers
    bins = np.arange(len(rv.bin_glat[aidx, :])) + 1

    # create summary plot
    fig = plt.figure(figsize=(15, 10))
    gs = gridspec.GridSpec(3, 4)
    gs.update(left=0.05, right=0.95, bottom=0.05, top=0.95, hspace=0.3)

    for i in range(3):
        ax = plt.subplot(gs[i, 0])
        c = ax.pcolormesh(rotation_angle,
                          bins,
                          trueVe[:, :, i].T,
                          vmin=-500.,
                          vmax=500.,
                          cmap=plt.get_cmap('rainbow'))
        ax.set_title('True Ve{}'.format(i + 1))
        ax.set_xlabel('Rotation Angle ($^\circ$)')
        ax.set_ylabel('Bin #')
        plt.colorbar(c)

        ax = plt.subplot(gs[i, 1])
        c = ax.pcolormesh(rotation_angle,
                          bins,
                          recstVe[:, :, i].T,
                          vmin=-500.,
                          vmax=500.,
                          cmap=plt.get_cmap('rainbow'))
        ax.set_title('Reconstructed Ve{}'.format(i + 1))
        ax.set_xlabel('Rotation Angle ($^\circ$)')
        ax.set_ylabel('Bin #')
        plt.colorbar(c)

        ax = plt.subplot(gs[i, 2])
        c = ax.pcolormesh(rotation_angle,
                          bins,
                          recsterr[:, :, i].T,
                          vmin=0.,
                          vmax=100.,
                          cmap=plt.get_cmap('Reds'))
        ax.set_title('Reconstructed Ve{} Error'.format(i + 1))
        ax.set_xlabel('Rotation Angle ($^\circ$)')
        ax.set_ylabel('Bin #')
        plt.colorbar(c)

        ax = plt.subplot(gs[i, 3])
        c = ax.pcolormesh(rotation_angle,
                          bins,
                          np.abs(trueVe[:, :, i].T - recstVe[:, :, i].T),
                          vmin=0.,
                          vmax=100.,
                          cmap=plt.get_cmap('Reds'))
        ax.set_title('|True Ve{0} - Reconstructed Ve{0}|'.format(i + 1))
        ax.set_xlabel('Rotation Angle ($^\circ$)')
        ax.set_ylabel('Bin #')
        plt.colorbar(c)

    plt.show()
    def dovels(self):

        # read data
        dat1 = self.h5file.readWholeh5file()

        # output latitude
        x=np.arange(self.plats[0][0],self.plats[0][1],self.plats[0][3])[:,np.newaxis]
        PLAT_OUT=np.concatenate((x,x+self.plats[0][2]),axis=1)
        if len(self.plats[1])>0:
            x=np.arange(self.plats[1][0],self.plats[1][1],self.plats[1][3])[:,np.newaxis]
            x=np.concatenate((x,x+self.plats[1][2]),axis=1)
            PLAT_OUT=np.concatenate((PLAT_OUT,x),axis=0)

        # beamcodes
        BeamCodes=dat1['/']['BeamCodes']

        # only use beams that we were asked to use, if empty,
        # use all beams.
        num_beamcodes = BeamCodes[:,0].size
        if len(self.beams2use) > 0:
            bm_inds = list()
            available_bms = list(BeamCodes[:,0])
            for beamcode in self.beams2use:
                if beamcode in available_bms:
                    bm_inds.append(available_bms.index(beamcode))
            bm_inds = np.array(bm_inds)
        else:
            bm_inds = np.arange(0,num_beamcodes)

        BeamCodes = BeamCodes[bm_inds,:]

        if self.CorrectVap:
            IupB=np.where(BeamCodes[:,0]==upBcode)[0]
            InotUpB=np.where(BeamCodes[:,0]!=upBcode)[0]



        # geographic k vectors and locations from hdf5 file
        kn=dat1['/Geomag']['kn'][bm_inds,:]
        ke=dat1['/Geomag']['ke'][bm_inds,:]
        kz=dat1['/Geomag']['kz'][bm_inds,:]
        glat=dat1['/Geomag']['Latitude'][bm_inds,:]
        glon=dat1['/Geomag']['Longitude'][bm_inds,:]
        alt=dat1['/Geomag']['Altitude'][bm_inds,:]

        # find array shape and where nans will be removed
        arr_shape = glat.shape
        removed_nans = np.argwhere(np.isnan(glat.ravel())).flatten()

        # remove nans and flatten array
        glat = glat[np.isfinite(glat)]
        glon = glon[np.isfinite(glon)]
        alt = alt[np.isfinite(alt)]

        # intialize apex coordinates
        A = Apex(date=2019)     # date should be set by some information in data file

        # find magnetic latitude and longitude
        plat, plong = A.geo2apex(glat,glon,alt/1000.)

        # kvec in geodetic coordinates [e n u]
        kvec = np.array([ke[np.isfinite(ke)], kn[np.isfinite(kn)], kz[np.isfinite(kz)]])
        # apex basis vectors in geodetic coordinates [e n u]
        f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(glat,glon,alt)
        # find components of k for e1, e2, e3 basis vectors (Laundal and Richmond, 2016 eqn. 60)
        ke1 = np.einsum('ij,ij->j',kvec,d1)
        ke2 = np.einsum('ij,ij->j',kvec,d2)
        ke3 = np.einsum('ij,ij->j',kvec,d3)

        # reintroduce NANs and reshape the array
        # find indices where nans should be inserted in new arrays
        replace_nans = np.array([r-i for i,r in enumerate(removed_nans)])

        plat = np.insert(plat,replace_nans,np.nan).reshape(arr_shape)
        plong = np.insert(plong,replace_nans,np.nan).reshape(arr_shape)

        ke1 = np.insert(ke1,replace_nans,np.nan).reshape(arr_shape)
        ke2 = np.insert(ke2,replace_nans,np.nan).reshape(arr_shape)
        ke3 = np.insert(ke3,replace_nans,np.nan).reshape(arr_shape)

        # DON'T NEED
        # convert to magnetic NEU (approximately)
        kpe = ke1
        kpn = -ke2
        kpar = -ke3


        # geomag
        # if self.byGeo>0: # geographic
        #     kpn=dat1['/Geomag']['kn'][bm_inds,:]
        #     kpe=dat1['/Geomag']['ke'][bm_inds,:]
        #     kpar=dat1['/Geomag']['kz'][bm_inds,:]
        #     if self.byGeo==2:
        #         plat=dat1['/Geomag']['Latitude'][bm_inds,:]
        #         plong=dat1['/Geomag']['Longitude'][bm_inds,:]
        #     else:
        #         plat=dat1['/Geomag']['MagneticLatitude'][bm_inds,:]
        #         plong=dat1['/Geomag']['MagneticLongitude'][bm_inds,:]
        # else: # geomagnetic
        #     kpn=dat1['/Geomag']['kpn'][bm_inds,:]
        #     kpe=dat1['/Geomag']['kpe'][bm_inds,:]
        #     kpar=dat1['/Geomag']['kpar'][bm_inds,:]
        #     try:
        #         plat=dat1['/Geomag']['MagneticLatitude'][bm_inds,:]
        #         plong=dat1['/Geomag']['MagneticLongitude'][bm_inds,:]
        #     except:
        #         plat=dat1['/Geomag']['plat']    #???
        #         plong=dat1['/Geomag']['plong']  #???
        Bn=dat1['/Geomag']['Bx'][bm_inds,:]
        Be=dat1['/Geomag']['By'][bm_inds,:]
        Bz=dat1['/Geomag']['Bz'][bm_inds,:]
        Babs=dat1['/Geomag']['Babs'][bm_inds,:]
        Bmed = np.nanmedian(Babs)
        for i in range(Bmed.ndim):
            Bmed=np.nanmedian(Bmed)		
        self.pppE=(np.array(self.ppp).copy()).tolist(); self.pppE[0]*=Bmed; self.pppE[2]*=Bmed; self.pppE[3]*=Bmed
        self.covarE=(np.array(self.covar).copy()).tolist(); self.covarE[0]*=Bmed*Bmed; self.covarE[1]*=Bmed*Bmed; self.covarE[2]*=Bmed*Bmed

        # fitted params
        ht=dat1['/FittedParams']['Altitude'][bm_inds,:]
        vlos1=dat1['/FittedParams']['Fits'][:,bm_inds,:,0,3] + self.chirp
        vlos1 = np.swapaxes(vlos1,0,1)
        dvlos1=dat1['/FittedParams']['Errors'][:,bm_inds,:,0,3]
        dvlos1 = np.swapaxes(dvlos1,0,1)
        ne1=dat1['/FittedParams']['Ne'][:,bm_inds,:]
        
        # time
        time1=dat1['/Time']['UnixTime']
        doy1=dat1['/Time']['doy']
        dtime1=dat1['/Time']['dtime']+(doy1-doy1[0,0])*24.0
        MLT=dat1['/Time']['MagneticLocalTimeSite']
        yr=dat1['/Time']['Year']
        mon=dat1['/Time']['Month']
        day=dat1['/Time']['Day']
        
        # low densities
        I=np.where((ne1 < self.neMin))
        vlos1[I]=np.nan
        dvlos1[I]=np.nan
    
        # just do a portion of data
        if len(self.zoomWhole)!=0:
            I=np.where((dtime1[:,0]>=self.zoomWhole[0]) & (dtime1[:,1]<=self.zoomWhole[1]))[0]	
            vlos1=vlos1[I]
            dvlos1=dvlos1[I]
            time1=time1[I]
            doy1=doy1[I]		
            dtime1=dtime1[I]		
            MLT=MLT[I]
            yr=yr[I]
            mon=mon[I]
            day=day[I]
    
        # title str
        yr=yr[0,0]; mon=mon[0,0]; day=day[0,0]
        self.titleString=' %d-%d-%d' % (mon, day, yr)
    
        (Nbeams,Nhts)=ht.shape

        if self.CorrectVap:
            Nbeams=Nbeams-1
            # up B
            vlos1upB=vlos1[:,IupB[0],:]
            dvlos1upB=dvlos1[:,IupB[0],:]
            htupB=ht[IupB[0],:]
            # not
            vlos1=vlos1[:,InotUpB,:]
            dvlos1=dvlos1[:,InotUpB,:]
            ht=ht[InotUpB,:]	
            kpn=kpn[InotUpB,:]
            kpe=kpe[InotUpB,:]
            kpar=kpar[InotUpB,:]
            plat=plat[InotUpB,:]
            plong=plong[InotUpB,:]    
                  
        for itimeInt in range(len(self.Time2Integrate)):
            
            Time2Integrate = self.Time2Integrate[itimeInt]
            ofname=self.outputFnames[itimeInt]       
            
            # output arrays
            timeout=[]
            dtimeout=[]
            MLTtime1=[]
            
            done=0 # flag to say when we are done
            Irec=0 # record counter
            IIrec=0 # record counter

            while not done:
                Irecs=np.where((time1[:,0]>=time1[Irec,0]) & (time1[:,0]<=(time1[Irec,0]+Time2Integrate)))[0]

                tvlos=vlos1[Irecs,:,:]
                tdvlos=dvlos1[Irecs,:,:]
                        
                if self.CorrectVap:
                    vUpB=vlos1upB[Irecs]
                    dvUpB=dvlos1upB[Irecs]
                    for i in range(Nbeams):
                        tupB=np.interpolate.interp1d(np.squeeze(htupB),vUpB,bounds_error=0,fill_value=0.0)(ht[i,:])
                        tvlos[:,i,:]=tvlos[:,i,:]-tupB*kpar[i,:]
                        tdvlos[:,i,:]=np.sqrt(np.power(tdvlos[:,i,:],2.0)+np.power(dvUpB*kpar[i,:],2.0))
                
                # line of sight velocities and errors
                vlosin=np.reshape(np.squeeze(tvlos),(Nhts*Nbeams*len(Irecs)))
                dvlosin=np.reshape(np.squeeze(tdvlos),(Nhts*Nbeams*len(Irecs)))

                # k vector (this is in mag coords)
                kin=np.zeros((Nbeams,Nhts,3),dtype=kpn.dtype)
                # kin[:,:,0]=kpn
                # kin[:,:,1]=kpe
                # kin[:,:,2]=kpar
                kin[:,:,0]=ke1
                kin[:,:,1]=ke2
                kin[:,:,2]=ke3
                kin=np.reshape(np.repeat(kin[np.newaxis,:,:,:],len(Irecs),axis=0),(len(Irecs)*Nhts*Nbeams,3))

                # # DON'T NEED
                # ekin=np.zeros((Nbeams,Nhts,3),dtype=kpn.dtype)
                # ekin[:,:,0]=(-Be*kpar-Bz*kpe)/Babs**2.0
                # ekin[:,:,1]=(Bz*kpn+Bn*kpar)/Babs**2.0
                # ekin[:,:,2]=(Bn*kpe-Be*kpn)/Babs**2.0
                # ekin=np.reshape(np.repeat(ekin[np.newaxis,:,:,:],len(Irecs),axis=0),(len(Irecs)*Nhts*Nbeams,3))
                
                # magnetic field
                bin=np.reshape(np.repeat(Babs[np.newaxis,:,:],len(Irecs),axis=0),(len(Irecs)*Nhts*Nbeams))
                
                # mag lat and long, altitude
                platin=np.reshape(np.repeat(plat[np.newaxis,:,:],len(Irecs),axis=0),(len(Irecs)*Nhts*Nbeams))
                plongin=np.reshape(np.repeat(plong[np.newaxis,:,:],len(Irecs),axis=0),(len(Irecs)*Nhts*Nbeams))
                htin=np.reshape(np.repeat(ht[np.newaxis,:,:],len(Irecs),axis=0),(len(Irecs)*Nhts*Nbeams))

                # compute vectors
                (plat_out1,Vest,dVest,vVestAll,Nmeas,vchi2)=vvels.compute_velvec2(PLAT_OUT,vlosin,dvlosin,kin,platin,plongin,htin,htmin=self.minAlt*1000,htmax=self.maxAlt*1000,covar=self.covar,p=self.ppp)
                dVest = np.diagonal(vVestAll,axis1=1,axis2=2)

                # rotate velocity to get the elecric field
                # assume magnetic longitude of site PFISR MLON = 267.4
                plon_out1 = np.full(plat_out1.shape, 267.4)

                # find Be3 value at each output bin location
                Be3, __, __, __ = A.bvectors_apex(plat_out1,plon_out1,300.,coords='apex')
                # Be3 = np.full(plat_out1.shape,1.0)        # set Be3 array to 1.0 - useful for debugging linear algebra

                # form rotation array
                R_E = np.einsum('i,jk->ijk',Be3,np.array([[0,-1,0],[1,0,0],[0,0,0]]))
                # Calculate contravarient components of electric field (Ed1, Ed2, Ed2)
                Eest = np.einsum('ijk,ik->ij',R_E,Vest)
                # Calculate electric field covariance matrix (SigE = R_E*SigV*R_E.T)
                vEestAll = np.einsum('ijk,ikl,iml->ijm',R_E,vVestAll,R_E)
                dEest = np.diagonal(vEestAll,axis1=1,axis2=2)

                # # DON'T NEED
                # (plat_out1,Eest,dEest,vEestAll,Nmeas1,echi2)=vvels.compute_velvec2(PLAT_OUT,vlosin,dvlosin,ekin,platin,plongin,htin,htmin=self.minAlt*1000,htmax=self.maxAlt*1000,covar=self.covarE,p=self.ppp)
                # Eest[:,-1]*=-1

                timeout.append([time1[Irecs[0],0],time1[Irecs[-1],1]])
                dtimeout.append([dtime1[Irecs[0],0],dtime1[Irecs[-1],1]])
                MLTtime1.append([MLT[Irecs[0],0],MLT[Irecs[-1],1]])
                if IIrec>0:
                    while MLTtime1[IIrec][0]<MLTtime1[IIrec-1][0]:
                        MLTtime1[IIrec][0]=MLTtime1[IIrec][0]+24.0
                        MLTtime1[IIrec][1]=MLTtime1[IIrec][1]+24.0

                if IIrec==0:
                    vvels1=Vest[np.newaxis,:,:]
                    dvvels1=dVest[np.newaxis,:,:]
                    varvvels1=vVestAll[np.newaxis,:,:,:]
                    Nall1=Nmeas[np.newaxis,:]
                    chi2 = vchi2[np.newaxis,:]
                    evec1=Eest[np.newaxis,:,:]
                    devec1=dEest[np.newaxis,:,:]
                    varevec1=vEestAll[np.newaxis,:,:,:]
                else:
                    vvels1=np.concatenate((vvels1,Vest[np.newaxis,:,:]),axis=0)
                    dvvels1=np.concatenate((dvvels1,dVest[np.newaxis,:,:]),axis=0)
                    varvvels1=np.concatenate((varvvels1,vVestAll[np.newaxis,:,:,:]),axis=0)
                    Nall1=np.concatenate((Nall1,Nmeas[np.newaxis,:]),axis=0)
                    chi2 = np.concatenate((chi2,vchi2[np.newaxis,:]),axis=0)
                    evec1=np.concatenate((evec1,Eest[np.newaxis,:,:]),axis=0)
                    devec1=np.concatenate((devec1,dEest[np.newaxis,:,:]),axis=0)
                    varevec1=np.concatenate((varevec1,vEestAll[np.newaxis,:,:,:]),axis=0)

                Irec=Irecs[-1]+1 # increment counters
                IIrec=IIrec+1

                if Irec>=time1.shape[0]:
                    done=1



            MLTtime1=np.array(MLTtime1)
            timeout=np.array(timeout)
            dtimeout=np.array(dtimeout)
            
            # magnitude and direction
            Vmag = np.sqrt( np.power(vvels1[:,:,0],2.0) + np.power(vvels1[:,:,1],2.0) ).real
            dVmag = np.sqrt( np.power(dvvels1[:,:,0],2.0)*np.power(vvels1[:,:,0]/Vmag,2.0) + np.power(dvvels1[:,:,1],2.0)*np.power(vvels1[:,:,1]/Vmag,2.0) ).real
            Vdir = 180.0/np.pi*np.arctan2(vvels1[:,:,1],vvels1[:,:,0]).real
            dVdir = 180.0/np.pi*((1.0/np.absolute(vvels1[:,:,0]))*(1.0/(1.0+np.power(vvels1[:,:,1]/vvels1[:,:,0],2.0)))*np.sqrt(np.power(dvvels1[:,:,1],2.0)+np.power(vvels1[:,:,1]/vvels1[:,:,0]*dvvels1[:,:,0],2.0))).real		
            
            Emag = np.sqrt( np.power(evec1[:,:,0],2.0) + np.power(evec1[:,:,1],2.0) ).real
            dEmag = np.sqrt( np.power(devec1[:,:,0],2.0)*np.power(evec1[:,:,0]/Emag,2.0) + np.power(devec1[:,:,1],2.0)*np.power(evec1[:,:,1]/Emag,2.0) ).real
            Edir = 180.0/np.pi*np.arctan2(evec1[:,:,1],evec1[:,:,0]).real
            dEdir = 180.0/np.pi*((1.0/np.absolute(evec1[:,:,0]))*(1.0/(1.0+np.power(evec1[:,:,1]/evec1[:,:,0],2.0)))*np.sqrt(np.power(devec1[:,:,1],2.0)+np.power(evec1[:,:,1]/evec1[:,:,0]*devec1[:,:,0],2.0))).real		
            
            ### Set up output dicts
            self.setOutDicts(dat1)
            self.Params['IntegrationTime']=Time2Integrate
            # Time
            self.Time['UnixTime'] = timeout
            self.Time['dtime'] = dtimeout
            self.Time['MagneticLocalTime'] = MLTtime1
            # Vector Vels
            if self.byGeo==2:
                self.VectorVels['Latitude']=PLAT_OUT
                self.VectorVels['MagneticLatitude']=[]
            else:
                self.VectorVels['Latitude']=[]
                self.VectorVels['MagneticLatitude']=PLAT_OUT
            self.VectorVels['Nmeas'] = Nall1.astype('int32')
            self.VectorVels['Chi2'] = chi2
            self.VectorVels['Vest'] = vvels1; self.VectorVels['errVest'] = dvvels1
            self.VectorVels['varVest'] = varvvels1
            self.VectorVels['Vmag'] = Vmag; self.VectorVels['errVmag'] = dVmag
            self.VectorVels['Vdir'] = Vdir; self.VectorVels['errVdir'] = dVdir
            self.VectorVels['Eest'] = evec1; self.VectorVels['errEest'] = devec1
            self.VectorVels['varEest'] = varevec1
            self.VectorVels['Emag'] = Emag; self.VectorVels['errEmag'] = dEmag
            self.VectorVels['Edir'] = Edir; self.VectorVels['errEdir'] = dEdir

            self.Output['Velocity'] = vvels1
            self.Output['ElectricField'] = evec1
            self.Output['SigV'] = varvvels1
            self.Output['SigE'] = varevec1
            self.Output['MLAT'] = plat_out1
            self.Output['MLON'] = plon_out1
            
            ### Output file
            if self.saveout:
                self.createOutputFile(ofname)
                
            ### Plot output
            if self.makeplot:            
                if (timeout[-1,-1]-timeout[0,0])/3600.0>36.0:
                    self.createPlots_byTime(ofname,binByDay=1)
                else:
                    self.createPlots(ofname)

            self.create_new_output('test_vvels.h5',vvels1,varvvels1,evec1,varevec1)        
        
        return
# glon = np.arange(-110., -65., 4.)

glat, glon = np.meshgrid(glat, glon)
galt = np.full(glat.shape, 300.)
glat = glat.flatten()
glon = glon.flatten()
galt = galt.flatten()
coords = [glat.tolist(), glon.tolist(), galt.tolist()]

print('field_coords = ', coords)

# Uniform field with only a Ve1 component
Ve1 = 500.
Ve2 = 0.
Ve3 = 0.
A = Apex(2019)
f1, f2, f3, g1, g2, g3, d1, d2, d3, e1, e2, e3 = A.basevectors_apex(
    glat, glon, galt)
Vgd = Ve1 * e1.T + Ve2 * e2.T + Ve3 * e3.T
Vgd = Vgd.tolist()

# # Uniform geodetic East
# Vgd = np.tile([0., 500., 0.], (len(galt),1)).tolist()

# # Roughly uniform field
# vx, vy, vz = pm.enu2uvw(500., 0., 0., np.mean(glat), np.mean(glon))
# ve, vn, vu = pm.uvw2enu(vx, vy, vz, glat, glon)
# Vgd = np.array([ve, vn, vu]).T.tolist()

print('field_values = ', Vgd)