Пример #1
0
def no_source(time: datetime, glat: float, glon: float, Nbins: int,
              Talt: float, Thot: float) -> xarray.Dataset:
    """ testing only, may give non-physical results"""
    idate, utsec = glowdate(time)

    ip = gi.get_indices([time - timedelta(days=1), time], 81)

    cmd = [
        str(EXE),
        idate,
        utsec,
        str(glat),
        str(glon),
        str(ip["f107s"][1]),
        str(ip["f107"][1]),
        str(ip["f107"][0]),
        str(ip["Ap"][1]),
        "-nosource",
        str(Nbins),
        str(Talt),
        str(Thot),
    ]

    dat = subprocess.check_output(cmd,
                                  timeout=15,
                                  stderr=subprocess.DEVNULL,
                                  universal_newlines=True)

    return glowparse(dat, time, ip, glat, glon)
Пример #2
0
def no_precipitation(time: datetime, glat: float, glon: float,
                     Nbins: int) -> xarray.Dataset:

    idate, utsec = glowdate(time)

    ip = gi.get_indices([time - timedelta(days=1), time], 81)

    cmd = [
        str(EXE),
        idate,
        utsec,
        str(glat),
        str(glon),
        str(ip["f107s"][1]),
        str(ip["f107"][1]),
        str(ip["f107"][0]),
        str(ip["Ap"][1]),
        "-noprecip",
        str(Nbins),
    ]

    dat = subprocess.check_output(cmd,
                                  timeout=15,
                                  stderr=subprocess.DEVNULL,
                                  universal_newlines=True)

    return glowparse(dat, time, ip, glat, glon)
Пример #3
0
def test_multi_past():
    dates = pandas.date_range(datetime(2017, 12, 31, 23), datetime(2018, 1, 1, 2), freq="3H")

    try:
        dat = gi.get_indices(dates)
    except ConnectionError as e:
        pytest.skip(f"possible timeout error {e}")

    assert (dat.index == [datetime(2017, 1, 1, 22, 30), datetime(2018, 1, 1, 1, 30)]).all
Пример #4
0
def test_farfuture():

    t = date(2029, 12, 21)

    dat = gi.get_indices(t, 81)

    assert dat.shape == (1, 5)
    assert dat.index[0] == datetime(2030, 1, 1, 2, 37, 40, 799998)

    assert "Ap" in dat
    assert "f107" in dat
    assert "f107s" in dat
    assert "Aps" in dat
Пример #5
0
def test_past_and_future():
    dates = [datetime(2017, 1, 1), datetime(2030, 3, 1)]

    try:
        dat = gi.get_indices(dates)
    except ConnectionError as e:
        pytest.skip(f"possible timeout error {e}")

    pasttime = datetime(2017, 1, 1)
    if dat["resolution"][0] == "d":
        pasttime += timedelta(hours=1, minutes=30)

    assert (dat.index == [pasttime, datetime(2030, 3, 2, 22, 55, 11, 999997)]).all()
Пример #6
0
def test_list():

    t = [date(2018, 1, 1), datetime(2018, 1, 2)]

    try:
        dat = gi.get_indices(t)
    except ConnectionError as e:
        pytest.skip(f"possible timeout error {e}")

    assert dat.shape[0] == 2
    assert dat.shape[1] in (3, 4)

    assert (dat.index == [datetime(2018, 1, 1, 1, 30), datetime(2018, 1, 2, 1, 30)]).all
Пример #7
0
def test_past(dt, hour, f107, f107s, ap, aps, kp):

    try:
        dat = gi.get_indices(dt, 81)
    except ConnectionError as e:
        pytest.skip(f"possible timeout error {e}")

    assert dat.shape[0] == 1
    assert dat["f107"].iloc[0] == approx(f107, abs=0.1)
    assert dat["f107s"].iloc[0] == approx(f107s, abs=0.1)
    assert dat["Ap"].iloc[0] == ap
    assert dat["Aps"].iloc[0] == approx(aps, abs=0.1)
    if "Kp" in dat:
        assert dat["Kp"].iloc[0] == approx(kp, abs=0.1)
