Esempio n. 1
0
 def fun(pos):
     llh = pos.llh
     point = Point(dt, llh[0], llh[1], llh[2] / 1e3)
     point.run_iri()
     if point.ne < 0:
         logger.warning('negative IRI Ne detected (h={:.1f} [km])'.format(llh[2] / 1e3))
         return 0
     else:
         return point.ne / 1e7
Esempio n. 2
0
 def fun(pos):
     llh = pos.llh
     point = Point(dt, llh[0], llh[1], llh[2] / 1e3)
     point.run_iri()
     if point.ne < 0:
         logger.warning('negative IRI Ne detected (h={:.1f} [km])'.format(
             llh[2] / 1e3))
         return 0
     else:
         return point.ne / 1e7
Esempio n. 3
0
def main2():
    dn = datetime(2011, 3, 23, 9, 30)
    lat = 0.
    lon = -80.
    alt = 250.

    pt = Point(dn, lat, lon, alt)
    pt.run_igrf()
    pt.run_hwm93()
    pt.run_msis()
    pt.run_iri()

    print pt
    print pt.nn
    print pt.Tn_msis
Esempio n. 4
0
def pyglowinput(
        latlonalt=[65.1367, -147.4472, 250.00],
        dn_list=[datetime(2015, 3, 21, 8, 00),
                 datetime(2015, 3, 21, 20, 00)],
        z=None):

    if z is None:
        z = sp.linspace(50., 1000., 200)
    dn_diff = sp.diff(dn_list)
    dn_diff_sec = dn_diff[-1].seconds
    timelist = sp.array([calendar.timegm(i.timetuple()) for i in dn_list])
    time_arr = sp.column_stack((timelist, sp.roll(timelist, -1)))
    time_arr[-1, -1] = time_arr[-1, 0] + dn_diff_sec

    v = []
    coords = sp.column_stack((sp.zeros((len(z), 2), dtype=z.dtype), z))
    all_spec = ['O+', 'NO+', 'O2+', 'H+', 'HE+']
    Param_List = sp.zeros((len(z), len(dn_list), len(all_spec), 2))
    for idn, dn in enumerate(dn_list):
        for iz, zcur in enumerate(z):
            latlonalt[2] = zcur
            pt = Point(dn, *latlonalt)
            pt.run_igrf()
            pt.run_msis()
            pt.run_iri()

            # so the zonal pt.u and meriodinal winds pt.v  will coorispond to x and y even though they are
            # supposed to be east west and north south. Pyglow does not seem to have
            # vertical winds.
            v.append([pt.u, pt.v, 0])

            for is1, ispec in enumerate(all_spec):
                Param_List[iz, idn, is1, 0] = pt.ni[ispec] * 1e6

            Param_List[iz, idn, :, 1] = pt.Ti

            Param_List[iz, idn, -1, 0] = pt.ne * 1e6
            Param_List[iz, idn, -1, 1] = pt.Te
    Param_sum = Param_List[:, :, :, 0].sum(0).sum(0)
    spec_keep = Param_sum > 0.
    species = sp.array(all_spec)[spec_keep[:-1]].tolist()
    species.append('e-')
    Param_List[:, :] = Param_List[:, :, spec_keep]
    Iono_out = IonoContainer(coords,
                             Param_List,
                             times=time_arr,
                             species=species)
    return Iono_out
Esempio n. 5
0
def calculate_delay(
    time,
    lat,
    lon,
    frequency,
    elevation,
):
    '''TODO: Docstring
    '''

    if Point is None or gcoord is None:
        raise ImportError('pyglow must be installed to calculate delay')

    if not isinstance(time, Time):
        dn = time
    else:
        dn = time.tt.datetime

    num = 500
    alts = np.linspace(0, 4000, num=num)
    distance = np.linspace(0, 4000, num=num)
    ne = np.zeros(num)
    xyz_prev = 0.0
    for ai, a in enumerate(alts):
        llh = coord.az_el_r2geodetic(lat, lon, 0, 180.0, elevation, a * 1e3)

        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            ne[ai] = pt.ne * 1e6
        else:
            ne[ai] = 0.0
        xyz = gcoord.lla2ecef(np.array([lat, lon, a]))[0]
        if ai == 0:
            distance[ai] = 0.0
        else:
            distance[ai] = np.sqrt(np.dot(xyz - xyz_prev,
                                          xyz - xyz_prev)) + distance[ai - 1]
        xyz_prev = xyz

    f_p = 8.98 * np.sqrt(ne)
    v_g = constants.c * np.sqrt(1 - (f_p / frequency)**2.0)

    dt2 = integrate.simps(1.0 - 1.0 / (np.sqrt(1 - (f_p / frequency)**2.0)),
                          distance * 1e3) / constants.c

    return dt2, ne, distance
