Exemplo n.º 1
0
def ne2xy_converter(stn, dt, nan=True, elevation=None):
    """ ??? """
    station_info = STATION_MAP[stn.upper()]
    lat = station_info.glat
    lon = station_info.glon
    point = Point(dt, lat, lon, elevation / 1e3 if elevation else 0)
    point.run_igrf()
    dec_deg = point.dec
    logger.info('using declination angle {:f} (deg) for {}'.format(
        dec_deg, stn))
    dec_rad = math.radians(dec_deg)
    cos_dec = math.cos(dec_rad)
    sin_dec = math.sin(dec_rad)

    def ne2xy(n, e):
        if n in [88888, 99999] or e in [88888, 99999]:
            if nan:
                return NP.nan, NP.nan
            else:
                return 88888, 88888
        x = cos_dec * n - sin_dec * e
        y = sin_dec * n + cos_dec * e
        return x, y

    return ne2xy
Exemplo 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
Exemplo n.º 3
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
Exemplo n.º 4
0
def get_B(pos):
    """
    Use pyglow to get IGRF magnetic field
    in ECEF coordinates
    """
    lat_lon_h = jcoord.ecef2geodetic(pos[0], pos[1], pos[2])
    pt = Point(datetime.datetime(2000, 1, 1, 1, 0), lat_lon_h[0], lat_lon_h[1],
               lat_lon_h[2] / 1e3)
    pt.run_igrf()
    Bxyz = jcoord.enu2ecef(lat_lon_h[0], lat_lon_h[1], lat_lon_h[2], pt.Bx,
                           pt.By, pt.Bz)
    return (Bxyz)
Exemplo 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
Exemplo n.º 6
0
def get_dec_tenths_arcminute(header, date):
    """
    Return the local magnetic declination angle associated with a
    sensor at the location given in *header* and *date*. The returned
    angle is in tenths of arcminutes (there are 360 * 60 * 10 tenths
    of arcminnutes in one circle).
    """
    point = Point(date, header['Geodetic Latitude'],
                  header['Geodetic Longitude'], header['Elevation'])
    point.run_igrf()
    dec_deg = point.dec
    if 'IAGA CODE' in header:
        logger.info('using declination angle {:f} (deg) for {}'.format(
            dec_deg, header['IAGA CODE']))
    else:
        logger.info('using declination angle {:f} (deg)'.format(dec_deg))
    return fix_sign(deg2tenths_of_arcminute(dec_deg))
Exemplo n.º 7
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
Exemplo n.º 8
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)
Exemplo n.º 9
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
Exemplo n.º 10
0
def main():
    s1 = datetime.utcnow()
    dn = datetime(2011, 3, 23, 9, 30)
    lat = 0.
    lon = -80.
    alt = 250.00, 300.00

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

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

    print("v1993\nu: {}     v: {}\n".format(pt.u, pt.v))
    print("v2007\nu: {}     v: {}\n".format(pt2.u, pt2.v))
    print("v2014\nu: {}     v: {}\n".format(pt3.u, pt3.v))
    print('\n\n{}'.format(datetime.utcnow() - s1))
Exemplo n.º 11
0
def ne2xy_converter(stn, dt, nan=True, elevation=None):
    """ ??? """
    station_info = STATION_MAP[stn.upper()]
    lat = station_info.glat
    lon = station_info.glon
    point = Point(dt, lat, lon, elevation / 1e3 if elevation else 0)
    point.run_igrf()
    dec_deg = point.dec
    dec_rad = math.radians(dec_deg)
    cos_dec = math.cos(dec_rad)
    sin_dec = math.sin(dec_rad)

    def ne2xy(n, e):
        if n in [88888, 99999] or e in [88888, 99999]:
            if nan:
                return NP.nan, NP.nan
            else:
                return 88888, 88888
        x = cos_dec * n - sin_dec * e
        y = sin_dec * n + cos_dec * e
        return x, y

    return ne2xy
