windborne 1.2.4__py3-none-any.whl → 1.2.6__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 CHANGED
@@ -39,7 +39,10 @@ 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,
45
+ get_population_weighted_cdd
43
46
  )
44
47
 
45
48
  # Define what should be available when users import *
@@ -82,5 +85,8 @@ __all__ = [
82
85
  "get_historical_500hpa_geopotential",
83
86
  "get_historical_500hpa_wind_u",
84
87
  "get_historical_500hpa_wind_v",
85
- "get_tropical_cyclones"
88
+ "get_tropical_cyclones",
89
+
90
+ "get_population_weighted_hdd",
91
+ "get_population_weighted_cdd"
86
92
  ]
windborne/cli.py CHANGED
@@ -23,7 +23,9 @@ 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,
28
+ get_population_weighted_cdd
27
29
 
28
30
  )
29
31
 
@@ -226,6 +228,22 @@ def main():
226
228
  tropical_cyclones_parser.add_argument('args', nargs='*',
227
229
  help='[optional: initialization time (YYYYMMDDHH, YYYY-MM-DDTHH, or YYYY-MM-DDTHH:mm:ss)] output_file')
228
230
 
231
+ # Population Weighted HDD Command
232
+ hdd_parser = subparsers.add_parser('hdd', help='Get population weighted heating degree days (HDD) forecasts')
233
+ hdd_parser.add_argument('initialization_time', help='Initialization time (YYYYMMDDHH, YYYY-MM-DDTHH, or YYYY-MM-DDTHH:mm:ss)')
234
+ hdd_parser.add_argument('-i', '--intracycle', action='store_true', help='Use the intracycle forecast')
235
+ hdd_parser.add_argument('-e', '--ens-member', help='Ensemble member (eg 1 or mean)')
236
+ hdd_parser.add_argument('-m', '--external-model', help='External model (eg gfs, ifs, hrrr, aifs)')
237
+ hdd_parser.add_argument('-o', '--output', help='Output file (supports .csv and .json formats)')
238
+
239
+ # Population Weighted CDD Command
240
+ cdd_parser = subparsers.add_parser('cdd', help='Get population weighted cooling degree days (CDD) forecasts')
241
+ cdd_parser.add_argument('initialization_time', help='Initialization time (YYYYMMDDHH, YYYY-MM-DDTHH, or YYYY-MM-DDTHH:mm:ss)')
242
+ cdd_parser.add_argument('-i', '--intracycle', action='store_true', help='Use the intracycle forecast')
243
+ cdd_parser.add_argument('-e', '--ens-member', help='Ensemble member (eg 1 or mean)')
244
+ cdd_parser.add_argument('-m', '--external-model', help='External model (eg gfs, ifs, hrrr, aifs)')
245
+ cdd_parser.add_argument('-o', '--output', help='Output file (supports .csv and .json formats)')
246
+
229
247
  # Initialization Times Command
230
248
  initialization_times_parser = subparsers.add_parser('init_times', help='Get available initialization times for point forecasts')
231
249
  initialization_times_parser.add_argument('-i', '--intracycle', action='store_true', help='Use the intracycle forecast')
@@ -527,6 +545,28 @@ def main():
527
545
  print("Error: Too many arguments")
528
546
  print("Usage: windborne tropical_cyclones [initialization_time] output_file")
529
547
 
548
+ elif args.command == 'hdd':
549
+ # Handle population weighted HDD
550
+ get_population_weighted_hdd(
551
+ initialization_time=args.initialization_time,
552
+ intracycle=args.intracycle,
553
+ ens_member=args.ens_member,
554
+ external_model=args.external_model,
555
+ output_file=args.output,
556
+ print_response=(not args.output)
557
+ )
558
+
559
+ elif args.command == 'cdd':
560
+ # Handle population weighted CDD
561
+ get_population_weighted_cdd(
562
+ initialization_time=args.initialization_time,
563
+ intracycle=args.intracycle,
564
+ ens_member=args.ens_member,
565
+ external_model=args.external_model,
566
+ output_file=args.output,
567
+ print_response=(not args.output)
568
+ )
569
+
530
570
  else:
531
571
  parser.print_help()
532
572
 
@@ -389,3 +389,79 @@ 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
430
+
431
+ def get_population_weighted_cdd(initialization_time, intracycle=False, ens_member=None, external_model=None, output_file=None, print_response=False):
432
+ """
433
+ Get population weighted CDD data from the API.
434
+ """
435
+ params = {
436
+ "initialization_time": initialization_time,
437
+ "intracycle": intracycle,
438
+ "ens_member": ens_member,
439
+ "external_model": external_model
440
+ }
441
+ response = make_api_request(f"{FORECASTS_API_BASE_URL}/cdd", params=params, as_json=True)
442
+
443
+ if output_file:
444
+ if output_file.endswith('.csv'):
445
+ import csv
446
+
447
+ # save as csv, with a row for each region, and a column for each date, sorted alphabetically by region
448
+ regions = sorted(response['cdd'].keys())
449
+ dates = response['dates']
450
+ data = [[response['cdd'][region][dates[i]] for region in regions] for i in range(len(dates))]
451
+
452
+ with open(output_file, 'w') as f:
453
+ writer = csv.writer(f)
454
+ writer.writerow(['Region'] + dates)
455
+
456
+ for region in regions:
457
+ writer.writerow([region] + [response['cdd'][region][date] for date in dates])
458
+
459
+ if print_response:
460
+ dates = response['dates']
461
+ print(response['cdd']['Alabama'])
462
+ for region in sorted(response['cdd'].keys()):
463
+ print(f"{region}:")
464
+ for i in range(len(dates)):
465
+ print(f" {dates[i]}: {response['cdd'][region][dates[i]]}")
466
+
467
+ return response
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: windborne
3
- Version: 1.2.4
3
+ Version: 1.2.6
4
4
  Summary: A Python library for interacting with WindBorne Data and Forecasts API
5
5
  Author-email: WindBorne Systems <data@windbornesystems.com>
6
6
  Classifier: Programming Language :: Python :: 3
@@ -0,0 +1,13 @@
1
+ windborne/__init__.py,sha256=eTmMmiGDOwvecD4Eyfe13v0dn8yU9PqpwZbce9xLkpE,2240
2
+ windborne/api_request.py,sha256=moFKZFKMrHCINtve6ZfQYgrGgd6tXQffVGuNkZzprV4,8508
3
+ windborne/cli.py,sha256=qjXfyPPKTvrssl2Mr2X2NsIxsJw31slffoic0GoY3eE,31459
4
+ windborne/data_api.py,sha256=sYZkcQog8RuLErfdLLa4gC8fRkAoPGNKKQJ8i6o-LTQ,33826
5
+ windborne/forecasts_api.py,sha256=TPSR25_GiFnQrWharrefSGpxN5300Un0d4sx1sFIN6E,20063
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.6.dist-info/METADATA,sha256=7P5KLbZ0q6HFRZ4ANStCOXGkHPeF3Bk0WDd6MAtt1SI,1304
10
+ windborne-1.2.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
11
+ windborne-1.2.6.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
12
+ windborne-1.2.6.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
13
+ windborne-1.2.6.dist-info/RECORD,,
@@ -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,,