pypromice 1.5.3__py3-none-any.whl → 1.6.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 (65) hide show
  1. pypromice/__init__.py +2 -0
  2. pypromice/{qc → core/qc}/percentiles/compute_thresholds.py +2 -2
  3. pypromice/{qc → core/qc}/persistence.py +22 -29
  4. pypromice/{process → core/qc}/value_clipping.py +3 -3
  5. pypromice/core/variables/__init__.py +1 -0
  6. pypromice/core/variables/air_temperature.py +64 -0
  7. pypromice/core/variables/gps.py +221 -0
  8. pypromice/core/variables/humidity.py +111 -0
  9. pypromice/core/variables/precipitation.py +108 -0
  10. pypromice/core/variables/pressure_transducer_depth.py +79 -0
  11. pypromice/core/variables/radiation.py +422 -0
  12. pypromice/core/variables/station_boom_height.py +49 -0
  13. pypromice/core/variables/station_pose.py +375 -0
  14. pypromice/io/bufr/__init__.py +0 -0
  15. pypromice/{postprocess → io/bufr}/bufr_to_csv.py +1 -1
  16. pypromice/{postprocess → io/bufr}/create_bufr_files.py +2 -2
  17. pypromice/{postprocess → io/bufr}/get_bufr.py +6 -6
  18. pypromice/{postprocess → io/bufr}/real_time_utilities.py +3 -3
  19. pypromice/io/ingest/__init__.py +0 -0
  20. pypromice/{utilities → io/ingest}/git.py +1 -3
  21. pypromice/io/ingest/l0.py +294 -0
  22. pypromice/io/ingest/l0_repository.py +103 -0
  23. pypromice/io/ingest/toa5.py +87 -0
  24. pypromice/{process → io}/write.py +1 -1
  25. pypromice/pipeline/L0toL1.py +291 -0
  26. pypromice/pipeline/L1toL2.py +233 -0
  27. pypromice/{process → pipeline}/L2toL3.py +97 -118
  28. pypromice/pipeline/__init__.py +4 -0
  29. pypromice/{process → pipeline}/aws.py +10 -82
  30. pypromice/{process → pipeline}/get_l2.py +2 -2
  31. pypromice/{process → pipeline}/get_l2tol3.py +19 -22
  32. pypromice/{process → pipeline}/join_l2.py +31 -32
  33. pypromice/{process → pipeline}/join_l3.py +16 -14
  34. pypromice/{process → pipeline}/resample.py +58 -45
  35. pypromice/{process → pipeline}/utilities.py +0 -22
  36. pypromice/resources/file_attributes.csv +4 -4
  37. pypromice/resources/variables.csv +27 -24
  38. {pypromice-1.5.3.dist-info → pypromice-1.6.0.dist-info}/METADATA +1 -2
  39. pypromice-1.6.0.dist-info/RECORD +64 -0
  40. pypromice-1.6.0.dist-info/entry_points.txt +12 -0
  41. pypromice/get/__init__.py +0 -1
  42. pypromice/get/get.py +0 -211
  43. pypromice/get/get_promice_data.py +0 -56
  44. pypromice/process/L0toL1.py +0 -564
  45. pypromice/process/L1toL2.py +0 -824
  46. pypromice/process/__init__.py +0 -4
  47. pypromice/process/load.py +0 -161
  48. pypromice-1.5.3.dist-info/RECORD +0 -54
  49. pypromice-1.5.3.dist-info/entry_points.txt +0 -13
  50. /pypromice/{postprocess → core}/__init__.py +0 -0
  51. /pypromice/{utilities → core}/dependency_graph.py +0 -0
  52. /pypromice/{qc → core/qc}/__init__.py +0 -0
  53. /pypromice/{qc → core/qc}/github_data_issues.py +0 -0
  54. /pypromice/{qc → core/qc}/percentiles/__init__.py +0 -0
  55. /pypromice/{qc → core/qc}/percentiles/outlier_detector.py +0 -0
  56. /pypromice/{qc → core/qc}/percentiles/thresholds.csv +0 -0
  57. /pypromice/{process → core/variables}/wind.py +0 -0
  58. /pypromice/{utilities → io}/__init__.py +0 -0
  59. /pypromice/{postprocess → io/bufr}/bufr_utilities.py +0 -0
  60. /pypromice/{postprocess → io/bufr}/positions_seed.csv +0 -0
  61. /pypromice/{station_configuration.py → io/bufr/station_configuration.py} +0 -0
  62. /pypromice/{postprocess → io}/make_metadata_csv.py +0 -0
  63. {pypromice-1.5.3.dist-info → pypromice-1.6.0.dist-info}/WHEEL +0 -0
  64. {pypromice-1.5.3.dist-info → pypromice-1.6.0.dist-info}/licenses/LICENSE.txt +0 -0
  65. {pypromice-1.5.3.dist-info → pypromice-1.6.0.dist-info}/top_level.txt +0 -0
