test_gfz.test_3hourly_index()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 17
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 14
nop 3
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
# vim:fileencoding=utf-8
3
#
4
# Copyright (c) 2024 Stefan Bender
5
#
6
# This module is part of pyspaceweather.
7
# pyspaceweather is free software: you can redistribute it or modify
8
# it under the terms of the GNU General Public License as published
9
# by the Free Software Foundation, version 2.
10
# See accompanying COPYING.GPLv2 file or http://www.gnu.org/licenses/gpl-2.0.html.
11
"""Space weather index read tests for GFZ formats
12
13
Parsing tests for the GFZ file formats.
14
"""
15
import os
16
17
import numpy as np
18
import pandas as pd
19
import requests
20
21
import pytest
22
23
from spaceweather import (
24
	gfz_3h, gfz_daily, get_gfz_age, update_gfz,
25
)
26
from spaceweather.gfz import GFZ_URL_30D
27
28
GFZ_PATH_ALL = os.path.join("tests", "Kp_ap_Ap_SN_F107_since_2024.txt")
29
GFZ_PATH_30D = os.path.join("tests", "Kp_ap_Ap_SN_F107_nowcast.txt")
30
31
32
@pytest.fixture(scope="module")
33
def df_3h():
34
	return gfz_3h(gfzpath_all=GFZ_PATH_ALL, gfzpath_30d=GFZ_PATH_30D)
35
36
37
def test_age():
38
	now = pd.Timestamp.utcnow()
39
	for p in [GFZ_PATH_ALL, GFZ_PATH_30D]:
40
		assert os.path.exists(p)
41
		fage0 = get_gfz_age(p)
42
		fage1 = now - get_gfz_age(p, relative=False)
43
		assert (fage0 > pd.Timedelta("3h")) == (fage1 > pd.Timedelta("3h"))
44
		assert (fage0 > pd.Timedelta("1d")) == (fage1 > pd.Timedelta("1d"))
45
46
47
def test_update(mocker):
48
	mocker.patch("requests.get")
49
	update_gfz(min_age="1d", gfzpath_all=GFZ_PATH_ALL, gfzpath_30d=GFZ_PATH_30D)
50
	requests.get.assert_called_with(GFZ_URL_30D, stream=True)
51
52
53
def test_auto_update(mocker, tmpdir):
54
	# test with non-existent file
55
	mocker.patch("requests.get")
56
	tmpdir = str(tmpdir)
57
	update_gfz(gfzpath_30d=os.path.join(tmpdir, "foo.dat"))
58
	requests.get.assert_called_with(GFZ_URL_30D, stream=True)
59
	# Should update the last-5-year data
60
	gfz_daily(
61
		gfzpath_all=GFZ_PATH_ALL, gfzpath_30d=GFZ_PATH_30D,
62
		update=True, update_interval="1d",
63
	)
64
	requests.get.assert_called_with(GFZ_URL_30D, stream=True)
65
	with pytest.warns(UserWarning):
66
		gfz_daily(
67
			gfzpath_all=GFZ_PATH_ALL, gfzpath_30d=GFZ_PATH_30D,
68
			update=False, update_interval="0h",
69
		)
70
71
72
def test_not_avail(mocker, tmpdir):
73
	# test with non-existent file
74
	mocker.patch("requests.get")
75
	tmpdir = str(tmpdir)
76
	tmpfile = os.path.join(tmpdir, "foo.dat")
77
	# daily
78
	with pytest.raises(IOError):
79
		with pytest.warns(UserWarning):
80
			gfz_daily(update=False, update_interval="0h", gfzpath_30d=tmpfile)
81
	# 3h data
82
	with pytest.raises(IOError):
83
		with pytest.warns(UserWarning):
84
			gfz_3h(update=False, update_interval="0h", gfzpath_30d=tmpfile)
85
86
87
def test_daily():
88
	df = gfz_daily(gfzpath_all=GFZ_PATH_ALL, gfzpath_30d=GFZ_PATH_30D)
89
	np.testing.assert_allclose(
90
		df.loc["2024-01-01"].values,
91
		np.array([
92
			2.024e+03, 1.000e+00, 1.000e+00,
93
			3.36030e+04, 3.36035e+04, 2.596e+03, 2.500e+01,
94
			6.670e-01, 3.330e-01, 6.670e-01, 1.333e+00,
95
			2.000e+00, 3.000e+00, 3.333e+00, 4.000e+00, 1.5333e+01,
96
			3.000e+00, 2.000e+00, 3.000e+00, 5.000e+00,
97
			7.000e+00, 1.500e+01, 1.800e+01, 2.700e+01, 1.000e+01,
98
			5.400e+01, 1.357e+02, 1.312e+02, 1.000e+00,
99
		], dtype=np.float64),
100
		rtol=1e-6,
101
	)
102
103
104
@pytest.mark.parametrize(
105
	"name, result",
106
	[
107
		("Ap", [3, 2, 3, 5, 7, 15, 18, 27]),
108
		("Kp", [0.667, 0.333, 0.667, 1.333, 2.0, 3.0, 3.333, 4.0]),
109
	]
110
)
111
def test_3hourly_index(name, result, df_3h):
112
	df = df_3h
113
	np.testing.assert_allclose(
114
		df.loc[
115
			pd.date_range(
116
				"2024-01-01 01:30", "2024-01-01 23:30", freq="3h"
117
			)
118
		][name].values,
119
		np.array(result, dtype=np.float64),
120
		rtol=1e-6,
121
	)
122