Exemplo n.º 12
0
def normalize_rho(orbitfile, lat, lon, alt, rho, base_alt):
    """
    Uses the MSIS empirical model to return the helium and total mass density in an array

    Arguments:
        orbitfile:  the filename of the DE-2 orbit
        lat     :  array of latitudes  [deg]
        long    :  array of longitudes [deg]
        alt     :  array of altitudes above body surface [km]
        rho     :  array of unnormalized number density values for helium (1/cm^3)
        base_alt:  the fixed altitude to normalize density value

    Returns:
        rho_matrix  : a 2Xn matrix of normalized number densities at the fixed "base altitude" and the expected MSIS value
                      densites are first row - i.e. rho_matrix[0:all]
                      MSIS expected values are second row - i.e. rho_matrix[1:all]
    """
    species = whatplot
    rho_norm = np.zeros(len(rho))
    rho_MSIS_fixed, rho_MSIS_vary = np.zeros(len(rho)), np.zeros(len(rho))
    ratio = np.zeros(len(rho))
    date = make_date(orbitfile)

    for i in range(0, len(rho)):
        # MSIS Point objects - pt1 = fixed alt, pt2 = variable alt
        pt1 = Point(date, lat[i], lon[i], base_alt)
        pt2 = Point(date, lat[i], lon[i], alt[i])

        result1, result2 = pt1.run_msis(), pt2.run_msis(
        )  # call MSIS for these Point objects
        rho_MSIS_fixed[i] = result1.nn[species]  # particles/cm^3
        rho_MSIS_vary[i] = result2.nn[species]
        ratio[i] = rho_MSIS_fixed[i] / rho_MSIS_vary[i]
        rho_norm[i] = rho[i] * ratio[i]

    plt.subplot(211)
    plt.title(filenames[j])
    plt.plot(alt, rho_MSIS_fixed, label='MSIS rho fixed')
    plt.plot(alt, rho_MSIS_vary, label='MSIS rho vary')
    plt.plot(alt, rho, label='rho')
    plt.plot(alt, rho_norm, label='rho norm')

    plt.legend(loc=1)
    plt.ylabel(whatplot + ' Density 1/cm^3')
    plt.ticklabel_format(axis='y', style='sci', scilimits=(0, 0))
    plt.grid()

    plt.subplot(212)
    plt.plot(alt, ratio)
    plt.xlabel('Altitude')
    plt.ylabel(r'Ratio MSIS $\rho(z_0))/ \rho(z)$')
    plt.minorticks_on()
    plt.grid()
    plt.show()

    rho_matrix = np.array([rho_norm, rho_MSIS_fixed])
    return rho_matrix  # return both so you can plot
Exemplo n.º 13
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
Exemplo n.º 14
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'
    }
Exemplo n.º 15
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)
Exemplo n.º 16
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)
Exemplo n.º 17
0
                    lat[k] = float(line.split(delimiter)[i])
                elif i == 5:
                    long[k] = float(line.split(delimiter)[i])
                elif i == 6:
                    LST[k] = float(line.split(delimiter)[i])
                else:
                    continue
            k += 1  # only increment k once per two lines
        counter += 1
    fread.close()

    # Get MSIS temperature data
    if add_MSIS:
        date = make_date(filenames[j])
        for i in range(0, len(temp)):
            pt = Point(date, lat[i], long[i], alt[i])
            result = pt.run_msis()  # call MSIS for these Point objects
            temp_MSIS[i] = result.Tn_msis

    # plt the data....

    print('Done reading files. Plotting...')

    plt.title('DE2 Orbit 1614 - LT 19.0')
    plt.scatter(lat, temp, marker='.', label='DE-2')
    if add_MSIS:
        plt.scatter(lat, temp_MSIS, marker='.', label='MSIS')
    plt.ylabel('Neutral Temperature [K]')
    plt.xlabel('Latitude [deg]')
    plt.legend()
    #plt.ylim([850, 1425])
Exemplo n.º 18
0
def create_point(dn, lat, lon, alt, ver):
    pt = Point(dn, lat, lon, alt)

    pt.run_hwm(version=ver)

    print("v{}\nu: {}     v: {}\n".format(ver, pt.u, pt.v))
