wxdata 2.0.3__tar.gz → 2.0.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {wxdata-2.0.3/src/wxdata.egg-info → wxdata-2.0.4}/PKG-INFO +1 -1
- {wxdata-2.0.3 → wxdata-2.0.4}/pyproject.toml +1 -1
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/soundings/wyoming_soundings.py +166 -80
- {wxdata-2.0.3 → wxdata-2.0.4/src/wxdata.egg-info}/PKG-INFO +1 -1
- {wxdata-2.0.3 → wxdata-2.0.4}/LICENSE +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/README.md +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/setup.cfg +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigefs/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigefs/aigefs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigefs/paths.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigefs/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigfs/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigfs/aigfs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigfs/paths.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/aigfs/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/calc/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/calc/derived_fields.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/calc/kinematics.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/calc/thermodynamics.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/calc/unit_conversion.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/cfs/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/cfs/cfs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/cfs/file_scanner.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/cfs/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/client/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/client/byte_range.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/client/client.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/client/level_coords.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/ecmwf.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/file_funcs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/keys.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/parsers.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/paths.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/ecmwf/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/fems/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/fems/meta_data.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/fems/observations.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gefs/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gefs/exception_messages.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gefs/file_funcs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gefs/gefs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gefs/paths.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gefs/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gfs/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gfs/exception_messages.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gfs/gfs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gfs/paths.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/gfs/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/hgefs/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/hgefs/hgefs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/hgefs/paths.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/hgefs/url_scanner.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/metars/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/metars/_clean_data.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/metars/metar_obs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/noaa/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/noaa/nws.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/aigefs_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/aigfs_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/cfs_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/ecmwf_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/gefs_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/gfs_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/hgefs_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/post_processors/rtma_post_processing.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/radar/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/radar/nexrad2.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/radar/url_scanner.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/rtma/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/rtma/file_funcs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/rtma/file_scanner.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/rtma/keys.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/rtma/rtma.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/rtma/url_scanners.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/soundings/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/soundings/_exceptions.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/__init__.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/coords.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/exceptions.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/file_funcs.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/file_scanner.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/nomads_gribfilter.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/progress_bar.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/recycle_bin.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/scripts.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/tools.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata/utils/xmacis2_cleanup.py +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata.egg-info/SOURCES.txt +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata.egg-info/dependency_links.txt +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata.egg-info/requires.txt +0 -0
- {wxdata-2.0.3 → wxdata-2.0.4}/src/wxdata.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wxdata
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: A Python package of end-to-end weather data clients & raw data clients with VPN/PROXY support, data processors that decode variable keys from GRIB format into a plain-language format & various tools for assisting Python automated workflows, querying meteorological datasets and filling gaps in meteorological data.
|
|
5
5
|
Author: Eric J. Drewitz
|
|
6
6
|
Project-URL: Documentation, https://github.com/edrewitz/wxdata/blob/main/Documentation/Landing%20Page.md
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "wxdata"
|
|
3
|
-
version = "2.0.
|
|
3
|
+
version = "2.0.4"
|
|
4
4
|
description = "A Python package of end-to-end weather data clients & raw data clients with VPN/PROXY support, data processors that decode variable keys from GRIB format into a plain-language format & various tools for assisting Python automated workflows, querying meteorological datasets and filling gaps in meteorological data."
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
requires-python = ">=3.10"
|
|
@@ -14,7 +14,6 @@ import metpy.calc as _mpcalc
|
|
|
14
14
|
import sys as _sys
|
|
15
15
|
import wxdata.soundings._exceptions as _exceptions
|
|
16
16
|
|
|
17
|
-
from wxdata.calc.thermodynamics import relative_humidity as _relative_humidity
|
|
18
17
|
from wxdata.calc.kinematics import get_u_and_v as _get_u_and_v
|
|
19
18
|
from metpy.units import units as _units
|
|
20
19
|
from bs4 import BeautifulSoup as _BeautifulSoup
|
|
@@ -44,6 +43,129 @@ except Exception as e:
|
|
|
44
43
|
now = _datetime.utcnow()
|
|
45
44
|
|
|
46
45
|
|
|
46
|
+
def _parse_sounding_text(data, usecols, names, widths=None):
|
|
47
|
+
"""
|
|
48
|
+
Parse the fixed-width Wyoming sounding text response while preserving the first
|
|
49
|
+
pressure level row. The text includes header lines that should not be treated as
|
|
50
|
+
data rows.
|
|
51
|
+
|
|
52
|
+
Required Arguments:
|
|
53
|
+
|
|
54
|
+
1) data (Bytes) - The sounding data in bytes format.
|
|
55
|
+
|
|
56
|
+
2) usecols (Integer List) - The list of columns to be used.
|
|
57
|
+
|
|
58
|
+
3) names (String List) - Column names.
|
|
59
|
+
|
|
60
|
+
Optional Arguments:
|
|
61
|
+
|
|
62
|
+
1) widths - Width of columns.
|
|
63
|
+
|
|
64
|
+
Returns
|
|
65
|
+
-------
|
|
66
|
+
|
|
67
|
+
A Pandas.DataFrame of the sounding data.
|
|
68
|
+
"""
|
|
69
|
+
if widths is None:
|
|
70
|
+
widths = [7] * 8
|
|
71
|
+
|
|
72
|
+
if hasattr(data, "readlines"):
|
|
73
|
+
lines = data.readlines()
|
|
74
|
+
else:
|
|
75
|
+
lines = data.splitlines()
|
|
76
|
+
|
|
77
|
+
cleaned_lines = [line.rstrip("\n") for line in lines]
|
|
78
|
+
start_idx = None
|
|
79
|
+
|
|
80
|
+
for idx, line in enumerate(cleaned_lines):
|
|
81
|
+
stripped = line.strip()
|
|
82
|
+
if not stripped:
|
|
83
|
+
continue
|
|
84
|
+
|
|
85
|
+
parts = stripped.split()
|
|
86
|
+
if not parts:
|
|
87
|
+
continue
|
|
88
|
+
|
|
89
|
+
first_token = parts[0]
|
|
90
|
+
if first_token.replace(".", "", 1).replace("-", "", 1).replace("+", "", 1).isdigit():
|
|
91
|
+
start_idx = idx
|
|
92
|
+
break
|
|
93
|
+
|
|
94
|
+
if start_idx is None:
|
|
95
|
+
raise ValueError("No sounding data rows found")
|
|
96
|
+
|
|
97
|
+
return _pd.read_fwf(
|
|
98
|
+
_StringIO("\n".join(cleaned_lines[start_idx:])),
|
|
99
|
+
widths=widths,
|
|
100
|
+
usecols=usecols,
|
|
101
|
+
names=names,
|
|
102
|
+
)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def _url_scanner(date,
|
|
106
|
+
station_number,
|
|
107
|
+
proxies):
|
|
108
|
+
|
|
109
|
+
"""
|
|
110
|
+
Scans URLs for a 200 response.
|
|
111
|
+
|
|
112
|
+
Required Arguments:
|
|
113
|
+
|
|
114
|
+
1) date (datetime) - The date and time of the observation.
|
|
115
|
+
|
|
116
|
+
2) station_number (Integer) - The number corresponding to the site.
|
|
117
|
+
|
|
118
|
+
3) proxies (String) - Default = None. If the user is requesting the data on a machine using a proxy server,
|
|
119
|
+
the user must set proxy='proxy_url'. The default setting assumes the user is not using a proxy server conenction.
|
|
120
|
+
|
|
121
|
+
proxies=None ---> proxies={
|
|
122
|
+
'http':'http://your-proxy-address:port',
|
|
123
|
+
'https':'http://your-proxy-address:port'
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
Optional Arguments: None
|
|
127
|
+
|
|
128
|
+
Returns
|
|
129
|
+
-------
|
|
130
|
+
|
|
131
|
+
The URL for data access.
|
|
132
|
+
|
|
133
|
+
"""
|
|
134
|
+
|
|
135
|
+
bufr = f"https://weather.uwyo.edu/wsgi/sounding?datetime={date.strftime('%Y-%m-%d')}%20{date.hour}:00:00&id={station_number}&src=BUFR&type=TEXT:LIST"
|
|
136
|
+
fm35 = f"https://weather.uwyo.edu/wsgi/sounding?datetime={date.strftime('%Y-%m-%d')}%20{date.hour}:00:00&id={station_number}&src=FM35&type=TEXT:LIST"
|
|
137
|
+
fm37 = f"https://weather.uwyo.edu/wsgi/sounding?datetime={date.strftime('%Y-%m-%d')}%20{date.hour}:00:00&id={station_number}&src=FM37&type=TEXT:LIST"
|
|
138
|
+
|
|
139
|
+
if proxies == None:
|
|
140
|
+
bufr_response = _requests.get(bufr)
|
|
141
|
+
fm35_response = _requests.get(fm35)
|
|
142
|
+
fm37_response = _requests.get(fm37)
|
|
143
|
+
|
|
144
|
+
else:
|
|
145
|
+
bufr_response = _requests.get(bufr,
|
|
146
|
+
proxies=proxies)
|
|
147
|
+
fm35_response = _requests.get(fm35,
|
|
148
|
+
proxies=proxies)
|
|
149
|
+
fm37_response = _requests.get(fm37,
|
|
150
|
+
proxies=proxies)
|
|
151
|
+
|
|
152
|
+
urls = []
|
|
153
|
+
urls.append(bufr)
|
|
154
|
+
urls.append(fm35)
|
|
155
|
+
urls.append(fm37)
|
|
156
|
+
|
|
157
|
+
responses = []
|
|
158
|
+
responses.append(bufr_response)
|
|
159
|
+
responses.append(fm35_response)
|
|
160
|
+
responses.append(fm37_response)
|
|
161
|
+
|
|
162
|
+
for r, url in zip(responses, urls):
|
|
163
|
+
if r.status_code == 200:
|
|
164
|
+
url = url
|
|
165
|
+
break
|
|
166
|
+
|
|
167
|
+
return url
|
|
168
|
+
|
|
47
169
|
def _station_ids(station_id):
|
|
48
170
|
|
|
49
171
|
"""
|
|
@@ -408,7 +530,7 @@ def get_observed_sounding_data(station_id,
|
|
|
408
530
|
if current == True:
|
|
409
531
|
date = now
|
|
410
532
|
if date.hour <= 12:
|
|
411
|
-
hour =
|
|
533
|
+
hour = 0
|
|
412
534
|
else:
|
|
413
535
|
hour = 12
|
|
414
536
|
|
|
@@ -427,15 +549,9 @@ def get_observed_sounding_data(station_id,
|
|
|
427
549
|
except Exception as e:
|
|
428
550
|
_exceptions.date_format_exception(date)
|
|
429
551
|
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
f"&YEAR={date.strftime('%Y')}&MONTH={date.strftime('%m')}&FROM={date.strftime('%d')}0{hour}&TO={date.strftime('%d')}0{hour}"
|
|
434
|
-
f"&STNM={station_number}")
|
|
435
|
-
else:
|
|
436
|
-
url = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
437
|
-
f"&YEAR={date.strftime('%Y')}&MONTH={date.strftime('%m')}&FROM={date.strftime('%d')}{hour}&TO={date.strftime('%d')}{hour}"
|
|
438
|
-
f"&STNM={station_number}")
|
|
552
|
+
url = _url_scanner(date,
|
|
553
|
+
station_number,
|
|
554
|
+
proxies)
|
|
439
555
|
|
|
440
556
|
max_retries = 5
|
|
441
557
|
retry = 0
|
|
@@ -469,14 +585,9 @@ def get_observed_sounding_data(station_id,
|
|
|
469
585
|
date = date - _timedelta(hours=12)
|
|
470
586
|
hour = date.hour
|
|
471
587
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
f"&STNM={station_number}")
|
|
476
|
-
else:
|
|
477
|
-
url = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
478
|
-
f"&YEAR={date.strftime('%Y')}&MONTH={date.strftime('%m')}&FROM={date.strftime('%d')}{hour}&TO={date.strftime('%d')}{hour}"
|
|
479
|
-
f"&STNM={station_number}")
|
|
588
|
+
url = _url_scanner(date,
|
|
589
|
+
station_number,
|
|
590
|
+
proxies)
|
|
480
591
|
|
|
481
592
|
max_retries = 5
|
|
482
593
|
retry = 0
|
|
@@ -513,13 +624,17 @@ def get_observed_sounding_data(station_id,
|
|
|
513
624
|
col_names = ['PRES', 'HGHT', 'TEMP', 'DWPT', 'RELH', 'MIXR', 'DRCT', 'SKNT', 'THTA', 'THTE', 'THTV']
|
|
514
625
|
|
|
515
626
|
try:
|
|
516
|
-
df =
|
|
517
|
-
|
|
627
|
+
df = _parse_sounding_text(
|
|
628
|
+
data,
|
|
629
|
+
usecols=[0, 1, 2, 3, 4, 5, 6, 7],
|
|
630
|
+
names=col_names,
|
|
631
|
+
widths=[7] * 8,
|
|
632
|
+
)
|
|
518
633
|
except Exception as e:
|
|
519
634
|
_exceptions.station_id_exception(station_id)
|
|
520
635
|
|
|
521
636
|
df['U-WIND'], df['V-WIND'] = _get_u_and_v(df['SKNT'], df['DRCT'])
|
|
522
|
-
df
|
|
637
|
+
df = df.rename(columns={'RELH': 'RH'})
|
|
523
638
|
pressure = df['PRES'].values * _units('hPa')
|
|
524
639
|
temperature = df['TEMP'].values * _units('degC')
|
|
525
640
|
dewpoint = df['DWPT'].values * _units('degC')
|
|
@@ -538,7 +653,7 @@ def get_observed_sounding_data(station_id,
|
|
|
538
653
|
if current == True:
|
|
539
654
|
date = now
|
|
540
655
|
if date.hour <= 12:
|
|
541
|
-
hour =
|
|
656
|
+
hour = 0
|
|
542
657
|
else:
|
|
543
658
|
hour = 12
|
|
544
659
|
|
|
@@ -559,24 +674,14 @@ def get_observed_sounding_data(station_id,
|
|
|
559
674
|
|
|
560
675
|
date_24 = date - _timedelta(hours=24)
|
|
561
676
|
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
f"&STNM={station_number}")
|
|
566
|
-
|
|
567
|
-
url_24 = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
568
|
-
f"&YEAR={date.strftime('%Y')}&MONTH={date_24.strftime('%m')}&FROM={date_24.strftime('%d')}0{hour}&TO={date_24.strftime('%d')}0{hour}"
|
|
569
|
-
f"&STNM={station_number}")
|
|
570
|
-
|
|
571
|
-
else:
|
|
572
|
-
url = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
573
|
-
f"&YEAR={date.strftime('%Y')}&MONTH={date.strftime('%m')}&FROM={date.strftime('%d')}{hour}&TO={date.strftime('%d')}{hour}"
|
|
574
|
-
f"&STNM={station_number}")
|
|
575
|
-
|
|
576
|
-
url_24 = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
577
|
-
f"&YEAR={date_24.strftime('%Y')}&MONTH={date_24.strftime('%m')}&FROM={date_24.strftime('%d')}{hour}&TO={date_24.strftime('%d')}{hour}"
|
|
578
|
-
f"&STNM={station_number}")
|
|
677
|
+
url = _url_scanner(date,
|
|
678
|
+
station_number,
|
|
679
|
+
proxies)
|
|
579
680
|
|
|
681
|
+
url_24 = _url_scanner(date_24,
|
|
682
|
+
station_number,
|
|
683
|
+
proxies)
|
|
684
|
+
|
|
580
685
|
max_retries = 5
|
|
581
686
|
retry = 0
|
|
582
687
|
if proxies == None:
|
|
@@ -621,23 +726,13 @@ def get_observed_sounding_data(station_id,
|
|
|
621
726
|
date_24 = date - _timedelta(hours=24)
|
|
622
727
|
hour = date.hour
|
|
623
728
|
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
f"&STNM={station_number}")
|
|
632
|
-
|
|
633
|
-
else:
|
|
634
|
-
url = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
635
|
-
f"&YEAR={date.strftime('%Y')}&MONTH={date.strftime('%m')}&FROM={date.strftime('%d')}{hour}&TO={date.strftime('%d')}{hour}"
|
|
636
|
-
f"&STNM={station_number}")
|
|
637
|
-
|
|
638
|
-
url_24 = (f"http://weather.uwyo.edu/cgi-bin/sounding?region=naconf&TYPE=TEXT%3ALIST"
|
|
639
|
-
f"&YEAR={date_24.strftime('%Y')}&MONTH={date_24.strftime('%m')}&FROM={date_24.strftime('%d')}{hour}&TO={date_24.strftime('%d')}{hour}"
|
|
640
|
-
f"&STNM={station_number}")
|
|
729
|
+
url = _url_scanner(date,
|
|
730
|
+
station_number,
|
|
731
|
+
proxies)
|
|
732
|
+
|
|
733
|
+
url_24 = _url_scanner(date_24,
|
|
734
|
+
station_number,
|
|
735
|
+
proxies)
|
|
641
736
|
|
|
642
737
|
max_retries = 5
|
|
643
738
|
retry = 0
|
|
@@ -684,13 +779,17 @@ def get_observed_sounding_data(station_id,
|
|
|
684
779
|
col_names = ['PRES', 'HGHT', 'TEMP', 'DWPT', 'RELH', 'MIXR', 'DRCT', 'SKNT', 'THTA', 'THTE', 'THTV']
|
|
685
780
|
|
|
686
781
|
try:
|
|
687
|
-
df =
|
|
688
|
-
|
|
782
|
+
df = _parse_sounding_text(
|
|
783
|
+
data,
|
|
784
|
+
usecols=[0, 1, 2, 3, 4, 5, 6, 7],
|
|
785
|
+
names=col_names,
|
|
786
|
+
widths=[7] * 8,
|
|
787
|
+
)
|
|
689
788
|
except Exception as e:
|
|
690
789
|
_exceptions.station_id_exception(station_id)
|
|
691
790
|
|
|
692
791
|
df['U-WIND'], df['V-WIND'] = _get_u_and_v(df['SKNT'], df['DRCT'])
|
|
693
|
-
df
|
|
792
|
+
df = df.rename(columns={'RELH': 'RH'})
|
|
694
793
|
pressure = df['PRES'].values * _units('hPa')
|
|
695
794
|
temperature = df['TEMP'].values * _units('degC')
|
|
696
795
|
dewpoint = df['DWPT'].values * _units('degC')
|
|
@@ -701,13 +800,17 @@ def get_observed_sounding_data(station_id,
|
|
|
701
800
|
df['WET-BULB'] = _mpcalc.wet_bulb_temperature(pressure, temperature, dewpoint)
|
|
702
801
|
|
|
703
802
|
try:
|
|
704
|
-
df_24 =
|
|
705
|
-
|
|
803
|
+
df_24 = _parse_sounding_text(
|
|
804
|
+
data_24,
|
|
805
|
+
usecols=[0, 1, 2, 3, 4, 5, 6, 7],
|
|
806
|
+
names=col_names,
|
|
807
|
+
widths=[7] * 8,
|
|
808
|
+
)
|
|
706
809
|
except Exception as e:
|
|
707
810
|
_exceptions.station_id_exception(station_id)
|
|
708
811
|
|
|
709
812
|
df_24['U-WIND'], df_24['V-WIND'] = _get_u_and_v(df_24['SKNT'], df_24['DRCT'])
|
|
710
|
-
df_24
|
|
813
|
+
df_24 = df_24.rename(columns={'RELH': 'RH'})
|
|
711
814
|
pressure_24 = df_24['PRES'].values * _units('hPa')
|
|
712
815
|
temperature_24 = df_24['TEMP'].values * _units('degC')
|
|
713
816
|
dewpoint_24 = df_24['DWPT'].values * _units('degC')
|
|
@@ -724,20 +827,3 @@ def get_observed_sounding_data(station_id,
|
|
|
724
827
|
df_24.dropna(axis=0, inplace=True)
|
|
725
828
|
|
|
726
829
|
return df, df_24, date, date_24
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: wxdata
|
|
3
|
-
Version: 2.0.
|
|
3
|
+
Version: 2.0.4
|
|
4
4
|
Summary: A Python package of end-to-end weather data clients & raw data clients with VPN/PROXY support, data processors that decode variable keys from GRIB format into a plain-language format & various tools for assisting Python automated workflows, querying meteorological datasets and filling gaps in meteorological data.
|
|
5
5
|
Author: Eric J. Drewitz
|
|
6
6
|
Project-URL: Documentation, https://github.com/edrewitz/wxdata/blob/main/Documentation/Landing%20Page.md
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|