pypromice 1.4.3__tar.gz → 1.4.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.
Potentially problematic release.
This version of pypromice might be problematic. Click here for more details.
- {pypromice-1.4.3/src/pypromice.egg-info → pypromice-1.4.4}/PKG-INFO +1 -1
- {pypromice-1.4.3 → pypromice-1.4.4}/setup.py +1 -1
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/bufr_utilities.py +2 -1
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/L1toL2.py +30 -24
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/value_clipping.py +15 -12
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/resources/variables.csv +32 -32
- pypromice-1.4.4/src/pypromice/utilities/dependency_graph.py +101 -0
- {pypromice-1.4.3 → pypromice-1.4.4/src/pypromice.egg-info}/PKG-INFO +1 -1
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice.egg-info/SOURCES.txt +1 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/LICENSE.txt +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/MANIFEST.in +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/README.md +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/setup.cfg +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/get/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/get/get.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/get/get_promice_data.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/bufr_to_csv.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/create_bufr_files.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/get_bufr.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/make_metadata_csv.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/positions_seed.csv +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/postprocess/real_time_utilities.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/L0toL1.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/L2toL3.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/aws.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/get_l2.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/get_l2tol3.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/join_l2.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/join_l3.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/load.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/resample.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/utilities.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/process/write.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/github_data_issues.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/percentiles/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/percentiles/compute_thresholds.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/percentiles/outlier_detector.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/percentiles/thresholds.csv +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/qc/persistence.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/resources/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/resources/file_attributes.csv +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/resources/variable_aliases_GC-Net.csv +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/station_configuration.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/tx/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/tx/get_l0tx.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/tx/get_msg.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/tx/payload_formats.csv +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/tx/payload_types.csv +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/tx/tx.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/utilities/__init__.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice/utilities/git.py +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice.egg-info/dependency_links.txt +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice.egg-info/entry_points.txt +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice.egg-info/requires.txt +0 -0
- {pypromice-1.4.3 → pypromice-1.4.4}/src/pypromice.egg-info/top_level.txt +0 -0
|
@@ -5,7 +5,7 @@ with open("README.md", "r", encoding="utf-8") as fh:
|
|
|
5
5
|
|
|
6
6
|
setuptools.setup(
|
|
7
7
|
name="pypromice",
|
|
8
|
-
version="1.4.
|
|
8
|
+
version="1.4.4",
|
|
9
9
|
author="GEUS Glaciology and Climate",
|
|
10
10
|
description="PROMICE/GC-Net data processing toolbox",
|
|
11
11
|
long_description=long_description,
|
|
@@ -120,7 +120,8 @@ class BUFRVariables:
|
|
|
120
120
|
)
|
|
121
121
|
# https://vocabulary-manager.eumetsat.int/vocabularies/BUFR/WMO/32/TABLE_B/012101
|
|
122
122
|
# Scale: 2, unit: K
|
|
123
|
-
|
|
123
|
+
# NOTE: The expected scale is 2, but our instantanous data is rounded to 1 decimal.
|
|
124
|
+
airTemperature: float = attrs.field(converter=round_converter(1))
|
|
124
125
|
# There is also a Dewpoint temperature in this template: 012103 which is currently unused.
|
|
125
126
|
# https://vocabulary-manager.eumetsat.int/vocabularies/BUFR/WMO/32/TABLE_B/012103
|
|
126
127
|
# Scale: 0, unit: %
|
|
@@ -94,7 +94,7 @@ def toL2(
|
|
|
94
94
|
.ffill().bfill())
|
|
95
95
|
mask = (np.abs(ds.gps_alt - baseline_elevation) < 100) & ds.gps_alt.notnull()
|
|
96
96
|
ds[['gps_alt','gps_lon', 'gps_lat']] = ds[['gps_alt','gps_lon', 'gps_lat']].where(mask)
|
|
97
|
-
|
|
97
|
+
|
|
98
98
|
# removing dlr and ulr that are missing t_rad
|
|
99
99
|
# this is done now becasue t_rad can be filtered either manually or with persistence
|
|
100
100
|
ds['dlr'] = ds.dlr.where(ds.t_rad.notnull())
|
|
@@ -113,12 +113,12 @@ def toL2(
|
|
|
113
113
|
if ~ds['t_i'].isnull().all():
|
|
114
114
|
ds['rh_i_cor'] = correctHumidity(ds['rh_i'], ds['t_i'],
|
|
115
115
|
T_0, T_100, ews, ei0)
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
# Determiune cloud cover for on-ice stations
|
|
118
118
|
cc = calcCloudCoverage(ds['t_u'], T_0, eps_overcast, eps_clear, # Calculate cloud coverage
|
|
119
119
|
ds['dlr'], ds.attrs['station_id'])
|
|
120
120
|
ds['cc'] = (('time'), cc.data)
|
|
121
|
-
|
|
121
|
+
|
|
122
122
|
# Determine surface temperature
|
|
123
123
|
ds['t_surf'] = calcSurfaceTemperature(T_0, ds['ulr'], ds['dlr'], # Calculate surface temperature
|
|
124
124
|
emissivity)
|
|
@@ -136,7 +136,7 @@ def toL2(
|
|
|
136
136
|
else:
|
|
137
137
|
lat = ds['gps_lat'].mean()
|
|
138
138
|
lon = ds['gps_lon'].mean()
|
|
139
|
-
|
|
139
|
+
|
|
140
140
|
# smoothing tilt and rot
|
|
141
141
|
ds['tilt_x'] = smoothTilt(ds['tilt_x'])
|
|
142
142
|
ds['tilt_y'] = smoothTilt(ds['tilt_y'])
|
|
@@ -151,8 +151,8 @@ def toL2(
|
|
|
151
151
|
ZenithAngle_rad, ZenithAngle_deg = calcZenith(lat, Declination_rad, # Calculate zenith
|
|
152
152
|
HourAngle_rad, deg2rad,
|
|
153
153
|
rad2deg)
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
|
|
155
|
+
|
|
156
156
|
# Correct Downwelling shortwave radiation
|
|
157
157
|
DifFrac = 0.2 + 0.8 * cc
|
|
158
158
|
CorFac_all = calcCorrectionFactor(Declination_rad, phi_sensor_rad, # Calculate correction
|
|
@@ -186,9 +186,9 @@ def toL2(
|
|
|
186
186
|
TOA_crit_nopass = (ds['dsr_cor'] > (0.9 * isr_toa + 10)) # Determine filter
|
|
187
187
|
ds['dsr_cor'][TOA_crit_nopass] = np.nan # Apply filter and interpolate
|
|
188
188
|
ds['usr_cor'][TOA_crit_nopass] = np.nan
|
|
189
|
-
|
|
190
|
-
ds['dsr_cor'] = ds.dsr_cor.where(ds.dsr.notnull())
|
|
191
|
-
ds['usr_cor'] = ds.usr_cor.where(ds.usr.notnull())
|
|
189
|
+
|
|
190
|
+
ds['dsr_cor'] = ds.dsr_cor.where(ds.dsr.notnull())
|
|
191
|
+
ds['usr_cor'] = ds.usr_cor.where(ds.usr.notnull())
|
|
192
192
|
# # Check sun position
|
|
193
193
|
# sundown = ZenithAngle_deg >= 90
|
|
194
194
|
# _checkSunPos(ds, OKalbedos, sundown, sunonlowerdome, TOA_crit_nopass)
|
|
@@ -205,27 +205,33 @@ def toL2(
|
|
|
205
205
|
ds['precip_l_cor'], ds['precip_l_rate']= correctPrecip(ds['precip_l'],
|
|
206
206
|
ds['wspd_l'])
|
|
207
207
|
|
|
208
|
-
# Get directional wind speed
|
|
209
|
-
|
|
210
|
-
ds
|
|
208
|
+
get_directional_wind_speed(ds) # Get directional wind speed
|
|
209
|
+
|
|
210
|
+
ds = clip_values(ds, vars_df)
|
|
211
|
+
return ds
|
|
212
|
+
|
|
213
|
+
def get_directional_wind_speed(ds: xr.Dataset) -> xr.Dataset:
|
|
214
|
+
"""
|
|
215
|
+
Calculate directional wind speed from wind speed and direction and mutates the dataset
|
|
216
|
+
"""
|
|
217
|
+
|
|
218
|
+
ds['wdir_u'] = ds['wdir_u'].where(ds['wspd_u'] != 0)
|
|
219
|
+
ds['wspd_x_u'], ds['wspd_y_u'] = calcDirWindSpeeds(ds['wspd_u'], ds['wdir_u'])
|
|
211
220
|
|
|
212
|
-
if ds.attrs['number_of_booms']==2:
|
|
213
|
-
ds['wdir_l'] = ds['wdir_l'].where(ds['wspd_l'] != 0)
|
|
221
|
+
if ds.attrs['number_of_booms']==2:
|
|
222
|
+
ds['wdir_l'] = ds['wdir_l'].where(ds['wspd_l'] != 0)
|
|
214
223
|
ds['wspd_x_l'], ds['wspd_y_l'] = calcDirWindSpeeds(ds['wspd_l'], ds['wdir_l'])
|
|
215
224
|
|
|
216
225
|
if hasattr(ds, 'wdir_i'):
|
|
217
226
|
if ~ds['wdir_i'].isnull().all() and ~ds['wspd_i'].isnull().all():
|
|
218
|
-
ds['wdir_i'] = ds['wdir_i'].where(ds['wspd_i'] != 0)
|
|
219
|
-
ds['wspd_x_i'], ds['wspd_y_i'] = calcDirWindSpeeds(ds['wspd_i'], ds['wdir_i'])
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
ds = clip_values(ds, vars_df)
|
|
227
|
+
ds['wdir_i'] = ds['wdir_i'].where(ds['wspd_i'] != 0)
|
|
228
|
+
ds['wspd_x_i'], ds['wspd_y_i'] = calcDirWindSpeeds(ds['wspd_i'], ds['wdir_i'])
|
|
223
229
|
return ds
|
|
224
230
|
|
|
225
231
|
|
|
226
232
|
def calcDirWindSpeeds(wspd, wdir, deg2rad=np.pi/180):
|
|
227
233
|
'''Calculate directional wind speed from wind speed and direction
|
|
228
|
-
|
|
234
|
+
|
|
229
235
|
Parameters
|
|
230
236
|
----------
|
|
231
237
|
wspd : xr.Dataarray
|
|
@@ -234,16 +240,16 @@ def calcDirWindSpeeds(wspd, wdir, deg2rad=np.pi/180):
|
|
|
234
240
|
Wind direction data array
|
|
235
241
|
deg2rad : float
|
|
236
242
|
Degree to radians coefficient. The default is np.pi/180
|
|
237
|
-
|
|
243
|
+
|
|
238
244
|
Returns
|
|
239
245
|
-------
|
|
240
246
|
wspd_x : xr.Dataarray
|
|
241
247
|
Wind speed in X direction
|
|
242
248
|
wspd_y : xr.Datarray
|
|
243
249
|
Wind speed in Y direction
|
|
244
|
-
'''
|
|
250
|
+
'''
|
|
245
251
|
wspd_x = wspd * np.sin(wdir * deg2rad)
|
|
246
|
-
wspd_y = wspd * np.cos(wdir * deg2rad)
|
|
252
|
+
wspd_y = wspd * np.cos(wdir * deg2rad)
|
|
247
253
|
return wspd_x, wspd_y
|
|
248
254
|
|
|
249
255
|
|
|
@@ -328,7 +334,7 @@ def smoothTilt(da: xr.DataArray, threshold=0.2):
|
|
|
328
334
|
either X or Y smoothed tilt inclinometer measurements
|
|
329
335
|
'''
|
|
330
336
|
# we calculate the moving standard deviation over a 3-day sliding window
|
|
331
|
-
# hourly resampling is necessary to make sure the same threshold can be used
|
|
337
|
+
# hourly resampling is necessary to make sure the same threshold can be used
|
|
332
338
|
# for 10 min and hourly data
|
|
333
339
|
moving_std_gap_filled = da.to_series().resample('h').median().rolling(
|
|
334
340
|
3*24, center=True, min_periods=2
|
|
@@ -2,6 +2,8 @@ import numpy as np
|
|
|
2
2
|
import pandas
|
|
3
3
|
import xarray
|
|
4
4
|
|
|
5
|
+
from pypromice.utilities.dependency_graph import DependencyGraph
|
|
6
|
+
|
|
5
7
|
|
|
6
8
|
def clip_values(
|
|
7
9
|
ds: xarray.Dataset,
|
|
@@ -27,9 +29,15 @@ def clip_values(
|
|
|
27
29
|
cols = ["lo", "hi", "OOL"]
|
|
28
30
|
assert set(cols) <= set(var_configurations.columns)
|
|
29
31
|
|
|
30
|
-
variable_limits = var_configurations[cols].
|
|
31
|
-
|
|
32
|
+
variable_limits = var_configurations[cols].assign(
|
|
33
|
+
dependents=lambda df: df.OOL.fillna("").str.split(),
|
|
34
|
+
# Find the closure of dependents using the DependencyGraph class
|
|
35
|
+
dependents_closure=lambda df: DependencyGraph.from_child_mapping(
|
|
36
|
+
df.dependents
|
|
37
|
+
).child_closure_mapping(),
|
|
38
|
+
)
|
|
32
39
|
|
|
40
|
+
for var, row in variable_limits.iterrows():
|
|
33
41
|
if var not in list(ds.variables):
|
|
34
42
|
continue
|
|
35
43
|
|
|
@@ -38,15 +46,10 @@ def clip_values(
|
|
|
38
46
|
if ~np.isnan(row.hi):
|
|
39
47
|
ds[var] = ds[var].where(ds[var] <= row.hi)
|
|
40
48
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
else:
|
|
47
|
-
if ~np.isnan(row.lo):
|
|
48
|
-
ds[var] = ds[var].where(ds[var] >= row.lo)
|
|
49
|
-
if ~np.isnan(row.hi):
|
|
50
|
-
ds[var] = ds[var].where(ds[var] <= row.hi)
|
|
49
|
+
# Flag dependents as NaN if parent is NaN
|
|
50
|
+
for o in row.dependents_closure:
|
|
51
|
+
if o not in list(ds.variables):
|
|
52
|
+
continue
|
|
53
|
+
ds[o] = ds[o].where(ds[var].notnull())
|
|
51
54
|
|
|
52
55
|
return ds
|
|
@@ -1,53 +1,53 @@
|
|
|
1
1
|
field,standard_name,long_name,units,coverage_content_type,coordinates,instantaneous_hourly,where_to_find,lo,hi,OOL,station_type,L0,L2,L3,max_decimals
|
|
2
2
|
time,time,Time,yyyy-mm-dd HH:MM:SS,physicalMeasurement,time,,,,,,all,1,1,1,
|
|
3
3
|
rec,record,Record,-,referenceInformation,time,,L0 or L2,,,,all,1,1,0,0
|
|
4
|
-
p_u,air_pressure,Air pressure (upper boom),hPa,physicalMeasurement,time,FALSE,,650,1100,
|
|
5
|
-
p_l,air_pressure,Air pressure (lower boom),hPa,physicalMeasurement,time,FALSE,,650,1100,
|
|
6
|
-
t_u,air_temperature,Air temperature (upper boom),degrees_C,physicalMeasurement,time,FALSE,,-80,40,
|
|
7
|
-
t_l,air_temperature,Air temperature (lower boom),degrees_C,physicalMeasurement,time,FALSE,,-80,40,
|
|
8
|
-
rh_u,relative_humidity,Relative humidity (upper boom),%,physicalMeasurement,time,FALSE,,0,100,
|
|
9
|
-
rh_u_cor,relative_humidity_corrected,Relative humidity (upper boom) - corrected,%,modelResult,time,FALSE,L2 or later,0,150,
|
|
10
|
-
qh_u,specific_humidity,Specific humidity (upper boom),kg/kg,modelResult,time,FALSE,L2 or later,0,100
|
|
11
|
-
rh_l,relative_humidity,Relative humidity (lower boom),%,physicalMeasurement,time,FALSE,,0,100,
|
|
12
|
-
rh_l_cor,relative_humidity_corrected,Relative humidity (lower boom) - corrected,%,modelResult,time,FALSE,L2 or later,0,150,
|
|
4
|
+
p_u,air_pressure,Air pressure (upper boom),hPa,physicalMeasurement,time,FALSE,,650,1100,"",all,1,1,1,4
|
|
5
|
+
p_l,air_pressure,Air pressure (lower boom),hPa,physicalMeasurement,time,FALSE,,650,1100,"",two-boom,1,1,1,4
|
|
6
|
+
t_u,air_temperature,Air temperature (upper boom),degrees_C,physicalMeasurement,time,FALSE,,-80,40,"",all,1,1,1,4
|
|
7
|
+
t_l,air_temperature,Air temperature (lower boom),degrees_C,physicalMeasurement,time,FALSE,,-80,40,"",two-boom,1,1,1,4
|
|
8
|
+
rh_u,relative_humidity,Relative humidity (upper boom),%,physicalMeasurement,time,FALSE,,0,100,"",all,1,1,1,4
|
|
9
|
+
rh_u_cor,relative_humidity_corrected,Relative humidity (upper boom) - corrected,%,modelResult,time,FALSE,L2 or later,0,150,"",all,0,1,1,4
|
|
10
|
+
qh_u,specific_humidity,Specific humidity (upper boom),kg/kg,modelResult,time,FALSE,L2 or later,0,100,"",all,0,1,1,4
|
|
11
|
+
rh_l,relative_humidity,Relative humidity (lower boom),%,physicalMeasurement,time,FALSE,,0,100,"",two-boom,1,1,1,4
|
|
12
|
+
rh_l_cor,relative_humidity_corrected,Relative humidity (lower boom) - corrected,%,modelResult,time,FALSE,L2 or later,0,150,"",two-boom,0,1,1,4
|
|
13
13
|
qh_l,specific_humidity,Specific humidity (lower boom),kg/kg,modelResult,time,FALSE,L2 or later,0,100,,two-boom,0,1,1,4
|
|
14
|
-
wspd_u,wind_speed,Wind speed (upper boom),m s-1,physicalMeasurement,time,FALSE,,0,100,
|
|
15
|
-
wspd_l,wind_speed,Wind speed (lower boom),m s-1,physicalMeasurement,time,FALSE,,0,100,
|
|
14
|
+
wspd_u,wind_speed,Wind speed (upper boom),m s-1,physicalMeasurement,time,FALSE,,0,100,wdir_u wspd_x_u wspd_y_u,all,1,1,1,4
|
|
15
|
+
wspd_l,wind_speed,Wind speed (lower boom),m s-1,physicalMeasurement,time,FALSE,,0,100,wdir_l wspd_x_l wspd_y_l,two-boom,1,1,1,4
|
|
16
16
|
wdir_u,wind_from_direction,Wind from direction (upper boom),degrees,physicalMeasurement,time,FALSE,,1,360,wspd_x_u wspd_y_u,all,1,1,1,4
|
|
17
17
|
wdir_std_u,wind_from_direction_standard_deviation,Wind from direction (standard deviation),degrees,qualityInformation,time,FALSE,L0 or L2,,,,one-boom,1,1,0,4
|
|
18
18
|
wdir_l,wind_from_direction,Wind from direction (lower boom),degrees,physicalMeasurement,time,FALSE,,1,360,wspd_x_l wspd_y_l,two-boom,1,1,1,4
|
|
19
|
-
wspd_x_u,wind_speed_from_x_direction,Wind speed from x direction (upper boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,
|
|
20
|
-
wspd_y_u,wind_speed_from_y_direction,Wind speed from y direction (upper boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,
|
|
21
|
-
wspd_x_l,wind_speed_from_x_direction,Wind speed from x direction (lower boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,
|
|
22
|
-
wspd_y_l,wind_speed_from_y_direction,Wind speed from y direction (lower boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,
|
|
23
|
-
dsr,surface_downwelling_shortwave_flux,Downwelling shortwave radiation,W m-2,physicalMeasurement,time,FALSE,,-10,1500,
|
|
19
|
+
wspd_x_u,wind_speed_from_x_direction,Wind speed from x direction (upper boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,"",all,0,1,1,4
|
|
20
|
+
wspd_y_u,wind_speed_from_y_direction,Wind speed from y direction (upper boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,"",all,0,1,1,4
|
|
21
|
+
wspd_x_l,wind_speed_from_x_direction,Wind speed from x direction (lower boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,"",two-boom,0,1,1,4
|
|
22
|
+
wspd_y_l,wind_speed_from_y_direction,Wind speed from y direction (lower boom),m s-1,modelResult,time,FALSE,L0 or L2,-100,100,"",two-boom,0,1,1,4
|
|
23
|
+
dsr,surface_downwelling_shortwave_flux,Downwelling shortwave radiation,W m-2,physicalMeasurement,time,FALSE,,-10,1500,"",all,1,1,1,4
|
|
24
24
|
dsr_cor,surface_downwelling_shortwave_flux_corrected,Downwelling shortwave radiation - corrected,W m-2,modelResult,time,FALSE,L2 or later,,,,all,0,1,1,4
|
|
25
|
-
usr,surface_upwelling_shortwave_flux,Upwelling shortwave radiation,W m-2,physicalMeasurement,time,FALSE,,-10,1000,
|
|
25
|
+
usr,surface_upwelling_shortwave_flux,Upwelling shortwave radiation,W m-2,physicalMeasurement,time,FALSE,,-10,1000,"",all,1,1,1,4
|
|
26
26
|
usr_cor,surface_upwelling_shortwave_flux_corrected,Upwelling shortwave radiation - corrected,W m-2,modelResult,time,FALSE,L2 or later,0,1000,,all,0,1,1,4
|
|
27
27
|
albedo,surface_albedo,Albedo,-,modelResult,time,FALSE,L2 or later,,,,all,0,1,1,4
|
|
28
|
-
dlr,surface_downwelling_longwave_flux,Downwelling longwave radiation,W m-2,physicalMeasurement,time,FALSE,,50,500,
|
|
29
|
-
ulr,surface_upwelling_longwave_flux,Upwelling longwave radiation,W m-2,physicalMeasurement,time,FALSE,,50,500,
|
|
28
|
+
dlr,surface_downwelling_longwave_flux,Downwelling longwave radiation,W m-2,physicalMeasurement,time,FALSE,,50,500,"",all,1,1,1,4
|
|
29
|
+
ulr,surface_upwelling_longwave_flux,Upwelling longwave radiation,W m-2,physicalMeasurement,time,FALSE,,50,500,"",all,1,1,1,4
|
|
30
30
|
cc,cloud_area_fraction,Cloud cover,%,modelResult,time,FALSE,L2 or later,,,,all,0,1,1,4
|
|
31
|
-
t_surf,surface_temperature,Surface temperature,C,modelResult,time,FALSE,L2 or later,-80,40,
|
|
31
|
+
t_surf,surface_temperature,Surface temperature,C,modelResult,time,FALSE,L2 or later,-80,40,"",all,0,1,1,4
|
|
32
32
|
dlhf_u,surface_downward_latent_heat_flux,Latent heat flux (upper boom),W m-2,modelResult,time,FALSE,L3 or later,,,,all,0,0,1,4
|
|
33
33
|
dlhf_l,surface_downward_latent_heat_flux,Latent heat flux (lower boom),W m-2,modelResult,time,FALSE,L3 or later,,,,two-boom,0,0,1,4
|
|
34
34
|
dshf_u,surface_downward_sensible_heat_flux,Sensible heat flux (upper boom),W m-2,modelResult,time,FALSE,L3 or later,,,,all,0,0,1,4
|
|
35
35
|
dshf_l,surface_downward_sensible_heat_flux,Sensible heat flux (lower boom),W m-2,modelResult,time,FALSE,L3 or later,,,,two-boom,0,0,1,4
|
|
36
|
-
z_boom_u,distance_to_surface_from_boom,Upper boom height,m,physicalMeasurement,time,TRUE,,0.3,10,
|
|
36
|
+
z_boom_u,distance_to_surface_from_boom,Upper boom height,m,physicalMeasurement,time,TRUE,,0.3,10,"",all,1,1,1,4
|
|
37
37
|
z_boom_q_u,distance_to_surface_from_boom_quality,Upper boom height (quality),-,qualityInformation,time,TRUE,L0 or L2,,,,all,1,1,0,4
|
|
38
|
-
z_boom_l,distance_to_surface_from_boom,Lower boom height,m,physicalMeasurement,time,TRUE,,0.3,5,
|
|
38
|
+
z_boom_l,distance_to_surface_from_boom,Lower boom height,m,physicalMeasurement,time,TRUE,,0.3,5,"",two-boom,1,1,1,4
|
|
39
39
|
z_boom_q_l,distance_to_surface_from_boom_quality,Lower boom height (quality),-,qualityInformation,time,TRUE,L0 or L2,,,,two-boom,1,1,0,4
|
|
40
40
|
z_stake,distance_to_surface_from_stake_assembly,Stake height,m,physicalMeasurement,time,TRUE,,0.3,8,,one-boom,1,1,1,4
|
|
41
41
|
z_stake_q,distance_to_surface_from_stake_assembly_quality,Stake height (quality),-,qualityInformation,time,TRUE,L0 or L2,,,,one-boom,1,1,0,4
|
|
42
|
-
z_pt,depth_of_pressure_transducer_in_ice,Depth of pressure transducer in ice,m,physicalMeasurement,time,FALSE,,0,30,
|
|
42
|
+
z_pt,depth_of_pressure_transducer_in_ice,Depth of pressure transducer in ice,m,physicalMeasurement,time,FALSE,,0,30,"",one-boom,1,1,1,4
|
|
43
43
|
z_pt_cor,depth_of_pressure_transducer_in_ice_corrected,Depth of pressure transducer in ice - corrected,m,modelResult,time,FALSE,L2 or later,0,30,,one-boom,0,1,1,4
|
|
44
44
|
z_surf_combined,height_of_surface_combined,"Surface height combined from multiple sensors, relative to ice surface height at installation",m,modelResult,time,FALSE,L3,,,,all,0,0,1,4
|
|
45
45
|
z_ice_surf,height_of_ice_surface,"Ice surface height, relative to ice surface height at installation and calculated from pt_cor and z_stake",m,modelResult,time,FALSE,L3,,,,one-boom,0,0,1,4
|
|
46
46
|
snow_height,height_of_snow,"Snow surface height, relative to ice surface",m,modelResult,time,FALSE,L3,0,,,one-boom,0,0,1,4
|
|
47
|
-
precip_u,precipitation,Precipitation (upper boom) (cumulative solid & liquid),mm,physicalMeasurement,time,TRUE,,0,,
|
|
47
|
+
precip_u,precipitation,Precipitation (upper boom) (cumulative solid & liquid),mm,physicalMeasurement,time,TRUE,,0,,"",all,1,1,1,4
|
|
48
48
|
precip_u_cor,precipitation_corrected,Precipitation (upper boom) (cumulative solid & liquid) – corrected,mm,modelResult,time,TRUE,L2 or later,0,,,all,0,1,1,4
|
|
49
49
|
precip_u_rate,precipitation_rate,Precipitation rate (upper boom) (cumulative solid & liquid) – corrected,mm,modelResult,time,TRUE,L2 or later,0,,,all,0,1,1,4
|
|
50
|
-
precip_l,precipitation,Precipitation (lower boom) (cumulative solid & liquid),mm,physicalMeasurement,time,TRUE,,0,,
|
|
50
|
+
precip_l,precipitation,Precipitation (lower boom) (cumulative solid & liquid),mm,physicalMeasurement,time,TRUE,,0,,"",two-boom,1,1,1,4
|
|
51
51
|
precip_l_cor,precipitation_corrected,Precipitation (lower boom) (cumulative solid & liquid) – corrected,mm,modelResult,time,TRUE,L2 or later,0,,,two-boom,0,1,1,4
|
|
52
52
|
precip_l_rate,precipitation_rate,Precipitation rate (lower boom) (cumulative solid & liquid) – corrected,mm,modelResult,time,TRUE,L2 or later,0,,,two-boom,0,1,1,4
|
|
53
53
|
t_i_1,ice_temperature_at_t1,Ice temperature at sensor 1,degrees_C,physicalMeasurement,time,FALSE,,-80,1,,all,1,1,1,4
|
|
@@ -73,8 +73,8 @@ d_t_i_9,depth_of_thermistor_9,Depth of thermistor 9,m,modelResult,time,FALSE,L3,
|
|
|
73
73
|
d_t_i_10,depth_of_thermistor_10,Depth of thermistor 10,m,modelResult,time,FALSE,L3,-10,100,,two-boom,0,0,1,4
|
|
74
74
|
d_t_i_11,depth_of_thermistor_11,Depth of thermistor 11,m,modelResult,time,FALSE,L3,-10,100,,two-boom,0,0,1,4
|
|
75
75
|
t_i_10m,10m_subsurface_temperature,10 m subsurface temperature,degrees_C,modelResult,time,FALSE,L3,-70,0,,all,0,0,1,4
|
|
76
|
-
tilt_x,platform_view_angle_x,Tilt to east,degrees,physicalMeasurement,time,FALSE,,-30,30,
|
|
77
|
-
tilt_y,platform_view_angle_y,Tilt to north,degrees,physicalMeasurement,time,FALSE,,-30,30,
|
|
76
|
+
tilt_x,platform_view_angle_x,Tilt to east,degrees,physicalMeasurement,time,FALSE,,-30,30,"",all,1,1,1,4
|
|
77
|
+
tilt_y,platform_view_angle_y,Tilt to north,degrees,physicalMeasurement,time,FALSE,,-30,30,"",all,1,1,1,4
|
|
78
78
|
rot,platform_azimuth_angle,Station rotation from true North,degrees,physicalMeasurement,time,FALSE,,0,360,,all,1,1,1,2
|
|
79
79
|
gps_lat,gps_latitude,Latitude,degrees_north,physicalMeasurement,time,TRUE,,50,83,,all,1,1,1,6
|
|
80
80
|
gps_lon,gps_longitude,Longitude,degrees_east,physicalMeasurement,time,TRUE,,5,70,,all,1,1,1,6
|
|
@@ -93,14 +93,14 @@ batt_v_ini,,,-,physicalMeasurement,time,TRUE,L0 or L2,0,30,,,1,1,0,2
|
|
|
93
93
|
batt_v_ss,battery_voltage_at_sample_start,Battery voltage (sample start),V,physicalMeasurement,time,TRUE,L0 or L2,0,30,,,1,1,0,2
|
|
94
94
|
fan_dc_u,fan_current,Fan current (upper boom),mA,physicalMeasurement,time,TRUE,L0 or L2,0,200,,all,1,1,0,2
|
|
95
95
|
fan_dc_l,fan_current,Fan current (lower boom),mA,physicalMeasurement,time,TRUE,,0,200,,two-boom,1,1,0,2
|
|
96
|
-
freq_vw,frequency_of_precipitation_wire_vibration,Frequency of vibrating wire in precipitation gauge,Hz,physicalMeasurement,time,TRUE,L0 or L2,0,10000,
|
|
96
|
+
freq_vw,frequency_of_precipitation_wire_vibration,Frequency of vibrating wire in precipitation gauge,Hz,physicalMeasurement,time,TRUE,L0 or L2,0,10000,"",,1,1,0,
|
|
97
97
|
t_log,temperature_of_logger,Logger temperature,degrees_C,physicalMeasurement,time,TRUE,,-80,40,,one-boom,1,1,0,4
|
|
98
|
-
t_rad,temperature_of_radiation_sensor,Radiation sensor temperature,degrees_C,physicalMeasurement,time,FALSE,,-80,40,
|
|
98
|
+
t_rad,temperature_of_radiation_sensor,Radiation sensor temperature,degrees_C,physicalMeasurement,time,FALSE,,-80,40,"",all,1,1,1,4
|
|
99
99
|
p_i,air_pressure,Air pressure (instantaneous) minus 1000,hPa,physicalMeasurement,time,TRUE,,-350,100,,all,1,1,1,4
|
|
100
100
|
t_i,air_temperature,Air temperature (instantaneous),degrees_C,physicalMeasurement,time,TRUE,,-80,40,,all,1,1,1,4
|
|
101
|
-
rh_i,relative_humidity,Relative humidity (instantaneous),%,physicalMeasurement,time,TRUE,,0,150,
|
|
101
|
+
rh_i,relative_humidity,Relative humidity (instantaneous),%,physicalMeasurement,time,TRUE,,0,150,"",all,1,1,1,4
|
|
102
102
|
rh_i_cor,relative_humidity_corrected,Relative humidity (instantaneous) – corrected,%,modelResult,time,TRUE,L2 or later,0,100,,all,0,1,1,4
|
|
103
103
|
wspd_i,wind_speed,Wind speed (instantaneous),m s-1,physicalMeasurement,time,TRUE,,0,100,wdir_i wspd_x_i wspd_y_i,all,1,1,1,4
|
|
104
104
|
wdir_i,wind_from_direction,Wind from direction (instantaneous),degrees,physicalMeasurement,time,TRUE,,1,360,wspd_x_i wspd_y_i,all,1,1,1,4
|
|
105
|
-
wspd_x_i,wind_speed_from_x_direction,Wind speed from x direction (instantaneous),m s-1,modelResult,time,TRUE,L2 or later,-100,100,
|
|
106
|
-
wspd_y_i,wind_speed_from_y_direction,Wind speed from y direction (instantaneous),m s-1,modelResult,time,TRUE,L2 or later,-100,100,
|
|
105
|
+
wspd_x_i,wind_speed_from_x_direction,Wind speed from x direction (instantaneous),m s-1,modelResult,time,TRUE,L2 or later,-100,100,"",all,0,1,1,4
|
|
106
|
+
wspd_y_i,wind_speed_from_y_direction,Wind speed from y direction (instantaneous),m s-1,modelResult,time,TRUE,L2 or later,-100,100,"",all,0,1,1,4
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
from typing import Mapping, Set, MutableMapping, Optional
|
|
2
|
+
|
|
3
|
+
import attr
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"DependencyNode",
|
|
7
|
+
"DependencyGraph",
|
|
8
|
+
]
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
@attr.define
|
|
12
|
+
class DependencyNode:
|
|
13
|
+
name: str = attr.field()
|
|
14
|
+
parents: Set["DependencyNode"] = attr.field(factory=set)
|
|
15
|
+
children: Set["DependencyNode"] = attr.field(factory=set)
|
|
16
|
+
|
|
17
|
+
def add_child(self, child: "DependencyNode"):
|
|
18
|
+
self.children.add(child)
|
|
19
|
+
child.parents.add(self)
|
|
20
|
+
|
|
21
|
+
def get_children_closure(self, closure: Optional[Set[str]] = None) -> Set[str]:
|
|
22
|
+
is_root = closure is None
|
|
23
|
+
if closure is None:
|
|
24
|
+
closure = set()
|
|
25
|
+
if self.name in closure:
|
|
26
|
+
return closure
|
|
27
|
+
closure.add(self.name)
|
|
28
|
+
for child in self.children:
|
|
29
|
+
closure |= child.get_children_closure(closure)
|
|
30
|
+
|
|
31
|
+
if is_root:
|
|
32
|
+
closure.remove(self.name)
|
|
33
|
+
return closure
|
|
34
|
+
|
|
35
|
+
def get_parents_closure(self, closure: Optional[Set[str]] = None) -> Set[str]:
|
|
36
|
+
is_root = closure is None
|
|
37
|
+
if closure is None:
|
|
38
|
+
closure = set()
|
|
39
|
+
if self.name in closure:
|
|
40
|
+
return closure
|
|
41
|
+
closure.add(self.name)
|
|
42
|
+
for parent in self.parents:
|
|
43
|
+
closure |= parent.get_parents_closure(closure)
|
|
44
|
+
|
|
45
|
+
if is_root:
|
|
46
|
+
closure.remove(self.name)
|
|
47
|
+
return closure
|
|
48
|
+
|
|
49
|
+
def __hash__(self):
|
|
50
|
+
return hash(self.name)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
@attr.define
|
|
54
|
+
class DependencyGraph:
|
|
55
|
+
nodes: MutableMapping[str, DependencyNode] = attr.field(factory=dict)
|
|
56
|
+
|
|
57
|
+
def add_node(self, name: str) -> DependencyNode:
|
|
58
|
+
if name not in self.nodes:
|
|
59
|
+
self.nodes[name] = DependencyNode(name)
|
|
60
|
+
return self.nodes[name]
|
|
61
|
+
|
|
62
|
+
def add_edge(self, parent: str, child: str):
|
|
63
|
+
parent_node = self.add_node(parent)
|
|
64
|
+
child_node = self.add_node(child)
|
|
65
|
+
parent_node.add_child(child_node)
|
|
66
|
+
|
|
67
|
+
@classmethod
|
|
68
|
+
def from_child_mapping(cls, mapping: Mapping[str, Set[str]]) -> "DependencyGraph":
|
|
69
|
+
graph = cls()
|
|
70
|
+
for var, children in mapping.items():
|
|
71
|
+
graph.add_node(var)
|
|
72
|
+
for child in children:
|
|
73
|
+
graph.add_edge(var, child)
|
|
74
|
+
return graph
|
|
75
|
+
|
|
76
|
+
@classmethod
|
|
77
|
+
def from_parent_mapping(cls, mapping: Mapping[str, Set[str]]) -> "DependencyGraph":
|
|
78
|
+
graph = cls()
|
|
79
|
+
for var, parents in mapping.items():
|
|
80
|
+
graph.add_node(var)
|
|
81
|
+
for parent in parents:
|
|
82
|
+
graph.add_edge(parent, var)
|
|
83
|
+
return graph
|
|
84
|
+
|
|
85
|
+
def child_mapping(self) -> Mapping[str, Set[str]]:
|
|
86
|
+
return {
|
|
87
|
+
node.name: {child.name for child in node.children}
|
|
88
|
+
for node in self.nodes.values()
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
def child_closure_mapping(self) -> Mapping[str, Set[str]]:
|
|
92
|
+
return {node.name: node.get_children_closure() for node in self.nodes.values()}
|
|
93
|
+
|
|
94
|
+
def parent_mapping(self) -> Mapping[str, Set[str]]:
|
|
95
|
+
return {
|
|
96
|
+
node.name: {parent.name for parent in node.parents}
|
|
97
|
+
for node in self.nodes.values()
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
def parent_closure_mapping(self) -> Mapping[str, Set[str]]:
|
|
101
|
+
return {node.name: node.get_parents_closure() for node in self.nodes.values()}
|
|
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
|