pypromice 1.3.6__py3-none-any.whl → 1.4.0__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.

Potentially problematic release.


This version of pypromice might be problematic. Click here for more details.

Files changed (53) hide show
  1. pypromice/postprocess/bufr_to_csv.py +6 -1
  2. pypromice/postprocess/bufr_utilities.py +91 -18
  3. pypromice/postprocess/create_bufr_files.py +178 -0
  4. pypromice/postprocess/get_bufr.py +248 -397
  5. pypromice/postprocess/make_metadata_csv.py +214 -0
  6. pypromice/postprocess/real_time_utilities.py +41 -11
  7. pypromice/process/L0toL1.py +12 -5
  8. pypromice/process/L1toL2.py +69 -14
  9. pypromice/process/L2toL3.py +1033 -186
  10. pypromice/process/aws.py +130 -808
  11. pypromice/process/get_l2.py +90 -0
  12. pypromice/process/get_l2tol3.py +111 -0
  13. pypromice/process/join_l2.py +112 -0
  14. pypromice/process/join_l3.py +551 -120
  15. pypromice/process/load.py +161 -0
  16. pypromice/process/resample.py +128 -0
  17. pypromice/process/utilities.py +68 -0
  18. pypromice/process/write.py +503 -0
  19. pypromice/qc/github_data_issues.py +10 -16
  20. pypromice/qc/persistence.py +52 -30
  21. pypromice/resources/__init__.py +28 -0
  22. pypromice/{process/metadata.csv → resources/file_attributes.csv} +0 -2
  23. pypromice/resources/variable_aliases_GC-Net.csv +78 -0
  24. pypromice/resources/variables.csv +106 -0
  25. pypromice/station_configuration.py +118 -0
  26. pypromice/tx/get_l0tx.py +7 -4
  27. pypromice/tx/payload_formats.csv +1 -0
  28. pypromice/tx/tx.py +27 -6
  29. pypromice/utilities/__init__.py +0 -0
  30. pypromice/utilities/git.py +61 -0
  31. {pypromice-1.3.6.dist-info → pypromice-1.4.0.dist-info}/METADATA +3 -3
  32. pypromice-1.4.0.dist-info/RECORD +53 -0
  33. {pypromice-1.3.6.dist-info → pypromice-1.4.0.dist-info}/WHEEL +1 -1
  34. pypromice-1.4.0.dist-info/entry_points.txt +13 -0
  35. pypromice/postprocess/station_configurations.toml +0 -762
  36. pypromice/process/get_l3.py +0 -46
  37. pypromice/process/variables.csv +0 -92
  38. pypromice/qc/persistence_test.py +0 -150
  39. pypromice/test/test_config1.toml +0 -69
  40. pypromice/test/test_config2.toml +0 -54
  41. pypromice/test/test_email +0 -75
  42. pypromice/test/test_payload_formats.csv +0 -4
  43. pypromice/test/test_payload_types.csv +0 -7
  44. pypromice/test/test_percentile.py +0 -229
  45. pypromice/test/test_raw1.txt +0 -4468
  46. pypromice/test/test_raw_DataTable2.txt +0 -11167
  47. pypromice/test/test_raw_SlimTableMem1.txt +0 -1155
  48. pypromice/test/test_raw_transmitted1.txt +0 -15411
  49. pypromice/test/test_raw_transmitted2.txt +0 -28
  50. pypromice-1.3.6.dist-info/RECORD +0 -53
  51. pypromice-1.3.6.dist-info/entry_points.txt +0 -8
  52. {pypromice-1.3.6.dist-info → pypromice-1.4.0.dist-info}/LICENSE.txt +0 -0
  53. {pypromice-1.3.6.dist-info → pypromice-1.4.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,503 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Module containing all the functions needed to prepare and AWS data
5
+ """
6
+ import datetime
7
+ import logging
8
+ import os
9
+ from pathlib import Path
10
+
11
+ import numpy as np
12
+ import pandas as pd
13
+ from pypromice.process.resample import resample_dataset
14
+ import pypromice.resources
15
+
16
+ logger = logging.getLogger(__name__)
17
+
18
+
19
+ def prepare_and_write(
20
+ dataset, output_path: Path | str, vars_df=None, meta_dict=None, time="60min", resample=True
21
+ ):
22
+ """Prepare data with resampling, formating and metadata population; then
23
+ write data to .nc and .csv hourly and daily files
24
+
25
+ Parameters
26
+ ----------
27
+ dataset : xarray.Dataset
28
+ Dataset to write to file
29
+ output_path : Path|str
30
+ Output directory
31
+ vars_df : pandas.DataFrame
32
+ Variables look-up table dataframe
33
+ meta_dict : dictionary
34
+ Metadata dictionary to write to dataset
35
+ time : str
36
+ Resampling interval for output dataset
37
+ """
38
+ # Resample dataset
39
+ if isinstance(output_path, str):
40
+ output_path = Path(output_path)
41
+
42
+ if resample:
43
+ d2 = resample_dataset(dataset, time)
44
+ logger.info("Resampling to " + str(time))
45
+ if len(d2.time) == 1:
46
+ logger.warning(
47
+ "Output of resample has length 1. Not enough data to calculate daily/monthly average."
48
+ )
49
+ return None
50
+ else:
51
+ d2 = dataset.copy()
52
+
53
+ # Reformat time
54
+ d2 = reformat_time(d2)
55
+
56
+ # finding station/site name
57
+ if "station_id" in d2.attrs.keys():
58
+ name = d2.attrs["station_id"]
59
+ else:
60
+ name = d2.attrs["site_id"]
61
+
62
+ # Reformat longitude (to negative values)
63
+ if "gps_lon" in d2.keys():
64
+ d2 = reformat_lon(d2)
65
+ else:
66
+ logger.info("%s does not have gps_lon" % name)
67
+
68
+ # Add variable attributes and metadata
69
+ if vars_df is None:
70
+ vars_df = pypromice.resources.load_variables()
71
+ if meta_dict is None:
72
+ meta_dict = pypromice.resources.load_metadata()
73
+
74
+ d2 = addVars(d2, vars_df)
75
+ d2 = addMeta(d2, meta_dict)
76
+
77
+ # Round all values to specified decimals places
78
+ d2 = roundValues(d2, vars_df)
79
+
80
+ # Get variable names to write out
81
+ if "site_id" in d2.attrs.keys():
82
+ remove_nan_fields = True
83
+ else:
84
+ remove_nan_fields = False
85
+ col_names = getColNames(vars_df, d2, remove_nan_fields=remove_nan_fields)
86
+
87
+ # Define filename based on resample rate
88
+ t = int(pd.Timedelta((d2["time"][1] - d2["time"][0]).values).total_seconds())
89
+
90
+ # Create out directory
91
+ output_dir = output_path / name
92
+ output_dir.mkdir(exist_ok=True, parents=True)
93
+
94
+ if t == 600:
95
+ out_csv = output_dir / f"{name}_10min.csv"
96
+ out_nc = output_dir / f"{name}_10min.nc"
97
+ elif t == 3600:
98
+ out_csv = output_dir / f"{name}_hour.csv"
99
+ out_nc = output_dir / f"{name}_hour.nc"
100
+ elif t == 86400:
101
+ # removing instantaneous values from daily and monthly files
102
+ for v in col_names:
103
+ if ("_i" in v) and ("_i_" not in v):
104
+ col_names.remove(v)
105
+ out_csv = output_dir / f"{name}_day.csv"
106
+ out_nc = output_dir / f"{name}_day.nc"
107
+ else:
108
+ # removing instantaneous values from daily and monthly files
109
+ for v in col_names:
110
+ if ("_i" in v) and ("_i_" not in v):
111
+ col_names.remove(v)
112
+ out_csv = output_dir / f"{name}_month.csv"
113
+ out_nc = output_dir / f"{name}_month.nc"
114
+
115
+ # Write to csv file
116
+ logger.info("Writing to files...")
117
+ writeCSV(out_csv, d2, col_names)
118
+
119
+ # Write to netcdf file
120
+ writeNC(out_nc, d2, col_names)
121
+ logger.info(f"Written to {out_csv}")
122
+ logger.info(f"Written to {out_nc}")
123
+
124
+
125
+ def writeAll(outpath, station_id, l3_h, l3_d, l3_m, csv_order=None):
126
+ """Write L3 hourly, daily and monthly datasets to .nc and .csv
127
+ files
128
+
129
+ Parameters
130
+ ----------
131
+ outpath : str
132
+ Output file path
133
+ station_id : str
134
+ Station name
135
+ l3_h : xr.Dataset
136
+ L3 hourly data
137
+ l3_d : xr.Dataset
138
+ L3 daily data
139
+ l3_m : xr.Dataset
140
+ L3 monthly data
141
+ csv_order : list, optional
142
+ List order of variables
143
+ """
144
+ if not os.path.isdir(outpath):
145
+ os.mkdir(outpath)
146
+ outfile_h = os.path.join(outpath, station_id + "_hour")
147
+ outfile_d = os.path.join(outpath, station_id + "_day")
148
+ outfile_m = os.path.join(outpath, station_id + "_month")
149
+ for o, l in zip([outfile_h, outfile_d, outfile_m], [l3_h, l3_d, l3_m]):
150
+ writeCSV(o + ".csv", l, csv_order)
151
+ writeNC(o + ".nc", l)
152
+
153
+
154
+ def writeCSV(outfile, Lx, csv_order):
155
+ """Write data product to CSV file
156
+
157
+ Parameters
158
+ ----------
159
+ outfile : str
160
+ Output file path
161
+ Lx : xr.Dataset
162
+ Dataset to write to file
163
+ csv_order : list
164
+ List order of variables
165
+ """
166
+ Lcsv = Lx.to_dataframe().dropna(how="all")
167
+ if csv_order is not None:
168
+ names = [c for c in csv_order if c in list(Lcsv.columns)]
169
+ Lcsv = Lcsv[names]
170
+ Lcsv.to_csv(outfile)
171
+
172
+
173
+ def writeNC(outfile, Lx, col_names=None):
174
+ """Write data product to NetCDF file
175
+
176
+ Parameters
177
+ ----------
178
+ outfile : str
179
+ Output file path
180
+ Lx : xr.Dataset
181
+ Dataset to write to file
182
+ """
183
+ if os.path.isfile(outfile):
184
+ os.remove(outfile)
185
+ if col_names is not None:
186
+ names = [c for c in col_names if c in list(Lx.keys())]
187
+ else:
188
+ names = list(Lx.keys())
189
+
190
+ Lx[names].to_netcdf(outfile, mode="w", format="NETCDF4", compute=True)
191
+
192
+
193
+ def getColNames(vars_df, ds, remove_nan_fields=False):
194
+ """
195
+ Get variable names for a given dataset with respect to its type and processing level
196
+
197
+ The dataset must have the the following attributes:
198
+ * level
199
+ * number_of_booms when the processing level is <= 2
200
+
201
+ This is mainly for exporting purposes.
202
+
203
+ Parameters
204
+ -------
205
+ list
206
+ Variable names
207
+ """
208
+ # selecting variable list based on level
209
+ vars_df = vars_df.loc[vars_df[ds.attrs["level"]] == 1]
210
+
211
+ # selecting variable list based on geometry
212
+ if ds.attrs["level"] in ["L0", "L1", "L2"]:
213
+ if ds.attrs["number_of_booms"] == 1:
214
+ vars_df = vars_df.loc[vars_df["station_type"].isin(["one-boom", "all"])]
215
+ elif ds.attrs["number_of_booms"] == 2:
216
+ vars_df = vars_df.loc[vars_df["station_type"].isin(["two-boom", "all"])]
217
+
218
+ var_list = list(vars_df.index)
219
+ if remove_nan_fields:
220
+ for v in var_list:
221
+ if v not in ds.keys():
222
+ var_list.remove(v)
223
+ continue
224
+ if ds[v].isnull().all():
225
+ var_list.remove(v)
226
+ return var_list
227
+
228
+
229
+ def addVars(ds, variables):
230
+ """Add variable attributes from file to dataset
231
+
232
+ Parameters
233
+ ----------
234
+ ds : xarray.Dataset
235
+ Dataset to add variable attributes to
236
+ variables : pandas.DataFrame
237
+ Variables lookup table file
238
+
239
+ Returns
240
+ -------
241
+ ds : xarray.Dataset
242
+ Dataset with metadata
243
+ """
244
+ for k in ds.keys():
245
+ if k not in variables.index:
246
+ continue
247
+ ds[k].attrs["standard_name"] = variables.loc[k]["standard_name"]
248
+ ds[k].attrs["long_name"] = variables.loc[k]["long_name"]
249
+ ds[k].attrs["units"] = variables.loc[k]["units"]
250
+ ds[k].attrs["coverage_content_type"] = variables.loc[k]["coverage_content_type"]
251
+ ds[k].attrs["coordinates"] = variables.loc[k]["coordinates"]
252
+ return ds
253
+
254
+
255
+ def addMeta(ds, meta):
256
+ """Add metadata attributes from file to dataset
257
+
258
+ Parameters
259
+ ----------
260
+ ds : xarray.Dataset
261
+ Dataset to add metadata attributes to
262
+ meta : dict
263
+ Metadata file
264
+
265
+ Returns
266
+ -------
267
+ ds : xarray.Dataset
268
+ Dataset with metadata
269
+ """
270
+
271
+ # a static latitude, longitude and altitude is saved as attribute along its origin
272
+ var_alias = {"lat": "latitude", "lon": "longitude", "alt": "altitude"}
273
+ for v in ["lat", "lon", "alt"]:
274
+ # saving the reference latitude/longitude/altitude
275
+ original_value = np.nan
276
+ if var_alias[v] in ds.attrs.keys():
277
+ original_value = ds.attrs[var_alias[v]]
278
+ if v in ds.keys():
279
+ # if possible, replacing it with average coordinates based on the extra/interpolated coords
280
+ ds.attrs[var_alias[v]] = ds[v].mean().item()
281
+ ds.attrs[var_alias[v] + "_origin"] = (
282
+ "average of gap-filled postprocessed " + v
283
+ )
284
+ elif "gps_" + v in ds.keys():
285
+ # if possible, replacing it with average coordinates based on the measured coords (can be gappy)
286
+ ds.attrs[var_alias[v]] = ds["gps_" + v].mean().item()
287
+ ds.attrs[var_alias[v] + "_origin"] = (
288
+ "average of GPS-measured " + v + ", potentially including gaps"
289
+ )
290
+
291
+ if np.isnan(ds.attrs[var_alias[v]]):
292
+ # if no better data was available to update the coordinate, then we
293
+ # re-use the original value
294
+ ds.attrs[var_alias[v]] = original_value
295
+ ds.attrs[var_alias[v] + "_origin"] = "reference value, origin unknown"
296
+
297
+ # Attribute convention for data discovery
298
+ # https://wiki.esipfed.org/Attribute_Convention_for_Data_Discovery_1-3
299
+
300
+ # Determine the temporal resolution
301
+ sample_rate = "unknown_sample_rate"
302
+ if len(ds["time"]) > 1:
303
+ time_diff = pd.Timedelta((ds["time"][1] - ds["time"][0]).values)
304
+ if time_diff == pd.Timedelta("10min"):
305
+ sample_rate = "10min"
306
+ elif time_diff == pd.Timedelta("1h"):
307
+ sample_rate = "hourly"
308
+ elif time_diff == pd.Timedelta("1D"):
309
+ sample_rate = "daily"
310
+ elif 28 <= time_diff.days <= 31:
311
+ sample_rate = "monthly"
312
+
313
+ if "station_id" in ds.attrs.keys():
314
+ id_components = [
315
+ "dk",
316
+ "geus",
317
+ "promice",
318
+ "station",
319
+ ds.attrs["station_id"],
320
+ ds.attrs["level"],
321
+ sample_rate,
322
+ ]
323
+ ds.attrs["id"] = ".".join(id_components)
324
+ else:
325
+ id_components = [
326
+ "dk",
327
+ "geus",
328
+ "promice",
329
+ "site",
330
+ ds.attrs["site_id"],
331
+ ds.attrs["level"],
332
+ sample_rate,
333
+ ]
334
+ ds.attrs["id"] = ".".join(id_components)
335
+
336
+ ds.attrs["history"] = "Generated on " + datetime.datetime.utcnow().isoformat()
337
+ ds.attrs["date_created"] = str(datetime.datetime.now().isoformat())
338
+ ds.attrs["date_modified"] = ds.attrs["date_created"]
339
+ ds.attrs["date_issued"] = ds.attrs["date_created"]
340
+ ds.attrs["date_metadata_modified"] = ds.attrs["date_created"]
341
+ ds.attrs["processing_level"] = ds.attrs["level"].replace("L", "Level ")
342
+
343
+ id = ds.attrs.get('station_id', ds.attrs.get('site_id'))
344
+ title_string_format = "AWS measurements from {id} processed to {processing_level}. {sample_rate} average."
345
+ ds.attrs["title"] = title_string_format.format(
346
+ id=id,
347
+ processing_level=ds.attrs["processing_level"].lower(),
348
+ sample_rate=sample_rate.capitalize(),
349
+ )
350
+
351
+ if "lat" in ds.keys():
352
+ lat_min = ds["lat"].min().values
353
+ lat_max = ds["lat"].max().values
354
+ elif "gps_lat" in ds.keys():
355
+ lat_min = ds["gps_lat"].min().values
356
+ lat_max = ds["gps_lat"].max().values
357
+ elif "latitude" in ds.attrs.keys():
358
+ lat_min = ds.attrs["latitude"]
359
+ lat_max = ds.attrs["latitude"]
360
+ else:
361
+ lat_min = np.nan
362
+ lat_max = np.nan
363
+
364
+ if "lon" in ds.keys():
365
+ lon_min = ds["lon"].min().values
366
+ lon_max = ds["lon"].max().values
367
+ elif "gps_lon" in ds.keys():
368
+ lon_min = ds["gps_lon"].min().values
369
+ lon_max = ds["gps_lon"].max().values
370
+ elif "longitude" in ds.attrs.keys():
371
+ lon_min = ds.attrs["longitude"]
372
+ lon_max = ds.attrs["longitude"]
373
+ else:
374
+ lon_min = np.nan
375
+ lon_max = np.nan
376
+
377
+ if "alt" in ds.keys():
378
+ alt_min = ds["alt"].min().values
379
+ alt_max = ds["alt"].max().values
380
+ elif "gps_alt" in ds.keys():
381
+ alt_min = ds["gps_alt"].min().values
382
+ alt_max = ds["gps_alt"].max().values
383
+ elif "altitude" in ds.attrs.keys():
384
+ alt_min = ds.attrs["altitude"]
385
+ alt_max = ds.attrs["altitude"]
386
+ else:
387
+ alt_min = np.nan
388
+ alt_max = np.nan
389
+
390
+ ds.attrs["geospatial_bounds"] = (
391
+ "POLYGON(("
392
+ + f"{lat_min} {lon_min}, "
393
+ + f"{lat_min} {lon_max}, "
394
+ + f"{lat_max} {lon_max}, "
395
+ + f"{lat_max} {lon_min}, "
396
+ + f"{lat_min} {lon_min}))"
397
+ )
398
+
399
+ ds.attrs["geospatial_lat_min"] = str(lat_min)
400
+ ds.attrs["geospatial_lat_max"] = str(lat_max)
401
+ ds.attrs["geospatial_lon_min"] = str(lon_min)
402
+ ds.attrs["geospatial_lon_max"] = str(lon_max)
403
+ ds.attrs["geospatial_vertical_min"] = str(alt_min)
404
+ ds.attrs["geospatial_vertical_max"] = str(alt_max)
405
+
406
+ ds.attrs["geospatial_vertical_positive"] = "up"
407
+ ds.attrs["time_coverage_start"] = str(ds["time"][0].values)
408
+ ds.attrs["time_coverage_end"] = str(ds["time"][-1].values)
409
+
410
+ # https://www.digi.com/resources/documentation/digidocs/90001437-13/reference/r_iso_8601_duration_format.htm
411
+ try:
412
+ ds.attrs["time_coverage_duration"] = str(
413
+ pd.Timedelta((ds["time"][-1] - ds["time"][0]).values).isoformat()
414
+ )
415
+ ds.attrs["time_coverage_resolution"] = str(
416
+ pd.Timedelta((ds["time"][1] - ds["time"][0]).values).isoformat()
417
+ )
418
+ except:
419
+ ds.attrs["time_coverage_duration"] = str(pd.Timedelta(0).isoformat())
420
+ ds.attrs["time_coverage_resolution"] = str(pd.Timedelta(0).isoformat())
421
+
422
+ # Note: int64 dtype (long int) is incompatible with OPeNDAP access via THREDDS for NetCDF files
423
+ # See https://stackoverflow.com/questions/48895227/output-int32-time-dimension-in-netcdf-using-xarray
424
+ ds.time.encoding["dtype"] = "i4" # 32-bit signed integer
425
+ # ds.time.encoding["calendar"] = 'proleptic_gregorian' # this is default
426
+
427
+ # Load metadata attributes and add to Dataset
428
+ [_addAttr(ds, key, value) for key, value in meta.items()]
429
+
430
+ # Check attribute formating
431
+ for k, v in ds.attrs.items():
432
+ if not isinstance(v, str) or not isinstance(v, int):
433
+ ds.attrs[k] = str(v)
434
+ return ds
435
+
436
+
437
+ def _addAttr(ds, key, value):
438
+ """Add attribute to xarray dataset
439
+
440
+ ds : xr.Dataset
441
+ Dataset to add attribute to
442
+ key : str
443
+ Attribute name, with "." denoting variable attributes
444
+ value : str/int
445
+ Value for attribute"""
446
+ if len(key.split(".")) == 2:
447
+ try:
448
+ ds[key.split(".")[0]].attrs[key.split(".")[1]] = str(value)
449
+ except:
450
+ pass
451
+ # logger.info(f'Unable to add metadata to {key.split(".")[0]}')
452
+ else:
453
+ ds.attrs[key] = value
454
+
455
+
456
+ def roundValues(ds, df, col="max_decimals"):
457
+ """Round all variable values in data array based on pre-defined rounding
458
+ value in variables look-up table DataFrame
459
+
460
+ Parameters
461
+ ----------
462
+ ds : xr.Dataset
463
+ Dataset to round values in
464
+ df : pd.Dataframe
465
+ Variable look-up table with rounding values
466
+ col : str
467
+ Column in variable look-up table that contains rounding values. The
468
+ default is "max_decimals"
469
+ """
470
+ df = df[col]
471
+ df = df.dropna(how="all")
472
+ for var in df.index:
473
+ if var not in list(ds.variables):
474
+ continue
475
+ if df[var] is not np.nan:
476
+ ds[var] = ds[var].round(decimals=int(df[var]))
477
+ return ds
478
+
479
+
480
+ def reformat_time(dataset):
481
+ """Re-format time"""
482
+ t = dataset["time"].values
483
+ dataset["time"] = list(t)
484
+ return dataset
485
+
486
+
487
+ def reformat_lon(dataset, exempt=["UWN", "Roof_GEUS", "Roof_PROMICE"]):
488
+ """Switch gps_lon to negative values (degrees_east). We do this here, and
489
+ NOT in addMeta, otherwise we switch back to positive when calling getMeta
490
+ in joinL2"""
491
+ if "station_id" in dataset.attrs.keys():
492
+ id = dataset.attrs["station_id"]
493
+ else:
494
+ id = dataset.attrs["site_id"]
495
+
496
+ if id not in exempt:
497
+ if "gps_lon" not in dataset.keys():
498
+ return dataset
499
+ dataset["gps_lon"] = np.abs(dataset["gps_lon"]) * -1
500
+ if "lon" not in dataset.keys():
501
+ return dataset
502
+ dataset["lon"] = np.abs(dataset["lon"]) * -1
503
+ return dataset
@@ -1,7 +1,5 @@
1
1
  import logging
2
2
  import os
3
- import urllib.request
4
- from urllib.error import HTTPError, URLError
5
3
 
6
4
  import numpy as np
7
5
  import pandas as pd
@@ -16,8 +14,7 @@ __all__ = [
16
14
  logger = logging.getLogger(__name__)
17
15
 
18
16
 
19
- def flagNAN(ds_in,
20
- flag_dir='../PROMICE-AWS-data-issues/flags'):
17
+ def flagNAN(ds_in, flag_dir):
21
18
  '''Read flagged data from .csv file. For each variable, and downstream
22
19
  dependents, flag as invalid (or other) if set in the flag .csv
23
20
 
@@ -65,17 +62,15 @@ def flagNAN(ds_in,
65
62
 
66
63
  for v in varlist:
67
64
  if v in list(ds.keys()):
68
- logger.info(f'---> flagging {t0} {t1} {v}')
65
+ logger.debug(f'---> flagging {t0} {t1} {v}')
69
66
  ds[v] = ds[v].where((ds['time'] < t0) | (ds['time'] > t1))
70
67
  else:
71
- logger.info(f'---> could not flag {v} not in dataset')
68
+ logger.debug(f'---> could not flag {v} not in dataset')
72
69
 
73
70
  return ds
74
71
 
75
72
 
76
- def adjustTime(ds,
77
- adj_dir='../PROMICE-AWS-data-issues/adjustments/',
78
- var_list=[], skip_var=[]):
73
+ def adjustTime(ds, adj_dir, var_list=[], skip_var=[]):
79
74
  '''Read adjustment data from .csv file. Only applies the "time_shift" adjustment
80
75
 
81
76
  Parameters
@@ -134,9 +129,7 @@ def adjustTime(ds,
134
129
  return ds_out
135
130
 
136
131
 
137
- def adjustData(ds,
138
- adj_dir='../PROMICE-AWS-data-issues/adjustments/',
139
- var_list=[], skip_var=[]):
132
+ def adjustData(ds, adj_dir, var_list=[], skip_var=[]):
140
133
  '''Read adjustment data from .csv file. For each variable, and downstream
141
134
  dependents, adjust data accordingly if set in the adjustment .csv
142
135
 
@@ -206,13 +199,14 @@ def adjustData(ds,
206
199
  t1 = pd.to_datetime(t1, utc=True).tz_localize(None)
207
200
 
208
201
  index_slice = dict(time=slice(t0, t1))
209
-
210
202
  if len(ds_out[var].loc[index_slice].time.time) == 0:
203
+ logger.info(f'---> {t0} {t1} {var} {func} {val}')
211
204
  logger.info("Time range does not intersect with dataset")
212
205
  continue
213
206
 
214
- logger.info(f'---> {t0} {t1} {var} {func} {val}')
215
-
207
+ else:
208
+ logger.debug(f'---> {t0} {t1} {var} {func} {val}')
209
+
216
210
  if func == "add":
217
211
  ds_out[var].loc[index_slice] = ds_out[var].loc[index_slice].values + val
218
212
  # flagging adjusted values
@@ -314,7 +308,7 @@ def _getDF(flag_file):
314
308
  ).dropna(how='all', axis='rows')
315
309
  else:
316
310
  df=None
317
- logger.info(f"No {flag_file.split('/')[-2][:-1]} file to read.")
311
+ logger.info(f"No {flag_file} file to read.")
318
312
  return df
319
313
 
320
314