Exemplo n.º 19
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
Exemplo n.º 20
0
def add_igrf(inst, glat_label='glat', glong_label='glong', alt_label='alt'):
    """ 
    Uses International Geomagnetic Reference Field (IGRF) model to obtain geomagnetic field values.
    
    Uses pyglow module to run IGRF. 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_igrf, '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 HWM winds.
        'B' total geomagnetic field
        'B_east' Geomagnetic field component along east/west directions (+ east)
        'B_north' Geomagnetic field component along north/south directions (+ north)
        'B_up' Geomagnetic field component along up/down directions (+ up)
        'B_ecef_x' Geomagnetic field component along ECEF x
        'B_ecef_y' Geomagnetic field component along ECEF y
        'B_ecef_z' Geomagnetic field component along ECEF z
        
    """

    import pyglow
    from pyglow.pyglow import Point
    import pysatMagVect

    igrf_params = []
    # print 'IRI Simulations'
    for time, lat, lon, alt in zip(inst.data.index, inst[glat_label],
                                   inst[glong_label], inst[alt_label]):
        pt = Point(time, lat, lon, alt)
        pt.run_igrf()
        igrf = {}
        igrf['B'] = pt.B
        igrf['B_east'] = pt.Bx
        igrf['B_north'] = pt.By
        igrf['B_up'] = pt.Bz
        igrf_params.append(igrf)
    # print 'Complete.'
    igrf = pds.DataFrame(igrf_params)
    igrf.index = inst.data.index
    inst[igrf.keys()] = igrf

    # convert magnetic field in East/north/up to ECEF basis
    x, y, z = pysatMagVect.enu_to_ecef_vector(inst['B_east'], inst['B_north'],
                                              inst['B_up'], inst[glat_label],
                                              inst[glong_label])
    inst['B_ecef_x'] = x
    inst['B_ecef_y'] = y
    inst['B_ecef_z'] = z

    # metadata
    inst.meta['B'] = {
        'units': 'nT',
        'desc': 'Total geomagnetic field from IGRF.'
    }
    inst.meta['B_east'] = {
        'units':
        'nT',
        'desc':
        'Geomagnetic field from IGRF expressed using the East/North/Up (ENU) basis.'
    }
    inst.meta['B_north'] = {
        'units':
        'nT',
        'desc':
        'Geomagnetic field from IGRF expressed using the East/North/Up (ENU) basis.'
    }
    inst.meta['B_up'] = {
        'units':
        'nT',
        'desc':
        'Geomagnetic field from IGRF expressed using the East/North/Up (ENU) basis.'
    }

    inst.meta['B_ecef_x'] = {
        'units':
        'nT',
        'desc':
        'Geomagnetic field from IGRF expressed using the Earth Centered Earth Fixed (ECEF) basis.'
    }
    inst.meta['B_ecef_y'] = {
        'units':
        'nT',
        'desc':
        'Geomagnetic field from IGRF expressed using the Earth Centered Earth Fixed (ECEF) basis.'
    }
    inst.meta['B_ecef_z'] = {
        'units':
        'nT',
        'desc':
        'Geomagnetic field from IGRF expressed using the Earth Centered Earth Fixed (ECEF) basis.'
    }
    return
Exemplo n.º 21
0
    # run_parallel()

    # JMAX = 121
    # DEN_I = np.zeros((JMAX))

    dn = datetime(2015, 10, 23, 21, 0)
    msis_alt = 335.
    msis_lat = 0.
    msis_lon = -40.

    # dn = datetime(2011, 3, 23, 9, 30)
    # msis_lat = 0.
    # msis_lon = -80.
    # msis_alt = 250.

    # Criando o Point do PyGlow
    # Criando o Point do PyGlow
    print('criando ponto')
    ponto = Point(dn, msis_lat, msis_lon, msis_alt)
    print('rodando igrf')
    ponto.run_igrf()
    print('rodando hwm')
    ponto.run_hwm93()
    print(ponto.u, ponto.v)
    print('rodando msis')
    ponto.run_msis()
    print(ponto.Tn_msis, np.float64(ponto.nn['O']), np.float64(ponto.nn['O2']), np.float64(ponto.nn['N2']))

    # from pyglow.pyglow import update_indices
    # update_indices([2012, 2016])  # grabs indices for 2012 and 2013
Exemplo n.º 22
0
O1 = np.zeros(len(m))
Hp_mbar = np.zeros(len(m))
Hp_he = np.zeros(len(m))
Hp_n2 = np.zeros(len(m))
Hp_o1 = np.zeros(len(m))

k = 1.3806 * 10**(-23)  #Boltzmann's constant
g0 = 9.81  #m/s^2
R = 6373  #Radius of earth in km
Av = 6.022141 * 10**23  #Avogadro's Constant
n = 0
rho = np.zeros(len(m))

