windborne 1.2.4__py3-none-any.whl → 1.2.5__py3-none-any.whl
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.
- windborne/__init__.py +6 -2
- windborne/cli.py +21 -1
- windborne/forecasts_api.py +38 -0
- {windborne-1.2.4.dist-info → windborne-1.2.5.dist-info}/METADATA +1 -1
- windborne-1.2.5.dist-info/RECORD +13 -0
- windborne-1.2.4.dist-info/RECORD +0 -13
- {windborne-1.2.4.dist-info → windborne-1.2.5.dist-info}/WHEEL +0 -0
- {windborne-1.2.4.dist-info → windborne-1.2.5.dist-info}/entry_points.txt +0 -0
- {windborne-1.2.4.dist-info → windborne-1.2.5.dist-info}/top_level.txt +0 -0
windborne/__init__.py
CHANGED
@@ -39,7 +39,9 @@ from .forecasts_api import (
|
|
39
39
|
get_historical_500hpa_geopotential,
|
40
40
|
get_historical_500hpa_wind_u, get_historical_500hpa_wind_v,
|
41
41
|
|
42
|
-
get_tropical_cyclones
|
42
|
+
get_tropical_cyclones,
|
43
|
+
|
44
|
+
get_population_weighted_hdd
|
43
45
|
)
|
44
46
|
|
45
47
|
# Define what should be available when users import *
|
@@ -82,5 +84,7 @@ __all__ = [
|
|
82
84
|
"get_historical_500hpa_geopotential",
|
83
85
|
"get_historical_500hpa_wind_u",
|
84
86
|
"get_historical_500hpa_wind_v",
|
85
|
-
"get_tropical_cyclones"
|
87
|
+
"get_tropical_cyclones",
|
88
|
+
|
89
|
+
"get_population_weighted_hdd"
|
86
90
|
]
|
windborne/cli.py
CHANGED
@@ -23,7 +23,8 @@ from . import (
|
|
23
23
|
get_generation_times,
|
24
24
|
get_full_gridded_forecast,
|
25
25
|
get_gridded_forecast,
|
26
|
-
get_tropical_cyclones
|
26
|
+
get_tropical_cyclones,
|
27
|
+
get_population_weighted_hdd
|
27
28
|
|
28
29
|
)
|
29
30
|
|
@@ -226,6 +227,14 @@ def main():
|
|
226
227
|
tropical_cyclones_parser.add_argument('args', nargs='*',
|
227
228
|
help='[optional: initialization time (YYYYMMDDHH, YYYY-MM-DDTHH, or YYYY-MM-DDTHH:mm:ss)] output_file')
|
228
229
|
|
230
|
+
# Population Weighted HDD Command
|
231
|
+
hdd_parser = subparsers.add_parser('hdd', help='Get population weighted heating degree days (HDD) forecasts')
|
232
|
+
hdd_parser.add_argument('initialization_time', help='Initialization time (YYYYMMDDHH, YYYY-MM-DDTHH, or YYYY-MM-DDTHH:mm:ss)')
|
233
|
+
hdd_parser.add_argument('-i', '--intracycle', action='store_true', help='Use the intracycle forecast')
|
234
|
+
hdd_parser.add_argument('-e', '--ens-member', help='Ensemble member (eg 1 or mean)')
|
235
|
+
hdd_parser.add_argument('-m', '--external-model', help='External model (eg gfs, ifs, hrrr, aifs)')
|
236
|
+
hdd_parser.add_argument('-o', '--output', help='Output file (supports .csv and .json formats)')
|
237
|
+
|
229
238
|
# Initialization Times Command
|
230
239
|
initialization_times_parser = subparsers.add_parser('init_times', help='Get available initialization times for point forecasts')
|
231
240
|
initialization_times_parser.add_argument('-i', '--intracycle', action='store_true', help='Use the intracycle forecast')
|
@@ -527,6 +536,17 @@ def main():
|
|
527
536
|
print("Error: Too many arguments")
|
528
537
|
print("Usage: windborne tropical_cyclones [initialization_time] output_file")
|
529
538
|
|
539
|
+
elif args.command == 'hdd':
|
540
|
+
# Handle population weighted HDD
|
541
|
+
get_population_weighted_hdd(
|
542
|
+
initialization_time=args.initialization_time,
|
543
|
+
intracycle=args.intracycle,
|
544
|
+
ens_member=args.ens_member,
|
545
|
+
external_model=args.external_model,
|
546
|
+
output_file=args.output,
|
547
|
+
print_response=(not args.output)
|
548
|
+
)
|
549
|
+
|
530
550
|
else:
|
531
551
|
parser.print_help()
|
532
552
|
|
windborne/forecasts_api.py
CHANGED
@@ -389,3 +389,41 @@ def download_and_save_output(output_file, response, silent=False):
|
|
389
389
|
if not silent:
|
390
390
|
print(f"Error processing the file: {e}")
|
391
391
|
return False
|
392
|
+
|
393
|
+
def get_population_weighted_hdd(initialization_time, intracycle=False, ens_member=None, external_model=None, output_file=None, print_response=False):
|
394
|
+
"""
|
395
|
+
Get population weighted HDD data from the API.
|
396
|
+
"""
|
397
|
+
params = {
|
398
|
+
"initialization_time": initialization_time,
|
399
|
+
"intracycle": intracycle,
|
400
|
+
"ens_member": ens_member,
|
401
|
+
"external_model": external_model
|
402
|
+
}
|
403
|
+
response = make_api_request(f"{FORECASTS_API_BASE_URL}/hdd", params=params, as_json=True)
|
404
|
+
|
405
|
+
if output_file:
|
406
|
+
if output_file.endswith('.csv'):
|
407
|
+
import csv
|
408
|
+
|
409
|
+
# save as csv, with a row for each region, and a column for each date, sorted alphabetically by region
|
410
|
+
regions = sorted(response['hdd'].keys())
|
411
|
+
dates = response['dates']
|
412
|
+
data = [[response['hdd'][region][dates[i]] for region in regions] for i in range(len(dates))]
|
413
|
+
|
414
|
+
with open(output_file, 'w') as f:
|
415
|
+
writer = csv.writer(f)
|
416
|
+
writer.writerow(['Region'] + dates)
|
417
|
+
|
418
|
+
for region in regions:
|
419
|
+
writer.writerow([region] + [response['hdd'][region][date] for date in dates])
|
420
|
+
|
421
|
+
if print_response:
|
422
|
+
dates = response['dates']
|
423
|
+
print(response['hdd']['Alabama'])
|
424
|
+
for region in sorted(response['hdd'].keys()):
|
425
|
+
print(f"{region}:")
|
426
|
+
for i in range(len(dates)):
|
427
|
+
print(f" {dates[i]}: {response['hdd'][region][dates[i]]}")
|
428
|
+
|
429
|
+
return response
|
@@ -0,0 +1,13 @@
|
|
1
|
+
windborne/__init__.py,sha256=tbcmwRlhTZAZCzOBeGSuaiOArA1OK-j94ZvEQN910eE,2172
|
2
|
+
windborne/api_request.py,sha256=moFKZFKMrHCINtve6ZfQYgrGgd6tXQffVGuNkZzprV4,8508
|
3
|
+
windborne/cli.py,sha256=qcETAJ0KXEmdJaIVrZqC7X742K9cNo6cS3racth1IGs,30353
|
4
|
+
windborne/data_api.py,sha256=sYZkcQog8RuLErfdLLa4gC8fRkAoPGNKKQJ8i6o-LTQ,33826
|
5
|
+
windborne/forecasts_api.py,sha256=kWpUPSzuepZ0G_mwtKgts2lmxlZAzcT7UB7kzurQ6D4,18558
|
6
|
+
windborne/observation_formatting.py,sha256=c739aaun6aaYhXl5VI-SRGR-TDS355_0Bfu1t6McoiM,14993
|
7
|
+
windborne/track_formatting.py,sha256=LaLfTyjpWoOtHmReJPLViY0MKm_iPL_5I2OB_lNvGGA,10054
|
8
|
+
windborne/utils.py,sha256=H8gvZ4Lrr0UmLl25iMZs6NsZliCY_73Ved_rBIqxJg4,7240
|
9
|
+
windborne-1.2.5.dist-info/METADATA,sha256=j22__ATrIramyQnlHMxQf7bY2ds1ITdfiDs4v4ZTWlY,1304
|
10
|
+
windborne-1.2.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
11
|
+
windborne-1.2.5.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
|
12
|
+
windborne-1.2.5.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
|
13
|
+
windborne-1.2.5.dist-info/RECORD,,
|
windborne-1.2.4.dist-info/RECORD
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
windborne/__init__.py,sha256=dslI8_5Wozr96w7c0E7_HEpYIHt9YaTLo3ADF2yapSk,2102
|
2
|
-
windborne/api_request.py,sha256=moFKZFKMrHCINtve6ZfQYgrGgd6tXQffVGuNkZzprV4,8508
|
3
|
-
windborne/cli.py,sha256=TzEZtfzOgMgPU11ARgJ6O3YZFV3TcXPPYOabHBKb01Y,29247
|
4
|
-
windborne/data_api.py,sha256=sYZkcQog8RuLErfdLLa4gC8fRkAoPGNKKQJ8i6o-LTQ,33826
|
5
|
-
windborne/forecasts_api.py,sha256=mg7rJkBUE9xSyKIx4RMN0-RIZBdqqSz7Jp5JqFg8DhI,17053
|
6
|
-
windborne/observation_formatting.py,sha256=c739aaun6aaYhXl5VI-SRGR-TDS355_0Bfu1t6McoiM,14993
|
7
|
-
windborne/track_formatting.py,sha256=LaLfTyjpWoOtHmReJPLViY0MKm_iPL_5I2OB_lNvGGA,10054
|
8
|
-
windborne/utils.py,sha256=H8gvZ4Lrr0UmLl25iMZs6NsZliCY_73Ved_rBIqxJg4,7240
|
9
|
-
windborne-1.2.4.dist-info/METADATA,sha256=IueZfHUEH8-ZAqiUm-pODRED1uRRsRKfecGq7lokM8E,1304
|
10
|
-
windborne-1.2.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
11
|
-
windborne-1.2.4.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
|
12
|
-
windborne-1.2.4.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
|
13
|
-
windborne-1.2.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|