Esempio n. 6
0
def get_delay(dn=datetime(2016, 3, 23, 00, 00),
              f=233e6,
              lat=e3d._tx[0].lat,
              lon=e3d._tx[0].lon,
              elevation=30.0,
              plot=False):

    np = 500
    alts = n.linspace(0, 4000, num=np)
    distance = n.linspace(0, 4000, num=np)
    ne = n.zeros(np)
    xyz_prev = 0.0
    for ai, a in enumerate(alts):
        llh = coord.az_el_r2geodetic(lat, lon, 0, 180.0, elevation, a * 1e3)
        #        print(llh[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            ne[ai] = pt.ne * 1e6
        else:
            ne[ai] = 0.0
        xyz = gcoord.lla2ecef(n.array([lat, lon, a]))[0]
        if ai == 0:
            distance[ai] = 0.0
        else:
            distance[ai] = n.sqrt(n.dot(xyz - xyz_prev,
                                        xyz - xyz_prev)) + distance[ai - 1]
        xyz_prev = xyz

    f_p = 8.98 * n.sqrt(ne)
    v_g = c.c * n.sqrt(1 - (f_p / f)**2.0)

    dt2 = si.simps(1.0 - 1.0 / (n.sqrt(1 -
                                       (f_p / f)**2.0)), distance * 1e3) / c.c

    if plot:
        print("ionospheric delay (s)")
        print(dt2)
        plt.plot(ne, distance)
        plt.ylabel("Distance (km)")
        plt.xlabel("$N_e$ ($m^{-3}$)")
        plt.show()
    return (dt2, ne, distance)
Esempio n. 7
0
def pyglowinput(latlonalt=[65.1367, -147.4472, 250.00], dn_list=[datetime(2015, 3, 21, 8, 00), datetime(2015, 3, 21, 20, 00)], z=None):


    if z is None:
        z = sp.linspace(50., 1000., 200)
    dn_diff = sp.diff(dn_list)
    dn_diff_sec = dn_diff[-1].seconds
    timelist = sp.array([calendar.timegm(i.timetuple()) for i in dn_list])
    time_arr = sp.column_stack((timelist, sp.roll(timelist, -1)))
    time_arr[-1, -1] = time_arr[-1, 0]+dn_diff_sec

    v=[]
    coords = sp.column_stack((sp.zeros((len(z), 2), dtype=z.dtype), z))
    all_spec = ['O+', 'NO+', 'O2+', 'H+', 'HE+']
    Param_List = sp.zeros((len(z), len(dn_list),len(all_spec),2))
    for idn, dn in enumerate(dn_list):
        for iz, zcur in enumerate(z):
            latlonalt[2] = zcur
            pt = Point(dn, *latlonalt)
            pt.run_igrf()
            pt.run_msis()
            pt.run_iri()

            # so the zonal pt.u and meriodinal winds pt.v  will coorispond to x and y even though they are
            # supposed to be east west and north south. Pyglow does not seem to have
            # vertical winds.
            v.append([pt.u, pt.v, 0])

            for is1, ispec in enumerate(all_spec):
                Param_List[iz, idn, is1, 0] = pt.ni[ispec]*1e6

            Param_List[iz, idn, :, 1] = pt.Ti

            Param_List[iz, idn, -1, 0] = pt.ne*1e6
            Param_List[iz, idn, -1, 1] = pt.Te
    Param_sum = Param_List[:, :, :, 0].sum(0).sum(0)
    spec_keep = Param_sum > 0.
    species = sp.array(all_spec)[spec_keep[:-1]].tolist()
    species.append('e-')
    Param_List[:, :] = Param_List[:, :, spec_keep]
    Iono_out = IonoContainer(coords, Param_List, times = time_arr, species=species)
    return Iono_out
Esempio n. 8
0
def add_iri_thermal_plasma(inst,
                           glat_label='glat',
                           glong_label='glong',
                           alt_label='alt'):
    """ 
    Uses IRI (International Reference Ionosphere) model to simulate an ionosphere.
    
    Uses pyglow module to run IRI. Configured to use actual solar parameters to run 
    model.
    
    Example
    -------
        # function added velow modifies the inst object upon every inst.load call
        inst.custom.add(add_iri_thermal_plasma, 'modify', glat_label='custom_label')
    
    Parameters
    ----------
    inst : pysat.Instrument
        Designed with pysat_sgp4 in mind
    glat_label : string
        label used in inst to identify WGS84 geodetic latitude (degrees)
    glong_label : string
        label used in inst to identify WGS84 geodetic longitude (degrees)
    alt_label : string
        label used in inst to identify WGS84 geodetic altitude (km, height above surface)
        
    Returns
    -------
    inst
        Input pysat.Instrument object modified to include thermal plasma parameters.
        'ion_temp' for ion temperature in Kelvin
        'e_temp' for electron temperature in Kelvin
        'ion_dens' for the total ion density (O+ and H+)
        'frac_dens_o' for the fraction of total density that is O+
        'frac_dens_h' for the fraction of total density that is H+
        
    """

    import pyglow
    from pyglow.pyglow import Point

    iri_params = []
    # print 'IRI Simulations'
    for time, lat, lon, alt in zip(inst.data.index, inst[glat_label],
                                   inst[glong_label], inst[alt_label]):
        # Point class is instantiated. Its parameters are a function of time and spatial location
        pt = Point(time, lat, lon, alt)
        pt.run_iri()
        iri = {}
        # After the model is run, its members like Ti, ni[O+], etc. can be accessed
        iri['ion_temp'] = pt.Ti
        iri['e_temp'] = pt.Te
        iri['ion_dens'] = pt.ni['O+'] + pt.ni['H+'] + pt.ni[
            'HE+']  #pt.ne - pt.ni['NO+'] - pt.ni['O2+'] - pt.ni['HE+']
        iri['frac_dens_o'] = pt.ni['O+'] / iri['ion_dens']
        iri['frac_dens_h'] = pt.ni['H+'] / iri['ion_dens']
        iri['frac_dens_he'] = pt.ni['HE+'] / iri['ion_dens']
        iri_params.append(iri)
    # print 'Complete.'
    iri = pds.DataFrame(iri_params)
    iri.index = inst.data.index
    inst[iri.keys()] = iri

    inst.meta['ion_temp'] = {'units': 'Kelvin', 'long_name': 'Ion Temperature'}
    inst.meta['ion_dens'] = {
        'units': 'N/cc',
        'long_name': 'Ion Density',
        'desc': 'Total ion density including O+ and H+ from IRI model run.'
    }
    inst.meta['frac_dens_o'] = {
        'units': '',
        'long_name': 'Fractional O+ Density'
    }
    inst.meta['frac_dens_h'] = {
        'units': '',
        'long_name': 'Fractional H+ Density'
    }