pypromice/get/get.py DELETED
@@ -1,211 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
- """
4
- AWS data retrieval module
5
- """
6
- from pyDataverse.api import NativeApi
7
- import pandas as pd
8
- import xarray as xr
9
- import unittest, pkg_resources
10
- from datetime import datetime
11
- import warnings, os
12
-
13
- def aws_names():
14
- '''Return PROMICE and GC-Net AWS names that can be used in get.aws_data()
15
- fetching'''
16
- lookup = lookup_table(['doi:10.22008/FK2/IW73UU'])
17
- print(f'Available dataset keywords: {list(lookup.keys())}')
18
- return list(lookup.keys())
19
-
20
- def aws_data(aws_name):
21
- '''Return PROMICE and GC-Net AWS L3 v3 hourly observations
22
-
23
- Returns
24
- -------
25
- df : pandas.DataFrame
26
- AWS observations dataframe
27
- '''
28
- lookup = lookup_table(['doi:10.22008/FK2/IW73UU'])
29
- assert aws_name.lower() in list(lookup.keys())
30
- data = pd.read_csv(lookup[aws_name], index_col=0, parse_dates=True)
31
- return data
32
-
33
- def watson_discharge(t='hour'):
34
- '''Return PROMICE hourly Watson river discharge
35
-
36
- Parameters
37
- ----------
38
- t : str
39
- Temporal resolution of the data - "hour", "day" or "year"
40
-
41
- Returns
42
- -------
43
- df : pandas.DataFrame
44
- Watson river discharge dataframe
45
- '''
46
- lookup = lookup_table(['doi:10.22008/FK2/XEHYCM'])
47
-
48
- dict_keys = lookup.keys()
49
-
50
- if 'year' in t.lower():
51
-
52
- key = [k for k in dict_keys if 'year' in k]
53
-
54
- if not key:
55
- warnings.warn('The yearly Watson River Discharge file does not exist, or has changed name, on GEUS Dataverse DOI, ' + \
56
- 'please check the dataset, and the naming of the txt files on Dataverse')
57
-
58
- if len(key) > 1:
59
- warnings.warn('Warning, there exist multiple yearly txt files on dataverse, please check ' + \
60
- 'if the correct txt file is used')
61
-
62
- link = lookup[key[0]]
63
- df = pd.read_csv(link, sep="\s+", skiprows=9, index_col=0)
64
-
65
- elif 'daily' in t.lower() or 'day' in t.lower():
66
-
67
- key = [k for k in dict_keys if 'daily' in k]
68
-
69
- if not key:
70
- warnings.warn('The daily Watson River Discharge file does not exist, or has changed name, on GEUS Dataverse DOI, ' + \
71
- 'please check the dataset, and the naming of the txt files on Dataverse')
72
-
73
- if len(key) > 1:
74
- warnings.warn('Warning, there exist multiple daily txt files on dataverse, please check ' + \
75
- 'if the correct txt file is used')
76
-
77
- link = lookup[key[0]]
78
-
79
- df = pd.read_csv(link, sep="\s+", parse_dates=[[0,1,2]])\
80
- .rename({"WaterFluxDiversOnly(m3/s)" : "divers",
81
- "Uncertainty(m3/s)" : "divers_err",
82
- "WaterFluxDivers&Temperature(m3/s)" : "divers_t",
83
- "Uncertainty(m3/s).1" : "divers_t_err",
84
- "WaterFluxCumulative(km3)" : "Q",
85
- "Uncertainty(km3)" : "err"},
86
- axis='columns')
87
- df['time'] = df.iloc[:,0]
88
- df = df.set_index('time')
89
- df.drop(columns=df.columns[0:1], axis=1, inplace=True)
90
-
91
- else:
92
-
93
- key = [k for k in dict_keys if 'hourly' in k]
94
-
95
- if not key:
96
- warnings.warn('The hourly Watson River Discharge file does not exist, or has changed name, on GEUS Dataverse DOI, ' + \
97
- 'please check the dataset, and the naming of the txt files on Dataverse')
98
-
99
- if len(key) > 1:
100
- warnings.warn('Warning, there exist multiple Houlry txt files on dataverse, please check ' + \
101
- 'if the correct txt file is used')
102
-
103
- link = lookup[key[0]]
104
-
105
- df = pd.read_csv(link, sep="\s+", parse_dates=[[0,1,2,3]])\
106
- .rename({"WaterFluxDiversOnly(m3/s)" : "divers",
107
- "Uncertainty(m3/s)" : "divers_err",
108
- "WaterFluxDivers&Temperature(m3/s)" : "divers_t",
109
- "Uncertainty(m3/s).1" : "divers_t_err",
110
- "WaterFluxCumulative(km3)" : "Q",
111
- "Uncertainty(km3)" : "err"},
112
- axis='columns')
113
- df = _getDFdatetime(df, list(df.iloc[:,0]))
114
-
115
- return df
116
-
117
- def lookup_table(base_dois,
118
- server='https://dataverse.geus.dk'):
119
- '''Fetch dictionary of data files and download URLs from a DOI entry in the
120
- GEUS Dataverse
121
-
122
- Parameters
123
- ----------
124
- base_dois : list
125
- List of DOIs to search
126
- server : str, optional
127
- DOI server. The default is "https://dataverse.geus.dk"
128
- '''
129
- # Prime API
130
- dataverse_server = server.strip("/")
131
- api = NativeApi(dataverse_server)
132
-
133
- # Look through DOI entries
134
- lookup_list = {}
135
- for d in base_dois:
136
- dataset = api.get_dataset(d)
137
-
138
- # Get file names and DOIs
139
- f_list = dataset.json()['data']['latestVersion']['files']
140
- for f in f_list:
141
- fname = f['dataFile']['filename'].lower()
142
- if '.csv' in fname or '.txt' in fname:
143
- link = _getURL(f['dataFile']['persistentId'])
144
- lookup_list[fname] = link
145
- return lookup_list
146
-
147
- def _getURL(persistentId,
148
- base_link='https://dataverse.geus.dk/api/access/datafile/:persistentId?persistentId='):
149
- '''Return URL download link from persistentId attached to DOI'''
150
- return base_link+persistentId
151
-
152
-
153
- def _getDFdatetime(df, dt_str, dt_format='%Y %m %d %H'):
154
- '''Format dataframe with datetime (year, month, day, hour) index column
155
-
156
- Parameters
157
- ----------
158
- df : pandas.DataFrame
159
- Input DataFrame
160
- dt_str : list
161
- List of datetime strings to format and add
162
- dt_format : str
163
- Datetime string format. Default is "%Y %m %d %H".
164
-
165
- Returns
166
- -------
167
- df : pandas.DataFrame
168
- DataFrame with added datetime as index
169
- '''
170
- dates = [datetime.strptime(str(d), dt_format) for d in dt_str]
171
- df['time'] = dates
172
- df = df.set_index('time')
173
- df.drop(columns=df.columns[0], axis=1, inplace=True)
174
- return df
175
-
176
- #------------------------------------------------------------------------------
177
-
178
- class TestGet(unittest.TestCase):
179
- def testURL(self):
180
- '''Test URL retrieval'''
181
- l = lookup_table(['doi:10.22008/FK2/IW73UU'])
182
- self.assertTrue('10.22008/FK2' in list(l.values())[0])
183
-
184
- # def testAWSname(self):
185
- # '''Test AWS names retrieval'''
186
- # n = aws_names()
187
- # self.assertIsInstance(n, list)
188
- # self.assertTrue('nuk_k_hour.csv' in n)
189
-
190
- # def testAWScsv(self):
191
- # '''Test AWS data retrieval'''
192
- # kan_b = aws_data('kan_b_hour.csv')
193
- # self.assertIsInstance(kan_b, pd.DataFrame)
194
-
195
- # def testWatsonHour(self):
196
- # '''Test Wason River discharge hourly data retrieval'''
197
- # wh = watson_discharge()
198
- # self.assertTrue(wh['Q']['2021-10-27 23:00:00']==5.48)
199
-
200
- # def testWatsonDaily(self):
201
- # '''Test Wason River discharge daily data retrieval'''
202
- # wd = watson_discharge(t='day')
203
- # self.assertTrue(wd['Q']['2009-09-04 00:00:00']==4.72)
204
-
205
- def testGetCLI(self):
206
- '''Test get_promice_data'''
207
- exit_status = os.system('get_promice_data -h')
208
- self.assertEqual(exit_status, 0)
209
-
210
- if __name__ == "__main__":
211
- unittest.main()
@@ -1,56 +0,0 @@
1
- #!/usr/bin/env python
2
- from argparse import ArgumentParser
3
- import os, unittest
4
- from pypromice.get.get import aws_data
5
-
6
-
7
- def parse_arguments_data():
8
- parser = ArgumentParser(description="PROMICE and GC-Net dataset fetcher")
9
- parser.add_argument('-n', '--awsname', default=None, type=str, required=True,
10
- help='AWS name')
11
- parser.add_argument('-f', '--format', default='csv', type=str, required=False,
12
- help='File format to save data as')
13
- parser.add_argument('-o', '--outpath', default=os.getcwd(), type=str, required=False,
14
- help='Directory where file will be written to')
15
- args = parser.parse_args()
16
- return args
17
-
18
-
19
- def get_promice_data():
20
- '''Command line driver for fetching PROMICE and GC-Net datasets'''
21
-
22
- args = parse_arguments_data()
23
-
24
- # Construct AWS dataset name
25
- # n = aws_names()
26
- # assert(args.awsname in n)
27
-
28
- # Check file format type
29
- f = args.format.lower()
30
- assert(args.format in ['csv', 'nc', '.csv', '.nc'])
31
-
32
- # Construct output file path
33
- assert(os.path.exists(args.outpath))
34
-
35
- # Remove pre-existing files of same name
36
- if os.path.isfile(f):
37
- os.remove(f)
38
-
39
- # Fetch data
40
- print(f'Fetching {args.awsname.lower()}...')
41
- data = aws_data(args.awsname.lower())
42
-
43
- # Save to file
44
- if f in 'csv':
45
- outfile = os.path.join(args.outpath, args.awsname.lower())
46
- if outfile is not None:
47
- data.to_csv(outfile)
48
- elif f in 'nc':
49
- data.to_netcdf(outfile, mode='w', format='NETCDF4', compute=True)
50
- if outfile is not None:
51
- outfile = os.path.join(args.outpath, args.awsname.lower().split('.csv')[0]+'.nc')
52
-
53
- print(f'File saved to {outfile}')
54
-
55
- if __name__ == "__main__":
56
- get_promice_data()