Пример #8
0
def ebins(time: datetime, glat: float, glon: float, Ebins: np.ndarray,
          Phitop: np.ndarray) -> xarray.Dataset:

    idate, utsec = glowdate(time)

    # %% Matlab compatible workaround (may change to use stdin in future)
    Efn = Path(tempfile.mkstemp(".dat")[1])
    with Efn.open("wb") as f:
        Ebins.tofile(f)
        Phitop.tofile(f)

    tmpfile_size = Efn.stat().st_size
    expected_size = (Ebins.size + Phitop.size) * 4
    if tmpfile_size != expected_size:
        raise OSError(f"{Efn} size {tmpfile_size} != {expected_size}")

    ip = gi.get_indices([time - timedelta(days=1), time], 81)

    cmd = [
        str(EXE),
        idate,
        utsec,
        str(glat),
        str(glon),
        str(ip["f107s"][1]),
        str(ip["f107"][1]),
        str(ip["f107"][0]),
        str(ip["Ap"][1]),
        "-e",
        str(Ebins.size),
        str(Efn),
    ]

    ret = subprocess.run(cmd,
                         timeout=15,
                         universal_newlines=True,
                         stdout=subprocess.PIPE)
    if ret.returncode:
        raise RuntimeError(f"GLOW failed at {time}")
    try:
        Efn.unlink()
    except PermissionError:
        # Windows sometimes does this if something else is holding the file open.
        # this is also why we don't use a tempfile context manager for this application.
        pass

    return glowparse(ret.stdout, time, ip, glat, glon)
Пример #9
0
def test_nearfuture():

    t = datetime.today() + timedelta(days=3)

    try:
        dat = gi.get_indices(t)
    except ConnectionError as e:
        pytest.skip(f"possible timeout error {e}")

    assert dat.shape[0] == 1

    if t.hour >= 12:
        assert dat.index[0] == datetime(t.year, t.month, t.day) + timedelta(days=1)
    else:
        assert dat.index[0] == datetime(t.year, t.month, t.day)

    assert "Ap" in dat
    assert "f107" in dat
Пример #10
0
def test_past(dt, hour, f107s, ap, aps, kp):

    try:
        dat = gi.get_indices(dt, 81)
    except ConnectionError as e:
        pytest.skip(f"possible timeout error {e}")

    assert dat.shape[0] == 1
    if dat["resolution"].iloc[0] == "m":
        assert dat["f107"].iloc[0] == approx(73.5, abs=0.1)
        assert dat["f107s"].iloc[0] == approx(76.4, abs=0.1)
        assert dat["Ap"].iloc[0] == 9
        assert dat["Aps"].iloc[0] == approx(9.66, abs=0.1)
    elif dat["resolution"].iloc[0] == "d":
        assert dat["f107"].iloc[0] == approx(76.4)
        assert dat["f107s"].iloc[0] == approx(f107s, abs=0.1)
        assert dat["Ap"].iloc[0] == ap
        assert dat["Aps"].iloc[0] == approx(aps, abs=0.1)
        assert dat["Kp"].iloc[0] == approx(kp, abs=0.1)
    else:
        raise ValueError(f"unknown resolution {dat.resolution}")