Esempio n. 9
0
def ray_trace(dn=datetime(2016, 6, 21, 12, 00),
              f=233e6,
              lat=e3d._tx[0].lat,
              lon=e3d._tx[0].lon,
              elevation=30.0,
              az=180.0,
              fpref="",
              plot=False):

    np = 1000
    alts = n.linspace(0, 4000, num=np)
    distance = n.linspace(0, 4000, num=np)
    ne = n.zeros(np)
    ne2 = n.zeros(np)
    dnex = n.zeros(np)
    dtheta = n.zeros(np)
    dalt = n.zeros(np)
    dney = n.zeros(np)
    dnez = n.zeros(np)
    xyz_prev = 0.0
    px = n.zeros(np)
    dk = n.zeros(np)
    py = n.zeros(np)
    pz = n.zeros(np)
    p0x = n.zeros(np)
    p0y = n.zeros(np)
    p0z = n.zeros(np)

    # initial direction and position
    k = coord.azel_ecef(lat, lon, 10e3, az, elevation)
    k0 = k
    p = coord.geodetic2ecef(lat, lon, 10e3)
    pe = coord.geodetic2ecef(lat, lon, 10e3)
    p0 = coord.geodetic2ecef(lat, lon, 10e3)
    dh = 4e3
    vg = 1.0

    p_orig = p
    ray_time = 0.0

    for ai, a in enumerate(alts):
        p = p + k * dh * vg
        p0 = p0 + k0 * dh
        ray_time += dh / c.c

        dpx = p + n.array([1.0, 0.0, 0.0]) * dh
        dpy = p + n.array([0.0, 1.0, 0.0]) * dh
        dpz = p + n.array([0.0, 0.0, 1.0]) * dh

        llh = coord.ecef2geodetic(p[0], p[1], p[2])
        llh_1 = coord.ecef2geodetic(p0[0], p0[1], p0[2])
        dalt[ai] = llh_1[2] - llh[2]

        if llh[2] / 1e3 > 1900:
            break
        alts[ai] = llh[2] / 1e3
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            ne[ai] = pt.ne * 1e6
            f_p = 8.98 * n.sqrt(ne[ai])
            v_g = n.sqrt(1.0 - (f_p / f)**2.0)
        else:
            ne[ai] = 0.0

        llh = coord.ecef2geodetic(dpx[0], dpx[1], dpx[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dnex[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dnex[ai] = 0.0

        llh = coord.ecef2geodetic(dpy[0], dpy[1], dpy[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dney[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dney[ai] = 0.0

        llh = coord.ecef2geodetic(dpz[0], dpz[1], dpz[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dnez[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dnez[ai] = 0.0
        grad = n.array([dnex[ai], dney[ai], dnez[ai]])
        px[ai] = p[0]
        py[ai] = p[1]
        pz[ai] = p[2]
        p0x[ai] = p0[0]
        p0y[ai] = p0[1]
        p0z[ai] = p0[2]
        #        print(ai)
        dk[ai] = n.arccos(
            n.dot(k0, k) / (n.sqrt(n.dot(k0, k0)) * n.sqrt(n.dot(k, k))))
        # no bending if gradient too small
        if n.dot(grad, grad) > 100.0:
            grad1 = grad / n.sqrt(n.dot(grad, grad))

            p2 = p + k * dh
            llh = coord.ecef2geodetic(p2[0], p2[1], p2[2])
            pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
            pt.run_iri()
            if pt.ne > 0.0:
                ne2 = pt.ne * 1e6
            else:
                ne2 = 0.0
            f0 = 8.98 * n.sqrt(ne[ai])
            n0 = n.sqrt(1.0 - (f0 / f)**2.0)
            f1 = 8.98 * n.sqrt(ne2)
            n1 = n.sqrt(1.0 - (f1 / f)**2.0)

            theta0 = n.arccos(
                n.dot(grad, k) /
                (n.sqrt(n.dot(grad, grad)) * n.sqrt(n.dot(k, k))))
            # angle cannot be over 90
            if theta0 > n.pi / 2.0:
                theta0 = n.pi - theta0
            sin_theta_1 = (n0 / n1) * n.sin(theta0)
            dtheta[ai] = 180.0 * n.arcsin(
                sin_theta_1) / n.pi - 180.0 * theta0 / n.pi
            #            print("n0/n1 %1.10f theta0 %1.2f theta1-theta0 %1.10f"%(n0/n1,180.0*theta0/n.pi,dtheta[ai]))
            cos_theta_1 = n.sqrt(1.0 - sin_theta_1**2.0)
            k_ref = (n0 / n1) * k + (
                (n0 / n1) * n.cos(theta0) - cos_theta_1) * grad1
            # normalize
            k_ref / n.sqrt(n.dot(k_ref, k_ref))
            k = k_ref

            angle = n.arccos(
                n.dot(grad, k) / n.sqrt(n.dot(grad, grad)) *
                n.sqrt(n.dot(k, k)))

    los_time = n.sqrt(n.dot(p_orig - p, p_orig - p)) / c.c
    excess_ionospheric_delay = ray_time - los_time
    print("Excess propagation time %1.20f mus" % ((1e6 *
                                                   (ray_time - los_time))))

    theta = n.arccos(
        n.dot(k0, k) / (n.sqrt(n.dot(k0, k0)) * n.sqrt(n.dot(k, k))))

    theta_p = n.arccos(
        n.dot(p0, p) / (n.sqrt(n.dot(p0, p0)) * n.sqrt(n.dot(p, p))))

    llh0 = coord.ecef2geodetic(px[ai - 2], py[ai - 2], pz[ai - 2])
    llh1 = coord.ecef2geodetic(p0x[ai - 2], p0y[ai - 2], p0z[ai - 2])
    print("d_coord")
    print(llh0 - llh1)
    if plot:
        print(p0 - p)
        print(180.0 * theta_p / n.pi)
        fig = plt.figure(figsize=(14, 8))
        plt.clf()
        plt.subplot(131)
        plt.title("Elevation=%1.0f" % (elevation))
        plt.plot(n.sqrt((p0x - px)**2.0 + (p0y - py)**2.0 + (p0z - pz)**2.0),
                 alts,
                 label="Total error")
        plt.plot(dalt, alts, label="Altitude error")
        plt.ylim([0, 1900])
        #        plt.xlim([-50,800.0])
        plt.grid()
        plt.legend()
        plt.xlabel("Position error (m)")
        plt.ylabel("Altitude km")

        plt.subplot(132)
        plt.plot(dtheta * 1e6, alts)
        #        plt.plot(1e6*180.0*dk/n.pi,alts)
        plt.xlabel("Ray-bending ($\mu$deg/km)")
        plt.ylabel("Altitude km")
        plt.title("Total error=%1.2g (deg)" % (180.0 * theta_p / n.pi))
        plt.ylim([0, 1900])
        plt.subplot(133)
        plt.plot(ne, alts)
        plt.xlabel("$N_{\mathrm{e}}$ ($\mathrm{m}^{-3}$)")
        plt.ylabel("Altitude km")
        plt.ylim([0, 1900])
        #    ax.plot(px,py,pz)
        plt.tight_layout()
        plt.savefig("ref-%s-%d-%d.png" % (fpref, f / 1e6, elevation))
        plt.close()

    return (p0, p, 180.0 * theta_p / n.pi, excess_ionospheric_delay)
Esempio n. 10
0
def ray_trace_error(dn=datetime(2016, 6, 21, 12, 00),
                    f=233e6,
                    lat=e3d._tx[0].lat,
                    lon=e3d._tx[0].lon,
                    elevation=30.0,
                    az=180.0,
                    fpref="",
                    ionosphere=False,
                    error_std=0.05,
                    plot=False):

    np = 2000
    alts = n.repeat(1e99, np)
    distance = n.linspace(0, 4000, num=np)
    ne = n.zeros(np)
    ne2 = n.zeros(np)
    dtheta = n.zeros(np)
    dalt = n.zeros(np)
    dnex = n.zeros(np)
    dney = n.zeros(np)
    dnez = n.zeros(np)
    xyz_prev = 0.0
    dk = n.zeros(np)
    px = n.zeros(np)
    py = n.zeros(np)
    pz = n.zeros(np)
    t_vec = n.zeros(np)
    t_i_vec = n.zeros(np)
    k_vecs = []
    # initial direction and position
    k = coord.azel_ecef(lat, lon, 10e3, az, elevation)
    k0 = k
    p = coord.geodetic2ecef(lat, lon, 10e3)
    dh = 4e3
    dt = 20e-6
    # correlated errors std=1, 100 km correlation length
    scale_length = 40.0
    ne_errors_x = n.convolve(
        n.repeat(1.0 / n.sqrt(scale_length), scale_length),
        n.random.randn(10000))
    ne_errors_y = n.convolve(
        n.repeat(1.0 / n.sqrt(scale_length), scale_length),
        n.random.randn(10000))
    ne_errors_z = n.convolve(
        n.repeat(1.0 / n.sqrt(scale_length), scale_length),
        n.random.randn(10000))

    p_orig = p
    ray_time = 0.0
    v_c = c.c
    for ai, a in enumerate(alts):
        # go forward in time
        dhp = v_c * dt
        p = p + k * dhp
        ray_time += dt
        print(ray_time * 1e6)
        t_vec[ai + 1] = dt
        k_vecs.append(k)

        dpx = p + n.array([1.0, 0.0, 0.0]) * dh
        dpy = p + n.array([0.0, 1.0, 0.0]) * dh
        dpz = p + n.array([0.0, 0.0, 1.0]) * dh

        llh = coord.ecef2geodetic(p[0], p[1], p[2])

        if llh[2] / 1e3 > 2100:
            break
        alts[ai] = llh[2] / 1e3
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            ne[ai] = pt.ne * (1.0 + error_std * ne_errors_x[ai]) * 1e6
            if ionosphere:
                f0 = 8.98 * n.sqrt(ne[ai])
                f_p = 8.98 * n.sqrt(ne[ai])
                # update group velocity
                v_c = c.c * n.sqrt(1.0 - (f0 / f)**2.0)
        else:
            ne[ai] = 0.0

        llh = coord.ecef2geodetic(dpx[0], dpx[1], dpx[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dnex[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dnex[ai] = 0.0

        llh = coord.ecef2geodetic(dpy[0], dpy[1], dpy[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dney[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dney[ai] = 0.0

        llh = coord.ecef2geodetic(dpz[0], dpz[1], dpz[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dnez[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dnez[ai] = 0.0

        grad = n.array([dnex[ai], dney[ai], dnez[ai]])

        px[ai] = p[0]
        py[ai] = p[1]
        pz[ai] = p[2]

        dk[ai] = n.arccos(
            n.dot(k0, k) / (n.sqrt(n.dot(k0, k0)) * n.sqrt(n.dot(k, k))))
        # no bending if gradient too small
        if n.dot(grad, grad) > 100.0 and ionosphere:
            grad1 = grad / n.sqrt(n.dot(grad, grad))

            p2 = p + k * dh
            llh = coord.ecef2geodetic(p2[0], p2[1], p2[2])
            pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
            pt.run_iri()
            if pt.ne > 0.0:
                ne2 = pt.ne * (1.0 + error_std * ne_errors_x[ai]) * 1e6
            else:
                ne2 = 0.0
            f0 = 8.98 * n.sqrt(ne[ai])
            n0 = n.sqrt(1.0 - (f0 / f)**2.0)
            f1 = 8.98 * n.sqrt(ne2)
            n1 = n.sqrt(1.0 - (f1 / f)**2.0)

            theta0 = n.arccos(
                n.dot(grad, k) /
                (n.sqrt(n.dot(grad, grad)) * n.sqrt(n.dot(k, k))))
            # angle cannot be over 90
            if theta0 > n.pi / 2.0:
                theta0 = n.pi - theta0
            sin_theta_1 = (n0 / n1) * n.sin(theta0)
            dtheta[ai] = 180.0 * n.arcsin(
                sin_theta_1) / n.pi - 180.0 * theta0 / n.pi
            #            print("n0/n1 %1.10f theta0 %1.2f theta1-theta0 %1.10f"%(n0/n1,180.0*theta0/n.pi,dtheta[ai]))
            cos_theta_1 = n.sqrt(1.0 - sin_theta_1**2.0)
            k_ref = (n0 / n1) * k + (
                (n0 / n1) * n.cos(theta0) - cos_theta_1) * grad1
            # normalize
            k_ref / n.sqrt(n.dot(k_ref, k_ref))
            k = k_ref

            angle = n.arccos(
                n.dot(grad, k) / n.sqrt(n.dot(grad, grad)) *
                n.sqrt(n.dot(k, k)))

    return (t_vec, px, py, pz, alts, ne, k_vecs)
Esempio n. 11
0
'''

from pyglow.pyglow import Point
from datetime import datetime
import matplotlib.pyplot as plt
import numpy as np

lat = 0 # Geographic Latitude
alt = 590 # Altitude
lons = np.arange(0, 360) # Longitudes

dn = datetime(2004, 9, 21, 1, 0) # 1 UT

Te = np.empty(len(lons))

for i, lon in enumerate(lons):
    pt = Point(dn, lat, lon, alt)
    pt.run_iri()
    Te[i] = pt.Te

plt.plot(lons, Te, 'k')
plt.title('Electron Temperatures')
plt.xlabel('Longitude, Degree')
plt.ylabel('Te, K')
plt.ylim(500, 3000)
plt.xlim(0, 400)
plt.xticks([0, 100, 200, 300, 400])
plt.grid()

plt.show()
dn = datetime(2010, 3, 23, 15, 30)
lat = 40.
lon = -80.
alt = 250.

pt = Point(dn, lat, lon, alt)

pt.run_hwm93()
pt.run_hwm07()
pt.run_hwm14()

pt.run_hwm(version=1993)
pt.run_hwm(version=2007)
pt.run_hwm(version=2014)
pt.run_hwm()

pt.run_msis()
pt.run_msis(version=2000)

pt.run_igrf()
pt.run_igrf(version=2011)

pt.run_iri()
pt.run_iri(version=2016)
pt.run_iri(version=2012)

try:
    pt.run_iri(version=2020)  # should fail
except ValueError as e:
    print("Caught an exception: %s" % e)
Esempio n. 13
0
def ray_trace(
    time,
    lat,
    lon,
    frequency,
    elevation,
    azimuth,
):
    '''TODO: Docstring
    '''

    if Point is None or gcoord is None:
        raise ImportError('pyglow must be installed to ray trace')

    if not isinstance(time, Time):
        dn = time
    else:
        dn = time.tt.datetime

    num = 1000
    alts = np.linspace(0, 4000, num=num)
    distance = np.linspace(0, 4000, num=num)
    ne = np.zeros(num)
    ne2 = np.zeros(num)
    dnex = np.zeros(num)
    dtheta = np.zeros(num)
    dalt = np.zeros(num)
    dney = np.zeros(num)
    dnez = np.zeros(num)
    xyz_prev = 0.0
    px = np.zeros(num)
    dk = np.zeros(num)
    py = np.zeros(num)
    pz = np.zeros(num)
    p0x = np.zeros(num)
    p0y = np.zeros(num)
    p0z = np.zeros(num)

    # initial direction and position
    k = frames.azel_to_ecef(lat, lon, 10e3, azimuth, elevation)
    k0 = k
    p = frames.geodetic_to_ITRS(lat, lon, 10e3)
    pe = frames.geodetic_to_ITRS(lat, lon, 10e3)
    p0 = frames.geodetic_to_ITRS(lat, lon, 10e3)
    dh = 4e3
    vg = 1.0

    p_orig = p
    ray_time = 0.0

    for ai, a in enumerate(alts):
        p = p + k * dh * vg
        p0 = p0 + k0 * dh
        ray_time += dh / constants.c

        dpx = p + np.array([1.0, 0.0, 0.0]) * dh
        dpy = p + np.array([0.0, 1.0, 0.0]) * dh
        dpz = p + np.array([0.0, 0.0, 1.0]) * dh

        llh = frames.ITRS_to_geodetic(p[0], p[1], p[2])
        llh_1 = frames.ITRS_to_geodetic(p0[0], p0[1], p0[2])
        dalt[ai] = llh_1[2] - llh[2]

        if llh[2] / 1e3 > 1900:
            break
        alts[ai] = llh[2] / 1e3
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            ne[ai] = pt.ne * 1e6
            f_p = 8.98 * np.sqrt(ne[ai])
            v_g = np.sqrt(1.0 - (f_p / frequency)**2.0)
        else:
            ne[ai] = 0.0

        llh = frames.ITRS_to_geodetic(dpx[0], dpx[1], dpx[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dnex[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dnex[ai] = 0.0

        llh = frames.ITRS_to_geodetic(dpy[0], dpy[1], dpy[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dney[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dney[ai] = 0.0

        llh = frames.ITRS_to_geodetic(dpz[0], dpz[1], dpz[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()
        if pt.ne > 0.0:
            dnez[ai] = (ne[ai] - pt.ne * 1e6) / dh
        else:
            dnez[ai] = 0.0
        grad = np.array([dnex[ai], dney[ai], dnez[ai]])
        px[ai] = p[0]
        py[ai] = p[1]
        pz[ai] = p[2]
        p0x[ai] = p0[0]
        p0y[ai] = p0[1]
        p0z[ai] = p0[2]

        dk[ai] = np.arccos(
            np.dot(k0, k) / (np.sqrt(np.dot(k0, k0)) * np.sqrt(np.dot(k, k))))
        # no bending if gradient too small
        if np.dot(grad, grad) > 100.0:
            grad1 = grad / np.sqrt(np.dot(grad, grad))

            p2 = p + k * dh
            llh = frames.ITRS_to_geodetic(p2[0], p2[1], p2[2])
            pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
            pt.run_iri()
            if pt.ne > 0.0:
                ne2 = pt.ne * 1e6
            else:
                ne2 = 0.0
            f0 = 8.98 * np.sqrt(ne[ai])
            n0 = np.sqrt(1.0 - (f0 / frequency)**2.0)
            f1 = 8.98 * np.sqrt(ne2)
            n1 = np.sqrt(1.0 - (f1 / frequency)**2.0)

            theta0 = np.arccos(
                np.dot(grad, k) /
                (np.sqrt(np.dot(grad, grad)) * np.sqrt(np.dot(k, k))))
            # angle cannot be over 90
            if theta0 > np.pi / 2.0:
                theta0 = np.pi - theta0
            sin_theta_1 = (n0 / n1) * np.sin(theta0)
            dtheta[ai] = 180.0 * np.arcsin(
                sin_theta_1) / np.pi - 180.0 * theta0 / np.pi
            #print("n0/n1 %1.10f theta0 %1.2f theta1-theta0 %1.10f"%(n0/n1,180.0*theta0/np.pi,dtheta[ai]))
            cos_theta_1 = np.sqrt(1.0 - sin_theta_1**2.0)
            k_ref = (n0 / n1) * k + (
                (n0 / n1) * np.cos(theta0) - cos_theta_1) * grad1
            # normalize
            k_ref / np.sqrt(np.dot(k_ref, k_ref))
            k = k_ref

            angle = np.arccos(
                np.dot(grad, k) / np.sqrt(np.dot(grad, grad)) *
                np.sqrt(np.dot(k, k)))

    los_time = np.sqrt(np.dot(p_orig - p, p_orig - p)) / constants.c
    excess_ionospheric_delay = ray_time - los_time

    # print("Excess propagation time %1.20f mus"%((1e6*(ray_time-los_time))))

    theta = np.arccos(
        np.dot(k0, k) / (np.sqrt(np.dot(k0, k0)) * np.sqrt(np.dot(k, k))))

    theta_p = np.arccos(
        np.dot(p0, p) / (np.sqrt(np.dot(p0, p0)) * np.sqrt(np.dot(p, p))))

    llh0 = frames.ITRS_to_geodetic(px[ai - 2], py[ai - 2], pz[ai - 2])
    llh1 = frames.ITRS_to_geodetic(p0x[ai - 2], p0y[ai - 2], p0z[ai - 2])

    # print("d_coord")
    # print(llh0-llh1)

    ret = dict(
        px=px,
        py=py,
        pz=pz,
        p0x=p0x,
        p0y=p0y,
        p0z=p0z,
        ray_bending=dtheta,
        electron_density=ne,
        altitudes=alts,
        altitude_errors=dalt,
        excess_ionospheric_delay=excess_ionospheric_delay,
        total_angle_error=180.0 * theta_p / np.pi,
        p_end=p,
        p0_end=p0,
    )

    return ret
Esempio n. 14
0
def ray_trace_error(
    time,
    lat,
    lon,
    frequency,
    elevation,
    azimuth,
    ionosphere=False,
    error_std=0.05,
):
    '''TODO: Docstring
    '''

    if Point is None or gcoord is None:
        raise ImportError('pyglow must be installed to ray trace')

    if not isinstance(time, Time):
        dn = time
    else:
        dn = time.tt.datetime

    num = 2000
    alts = np.repeat(1e99, num)
    distance = np.linspace(0, 4000, num=num)
    ne = np.zeros(num)
    ne2 = np.zeros(num)
    dtheta = np.zeros(num)
    dalt = np.zeros(num)
    dnex = np.zeros(num)
    dney = np.zeros(num)
    dnez = np.zeros(num)
    xyz_prev = 0.0
    dk = np.zeros(num)
    px = np.zeros(num)
    py = np.zeros(num)
    pz = np.zeros(num)
    t_vec = np.zeros(num)
    t_i_vec = np.zeros(num)
    k_vecs = []
    # initial direction and position
    k = frames.azel_to_ecef(lat, lon, 10e3, az, elevation)
    k0 = k
    p = frames.geodetic_to_ITRS(lat, lon, 10e3)
    dh = 4e3
    dt = 20e-6
    # correlated errors std=1, 100 km correlation length
    scale_length = 40.0
    ne_errors_x = np.convolve(
        np.repeat(1.0 / np.sqrt(scale_length), scale_length),
        np.random.randn(10000))
    ne_errors_y = np.convolve(
        np.repeat(1.0 / np.sqrt(scale_length), scale_length),
        np.random.randn(10000))
    ne_errors_z = np.convolve(
        np.repeat(1.0 / np.sqrt(scale_length), scale_length),
        np.random.randn(10000))

    p_orig = p
    ray_time = 0.0
    v_c = constants.c
    for ai, a in enumerate(alts):
        # go forward in time
        dhp = v_c * dt
        p = p + k * dhp
        ray_time += dt
        print(ray_time * 1e6)
        t_vec[ai + 1] = dt
        k_vecs.append(k)

        dpx = p + np.array([1.0, 0.0, 0.0]) * dh
        dpy = p + np.array([0.0, 1.0, 0.0]) * dh
        dpz = p + np.array([0.0, 0.0, 1.0]) * dh

        llh = frames.ITRS_to_geodetic(p[0], p[1], p[2])

        if llh[2] / 1e3 > 2100:
            break
        alts[ai] = llh[2] / 1e3
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            ne[ai] = pt.ne * (1.0 + error_std * ne_errors_x[ai]) * 1e6
            if ionosphere:
                f0 = 8.98 * np.sqrt(ne[ai])
                f_p = 8.98 * np.sqrt(ne[ai])
                # update group velocity
                v_c = constants.c * np.sqrt(1.0 - (f0 / frequency)**2.0)
        else:
            ne[ai] = 0.0

        llh = frames.ITRS_to_geodetic(dpx[0], dpx[1], dpx[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dnex[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dnex[ai] = 0.0

        llh = frames.ITRS_to_geodetic(dpy[0], dpy[1], dpy[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dney[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dney[ai] = 0.0

        llh = frames.ITRS_to_geodetic(dpz[0], dpz[1], dpz[2])
        pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
        pt.run_iri()

        if pt.ne > 0.0:
            dnez[ai] = (ne[ai] - pt.ne *
                        (1.0 + error_std * ne_errors_x[ai]) * 1e6) / dh
        else:
            dnez[ai] = 0.0

        grad = np.array([dnex[ai], dney[ai], dnez[ai]])

        px[ai] = p[0]
        py[ai] = p[1]
        pz[ai] = p[2]

        dk[ai] = np.arccos(
            np.dot(k0, k) / (np.sqrt(np.dot(k0, k0)) * np.sqrt(np.dot(k, k))))
        # no bending if gradient too small
        if np.dot(grad, grad) > 100.0 and ionosphere:
            grad1 = grad / np.sqrt(np.dot(grad, grad))

            p2 = p + k * dh
            llh = frames.ITRS_to_geodetic(p2[0], p2[1], p2[2])
            pt = Point(dn, llh[0], llh[1], llh[2] / 1e3)
            pt.run_iri()
            if pt.ne > 0.0:
                ne2 = pt.ne * (1.0 + error_std * ne_errors_x[ai]) * 1e6
            else:
                ne2 = 0.0
            f0 = 8.98 * np.sqrt(ne[ai])
            n0 = np.sqrt(1.0 - (f0 / frequency)**2.0)
            f1 = 8.98 * np.sqrt(ne2)
            n1 = np.sqrt(1.0 - (f1 / frequency)**2.0)

            theta0 = np.arccos(
                np.dot(grad, k) /
                (np.sqrt(np.dot(grad, grad)) * np.sqrt(np.dot(k, k))))
            # angle cannot be over 90
            if theta0 > np.pi / 2.0:
                theta0 = np.pi - theta0
            sin_theta_1 = (n0 / n1) * np.sin(theta0)
            dtheta[ai] = 180.0 * np.arcsin(
                sin_theta_1) / np.pi - 180.0 * theta0 / np.pi
            #            print("n0/n1 %1.10f theta0 %1.2f theta1-theta0 %1.10f"%(n0/n1,180.0*theta0/np.pi,dtheta[ai]))
            cos_theta_1 = np.sqrt(1.0 - sin_theta_1**2.0)
            k_ref = (n0 / n1) * k + (
                (n0 / n1) * np.cos(theta0) - cos_theta_1) * grad1
            # normalize
            k_ref / np.sqrt(np.dot(k_ref, k_ref))
            k = k_ref

            angle = np.arccos(
                np.dot(grad, k) / np.sqrt(np.dot(grad, grad)) *
                np.sqrt(np.dot(k, k)))

    return t_vec, px, py, pz, alts, ne, k_vecs
Esempio n. 15
0
# Inputs:
lat = 40.
lon = -80.
alt = 250.
alts = np.linspace(100., 500., 101)
dn = datetime(2015, 3, 23, 15, 30)

ne_2012 = []
ne_2016 = []

# Calculate for both IRI model year 2012 and 2016:
for alt in alts:
    print "Computing alt=%3.1f km..." % (alt)
    pt = Point(dn, lat, lon, alt)

    pt.run_iri()  # default year is 2016
    ne_2016.append(pt.ne)

    pt.run_iri(version=2012)  # Can revert back to 2012 model, if necessary.
    ne_2012.append(pt.ne)

# Plot
plt.figure(1)
plt.clf()
plt.semilogx(ne_2016, alts, 'bo-', label='IRI Model Year: 2016')
plt.semilogx(ne_2012, alts, 'r.--', label='IRI Model Year: 2012')
plt.grid()
plt.xlabel(r'$n_e$ [cm$^{-3}$]')
plt.ylabel('Altitude [km]')
plt.title('%s UT, lat=%3.1f$^\circ$, lon=%3.1f$^\circ$' %\
        (dn.strftime('%Y-%m-%d %H:%M:%S'), lat, lon))
Esempio n. 16
0
from pyglow.pyglow import Point
from datetime import datetime

dn = datetime(2011, 3, 23, 9, 30)
lat = 0.
lon = -80.
alt = 250.

pt = Point(dn, lat, lon, alt)

print "Before running any models:"
print pt

pt.run_igrf()
pt.run_hwm93()
pt.run_msis()
pt.run_iri()

print "After running models:"
print pt
Esempio n. 17
0

if __name__ == '__main__':
    from pyglow.pyglow import Point

    N = 200
    alt = NP.linspace(100, 1500, N)

    dt = datetime(2000, 1, 1)
    lat = 0
    lon = 0

    iri_ne = []
    for alt_i in alt:
        point = Point(dt, lat, lon, alt_i)
        point.run_iri()
        iri_ne.append(point.ne)

    Nm_star, Hm_star, H_O_star = chapman_fit(alt, iri_ne, verbose=True)

    chapman_ne = [chapman(z, Nm_star, Hm_star, H_O_star) for z in alt]

    fig = PL.figure(figsize=(6,10))
    PL.plot(iri_ne,
            alt,
            color='b',
            label='IRI')
    PL.plot(chapman_ne,
            alt,
            color='g',
            label='Chapman fit')
Esempio n. 18
0

if __name__ == '__main__':
    from pyglow.pyglow import Point

    N = 200
    alt = NP.linspace(100, 1500, N)

    dt = datetime(2000, 1, 1)
    lat = 0
    lon = 0

    iri_ne = []
    for alt_i in alt:
        point = Point(dt, lat, lon, alt_i)
        point.run_iri()
        iri_ne.append(point.ne)

    Nm_star, Hm_star, H_O_star = chapman_fit(alt, iri_ne, verbose=True)

    chapman_ne = [chapman(z, Nm_star, Hm_star, H_O_star) for z in alt]

    fig = PL.figure(figsize=(6, 10))
    PL.plot(iri_ne, alt, color='b', label='IRI')
    PL.plot(chapman_ne, alt, color='g', label='Chapman fit')
    PL.legend()
    PL.xlabel('Electron density [cm$^{-3}$]')
    PL.ylabel('Height [km]')
    PL.ticklabel_format(style='sci', axis='x', scilimits=(0, 0))
    PL.axis('tight')