Пример #1
0
def density_lookup(year, month, day, hour, altitude, glat, glon):
    """
    Function: density_lookup

    Gets atmospheric density using MSISE-00 atmospheric model.
    Must have https://pypi.org/project/msise00/ library installed.

    Inputs:
        year
        month
        day
        hour
        altitude (km)
        glat: geodetic latitude
        glon: geodetic longitude

    Outputs:
        rho: atmospheric density (kg/m^3)
    """
    atmos = msise00.run(time=datetime(year, month, day, hour),
                        altkm=altitude,
                        glat=glat,
                        glon=glon)
    rho = atmos.Total.values[0].item()
    return rho
Пример #2
0
def msise00_model(alt, datetime_obj):
	atmos = msise00.run(time=datetime_obj, altkm=alt/1000, glat=65., glon=-148.)
	r = D(atmos['Total'].values[0,0,0,0])			# Denisty (kg/m^3)
	T = D(atmos['Tn'].values[0,0,0,0])				# Temperature (K)
	p = r*D(0.2869)*T								# Pressure (kPa)

	return [T-D(273.15), p, r]						# Return C, kPa, kg/m^3
Пример #3
0
def test_forecast():
    t = datetime(2023, 3, 31, 12)
    altkm = 150.0
    glat = 65.0
    glon = -148.0

    atmos = msise00.run(t, altkm, glat, glon)

    assert atmos["He"].ndim == 4
    assert atmos["He"].size == 1
    dims = list(atmos.dims)
    assert ["alt_km", "lat", "lon", "time"] == dims

    assert atmos["He"].item() == approx(4.3926901e12)
    assert atmos["O"].item() == approx(4.5728936e15)
    assert atmos["N2"].item() == approx(3.7001117e16)
    assert atmos["O2"].item() == approx(8.1215314e15)
    assert atmos["Ar"].item() == approx(3.3594181e14)
    assert atmos["Total"].item() == approx(2.2950717e-09)
    assert atmos["N"].item() == approx(2.155302e12)
    assert atmos["AnomalousO"].item() == approx(8.7590428e-16)

    assert atmos.species == [
        "He", "O", "N2", "O2", "Ar", "Total", "H", "N", "AnomalousO"
    ]

    assert atmos["Tn"].item() == approx(667.06, abs=0.01)
    assert atmos["Texo"].item() == approx(922.28, abs=0.01)
Пример #4
0
def test_ccmc():
    t = datetime(2001, 2, 2, 8, 0, 0)
    glat = 60.0
    glon = -70.0
    altkm = 400.0
    indices = {"f107s": 163.6666, "f107": 146.7, "Ap": 7}

    with importlib.resources.path(__package__, "ccmc.log") as fn:
        A = np.loadtxt(fn, skiprows=25)

    atmos = msise00.run(t, altkm, glat, glon, indices)
    assert atmos.f107s == approx(indices["f107s"])
    assert atmos.f107 == approx(indices["f107"])
    assert atmos.Ap == indices["Ap"]
    assert A[0] == approx(altkm)
    assert A[1] == approx(atmos["O"].item() / 1e6, rel=0.01)
    assert A[2] == approx(atmos["N2"].item() / 1e6, rel=0.01)
    assert A[3] == approx(atmos["O2"].item() / 1e6, rel=0.01)
    assert A[7] == approx(atmos["He"].item() / 1e6, rel=0.01)
    assert A[8] == approx(atmos["Ar"].item() / 1e6, rel=0.01)
    assert A[9] == approx(atmos["H"].item() / 1e6, rel=0.01)
    assert A[10] == approx(atmos["N"].item() / 1e6, rel=0.01)
    assert A[11] == approx(atmos["AnomalousO"].item() / 1e6, rel=0.01)

    assert A[5] == approx(atmos["Tn"].item(), rel=0.001)
    assert A[6] == approx(atmos["Texo"].item(), rel=0.001)
Пример #5
0
def test_past():
    t = datetime(2013, 3, 31, 12)
    altkm = 150.0
    glat = 65.0
    glon = -148.0

    try:
        atmos = msise00.run(t, altkm, glat, glon)
    except ConnectionError:
        pytest.skip("unable to download RecentIndices.txt")

    assert atmos["He"].ndim == 4
    assert atmos["He"].size == 1
    dims = list(atmos.dims)
    assert ["alt_km", "lat", "lon", "time"] == dims

    # daily resolution
    assert atmos["He"].item() == approx(1.2523275e13)
    assert atmos["O"].item() == approx(1.3222577e16)
    assert atmos["N2"].item() == approx(2.9318694e16)
    assert atmos["O2"].item() == approx(2.6164412e15)
    assert atmos["Ar"].item() == approx(5.9933693e13)
    assert atmos["Total"].item() == approx(1.8571854e-9)
    assert atmos["N"].item() == approx(9.1038102e12)
    assert atmos["AnomalousO"].item() == approx(4.503e-14)

    assert atmos["Tn"].item() == approx(655.79, abs=0.01)
    assert atmos["Texo"].item() == approx(875.18, abs=0.01)

    assert atmos.species == [
        "He", "O", "N2", "O2", "Ar", "Total", "H", "N", "AnomalousO"
    ]