#Iterate through altitudes in range m
for x in m:
    pt = Point(dn, lat, lon, x)
    result = pt.run_msis()
    #Knudsen number estimate
    n_dens_tot = result.nn['HE']+result.nn['N2']+result.nn['O2'] \
        +result.nn['AR']+result.nn['H']+result.nn['O']+result.nn['N']# number density per cm^3

    g = g0 * R**2 / (R + x)**2
    m_dens1 = (result.nn['HE']*.004003/Av+result.nn['N2']*.0280134/Av\
    +result.nn['O2']*.032/Av+result.nn['AR']*.039948/Av+result.nn['N']\
    *.01401/Av+result.nn['H']*.001/Av+result.nn['O']*.016/Av)#kg/cm^3

    Mbar[n] = m_dens1 * Av * 1000 / (n_dens_tot)  #kg/kmol
    Tn[n] = result.Tn_msis

    #Follows form of kT/mg for pressure scale height
    Hp_mbar[n] = k * Tn[n] / (Mbar[n] * g) * Av
Exemplo n.º 23
0
    return x_star


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')
Exemplo n.º 24
0
    # Parametros PyGlow
    versao_hwm = 1993   # Ano da versao do HWM
    dn = datetime(2015, 10, 23, 21)
    lon = 0

    msis_alt = 335.0
    msis_lat = 0
    msis_lon = -40.0

    F0F2 = leitores.leitor_frequencia_fof2(os.getcwd() + "/inputs/input-foF2.dat")
    EE0 = leitores.leitor_campo_eletrico_zonal("inputs/input-vz.dat")
    UX, UYZ = leitores.leitor_vento_termosferico("inputs/input-wind.dat")

    # Criando o Point do PyGlow
    ponto = Point(dn, msis_lat, msis_lon, msis_alt)
    ponto.run_msis()

    # Definindo parametros da malha
    IMAX = NY           # Contador en la horizontal
    JMAX = NZ           # Contador en la vertical
    DY = 5.0            # Paso en Longitud  [km]
    DZ = 5.0            # Paso en altura    [km]
    DTT = 10.0          # Paso en tiempo    [s]
    UT0 = 21.666        # Tiempo inicial en UT = 21:40

    # Parametros da regiao F
    HB = 200.0              # Altura base da regiao F [km]
    RK1 = 4.0E-11           # Recombinacion [O+] con [O2]
    RK2 = 1.3E-12           # Recombinacion [O+] con [N2]
    # TN = 1200.4             # Temperatura neutra exosferica
Exemplo n.º 25
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
Exemplo n.º 26
0
# To begin, lets first create a Point object from Jan 1st, 2000.

#-------------- Variables to change ---------------

date = datetime(2000, 1, 1, 0, 0)               # (yr, month, day, hour, minute) - refer to datetime module online
latitude = 45
longitude = 90
altitude = 400

#--------------------------------------------------

# for now we will not deal with inputting our out geophys indices, so we let the Point obj do this for us.
# Now make the Point object!

new_pt = Point(date, latitude, longitude, altitude)

# from this new_pt Point object, we can run MSIS (or anything else in the Point class).

result = new_pt.run_msis()          # result now contains the neutral temp, number densities (given in the run_msis fuction)
                                    # and total number density for the specific variables given above
'''
check them out...
which neutral species do you what to look at? 
Can be: 
HE, O, N2, O2, AR, H, N, O_anomalous, or rho (total number density) 

Or:
Tn_msis (neutral temperature [K])
'''
Exemplo n.º 27
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
Exemplo n.º 28
0
T2 = np.zeros(len(m))
M2 = np.zeros(len(m))
Kn1 = np.zeros(len(m))  #Knudsen number for characteristic length
Kn2 = np.zeros(len(m))
Kn1At = np.zeros(len(m))  #Atmospheric knudsen number
Kn2At = np.zeros(len(m))
k = 1.3806 * 10**(-23)  #Boltzmann's constant
g0 = 9.81  #m/s^2
R = 6373  #Radius of earth in km
Av = 6.022141 * 10**23  #Avogadro's Constant
n = 0
rho = np.zeros(len(m))

