windborne 1.2.5__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
@@ -41,7 +41,8 @@ from .forecasts_api import (
41
41
 
42
42
  get_tropical_cyclones,
43
43
 
44
- get_population_weighted_hdd
44
+ get_population_weighted_hdd,
45
+ get_population_weighted_cdd
45
46
  )
46
47
 
47
48
  # Define what should be available when users import *
@@ -86,5 +87,6 @@ __all__ = [
86
87
  "get_historical_500hpa_wind_v",
87
88
  "get_tropical_cyclones",
88
89
 
89
- "get_population_weighted_hdd"
90
+ "get_population_weighted_hdd",
91
+ "get_population_weighted_cdd"
90
92
  ]
windborne/cli.py CHANGED
@@ -24,7 +24,8 @@ from . import (
24
24
  get_full_gridded_forecast,
25
25
  get_gridded_forecast,
26
26
  get_tropical_cyclones,
27
- get_population_weighted_hdd
27
+ get_population_weighted_hdd,
28
+ get_population_weighted_cdd
28
29
 
29
30
  )
30
31
 
@@ -235,6 +236,14 @@ def main():
235
236
  hdd_parser.add_argument('-m', '--external-model', help='External model (eg gfs, ifs, hrrr, aifs)')
236
237
  hdd_parser.add_argument('-o', '--output', help='Output file (supports .csv and .json formats)')
237
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
+
238
247
  # Initialization Times Command
239
248
  initialization_times_parser = subparsers.add_parser('init_times', help='Get available initialization times for point forecasts')
240
249
  initialization_times_parser.add_argument('-i', '--intracycle', action='store_true', help='Use the intracycle forecast')
@@ -547,6 +556,17 @@ def main():
547
556
  print_response=(not args.output)
548
557
  )
549
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
+
550
570
  else:
551
571
  parser.print_help()
552
572
 
@@ -427,3 +427,41 @@ def get_population_weighted_hdd(initialization_time, intracycle=False, ens_membe
427
427
  print(f" {dates[i]}: {response['hdd'][region][dates[i]]}")
428
428
 
429
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.5
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=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,,