Пример #6
0
def test_forecast():
    t = datetime(2023, 3, 31, 12)
    altkm = 150.0
    glat = 65.0
    glon = -148.0

    atmos = msise00.run(t, altkm, glat, glon)

    assert atmos["He"].ndim == 4
    assert atmos["He"].size == 1
    dims = list(atmos.dims)
    assert ["alt_km", "lat", "lon", "time"] == dims

    assert atmos["He"].item() == approx(1240641440000.0)
    assert atmos["O"].item() == approx(3047968100000000.0)
    assert atmos["N2"].item() == approx(3.597249e16)
    assert atmos["O2"].item() == approx(7343665540000000.0)
    assert atmos["Ar"].item() == approx(334703983000000.0)
    assert atmos["Total"].item() == approx(2.16534546e-09)
    assert atmos["N"].item() == approx(2576280450000.0)
    assert atmos["AnomalousO"].item() == approx(8.75042368e-16)

    assert atmos.species == [
        "He", "O", "N2", "O2", "Ar", "Total", "H", "N", "AnomalousO"
    ]

    assert atmos["Tn"].item() == approx(671.513, abs=0.01)
    assert atmos["Texo"].item() == approx(883.342, abs=0.01)
Пример #7
0
def test_ccmc():
    t = datetime(2001, 2, 2, 8, 0, 0)
    glat = 60.0
    glon = -70.0
    altkm = 400.0
    indices = {"f107s": 163.6666, "f107": 146.7, "Ap": 7}

    A = np.loadtxt(reffn, skiprows=25)

    atmos = msise00.run(t, altkm, glat, glon, indices)
    assert atmos.f107s == approx(163.6666)
    assert atmos.f107 == approx(146.7)
    assert atmos.Ap == approx(7)
    assert A[0] == approx(altkm)
    assert A[1] == approx(atmos["O"].item() / 1e6, rel=0.05)
    assert A[2] == approx(atmos["N2"].item() / 1e6, rel=0.3)
    assert A[3] == approx(atmos["O2"].item() / 1e6, rel=0.35)
    assert A[7] == approx(atmos["He"].item() / 1e6, rel=0.2)
    assert A[8] == approx(atmos["Ar"].item() / 1e6, rel=0.6)
    assert A[9] == approx(atmos["H"].item() / 1e6, rel=0.1)
    assert A[10] == approx(atmos["N"].item() / 1e6, rel=0.3)
    assert A[11] == approx(atmos["AnomalousO"].item() / 1e6, rel=0.3)

    assert A[5] == approx(atmos["Tn"].item(), rel=0.1)
    assert A[6] == approx(atmos["Texo"].item(), rel=0.1)
Пример #8
0
def test_one_loc_one_time(altkm, reffn):
    pytest.importorskip("netCDF4")
    ref = xarray.open_dataset(R / reffn)

    try:
        dat_mod = msise00.run(time, altkm, lat, lon).squeeze()
    except ConnectionError:
        pytest.skip("unable to download RecentIndices.txt")
    xarray.tests.assert_allclose(ref, dat_mod)
Пример #9
0
def test_multiple_time():
    pytest.importorskip("netCDF4")
    ref = xarray.open_dataset(R / "ref4.nc")

    lat, lon = msise00.worldgrid.latlonworldgrid(90, 90)

    try:
        dat_mod = msise00.run(time, altkm, lat, lon).squeeze()
    except ConnectionError:
        pytest.skip("unable to download RecentIndices.txt")
    xarray.tests.assert_allclose(ref, dat_mod)
Пример #10
0
def test_one_alt_one_time():
    pytest.importorskip("netCDF4")
    ref = xarray.open_dataset(R / "ref3.nc")

    lat, lon = msise00.worldgrid.latlonworldgrid(30, 60)

    indices = {"f107": 79.3, "f107s": 76.6802469, "Ap": 39}
    try:
        dat_mod = msise00.run(time, altkm, lat, lon, indices).squeeze()
    except ConnectionError:
        pytest.skip("unable to download RecentIndices.txt")
    xarray.tests.assert_allclose(ref, dat_mod)