#Iterate through altitudes in range m
for x in m:
    pt = Point(dn, lat, lon, x)
    pt2 = Point(dn2, lat, lon, x)
    result = pt.run_msis()
    result2 = pt2.run_msis()

    #Knudsen number estimate
    n_dens_tot = result.nn['HE']+result.nn['N2']+result.nn['O2'] \
        +result.nn['AR']+result.nn['H']+result.nn['O']+result.nn['N']# number density per cm^3

    d_avg = (result.nn['HE']/n_dens_tot*260+result.nn['N2']/n_dens_tot*364\
        +result.nn['O2']/n_dens_tot*346+result.nn['AR']/n_dens_tot*340)\
        *10**(-12)+(result.nn['H']+result.nn['O']+result.nn['N'])/n_dens_tot*5.046*10**(-10)# average kinetic diameter of
    # molecules in atmosphere. Note H and O are ignored due to no data on
    # their kinetic diameters and the breakdown of the model with ions
    # (hard sphere collisions of molecules)
    lam = 1 / (math.sqrt(2) * math.pi * d_avg**2 * n_dens_tot * 10**(6))
Exemplo n.º 29
0
def add_msis(inst, glat_label='glat', glong_label='glong', alt_label='alt'):
    """ 
    Uses MSIS model to obtain thermospheric values.
    
    Uses pyglow module to run MSIS. 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_msis, '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 MSIS values winds.
        'Nn' total neutral density particles/cm^3
        'Nn_N' Nitrogen number density (particles/cm^3)
        'Nn_N2' N2 number density (particles/cm^3)
        'Nn_O' Oxygen number density (particles/cm^3)
        'Nn_O2' O2 number density (particles/cm^3)
        'Tn_msis' Temperature from MSIS (Kelvin)
        
    """

    import pyglow
    from pyglow.pyglow import Point

    msis_params = []
    # print 'IRI Simulations'
    for time, lat, lon, alt in zip(inst.data.index, inst[glat_label],
                                   inst[glong_label], inst[alt_label]):
        pt = Point(time, lat, lon, alt)
        pt.run_msis()
        msis = {}
        total = 0
        for key in pt.nn.keys():
            total += pt.nn[key]
        msis['Nn'] = total
        msis['Nn_N'] = pt.nn['N']
        msis['Nn_N2'] = pt.nn['N2']
        msis['Nn_O'] = pt.nn['O']
        msis['Nn_O2'] = pt.nn['O2']
        msis['Tn_msis'] = pt.Tn_msis
        msis_params.append(msis)
    # print 'Complete.'
    msis = pds.DataFrame(msis_params)
    msis.index = inst.data.index
    inst[msis.keys()] = msis

    # metadata
    inst.meta['Nn'] = {
        'units': 'cm^-3',
        'desc': 'Total neutral number particle density from MSIS.'
    }
    inst.meta['Nn_N'] = {
        'units': 'cm^-3',
        'desc': 'Total nitrogen number particle density from MSIS.'
    }
    inst.meta['Nn_N2'] = {
        'units': 'cm^-3',
        'desc': 'Total N2 number particle density from MSIS.'
    }
    inst.meta['Nn_O'] = {
        'units': 'cm^-3',
        'desc': 'Total oxygen number particle density from MSIS.'
    }
    inst.meta['Nn_O2'] = {
        'units': 'cm^-3',
        'desc': 'Total O2 number particle density from MSIS.'
    }
    inst.meta['Tn_msis'] = {
        'units': 'K',
        'desc': 'Neutral temperature from MSIS.'
    }

    return
