CMIP7-data-request-api 1.1.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.
- CMIP7_data_request_api-1.1.2.dist-info/LICENSE +21 -0
- CMIP7_data_request_api-1.1.2.dist-info/METADATA +210 -0
- CMIP7_data_request_api-1.1.2.dist-info/RECORD +36 -0
- CMIP7_data_request_api-1.1.2.dist-info/WHEEL +5 -0
- CMIP7_data_request_api-1.1.2.dist-info/entry_points.txt +2 -0
- CMIP7_data_request_api-1.1.2.dist-info/top_level.txt +1 -0
- data_request_api/__init__.py +1 -0
- data_request_api/command_line/__init__.py +0 -0
- data_request_api/command_line/export_dreq_lists_json.py +136 -0
- data_request_api/dev/JA/__init__.py +0 -0
- data_request_api/dev/JA/check_plev_requests.py +416 -0
- data_request_api/dev/JA/read_feedback_spreadsheet.py +141 -0
- data_request_api/dev/JA/workflow_example_GRtest.py +275 -0
- data_request_api/dev/JA/workflow_example_test.py +222 -0
- data_request_api/dev/MM/checksum.py +68 -0
- data_request_api/dev/MM/walking_data_request.ipynb +380 -0
- data_request_api/dev/MS/dreq_content_and_walking_data_request.ipynb +3755 -0
- data_request_api/dev/__init__.py +0 -0
- data_request_api/stable/__init__.py +0 -0
- data_request_api/stable/content/README.MD +106 -0
- data_request_api/stable/content/__init__.py +0 -0
- data_request_api/stable/content/dreq_api/__init__.py +0 -0
- data_request_api/stable/content/dreq_api/consolidate_export.py +488 -0
- data_request_api/stable/content/dreq_api/dreq_content.py +593 -0
- data_request_api/stable/content/dreq_api/mapping_table.py +335 -0
- data_request_api/stable/content/dreq_api/test_dreq_content.py +194 -0
- data_request_api/stable/content/dump_transformation.py +550 -0
- data_request_api/stable/query/__init__.py +0 -0
- data_request_api/stable/query/data_request.py +1120 -0
- data_request_api/stable/query/dreq_classes.py +372 -0
- data_request_api/stable/query/dreq_query.py +981 -0
- data_request_api/stable/query/vocabulary_server.py +208 -0
- data_request_api/stable/utilities/__init__.py +0 -0
- data_request_api/stable/utilities/logger.py +71 -0
- data_request_api/stable/utilities/tools.py +49 -0
- data_request_api/version.py +16 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
from __future__ import division, print_function, unicode_literals, absolute_import
|
|
8
|
+
|
|
9
|
+
import pprint
|
|
10
|
+
from collections import defaultdict
|
|
11
|
+
|
|
12
|
+
import six
|
|
13
|
+
|
|
14
|
+
import json
|
|
15
|
+
|
|
16
|
+
from data_request_api.stable.content.dreq_api import dreq_content as dc
|
|
17
|
+
from data_request_api.stable.query.data_request import DataRequest
|
|
18
|
+
from data_request_api.stable.utilities.logger import change_log_file, change_log_level
|
|
19
|
+
|
|
20
|
+
# Set up log file (default to stdout) and log level
|
|
21
|
+
change_log_file(default=True)
|
|
22
|
+
change_log_level("debug")
|
|
23
|
+
|
|
24
|
+
### Step 1: Get the content of the DR
|
|
25
|
+
# Define content version to be used
|
|
26
|
+
use_dreq_version = 'v1.0beta'
|
|
27
|
+
# use_dreq_version = "first_export"
|
|
28
|
+
# use_dreq_version = 'new_export_15Oct2024'
|
|
29
|
+
# Download specified version of data request content (if not locally cached)
|
|
30
|
+
# dc.retrieve(use_dreq_version)
|
|
31
|
+
# Load content into python dict
|
|
32
|
+
# content = dc.load(use_dreq_version)
|
|
33
|
+
|
|
34
|
+
### Step 2: Load it into the software of the DR
|
|
35
|
+
# DR = DataRequest.from_input(json_input=content, version=use_dreq_version)
|
|
36
|
+
# path = f'../sandbox/MS/dreq_api/dreq_res/{use_dreq_version}'
|
|
37
|
+
path = f'../MS/dreq_api/dreq_res/{use_dreq_version}'
|
|
38
|
+
DR = DataRequest.from_separated_inputs(DR_input=f"{path}/DR_content.json",
|
|
39
|
+
VS_input=f"{path}/VS_content.json")
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
GR_demo = False
|
|
43
|
+
if GR_demo:
|
|
44
|
+
### Step 3: Get information from the DR
|
|
45
|
+
# -> Print DR content
|
|
46
|
+
print(DR)
|
|
47
|
+
# -> Print an experiment group content
|
|
48
|
+
print(DR.get_experiments_groups()[0])
|
|
49
|
+
# -> Get all variables' id associated with an opportunity
|
|
50
|
+
print(DR.find_variables_per_opportunity(DR.get_opportunities()[0]))
|
|
51
|
+
# -> Get all experiments' id associated with an opportunity
|
|
52
|
+
print(DR.find_experiments_per_opportunity(DR.get_opportunities()[0]))
|
|
53
|
+
# -> Get information about the shapes of the variables of all variables groups
|
|
54
|
+
rep = dict()
|
|
55
|
+
for elt in DR.get_variables_groups():
|
|
56
|
+
rep[elt.id] = dict(spatial_shape=set(), frequency=set(), temporal_shape=set(), physical_parameter=set())
|
|
57
|
+
for var in elt.get_variables():
|
|
58
|
+
for key in ["spatial_shape", "frequency", "temporal_shape", "physical_parameter"]:
|
|
59
|
+
rep[elt.id][key] = rep[elt.id][key].union(set([elt.get("name", "???") if isinstance(elt, dict) else elt
|
|
60
|
+
for elt in var.__getattribute__(key)]))
|
|
61
|
+
|
|
62
|
+
rep = defaultdict(lambda: defaultdict(set))
|
|
63
|
+
for elt in DR.get_variables_groups():
|
|
64
|
+
for var in elt.get_variables():
|
|
65
|
+
param = var.physical_parameter["name"]
|
|
66
|
+
freq = var.frequency["name"]
|
|
67
|
+
realm = set([elt if isinstance(elt, six.string_types) else elt.get("name", "???") for elt in var.modelling_realm])
|
|
68
|
+
spt_shp = set([elt if isinstance(elt, six.string_types) else elt.get("name", "???") for elt in var.spatial_shape])
|
|
69
|
+
tmp_shp = set([elt if isinstance(elt, six.string_types) else elt.get("name", "???") for elt in var.temporal_shape])
|
|
70
|
+
for (rlm, freq, sshp, tshp) in zip(realm, [freq, ], spt_shp, tmp_shp):
|
|
71
|
+
rep[rlm][param].add(f"{freq} // {sshp} // {tshp}")
|
|
72
|
+
pprint.pprint(rep)
|
|
73
|
+
# pprint.pprint(rep_data)
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
# from copy import deepcopy
|
|
79
|
+
# DR0 = deepcopy(DR)
|
|
80
|
+
|
|
81
|
+
print(type(DR))
|
|
82
|
+
|
|
83
|
+
opp = DR.get_opportunities()[0]
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# simpler way to do this?
|
|
87
|
+
def get_name(x):
|
|
88
|
+
return x.vs.get_element(x.DR_type, x.id, 'name')
|
|
89
|
+
|
|
90
|
+
title = 'Ocean Extremes'
|
|
91
|
+
opp = [opp for opp in DR.get_opportunities() if get_name(opp) == 'Ocean Extremes'][0]
|
|
92
|
+
|
|
93
|
+
# print()
|
|
94
|
+
# print(opp)
|
|
95
|
+
|
|
96
|
+
# print()
|
|
97
|
+
# for theme in opp.get_themes():
|
|
98
|
+
# print(theme)
|
|
99
|
+
|
|
100
|
+
# print()
|
|
101
|
+
# for expt_group in opp.get_experiments_groups():
|
|
102
|
+
# print(expt_group)
|
|
103
|
+
|
|
104
|
+
# print()
|
|
105
|
+
# for var_group in opp.get_variables_groups():
|
|
106
|
+
# print(var_group)
|
|
107
|
+
|
|
108
|
+
# print()
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
# print(len(opp_vars), len(opp_expts))
|
|
112
|
+
|
|
113
|
+
# var = opp_vars[0]
|
|
114
|
+
|
|
115
|
+
# copied this out of VS_content.json, surely there's a way to get this lookup info from DR object?
|
|
116
|
+
lookup = {
|
|
117
|
+
"priority_level": {
|
|
118
|
+
# note, this info is keyed on the uid, which is found in the export
|
|
119
|
+
# e.g. in dreq_release_export.json for v1.0beta:
|
|
120
|
+
# "Name": "High",
|
|
121
|
+
# "Notes": "High priority should be used sparingly",
|
|
122
|
+
# "UID": "527f5c94-8c97-11ef-944e-41a8eb05f654",
|
|
123
|
+
# "Value": 2,
|
|
124
|
+
"527f5c94-8c97-11ef-944e-41a8eb05f654": {
|
|
125
|
+
"name": "High",
|
|
126
|
+
"notes": "High priority should be used sparingly",
|
|
127
|
+
"value": 2
|
|
128
|
+
},
|
|
129
|
+
"527f5c95-8c97-11ef-944e-41a8eb05f654": {
|
|
130
|
+
"name": "Medium",
|
|
131
|
+
"value": 3
|
|
132
|
+
},
|
|
133
|
+
"527f5c96-8c97-11ef-944e-41a8eb05f654": {
|
|
134
|
+
"name": "Low",
|
|
135
|
+
"value": 4
|
|
136
|
+
},
|
|
137
|
+
"527f5c97-8c97-11ef-944e-41a8eb05f654": {
|
|
138
|
+
"name": "Core",
|
|
139
|
+
"notes": "Top priority -- adopted by panels",
|
|
140
|
+
"value": 1
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
priority_levels = [info['name'] for info in lookup['priority_level'].values()]
|
|
145
|
+
|
|
146
|
+
def get_unique_var_name(var):
|
|
147
|
+
return var.compound_name
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
use_opps = []
|
|
151
|
+
use_opps.append('Baseline Climate Variables for Earth System Modelling')
|
|
152
|
+
use_opps.append('Synoptic systems and impacts')
|
|
153
|
+
# use_opps.append('Climate impact assessments on freshwater ecosystems')
|
|
154
|
+
# use_opps.append('Ocean Extremes')
|
|
155
|
+
|
|
156
|
+
use_opps = 'all'
|
|
157
|
+
|
|
158
|
+
# lookup table of opportunities by their title
|
|
159
|
+
opps = {}
|
|
160
|
+
for opp in DR.get_opportunities():
|
|
161
|
+
title = get_name(opp)
|
|
162
|
+
assert title not in opps, f'opp title not unique: {title}'
|
|
163
|
+
opps[title] = opp
|
|
164
|
+
|
|
165
|
+
request = {} # dict to hold aggregated request
|
|
166
|
+
|
|
167
|
+
check = not True
|
|
168
|
+
|
|
169
|
+
if use_opps == 'all':
|
|
170
|
+
use_opps = list(opps.keys())
|
|
171
|
+
|
|
172
|
+
use_opps = sorted(use_opps)
|
|
173
|
+
for title in use_opps:
|
|
174
|
+
|
|
175
|
+
opp = opps[title]
|
|
176
|
+
|
|
177
|
+
if check:
|
|
178
|
+
opp_expts = set()
|
|
179
|
+
for expt_group in opp.experiments_groups:
|
|
180
|
+
opp_expts.update([expt.name for expt in expt_group.get_experiments()])
|
|
181
|
+
opp_expts0 = opp_expts
|
|
182
|
+
|
|
183
|
+
# -> Get all experiments' id associated with an opportunity
|
|
184
|
+
opp_expts = DR.find_experiments_per_opportunity(opp)
|
|
185
|
+
opp_expts = set([expt.name for expt in opp_expts])
|
|
186
|
+
|
|
187
|
+
if check:
|
|
188
|
+
assert opp_expts == opp_expts0
|
|
189
|
+
del opp_expts0
|
|
190
|
+
|
|
191
|
+
if check:
|
|
192
|
+
# -> Get all variables' id associated with an opportunity
|
|
193
|
+
opp_vars = DR.find_variables_per_opportunity(opp)
|
|
194
|
+
opp_vars0 = set([get_unique_var_name(var) for var in opp_vars])
|
|
195
|
+
|
|
196
|
+
# Loop over variable groups to get opportunity's variables separated by priority level
|
|
197
|
+
opp_vars = {p : set() for p in priority_levels}
|
|
198
|
+
for vg in opp.variables_groups:
|
|
199
|
+
|
|
200
|
+
assert isinstance(vg.priority, list) and len(vg.priority) == 1
|
|
201
|
+
priority_info = lookup['priority_level'][vg.priority[0]]
|
|
202
|
+
priority_level = priority_info['name'] # e.g. "Core", "High", ...
|
|
203
|
+
|
|
204
|
+
for var in vg.variables:
|
|
205
|
+
var_name = get_unique_var_name(var)
|
|
206
|
+
# Add this variable to the list of requested variables at the specified priority
|
|
207
|
+
opp_vars[priority_level].add(var_name)
|
|
208
|
+
|
|
209
|
+
if check:
|
|
210
|
+
opp_vars1 = set()
|
|
211
|
+
for priority_level in opp_vars:
|
|
212
|
+
opp_vars1.update(opp_vars[priority_level])
|
|
213
|
+
assert opp_vars1 == opp_vars0 # confirm that DR.find_variables_per_opportunity(opp) lumps all priority levels together
|
|
214
|
+
del opp_vars0, opp_vars1
|
|
215
|
+
|
|
216
|
+
# Aggregate this Opportunity's request into the master list of requests
|
|
217
|
+
for expt_name in opp_expts:
|
|
218
|
+
if expt_name not in request:
|
|
219
|
+
# If we haven't encountered this experiment yet, initialize an expt_request object for it
|
|
220
|
+
request[expt_name] = {p : set() for p in priority_levels}
|
|
221
|
+
|
|
222
|
+
# Add this Opportunity's variables request to the expt_request object
|
|
223
|
+
for priority_level, var_names in opp_vars.items():
|
|
224
|
+
request[expt_name][priority_level].update(opp_vars[priority_level])
|
|
225
|
+
|
|
226
|
+
|
|
227
|
+
# Remove any overlaps in variable lists between different priority levels
|
|
228
|
+
priority_hierarchy = ['Core', 'High', 'Medium', 'Low'] # ordered from highest to lowest priority
|
|
229
|
+
assert set(priority_hierarchy) == set(priority_levels)
|
|
230
|
+
assert len(set(priority_hierarchy)) == len(priority_hierarchy)
|
|
231
|
+
for expt_request in request.values():
|
|
232
|
+
for k,p in enumerate(priority_hierarchy):
|
|
233
|
+
for p_higher in priority_hierarchy[:k]:
|
|
234
|
+
expt_request[p] = expt_request[p].difference(expt_request[p_higher])
|
|
235
|
+
# print(p,p_higher)
|
|
236
|
+
# print()
|
|
237
|
+
|
|
238
|
+
# convert sets to lists for json output
|
|
239
|
+
for p in expt_request:
|
|
240
|
+
expt_request[p] = sorted(expt_request[p], key=str.lower)
|
|
241
|
+
|
|
242
|
+
expt_vars = {
|
|
243
|
+
'Header' : {
|
|
244
|
+
'Opportunities' : use_opps,
|
|
245
|
+
'dreq version' : use_dreq_version,
|
|
246
|
+
},
|
|
247
|
+
'experiment' : request,
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
|
|
251
|
+
if len(expt_vars['experiment']) > 0:
|
|
252
|
+
|
|
253
|
+
# Show user what was found
|
|
254
|
+
print(f'\nFor data request version {use_dreq_version}, number of requested variables found by experiment:')
|
|
255
|
+
priority_levels = ['Core', 'High', 'Medium', 'Low']
|
|
256
|
+
for expt, req in sorted(expt_vars['experiment'].items()):
|
|
257
|
+
d = {p : 0 for p in priority_levels}
|
|
258
|
+
for p in priority_levels:
|
|
259
|
+
if p in req:
|
|
260
|
+
d[p] = len(req[p])
|
|
261
|
+
n_total = sum(d.values())
|
|
262
|
+
print(f' {expt} : ' + ' ,'.join(['{p}={n}'.format(p=p,n=d[p]) for p in priority_levels]) + f', TOTAL={n_total}')
|
|
263
|
+
|
|
264
|
+
# Write the results to json
|
|
265
|
+
filename = 'requested2.json'
|
|
266
|
+
with open(filename, 'w') as f:
|
|
267
|
+
json.dump(expt_vars, f, indent=4, sort_keys=True)
|
|
268
|
+
print('\nWrote requested variables to ' + filename)
|
|
269
|
+
|
|
270
|
+
else:
|
|
271
|
+
print(f'\nFor data request version {use_dreq_version}, no requested variables were found')
|
|
272
|
+
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
#!/usr/bin/env python
|
|
2
|
+
'''
|
|
3
|
+
Example script for basic use of CMIP7 data request content
|
|
4
|
+
|
|
5
|
+
Getting started
|
|
6
|
+
---------------
|
|
7
|
+
First create an environment with the required dependencies:
|
|
8
|
+
|
|
9
|
+
conda env create -n my_dreq_env --file env.yml
|
|
10
|
+
|
|
11
|
+
(replacing my_dreq_env with your preferred env name). Then activate it and run the script:
|
|
12
|
+
|
|
13
|
+
conda activate my_dreq_env
|
|
14
|
+
python workflow_example.py
|
|
15
|
+
|
|
16
|
+
will load the data request content and save a json file of requested variables in the current dir.
|
|
17
|
+
To run interactively in ipython:
|
|
18
|
+
|
|
19
|
+
run -i workflow_example.py
|
|
20
|
+
|
|
21
|
+
'''
|
|
22
|
+
# try: tables
|
|
23
|
+
# except: tables = {}
|
|
24
|
+
|
|
25
|
+
# use_export = 'release'
|
|
26
|
+
# use_export = 'raw'
|
|
27
|
+
|
|
28
|
+
# if True:
|
|
29
|
+
if False:
|
|
30
|
+
|
|
31
|
+
for use_export in tables:
|
|
32
|
+
|
|
33
|
+
print(f'\n*** {use_export} ***')
|
|
34
|
+
|
|
35
|
+
VarGroups = tables[use_export]['VarGroups']
|
|
36
|
+
Opps = tables[use_export]['Opps']
|
|
37
|
+
|
|
38
|
+
titles = []
|
|
39
|
+
titles.append('Temperature variability')
|
|
40
|
+
titles.append('Ocean Extremes')
|
|
41
|
+
|
|
42
|
+
for title in titles:
|
|
43
|
+
print()
|
|
44
|
+
opp = Opps.get_attr_record('title', title)
|
|
45
|
+
print(opp.title)
|
|
46
|
+
for link in opp.variable_groups:
|
|
47
|
+
vg = VarGroups.get_record(link)
|
|
48
|
+
print(vg.name)
|
|
49
|
+
|
|
50
|
+
stop
|
|
51
|
+
|
|
52
|
+
import json
|
|
53
|
+
from data_request_api.stable.content.dreq_api import dreq_content as dc
|
|
54
|
+
from data_request_api.stable.query import dreq_query as dq
|
|
55
|
+
|
|
56
|
+
from importlib import reload
|
|
57
|
+
reload(dq)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
test = True
|
|
61
|
+
|
|
62
|
+
|
|
63
|
+
# Specify opportunities that modelling group chooses to support
|
|
64
|
+
# This can be a subset:
|
|
65
|
+
use_opps = []
|
|
66
|
+
use_opps.append('Baseline Climate Variables for Earth System Modelling')
|
|
67
|
+
# use_opps.append('Synoptic systems and impacts')
|
|
68
|
+
# use_opps.append('Climate impact assessments on freshwater ecosystems')
|
|
69
|
+
use_opps.append('Ocean Extremes')
|
|
70
|
+
|
|
71
|
+
# Or to use all opportunities in the data request:
|
|
72
|
+
use_opps = 'all'
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if test:
|
|
76
|
+
|
|
77
|
+
import os
|
|
78
|
+
|
|
79
|
+
use_dreq_version = 'v1.0beta'
|
|
80
|
+
|
|
81
|
+
use_export = 'release'
|
|
82
|
+
use_export = 'raw'
|
|
83
|
+
|
|
84
|
+
use_consolidated = not True
|
|
85
|
+
|
|
86
|
+
load_manually = not True
|
|
87
|
+
|
|
88
|
+
if load_manually:
|
|
89
|
+
# just for testing
|
|
90
|
+
path = '/home/rja001/code/dreq/CMIP7_DReq_Content/airtable_export'
|
|
91
|
+
filepath = os.path.join(path, 'dreq_working.json')
|
|
92
|
+
with open(filepath, 'r') as f:
|
|
93
|
+
content = json.load(f)
|
|
94
|
+
print('loaded ' + filepath)
|
|
95
|
+
|
|
96
|
+
use_consolidated = False
|
|
97
|
+
|
|
98
|
+
else:
|
|
99
|
+
# Download specified version of data request content (if not locally cached)
|
|
100
|
+
dc.retrieve(use_dreq_version, export=use_export)
|
|
101
|
+
# Load content into python dict
|
|
102
|
+
content = dc.load(use_dreq_version, export=use_export, consolidate=use_consolidated)
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
else:
|
|
108
|
+
|
|
109
|
+
use_dreq_version = 'v1.0beta'
|
|
110
|
+
|
|
111
|
+
# Download specified version of data request content (if not locally cached)
|
|
112
|
+
dc.retrieve(use_dreq_version)
|
|
113
|
+
# Load content into python dict
|
|
114
|
+
content = dc.load(use_dreq_version)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
# Get consolidated list of requested variables that supports these opportunities
|
|
118
|
+
dq.DREQ_VERSION = use_dreq_version
|
|
119
|
+
|
|
120
|
+
if test:
|
|
121
|
+
|
|
122
|
+
use_old_get = False
|
|
123
|
+
|
|
124
|
+
if use_old_get:
|
|
125
|
+
|
|
126
|
+
if len(content.keys()) == 1:
|
|
127
|
+
k = 'Data Request'
|
|
128
|
+
if k in content:
|
|
129
|
+
content[f'{k} {use_dreq_version}'] = content[k]
|
|
130
|
+
content.pop(k)
|
|
131
|
+
expt_vars = dq._get_requested_variables(content, use_opps, priority_cutoff='Low')
|
|
132
|
+
|
|
133
|
+
else:
|
|
134
|
+
|
|
135
|
+
expt_vars = dq.get_requested_variables(content, use_opps, priority_cutoff='Low', verbose=False, consolidated=use_consolidated)
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
if False:
|
|
141
|
+
# return Opps, VarGroups, PriorityLevel, ExptGroups, Expts
|
|
142
|
+
|
|
143
|
+
Opps, VarGroups, PriorityLevel, ExptGroups, Expts = expt_vars
|
|
144
|
+
del expt_vars
|
|
145
|
+
|
|
146
|
+
tables[use_export] = {
|
|
147
|
+
'Opps' : Opps, 'VarGroups' : VarGroups,
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
opps = []
|
|
151
|
+
opps.append( Opps.get_attr_record('title', 'Temperature variability') )
|
|
152
|
+
|
|
153
|
+
# opps.append( Opps.get_attr_record('title', 'Ocean Extremes') )
|
|
154
|
+
|
|
155
|
+
for title in [
|
|
156
|
+
"Ocean Extremes",
|
|
157
|
+
"Ocean changes, drivers and impacts",
|
|
158
|
+
"Rapid Evaluation Framework",
|
|
159
|
+
"Paleoclimate research at the interface between past, present, and future",
|
|
160
|
+
"Robust Risk Assessment of Tipping Points",
|
|
161
|
+
]:
|
|
162
|
+
opps.append( Opps.get_attr_record('title', title) )
|
|
163
|
+
|
|
164
|
+
# achtung!
|
|
165
|
+
# "Ocean Extremes",
|
|
166
|
+
# "Ocean changes, drivers and impacts",
|
|
167
|
+
# "Rapid Evaluation Framework",
|
|
168
|
+
# "Paleoclimate research at the interface between past, present, and future",
|
|
169
|
+
# "Robust Risk Assessment of Tipping Points",
|
|
170
|
+
|
|
171
|
+
# opp = opps[0]
|
|
172
|
+
# opp_expts0 = dq.get_opp_expts(opp, ExptGroups, Expts, verbose=False)
|
|
173
|
+
|
|
174
|
+
for opp in opps:
|
|
175
|
+
print('\n' + opp.title)
|
|
176
|
+
# opp_expts = dq.get_opp_expts(opp, ExptGroups, Expts, verbose=False)
|
|
177
|
+
# print(opp_expts.difference(opp_expts0))
|
|
178
|
+
for link in opp.variable_groups:
|
|
179
|
+
vg = VarGroups.get_record(link)
|
|
180
|
+
if isinstance(vg.priority_level, str):
|
|
181
|
+
assert PriorityLevel is None
|
|
182
|
+
print(vg.priority_level)
|
|
183
|
+
else:
|
|
184
|
+
link = vg.priority_level[0]
|
|
185
|
+
pl = PriorityLevel.get_record(link)
|
|
186
|
+
print(' ' + pl.name)
|
|
187
|
+
stop
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
else:
|
|
191
|
+
|
|
192
|
+
expt_vars = dq.get_requested_variables(content, use_opps, priority_cutoff='Low')
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
if len(expt_vars['experiment']) > 0:
|
|
196
|
+
|
|
197
|
+
# Show user what was found
|
|
198
|
+
print(f'\nFor data request version {use_dreq_version}, number of requested variables found by experiment:')
|
|
199
|
+
priority_levels = ['Core', 'High', 'Medium', 'Low']
|
|
200
|
+
for expt, req in expt_vars['experiment'].items():
|
|
201
|
+
d = {p : 0 for p in priority_levels}
|
|
202
|
+
for p in priority_levels:
|
|
203
|
+
if p in req:
|
|
204
|
+
d[p] = len(req[p])
|
|
205
|
+
n_total = sum(d.values())
|
|
206
|
+
print(f' {expt} : ' + ' ,'.join(['{p}={n}'.format(p=p,n=d[p]) for p in priority_levels]) + f', TOTAL={n_total}')
|
|
207
|
+
|
|
208
|
+
# Write the results to json
|
|
209
|
+
# filename = 'requested.json'
|
|
210
|
+
filename = f'requested_{use_export}.json'
|
|
211
|
+
|
|
212
|
+
with open(filename, 'w') as f:
|
|
213
|
+
json.dump(expt_vars, f, indent=4, sort_keys=True)
|
|
214
|
+
print('\nWrote requested variables to ' + filename)
|
|
215
|
+
|
|
216
|
+
else:
|
|
217
|
+
print(f'\nFor data request version {use_dreq_version}, no requested variables were found')
|
|
218
|
+
|
|
219
|
+
# To remove locally cached version:
|
|
220
|
+
# dc.delete(use_dreq_version)
|
|
221
|
+
# To remove all locally cached versions:
|
|
222
|
+
# dc.delete()
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
'''
|
|
2
|
+
https://gist.github.com/matthew-mizielinski/643ca1841dc760edf230473a8b81d396
|
|
3
|
+
'''
|
|
4
|
+
|
|
5
|
+
import copy
|
|
6
|
+
import json
|
|
7
|
+
import hashlib
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
def set_checksum(dictionary, overwrite=True):
|
|
11
|
+
"""
|
|
12
|
+
Calculate the checksum for the ``dictionary``, then add the
|
|
13
|
+
value to ``dictionary`` under the ``checksum`` key. ``dictionary``
|
|
14
|
+
is modified in place.
|
|
15
|
+
|
|
16
|
+
Parameters
|
|
17
|
+
----------
|
|
18
|
+
dictionary: dict
|
|
19
|
+
The dictionary to set the checksum to.
|
|
20
|
+
overwrite: bool
|
|
21
|
+
Overwrite the existing checksum (default True).
|
|
22
|
+
|
|
23
|
+
Raises
|
|
24
|
+
------
|
|
25
|
+
RuntimeError
|
|
26
|
+
If the ``checksum`` key already exists and ``overwrite`` is
|
|
27
|
+
False.
|
|
28
|
+
"""
|
|
29
|
+
if 'checksum' in dictionary:
|
|
30
|
+
if not overwrite:
|
|
31
|
+
raise RuntimeError('Checksum already exists.')
|
|
32
|
+
del dictionary['checksum']
|
|
33
|
+
checksum = _checksum(dictionary)
|
|
34
|
+
dictionary['checksum'] = checksum
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def validate_checksum(dictionary):
|
|
38
|
+
"""
|
|
39
|
+
Validate the checksum in the ``dictionary``.
|
|
40
|
+
|
|
41
|
+
Parameters
|
|
42
|
+
----------
|
|
43
|
+
dictionary: dict
|
|
44
|
+
The dictionary containing the ``checksum`` to validate.
|
|
45
|
+
|
|
46
|
+
Raises
|
|
47
|
+
------
|
|
48
|
+
KeyError
|
|
49
|
+
If the ``checksum`` key does not exist.
|
|
50
|
+
RuntimeError
|
|
51
|
+
If the ``checksum`` value is invalid.
|
|
52
|
+
"""
|
|
53
|
+
if 'checksum' not in dictionary:
|
|
54
|
+
raise KeyError('No checksum to validate')
|
|
55
|
+
dictionary_copy = copy.deepcopy(dictionary)
|
|
56
|
+
del dictionary_copy['checksum']
|
|
57
|
+
checksum = _checksum(dictionary_copy)
|
|
58
|
+
if dictionary['checksum'] != checksum:
|
|
59
|
+
msg = ('Expected checksum "{}"\n'
|
|
60
|
+
'Calculated checksum "{}"').format(dictionary['checksum'],
|
|
61
|
+
checksum)
|
|
62
|
+
raise RuntimeError(msg)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _checksum(obj):
|
|
66
|
+
obj_str = json.dumps(obj, sort_keys=True)
|
|
67
|
+
checksum_hex = hashlib.md5(obj_str.encode('utf8')).hexdigest()
|
|
68
|
+
return 'md5: {}'.format(checksum_hex)
|