Пример #11
0
def test_one_alt_one_time():
    pytest.importorskip("netCDF4")

    with importlib.resources.path(__package__, "ref3.nc") as fn:
        ref = xarray.open_dataset(fn)

    lat, lon = msise00.worldgrid.latlonworldgrid(30, 60)

    try:
        dat_mod = msise00.run(time, altkm, lat, lon).squeeze()
    except ConnectionError:
        pytest.skip("unable to download RecentIndices.txt")
    xarray.tests.assert_allclose(ref, dat_mod)
Пример #12
0
def test_ccmc2():
    t = datetime(2018, 5, 17, 21, 0, 0)
    glat = 55.0
    glon = 120.0
    altkm = 300.0
    indices = {"f107s": 72.6, "f107": 71.5, "Ap": 9.5}

    atmos = msise00.run(t, altkm, glat, glon, indices)

    assert 4.874e7 == approx(atmos["N2"].item() / 1e6, rel=0.2)
    assert 1.622e6 == approx(atmos["O2"].item() / 1e6, rel=0.1)

    assert 794.1 == approx(atmos["Tn"].item(), rel=0.1)
    assert 800.0 == approx(atmos["Texo"].item(), rel=0.1)
Пример #13
0
def test_past():
    t = datetime(2013, 3, 31, 12)
    altkm = 150.0
    glat = 65.0
    glon = -148.0

    try:
        atmos = msise00.run(t, altkm, glat, glon)
    except ConnectionError:
        pytest.skip("unable to download RecentIndices.txt")

    assert atmos["He"].ndim == 4
    assert atmos["He"].size == 1
    dims = list(atmos.dims)
    assert ["alt_km", "lat", "lon", "time"] == dims

    try:  # daily resolution
        assert atmos["He"].item() == approx(4365665440000.0)
        assert atmos["O"].item() == approx(9612878760000000.0)
        assert atmos["N2"].item() == approx(3.15052301e16)
        assert atmos["O2"].item() == approx(2312921490000000.0)
        assert atmos["Ar"].item() == approx(71974164400000.0)
        assert atmos["Total"].item() == approx(1.84757176e-09)
        assert atmos["N"].item() == approx(9424203680000.0)
        assert atmos["AnomalousO"].item() == approx(1.17317104e-14)

        assert atmos["Tn"].item() == approx(682.538, abs=0.01)
        assert atmos["Texo"].item() == approx(948.350, abs=0.01)
    except AssertionError:  # monthly resolution
        assert atmos["He"].item() == approx(4200180480000.0)
        assert atmos["O"].item() == approx(9338048100000000.0)
        assert atmos["N2"].item() == approx(3.23984781e16)
        assert atmos["O2"].item() == approx(2413811350000000.0)
        assert atmos["Ar"].item() == approx(81071685200000.0)
        assert atmos["Total"].item() == approx(1.88774951e-09)
        assert atmos["N"].item() == approx(9310465690000.0)
        assert atmos["AnomalousO"].item() == approx(5.3806201e-15)

        assert atmos["Tn"].item() == approx(699.021, abs=0.01)
        assert atmos["Texo"].item() == approx(1000.513, abs=0.01)

    assert atmos.species == [
        "He", "O", "N2", "O2", "Ar", "Total", "H", "N", "AnomalousO"
    ]
Пример #14
0
def get_atmos(time, lat, lon, altitude=(0, 140, 1), apindex=35):
    """
    Retrieve atmospheric conditions (temperature and wind) from MSISE-00
    and HWM2014 models.
    """
    alt_vector = np.arange(*altitude)
    Tn = msise00.run(time, altkm=alt_vector, glat=lat,
                     glon=lon).Tn.data.ravel()
    wind = HWM14(altlim=[alt_vector[0], alt_vector[-1]],
                 altstp=altitude[2],
                 glat=lat,
                 glon=lon,
                 ap=[-1, apindex],
                 ut=time.hour,
                 day=time.julday,
                 year=time.year,
                 verbose=0)
    W_zonal, W_meridional = np.array([wind.Uwind, wind.Vwind])

    return alt_vector, Tn, W_zonal, W_meridional
Пример #15
0
mOxygen   = 2.6567e-26;
mNitrogen = 2.3259e-26;
mHelium   = 6.646477e-27;
mArgon    = 6.6335e-26;
mHydrogen = 1.674e-27;
mOxygen2  = mOxygen * 2.;
mNitrogen2= mNitrogen * 2.;