Exemplo n.º 30
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()
Exemplo n.º 31
0
'''
testing out the different 'version' keywords
'''
from datetime import datetime, timedelta
from pyglow.pyglow import Point

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)
Exemplo n.º 32
0
def plot_indices(d1,
                 d2,
                 fig=None,
                 style='display',
                 bar_lw=0.2,
                 dst_lw=1.75,
                 edgecolor=(0.1, 0.1, 0.1),
                 title_dt_format='%Y-%m-%d %H:%M',
                 stats=False):
    """
    """
    # gather Kp
    kp = []
    kp_dt = []
    for dt in PD.date_range(d1, d2, freq='3H'):
        point = Point(dt, 0, 0, 0)
        kp.append(point.kp)
        kp_dt.append(dt)
    # gather Dst
    dst = []
    dst_dt = []
    for dt in PD.date_range(d1, d2, freq='1H'):
        point = Point(dt, 0, 0, 0)
        dst.append(point.dst)
        dst_dt.append(dt)
    # create plot
    N_days = (dst_dt[-1] - dst_dt[0]).total_seconds() / 60 / 60 / 24
    if fig is None:
        fig = PL.figure(figsize=(11 * N_days / 6, 5))
    kp_colors, kp_hatch = STYLE_MAP[style]
    # Kp subplot
    ax1 = PL.subplot(111)
    left = NP.array(kp_dt) - timedelta(hours=1.5)
    width = 3 / 24
    height = kp
    color = [kp_colors[int(math.floor(x))] for x in kp]
    hatch = [kp_hatch[int(math.floor(x))] if kp_hatch else None for x in kp]
    left = [x.to_pydatetime() for x in left]
    bars = PL.bar(left,
                  height,
                  width=width,
                  color=color,
                  linewidth=bar_lw,
                  edgecolor=[edgecolor] * len(left))
    for bar, hatch_i in zip(bars, hatch):
        bar.set_hatch(hatch_i)
    ax1.xaxis_date()
    PL.ylim(0, 9)
    PL.xlabel('UT')
    PL.ylabel('3-hour Kp index')
    # Dst subplot
    ax2 = ax1.twinx()
    PL.plot_date(dst_dt, dst, lw=dst_lw, marker=None, ls='-')
    PL.ylabel('Hourly DST [nT]')
    d1_str = datetime.strftime(dst_dt[0], title_dt_format)
    d2_str = datetime.strftime(dst_dt[-1], title_dt_format)
    title = 'GFZ $K_p$ and Dst Indices, {} to {}'.format(d1_str, d2_str)
    PL.title(title)
    if stats:
        index_stats = IndexStats(Stats(*kp), Stats(*dst))
        return index_stats, fig, ax1, ax2
    else:
        return fig, ax1, ax2
#==============================================================================

#Load magnetic equator data points to be overlayed on plot
mag_equator = np.loadtxt("Magnetic_equator_lat_lon.txt", delimiter=',')
top = mag_equator[180:360, :]
bottom = mag_equator[0:180, :]
mag_equator = np.concatenate((top, bottom), axis=0)

data = np.zeros((120, 240))
marklon = 0

#Loop through lat and lon. select what MSIS values are desired
for Lon in range(-120, 120, 1):
    marklat = 0
    for Lat in range(-60, 60, 1):
        pt = Point(dn, Lat * 1.5, Lon * 1.5, 400)  #1.5 degree grid size
        pt.f107a = 180
        pt.f107p = 180  # previous day's F10.7
        pt.apmsis = [
            0,
        ] * 7
        result = pt.run_msis()

        #data[marklat,marklon] = math.log10((result.nn['HE']*4/Av)/(result.rho-result.nn['HE']*4/Av),10) #Derived helium
        if whatplot == 'He':
            data[marklat, marklon] = result.nn[
                'HE'] * .004003 / Av * 10**6  # MSIS helium (Should be the same as derived)
        elif whatplot == 'Temp':
            data[marklat, marklon] = result.Tn_msis  #Neutral Temperature
        else:
            print('Bad Plot input')
Exemplo n.º 34
0
from pyglow.pyglow import Point

# 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]')
Exemplo n.º 35
0
    return x_star


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',
Exemplo n.º 36
0
dn = datetime(1992, 3, 20, 0, 2)#year,month,day,hour,minute
Av = 6.022141*10**23
#==============================================================================
# pt = Point(dn, lat, lon, 400)
# result = pt.run_msis()
# print pt
# print result.f107
#==============================================================================

data = np.zeros(121)
marklon = 0
latitudes = range(-60,61,1)

#Run MSIS for range of latitudes
for Lat in range(-60,61,1) :
    pt = Point(dn, Lat, lon, 400)
    result = pt.run_msis()
    data[marklon] = result.Tn_msis
    marklon = marklon+1

f=result.f107
fa=result.f107a
apmsis=result.apmsis

#Plot the data
fig = plt.figure()
plt.plot(latitudes,data)
plt.title('Temperature ETA MSIS lon=%.1f UT=0.03 F10.7=%.1f'%(lon,f),fontweight='bold')
plt.ylabel('Neutral Temperature (K)')
plt.xlabel('Latitude')