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,380 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "code",
|
|
5
|
+
"execution_count": 1,
|
|
6
|
+
"id": "ee4ccd2a-6455-4ce7-81a8-cad76b950c91",
|
|
7
|
+
"metadata": {},
|
|
8
|
+
"outputs": [],
|
|
9
|
+
"source": [
|
|
10
|
+
"# imports\n",
|
|
11
|
+
"from collections import defaultdict\n",
|
|
12
|
+
"import json\n",
|
|
13
|
+
"from dataclasses import dataclass"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
"cell_type": "code",
|
|
18
|
+
"execution_count": 2,
|
|
19
|
+
"id": "c21eafe7-973b-4df9-ab51-3294fe83bd5e",
|
|
20
|
+
"metadata": {},
|
|
21
|
+
"outputs": [],
|
|
22
|
+
"source": [
|
|
23
|
+
"# Define data classes for each object type.\n",
|
|
24
|
+
"# Have only pulled out a very limited set of objects and their parameters as a demonstration\n",
|
|
25
|
+
"\n",
|
|
26
|
+
"@dataclass\n",
|
|
27
|
+
"class Experiment:\n",
|
|
28
|
+
" record_id: str\n",
|
|
29
|
+
" experiment_name: str\n",
|
|
30
|
+
" mips: list\n",
|
|
31
|
+
" experiment_groups: list\n",
|
|
32
|
+
"\n",
|
|
33
|
+
"\n",
|
|
34
|
+
"@dataclass\n",
|
|
35
|
+
"class ExperimentGroup:\n",
|
|
36
|
+
" record_id: str\n",
|
|
37
|
+
" experiments: list\n",
|
|
38
|
+
" name: str\n",
|
|
39
|
+
" opportunities: list\n",
|
|
40
|
+
"\n",
|
|
41
|
+
"\n",
|
|
42
|
+
"@dataclass\n",
|
|
43
|
+
"class Opportunity:\n",
|
|
44
|
+
" record_id: str\n",
|
|
45
|
+
" description: str\n",
|
|
46
|
+
" experiment_groups: list\n",
|
|
47
|
+
" variable_groups: list\n",
|
|
48
|
+
"\n",
|
|
49
|
+
"\n",
|
|
50
|
+
"@dataclass\n",
|
|
51
|
+
"class VariableGroup:\n",
|
|
52
|
+
" record_id: str\n",
|
|
53
|
+
" title: str\n",
|
|
54
|
+
" variables: list\n",
|
|
55
|
+
" priority: str\n",
|
|
56
|
+
"\n",
|
|
57
|
+
"\n",
|
|
58
|
+
"@dataclass\n",
|
|
59
|
+
"class Variable:\n",
|
|
60
|
+
" record_id: str\n",
|
|
61
|
+
" standard_name: str\n",
|
|
62
|
+
" frequency: str\n",
|
|
63
|
+
" name: str"
|
|
64
|
+
]
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
"cell_type": "code",
|
|
68
|
+
"execution_count": 3,
|
|
69
|
+
"id": "abcc77b8-d0d8-4630-9479-9c18c89676d5",
|
|
70
|
+
"metadata": {},
|
|
71
|
+
"outputs": [],
|
|
72
|
+
"source": [
|
|
73
|
+
"# build dictionaries allowing Data request network to be navigated\n",
|
|
74
|
+
"\n",
|
|
75
|
+
"def build_dictionaries(filename):\n",
|
|
76
|
+
" \"\"\"\n",
|
|
77
|
+
" load json in filename and build dictionaries of data request objects\n",
|
|
78
|
+
" \"\"\"\n",
|
|
79
|
+
" # Dictionaries to be returned\n",
|
|
80
|
+
" object_dict = {}\n",
|
|
81
|
+
" structured_dict = defaultdict(dict)\n",
|
|
82
|
+
"\n",
|
|
83
|
+
" with open(filename) as fh:\n",
|
|
84
|
+
" raw_data = json.load(fh)\n",
|
|
85
|
+
"\n",
|
|
86
|
+
" # load experiments\n",
|
|
87
|
+
" for record_id, entry in raw_data['Experiments']['records'].items():\n",
|
|
88
|
+
" try:\n",
|
|
89
|
+
" expt = Experiment(\n",
|
|
90
|
+
" record_id=record_id, \n",
|
|
91
|
+
" experiment_name=entry[' Experiment'].strip(), \n",
|
|
92
|
+
" mips=entry['MIP'],\n",
|
|
93
|
+
" experiment_groups=entry['Experiment Group'])\n",
|
|
94
|
+
" except:\n",
|
|
95
|
+
" print(\"Could not interpret experiment: \", entry)\n",
|
|
96
|
+
" structured_dict['experiment'][record_id] = expt\n",
|
|
97
|
+
" object_dict[record_id] = expt\n",
|
|
98
|
+
"\n",
|
|
99
|
+
" # load experiment groups\n",
|
|
100
|
+
" for record_id, entry in raw_data['Experiment Group']['records'].items():\n",
|
|
101
|
+
" try:\n",
|
|
102
|
+
" expt_group = ExperimentGroup(\n",
|
|
103
|
+
" record_id=record_id,\n",
|
|
104
|
+
" experiments=entry['Experiments'],\n",
|
|
105
|
+
" name=entry['Name'],\n",
|
|
106
|
+
" opportunities=entry['Opportunities']\n",
|
|
107
|
+
" )\n",
|
|
108
|
+
" except:\n",
|
|
109
|
+
" print(\"Could not interpret experiment_group:\", entry)\n",
|
|
110
|
+
" structured_dict['experiment_group'][record_id] = expt_group\n",
|
|
111
|
+
" object_dict[record_id] = expt_group\n",
|
|
112
|
+
"\n",
|
|
113
|
+
" # load opportunities\n",
|
|
114
|
+
" for record_id, entry in raw_data['Opportunity']['records'].items():\n",
|
|
115
|
+
" try:\n",
|
|
116
|
+
" opportunity = Opportunity(\n",
|
|
117
|
+
" record_id=record_id,\n",
|
|
118
|
+
" description=entry['Description'],\n",
|
|
119
|
+
" experiment_groups=entry['Experiment Groups'],\n",
|
|
120
|
+
" variable_groups=entry['Variable Groups']\n",
|
|
121
|
+
" )\n",
|
|
122
|
+
" except:\n",
|
|
123
|
+
" print(\"could not interpret opportunity\", entry)\n",
|
|
124
|
+
" structured_dict['opportunity'][record_id] = opportunity\n",
|
|
125
|
+
" object_dict[record_id] = opportunity\n",
|
|
126
|
+
"\n",
|
|
127
|
+
" # load variable groups\n",
|
|
128
|
+
" for record_id, entry in raw_data['Variable Group']['records'].items():\n",
|
|
129
|
+
" try:\n",
|
|
130
|
+
" variable_group = VariableGroup(\n",
|
|
131
|
+
" record_id=record_id,\n",
|
|
132
|
+
" title=entry['Title'],\n",
|
|
133
|
+
" variables=entry['Variables'],\n",
|
|
134
|
+
" priority=entry['Priority Level']\n",
|
|
135
|
+
" )\n",
|
|
136
|
+
" except:\n",
|
|
137
|
+
" print(\"Could not interpret variable group\", entry)\n",
|
|
138
|
+
" structured_dict['variable_group'][record_id] = variable_group\n",
|
|
139
|
+
" object_dict[record_id] = variable_group\n",
|
|
140
|
+
"\n",
|
|
141
|
+
" # load variables\n",
|
|
142
|
+
" for record_id, entry in raw_data['Variables']['records'].items():\n",
|
|
143
|
+
" try:\n",
|
|
144
|
+
" variable = Variable(\n",
|
|
145
|
+
" record_id=record_id,\n",
|
|
146
|
+
" standard_name=entry['CF Standard Name (from MIP Variables)'],\n",
|
|
147
|
+
" frequency=entry['Frequency'][0],\n",
|
|
148
|
+
" name=entry['Compound Name']\n",
|
|
149
|
+
" )\n",
|
|
150
|
+
" except:\n",
|
|
151
|
+
" print(\"Could not interpret as variable:\", entry)\n",
|
|
152
|
+
" structured_dict['variable'][record_id] = variable\n",
|
|
153
|
+
" object_dict[record_id] = variable\n",
|
|
154
|
+
"\n",
|
|
155
|
+
" # return dictionaries\n",
|
|
156
|
+
" return object_dict, structured_dict"
|
|
157
|
+
]
|
|
158
|
+
},
|
|
159
|
+
{
|
|
160
|
+
"cell_type": "code",
|
|
161
|
+
"execution_count": 4,
|
|
162
|
+
"id": "4a639eb1-5bdf-411b-a3e2-0774c46b9c55",
|
|
163
|
+
"metadata": {},
|
|
164
|
+
"outputs": [
|
|
165
|
+
{
|
|
166
|
+
"name": "stdout",
|
|
167
|
+
"output_type": "stream",
|
|
168
|
+
"text": [
|
|
169
|
+
"Could not interpret experiment_group: {'Experiments': ['recFIIkEdefZynPhh'], 'Name': 'spin-up', 'Title': 'The spin-up'}\n",
|
|
170
|
+
"could not interpret opportunity {'Experiment Groups': ['rec0J4qnPn2vktlhO'], 'References': ['recw7gRoApscR5fsW'], 'Status': 'New', 'Title of Opportunity': 'Benchmarking'}\n",
|
|
171
|
+
"Could not interpret as variable: {'Atmosphere author team review': 'In progress', 'CF Standard Name (from MIP Variables)': 'air_temperature', 'Cell Measures': ['recb1V00ayWZnmm79'], 'Cell Methods': ['recfYDayRm62sFUsp'], 'Coordinates': 'height2m', 'Description': 'For models with fractional land areas (SFTLF) we are not currently able to diagnose near-surface air temperatures over just the land part of coastal gridboxes, with the current CMIP diagnostic set. The TAS diagnostic will be a weighted mean of the air temperatures over land and sea. If the diagnostic (lets call it LTAS) is available, we can then diagnose the air temperatures just over land, and in conjunction with TAS and SFTLF diagnose the air temperatures just over sea/sea-ice in coastal gridboxes. This will enable consistent comparisons with observational datasets (e.g. CRUTEM5 which is just air temperature over land) over regional areas with large coastal areas. \\nReference: Jones, GS, 2020, \"Apples and oranges\": on comparing near surface temperatures from climate models with observations, QJRMS, 146, Issue 733, 3747-3771, https://doi.org/10.1002/qj.3871.\\n', 'Extra Dimensions': 'latitude, longitude, time', 'Frequency': ['mon'], 'Modeling Realm': ['atmos'], 'Physical Parameter': ['reccZFphgzh8sN3yC'], 'Processing Note': \"The diagnostic is used within models that have fractional land areas to calculate coastal gridbox mean TAS, i.e., the mean of air temperatures over sea and air temperatures over land (weighted by the land/ocean areas) in models with fractional land areas. So it shouldn't be too difficult to produce the diagnostic for CMIP.\\n\", 'Spatial Shape': ['rec1eFSEpR5EWjdLK'], 'Status': 'Under review', 'Table': ['Amon'], 'Temporal Shape': ['recF1jvxHxPzKHG62'], 'Theme': ['Atmosphere'], 'Title': 'Near-surface air temperature over land', 'Type': 'real'}\n"
|
|
172
|
+
]
|
|
173
|
+
}
|
|
174
|
+
],
|
|
175
|
+
"source": [
|
|
176
|
+
"object_dict, structured_dict = build_dictionaries('request_basic_dump2.json')"
|
|
177
|
+
]
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"cell_type": "code",
|
|
181
|
+
"execution_count": 5,
|
|
182
|
+
"id": "c4ffda0e-0174-4a70-9053-6547a2d8d873",
|
|
183
|
+
"metadata": {},
|
|
184
|
+
"outputs": [],
|
|
185
|
+
"source": [
|
|
186
|
+
"# dictionary to allow lookup up of experiments\n",
|
|
187
|
+
"experiment_name_to_record_id = {i.experiment_name: i.record_id \n",
|
|
188
|
+
" for i in structured_dict['experiment'].values()}"
|
|
189
|
+
]
|
|
190
|
+
},
|
|
191
|
+
{
|
|
192
|
+
"cell_type": "code",
|
|
193
|
+
"execution_count": 6,
|
|
194
|
+
"id": "082b69c9-976a-4d5a-861c-e1679f2a42d6",
|
|
195
|
+
"metadata": {},
|
|
196
|
+
"outputs": [
|
|
197
|
+
{
|
|
198
|
+
"data": {
|
|
199
|
+
"text/plain": [
|
|
200
|
+
"'rec7mTVv08z3iBObw'"
|
|
201
|
+
]
|
|
202
|
+
},
|
|
203
|
+
"execution_count": 6,
|
|
204
|
+
"metadata": {},
|
|
205
|
+
"output_type": "execute_result"
|
|
206
|
+
}
|
|
207
|
+
],
|
|
208
|
+
"source": [
|
|
209
|
+
"experiment_name_to_record_id['historical']"
|
|
210
|
+
]
|
|
211
|
+
},
|
|
212
|
+
{
|
|
213
|
+
"cell_type": "code",
|
|
214
|
+
"execution_count": 7,
|
|
215
|
+
"id": "c6af3294-447f-4424-a992-f24381c805f9",
|
|
216
|
+
"metadata": {},
|
|
217
|
+
"outputs": [
|
|
218
|
+
{
|
|
219
|
+
"data": {
|
|
220
|
+
"text/plain": [
|
|
221
|
+
"'recR7YVoWYdbQp3wk'"
|
|
222
|
+
]
|
|
223
|
+
},
|
|
224
|
+
"execution_count": 7,
|
|
225
|
+
"metadata": {},
|
|
226
|
+
"output_type": "execute_result"
|
|
227
|
+
}
|
|
228
|
+
],
|
|
229
|
+
"source": [
|
|
230
|
+
"experiment_name_to_record_id['amip']\n"
|
|
231
|
+
]
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"cell_type": "code",
|
|
235
|
+
"execution_count": 8,
|
|
236
|
+
"id": "d0afab7c-5319-4ae6-a51d-4c80672d8602",
|
|
237
|
+
"metadata": {},
|
|
238
|
+
"outputs": [],
|
|
239
|
+
"source": [
|
|
240
|
+
"# Walk data request network from experiment to variable list:\n",
|
|
241
|
+
"\n",
|
|
242
|
+
"def walk_experiment_to_variables(experiment_id, object_dict):\n",
|
|
243
|
+
" \"\"\"\n",
|
|
244
|
+
" Navigate data request from specified experiment ids to record ids of corresponding variables\n",
|
|
245
|
+
" \"\"\"\n",
|
|
246
|
+
" expt_groups = set(object_dict[experiment_id].experiment_groups)\n",
|
|
247
|
+
" print(\"found {} connected experiment groups\".format(len(expt_groups)))\n",
|
|
248
|
+
"\n",
|
|
249
|
+
" opportunities = set()\n",
|
|
250
|
+
" for expt_group_id in expt_groups:\n",
|
|
251
|
+
" expt_group_object = object_dict[expt_group_id]\n",
|
|
252
|
+
" for opportunity_id in expt_group_object.opportunities:\n",
|
|
253
|
+
" opportunities.add(opportunity_id)\n",
|
|
254
|
+
"\n",
|
|
255
|
+
" print(\"found {} connected opportunities\".format(len(opportunities)))\n",
|
|
256
|
+
"\n",
|
|
257
|
+
" variable_groups = set()\n",
|
|
258
|
+
" for opportunity_id in opportunities:\n",
|
|
259
|
+
" opportunity_object = object_dict[opportunity_id]\n",
|
|
260
|
+
" for variable_group_id in opportunity_object.variable_groups:\n",
|
|
261
|
+
" variable_groups.add(variable_group_id)\n",
|
|
262
|
+
"\n",
|
|
263
|
+
" print(\"found {} connected variable groups\".format(len(variable_groups)))\n",
|
|
264
|
+
"\n",
|
|
265
|
+
" variables = set()\n",
|
|
266
|
+
" for variable_group_id in variable_groups:\n",
|
|
267
|
+
" variable_group_object = object_dict[variable_group_id]\n",
|
|
268
|
+
" for variable_id in variable_group_object.variables:\n",
|
|
269
|
+
" variables.add(variable_id)\n",
|
|
270
|
+
"\n",
|
|
271
|
+
" print(\"found {} connected variables\".format(len(variables)))\n",
|
|
272
|
+
"\n",
|
|
273
|
+
" return list(variables)"
|
|
274
|
+
]
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
"cell_type": "code",
|
|
278
|
+
"execution_count": 9,
|
|
279
|
+
"id": "d8f55064-b6f4-4227-825d-7ee328ebfd88",
|
|
280
|
+
"metadata": {},
|
|
281
|
+
"outputs": [
|
|
282
|
+
{
|
|
283
|
+
"name": "stdout",
|
|
284
|
+
"output_type": "stream",
|
|
285
|
+
"text": [
|
|
286
|
+
"found 2 connected experiment groups\n",
|
|
287
|
+
"found 4 connected opportunities\n",
|
|
288
|
+
"found 9 connected variable groups\n",
|
|
289
|
+
"found 239 connected variables\n"
|
|
290
|
+
]
|
|
291
|
+
}
|
|
292
|
+
],
|
|
293
|
+
"source": [
|
|
294
|
+
"historical_variables = walk_experiment_to_variables(experiment_name_to_record_id['historical'], object_dict)"
|
|
295
|
+
]
|
|
296
|
+
},
|
|
297
|
+
{
|
|
298
|
+
"cell_type": "code",
|
|
299
|
+
"execution_count": 10,
|
|
300
|
+
"id": "2d932550-6b13-487f-9ac7-450c533c53a7",
|
|
301
|
+
"metadata": {},
|
|
302
|
+
"outputs": [
|
|
303
|
+
{
|
|
304
|
+
"data": {
|
|
305
|
+
"text/plain": [
|
|
306
|
+
"['recGfiAQ8b62b8D0H',\n",
|
|
307
|
+
" 'recc29R75UVqSGpFC',\n",
|
|
308
|
+
" 'reck2Ofq8KEbUw4Yz',\n",
|
|
309
|
+
" 'recH0aJ4cZJt7up4d',\n",
|
|
310
|
+
" 'recQMtSbbOQwkDBcL',\n",
|
|
311
|
+
" 'recyHFBDBY1oy7jib',\n",
|
|
312
|
+
" 'recIWQRAqz9K78QhF',\n",
|
|
313
|
+
" 'recS5sYw7lg0By4Dn',\n",
|
|
314
|
+
" 'reczhZLOX2BxzRT93',\n",
|
|
315
|
+
" 'rec57DB6wHX5cC9uo']"
|
|
316
|
+
]
|
|
317
|
+
},
|
|
318
|
+
"execution_count": 10,
|
|
319
|
+
"metadata": {},
|
|
320
|
+
"output_type": "execute_result"
|
|
321
|
+
}
|
|
322
|
+
],
|
|
323
|
+
"source": [
|
|
324
|
+
"# Show first few variable record_ids \n",
|
|
325
|
+
"historical_variables[:10]"
|
|
326
|
+
]
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"cell_type": "code",
|
|
330
|
+
"execution_count": 11,
|
|
331
|
+
"id": "37f8ba4e-b84b-4109-8c15-b06c3579015d",
|
|
332
|
+
"metadata": {},
|
|
333
|
+
"outputs": [
|
|
334
|
+
{
|
|
335
|
+
"data": {
|
|
336
|
+
"text/plain": [
|
|
337
|
+
"False"
|
|
338
|
+
]
|
|
339
|
+
},
|
|
340
|
+
"execution_count": 11,
|
|
341
|
+
"metadata": {},
|
|
342
|
+
"output_type": "execute_result"
|
|
343
|
+
}
|
|
344
|
+
],
|
|
345
|
+
"source": [
|
|
346
|
+
"# problem: record_ids for variables don't appear to match up in the json file used here\n",
|
|
347
|
+
"any([i in object_dict for i in historical_variables])"
|
|
348
|
+
]
|
|
349
|
+
},
|
|
350
|
+
{
|
|
351
|
+
"cell_type": "code",
|
|
352
|
+
"execution_count": null,
|
|
353
|
+
"id": "7269f54c-00f3-43c9-95fb-a9309b7357e6",
|
|
354
|
+
"metadata": {},
|
|
355
|
+
"outputs": [],
|
|
356
|
+
"source": []
|
|
357
|
+
}
|
|
358
|
+
],
|
|
359
|
+
"metadata": {
|
|
360
|
+
"kernelspec": {
|
|
361
|
+
"display_name": "Python 3 (ipykernel)",
|
|
362
|
+
"language": "python",
|
|
363
|
+
"name": "python3"
|
|
364
|
+
},
|
|
365
|
+
"language_info": {
|
|
366
|
+
"codemirror_mode": {
|
|
367
|
+
"name": "ipython",
|
|
368
|
+
"version": 3
|
|
369
|
+
},
|
|
370
|
+
"file_extension": ".py",
|
|
371
|
+
"mimetype": "text/x-python",
|
|
372
|
+
"name": "python",
|
|
373
|
+
"nbconvert_exporter": "python",
|
|
374
|
+
"pygments_lexer": "ipython3",
|
|
375
|
+
"version": "3.11.8"
|
|
376
|
+
}
|
|
377
|
+
},
|
|
378
|
+
"nbformat": 4,
|
|
379
|
+
"nbformat_minor": 5
|
|
380
|
+
}
|