windborne 1.0.1__py3-none-any.whl → 1.0.2__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/utils.py CHANGED
@@ -277,7 +277,7 @@ def save_csv_json(save_to_file, response, csv_data_key=None):
277
277
  json.dump(response, f, indent=4)
278
278
  print("Saved to", save_to_file)
279
279
  elif save_to_file.lower().endswith('.csv'):
280
- # Extract data for CSV if a key is provided
280
+ # Extract data for CSV if a key is provided
281
281
  data = response if not csv_data_key else response.get(csv_data_key, [])
282
282
  if not data:
283
283
  print("No data available to save to CSV.")
@@ -364,8 +364,11 @@ def convert_to_netcdf(data, curtime, output_filename=None):
364
364
  # Handle dropsondes
365
365
  mission_name = str(df['mission_name'].iloc[0]) if (not df.empty and not pd.isna(df['mission_name'].iloc[0])) else ' '
366
366
 
367
+ is_multi_mission = False
368
+
367
369
  if output_filename:
368
370
  output_file = output_filename
371
+ is_multi_mission = True # we should calculate this directly, rather than relying on the filename
369
372
  else:
370
373
  output_file = f"WindBorne_{mission_name}_{mt.year:04d}-{mt.month:02d}-{mt.day:02d}_{mt.hour:02d}.nc"
371
374
 
@@ -386,8 +389,7 @@ def convert_to_netcdf(data, curtime, output_filename=None):
386
389
  ds = ds.assign_coords(time=("time", ds['time'].data))
387
390
 
388
391
  # Now that calculations are done, remove variables not needed in the netcdf output
389
- variables_to_drop = ['humidity', 'speed_u', 'speed_v', 'speed_x', 'speed_y', 'specific_humidity',
390
- 'timestamp', 'mission_name']
392
+ variables_to_drop = ['humidity', 'speed_x', 'speed_y', 'timestamp', 'mission_name']
391
393
  existing_vars = [var for var in variables_to_drop if var in ds]
392
394
  ds = ds.drop_vars(existing_vars)
393
395
 
@@ -395,33 +397,91 @@ def convert_to_netcdf(data, curtime, output_filename=None):
395
397
  ds = ds.rename(rename_dict)
396
398
 
397
399
  # Adding attributes to variables in the xarray dataset
398
- ds['time'].attrs = {'units': 'seconds since 1970-01-01T00:00:00', 'long_name': 'Time', '_FillValue': float('nan'),
399
- 'processing_level': ''}
400
- ds['lat'].attrs = {'units': 'degrees_north', 'long_name': 'Latitude', '_FillValue': float('nan'),
401
- 'processing_level': ''}
402
- ds['lon'].attrs = {'units': 'degrees_east', 'long_name': 'Longitude', '_FillValue': float('nan'),
403
- 'processing_level': ''}
404
- ds['altitude'].attrs = {'units': 'meters_above_sea_level', 'long_name': 'Altitude', '_FillValue': float('nan'),
405
- 'processing_level': ''}
406
- ds['air_temperature'].attrs = {'units': 'Kelvin', 'long_name': 'Air Temperature', '_FillValue': float('nan'),
407
- 'processing_level': ''}
408
- ds['wind_speed'].attrs = {'units': 'm/s', 'long_name': 'Wind Speed', '_FillValue': float('nan'),
409
- 'processing_level': ''}
410
- ds['wind_direction'].attrs = {'units': 'degrees', 'long_name': 'Wind Direction', '_FillValue': float('nan'),
411
- 'processing_level': ''}
412
- ds['humidity_mixing_ratio'].attrs = {'units': 'kg/kg', 'long_name': 'Humidity Mixing Ratio',
413
- '_FillValue': float('nan'), 'processing_level': ''}
414
- ds['air_pressure'].attrs = {'units': 'Pa', 'long_name': 'Atmospheric Pressure', '_FillValue': float('nan'),
415
- 'processing_level': ''}
400
+ ds['time'].attrs = {
401
+ 'units': 'seconds since 1970-01-01T00:00:00',
402
+ 'long_name': 'Time', '_FillValue': float('nan'),
403
+ 'processing_level': ''
404
+ }
405
+
406
+ ds['lat'].attrs = {
407
+ 'units': 'degrees_north',
408
+ 'long_name': 'Latitude',
409
+ '_FillValue': float('nan'),
410
+ 'processing_level': ''
411
+ }
412
+ ds['lon'].attrs = {
413
+ 'units': 'degrees_east',
414
+ 'long_name': 'Longitude',
415
+ '_FillValue': float('nan'),
416
+ 'processing_level': ''
417
+ }
418
+ ds['altitude'].attrs = {
419
+ 'units': 'meters_above_sea_level',
420
+ 'long_name': 'Altitude',
421
+ '_FillValue': float('nan'),
422
+ 'processing_level': ''
423
+ }
424
+ ds['air_temperature'].attrs = {
425
+ 'units': 'Kelvin',
426
+ 'long_name': 'Air Temperature',
427
+ '_FillValue': float('nan'),
428
+ 'processing_level': ''
429
+ }
430
+ ds['wind_speed'].attrs = {
431
+ 'units': 'm/s',
432
+ 'long_name': 'Wind Speed',
433
+ '_FillValue': float('nan'),
434
+ 'processing_level': ''
435
+ }
436
+ ds['wind_direction'].attrs = {
437
+ 'units': 'degrees',
438
+ 'long_name': 'Wind Direction',
439
+ '_FillValue': float('nan'),
440
+ 'processing_level': ''
441
+ }
442
+ ds['humidity_mixing_ratio'].attrs = {
443
+ 'units': 'kg/kg',
444
+ 'long_name': 'Humidity Mixing Ratio',
445
+ '_FillValue': float('nan'),
446
+ 'processing_level': ''
447
+ }
448
+ ds['air_pressure'].attrs = {
449
+ 'units': 'Pa',
450
+ 'long_name': 'Atmospheric Pressure',
451
+ '_FillValue': float('nan'),
452
+ 'processing_level': ''
453
+ }
454
+ ds['speed_u'].attrs = {
455
+ 'units': 'm/s',
456
+ 'long_name': 'Wind speed in direction of increasing longitude',
457
+ '_FillValue': float('nan'),
458
+ 'processing_level': ''
459
+ }
460
+ ds['speed_v'].attrs = {
461
+ 'units': 'm/s',
462
+ 'long_name': 'Wind speed in direction of increasing latitude',
463
+ '_FillValue': float('nan'),
464
+ 'processing_level': ''
465
+ }
466
+
467
+ ds['specific_humidity'].attrs = {
468
+ 'units': 'mg/kg',
469
+ 'long_name': 'Specific Humidity',
470
+ '_FillValue': float('nan'),
471
+ 'processing_level': '',
472
+ 'Conventions': "CF-1.8, WMO-CF-1.0"
473
+ }
416
474
 