# Construct altitude array
altitudeArr = np.linspace(lowerAlt, 
                          upperAlt, 
                      int((upperAlt+altitudeStepSize)/altitudeStepSize));
# Call MSIS model
atmos = msise00.run(time=time, 
                    altkm=altitudeArr, 
                    glat=g_lat_lon[0], 
                    glon=g_lat_lon[1])

# If program gets any arguments it'll plot the profiles
if len(sys.argv) > 1: 
    import matplotlib.pyplot as plt
    fig = plt.figure();
    ax1 = fig.add_subplot(131)
    for var in atmos.species:
        if var is not 'Total':
            atmos[var].plot(y='alt_km', label=var, ax=ax1)
    plt.xscale('log'); plt.legend(fontsize=8);
    plt.xlabel('Species number density [m$^{-3}$]')
    plt.ylabel('Altitude [km]');
    plt.title('Number Density Profile')
    plt.grid();
Пример #16
0
def main():
    p = ArgumentParser(
        description='calls MSISE-00 from Python, save to NetCDF4 and/or plot')
    p.add_argument(
        '-t',
        '--time',
        help=
        'time: (single time or START STOP (1 hour time step) or list of times)',
        nargs='+',
        required=True)
    p.add_argument(
        '-a',
        '--altkm',
        help='altitude (km). scalar, or (start,stop,step) or list of alts.',
        type=float,
        nargs='+',
        required=True)
    p.add_argument('-c',
                   '--latlon',
                   help='geodetic latitude/longitude (deg)',
                   metavar=('lat', 'lon'),
                   type=float,
                   nargs=2)
    p.add_argument('-o', '--odir', help='directory to write plots to')
    p.add_argument('-w', help='NetCDF4 .nc filename to write')
    p.add_argument('-gs',
                   help='geographic grid spacing (lat, lon)',
                   nargs=2,
                   type=float,
                   default=(10, 10))
    p.add_argument('-q',
                   '--quiet',
                   help='disable plotting',
                   action='store_true')
    P = p.parse_args()

    # %% altitude
    if len(P.altkm) == 1:
        altkm = P.altkm[0]
    elif len(P.altkm) == 3:
        altkm = np.arange(*P.altkm)
    else:
        altkm = P.altkm
# %% latlon
    if P.latlon is not None:
        glat, glon = P.latlon
    else:
        glat, glon = latlonworldgrid(*P.gs)
# %% run
    atmos = msise00.run(P.time, altkm, glat, glon)
    # %% save
    if P.w:
        ncfn = Path(P.w).expanduser()
        print('saving', ncfn)
        # NOTE: .squeeze() avoids ValueError: unsupported dtype for netCDF4 variable: datetime64[ns]
        atmos.squeeze().to_netcdf(ncfn)


# %% plot
    if msplots is not None and not P.quiet:
        msplots.plotgtd(atmos, P.odir)
        show()
    else:
        print('skipped plots')
Пример #17
0
#!/usr/bin/env python
"""
Time profile example
"""
import numpy as np
from datetime import datetime, timedelta
from matplotlib.pyplot import show

import msise00.plots as msplots
import msise00

glat = 65.1
glon = -147.5
alt_km = 200
t0 = datetime(2015, 12, 13, 10, 0, 0)
t1 = datetime(2015, 12, 14, 10, 0, 0)

times = np.arange(t0, t1, timedelta(hours=1))

atmos = msise00.run(times, alt_km, glat, glon)

msplots.plotgtd(atmos)

show()
Пример #18
0
#%% altitude 1-D mode
    if p.latlon is not None:
        print('entering single location mode')
        if p.altkm is None:
            p.altkm = (60., 1000, 5)
        altkm = np.arange(*p.altkm)
        glat, glon = p.latlon
#%% lat/lon grid mode at constant altitude
    else:  # len(p.altkm)==1:
        print(
            'lat/lon not specified, entering auto whole-world grid mode at first altitude'
        )
        if p.altkm is None:
            altkm = 200.
        else:
            altkm = p.altkm[0]
        glat, glon = latlonworldgrid()

    altkm = np.atleast_1d(altkm)
    print(f'using altitudes from {altkm[0]:.1f} to {altkm[-1]:.1f} km')
    # %% run
    atmos = msise00.run(time, altkm, glat, glon)
    #%%
    if p.w:
        ncfn = Path(p.w).expanduser()
        print('saving', ncfn)
        atmos.to_netcdf(ncfn)

    plotgtd(atmos, p.odir)
    show()