Пример #11
0
def rungtd1d(
    time: datetime, altkm: float, glat: float, glon: float, indices: dict[str, typing.Any] = None
) -> xarray.Dataset:
    """
    This is the "atomic" function looped by other functions
    """
    time = todatetime(time)
    # %% get solar parameters for date
    if not indices:
        indices = gi.get_indices(time, smoothdays=81).squeeze().to_dict()
    assert isinstance(indices, dict)
    # %% dimensions
    altkm = np.atleast_1d(altkm)
    if altkm.ndim != 1:
        raise ValueError("altitude read incorrectly")
    if not isinstance(glon, (int, float, np.int32, np.int64)):
        raise TypeError("single longitude only")
    if not isinstance(glat, (int, float, np.int32, np.int64)):
        raise TypeError("single latitude only")

    # %%
    doy = time.strftime("%j")
    altkm = np.atleast_1d(altkm)
    # %%
    dens = np.empty((altkm.size, len(species)))
    temp = np.empty((altkm.size, len(ttypes)))
    # %% build on run
    exe_name = "msise00_driver"
    if os.name == "nt":
        exe_name += ".exe"
    if not importlib.resources.is_resource(__package__, exe_name):
        # check for CMake here to avoid "generator didn't stop after throw() higher level raise"
        if not shutil.which("ctest"):
            raise FileNotFoundError(
                """
    CMake not available. try installing CMake like:

        pip install cmake"""
            )

        with importlib.resources.path(__package__, "setup.cmake") as setup_file:
            cmake(setup_file)
    if not importlib.resources.is_resource(__package__, exe_name):
        raise RuntimeError("could not build MSISE00 Fortran driver")

    # check inputs for error, especially unavailable indices
    if not np.isfinite(glat).all():
        raise ValueError("glat is not finite.")

    if not np.isfinite(glon).all():
        raise ValueError("glon is not finite.")

    f107s = indices["f107s"]
    if not np.isfinite(f107s):
        raise ValueError("f107s is not finite.")

    f107s = indices["f107s"]
    if not np.isfinite(f107s):
        raise ValueError("f107s is not finite.")

    f107 = indices["f107"]
    if not np.isfinite(f107):
        raise ValueError("f107 is not finite.")

    Ap = indices["Ap"]
    if not np.isfinite(Ap):
        raise ValueError("Ap is not finite.")

    with importlib.resources.path(__package__, exe_name) as exe:
        for i, a in enumerate(altkm):
            cmd = [
                str(exe),
                doy,
                str(time.hour),
                str(time.minute),
                str(time.second),
                str(glat),
                str(glon),
                str(f107s),
                str(f107),
                str(Ap),
                str(a),
            ]

            logging.info(" ".join(cmd))

            ret = subprocess.check_output(cmd, text=True)

            # different compilers throw in extra \n
            raw = list(map(float, ret.split()))
            if not len(raw) == 9 + 2:
                raise ValueError(ret)
            dens[i, :] = raw[:9]
            temp[i, :] = raw[9:]

    dsf = {
        k: (("time", "alt_km", "lat", "lon"), v[None, :, None, None])
        for (k, v) in zip(species, dens.T)
    }
    dsf.update(
        {
            "Tn": (("time", "alt_km", "lat", "lon"), temp[:, 1][None, :, None, None]),
            "Texo": (("time", "alt_km", "lat", "lon"), temp[:, 0][None, :, None, None]),
        }
    )

    atmos = xarray.Dataset(
        dsf,  # type: ignore
        coords={"time": [time], "alt_km": altkm, "lat": [glat], "lon": [glon]},
        attrs={
            "species": species,
            "f107s": indices["f107s"],
            "f107": indices["f107"],
            "Ap": indices["Ap"],
        },
    )

    return atmos
Пример #12
0
    from argparse import ArgumentParser

    p = ArgumentParser()
    p.add_argument(
        "start_stop",
        help="date or date range of observation yyyy-mm-dd  (START, STOP)",
        nargs="+")
    a = p.parse_args()

    start = parse(a.start_stop[0])
    if len(a.start_stop) > 1:
        end = parse(a.start_stop[1])
    else:
        end = start + timedelta(days=1)

    dates = pandas.date_range(start, end, freq="3H")

    inds = gi.get_indices(dates)

    # %% plot
    fig = figure()
    ax = fig.gca()
    inds.plot(ax=ax)  # , marker='.'
    ax.set_ylabel("index values")
    ax.set_xlabel("time [UTC]")
    ax.grid(True)

    # fig.savefig('2015.png', bbox_inches='tight')

    show()