417
475
  # Add Global Attributes synonymous across all UASDC providers
418
- ds.attrs['Conventions'] = "CF-1.8, WMO-CF-1.0"
419
- ds.attrs['wmo__cf_profile'] = "FM 303-2024"
420
- ds.attrs['featureType'] = "trajectory"
476
+ if not is_multi_mission:
477
+ ds.attrs['wmo__cf_profile'] = "FM 303-2024"
478
+ ds.attrs['featureType'] = "trajectory"
421
479
 
422
480
  # Add Global Attributes unique to Provider
423
481
  ds.attrs['platform_name'] = "WindBorne Global Sounding Balloon"
424
- ds.attrs['flight_id'] = mission_name
482
+ if not is_multi_mission:
483
+ ds.attrs['flight_id'] = mission_name
484
+
425
485
  ds.attrs['site_terrain_elevation_height'] = 'not applicable'
426
486
  ds.attrs['processing_level'] = "b1"
427
487
  ds.to_netcdf(output_file)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.2
2
2
  Name: windborne
3
- Version: 1.0.1
3
+ Version: 1.0.2
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
@@ -17,9 +17,16 @@ Requires-Dist: netCDF4
17
17
 
18
18
  # WindBorne API
19
19
  A Python library for interacting with the WindBorne API to fetch and process observations and forecasts data.
20
+
20
21
  ## - [Data API](https://windbornesystems.com/docs/api/pip_data)
22
+ This allows pulling observations collected by WindBorne balloons.
23
+
21
24
  ## - [Forecasts API](https://windbornesystems.com/docs/api/pip_forecasts)
25
+ This allows pulling forecasts generated by WindBorne models.
26
+
22
27
  ## - [Command Line Interface](https://windbornesystems.com/docs/api/cli)
28
+ This allows pulling data from the WindBorne API using the command line.
29
+ Run `windborne --help` for more information.
23
30
 
24
31
  ## Further information and help request
25
- If you encounter issues or have questions, please ask your WindBorne Systems contact.
32
+ If you encounter issues or have questions, please ask your WindBorne Systems contact or email data@windbornesystems.com.
@@ -3,9 +3,9 @@ windborne/cli.py,sha256=ZNqeIlWqlKE4iCo8kptUH6Wbish0T8O7-Hljt-gEi9Q,31031
3
3
  windborne/config.py,sha256=FYIBRiIuii5igAFQlOsHUa6u2i1kKnO1yZE7QfQJvUg,1688
4
4
  windborne/data_api.py,sha256=dnF54sLPYRU5dect3WxmonbHKUjihfE9dVdpaT-fylk,35560
5
5
  windborne/forecasts_api.py,sha256=AYuhFRls_XvzuNB55NF0w3y-_ocYwPxmI6C1lIyFkgM,16865
6
- windborne/utils.py,sha256=B6aW-pGJoom8IjahrCE5UgKujSIVsfh7bjPXn4lZoq0,37594
7
- windborne-1.0.1.dist-info/METADATA,sha256=6CTHgHt5zwR3-YD0s2n1fxPDdrZddjM7y080zO8FTOQ,982
8
- windborne-1.0.1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
- windborne-1.0.1.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
10
- windborne-1.0.1.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
11
- windborne-1.0.1.dist-info/RECORD,,
6
+ windborne/utils.py,sha256=4-6HzfkSRF2l6S37Otu1HywzmxTVCW84InroBCpStFo,38369
7
+ windborne-1.0.2.dist-info/METADATA,sha256=o42RejgsI8-Hpc3Pno6gG4eJeAIPun9rzws48Svwz4Q,1264
8
+ windborne-1.0.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
9
+ windborne-1.0.2.dist-info/entry_points.txt,sha256=j_YrqdCDrCd7p5MIwQ2BYwNXEi95VNANzLRJmcXEg1U,49
10
+ windborne-1.0.2.dist-info/top_level.txt,sha256=PE9Lauriu5S5REf7JKhXprufZ_V5RiZ_TnfnrLGJrmE,10
11
+ windborne-1.0.2.dist-info/RECORD,,