sparclclient 1.2.1.dev6__py2.py3-none-any.whl → 1.2.2__py2.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.
- sparcl/Results.py +11 -2
- sparcl/__init__.py +4 -11
- sparcl/client.py +163 -32
- sparcl/exceptions.py +10 -2
- sparcl/fields.py +1 -0
- sparcl/gather_2d.py +2 -1
- sparcl/notebooks/sparcl-examples.ipynb +2054 -0
- sparcl/utils.py +13 -0
- {sparclclient-1.2.1.dev6.dist-info → sparclclient-1.2.2.dist-info}/METADATA +2 -2
- sparclclient-1.2.2.dist-info/RECORD +19 -0
- sparclclient-1.2.1.dev6.dist-info/RECORD +0 -18
- {sparclclient-1.2.1.dev6.dist-info → sparclclient-1.2.2.dist-info}/LICENSE +0 -0
- {sparclclient-1.2.1.dev6.dist-info → sparclclient-1.2.2.dist-info}/WHEEL +0 -0
|
@@ -0,0 +1,2054 @@
|
|
|
1
|
+
{
|
|
2
|
+
"cells": [
|
|
3
|
+
{
|
|
4
|
+
"cell_type": "markdown",
|
|
5
|
+
"metadata": {
|
|
6
|
+
"tags": []
|
|
7
|
+
},
|
|
8
|
+
"source": [
|
|
9
|
+
"# SPARCLCLIENT Example Usage"
|
|
10
|
+
]
|
|
11
|
+
},
|
|
12
|
+
{
|
|
13
|
+
"cell_type": "code",
|
|
14
|
+
"execution_count": 1,
|
|
15
|
+
"metadata": {
|
|
16
|
+
"tags": []
|
|
17
|
+
},
|
|
18
|
+
"outputs": [],
|
|
19
|
+
"source": [
|
|
20
|
+
"__author__ = 'Steve Pothier <steve.pothier@noirlab.edu>'\n",
|
|
21
|
+
"__version__ = '20240306' # yyyymmdd; \n",
|
|
22
|
+
"__keywords__ = ['HowTo', 'astronomy', 'tutorial', 'client', 'sparcl', 'NOIRlab']"
|
|
23
|
+
]
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
"cell_type": "markdown",
|
|
27
|
+
"metadata": {
|
|
28
|
+
"tags": []
|
|
29
|
+
},
|
|
30
|
+
"source": [
|
|
31
|
+
"## Table of contents\n",
|
|
32
|
+
"* [Goals & Summary](#goals)\n",
|
|
33
|
+
"* [Imports and setup](#imports)\n",
|
|
34
|
+
"* [Install SPARCLCLIENT](#install)\n",
|
|
35
|
+
"* [Prepare to use sparcl](#prepare)\n",
|
|
36
|
+
"* [Get general info from SPARCL](#info)\n",
|
|
37
|
+
"* [Get Metadata and Spectra](#get)"
|
|
38
|
+
]
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
"cell_type": "markdown",
|
|
42
|
+
"metadata": {
|
|
43
|
+
"tags": []
|
|
44
|
+
},
|
|
45
|
+
"source": [
|
|
46
|
+
"<a class=\"anchor\" id=\"goals\"></a>\n",
|
|
47
|
+
"## Goals & Summary \n",
|
|
48
|
+
"Demonstrate the use of the `sparclclient` package to get metadata and spectra data from the [NOIRLab SPARCL Server](https://astrosparcl.datalab.noirlab.edu/). Show how to get non-public data if you have authorized credentials.\n",
|
|
49
|
+
"- Discovery: Search for matching metadata and return metadata records.\n",
|
|
50
|
+
"- Retrieve spectra"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
"cell_type": "markdown",
|
|
55
|
+
"metadata": {
|
|
56
|
+
"tags": []
|
|
57
|
+
},
|
|
58
|
+
"source": [
|
|
59
|
+
"<a class=\"anchor\" id=\"imports\"></a>\n",
|
|
60
|
+
"## Imports and Setup"
|
|
61
|
+
]
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
"cell_type": "code",
|
|
65
|
+
"execution_count": 2,
|
|
66
|
+
"metadata": {
|
|
67
|
+
"tags": []
|
|
68
|
+
},
|
|
69
|
+
"outputs": [],
|
|
70
|
+
"source": [
|
|
71
|
+
"from pprint import pformat as pf\n",
|
|
72
|
+
"from pprint import pp\n",
|
|
73
|
+
"import os.path\n",
|
|
74
|
+
"from importlib import reload\n",
|
|
75
|
+
"from collections import defaultdict\n",
|
|
76
|
+
"from datetime import datetime\n",
|
|
77
|
+
"import warnings\n",
|
|
78
|
+
"from getpass import getpass\n",
|
|
79
|
+
"\n",
|
|
80
|
+
"import matplotlib.pyplot as plt\n",
|
|
81
|
+
"import numpy as np\n",
|
|
82
|
+
"import pandas as pd\n",
|
|
83
|
+
"from IPython.display import display, Markdown, Latex\n",
|
|
84
|
+
"\n",
|
|
85
|
+
"class StopExecution(Exception):\n",
|
|
86
|
+
" def _render_traceback_(self):\n",
|
|
87
|
+
" pass\n",
|
|
88
|
+
"\n",
|
|
89
|
+
"# %matplotlib inline\n",
|
|
90
|
+
"# requires installing ipympl\n",
|
|
91
|
+
"%matplotlib widget\n",
|
|
92
|
+
"plt.rcParams['font.size'] = 14"
|
|
93
|
+
]
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"cell_type": "raw",
|
|
97
|
+
"metadata": {},
|
|
98
|
+
"source": [
|
|
99
|
+
"### "
|
|
100
|
+
]
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"cell_type": "markdown",
|
|
104
|
+
"metadata": {
|
|
105
|
+
"tags": []
|
|
106
|
+
},
|
|
107
|
+
"source": [
|
|
108
|
+
"<a class=\"anchor\" id=\"install\"></a>\n",
|
|
109
|
+
"## Install most recent version of the SPARCLCLIENT\n",
|
|
110
|
+
"*NOTE: After installing the most recent version, please restart your kernel.*"
|
|
111
|
+
]
|
|
112
|
+
},
|
|
113
|
+
{
|
|
114
|
+
"cell_type": "code",
|
|
115
|
+
"execution_count": 3,
|
|
116
|
+
"metadata": {
|
|
117
|
+
"tags": []
|
|
118
|
+
},
|
|
119
|
+
"outputs": [
|
|
120
|
+
{
|
|
121
|
+
"name": "stdout",
|
|
122
|
+
"output_type": "stream",
|
|
123
|
+
"text": [
|
|
124
|
+
"Processing /home/pothiers/sandbox/sparclclient\n",
|
|
125
|
+
" Installing build dependencies ... \u001b[?25ldone\n",
|
|
126
|
+
"\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n",
|
|
127
|
+
"\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n",
|
|
128
|
+
"\u001b[?25hBuilding wheels for collected packages: sparclclient\n",
|
|
129
|
+
" Building wheel for sparclclient (pyproject.toml) ... \u001b[?25ldone\n",
|
|
130
|
+
"\u001b[?25h Created wheel for sparclclient: filename=sparclclient-1.2.2b8-py2.py3-none-any.whl size=3533665 sha256=fc035800e3269eccc70d3658f293c93d2fe7f07850a17cbdb47c9b2ce0de36ad\n",
|
|
131
|
+
" Stored in directory: /tmp/pip-ephem-wheel-cache-lko1mvqq/wheels/9b/de/a2/3f7a82cf4ca7c9e775a1ed1daeea35010570464a1aaa8c370c\n",
|
|
132
|
+
"Successfully built sparclclient\n",
|
|
133
|
+
"Installing collected packages: sparclclient\n",
|
|
134
|
+
" Attempting uninstall: sparclclient\n",
|
|
135
|
+
" Found existing installation: sparclclient 1.2.2b8\n",
|
|
136
|
+
" Uninstalling sparclclient-1.2.2b8:\n",
|
|
137
|
+
" Successfully uninstalled sparclclient-1.2.2b8\n",
|
|
138
|
+
"Successfully installed sparclclient-1.2.2b8\n"
|
|
139
|
+
]
|
|
140
|
+
}
|
|
141
|
+
],
|
|
142
|
+
"source": [
|
|
143
|
+
"# !pip install --upgrade sparclclient # Latest released version\n",
|
|
144
|
+
"# !pip install --pre --upgrade sparclclient # Lastest pre-released version\n",
|
|
145
|
+
"\n",
|
|
146
|
+
"# Uncomment next line to load SPARCLCLIENT from local current version of software.\n",
|
|
147
|
+
"!pip install --pre --upgrade ../.."
|
|
148
|
+
]
|
|
149
|
+
},
|
|
150
|
+
{
|
|
151
|
+
"cell_type": "code",
|
|
152
|
+
"execution_count": 4,
|
|
153
|
+
"metadata": {
|
|
154
|
+
"tags": []
|
|
155
|
+
},
|
|
156
|
+
"outputs": [
|
|
157
|
+
{
|
|
158
|
+
"name": "stdout",
|
|
159
|
+
"output_type": "stream",
|
|
160
|
+
"text": [
|
|
161
|
+
"Run started: 2024-05-02 10:22:12.795845\n"
|
|
162
|
+
]
|
|
163
|
+
}
|
|
164
|
+
],
|
|
165
|
+
"source": [
|
|
166
|
+
"import sparcl.client\n",
|
|
167
|
+
"print(f'Run started: {str(datetime.now())}')"
|
|
168
|
+
]
|
|
169
|
+
},
|
|
170
|
+
{
|
|
171
|
+
"cell_type": "markdown",
|
|
172
|
+
"metadata": {
|
|
173
|
+
"editable": true,
|
|
174
|
+
"slideshow": {
|
|
175
|
+
"slide_type": ""
|
|
176
|
+
},
|
|
177
|
+
"tags": []
|
|
178
|
+
},
|
|
179
|
+
"source": [
|
|
180
|
+
"<a class=\"anchor\" id=\"prepare\"></a>\n",
|
|
181
|
+
"# Configure SPARCLCLIENT"
|
|
182
|
+
]
|
|
183
|
+
},
|
|
184
|
+
{
|
|
185
|
+
"cell_type": "code",
|
|
186
|
+
"execution_count": 5,
|
|
187
|
+
"metadata": {
|
|
188
|
+
"scrolled": true,
|
|
189
|
+
"tags": []
|
|
190
|
+
},
|
|
191
|
+
"outputs": [
|
|
192
|
+
{
|
|
193
|
+
"name": "stdin",
|
|
194
|
+
"output_type": "stream",
|
|
195
|
+
"text": [
|
|
196
|
+
" ········\n"
|
|
197
|
+
]
|
|
198
|
+
}
|
|
199
|
+
],
|
|
200
|
+
"source": [
|
|
201
|
+
"# How much output to we want to show?\n",
|
|
202
|
+
"show_help = False # HELP for client functions\n",
|
|
203
|
+
"show_curl = True # Show the underlying SPARCL Server API call\n",
|
|
204
|
+
"verbose = True\n",
|
|
205
|
+
"\n",
|
|
206
|
+
"server = 'https://astrosparcl.datalab.noirlab.edu' # Public Server\n",
|
|
207
|
+
"server = 'https://sparc1.datalab.noirlab.edu' # internal TEST Server\n",
|
|
208
|
+
"server = 'http://localhost:8050' # internal DEV Server\n",
|
|
209
|
+
"\n",
|
|
210
|
+
"priv_dr = 'SDSS-DR17-test'\n",
|
|
211
|
+
"pub_dr = 'BOSS-DR16'\n",
|
|
212
|
+
"\n",
|
|
213
|
+
"# Authenticated Users that are never authorized for anything important.\n",
|
|
214
|
+
"# These are authenticated on both Public and Test SSO servers.\n",
|
|
215
|
+
"auth_user = 'test_user_1@noirlab.edu'\n",
|
|
216
|
+
"unauth_user = 'test_user_2@noirlab.edu'\n",
|
|
217
|
+
"non_user = 'test_user_3@noirlab.edu'\n",
|
|
218
|
+
"usrpw = getpass()"
|
|
219
|
+
]
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
"cell_type": "code",
|
|
223
|
+
"execution_count": 6,
|
|
224
|
+
"metadata": {
|
|
225
|
+
"scrolled": true,
|
|
226
|
+
"tags": []
|
|
227
|
+
},
|
|
228
|
+
"outputs": [
|
|
229
|
+
{
|
|
230
|
+
"name": "stdout",
|
|
231
|
+
"output_type": "stream",
|
|
232
|
+
"text": [
|
|
233
|
+
"apiurl=http://localhost:8050/sparc\n",
|
|
234
|
+
"client=(sparclclient:1.2.2b8, api:11.0, http://localhost:8050/sparc, client_hash=f7bd410278bee26a425387c598dd47e80a8fcdcb, verbose=True, connect_timeout=1.1, read_timeout=5400.0)\n"
|
|
235
|
+
]
|
|
236
|
+
}
|
|
237
|
+
],
|
|
238
|
+
"source": [
|
|
239
|
+
"if show_help:\n",
|
|
240
|
+
" help(sparcl.client.SparclClient)\n",
|
|
241
|
+
"client = sparcl.client.SparclClient(url=server, show_curl=show_curl, verbose=verbose)\n",
|
|
242
|
+
"print(f'{client=}')"
|
|
243
|
+
]
|
|
244
|
+
},
|
|
245
|
+
{
|
|
246
|
+
"cell_type": "markdown",
|
|
247
|
+
"metadata": {},
|
|
248
|
+
"source": [
|
|
249
|
+
"<a class=\"anchor\" id=\"info\"></a>\n",
|
|
250
|
+
"# General Info from SPARCL"
|
|
251
|
+
]
|
|
252
|
+
},
|
|
253
|
+
{
|
|
254
|
+
"cell_type": "markdown",
|
|
255
|
+
"metadata": {},
|
|
256
|
+
"source": [
|
|
257
|
+
"<a class=\"anchor\" id=\"datasets\"></a>\n",
|
|
258
|
+
"## Data sets available\n",
|
|
259
|
+
"List all currently available data sets from the server/url associated with client"
|
|
260
|
+
]
|
|
261
|
+
},
|
|
262
|
+
{
|
|
263
|
+
"cell_type": "code",
|
|
264
|
+
"execution_count": 7,
|
|
265
|
+
"metadata": {
|
|
266
|
+
"tags": []
|
|
267
|
+
},
|
|
268
|
+
"outputs": [
|
|
269
|
+
{
|
|
270
|
+
"data": {
|
|
271
|
+
"text/plain": [
|
|
272
|
+
"{'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16', 'SDSS-DR17-test'}"
|
|
273
|
+
]
|
|
274
|
+
},
|
|
275
|
+
"execution_count": 7,
|
|
276
|
+
"metadata": {},
|
|
277
|
+
"output_type": "execute_result"
|
|
278
|
+
}
|
|
279
|
+
],
|
|
280
|
+
"source": [
|
|
281
|
+
"client.all_datasets"
|
|
282
|
+
]
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
"cell_type": "markdown",
|
|
286
|
+
"metadata": {},
|
|
287
|
+
"source": [
|
|
288
|
+
"<a class=\"anchor\" id=\"defaultfieldnames\"></a>\n",
|
|
289
|
+
"## Default field names\n",
|
|
290
|
+
"Gets fields tagged as 'default' that are common to all data sets in the `dataset_list` passed to the function. If `dataset_list` is None (the default), the function returns the intersection of 'default' fields across all datasets currently available in the SPARC database. The following example of this function produces the same output as it would with no `dataset_list` argument because we currently only have SDSS-DR16 and BOSS-DR16 records in the SPARC database."
|
|
291
|
+
]
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"cell_type": "code",
|
|
295
|
+
"execution_count": 8,
|
|
296
|
+
"metadata": {
|
|
297
|
+
"scrolled": true,
|
|
298
|
+
"tags": []
|
|
299
|
+
},
|
|
300
|
+
"outputs": [],
|
|
301
|
+
"source": [
|
|
302
|
+
"if show_help:\n",
|
|
303
|
+
" client.get_default_fields?"
|
|
304
|
+
]
|
|
305
|
+
},
|
|
306
|
+
{
|
|
307
|
+
"cell_type": "code",
|
|
308
|
+
"execution_count": 9,
|
|
309
|
+
"metadata": {
|
|
310
|
+
"tags": []
|
|
311
|
+
},
|
|
312
|
+
"outputs": [
|
|
313
|
+
{
|
|
314
|
+
"data": {
|
|
315
|
+
"text/plain": [
|
|
316
|
+
"['dec', 'flux', 'ra', 'sparcl_id', 'specid', 'wavelength']"
|
|
317
|
+
]
|
|
318
|
+
},
|
|
319
|
+
"execution_count": 9,
|
|
320
|
+
"metadata": {},
|
|
321
|
+
"output_type": "execute_result"
|
|
322
|
+
}
|
|
323
|
+
],
|
|
324
|
+
"source": [
|
|
325
|
+
"client.get_default_fields(dataset_list=['SDSS-DR16', 'BOSS-DR16'])"
|
|
326
|
+
]
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"cell_type": "markdown",
|
|
330
|
+
"metadata": {},
|
|
331
|
+
"source": [
|
|
332
|
+
"<a class=\"anchor\" id=\"allfieldnames\"></a>\n",
|
|
333
|
+
"## All field names\n",
|
|
334
|
+
"Gets fields tagged as 'all' that are common to all data sets in the `dataset_list` passed to the function. If `dataset_list` is None (the default), the function returns the intersection of 'all' fields across all datasets currently available in the SPARC database. The following example of this function produces the same output as it would with no `dataset_list` argument because we currently only have SDSS-DR16 and BOSS-DR16 records in the SPARC database."
|
|
335
|
+
]
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
"cell_type": "code",
|
|
339
|
+
"execution_count": 10,
|
|
340
|
+
"metadata": {
|
|
341
|
+
"tags": []
|
|
342
|
+
},
|
|
343
|
+
"outputs": [
|
|
344
|
+
{
|
|
345
|
+
"data": {
|
|
346
|
+
"text/plain": [
|
|
347
|
+
"\u001b[0;31mSignature:\u001b[0m \u001b[0mclient\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mget_all_fields\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m*\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mdataset_list\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0;32mNone\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
|
|
348
|
+
"\u001b[0;31mDocstring:\u001b[0m\n",
|
|
349
|
+
"Get fields tagged as 'all' that are in DATASET_LIST.\n",
|
|
350
|
+
"These are the fields used for the ALL value of the include parameter\n",
|
|
351
|
+
"of client.retrieve().\n",
|
|
352
|
+
"\n",
|
|
353
|
+
"Args:\n",
|
|
354
|
+
" dataset_list (:obj:`list`, optional): List of data sets from\n",
|
|
355
|
+
" which to get all fields. Defaults to None, which\n",
|
|
356
|
+
" will return the intersection of all fields in all\n",
|
|
357
|
+
" data sets hosted on the SPARCL database.\n",
|
|
358
|
+
"\n",
|
|
359
|
+
"Returns:\n",
|
|
360
|
+
" List of fields tagged as 'all' from DATASET_LIST.\n",
|
|
361
|
+
"\n",
|
|
362
|
+
"Example:\n",
|
|
363
|
+
" >>> client = SparclClient()\n",
|
|
364
|
+
" >>> client.get_all_fields()\n",
|
|
365
|
+
" ['data_release', 'datasetgroup', 'dateobs', 'dateobs_center', 'dec', 'exptime', 'flux', 'instrument', 'ivar', 'mask', 'model', 'ra', 'redshift', 'redshift_err', 'redshift_warning', 'site', 'sparcl_id', 'specid', 'specprimary', 'spectype', 'survey', 'targetid', 'telescope', 'wave_sigma', 'wavelength', 'wavemax', 'wavemin']\n",
|
|
366
|
+
"\u001b[0;31mFile:\u001b[0m ~/sandbox/sparclclient/venv/lib/python3.10/site-packages/sparcl/client.py\n",
|
|
367
|
+
"\u001b[0;31mType:\u001b[0m method"
|
|
368
|
+
]
|
|
369
|
+
},
|
|
370
|
+
"metadata": {},
|
|
371
|
+
"output_type": "display_data"
|
|
372
|
+
}
|
|
373
|
+
],
|
|
374
|
+
"source": [
|
|
375
|
+
"client.get_all_fields?"
|
|
376
|
+
]
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"cell_type": "code",
|
|
380
|
+
"execution_count": 11,
|
|
381
|
+
"metadata": {
|
|
382
|
+
"tags": []
|
|
383
|
+
},
|
|
384
|
+
"outputs": [
|
|
385
|
+
{
|
|
386
|
+
"name": "stdout",
|
|
387
|
+
"output_type": "stream",
|
|
388
|
+
"text": [
|
|
389
|
+
"['ancillary_target1', 'ancillary_target2', 'anyandmask', 'anyormask', 'bluefiber', 'boss_specobj_id', 'boss_target1', 'boss_target2', 'calibflux', 'calibflux_ivar', 'chi68p', 'chunk', 'class_noqso', 'class_person', 'comments_person', 'cx', 'cy', 'cz', 'data_release', 'datasetgroup', 'dateobs', 'dateobs_center', 'dec', 'deredsn2', 'designid', 'dof', 'eboss_target0', 'eboss_target1', 'eboss_target2', 'eboss_target_id', 'elodie_bv', 'elodie_dof', 'elodie_feh', 'elodie_filename', 'elodie_logg', 'elodie_object', 'elodie_rchi2', 'elodie_sptype', 'elodie_teff', 'elodie_z', 'elodie_z_err', 'elodie_z_modelerr', 'exptime', 'fiberid', 'firstrelease', 'flux', 'fluxobjid', 'fracnsighi', 'fracnsiglo', 'fracnsigma', 'instrument', 'ivar', 'lambda_eff', 'legacy_target1', 'legacy_target2', 'marvels_target1', 'marvels_target2', 'mask', 'mjd', 'model', 'npoly', 'nspecobs', 'nturnoff', 'objid', 'plate', 'plateid', 'platequality', 'platerun', 'platesn2', 'primtarget', 'programname', 'ra', 'rchi2', 'rchi2diff', 'rchi2diff_noqso', 'redshift', 'redshift_err', 'redshift_warning', 'run1d', 'run2d', 'sectarget', 'segue1_target1', 'segue1_target2', 'segue2_target1', 'segue2_target2', 'site', 'sky', 'sn_median', 'sn_median_all', 'snturnoff', 'sourcetype', 'sparcl_id', 'spec1_g', 'spec1_i', 'spec1_r', 'spec2_g', 'spec2_i', 'spec2_r', 'specboss', 'special_target1', 'special_target2', 'specid', 'speclegacy', 'specprimary', 'specsdss', 'specsegue', 'specsegue1', 'specsegue2', 'spectroflux', 'spectroflux_ivar', 'spectrographid', 'spectroskyflux', 'spectrosynflux', 'spectrosynflux_ivar', 'spectype', 'subclass', 'subclass_noqso', 'survey', 'targetid', 'targetobjid', 'targettype', 'tcolumn', 'telescope', 'tfile', 'theta', 'thing_id', 'thing_id_targeting', 'tile', 'vdisp', 'vdisp_err', 'vdispchi2', 'vdispdof', 'vdispnpix', 'vdispz', 'vdispz_err', 'wave_sigma', 'wavelength', 'wavemax', 'wavemin', 'wcoverage', 'xfocal', 'yfocal', 'z_conf_person', 'z_err_noqso', 'z_noqso', 'z_person', 'zoffset', 'zwarning_noqso']\n"
|
|
390
|
+
]
|
|
391
|
+
}
|
|
392
|
+
],
|
|
393
|
+
"source": [
|
|
394
|
+
"print(sorted(client.get_all_fields(dataset_list=['SDSS-DR16', 'BOSS-DR16'])))"
|
|
395
|
+
]
|
|
396
|
+
},
|
|
397
|
+
{
|
|
398
|
+
"cell_type": "markdown",
|
|
399
|
+
"metadata": {},
|
|
400
|
+
"source": [
|
|
401
|
+
"## Version of Server API used by this client\n",
|
|
402
|
+
"The SPARCL Client you use must match the version of the SPARCL Server you use. The server is specified with the client.SparclClient `url` parameter. If Server and Client are incompatible, when you excecute SparclClient() you will instructed to upgrade your client."
|
|
403
|
+
]
|
|
404
|
+
},
|
|
405
|
+
{
|
|
406
|
+
"cell_type": "code",
|
|
407
|
+
"execution_count": 12,
|
|
408
|
+
"metadata": {
|
|
409
|
+
"tags": []
|
|
410
|
+
},
|
|
411
|
+
"outputs": [
|
|
412
|
+
{
|
|
413
|
+
"data": {
|
|
414
|
+
"text/plain": [
|
|
415
|
+
"11.0"
|
|
416
|
+
]
|
|
417
|
+
},
|
|
418
|
+
"execution_count": 12,
|
|
419
|
+
"metadata": {},
|
|
420
|
+
"output_type": "execute_result"
|
|
421
|
+
}
|
|
422
|
+
],
|
|
423
|
+
"source": [
|
|
424
|
+
"client.version"
|
|
425
|
+
]
|
|
426
|
+
},
|
|
427
|
+
{
|
|
428
|
+
"cell_type": "markdown",
|
|
429
|
+
"metadata": {},
|
|
430
|
+
"source": [
|
|
431
|
+
"<a class=\"anchor\" id=\"get\"></a>\n",
|
|
432
|
+
"# Get Metadata and Spectra"
|
|
433
|
+
]
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
"cell_type": "markdown",
|
|
437
|
+
"metadata": {},
|
|
438
|
+
"source": [
|
|
439
|
+
"<a class=\"anchor\" id=\"find\"></a>\n",
|
|
440
|
+
"## Get Metadata: `client.find`"
|
|
441
|
+
]
|
|
442
|
+
},
|
|
443
|
+
{
|
|
444
|
+
"cell_type": "markdown",
|
|
445
|
+
"metadata": {},
|
|
446
|
+
"source": [
|
|
447
|
+
"The first way you can discover your data is by using SPARCL's `client.find()` method, which allows you to find records in the SPARCL database based on certain parameters passed to the function. Only Core fields may be in the `outfields` and `constraints` parameters. The descriptions for all fields, including Core fields, is located [here](https://astrosparcl.datalab.noirlab.edu/sparc/sfc/). The SPARCL Core fields constraint types are:\n",
|
|
448
|
+
"\n",
|
|
449
|
+
"\n",
|
|
450
|
+
"| Field name | Constraint type | Example |\n",
|
|
451
|
+
"|:----------------|:---------------|:-------|\n",
|
|
452
|
+
"| id | List of values (but not<br>intended for data discovery) | ['00001658-460c-4da1-987d-e493d8c9b89b',<br>'000017b6-56a2-4f87-8828-3a3409ba1083']\n",
|
|
453
|
+
"| specid | List of values | [6988698046080241664, 6971782884823945216]\n",
|
|
454
|
+
"| targetid | List of values | [1237679502171374316, 1237678619584692841]\n",
|
|
455
|
+
"| data_release | List of allowed values<br>from [SPARCL Categoricals](https://astrosparcl.datalab.noirlab.edu/sparc/cats/) | ['BOSS-DR16', 'SDSS-DR16']\n",
|
|
456
|
+
"| datasetgroup | List of allowed values<br>from [SPARCL Categoricals](https://astrosparcl.datalab.noirlab.edu/sparc/cats/) | ['SDSS_BOSS']\n",
|
|
457
|
+
"| ra | Range of values (may not<br>\"wrap\" around RA=0) | [44.53, 47.96]\n",
|
|
458
|
+
"| dec | Range of values | [2.03, 7.76]\n",
|
|
459
|
+
"| redshift | Range of values | [0.5, 0.9]\n",
|
|
460
|
+
"| redshift_err | Range of values | [0.000225, 0.000516]\n",
|
|
461
|
+
"| redshift_warning | List of values | [0, 3, 5]\n",
|
|
462
|
+
"| spectype | List of allowed values<br>from [SPARCL Categoricals](https://astrosparcl.datalab.noirlab.edu/sparc/cats/) | ['GALAXY', 'STAR']\n",
|
|
463
|
+
"| instrument | List of allowed values<br>from [SPARCL Categoricals](https://astrosparcl.datalab.noirlab.edu/sparc/cats/) | ['SDSS', 'BOSS']\n",
|
|
464
|
+
"| telescope | List of allowed values<br>from [SPARCL Categoricals](https://astrosparcl.datalab.noirlab.edu/sparc/cats/) | ['sloan25m']\n",
|
|
465
|
+
"| site | List of allowed values<br>from [SPARCL Categoricals](https://astrosparcl.datalab.noirlab.edu/sparc/cats/) | ['apo']\n",
|
|
466
|
+
"| specprimary | List of values (but typically<br>would only include 1 if<br>being used for data<br>discovery constraints) | [1]\n",
|
|
467
|
+
"| wavemin | Range of values | [3607, 3608]\n",
|
|
468
|
+
"| wavemax | Range of values | [10363, 10364]\n",
|
|
469
|
+
"| dateobs_center | Range of values | ['2013-03-14T10:16:17Z',<br>'2014-05-24T12:10:00Z']\n",
|
|
470
|
+
"| exptime | Range of values | [3603.46, 3810.12]\n",
|
|
471
|
+
"| updated | Range of values | ['2022-08-20T21:37:50.636363Z',<br>'2022-09-20T20:00:00.000000Z']\n"
|
|
472
|
+
]
|
|
473
|
+
},
|
|
474
|
+
{
|
|
475
|
+
"cell_type": "code",
|
|
476
|
+
"execution_count": 13,
|
|
477
|
+
"metadata": {
|
|
478
|
+
"editable": true,
|
|
479
|
+
"scrolled": true,
|
|
480
|
+
"slideshow": {
|
|
481
|
+
"slide_type": ""
|
|
482
|
+
},
|
|
483
|
+
"tags": []
|
|
484
|
+
},
|
|
485
|
+
"outputs": [],
|
|
486
|
+
"source": [
|
|
487
|
+
"if show_help:\n",
|
|
488
|
+
" client.find?"
|
|
489
|
+
]
|
|
490
|
+
},
|
|
491
|
+
{
|
|
492
|
+
"cell_type": "markdown",
|
|
493
|
+
"metadata": {},
|
|
494
|
+
"source": [
|
|
495
|
+
"#### Define fields and constraints for metadata FIND\n",
|
|
496
|
+
"Define the fields we want returned (`outfields`) and the constraints (`constraints`)"
|
|
497
|
+
]
|
|
498
|
+
},
|
|
499
|
+
{
|
|
500
|
+
"cell_type": "code",
|
|
501
|
+
"execution_count": 14,
|
|
502
|
+
"metadata": {
|
|
503
|
+
"tags": []
|
|
504
|
+
},
|
|
505
|
+
"outputs": [],
|
|
506
|
+
"source": [
|
|
507
|
+
"out = ['sparcl_id','specid', 'ra', 'dec', 'redshift', 'spectype', 'data_release', 'redshift_err']\n",
|
|
508
|
+
"cons = {'spectype': ['GALAXY'],\n",
|
|
509
|
+
" 'redshift': [0.5, 0.9],\n",
|
|
510
|
+
" 'data_release': ['BOSS-DR16', 'SDSS-DR16']}"
|
|
511
|
+
]
|
|
512
|
+
},
|
|
513
|
+
{
|
|
514
|
+
"cell_type": "markdown",
|
|
515
|
+
"metadata": {},
|
|
516
|
+
"source": [
|
|
517
|
+
"#### Execute FIND\n",
|
|
518
|
+
"Execute the `client.find()` method with our parameters.\n",
|
|
519
|
+
"The `limit` argument here is being used for demonstration purposes only, and simply returns only the first 20 results here."
|
|
520
|
+
]
|
|
521
|
+
},
|
|
522
|
+
{
|
|
523
|
+
"cell_type": "code",
|
|
524
|
+
"execution_count": 15,
|
|
525
|
+
"metadata": {
|
|
526
|
+
"scrolled": true,
|
|
527
|
+
"tags": []
|
|
528
|
+
},
|
|
529
|
+
"outputs": [
|
|
530
|
+
{
|
|
531
|
+
"name": "stdout",
|
|
532
|
+
"output_type": "stream",
|
|
533
|
+
"text": [
|
|
534
|
+
"url=http://localhost:8050/sparc/find/?limit=20 sspec={'outfields': ['sparcl_id', 'specid', 'ra', 'dec', 'redshift', 'spectype', 'data_release', 'redshift_err'], 'search': [['spectype', 'GALAXY'], ['redshift', 0.5, 0.9], ['data_release', 'BOSS-DR16', 'SDSS-DR16']]}\n",
|
|
535
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"specid\", \"ra\", \"dec\", \"redshift\", \"spectype\", \"data_release\", \"redshift_err\"], \"search\": [[\"spectype\", \"GALAXY\"], [\"redshift\", 0.5, 0.9], [\"data_release\", \"BOSS-DR16\", \"SDSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=20' | python3 -m json.tool\n",
|
|
536
|
+
"Record key counts: {'spectype': 20, 'redshift': 20, 'sparcl_id': 20, 'ra': 20, 'dec': 20, 'specid': 20, '_dr': 20, 'data_release': 20, 'redshift_err': 20}\n"
|
|
537
|
+
]
|
|
538
|
+
}
|
|
539
|
+
],
|
|
540
|
+
"source": [
|
|
541
|
+
"found = client.find(outfields=out, constraints=cons, limit=20)"
|
|
542
|
+
]
|
|
543
|
+
},
|
|
544
|
+
{
|
|
545
|
+
"cell_type": "code",
|
|
546
|
+
"execution_count": null,
|
|
547
|
+
"metadata": {
|
|
548
|
+
"scrolled": true
|
|
549
|
+
},
|
|
550
|
+
"outputs": [],
|
|
551
|
+
"source": []
|
|
552
|
+
},
|
|
553
|
+
{
|
|
554
|
+
"cell_type": "code",
|
|
555
|
+
"execution_count": 16,
|
|
556
|
+
"metadata": {
|
|
557
|
+
"tags": []
|
|
558
|
+
},
|
|
559
|
+
"outputs": [
|
|
560
|
+
{
|
|
561
|
+
"data": {
|
|
562
|
+
"text/html": [
|
|
563
|
+
"<div>\n",
|
|
564
|
+
"<style scoped>\n",
|
|
565
|
+
" .dataframe tbody tr th:only-of-type {\n",
|
|
566
|
+
" vertical-align: middle;\n",
|
|
567
|
+
" }\n",
|
|
568
|
+
"\n",
|
|
569
|
+
" .dataframe tbody tr th {\n",
|
|
570
|
+
" vertical-align: top;\n",
|
|
571
|
+
" }\n",
|
|
572
|
+
"\n",
|
|
573
|
+
" .dataframe thead th {\n",
|
|
574
|
+
" text-align: right;\n",
|
|
575
|
+
" }\n",
|
|
576
|
+
"</style>\n",
|
|
577
|
+
"<table border=\"1\" class=\"dataframe\">\n",
|
|
578
|
+
" <thead>\n",
|
|
579
|
+
" <tr style=\"text-align: right;\">\n",
|
|
580
|
+
" <th></th>\n",
|
|
581
|
+
" <th>redshift</th>\n",
|
|
582
|
+
" <th>ra</th>\n",
|
|
583
|
+
" <th>dec</th>\n",
|
|
584
|
+
" <th>data_release</th>\n",
|
|
585
|
+
" <th>specid</th>\n",
|
|
586
|
+
" <th>redshift_err</th>\n",
|
|
587
|
+
" <th>spectype</th>\n",
|
|
588
|
+
" <th>sparcl_id</th>\n",
|
|
589
|
+
" <th>_dr</th>\n",
|
|
590
|
+
" </tr>\n",
|
|
591
|
+
" </thead>\n",
|
|
592
|
+
" <tbody>\n",
|
|
593
|
+
" <tr>\n",
|
|
594
|
+
" <th>0</th>\n",
|
|
595
|
+
" <td>0.545929</td>\n",
|
|
596
|
+
" <td>246.74298</td>\n",
|
|
597
|
+
" <td>35.985258</td>\n",
|
|
598
|
+
" <td>SDSS-DR16</td>\n",
|
|
599
|
+
" <td>1506516519029336064</td>\n",
|
|
600
|
+
" <td>0.000422</td>\n",
|
|
601
|
+
" <td>GALAXY</td>\n",
|
|
602
|
+
" <td>2c6c82dc-fe87-11ee-838b-08002725f1ef</td>\n",
|
|
603
|
+
" <td>SDSS-DR16</td>\n",
|
|
604
|
+
" </tr>\n",
|
|
605
|
+
" <tr>\n",
|
|
606
|
+
" <th>1</th>\n",
|
|
607
|
+
" <td>0.667431</td>\n",
|
|
608
|
+
" <td>245.40676</td>\n",
|
|
609
|
+
" <td>36.438884</td>\n",
|
|
610
|
+
" <td>SDSS-DR16</td>\n",
|
|
611
|
+
" <td>1506548404866541568</td>\n",
|
|
612
|
+
" <td>0.000026</td>\n",
|
|
613
|
+
" <td>GALAXY</td>\n",
|
|
614
|
+
" <td>3063feb6-fe87-11ee-8aa0-08002725f1ef</td>\n",
|
|
615
|
+
" <td>SDSS-DR16</td>\n",
|
|
616
|
+
" </tr>\n",
|
|
617
|
+
" <tr>\n",
|
|
618
|
+
" <th>2</th>\n",
|
|
619
|
+
" <td>0.502511</td>\n",
|
|
620
|
+
" <td>246.45702</td>\n",
|
|
621
|
+
" <td>36.657405</td>\n",
|
|
622
|
+
" <td>SDSS-DR16</td>\n",
|
|
623
|
+
" <td>1506572869000259584</td>\n",
|
|
624
|
+
" <td>0.000172</td>\n",
|
|
625
|
+
" <td>GALAXY</td>\n",
|
|
626
|
+
" <td>336d71cf-fe87-11ee-9390-08002725f1ef</td>\n",
|
|
627
|
+
" <td>SDSS-DR16</td>\n",
|
|
628
|
+
" </tr>\n",
|
|
629
|
+
" <tr>\n",
|
|
630
|
+
" <th>3</th>\n",
|
|
631
|
+
" <td>0.724874</td>\n",
|
|
632
|
+
" <td>246.89323</td>\n",
|
|
633
|
+
" <td>37.209662</td>\n",
|
|
634
|
+
" <td>SDSS-DR16</td>\n",
|
|
635
|
+
" <td>1506578916314212352</td>\n",
|
|
636
|
+
" <td>11.831918</td>\n",
|
|
637
|
+
" <td>GALAXY</td>\n",
|
|
638
|
+
" <td>342e5eaa-fe87-11ee-9047-08002725f1ef</td>\n",
|
|
639
|
+
" <td>SDSS-DR16</td>\n",
|
|
640
|
+
" </tr>\n",
|
|
641
|
+
" <tr>\n",
|
|
642
|
+
" <th>4</th>\n",
|
|
643
|
+
" <td>0.741196</td>\n",
|
|
644
|
+
" <td>247.40873</td>\n",
|
|
645
|
+
" <td>36.381456</td>\n",
|
|
646
|
+
" <td>SDSS-DR16</td>\n",
|
|
647
|
+
" <td>1506596508500256768</td>\n",
|
|
648
|
+
" <td>0.614932</td>\n",
|
|
649
|
+
" <td>GALAXY</td>\n",
|
|
650
|
+
" <td>36565b1b-fe87-11ee-b857-08002725f1ef</td>\n",
|
|
651
|
+
" <td>SDSS-DR16</td>\n",
|
|
652
|
+
" </tr>\n",
|
|
653
|
+
" <tr>\n",
|
|
654
|
+
" <th>5</th>\n",
|
|
655
|
+
" <td>0.675723</td>\n",
|
|
656
|
+
" <td>134.10755</td>\n",
|
|
657
|
+
" <td>28.038851</td>\n",
|
|
658
|
+
" <td>BOSS-DR16</td>\n",
|
|
659
|
+
" <td>-6444647351317147648</td>\n",
|
|
660
|
+
" <td>0.000241</td>\n",
|
|
661
|
+
" <td>GALAXY</td>\n",
|
|
662
|
+
" <td>5182df54-fe87-11ee-a660-08002725f1ef</td>\n",
|
|
663
|
+
" <td>BOSS-DR16</td>\n",
|
|
664
|
+
" </tr>\n",
|
|
665
|
+
" <tr>\n",
|
|
666
|
+
" <th>6</th>\n",
|
|
667
|
+
" <td>0.782685</td>\n",
|
|
668
|
+
" <td>134.23727</td>\n",
|
|
669
|
+
" <td>28.084685</td>\n",
|
|
670
|
+
" <td>BOSS-DR16</td>\n",
|
|
671
|
+
" <td>-6444646251805519872</td>\n",
|
|
672
|
+
" <td>0.000242</td>\n",
|
|
673
|
+
" <td>GALAXY</td>\n",
|
|
674
|
+
" <td>51ad9b94-fe87-11ee-af3e-08002725f1ef</td>\n",
|
|
675
|
+
" <td>BOSS-DR16</td>\n",
|
|
676
|
+
" </tr>\n",
|
|
677
|
+
" <tr>\n",
|
|
678
|
+
" <th>7</th>\n",
|
|
679
|
+
" <td>0.797439</td>\n",
|
|
680
|
+
" <td>133.98095</td>\n",
|
|
681
|
+
" <td>28.226386</td>\n",
|
|
682
|
+
" <td>BOSS-DR16</td>\n",
|
|
683
|
+
" <td>-6444643503026450432</td>\n",
|
|
684
|
+
" <td>0.000424</td>\n",
|
|
685
|
+
" <td>GALAXY</td>\n",
|
|
686
|
+
" <td>521321c8-fe87-11ee-946d-08002725f1ef</td>\n",
|
|
687
|
+
" <td>BOSS-DR16</td>\n",
|
|
688
|
+
" </tr>\n",
|
|
689
|
+
" <tr>\n",
|
|
690
|
+
" <th>8</th>\n",
|
|
691
|
+
" <td>0.647712</td>\n",
|
|
692
|
+
" <td>134.54531</td>\n",
|
|
693
|
+
" <td>28.429551</td>\n",
|
|
694
|
+
" <td>BOSS-DR16</td>\n",
|
|
695
|
+
" <td>-6444641304003194880</td>\n",
|
|
696
|
+
" <td>0.000238</td>\n",
|
|
697
|
+
" <td>GALAXY</td>\n",
|
|
698
|
+
" <td>52643970-fe87-11ee-abb3-08002725f1ef</td>\n",
|
|
699
|
+
" <td>BOSS-DR16</td>\n",
|
|
700
|
+
" </tr>\n",
|
|
701
|
+
" <tr>\n",
|
|
702
|
+
" <th>9</th>\n",
|
|
703
|
+
" <td>0.886086</td>\n",
|
|
704
|
+
" <td>134.46525</td>\n",
|
|
705
|
+
" <td>28.452505</td>\n",
|
|
706
|
+
" <td>BOSS-DR16</td>\n",
|
|
707
|
+
" <td>-6444640754247380992</td>\n",
|
|
708
|
+
" <td>0.000274</td>\n",
|
|
709
|
+
" <td>GALAXY</td>\n",
|
|
710
|
+
" <td>5278859e-fe87-11ee-8427-08002725f1ef</td>\n",
|
|
711
|
+
" <td>BOSS-DR16</td>\n",
|
|
712
|
+
" </tr>\n",
|
|
713
|
+
" <tr>\n",
|
|
714
|
+
" <th>10</th>\n",
|
|
715
|
+
" <td>0.898559</td>\n",
|
|
716
|
+
" <td>134.43695</td>\n",
|
|
717
|
+
" <td>28.450988</td>\n",
|
|
718
|
+
" <td>BOSS-DR16</td>\n",
|
|
719
|
+
" <td>-6444640204491567104</td>\n",
|
|
720
|
+
" <td>0.000311</td>\n",
|
|
721
|
+
" <td>GALAXY</td>\n",
|
|
722
|
+
" <td>52913c34-fe87-11ee-844b-08002725f1ef</td>\n",
|
|
723
|
+
" <td>BOSS-DR16</td>\n",
|
|
724
|
+
" </tr>\n",
|
|
725
|
+
" <tr>\n",
|
|
726
|
+
" <th>11</th>\n",
|
|
727
|
+
" <td>0.566015</td>\n",
|
|
728
|
+
" <td>133.95386</td>\n",
|
|
729
|
+
" <td>27.305313</td>\n",
|
|
730
|
+
" <td>BOSS-DR16</td>\n",
|
|
731
|
+
" <td>-6444639654735753216</td>\n",
|
|
732
|
+
" <td>0.000315</td>\n",
|
|
733
|
+
" <td>GALAXY</td>\n",
|
|
734
|
+
" <td>52a796f0-fe87-11ee-b337-08002725f1ef</td>\n",
|
|
735
|
+
" <td>BOSS-DR16</td>\n",
|
|
736
|
+
" </tr>\n",
|
|
737
|
+
" <tr>\n",
|
|
738
|
+
" <th>12</th>\n",
|
|
739
|
+
" <td>0.599517</td>\n",
|
|
740
|
+
" <td>134.05133</td>\n",
|
|
741
|
+
" <td>27.381025</td>\n",
|
|
742
|
+
" <td>BOSS-DR16</td>\n",
|
|
743
|
+
" <td>-6444639104979939328</td>\n",
|
|
744
|
+
" <td>0.000412</td>\n",
|
|
745
|
+
" <td>GALAXY</td>\n",
|
|
746
|
+
" <td>52bbb47f-fe87-11ee-b8d7-08002725f1ef</td>\n",
|
|
747
|
+
" <td>BOSS-DR16</td>\n",
|
|
748
|
+
" </tr>\n",
|
|
749
|
+
" <tr>\n",
|
|
750
|
+
" <th>13</th>\n",
|
|
751
|
+
" <td>0.812179</td>\n",
|
|
752
|
+
" <td>133.95189</td>\n",
|
|
753
|
+
" <td>27.333753</td>\n",
|
|
754
|
+
" <td>BOSS-DR16</td>\n",
|
|
755
|
+
" <td>-6444638555224125440</td>\n",
|
|
756
|
+
" <td>0.000338</td>\n",
|
|
757
|
+
" <td>GALAXY</td>\n",
|
|
758
|
+
" <td>52cfb971-fe87-11ee-be51-08002725f1ef</td>\n",
|
|
759
|
+
" <td>BOSS-DR16</td>\n",
|
|
760
|
+
" </tr>\n",
|
|
761
|
+
" <tr>\n",
|
|
762
|
+
" <th>14</th>\n",
|
|
763
|
+
" <td>0.795586</td>\n",
|
|
764
|
+
" <td>134.21014</td>\n",
|
|
765
|
+
" <td>27.571681</td>\n",
|
|
766
|
+
" <td>BOSS-DR16</td>\n",
|
|
767
|
+
" <td>-6444638005468311552</td>\n",
|
|
768
|
+
" <td>0.000337</td>\n",
|
|
769
|
+
" <td>GALAXY</td>\n",
|
|
770
|
+
" <td>52e3cf35-fe87-11ee-b89c-08002725f1ef</td>\n",
|
|
771
|
+
" <td>BOSS-DR16</td>\n",
|
|
772
|
+
" </tr>\n",
|
|
773
|
+
" <tr>\n",
|
|
774
|
+
" <th>15</th>\n",
|
|
775
|
+
" <td>0.554642</td>\n",
|
|
776
|
+
" <td>134.11568</td>\n",
|
|
777
|
+
" <td>27.491442</td>\n",
|
|
778
|
+
" <td>BOSS-DR16</td>\n",
|
|
779
|
+
" <td>-6444636356200869888</td>\n",
|
|
780
|
+
" <td>0.000287</td>\n",
|
|
781
|
+
" <td>GALAXY</td>\n",
|
|
782
|
+
" <td>53203e47-fe87-11ee-b26f-08002725f1ef</td>\n",
|
|
783
|
+
" <td>BOSS-DR16</td>\n",
|
|
784
|
+
" </tr>\n",
|
|
785
|
+
" <tr>\n",
|
|
786
|
+
" <th>16</th>\n",
|
|
787
|
+
" <td>0.688878</td>\n",
|
|
788
|
+
" <td>134.19652</td>\n",
|
|
789
|
+
" <td>27.657880</td>\n",
|
|
790
|
+
" <td>BOSS-DR16</td>\n",
|
|
791
|
+
" <td>-6444635256689242112</td>\n",
|
|
792
|
+
" <td>0.000177</td>\n",
|
|
793
|
+
" <td>GALAXY</td>\n",
|
|
794
|
+
" <td>534af931-fe87-11ee-8467-08002725f1ef</td>\n",
|
|
795
|
+
" <td>BOSS-DR16</td>\n",
|
|
796
|
+
" </tr>\n",
|
|
797
|
+
" <tr>\n",
|
|
798
|
+
" <th>17</th>\n",
|
|
799
|
+
" <td>0.638226</td>\n",
|
|
800
|
+
" <td>133.85629</td>\n",
|
|
801
|
+
" <td>28.080178</td>\n",
|
|
802
|
+
" <td>BOSS-DR16</td>\n",
|
|
803
|
+
" <td>-6444633057665986560</td>\n",
|
|
804
|
+
" <td>0.000194</td>\n",
|
|
805
|
+
" <td>GALAXY</td>\n",
|
|
806
|
+
" <td>539b0add-fe87-11ee-b991-08002725f1ef</td>\n",
|
|
807
|
+
" <td>BOSS-DR16</td>\n",
|
|
808
|
+
" </tr>\n",
|
|
809
|
+
" <tr>\n",
|
|
810
|
+
" <th>18</th>\n",
|
|
811
|
+
" <td>0.614235</td>\n",
|
|
812
|
+
" <td>133.79296</td>\n",
|
|
813
|
+
" <td>27.907149</td>\n",
|
|
814
|
+
" <td>BOSS-DR16</td>\n",
|
|
815
|
+
" <td>-6444632233032265728</td>\n",
|
|
816
|
+
" <td>0.000294</td>\n",
|
|
817
|
+
" <td>GALAXY</td>\n",
|
|
818
|
+
" <td>53b9cd41-fe87-11ee-8132-08002725f1ef</td>\n",
|
|
819
|
+
" <td>BOSS-DR16</td>\n",
|
|
820
|
+
" </tr>\n",
|
|
821
|
+
" <tr>\n",
|
|
822
|
+
" <th>19</th>\n",
|
|
823
|
+
" <td>0.804484</td>\n",
|
|
824
|
+
" <td>133.87033</td>\n",
|
|
825
|
+
" <td>28.192423</td>\n",
|
|
826
|
+
" <td>BOSS-DR16</td>\n",
|
|
827
|
+
" <td>-6444631408398544896</td>\n",
|
|
828
|
+
" <td>0.000317</td>\n",
|
|
829
|
+
" <td>GALAXY</td>\n",
|
|
830
|
+
" <td>53d853da-fe87-11ee-9f77-08002725f1ef</td>\n",
|
|
831
|
+
" <td>BOSS-DR16</td>\n",
|
|
832
|
+
" </tr>\n",
|
|
833
|
+
" </tbody>\n",
|
|
834
|
+
"</table>\n",
|
|
835
|
+
"</div>"
|
|
836
|
+
],
|
|
837
|
+
"text/plain": [
|
|
838
|
+
" redshift ra dec data_release specid \\\n",
|
|
839
|
+
"0 0.545929 246.74298 35.985258 SDSS-DR16 1506516519029336064 \n",
|
|
840
|
+
"1 0.667431 245.40676 36.438884 SDSS-DR16 1506548404866541568 \n",
|
|
841
|
+
"2 0.502511 246.45702 36.657405 SDSS-DR16 1506572869000259584 \n",
|
|
842
|
+
"3 0.724874 246.89323 37.209662 SDSS-DR16 1506578916314212352 \n",
|
|
843
|
+
"4 0.741196 247.40873 36.381456 SDSS-DR16 1506596508500256768 \n",
|
|
844
|
+
"5 0.675723 134.10755 28.038851 BOSS-DR16 -6444647351317147648 \n",
|
|
845
|
+
"6 0.782685 134.23727 28.084685 BOSS-DR16 -6444646251805519872 \n",
|
|
846
|
+
"7 0.797439 133.98095 28.226386 BOSS-DR16 -6444643503026450432 \n",
|
|
847
|
+
"8 0.647712 134.54531 28.429551 BOSS-DR16 -6444641304003194880 \n",
|
|
848
|
+
"9 0.886086 134.46525 28.452505 BOSS-DR16 -6444640754247380992 \n",
|
|
849
|
+
"10 0.898559 134.43695 28.450988 BOSS-DR16 -6444640204491567104 \n",
|
|
850
|
+
"11 0.566015 133.95386 27.305313 BOSS-DR16 -6444639654735753216 \n",
|
|
851
|
+
"12 0.599517 134.05133 27.381025 BOSS-DR16 -6444639104979939328 \n",
|
|
852
|
+
"13 0.812179 133.95189 27.333753 BOSS-DR16 -6444638555224125440 \n",
|
|
853
|
+
"14 0.795586 134.21014 27.571681 BOSS-DR16 -6444638005468311552 \n",
|
|
854
|
+
"15 0.554642 134.11568 27.491442 BOSS-DR16 -6444636356200869888 \n",
|
|
855
|
+
"16 0.688878 134.19652 27.657880 BOSS-DR16 -6444635256689242112 \n",
|
|
856
|
+
"17 0.638226 133.85629 28.080178 BOSS-DR16 -6444633057665986560 \n",
|
|
857
|
+
"18 0.614235 133.79296 27.907149 BOSS-DR16 -6444632233032265728 \n",
|
|
858
|
+
"19 0.804484 133.87033 28.192423 BOSS-DR16 -6444631408398544896 \n",
|
|
859
|
+
"\n",
|
|
860
|
+
" redshift_err spectype sparcl_id _dr \n",
|
|
861
|
+
"0 0.000422 GALAXY 2c6c82dc-fe87-11ee-838b-08002725f1ef SDSS-DR16 \n",
|
|
862
|
+
"1 0.000026 GALAXY 3063feb6-fe87-11ee-8aa0-08002725f1ef SDSS-DR16 \n",
|
|
863
|
+
"2 0.000172 GALAXY 336d71cf-fe87-11ee-9390-08002725f1ef SDSS-DR16 \n",
|
|
864
|
+
"3 11.831918 GALAXY 342e5eaa-fe87-11ee-9047-08002725f1ef SDSS-DR16 \n",
|
|
865
|
+
"4 0.614932 GALAXY 36565b1b-fe87-11ee-b857-08002725f1ef SDSS-DR16 \n",
|
|
866
|
+
"5 0.000241 GALAXY 5182df54-fe87-11ee-a660-08002725f1ef BOSS-DR16 \n",
|
|
867
|
+
"6 0.000242 GALAXY 51ad9b94-fe87-11ee-af3e-08002725f1ef BOSS-DR16 \n",
|
|
868
|
+
"7 0.000424 GALAXY 521321c8-fe87-11ee-946d-08002725f1ef BOSS-DR16 \n",
|
|
869
|
+
"8 0.000238 GALAXY 52643970-fe87-11ee-abb3-08002725f1ef BOSS-DR16 \n",
|
|
870
|
+
"9 0.000274 GALAXY 5278859e-fe87-11ee-8427-08002725f1ef BOSS-DR16 \n",
|
|
871
|
+
"10 0.000311 GALAXY 52913c34-fe87-11ee-844b-08002725f1ef BOSS-DR16 \n",
|
|
872
|
+
"11 0.000315 GALAXY 52a796f0-fe87-11ee-b337-08002725f1ef BOSS-DR16 \n",
|
|
873
|
+
"12 0.000412 GALAXY 52bbb47f-fe87-11ee-b8d7-08002725f1ef BOSS-DR16 \n",
|
|
874
|
+
"13 0.000338 GALAXY 52cfb971-fe87-11ee-be51-08002725f1ef BOSS-DR16 \n",
|
|
875
|
+
"14 0.000337 GALAXY 52e3cf35-fe87-11ee-b89c-08002725f1ef BOSS-DR16 \n",
|
|
876
|
+
"15 0.000287 GALAXY 53203e47-fe87-11ee-b26f-08002725f1ef BOSS-DR16 \n",
|
|
877
|
+
"16 0.000177 GALAXY 534af931-fe87-11ee-8467-08002725f1ef BOSS-DR16 \n",
|
|
878
|
+
"17 0.000194 GALAXY 539b0add-fe87-11ee-b991-08002725f1ef BOSS-DR16 \n",
|
|
879
|
+
"18 0.000294 GALAXY 53b9cd41-fe87-11ee-8132-08002725f1ef BOSS-DR16 \n",
|
|
880
|
+
"19 0.000317 GALAXY 53d853da-fe87-11ee-9f77-08002725f1ef BOSS-DR16 "
|
|
881
|
+
]
|
|
882
|
+
},
|
|
883
|
+
"execution_count": 16,
|
|
884
|
+
"metadata": {},
|
|
885
|
+
"output_type": "execute_result"
|
|
886
|
+
}
|
|
887
|
+
],
|
|
888
|
+
"source": [
|
|
889
|
+
"pd.DataFrame.from_records(found.records)"
|
|
890
|
+
]
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
"cell_type": "markdown",
|
|
894
|
+
"metadata": {},
|
|
895
|
+
"source": [
|
|
896
|
+
"<a class=\"anchor\" id=\"retrieve\"></a>\n",
|
|
897
|
+
"## Get Spectra: `client.retrieve`"
|
|
898
|
+
]
|
|
899
|
+
},
|
|
900
|
+
{
|
|
901
|
+
"cell_type": "markdown",
|
|
902
|
+
"metadata": {},
|
|
903
|
+
"source": [
|
|
904
|
+
"In order to retrieve spectra records from SPARCL, pass the following to the `client.retrieve()` function:\n",
|
|
905
|
+
"```\n",
|
|
906
|
+
"uuid_list : List of IDs.\n",
|
|
907
|
+
"dataset_list : List of data sets to search for the IDs in (default: None).\n",
|
|
908
|
+
"include : List of field names to include in each record (default: 'DEFAULT').\n",
|
|
909
|
+
"```\n",
|
|
910
|
+
"\n",
|
|
911
|
+
"**NOTE: A reasonable amount of records to request retrieval of is about 10,000. Exceeding this value may cause the retrieval to timeout or fail.**"
|
|
912
|
+
]
|
|
913
|
+
},
|
|
914
|
+
{
|
|
915
|
+
"cell_type": "code",
|
|
916
|
+
"execution_count": 17,
|
|
917
|
+
"metadata": {
|
|
918
|
+
"scrolled": true,
|
|
919
|
+
"tags": []
|
|
920
|
+
},
|
|
921
|
+
"outputs": [],
|
|
922
|
+
"source": [
|
|
923
|
+
"if show_help:\n",
|
|
924
|
+
" client.retrieve?"
|
|
925
|
+
]
|
|
926
|
+
},
|
|
927
|
+
{
|
|
928
|
+
"cell_type": "markdown",
|
|
929
|
+
"metadata": {},
|
|
930
|
+
"source": [
|
|
931
|
+
"#### Use IDs from FIND to RETRIEVE records\n",
|
|
932
|
+
"Use the IDs from the output of using `client.find()` to retrieve records from SPARCL. \n",
|
|
933
|
+
"\n",
|
|
934
|
+
"Note that `ids` in `found_I.ids` is a property name of the Found class. It is a list of records from all records, not a field name of a record."
|
|
935
|
+
]
|
|
936
|
+
},
|
|
937
|
+
{
|
|
938
|
+
"cell_type": "code",
|
|
939
|
+
"execution_count": 18,
|
|
940
|
+
"metadata": {
|
|
941
|
+
"tags": []
|
|
942
|
+
},
|
|
943
|
+
"outputs": [],
|
|
944
|
+
"source": [
|
|
945
|
+
"# Define the fields to include in the retrieve function\n",
|
|
946
|
+
"inc = ['specid', 'data_release', 'redshift', 'flux', 'wavelength', 'model', 'ivar', 'mask', 'spectype']"
|
|
947
|
+
]
|
|
948
|
+
},
|
|
949
|
+
{
|
|
950
|
+
"cell_type": "code",
|
|
951
|
+
"execution_count": 19,
|
|
952
|
+
"metadata": {
|
|
953
|
+
"tags": []
|
|
954
|
+
},
|
|
955
|
+
"outputs": [
|
|
956
|
+
{
|
|
957
|
+
"name": "stdout",
|
|
958
|
+
"output_type": "stream",
|
|
959
|
+
"text": [
|
|
960
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=mask%2Cspectype%2Cmodel%2Credshift%2Cwavelength%2Cspecid%2Civar%2Cdata_release%2Cflux&format=pkl&dataset_list=SDSS-DR16%2CBOSS-DR16\"\n",
|
|
961
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"2c6c82dc-fe87-11ee-838b-08002725f1ef\", \"3063feb6-fe87-11ee-8aa0-08002725f1ef\", \"336d71cf-fe87-11ee-9390-08002725f1ef\", \"342e5eaa-fe87-11ee-9047-08002725f1ef\", \"36565b1b-fe87-11ee-b857-08002725f1ef\", \"5182df54-fe87-11ee-a660-08002725f1ef\", \"51ad9b94-fe87-11ee-af3e-08002725f1ef\", \"521321c8-fe87-11ee-946d-08002725f1ef\", \"52643970-fe87-11ee-abb3-08002725f1ef\", \"5278859e-fe87-11ee-8427-08002725f1ef\", \"52913c34-fe87-11ee-844b-08002725f1ef\", \"52a796f0-fe87-11ee-b337-08002725f1ef\", \"52bbb47f-fe87-11ee-b8d7-08002725f1ef\", \"52cfb971-fe87-11ee-be51-08002725f1ef\", \"52e3cf35-fe87-11ee-b89c-08002725f1ef\", \"53203e47-fe87-11ee-b26f-08002725f1ef\", \"534af931-fe87-11ee-8467-08002725f1ef\", \"539b0add-fe87-11ee-b991-08002725f1ef\", \"53b9cd41-fe87-11ee-8132-08002725f1ef\", \"53d853da-fe87-11ee-9f77-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=mask%2Cspectype%2Cmodel%2Credshift%2Cwavelength%2Cspecid%2Civar%2Cdata_release%2Cflux&format=pkl&dataset_list=SDSS-DR16%2CBOSS-DR16' | python3 -m json.tool\n",
|
|
962
|
+
"Got response to post in 0.264625997049734 seconds\n",
|
|
963
|
+
"Got 20 spectra in 0.26 seconds (76 spectra/sec)\n",
|
|
964
|
+
"{'success': True, 'info': [\"Successfully found 20 records in dr_list=['SDSS-DR16', 'BOSS-DR16']\"], 'warnings': []}\n",
|
|
965
|
+
"CPU times: user 7.69 ms, sys: 10 ms, total: 17.7 ms\n",
|
|
966
|
+
"Wall time: 269 ms\n"
|
|
967
|
+
]
|
|
968
|
+
},
|
|
969
|
+
{
|
|
970
|
+
"data": {
|
|
971
|
+
"text/plain": [
|
|
972
|
+
"{'status': {'success': True,\n",
|
|
973
|
+
" 'info': [\"Successfully found 20 records in dr_list=['SDSS-DR16', 'BOSS-DR16']\"],\n",
|
|
974
|
+
" 'warnings': []}}"
|
|
975
|
+
]
|
|
976
|
+
},
|
|
977
|
+
"execution_count": 19,
|
|
978
|
+
"metadata": {},
|
|
979
|
+
"output_type": "execute_result"
|
|
980
|
+
}
|
|
981
|
+
],
|
|
982
|
+
"source": [
|
|
983
|
+
"%%time\n",
|
|
984
|
+
"results = client.retrieve(uuid_list=found.ids,\n",
|
|
985
|
+
" include=inc,\n",
|
|
986
|
+
" dataset_list=['SDSS-DR16','BOSS-DR16'])\n",
|
|
987
|
+
"results.info"
|
|
988
|
+
]
|
|
989
|
+
},
|
|
990
|
+
{
|
|
991
|
+
"cell_type": "code",
|
|
992
|
+
"execution_count": 20,
|
|
993
|
+
"metadata": {
|
|
994
|
+
"tags": []
|
|
995
|
+
},
|
|
996
|
+
"outputs": [
|
|
997
|
+
{
|
|
998
|
+
"data": {
|
|
999
|
+
"text/plain": [
|
|
1000
|
+
"{'redshift': 0.5459291338920593,\n",
|
|
1001
|
+
" 'specid': 1506516519029336064,\n",
|
|
1002
|
+
" 'spectype': 'GALAXY',\n",
|
|
1003
|
+
" 'data_release': 'SDSS-DR16',\n",
|
|
1004
|
+
" '_dr': 'SDSS-DR16',\n",
|
|
1005
|
+
" 'ivar': array([0., 0., 0., ..., 0., 0., 0.]),\n",
|
|
1006
|
+
" 'mask': array([16777216, 16777216, 16777216, ..., 16777216, 16777216, 16777216]),\n",
|
|
1007
|
+
" 'flux': array([1.23176956, 1.23148859, 1.23120809, ..., 4.00684404, 4.00690508,\n",
|
|
1008
|
+
" 4.00696611]),\n",
|
|
1009
|
+
" 'wavelength': array([3794.89706208, 3795.77097003, 3796.64507922, ..., 9217.22098659,\n",
|
|
1010
|
+
" 9219.34357452, 9221.46665124]),\n",
|
|
1011
|
+
" 'model': array([0.34971759, 0.35207507, 0.35443148, ..., 2.31373858, 2.30945611,\n",
|
|
1012
|
+
" 2.30356026])}"
|
|
1013
|
+
]
|
|
1014
|
+
},
|
|
1015
|
+
"execution_count": 20,
|
|
1016
|
+
"metadata": {},
|
|
1017
|
+
"output_type": "execute_result"
|
|
1018
|
+
}
|
|
1019
|
+
],
|
|
1020
|
+
"source": [
|
|
1021
|
+
"results.records[0]"
|
|
1022
|
+
]
|
|
1023
|
+
},
|
|
1024
|
+
{
|
|
1025
|
+
"cell_type": "markdown",
|
|
1026
|
+
"metadata": {},
|
|
1027
|
+
"source": [
|
|
1028
|
+
"## Plot spectra"
|
|
1029
|
+
]
|
|
1030
|
+
},
|
|
1031
|
+
{
|
|
1032
|
+
"cell_type": "code",
|
|
1033
|
+
"execution_count": 21,
|
|
1034
|
+
"metadata": {
|
|
1035
|
+
"tags": []
|
|
1036
|
+
},
|
|
1037
|
+
"outputs": [
|
|
1038
|
+
{
|
|
1039
|
+
"data": {
|
|
1040
|
+
"text/plain": [
|
|
1041
|
+
"<matplotlib.legend.Legend at 0x7fd1f96db7c0>"
|
|
1042
|
+
]
|
|
1043
|
+
},
|
|
1044
|
+
"execution_count": 21,
|
|
1045
|
+
"metadata": {},
|
|
1046
|
+
"output_type": "execute_result"
|
|
1047
|
+
},
|
|
1048
|
+
{
|
|
1049
|
+
"data": {
|
|
1050
|
+
"application/vnd.jupyter.widget-view+json": {
|
|
1051
|
+
"model_id": "84c674d2919c4a9f804a778cb667076f",
|
|
1052
|
+
"version_major": 2,
|
|
1053
|
+
"version_minor": 0
|
|
1054
|
+
},
|
|
1055
|
+
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAyAAAAGQCAYAAABWJQQ0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAACFfklEQVR4nO3dd3gUVdsG8Hu2JqQCCRAgDQhI70gvUlUUFURREVB4bXwWVBAEaQKiKGIvqCCCDRQUUHoNvQSQGiDUAKEmJKRsOd8fyW62l2Szu0nu33VxkcycnTk7mZ2dZ845z5GEEAJEREREREReIPN1BYiIiIiIqPxgAEJERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBEREREReQ0DECIiIiIi8hoGIERERERE5DUMQIiIiIiIyGsYgBARERERkdcwACEiIiIiIq9hAEJERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBEREREReQ0DECIiIiIi8hoGIERERERE5DUKX1eACun1eqSmpiIkJASSJPm6OkRERERkQQiB27dvo3r16pDJ+Cy/KBiA+JHU1FRER0f7uhpERERE5MT58+dRs2ZNX1ejVGIA4kdCQkIA5J/QoaGhPq4NEREREVnKyMhAdHS08b6N3McAxI8Yul2FhoYyACEiIiLyY+wuX3TsuEZERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrmIaXiIiIqIBOp4NGo/F1NciL5HI5lEqlr6tRrjAAISIionJPCIHLly8jPT0dQghfV4e8TK1WIyIigvOw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ujrkZWq1GjVq1EBoaKivq1IuMAAhIiKick+SJERFRaFKlSrGsQBUPsjlcna78jIGIEREREQFDONBiKjkcBA6ERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBFRGSCEr2tARETkGgYgRERERETkNQxAiIiIiIjIaxiAEBGVAZLk6xoQERG5hgEIEVEZwDEgRERUWjAAISIiIiIir2EAQkREREREXsMAhIioDOAYECIiKi0YgBARlQEcA0JERKUFAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIjKAAHh6yoQERG5hAEIERERERF5DQMQIqIyQILk6yoQERG5hAEIERERERF5DQMQIqIygGNAiIiotGAAQkREREREXsMAhIioDOAYECIiKi0YgBARERERkdcwACEiKgM4BoSIiEoLBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMACx8NNPP+G5555Dq1atoFarIUkS5s2bZ7d8RkYGRo0ahdjYWKjVasTFxeHNN99EZmam9ypNRERERFRKKHxdAX8zfvx4nD17FhEREYiKisLZs2ftls3KykKXLl2QlJSEXr16YdCgQdi/fz9mzZqFTZs2YfPmzQgICPBi7YmIiIiI/BtbQCzMnTsXZ86cwdWrV/H88887LPv+++8jKSkJY8aMwapVq/Dee+9h1apVGDNmDHbv3o3Zs2d7qdZERIWEYEYsIiLyXwxALPTo0QOxsbFOywkhMHfuXAQHB2PChAlm6yZMmIDg4GDMnTu3pKpJRERERFQqMQApouTkZKSmpqJDhw4ICgoyWxcUFIQOHTrg9OnTOH/+vI9qSERERETkfxiAFFFycjIAICEhweZ6w3JDOSIiIiIi4iD0IktPTwcAhIWF2VwfGhpqVs6W3Nxc5ObmGn/PyMjwYA2JiIiIiPwPW0B8aMaMGQgLCzP+i46O9nWViKgM4Bh0IvJ3By/cwpu/H0BaRo6vq0I+wACkiAwtH/ZaOAytGfZaSABg7NixSE9PN/7jeBEiIiIqDx78LBG/772A138/4OuqkA+wC1YRORvj4WyMCACo1Wqo1WrPV46IiIioFDh9NcvXVSAfYAtIESUkJKB69epITExEVpb5hycrKwuJiYmIj49ntyoiIiIiOzhvUfnEAKSIJEnC8OHDkZmZialTp5qtmzp1KjIzMzFixAgf1Y6IyjN+nRMRkT9jFywLc+fOxdatWwEAhw4dMi7buHEjAKBjx44YPnw4AGD06NFYtmwZZs6cif3796NFixbYt28fVq9ejdatW+PVV1/1xVsgIvK5HI0OuVo9wgKVvq4KEfkRnV5ALpPsrtfrBS7eykZ0pQperBV5GwMQC1u3bsX8+fPNliUmJiIxMdH4uyEACQoKwqZNmzBp0iQsWbIEGzZsQFRUFF5//XVMnDgRgYGBXq07EZG/aDdjHW7e0eDAO70QVoFBCBEBSedv4fFvtuPN3nfZLfPG7wfwx/6LeH9AEwxsxW7sZRW7YFmYN28ehBB2/82bN8+sfFhYGGbPno1z584hLy8PZ8+exaxZsxASEuKbN0BE5ZK/daO+eUcDAEi6cMu3FSEiv/Hm7weQo9Fj6vIjdsv8sf8iAOCz9Se9VS3yAQYgRERUYjjAlIgMbHW94hWifGIAQkRUxvCmn4j8kUyyP/aDyhcGIEREZQC/14nI3ynkvFBRPgYgRERlABs9iMjfOcp+ReULAxAiIioxjIuIyEDOploqwACEiKiM4U0/Efkjma1B6LxglUsMQIiIygB/fbDop9UiIh9QsAsWFWAAQkRUBvjrU0Q/rRYR+QDHgJABAxAiIiIqMR+sOoZRvyYxPTTZJPiYolxiAEJEREQl5vMNp/DH/os4nJrh66oQkZ9gAEJEVMb4+kEzn3STLXk6va+rQD5m69IguTlS7HpmLh75IhG/7DrnoVqRLzAAISIilwghsPvMDdy6k+eknOkvJVsnIirdBPKvK/2/3Ib/LqY7Lf/x2mTsO3cLb/1xyAu1o5Ki8HUFiIiodPj3v8t4YeE+VA1VY+e4HnbLMeYgIlvsjfd49KvtAIAn5+40Ly8Ebt3RoGKQyrgsK1dbchUkr2ELCBERuWT5oUsAgCsZuQ7L6dkFi2zgaVF+XLh5B6evZrr9uvRsjdnvr/yShOZT12D7qeueqhr5CQYgVKqcu34H87edwdFLGVi6/yL7mhPZUFJZZVYcvOTa/vmxJJt4YpQXHWduwD0fbkJGjsZpWXvXi3M37uCvA6kAgC83nSpcwUy+ZQK7YBH2nLmBnSk38HyX2n6fo/ueDzdCqy+8WkkS0K9ZDR/WiIgsmQZAV2/bbi2ZsfIoJEnCW/fe5a1qkY8xMC1/Lt3KQWg1pfH3op4Dpg8b3R20Tv6JLSCEAV9txwerjmPJ3gu+ropTpsEHAOw9e9NHNSEqH3R64XZLo2nx0UsOWq2/kZWHrzefxlebTuG2C09IiUqT5QdTceiC88HUZZXp9eLX3ect1hV1m8WpEfkjBiBkdOqa+/01fY0XJaKSk6fVo+usDRj83S63Xufsc5mnLUzHqmdm1nKjPFyu9527iZGL9uOBz7b6uio+Y/r5/z4xxXxdEc8CTlZY9jAAoVKNg12prMvV6vDqL/uxLOmiw3KWH4W9Z29g1eHLTl4jMH3lUfy257zN9fvP3cT5G9nYevIaJv992OU6+8PNwoLtZ/DQ54m4meU4ZTCRJ528Uvoe5HlaSXz6E09ex7qjVwDkd72m0o8BCBmVxn6Vvr/NISpZi3aew9KkVLzyS5LLrxEC6P/ldjy3YC/i3lphN7f+9lPX8c3m0xi92LqbFADITMaE/ZB4xu7+tDo9hs/fjc83nAQA7D5TvK6RG4+n4cSV28XaxoRlh5F0/hY+XX+yWNshzykPz4v8IfguCWkZOfjrQCo0Lkwm6XaXTRfLPTt/j1vbJf/GAIRKtfLwhUbl27VMxylvDRw9FXxp0T7b23bSOuBqTorVR65g7dE0fLDqOLafuo4h35t32UrP1ph1uzK9SRMQ+GXXOfzvxz3I0ehwODUdQ3/YjV6zN7u2cyfu5HHOAPIef/lOupOnxQ+JKbhw845HtnffJ1vx8s/78dXGU84L27D/3E18uPo4crXF73NZ+h6Vki0MQKiU85OrPVEJ0XvgFL91R4Mpfx/B4O924uz1rMJtW2w8/Y7GOHhW52TH6Xc0mPTXYRy8cMtsYrDNyVetyjadvBrdZm00/m56k6bTC7z1xyGsPnIFC3eeK3bLhyV20/QfTJvuPe/9cwyT/z6C+z/xzFgUw4OQtcfSnJa19Vd++Itt+HT9Sew/d6vYdWEXrLKBaXipVOP3GfmjPK0eKoVnnu+4egPtqFh6tsY4GHToD7uxbGQH7DlzA7lanVm5bh9uxI2sPDzSogb+PpAKjc7+RqeuOILFey9g3rYzeH9AE6f1uHgr2/iz6XsyjXPSszWobDLjsSd4IoCjoitvQYfpu9XrhVk3Rm/aknwNgPXEfsVl693kaHRYuPMc7rmrCuIjgrz6vZxyLQvxEUHe2yF5DFtAyKg0PlUoZ99tVAqcv3EH9Sb8gzd/P2C2PM+Nrgfrj13BqF+T8lsWinCO9/3U/lPPlGtZGPr9Ljwzbw8+Xptstu5GQZesP/ZddBh8AMDxy4UtFaY3ma7ccGZkF7aYmJbPztPi1V+TnL7eHbxG+FZZOP538rQY9WuS06QOgPn7Xe9Ca0FJcfTgQgiBpPO3kKPR2S3jjjnrkjF1+RFjK6e742DszRVkj+l41cST19x6LfkPBiBUqpXVAX9Uen23NQVCAL+bzKvz7vIjqDv+H5e7Fz0zbw/+2H8Rn6xPdngjkZmrNd7Amz5AOJnmOBPPvoJuEJfSc1yqjzNjlhwy/uzoE2mo632fbDEuM22hWJaUalZ+04mr6DhzPbYV3GTo9QJDvt+FxpNWIS3Dtbp74gn8H/su4MPVx8vd03xPK61H75vNp/HH/ot4bsFep2VNv5O2nbqOF37ai5Npnu1W6Apbp+rve87jtz3n8dOOs3jo80Q8/b176bXt2XPmhke244r9526aXetkpfHJKQFgAEKlHLtXUGkwd2t+96fZa05gzZErmLjsP5eyyVy4kW33HF+WdBGNJq7Co19tB1D8J82pJl2kXGE6lsSU5bgSU8sPXrJapjOpeJrFk9Ah3+/ChZvZeLkgA9iOlOvYdOIqbufkt5RcvZ3rtIuJJy4Ro347gE/Xn8QeTnzqNneO//XMXExbcQTJHh4HVFxXMlx/Qm85B8Y//13Gk3N3lkCtnNTD4shn5mrx5uKDGL34IL7adBoAsCvF/cDB1v2+ZQbNkozTH/5im9nvct7Fllr801Gp5uxCl53nmSZmync9MxefbziJyw6enN/O0WDEj3vw14FUu2XKKyGAET/uwfztZ+3OvWFKo9ObtYDkaHRYcfAS0rM1xrS8e87e9MgTSFee7prKyLGdXcrRQ4H/+3k/5lh0+3IUsBjkFnQVydUUBm3bTl1H62lr0XTyaoev9eQgdM4pUjzO/hRjlhzEt1tS0GfOFscFSxl3AhhPsTzWpl1A3el6df7GHTwzb7fDMt5uhPjFZHZ1iS0gpRYDEDLz38V0fLIu2WN9Q0uaoy5Y45ceQv13/sWB87e8V6EybuSi/fhg1XE8/b39J3qfbziFNUeu4OWf93uxZqWD6c2wKzclWr0wu5F4d8URvLRoH4bPN78hGPDVduRoi/eZPWRnrhB3Wc58bGn22hNmv+e50BJ0O1eLlYcu2U3h6SiIsbdq28lrSLlmuxXHHk8P6AXyu4itOnzZ7bqUBjq9MBsr5Iyha6CzDGz+zJc1n7/tDH4veLDhqbj7lV/2m41lsXW7b9oNasLS/7w67oddsEovBiBkJCF/8OpHa07g64ImWr/n4EL3045zAIBP1iXbL0Ru2X76OgDghIPZfm9kef9pn7+yHDNgel9lSI6z/dR1jP3jEG7nWN/canR6s20s2Zs/G7qtif7e/vO/YtXVV9/j3T/c5FK5Fxfuw/M/2W6l6ThzPdYeuWJzna1xG0cvZeCJuTvNUgO74s3FB3Hwwi0AMEs9XBybTlzFcwv2ul0XwLXWI1+a+Nd/ZuN9nI3Z83TgIYTApL8O4/utjoNiD+/Ue/sycTk9BxP/Oow3Fx+0eRxNP97u1DD1lvOxVjKTO8kFO8569QGmj5KMkQcwACGbjlzyzNPQkubKhZQPSLzLsj9weWP65Xv39HUWEwkWnrEySYIQAoO+3YGfd53Dh6vNWwYAQxeswt+zS/CLXV6KPyip6TkY/mPhLMn7zhUGaLbGnRxOzTD7PUejM0sTvGjnOfT8aJPNSdy+2nQK7/97DA0nrsK2U9ew+vBlrD9mO/hxxd4ijitZsOMsmkxebfZe/Y3hIZCrPB1QHbiQjnnbzmDK8iMe3a4j3gg/hBDYd+6m2UOLcX8eMltvGXibfrzdSabgymXB8prvzbl32AJSejEAoVLNtQspL1DkHROW/mfWPzntdi6+M3n6atkCYvr0/7SNLjh64b1Mb2XhizwzV4tP1yVj1qrjZsvT75i3Llm+0/s+2YIO763H4dT8By/j/jyE5LRMTF951GofuRo9viiYDfq1X5PwvwV78cy8PdAWdCXL0egw5Ptd+MFGVzQhBF7/7QAm/XXYuKyoN2sTlv6HzFwtXi0YC2SQp9U7vC5+sfEk4t5agXlOusqVhO2nrjt8Oq71cADiSivVjH+OYvj83XaDn7TbObAVVmh1euw4fd1qLh1v3HsvP3gJj3yxDQ+YpNs27SaVf90wZxokOKviybTb+HD1caRna6wy5dkac2H5N/Vmw5yv5lmh4uNEhGRTack26c/VnLvlNBJPXsNXg1tCrZD7ujpeY+8+Nkejw/pjaehQOwJhFZQubWv80kPQ6QVmPNLEeWE/sGDHWYfrTW8MZ1m0eOj0eqsygPe+zF0Zi+HvGk1cZXN5q2lrsP71roiuVAHnb9yxGi9z+mp+8Lfy0CU0rB5mXJ6j0WNrsvk8A6bjUEzH8Wh0AhqdDot2ncOmE1ex6cRV9GtWA0FqufHzf/FWNpbsy0/PPPa+u6BWyJ3+faevPIoTV27juyGtIbdxsyWQP87ilV/248m7YzBl+RHc2ygKnwxqbnN77/+bH5xN+vsIBrSKRrDa+jbgemYuKgWpIIRnb/A+XX8SKdey8NkTLWyu19n54tlwLA01KgaibtUQj9UFyA9MDd2Nd525gba1KgPI/zv9uO0MFHIJn284ZfO1z8zfg80nrgIAzrx3f3799cIrT/8NCT7OXLduoQPyzwlH1XBWxR4fbQbgeppuy+xw3m0B8dquyMMYgJBNppePG1l5qOTh2Yk9xZWbM1892H13Rf7T0z/3XcTjbWJslkk8eQ1xEUGoER5YYvW4kpGDk2mZaF+7colnDLmcnmPWAmDqg1XH8d3WFDSNDseylzo43dbtHI2xC8eonvUQGaL2aF2LIiNHg9s5Wrf+XkcvFXb3cXS6anUCy5Iu4u8D5l2GFu10rxtLWaWEFhrIUZQWTY1O4L1/j+HV7gnoOXuzy6+TkN9iYGqrnYnPnv5+p9XYnBZT1yC2cgVserMbAPMbv+2nrqN5dEWnN4PfbM6/Qd6SfBVt4iuhgsr8a9uQWe3cjTuYsCy/ZeWvA6k4fS0TE+5vgLsLbqptydXorAKQfw5dwgsL96FtrUo4nJqBV7onoHPdSMzfdgaPtY5Gk5rhjivsxPKDl/DZE7bXmbZCaHR6KOUyHLqQjmEFWZgMN/r2aHR6aHUCgSrXHvg89s124897z940BiDP/LAbx52kAjYEHwZanR69Zm+22ZLpac7OGWGj5dT0d9NkCsuSLqJfsxo2t2MrgYvlp2+DjckWOQidXMEuWGRk3kc0v/m6zbS1aDF1jUcGcpfEwDRXumB58/KUlpFj1ZR/x04q4O2nruPJuTvR4b31JVqnu6evw5Nzd2Lj8avOC9tw9XYu3v7zEP5zIUvSq7/az3y1dH/+AGrTLzWtg6fupkdRq/ePp/NNJq1Gh/fW40rBJHhanR4p17Jw4eYduymfTY+7o4B5Z8oNvPJLEtYeLRxPUJQ8/WVRU+kk/lM/i8+Un5gt7ybbj7nKDxCF6063seLgJZvjbPabjKHQ6ITZmIx1x9Kw7ZTzbQO2EwMAwFmTp9SmXYyG/rAb987ZbHZjqNcLrDt6BXvP3sCMlUfN0l0P/WE3Wk5di0vp5vO1XLiZjXM3rJ+E/3cxA499swPHL9/G238ewpHUDON5a9Bm+jqcumqeUGLGP8cAADtO38DtHC3eXXEU93+yBQt3nsODnyV6fObpU1czsSzpIoQQZi0gk//OD6aOXs6w91IrPT/ahPrv/OtygoBjJhm6Pijotpd85bbT4MOWE1cy3Q4+fkhMwdTlR4owwWVh+euZ1kk/9EJYZdmzt4tXLLrwmUp2MqEpAGNwaGpnimufGU9g+FF6MQAhu2atPm6cGOyjNdZf3O74c/8F3DXhX/yyy7NPc73xoGXH6et4/JvtTmez3Xg8DW2mr8P/uZh+1psXaQDYkly0G4e3lhzEwp3n0Nekv7E9Ry/ZP0aWD6q+3XwaCeP/sXuTbfqFaXrjnnItC8/O213kwbt7ztzA6MUHbM7pcDLtNmavOWE2uPNyeg7+9+Me42zcQH5QN/i7nXj+p/zsRR1nbsDQH5zPKmz51LS0CUWmSzf7phTQ4nvl+zgT8ASWq8ZBBfdT2Y5W/Aq1pEFf+U5UK9h/vHQJP6g+QA/5foxVLnJpO/8evmy1zHRis282n0b/L7dZlfGEFQcvWWW6Sk3PwcHzhYH90qSLeHb+HvT/cju+3nwaY/84aFY+W6Nzu0Xs4S8SsXDnOdz3yRbcPX2d2TqdXmDK30eQlas1Xt+UcutbOo2u8AM4b9sZZOVqizVgfO/Zws989w834ZVfkrDy0GWzz7y9AezbTl7DR6uP28z0ZOiSdKAgU5m7tiRfdauFzFRRHsRP/vsIvtuagoMXrB/upN/R4PutKQVjUOxr+e5aq2W2/jQl8V1p7xxwFNQQGTAAIbsO2bgoFtVrvx4AALz1xyEnJd3khS5Yj3+zAztO38CIHx1P1PZlwcDUFYfMu9DY27+3M2gWtV/uMTfy+CssOuReNZvZ2nzdtJVHIUR+gGOL6VNB0y+65xbswbpjaUW+URzw1Xb8tucCptrIjNPjo82Ysy7ZbPDx09/vxOojV/CExWzGW5KvYe3Rwu4HO8toa0UoMnEm4AmcCXgCm9SjsF79OmKkKwAEgnEHph/CR+UbMUf5GWpKaVBCiwHyTTgZ8DTukScBABrJzmCW8iu8pliMLapX0E52GC2kE/hE+SnOBDyB7eqRUMM8MKwtXUQ7WeHf6mfVuwCA+2U7jMvul+1AJG6V0BEovlytDi8t2mdznSG1NZA/47qpDTZaLfN0eqt5YByx1wJrWre+n25Fj482Y1fKDSidTC2deisbDSeuMnvy/fmGk3ji2x0ut3L3/3I7Rvy4B3dPL7x53nPWtc/PE3N34pP1J1F73EqcupqJ9GwNBn2zw+zh1q07GsxecwLnTVqGztkZL2Fq8HfOHyLY4873TFpGjtn17eYd64chbyw+gCnLj+BpG3Vydim3da13pZXl1p089JrtOC226fu0N2bHm/yhDlQ0HANCRlKRM4X7jisZgjyVFtay+4J1XdzjfrN78TjbX65Wh9WHr6B97cqoHFy08RYKi6enWbla49gNe4MFT1/Lwq07eQivYD7OyPQJp+kXqq3uJkVx5rr97hL7CyZEE0I4nPOktKuMdNwtO4qLIgIHRG1IEBij+AVZIgBnRDWMUy7CaX2UsXxFKf9YbFa/ZlyWpK+Nx/PGY736dVSX8m8i+8m34ay+CmJl1v3DH5QX9rv/WTXNbF2UdAPHA4YCAEbkjcJufT2sU79pViZedgXvKH7EvfLCGzO5JDBYsRofaQcW8UiUrHrj/3WpXCRuop7sAhL1DSHsPB+8k6szC3yLKz1ba5wEce4W5/M/GVIYbzJpzTN0X/p9z3kMbhfn0n7XWMzbYm8OEEdX76E/7ML5G/ld0kwDuTGLD+K2RTeszh9swFv33oXnu9R2qX6OHHOjW5ilP/dfwGu/HsDT7WKNy2xNsGnoimnrAZCzh0mWXdBm/HPUpbES329Ncet65w8TRvpBFaiIGICQ0Zbkwi8UIdxvOTh++TZWHEzFc11qI8hGZhUDvV44zKxy4PwtxFUOcilTkjfv4Z3uy826FLVFIk+rxy+7z6FjnQjUigx2+XVXMnIx5e8jeOLuaNSpYp1NZvaaZHy16RTqVAnG2lFdXN7u5fQcJJ68hgeaVodCZv/pqaPzaewfh/DlUy3Nlpk+2TLtO+8soDx7PQtj/ziEF7rWRqeESAf1cX6C++OXW1PpJNIRhBgpDT+qZmKtrjme17wGOfToLDuIU6I6akjXkCKi0FO2BxOVC8xe/4+uNSQAh/TxeFP5m9P9RckdP5luJjuFYwHDrJabBh+fax/EB9rHMVExH8MUtjNVWfpW9ZHZ70Pz3sQ81QcAgGcU+Tf0OiHhDc3zmK36Ei8rluJbbV/cRgWXtm9PfeksYqQ0rNc3h6aYX5HNpJOoKzuPJbrO0MHxwOhPlZ/gAXl+q84c7cOYrX3UZjlnD0LcZZokYbWdyRxdNWHZYeRo9BjaIc44eN5Vpt28DIQQxuDGFkPwYcky+DB4759jeL5LbexKuYH3/rFOseyK/y6mW3VHFUK4/KDrvYIxNj9uL8yYl2cjAJFJks2n+1qd3mmr1pS/zVt3XZ1YOM/G38CS6fv0ZrYre/x9Mk6yjwEIGR0w6XIl4FrLQZ5Wj60nr6JNfGX0+3wrcjR6pN3OxXv97adNXXbgIh5uXtPmuk0nrmLI97sQEazCnvE9ne7fcP3T6vSYsy4Z7WpVRvs6EWZlHNwTe4W9o1jUrKffbD5lTOGaMuM+lzNbGfq/L9p1Ft3rV0V85SC80buecf3fBakdT7ow8NDUfZ9swY2sPJy/eQeZDgZ/OnoCt+fsTcz89xg2HEvD4hfaI1itgOm4c63JF6OzVq9Xf03C/nO3sO3UdYdZc1w5av7whA/IzwDVS7YHn6s+sVrXQ74fC6XpuFt2zKVt3SvP7zrTR+56Nx4A+E57Lw7oa+F95TcIkGyP49itr4vFui6YqfwWAJApAnBP7odIQ0UAwGTt0/hV1w3XRBhqSlexVP0OrohwvJD3KvaJuhit+AUvKv6y2u5aXXNs1DdDvZx5xhYSAPha9wCW6TtglH4xomVXcShgOABgja4l/tPHYYGuJ24gFI/KN2KM4hekiGq4KUJwVlRFT9leKCUtbooQREq38IW2H/KgwAzld8btL9D2gBZyJEgXkIaKeEReeOM5QzMIQxSrjK0+O/T1URkZqCDlYGTeyzgqYvCt6kNESuloKSVjnPZZxEhpkEGPTBGIX1RTES+7gv/lvYYPlF8jTCps2XtOvhyrda1xVlRBpkVAZeiuE4pMDJRvwnJdW1yG/UxX3jZt5VFk5moxx83EJbYSUiSevG4chwjAas6Nohr49XbnheywNRbOneuErev+uRt3MPaPQxjSPhZ3VQsFkD8xqK7gWnc9M9fYKt3r483GtNH2mCaycIe7Dx1tBY3e5g9BEBUNAxAqllmrj+ObzafRtlYl5Gjyr6zOLn57z960G4CsLrhJvpZp3SfWFsPFZ/HeC/h0/Ul8uv6k1U1ncbpgmXYzcHbja2+95VKtTg+FXFbkLlgfry38Yk88eR0dEyJsljt7PQs/JJ6xWp6j0WNFwezQpgGIrQt52u0cm90DTN0oGMz9/dYUZOSYByAaO1HWSotxMkII4xiaX3efx7Md482e/ml0+ZOr/XUg1XieAcCJK7dRt2oIMnO1xnSiVyxy1x+9lIGTaZmQSRI+21CYUtVZl4QLN+/4JP10O9lhdJUl4aSogYP6Wugn32bzptyUq8GHPRmiAkIlx13bvtXeh8uojA25+fNL5Lc0CBxQjzDePD+Z9zbyoESivhGEAC4iAuahnoRjIj8l9TURhrgc88Hj72sfx/vax6FGHraqX0aklIGJmiGYr+sNAMiFCrVzFmCofBWS9LWxV+SfvzO1j+Mz1afG7fSU70VP+V68plxitv0IybrrTA0pv+vOZOV8q3WDFdYDfA3GKn82+72trPCJ+p/qiWbrHlNsxGOKjTa3841qttnvN0UwKkqZWKEeh6siDO9ohuJZxT/YpGuC9frmyMjOb70cpViMoYrVGKpYhe65sxAppSNNhCMPrs2x4wkand5mqlZ3gw8gf4C9pae+Mx935WpXNkeWJV0s9jYsad2Y/0NnI6OfoZXn193ncHpG/veXTAag4JCMWXIQc4e0hk4vnAYfhvq463aOxiwjnCseczGQs7zee9If+y7ikRa27yfIvzEAIftcuG//uWDg347Thd00TG8QbbF3bSzKDbnhFWc9NC7AVPodDYZ87/qgRHvV/2RdMoZ1iAeQ30d6/NL/8M3TrVz6wrqTp8W5G3eMT8V2n7lh9uVyPcs6BaPBE9/uxMVbtrso2GL6FG/p/otoHV/JYYrg9GwNwgILb3Ysgw8A6Dl7M96+rz6OX7ltNqnViwvNB+SaBpyGoMW0aV2rF9icfM0qu0qv2ZvRtV4kNh6/igXPtkGnhEirgO/eOVtsvwGT8ztHozNO7gXk97vuOHMDBrYquS+2BtIZVJVuYoe+PqpL1/GUfC36yRNRSXK9BeozbT90lh1EE1mKcdl7msfRSJaCvvKd+E57L6Zqn4ISOmggR33pHO6R7cchEY92siP4VdcVZ0T+GI8wZEIFDa4WtFYAAv+oxqK+LP8zfhmVAMCii5OEprnf4l7ZLuzR1zXe/F4Q9ru+uSIXKrTO/crmOh3k+E53n9my5fp2yMtTWN3MO5Koa4hWshNIEdVwl6xw7pqj+hi8qnkRq9RvFa3yRbRc1xbvap7E/xQrjF3MIqV0fKmaAwBoJTuB17EYv2bej5aq/agjyz9fa0rXjK1CF0VlDMsbjQgpHSposUdfF5kIxO+qyWgtO4HOubNxTlR1UAsBCcLu+BNLPT7aZJZmuDiWHyy5m1RTJZGhSacXLrWC5Gn1uHnHfhY4003ITR6Q7CsYk3bexe+5ojzb6vd5okvBTdL5W/i/n/fj7fvqu5ygxPJ670lbT17DphNX0aVu8a455H0MQMim/D6t5rLzdNYTPNm40Dmbs8FWn80/91/AtBXHUC3MvcHPhgutw1ipiA0gppM1me7Lbl1Mfj6SWvik1fQL583F+Rmfhny/C892jDcuP3Y5AwlVQqxmOu73WSKS0zLxw7DW6FavCvZYzDXwyi9JiAxWG7udbTiWhtjKFZCt0bkcfNzO0WDC0v/Mujq8+msS3n2okcPXNZ28Gien3et0+9NWutfX2nCcTQM0rU5vNxg0zLMxfeUxrPi/CJdn7zU90rNWHcfcrSlWZX7bc8G1SpsIQjZ6yvYiWdTESVEdAhKGy1cgSdTBN8qPECzlYJrmCbztYupYUzdEMLrnzsJNhBbWHQPxkCwRPeV78I5mGK4jDNABI01OX8NYhqMiFkd1+YNfN+ubmm07HZbjiSS8pnkRD8m3Yq72fhiO2B8vtscjX2wzK/eP/m6334unrda3NraoqKBBS9kJzFF+jirSLYzKex6nRHW8qliCWdqBSBFRuIMA42uDkI0PlV9hn74OftDdCw0UBdsSCEY2MlEBEUiHAPKPLwTayY7gtD4KVwoCM8MVoCpuood8H0JxB3Vl5/Gp9mE8Kt+EFxR/AwC+1t6PnrK9CJTyMFd7LxrLUvCp9mGcEvmTwa3Vt8AzsP+k/zHdCrv5K2tI17FaPcbuazerX8PA3Ak4JqIhg4ASOlxFGPL/tgKfKD/Dg/LtGK8Zhp90zrvAeir4KO20OtcCkPnbzri8TdNxkoaHc/aubb/uLl56+1t38lwKPoD8LGx/H0jF6av+k5xjyPe7UDlIhZqVKrg0yS35BwYgZJOtS2mbaWtxaHJvp+WcXYhtPfk3pOm9ZmNSJcfyt+WoN01RO2AVJ33vfZ+YP3UXQiDPojuS6XHo8/EWPNYqGjMHmI+dMUwEtXT/RXSrV8VmJqkn5u7Emffux96zN2xOCuVIVq4Wc9YmY2lSqtW6sw6yRBW+vgQmlyz4m5rOKeJKX2MhBKbYSK1rz86UG2gzbS02vtm1yH2mLcVJl/Cx8gs0k51yWM6V4ONXbVdjt51JmqexUNfDzqBoCUv1HbFU37EINXbsmIjBe9r8aatPTrsXCicpWt0hl0klNsYmD0ps1zdEm9wvzJYP09i+Oc9CIJ7XvGZjjWQcg3ENYWbLt+sbWpUFgCuohIW6HvmLCj4eM7WD8KH2UQhI0EGOGXiy8GUWH6Ht+gb4UvsALohIyKFDrJSGOdqH0VB2Fu8pvkWsLA0XRWVM0zyJdfoWaCU7jtnKLyGHDpUl50+kf1NPNfv9X11rTNQMwRr1aGM3vHeVP+Atxc84oK+Nd7RDcUFEoop0E91l+5ELJSKRjnX6Fjgs4sy2VVNKQzvZEWzSNcXdsqO4X74TH2gHGoOrRtJpNJalYLGuS7EH+PuTw6np+GX3eYdlcrU6tx7GmHYRNXxK7LWaj1lSvPT27Wa4Pxnu4dSiZwIrCdez8hAcUHbOqfKAfy2yy/IG3FZmEVvdppzdLBZ18LUthS0gnp8P1fL9O02C5aCJ5FJ6DrpaTEJmWfzXPeetAhDLso6CogMmE5q56oNVxy3m6ij07RbrFgFLJTEA0LDJ538qnHfFMniz97p5Fk8YnXXrS7udiwbvrELtyCC36wnkp7GdqfwGW/WNsVtfDyvUbxdpOwbjNcOwQne3sYVjjHYEQnEHGSha/YoqNECBR1tF4zuTViFXg49eDaq6lE0pMliNy25mdAoNUJh19Xule0KRxhv4gtbFr1sBGWZqB1kt365viPvyZmCQfD3+1bcxdnNL1DcuCLQEWkjJCJRycV5UQbZQY47yM7SXH8Efuo74SPsoNqhGQSmZRzx95LttJiQIlnLQQX4Y6+RvWq0DgFFYjF36evhK+wC0kGOs4mdjdz3TYSh95LuRLVRYp2+OvvL8MR0zlN/hodwpGK5YgSP6OMzV3Yc8KHCPbD8ek2/Ee9pBSBHVCrbg+NoegFy8rPgTg+Vr0D13FnKgLPi85L8uEDnQQV6iY2Ms5wjKJ/Ch8ku0kJIxTjsc/ybd5dY25WYtIPn/F2Vshytsjb8pTeYNa42osECbk2iS/2IAQna5clOf5SAd4PkbdzB1+RGM6FzLbLnpTatOL5DqxjgFS65cjp1licrR6JCr0Vul/XU1u9Qn65KRo9E5rMsvu89bpVp05+bdUNbe36SozeE7Tl9HrSLefANw+wbSFUIIq2w3rozFOX7F+umvswH0Bo7SB9sm8H/yP/G6cjGA/ExUrrouQnBeVMEP2t5Ypu+AIOQgDFkIknKQLCzHnEheDz4AoHp4ICb0bYBtp66bpWm1JJOAMX3uwox/CgfBP9k2tsjpXKf2a4gJyw7bXR9eQWUWgLzWsy52plw3G4NWlmUhEHN1+YOUH2ha3Zi5Lp+EfaKu2UXxCc14mE483zz3a0xXfgc1NEgR1dBTthe1ZYVjL26KYDyUNwW9ZbsRLmVhkHy9ce4XW9rIjqONyn6aXINAKc8YfBgsVb8DAOgr34nRyl/N1vWW7zH+nCfk2KBvjjayY3hR8wqGy1eihSwZaSIcQVIOakrXjGV3BbwEID9r2gjN66iCW1ihHocroiIG5Y2HHDqz7ouByMF4xULs1SfgD31nSNBjlGIx6ktnMVLzMlrJTiBKuo7fdV2dvkdLLaRk9C/ImvazahqurFkICe+6PL7GrAVECCSevIaLN4v+XVmWNa0Zjoo+SBhCxcMAhGzyxIPt1387gF1nbljdjJh2u3hp4T5jetiiMDzhNu2a9OhX2zCmT+HTJmdhRLsZ63Dzjgb7J/Q0u4hZdXeycUwW7TyHj9bkp8StEmJ//IqtzCfuBCCGkvZioinLjxRpEN6xy7fdmunc0hcbHXc1KgohgPf/dX5T44q7JriWNcfRvDQAIIMe1aVrGCJfjRGKlU631z93IvaKuoiTLuOsqAoBGZTQIgjZuIVgmJ6VWQhEFgI9Pvdn3arBRZ5E8dNB+ZmunOXYH3dffQzvVMssAFE4OZYGllnjpvZriMHt4hwGIF882cKYBrVqaP7nzTQRgilDX/B+nye6VB9/9uWTLTDqtwNmT6rf6FXXIgBxLhMV8LLm/4y/z8YATFX8AKWkxRua541zlXyjeyD/f+39GKb4F5G4hQBJg4+0j+KyqAgdZBgpX2oMwAEgVygwUzsIq3St8JnqU2SICvhX3xr3ynZBBj2uoBLW6lpACS1mKOciSHKtu61K0hkDEtOJKx0FRj3k+5Eif8r4e4SUgYMBIwAAA3MnoK3sKMKlTHSUHUJd2UU8iXX4CF/hH11rY5rqY/LCuW0mKn5El9zZ6CQ7hI9VXyBHKDFROxTx0mVcEBFI0tfGOMUi5EGJCCkdjWRnkCvMb6+q5p5BZ9khNJJSsF/UwTa99Ri7CsgBcjKAgFCYNjhm5GjxpM1WFgIApcLHufapSBiAkE0Ctm9295+7iWVJqXitZ127X/wG9gZBm6ZXLU7wAZhkDTGp7O4zNzHgK/vpAW9m5WHYvN3o36IGBreLMw4STzp/C0cuZSA7T4c3etezam0w3DDdydNi3dE0dK0XiXF/Fva9TbPTlQmwHdDZurfbduoaEqqEGGcPL3x9fmFbaXUB4HZO4WzG3uTuDZArdp+9ic0m6Y+9wdZTfjXy8Lrid2SJAKt0rqZS9FWhhwx3oEYYsvCM5k2cLGjJMGSYAvIHgt+C9QSQJaVtrcpmAciGN7qim0k3wL9GdsCDn9m+Oa9TJX9Aeo8GVXD8ym1UCw2wWc6gVmSQcRCrqwFItkXrqWEG7d+fb4ez1+9gx+nruJ2jQcq1LOP7aFQjDGfeux9HUjNQs1IgAPsPSxpWD4VCLsOsR5vijd8PuFQnT3qqbQx+2lG8wcEGDaqHYupDjczeR0ylCogIVhdh3FyhXKgwWvuczXUVVHLcyguxOyHip7pH8IOuDx6Wb8VSXUez7GgP500x/vyzrrvVa0/lVcezin/wp64jrokwfKD8Go1kZzBH+wiW6DrhOfly1JalmqU2dmaJriMU0KON7BiiJPstYpZjYEzda2dunGApB3sDXjD+HiBpjHPd2KOWrLssz1fNNP78f3kjESGl40ddL+ggR0VkYKf6JeA9HTDsH7MsWOQYu16VTgxAyC5bs7M+XJD9Jk+nx/SHGzt8vcrOU4mizn9hc1sulLmdo8HG42nolBAJuSx/Loik87eQdP6W8aYHyG+RMORjf7JtjNU8EYZqf7j6BL7bmoIOdVyf/OvbLdYz0S7aaX1z8sS3OxGolGP72HsQXqGwNcawb3tB3d6zN7H3rHs53P2Vt4MPW2pJqVivfsNhmWR9DQzKG28xONm7qoSo7Qa+A1tFm822HB9h3pUrSG3/8m/ofvhy9wTUighGJztzzRgsePZuY8pmy0xucpmELaO7ocPM9WbBgr3um63jKqF1XCUMaJkfxH2x8aRVi1iD6oXdaO5vEmXVyvpSt9rGMSu+ytbzao+6TgOQR1vWxDMd4/Hvf5cxvFM8/th3ERP/OoxqoQFm3RsrBqnMbrI61omAJEnYM74HNDo9mkxajWyNDqN61jW2yDrTo35Vh8kX2taqjPXH0uyuB/JbVBboerm0P1OHRTxGaV40/t43b7rZ+re1zxp/lkMHHWSoiNu4V74b/+haG7tRqaDBr6qpaC47iQXaXkgSdRCGTCxQzUAt6RImaYdALyT8T7HCLNWyQZoIxyLdPXhV8YfZ8jnaR/BKwbJ0UcFskkh3ZIhAdMydAzW0+FP9jll3sU9VnwEAmshO46C+Fl5TLIaqYHyOJvELSNIzZtuKly6hiXQKf+vbQ+9iN67yQunr2YapSBiAkE07Tl+3GYAYnHIyW/bJtNt2n4R6MvONMI6NsG/D8avYcPwq3r6vPkZ0roUsO7N1m8YbeVo91ArzlMNavcBjX2/HzpT8p2uJJ6+7XE93ZozN1ujQbMoaTOjbwLiMs716xwvyvzBG+YvDMlt1DfGbrhtW6O82dlnxBls3lzvGdketcba7hEUEqzHxgQaY/PcRmw8D7D1hXfVqZ+PPaoUc/VvanwvFcFqGmGSfsQxAosICUD080KqlwtXrQKDS8TF+sGl1RIUFIixQid4fby6oQ+H7zbTzebc0sFVNtK8dgaVJF3HPXVXwjklXsB+faYPRiw8ag4Kp/RpCAOhQJwLdP9zk0vYtmU6YWj8q/4Z6SPs4DGkfh0/WJRv/1tMfbozQAKXZ8fv48WbGn5VyGfa/0xN6IVBBpbAZgJx5735sTb6GrDwtnluQn9zhw4FN0XTyarNyP49oi0Hf7rBZ3+Pv9nE4EeBzXWrh603WD1qKy/AZu4lQLLJoTcmDEo/kTUJFZOJGQVCSjmA8mDfNrNwfefnn9MOyLRipWIrbqIDpmiewS9QHAHysHYA+sl34SvUxtEKGz7X9MFs7wPj6BOkChsn/xS+6bjgoaqMiMtBXvgPrdC0QJOXgK+VsfKh9FFv0TaCHhGyo8ZBsK46LGGQUpLd+RzMU36tmWb2/h+WJeFhu3hKpPPE3ZupOQ1ICe0RdzNH2x3zle4iRXUVjbQo+1D6K7II00uG4bWxZVUGDptIpJIk6ZSrLmDPOutCSfyo/Zyi5xVHwATifRTotIxdKO1lznG3bnv8u2s7ypNMLlzLh/H0wFc1jws1aCkxbY+x1uTJlCD68YapJSlnGH8UXgXRkoAJCcQf95ZtxQUTiCfk6dJDbH3NgMFXzJL7T3e+0nD0rX+5klZrZXQ80rW52c7nq1c6QySSM7FbHbIZ3A7lMwtPt4hARrEbL2IpW6+19hutVc7+bmOmWLAf0F7cnyeOtY/DPocvodlcV2/uWJLSJr2S2zDS4chTATH6wISb+Vfj3f6h5DTzUPD9lrGkA0rluJLaPvQdnrt/B+Rt30NlkvNWkBxpg0t/W6Z/DnXRRdeSZjvHYd+4m7msUhYGtowGYH8eKFcwH3AY4CdIAoGNBK9akBxpApZBbdaGtWTEQzWPCjb9btlSbPpCpFKTCjaw8s/UhDlrUSpKAzBh8OPOnvhP+zOtkc92/+jbGeWQsJYuaGKcdbvz9JkILW34E0D3vQ6vX/KHvbPb7en0L9Ml9D5dEJfSW74YKWnSRHUBPeeEkfbdEENJFEGJlaehYcF3qgMN4RfGnscxwxT8YrvgHe/UJyBEqdJAfxo/annhascZYJklfCy/kvYbe8t24ICKRCyXOi0icFVXRTZaEqyIch4R5chh/p0YeZNAbAy8q/RiAUJE4u6nQCYEcO6n9Nhy/iqnLj5g94Xdk79kbGPfHfzazHAkB7ExxrSUiM1drNTbE9CGsZcDhTzf9JZR9scypiAxoCtJ5RkgZeEi+1WyWcHc9kjsJ1xDmZPZooEf9Klh71H53lUpBKnRKiMCW5Gt2yzhjelP976udjIHCG73r4Y3e9ZDw9kqzlrZAlRxymYQHmlY3LqsfFWoc7+LJXgump6dlC8gnjze3+Zqm0eFIqBKMxXsv4P/uqWN324EqOX57vp1b9TF99uGo9TBA6fpBkCQJ8RFBVl3ZhnaIx+NtYjBl+RGsPXLF2CVOIZfhv8m90WjiKqtt2eueahCsVmDesDZW+zewPMbuGNoh3mrZMx3iMe6+u8xSLdetGoINx213hxzRqRZm/luYeECtkGFg62jMWm3d+jLn8WYlMvs4ALzYtXaJJMIoKcdEDADgN103AMBPup5opD2NK6IiZBDQQ4YMVMCvqqlO5xJqKSt86GYafABAM9lpbA/4P8uXmLktAiGDHkFSLs7qq2CJrjN2i3om89vkf24qIBdPyNdht74eDgj7n9OSpIQWK1VjUVW6iX55U43zylDpxgCEisRZC8j1zDycdjAo+rutKS4HIP2/tD+gXEC43L3pdo51Vwx73UC2JF/D+KX/ubRdb1h79Aq2nSz6zWtpJEEPFbQIxR1cRyjuks5hiHw1Kkq3UQE5aCY7hWDJs2mAk/U10DdvGgQkyKFz+Wlb+9oRDgMQmczx4Owfn2mDp52kGjYNGCoHWWdcUyvk0OgKz/EglfVT8Xf6NjB2sZFJEoa2jzObO+WnZ12b0bx97crYduq6MbgRJo2aljfHzWOsW1/euvcuPNK8BioGqfB0u1g0rO7ZcTSmra+OgndXU207E6CUY/rDjZGj0eGPfReNy4PVCiS90xPNppjfID7f2f2nz64OSl75cifsO3cTM1YedZgm3VSQWm4MPv58sT3++e8yXu6egL8OpOJSeo5VRkDTAE8uk7D/nZ6ooFJgxcsd8fmGk1h5KD+5yOrXOuP8Dc/Mlv5+/ya4k6c1a20a1iG+VAUgtvxnoyXiobwp6CHbh2yo8Lz8b3SS/4dVulZ4SfMyoqTr2KK2NWkmsEXXCBv1TTFBudDpfkOkwvGEsbI0jJLlZzQ7qo/BCVETTaRTiJeZjxHaqmuIwyIOAhL26OuhuSwZ63Qt0FR2Cpv1TcwCAxU0CMEdXPfAGLm7pHPGdNEvKv7C65oXnLyCSgMGIFQkKdeyHA4m98TM0lqdHqsOO96OO60UtsqaBiCmXbD8KfgwsD3ZVemkRh7qSKloKzuMh+WJuCbC0FXuvUxFO/V3YYe+PjJEEHbr6+E2KuBMQbrcQq53oXF2b+jo5nHL6G6IrlQB0ZUCcf6G/Tz/pjfLrmSasnVzHW4y141cJmHSgw2x4/R1Yyrmjk4Gmxv89OzdyNXqEVgQ5Egmh83Z030AeL5LbePPTWqGu7RPVwzvGI+1R69g0N0xxmWOxpp4uue4rWtMaID5efTFky3Qq4HjFjVbWsfnB3LOsg82qB6KBtVDsebIFWw6cdVh1yjDxI496hfWp3lMRWPQOP+ZNnjvn2N4rUddAEDlIBWuZ+WhW70qmJd4BqnpObi/cRQqqPL30bB6GO6Or2wMQOpWDfFIANIytqIxKcGMf44Z5/dxNeOaLfc1robJDzZC62lri10/z5OwVt8SQP5Ek9AIGM7W86IqWud8gRcVy3BcRONXXVfESVdwW1QwJsS4JsIQI6Vhp74+/k/xJ3boG2CDvhkelW/Cn7qOqCc7j8HyNYiR0hAumT8orC87h/qwnTyho/wwOsLQNXE5AOAlxV/G9VdFKNbrWuAO1Ogj340o6QZezHsZK/VtrbYlgx7x0iWcFlE250ZpFVsRe8/dhBBAPZMEAp1lB1CQp9OVA0l+jAEIFcnFW9l43UFqS08Mmv52S4pZM39x92MrXaXWdH4OXs88LgyZeFq+Gk8o1jtMjVlU5/SRiJHldxM5ra+GCCkdoVI2ftT2xDe6vsbZooOQDTU0LvcVd1evhtUw2cY4AANHEx1GV8pPXxqsVgKwH4CYBvxyJ2kn/3yxvc3lpi2XxXn4L5NJxuADyL/JHt4xHjohUDnYdxOCje/bAOMtWlYtH5R89kRzjFzk+sSR7rD1UEYmkxColBvn8LivcZRVGVdUCQnArnHdHWYvM/XhwKaYuyUFA1vZTyKweXQ3pN7KMcsqZqpu1RB8P7S18fdNo7vhemYuYisH4ef/tcXfB1LxdPs4s9fEVK5g9ru98+yjgU2RrdHh6KUMm9nCUmbch+UHL2HV4cuY2b+JcaBxi5iK2H46v9uts8+BI188mX+DP+3hRnj7T/974GTO/H1eRTgma4cYf08R5ufUMn1H48+DNfWNP0/WxgEADupqm02uWEtKhQx6hCMTD8sTcZfsHPbpE5AHBZ6Qr8dvui7Yp6+Lj5RfIEjKxTURigjJOnV5pJSBxxQbzZZ9ofoEm3UbcFLUQADy0EZ2DL/puqCnfC9ay05gj74uBuRNstrWA02rY/GIVogbvxoNpMJsfpFSBupKF3BCRNs9WlQ6MAChIjPtamDJlQw3pnNo2OIs+ACKP07DNE0puUYGPYKQgwDkoYp0E5WlDLSTHUFD6Qw6yx3/TV2VK5S4ijCc01fBKVEd98p34ag+BlO1g6GHBDn0OC5inG+ogHGyvxJSPSwAByb2wuHUdDzxbX5L1f2No7DiUH63AZkMVlnVLNnJ2WBkeq47645jq9sTYH4zaNiGpzKsGW78b+donJT0Lp3F++vbpLoxAPFUFywDe5e93eN7YO2RK8Zgs6iqOJmPxVREsBpv3XuXwzLhFVRm6b6dCVYrEFwQAMVWDsLIexKsynStG4l3+jawGdSYjpV6qFkNyGQSvthonUAByP/bPNC0utkYJsD8u8UTc2U8eXdsKQhAStZpUXiM92jNz5kPtI8bf26b+zmCkY1LqIwY6Qqui1C0kR3DIX0tfKL8FHVkqZCgR6SUgYP6eOP4u87yQ+iMwu+GcbKfjT+3kp3AmYAnsEnXBFv0jXFSVIcaGnRO+h5YvRaH1WqrSSu/Vn6Et7XPYpf+LmghB/Q6QOa9jITkGQxAqES4Mmja1jwY7irurZNh3g/KVwkZCJKycY8sCTlQ4WH5VrcmA3PFTv1dqCFdwxl9VSzTd8AqXWvkQoloKQ0SgGRjP+LCm4sJ2mdsbssWQ7cSb5IkCWGBSjSsHgZJyp+fo3/LGsYARC6TcH+TKKuJN38YVvh0ecL9DfDYN7ZToFpyNgbLHtN7cZkxACnSpuwqat1Kis5B0j3TmnoiDrMXzAWrFcbsWmWdJEl4pmPhQHfL7IIGhhYNy4xezpgGlJbjjepWDcaJK5lQK2SY0LeBX3al9Rc/DG2NYfNsT7xoz21UME44aUjMsUGfn2TiCc14Yzk18pALFepJ5/C2YiE6yw/hmD4agchFrKxwrFyKvqpxnEkX+UF0kR8s3FlBMUPwkSkC8KX2Qbyp/A3xsitYpJqOPCHPnzvFMO9lv8+BxgMBhe9aYcl1DECoRHhyrg+HPLgbnRtzdZQmQchGDlTQQY5est14VvEPYqUrUEGDSlLJTdJ2UwRjma49/ta1w3ERDQ0UyIX9LwbD7OHF5e3gw1RYoBJ7x/dEBZUciSZJA2SShL5NovB/P5t3/WlXq3Ayy7trVcb4++vj3RXWAV/dqsGoHh6I2pFBCFDK3creZMo005vhBtDTc8zYiz+CVHJk5ekQ4eUuWo5mcfd0rORPmfP8hmT3FwBA/xY1MfYP11tOp/ZrhMe+3o6XuyeYpR+uWTEQq1/rgqu3c1E5SIVrWbleCUAClDLkaIqWWt6XoisFol7VEGRrdDjnoUQBBobr/HERg6c1YwGzRlGB5tJJnBQ1cBsV0EA6g8flG1BFugU18lBVuoVcKFEpMgqxLfvgzqop0EKGCZphWK5vh0jpFu6WHUW0dNU6CcnaSUDjRz36XqjkMAChEqH1UgCy56znxhVYdtUoHQSCkY22sqOIla4gHUEIQxbule9CK5lrMyK7a7muLU6J6jilr45jIhrXRSg0kCMPSuggt5oAq0Z4IDLtzOBeFlUKyv/yNc3EpJBJNrv7qC0GbD/TIR51q4bg/37ej/Tswm/t74a0hlwmYfVrXSCh6F2HzFtADAuLtCm77LWA/PZ8O8xek4zRfep5dodO/K9zLcxe6/yz4IlghBOGOmbrGJsmLaigkuOOk8xdDaqHImliL2Prx8z+jTF/21l8N7QVACAyJD9DnKOWuLpVg92tul1fD26FISYZ7N7sXa9UtKzXrFgB/7zSCZczctD+vfVF3s72sfeg3Qx3Xi9hvyjsundExOEd7TCrUmMa34UX2tdGg7/iYTrofJJ2aEEJgRq4htay4/i43R1AmwdUbwYorDMEkn9iAEIlQu+lAMSTu/l0vfPJDL1LoK50Aa8pFiNKuoEIKR2ZIhB3mWQE8aRkfQ1kQ4WvtA8gWrqKSOkWPtM+ZJxlt6j6NKqG77YWfS4OT5nxSGO3nrS66u376ttcHmxjdvAPBjRB4slrqBSkRtVQtVUgIZNJ6Fw3EkEquVkAYhg74Gj+B1fun83GkZRQC4ip303m72hYPQxzh7QqsX3ZE6iS49mO8TbPQUc3qSq5DHk6PSoHud5iwwDEmukRNgQH9vRrVgNta1VC82jbY5gMTD8Hj7WOwWOtrceD2fvbHpzUCxUsJm5cO6oL9py5geYxFdH7480O9+1M/xY1jQHIhje6otusjcXaXkkxtB4VtctkVFgA/v6/jogILpkbfvPPkq06SriISLzYrxtwd2yJ1IFKFgMQKhFe64LlQf9dtM7q4Q3BuIMIKR0dZf/haflq1JXZH9xflExd6aIC1ulbYKOuKTbqmyEXSuggQwju4GYJZYUyVdybsl//19blsRGODGoT4/EApFZkEJ416e9uqm7VwsDNEGg82ioaj7Zynr1FU4TPjyuvMOuCVVCn4kxqZ4vpDY2/jAfpVq8KvtuaYjUruqPqLXmhPWatPo6x9zkeyG2qNF73vOnNXvWQlpGLR+1k5pJJ+UGIJ9g7rS3TIgNAnSrBqFMlv1Xkjxfb4/XfDiDFwTxWBrvGdcfRy+YT5JqeU4FKOWpFBFnNiXXi3Xvx4sK9DucOckfTmmE4cCG9SK8t6sf/7fvrl1jwAdjOKAcA3w1phWfn7zH+/iSDj1KLAQiViOS0khtb4P8EZBBQQQM59KgsZeBZ+Up0kB3GOVEFgchDO7n9lK2uWqFrAxkEJABLdR2wR18P1xCKIOTgDtQ2c6ub8kbwAbjWL/7l7gnYdvIa9py9aba8btVg3G0yTqKoahXMXr34+XYY8JX9iS2d6d+iJpbsuwAgv7vI+te72i0brFZgz/geZl2xXKU1GTn9wYAmbr/eHluD0Oc83hzPzNuN0X1cv9F2xE9iDjMdEyKw5IV2iKsc5LxwgcY1wzD/mTbOC5qwNdlpeWfaylcxSOW1VjB7g9+daRFTEXMeb4YHP0u0W6ZGeCC2jO4GmUyyCkDM6iDlz6XS6f0NZstVChnmDmmNlYcu4cWF+4zLq4aqcSXDOl28MwNaRRc5ALFshW0VW9HqOmzzdSWct95wCVz2Ugf0+7zwb9G9vvtz6JB/YgBCJcLWnBtliWGW7jjpMprITuNu2THcL9uBQCnP4evqINXlfSTqGmKm9nEcFLXgTtOHs3SznRIisCW5ZGZVf6RFDav0zK48FR7Vsy4ebVnT6ot6zuPNPVIvw9wUreIqmaXHddW2t+7BjtP5M38bApB+zao7eRWK/ISwZWwlrD16BeEVlC61mLjK1hiQRjXCsHNcd4+lpPWXVg9LLWMrOVzvid5TCVWDsTPF8/PdkPukouVpAADEVnIcqC54to0xiYPVfi1+j65UAbGVK+Ds9fyB3l8PbmlcZzknzB8vdkCHYozHKArLj+tDzWsgPiIIv++94PB1Hm44tWIYk1mvmnUX4Dd61cWs1Sc8+nCGvI8BCJV6Gq1nM5AEIgcqaKGADgPkmxEjpaG/fDMCJA0yRQAqIBcyyXNdLb7R3o8Fuh64IUJLdK4Kg0FtYkosAPloYDMsP3gJeSZ/E1cH99uaI6F+lGdaaWY92tT4s62Zuh0FJWtHdUH18EA80iK/28iUfg2xaOc54+zQJeH9AU0wLzEF/Vu6nhnMpTEgJl2wTLteeXI+DPMbE//ukuTpeUDe7H0XglQKPOhCcFpe+CoctRUIr3mts0uvDaugxJ8vtsfl9By8YNJC0TquIjolRKJWZOEg9hrh9q/Zhhq81K0ORi/OTzHbu2E1szIDW9XEb3su2NzWxje6oqsLY0gebl4DE4qY8cvyOPVuWA37XGkBKeE/rKELlq2/40vd6mBQmxhULsEuYFTyGIBQqTf8xz3OC1lQQIswZOEB+XY0lp1Gf/lWl15nlfbPge+1fbBXXxc6yJAqKiNZ1DBmivKlkh4n+/tz7XD2xh28XJBy1rQvb8qM+xA/dqXd19aPCsXRS0Ubi1MjPBAXC7Jt9ahfFWuPXjGuizXpeqOy0SXq/ib2AxDLQchPt4vD0+3iilRHV1UKUmFUL/eyRbk0BsSkkKdvvkt6u6VBWKASY+0kJSivfHU6mO42WK3AwYm97LZa2GI5mackAb8/396qXJ0qwQgJUBR2v7OxC3vjGQDHD1niIoLQNDocB87fslvm3kbVjJNDFoXlIYkMUSPX0eQ5RiXdBSv/mNk6fyRJYvBRBjAAKcc+XZeMW9n+NWuxpwTjDqpKN9FTthfR0lU8qVgHnZCghRxqyf1+2ldEOKpKt/CfPg5nRDXs19dGuJSFzbom2CvqQu9kvIU/0QuBwW1jsWBH0WeB71CnMhJPXre5rml0OJpGhxsDkMiQwnkYJEnCXdVCcMxOv+l+zaobA5CWsYU3AK5MmtWgeqgxAPn26ZZ4d8VRm5mPTFtAWsSE47+LGehQJwItYytirwtP/koz/26P8D7Te5tyHDeVqJIeK2CP6ZPzYLXCreDDFkc3+Ylv3YOvN53Cg00tBtAX7NLRQ5+G1cPMfh/QsiYWm3R/qhURZAxAZj3aFE1qhqHX7MJMXYa3aWuwuyts/X3yXOhVYPp5+e25dhj4deHYuiUvtEP/L4s21q5trUrYcfqGsfWXH8uyiwFIOfb73gsen4DIW1TQIEq6jhrSNUThBqpKN1BNuoko6QZqSmmobyNVrVwSkMM8+LghgnFKVEecdAWRUjrmau/Fal0rZCIQYVIWjupjkI4gpwO6/dWucd3RZvo6q+WmKWIN9k/oieZT17i0XbXCuhUnPsK83/SXT7ZAerYGDzWvgd0pN9AxIQKA4y/j4R3jUamCCqnp2RjctjC7Sbe7qjit09v31cfeszfxTIc4SJJkd7I+0wBk8fPtkavVI1AlR92qITYDEFvHyh+58kVdNZRPDU0x6Ci7TP+2nvg7O0rHHBqgxJu985M4XL1dOP7RcHPvKPBvE18JXzzZwpggwbIbVue6Efhzf/64ugEOumQWNcAyzVI4slsdAOYByIGJvdB08mqr15nuzXJyUWfjrRxZNLwtbudoEVYhP1uZaSDZqIZ3EqeQd5SOb1YqEYPbxiLx1DVsPH7V11WxEogc1JCuoaZ0reD/q6hR8HMN6Rqq4JbL4zCuiVBESPlP1RfrOuOoPhpVpFv4UdsLFxEBu7dupfxx8Q9DWxsnxQOAxjXCkKfVo2eDqja7OQW50YxvmU1o7tOtzFosAOBekwGWP/+vrfHnPo2q4fgV2y0gCrkMA1u7P+j648eaIS4iCHvH9zB2AbL35NV08j+ZTEKgKj+YsrxJ2TO+BwAUKYuVL7hyukaFBeL7oa1spiItCf46LcYjzWtg37mb6GGSUcdXT+rLOp91wfLQfhc82waz15zAe/2LPuDZ2efAdDC6ZXeth5rVQKBSjsY1w43LglRyZFlM2KgwCUDcac01DUCGdogDAPRsUBWbTlxFVFgAwgJtXytMAwOPjiGTScbgI3/bhes+fLSZx/ZDvscApBwb0bkWwgKVPghABEKRZTe4qCldRSXJeRrfbKHCRRGBS6ISLotKuIxKuCIq4qoIhxw67NA3wE0El9rWi+LqdlcVsy+zSQ82tAoSDB5oWt3m4Gx7XumRgO8T87s3RYao0aOB66kRX+pWByqFrFizBRu6cfVsUBXfPl2Y1tOVL8Ih7eMwb9sZqyxWlq8syRz3vnTPXUxj+dFjzSCEMDtfaldxPUUv+T/TgLI4t8edEiLRKSHS9f3aaHkpzlxIkiShTyPzbFkrXu5kNTjdNKlEp4QItIgJx7dbnE8Aa/rgydDNbFCbGFQPD0BTk6DHkun3hafCj/a1rVOum35GRWl/KkhmGICUcyXzdEogHJmIlq4iWkozCzAMQUeIlO10KxmiAi6KCFwQEbggInFRRBj/XRCRuIEQsIeoY6YXb3vpcP94sT1axNgOTOwJUSvwy//aYtaq45jSr5Fbr1UpZHipWx18tv4ksjU6Y7O/O+YNa4O/D6Q6bC2x1yOhamgADkzsZdWy4a/pY13lj7X35+5rhs/Ge480xpbkaxjSPs63FSKPMv38K914uFIS3LltvrtWZWD9SYdl4iKsg2XTFpD/da6F2WtOuLS/AKUcy/+vIySpcHZ0uUxy+qCiQ50Il7bvqj3je6BiBdvd3JrWDMP1rDzUNsk+RqWf/347lCK7d+/GxIkTsW3bNmg0GjRu3BijRo3CwIEDfV01p4p606VGHmoWBBjR0lXEmPxfU0pDqAsBxjURagwwLpoEGIZg4zas07L6u37NqmNZkutzfXhTaGDhx930z24r+OjZoCrWHMnPIvX5Ey3w0qJ9ZutlMglta1XG4hess8K46ujUPriUno1qoQHOC1uoFhaAEZ1rOS7k4Ny21a3K9IZlSTHeFwFTH2qEy+nZuKua//fZfrxNDB5vE+PrapRZvgqMFSafcUepcr3CjRaQDnUi8NOzd7vcImdo6TF9vxVU7t3aNaoR5ryQiWEd4izSeLv1cpsctTj/+WIHCJi38lDpxwCkmDZs2IDevXsjICAAjz/+OEJCQrBkyRI89thjOH/+PF5//XVfV9Ehex9oCXpUxc3C4EKWZhZsVJOc9y+9IsJxXlQpCDDyg4wLJq0YOSh7XVxmD2yG6Q83RsOJq0p0PzGVKhgTCPw9siMe+Cw/jfA9d1VBZLAazWLCjWXnPN4MqbdyzG4GnfV3b1wjzBiAWN6rV1B5Lo1wVFjJ3Ri4+1Vl2lpkr6saucY0gQCVc7xnhAtzsZoxJOxwR0KVYLvjPpb/X0fsOH0d+8/dcnsSVlvkFhFHSY+fKm4GM/JPDECKQavVYsSIEZDJZNi8eTOaNWsGAHjnnXfQpk0bjBs3DgMGDEBsrJ9+GeekIzz9CHrLdpm1YOR3m7oGteQ4RW+mCMB5UQXnRBWcF5EF/+f/fkFEIhf2s4aUVTKZ5NJg7pfvqYNPnDSzO6I1ydPeuGYYBrWJwYWbdzD36VZWF+t+zWpYvtwp0000iy68GW8QFYo/XiwdrQP3N4nCnHXJqGWju4ItpbwHFpFf4uB+x/OAeMrY++pDkoCHm1tnympUIwyNaoQZU6MXl2XXSl47qSgYgBTD+vXrcerUKQwbNswYfABAWFgYxo0bh6FDh2L+/Pl45513fFdJR+Y0Rdfsm+hqJ07QChkuighjcHGhILgwBBw3OQajyEbek4A6VUPwV1KqccK8r55qied/2uvS6+tWC0FqeuGkiDMeaezR+lVQKXBwUi/cztGiWlhhF6ngAIWxn7C3PXl3DBbuPIeHm7sWUNWtGoIdY7ujYpBrGZ9K+xgQotKuZsWS6Xbr6492iYYfBe8tLFCJGY8UZuqyFfN46jg82zHeMxuico0BSDFs3LgRANCrVy+rdb179wYAbNq0yZtVck/FOOTqJRzJrmTVgnFeVMElUcnns3aXVSqFDA82rY4Hm1ZH3FsrANj+coitXAFnr99BiFqB2lWCMbxTPDolRGLaiiPF2r9l3naDt++rj/XH0jCoTQwCVXKvpWt1xcQHGuL+xlFo4Ub3KNPgyRmGH0Se58pN74Jn22Dd0TQMK0gD62m25i0qKbZu/P01HXVRhVh8L/g6wKPSiQFIMSQnJwMAEhISrNZVq1YNwcHBxjJ+6ZnV2HDsOp7/aZ/zslRiGtcIw+HUdLSzkYJw05vdcPZ6FqLCAs3SHr7Rqx6OXMrAE22K1r1v0N0xOHgxHV3rmU/wN6JzLZuDu4PVCmTmatGlruvpKD1NpZChvYczr5hiP2Mi33A31a2rpj/cGN9uOY2JDzTw+Lbd4YsbdFv75BWO/AkDkGJIT08HkN/lypbQ0FBjGVtyc3ORm1s4a2pGhvXkcCVKoWK3Ex+wnH9i6UsdoNHpEaCUY96w1kg8eQ1hgUpj7vfYytZjGKqEBmD5/3Uqch3UCjk+GtjM5fKrX+uM7aeu44Gm1Z0XLqX4USDyPF9+rJ64OwZP3O3dDGe2riMDWtbE/G1n0O2uKtYri7s/d8qW0EWuqNvtWCcCW09e83BtqLRgAOJDM2bMwOTJk31aBwYgRVM1VI0rGbkIUsnx1eCWGPzdLkzo6/wp25N3x+Ddh8znzZDLJMhl+V0EutarYtUq4Q+qhweif0vrwY1lCQfLEpEnGa4oIQFKbHija4kEAP7Qu4tXTiqK8jlFtIcYWj7stXJkZGTYbR0BgLFjxyI9Pd347/z58yVST0eYV9u+bvXsdwlY+lIHPNU2BstGdkCnhEicee9+lwbmBasVJfYUioqHHwUiz2saHY5gtQJ3VQvxdVV8ytvXfZuD0EtoX0V9a5zZvHxjAFIMhrEftsZ5XL58GZmZmTbHhxio1WqEhoaa/fO28n4vXDnIfqrgVnGV7K6LCgvEuw81Rp0q7n2p8nLrvwxdNfo0rObjmhCVHQFKOfZN6IkVLxe9y2hp4u0B5259hZfQ931RW4/L2uB8cg8DkGLo0qULAGD16tVW61atWmVWxl+V9y5YHz/ezO664Z08n2rQG/ngqWhqVqyAo1P64MunWvi6KkRlikohK5et7f52tWc3U/InDECKoXv37qhVqxYWLVqEpKQk4/L09HRMnz4dKpUKTz/9tO8q6ILy+KVgylE8YJm68aOBTQEAjWoUvaXK3RlxybsCVXJ2kSOiMqlamLpIr2tcw35XcoA9KahoOAi9GBQKBebOnYvevXujc+fOePzxxxESEoIlS5bg7NmzmDVrFuLi4nxdTYd43bBWKyIIo/vcBSB/voxrmXkAgEda1MQDTatDXoyrLRtAiIjIU+pHuf5A7MWudXDxZjbuaxzl1j5+e64d6r/zr931WidP1iY90ACT/i7e3FVU9rAFpJi6deuGrVu3okOHDvj111/x5ZdfomrVqvjll1/w+uuv+7p6zpXzCMSyC9r3Q1th/Rtd0adR/jiArwe3QkylCvhmcEsAgFIuK9Z8ERx0R0RExfXXyA4Y1bOuW12Fg9QKfPx4c/Ryc5xboErucJJIrU7v8PVPt7P92goqTnRcnrEFxAPatGmDf/75x9fVKJKy3Cf07vhK2Jlyw2GZQFV+32RdwRMcy8mwWsZWxObR3TxWJ7aAEBGVDyX57dqkZjia1AwvwT2YqxoaYHddTKUKDl9rr9PAuPvq41J6DobYCVCobGMLCJVZHz3WDNUcXDSB/Awtm0d3Q5e6kfh6cEso5Z7/SLx9X32Pb5PIStl9lkBEPja4bSzaxFXC+Putv88kSXI4D5a9cXVRYYFY8XInDGwd7bF6UunBAKScK8uDx2qEB+ILJxmNIkPUqBEeiPnPtEHvEki/2qdhNYzoXMv4e71yngufShBb14iohASpFfjt+XYY3qmW88JELmAXrHKuDMcfAMy7PLWrVRnbT18HAMx9uhWyNTpUCXHcQlJUr/Woi7lbT2N0n3oAgL9HdsSO09cxsBWf9BARUdlS1u8lyPMYgJBX1Y4MwqmrWV7cY2EEolIUNvj1aFC1RPf6So8EjLynjjHNceOaYWhc03EqQ6Ji4R0Akc+FBSqNP4cEKB2UpLLcA4OcYxescs6bcx60iq3o9dlwTbMDvvNAA4QFKvFGr7pe2Xd5n2OFiKi8USlk2DO+B/aM72H20IuIzPHTUc558wmEQP6g7/iIIJfKz36safH3aRKA1I4Mxv4JPTHynoRib5fI73AMCJFfiAhWIyK4aJP+EZUXDEDKOW8+ozdkz9A4yRluUCnI/gV885uupcYVFnlvizOHBxERUWng6+cRNcIDfVwD8ncMQMjjdoztjmc6xGNMwWziAHDi3XvRPKYiAECrK96lsX3tyoipbDvveJDFxEbNYsJRIzwQbWtVKtY+ifweY2si8hMfP97M11UgP8cApJwriS5Y1cIC8M4DDcy6Wpn2ha0a5lrmKWdVe39AEzzbMR4hAYW5FAJV5nkV1Ao5Nr3ZFT+PaOvSPomIiKh4mkeHo3GNMPRtEgUA+GBAEwQq5Xi5e2EXaA5CL98YgJR77l8B5g1rXaw9fvJ4M3SrF+m0nMJJd6mBraIxoW8Dp+UUcplXB9sTERGVZwq5DH+N7IDPnsifi+vRVtH4b3JvdKwT4eOakb9gAEJuq+pkdnGDKDstHbGVg/DDsDaYN6y1w36i9sZrWMYSptmmHmxaHTIJ6H5XFZfqSERERMVj6xmf5YM/ZoYkU5wHpJwrSsOAo9e0iSsca9E0OhxT+zVEdCXb4zW61quCxLfuwSNfJGLfuVtW+3DWslFYtrBc5WAVjk7tA5WcsTUREZG/kjhwrVxjAEJuc3TRmPZwI7PfB7eLc749OxGN3RYQi/3LTV5fOzIYaoXc8iVERERE5Cf4mLicaxAV6lb5HvWrOGwBCVB65uZfgv0WkJe61TH73bRZt3fDkp3hnIiIiIqPQzPLNwYg5Zy7AcNHjzUrmYrYYKu/aK2IILSrXdlsmWm2LQ42JyIi8k+Wc3NR+cUAhNwSGqCEp68f9kIGhcz69KwYpLJa9sGjTXB/4yj8/nw7z1aMiIiIiDyOY0DIZfc3jnJaxpOD2quGWs+ELrdROCosEJ8/2cL9HRMREZFPsL9C+cYAhFyyf0JPhFdQAgAE7DeBeKoL1OzHmiG8ggpLXmgPtUKGvp9uBQDYaBQhIiIiolKEAQi5JLyC0qXgwlNPNPo1qwEAaBlb0Wy5rW5ZRERE5DsRwdY9FpzhmM3yjQEIucTVC0VJX0/speYlKu/4ySAiA2+P9b6vcRR2n7lh9dCQyB4GIGTlnruqoGbFQEx8oCFmrT6OigVdrwwcXdiKMrGQO6+R8y6LyCbmliEiX5HLJEzp18h5QaICDEDIygNNo/Bw85oAgDF97ir5HboRVMjZBYuIiKjU4/PE8o13c+Q2hy0gJXRF6VovEgAwrENcyeyAiIiIiLyCLSBkpSjdqApfWzK+G9IaV2/nolpYQAntgah049NEIjLg+G7ydwxAyG2maXj/eLE9ZJKEhz5PzF9QlHlATH5e/3oXVKxgPdmgXCYx+CBygGNAiMigNEw4ziCpfGMXLCqWxjXCEKyWG38v0iB0k5fUigy2Ods5EREREZUNDEDIbaZPVmSSBHb+IPI9fgqJqDThPCDlGwMQKhYJ+d2jjL/zekLkE6WgxwURlXO8TpEBAxCy4k4QIUlASEDhUCJ9ETqeFmfQOxERERGVLgxAyG2mMYYkSQgNUNovTERewTCeiIhKC2bBItSPCsXRSxlFfr1KIcOUfg1xO0eLKiHuZ6pity0iIiKi8oMBCOGX/7XF7pQbGP7jHpfK16kSDACooCrMfvV0u7iSqBoRERERlTEMQAhhgUr0aFDV+LuzzBSBKjn+m9wbCplnmi7YAkJEROQ5aiV72JN/YwBCRRKs5qlDRETkj57vXBubT1xFv2bVfV0VIpt4F0lWvN0gEW5j5nMiIiIqmrAKSqx4uZOvq0FkFwMQsuKprlWumti3Aa5n5mJw2ziv7peIiIi8pwiZ+qmMYgBCRiM6xSPp/C10r1/VeWEPqhIagF/+186r+yQiIiIi32AAQkZv39/A11UgIiKiMopJZ8iAaRKIiIiIqMSxCxYZMAAhIiIiIiKvYQBCRERERCWOXbDIgAEIEREREZU4dsEiAwYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIqAySO7iQiolKCAQgRURkgOLqTiPycAK9TlI8BCBEREREReQ0DECKiMoBdsIjI30ngdYryMQAhIiIiohLHLlhkwACEiKgM4BgQIiIqLRiAEBEREVGJYxcsMmAAQkRUBnAMCBH5O3bBIgMGIEREZQC7YBERUWnBAISIiIiIiLyGAQgRURnALlhERFRaMAAhIiIiIiKvYQBCRERERCWuUpDK11UgP6HwdQWIiIiIqOy7q1oo3r6vPqqFBfi6KuRjDECIiIiIyCtGdK7l6yqQH2AXLCIiIiIi8hoGIERERERE5DUMQIiIiIiIyGsYgBARERERkdcwACEiKgM4DyEREZUWDECIiMoAIXxdAyIiItcwACEiIiIiIq9hAEJERERERF7DAISIiIiIiLyGAUiBpKQkjBs3Dr1790ZkZCQkSULXrl2dvm7hwoVo06YNgoKCULFiRfTt2xf79u0r+QoTEREREZVCDEAKLF26FDNmzMDGjRtRrVo1l14zbdo0PPXUU0hLS8Pzzz+PRx99FJs3b0b79u2RmJhYwjUmIiIiIip9FL6ugL949NFH8eCDD6Jx48a4fv06oqKiHJZPTk7GpEmTULduXezatQthYWEAgBdffBFt27bFiBEj8N9//0EmY4xHRCWPaXiJiKi04N1xgYYNG6JFixZQKpUulf/hhx+g1Wrx9ttvG4MPAGjWrBkGDRqEo0ePYuvWrSVVXSIiM0zDS0REpQUDkCLauHEjAKBXr15W63r37g0A2LRpkzerRERERETk9xiAFFFycjKCg4NtjhdJSEgwliEi8gZ2wSIiotKCY0CKKD09HVWqVLG5LjQ01FjGkdzcXOTm5hp/z8jI8FwFiYiIiIj8UJkKQF5//XWzG3pnXnnlFWNrhS/MmDEDkydP9tn+iYiIiIi8rUwFIF9//TWysrJcLj9gwIAiByBhYWF2WzgMLRmmg9NtGTt2LEaNGmX2uujo6CLVh4iIiIioNChTAUhmZqbX9pWQkIDt27fj8uXLVuNADGM/nAU3arUaarW6xOpIRERERORvOAi9iLp06QIAWL16tdW6VatWmZUhIiIiIqJ8DECKaNiwYVAoFJg2bZpZV6ykpCT8/PPPqF+/Pjp27OjDGhJRefLt060QGqDAh4829XVViIiIHCpTXbCK49ixY3jvvfcAANnZ2cZlQ4cONZaZN2+e8ee6deti0qRJGD9+PJo2bYr+/fvj9u3b+OWXXwAA3377LWdBJyKvaR1XCUnv9IJMxny8RETk3yQhOH8ukD+xYLdu3RyWsXWoFi5ciI8//hiHDx+GSqVChw4dMHXqVLRo0cLtOmRkZBgHtxtS+RIRERGR/+D9WvExAPEjPKGJiIiI/Bvv14qPfYSIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxS+rgAVMkxKn5GR4eOaEBEREZEthvs0w30buY8BiB+5ffs2ACA6OtrHNSEiIiIiR27fvo2wsDBfV6NUkgTDN7+h1+uRmpqKkJAQSJJU4vvLyMhAdHQ0zp8/j9DQ0BLfX2nEY+Qcj5FzPEau4XFyjsfIOR4j53iMnHN0jIQQuH37NqpXrw6ZjKMZioItIH5EJpOhZs2aXt9vaGgoL0BO8Bg5x2PkHI+Ra3icnOMxco7HyDkeI+fsHSO2fBQPwzYiIiIiIvIaBiBEREREROQ1DEDKMbVajYkTJ0KtVvu6Kn6Lx8g5HiPneIxcw+PkHI+RczxGzvEYOcdjVLI4CJ2IiIiIiLyGLSBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBSDu3evRv33XcfwsPDERQUhLZt2+K3337zdbVKTFxcHCRJsvmva9euVuVzc3MxZcoUJCQkICAgANWrV8f//vc/pKWl2d3HwoUL0aZNGwQFBaFixYro27cv9u3bV4Lvqmh++uknPPfcc2jVqhXUajUkScK8efPsls/IyMCoUaMQGxsLtVqNuLg4vPnmm8jMzLRZXq/X49NPP0Xjxo0RGBiIyMhIDBo0CKdPn7a7j1WrVqFLly4ICQlBaGgounXrhnXr1hX3rRaZO8do0qRJds8tSZJw5swZm69z9z2fOHECAwcOREREBAIDA9G0aVN8+eWX8EUOkYsXL+Ljjz9Gr169EBMTA5VKhWrVqqF///7YuXOnzdeUt/PI3WNUHs8jAMjJycGoUaPQuXNnVK9eHQEBAahWrRo6dOiAH374ARqNxuo15e1ccvcYlddzydLMmTON73nHjh1W68vbeeSXBJUr69evF0qlUoSEhIgRI0aIUaNGidjYWAFAzJo1y9fVKxGxsbEiLCxMTJw40erfDz/8YFZWp9OJ3r17CwCibdu2YsyYMeKRRx4RkiSJWrVqibS0NKvtv/vuuwKAiI2NFaNGjRIjRowQISEhQq1Wi61bt3rpXbrG8LeOiIgw/mx5DAwyMzNFs2bNBADRq1cvMWbMGNGrVy8BQLRu3VpkZ2dbvWb48OECgGjYsKEYPXq0eOqpp4RKpRKVKlUSJ06csCq/YMECAUBERkaKkSNHipEjR4rIyEghSZL4/fffPf32XeLOMZo4caIAIIYMGWLz/Lp586bVa9x9z4cPHxZhYWFCpVKJp556SowePVo0bNhQABAjR4708Lt3bsyYMQKAqF27tnj22WfFW2+9Jfr37y/kcrmQyWTil19+MStfHs8jd49ReTyPhBDi6tWrIiAgQHTu3FkMHz5cjB07Vjz//PPGz12vXr2ETqczli+P55K7x6i8nkumDh06JNRqtQgKChIAxPbt283Wl8fzyB8xAClHNBqNqF27tlCr1WL//v3G5bdu3RJ169YVKpVKnDlzxncVLCGxsbEiNjbWpbLff/+9ACAGDRok9Hq9cfmXX34pAIj//e9/ZuVPnDghFAqFqFu3rrh165Zx+f79+4VarRb169c3+3LwtTVr1hj/xjNmzHB4c/3OO+8IAGLMmDFmyw03V9OnTzdbvn79egFAdO7cWeTm5hqXr1y50nihN3Xjxg0RHh4uIiIixPnz543Lz58/LyIiIkRERITIyMgoztstEneOkeHLfsOGDS5tuyjvuXPnzgKAWLlypXFZbm6u6NSpkwAgtm3b5t4bLKYlS5aIjRs3Wi3fvHmzUCqVomLFiiInJ8e4vDyeR+4eo/J4HgmR/8DH9G9soNFoRNeuXQUAsXz5cuPy8nguuXuMyuu5ZJCXlydatGgh7r77bvHUU0/ZDEDK43nkjxiAlCOrVq0SAMSwYcOs1s2bN08AEJMnT/ZBzUqWOwFIu3btBACrQEyv14tatWqJoKAgcefOHePysWPHCgBi/vz5VtsaOnSoACA2bdpUrPqXFEc313q9XlSvXl0EBweLzMxMs3WZmZkiODhY1KpVy2z5oEGD7L5fwxfl2bNnjcu+/vpru+fcpEmT7B5Xb/J0AOLuez5+/LgAILp162ZVfuPGjXY/z75ieIq4e/duIQTPI1ssj5EQPI9smTNnjgAgPv74YyEEzyVbLI+REDyXJk6cKNRqtTh8+LAYMmSIVQDC88h/cAxIObJx40YAQK9evazW9e7dGwCwadMmb1bJa3JzczFv3jxMnz4dn332mc1+2Dk5Odi5cyfq1auH2NhYs3WSJKFnz57IysrCnj17jMvL6jFNTk5GamoqOnTogKCgILN1QUFB6NChA06fPo3z588bl2/cuNG4zpKtY1GWjt3mzZsxc+ZMfPDBB1i6dKndfsTuvmdH5Tt27IigoCC/OkZKpRIAoFAoAPA8ssXyGJnieZRPr9fj33//BQA0atQIAM8lS7aOkanyeC7t27cP06ZNw8SJE9GgQQObZXge+Q/rKyCVWcnJyQCAhIQEq3XVqlVDcHCwsUxZc/nyZQwbNsxsWevWrfHzzz+jdu3aAIBTp05Br9fbPD5A4XFLTk5Gp06djD8HBwejWrVqDsuXNo7OFcPyVatWITk5GdHR0cjKysKlS5fQqFEjyOVym+VNt+tsH6Xt2E2cONHs9/DwcMyZMwdPP/202XJ337Oj8nK5HPHx8Thy5Ai0Wq3NG1pvOnfuHNauXYuoqCg0btwYAM8jS7aOkanyeh7l5eVh+vTpEELg+vXrWLduHY4dO4Zhw4ahe/fuAHguuXKMTJW3cyk3NxdPP/00mjVrhtGjR9stV97PI3/CFpByJD09HQAQFhZmc31oaKixTFkybNgwrFu3DleuXEFWVhb279+PwYMHY/fu3ejevTtu374NwLXjY1rO8LM75UsLd49FUY+dvdeUlmPXtGlTfP/99zh9+jSys7ORkpKCTz/9FJIkYejQofjrr7/Myrv7nl05rnq93ngO+4pGo8HgwYORm5uLmTNnGr+oeR4VsneMAJ5HeXl5mDx5MqZMmYLPP/8cx48fxxtvvIFvvvnGWKa8n0uuHCOg/J5L77zzDpKTk/HDDz/YDBQMyvt55E/YAkJlnuWToGbNmuHHH38EACxYsADffvstRo0a5YuqUSn38MMPm/0eFxeHkSNHon79+ujZsyfGjx+PBx980Ee18w69Xo+hQ4di8+bNGDFiBAYPHuzrKvkdZ8eovJ9HwcHBEEJAr9cjNTUVf//9N8aNG4ft27dj5cqVxpu28szVY1Qez6Xt27dj1qxZmDRpks3uaOSf2AJSjhiicXuRd0ZGht0ovyx67rnnAACJiYkAXDs+puUMP7tTvrRw91gU9djZe01pPnYA0L17d9SuXRuHDh0yvhfA/ffsynGVJAkhISEeq7s79Ho9nnnmGSxatAhPPfUUvvrqK7P1PI+cHyNHyst5ZCCTyVCzZk288MIL+Oabb5CYmIhp06YB4Llk4OgYOVJWzyWtVoshQ4agSZMmeOutt5yW53nkPxiAlCOO+h5evnwZmZmZdvtFlkUREREAgKysLABArVq1IJPJ7PbNtNWvMyEhAZmZmbh8+bJL5UsLZ/1ULd9bUFAQoqKikJKSAp1O57S8s32U5mNnYDi/7ty5Y1zm7nt2VF6n0yElJQXx8fE+6bev1+sxbNgwzJ8/H4MGDcK8efMgk5l/pZT388iVY+RMWT+P7DEM4DUM6C3v55ItlsfImbJ4LmVmZiI5ORlJSUlQqVRmky7Onz8fANCuXTtIkoSlS5fyPPIjDEDKkS5dugAAVq9ebbVu1apVZmXKA0MmrLi4OABAYGAg2rRpg+PHj+Ps2bNmZYUQWLNmDYKCgtCqVSvj8rJ6TBMSElC9enUkJiYaAzSDrKwsJCYmIj4+HtHR0cblXbp0Ma6zZDgWnTt3NisPlL1jB+Qfo8OHDyMoKMj4pQ+4/54dld+6dSuysrJ8cowMN9Y//vgjHnvsMSxYsMDuAM3yeh65eowcKevnkSOpqakACrOGledzyR7LY+RIWT2X1Go1nn32WZv/DDf5Dz74IJ599lnExcXxPPInPk0CTF6l0WhErVq1HE5EmJKS4rP6lYSjR4+KrKwsm8urVatmldvb3YkIjx8/XqomIjTlDxMRhoWF+fVkTY6OUUZGhjh+/LjV8jt37hjzxlvmwy/Ke3Y26VdiYmIx36V7dDqdMb/+o48+KjQajcPy5fE8cucYldfzSIj8GbVtXZ+zsrJEnz59BAAxbdo04/LyeC65c4zK87lki615QIQon+eRP2IAUs6sX79eKJVKERISIkaMGCFGjRolYmNjBQAxa9YsX1fP4yZOnChCQkLE/fffL1588UXx5ptvin79+gmlUikAiLFjx5qV1+l0onfv3gKAaNu2rRgzZozo37+/kCRJxMfHi7S0NKt9vPvuuwKAiI2NFaNGjRIjRowQISEhQq1Wi61bt3rrrbrk22+/FUOGDBFDhgwRLVq0EABEhw4djMu+/fZbY9nMzEzRtGlT4wX2rbfeMk6i1rp1a7MJGQ2GDx8uAIiGDRuK0aNHi8GDBwuVSiUqVapk84txwYIFAoCIjIwUI0eOFCNHjhSRkZFCkiTx22+/leixsMfVY5SSkiIkSRJt2rQRQ4YMEWPGjBFDhw4VNWvWFABE48aNxbVr16y27+57/u+//0RYWJhQqVRi8ODBYvTo0aJhw4YCgBg5cmSJHw9LhonOgoODxdtvvy0mTpxo9c/0AUd5PI/cOUbl9TwSovD6fO+994oXXnhBjBkzRjz11FOicuXKAoDo1KmT2flRXs8lV49ReT6XbLEXgJTH88gfMQAph3bu3Cn69OkjQkNDRWBgoGjTpo345ZdffF2tErFx40YxcOBAkZCQIEJDQ4VCoRDVqlUT/fr1E6tWrbL5mpycHDFp0iRRu3ZtoVKpRLVq1cTw4cPF5cuX7e7np59+Eq1atRKBgYEiLCxM3HfffWLv3r0l9baKzHBBtvdvyJAhZuVv3bolXn31VREdHS2USqWIiYkRr7/+ut2nNzqdTsyZM0c0bNhQqNVqUblyZfHYY4+JkydP2q3TP//8Izp16iSCgoJEcHCw6NKli1izZo0n37ZbXD1G6enp4qWXXhKtW7cWkZGRQqFQiJCQENGmTRvx/vvv2/wSM3D3PR87dkwMGDBAVKpUSajVatG4cWPx+eefm7XSeYuz42Orxai8nUfuHKPyeh4JIcTu3bvFiBEjRMOGDUV4eLhQKBSicuXKolu3buLrr7+22XJU3s4ld45ReT6XbLEXgAhR/s4jfyQJIYSjLlpERERERESewkHoRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBEREREReQ0DECIiIiIi8hoGIERERERE5DUMQIiIiIiIyGsYgBARERERkdcwACEiIiIiIq9hAEJERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhr/h/IDoeNzfYrXQAAAABJRU5ErkJggg==",
|
|
1056
|
+
"text/html": [
|
|
1057
|
+
"\n",
|
|
1058
|
+
" <div style=\"display: inline-block;\">\n",
|
|
1059
|
+
" <div class=\"jupyter-widgets widget-label\" style=\"text-align: center;\">\n",
|
|
1060
|
+
" Figure\n",
|
|
1061
|
+
" </div>\n",
|
|
1062
|
+
" <img src='data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAyAAAAGQCAYAAABWJQQ0AAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/SrBM8AAAACXBIWXMAAA9hAAAPYQGoP6dpAACFfklEQVR4nO3dd3gUVdsG8Hu2JqQCCRAgDQhI70gvUlUUFURREVB4bXwWVBAEaQKiKGIvqCCCDRQUUHoNvQSQGiDUAKEmJKRsOd8fyW62l2Szu0nu33VxkcycnTk7mZ2dZ845z5GEEAJEREREREReIPN1BYiIiIiIqPxgAEJERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBEREREReQ0DECIiIiIi8hoGIERERERE5DUMQIiIiIiIyGsYgBARERERkdcwACEiIiIiIq9hAEJERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBEREREReQ0DECIiIiIi8hoGIERERERE5DUKX1eACun1eqSmpiIkJASSJPm6OkRERERkQQiB27dvo3r16pDJ+Cy/KBiA+JHU1FRER0f7uhpERERE5MT58+dRs2ZNX1ejVGIA4kdCQkIA5J/QoaGhPq4NEREREVnKyMhAdHS08b6N3McAxI8Yul2FhoYyACEiIiLyY+wuX3TsuEZERERERF7DAISIiIiIiLyGAQgREREREXkNAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrmIaXiIiIqIBOp4NGo/F1NciL5HI5lEqlr6tRrjAAISIionJPCIHLly8jPT0dQghfV4e8TK1WIyIigvOw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ujrkZWq1GjVq1EBoaKivq1IuMAAhIiKick+SJERFRaFKlSrGsQBUPsjlcna78jIGIEREREQFDONBiKjkcBA6ERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIiIiIjIaxiAEBERERGR1zAAISIiIiIir2EAQkREREREXsMAhIiIiIiIvIYBCBFRGSCEr2tARETkGgYgRERERETkNQxAiIiIiIjIaxiAEBGVAZLk6xoQERG5hgEIEVEZwDEgRERUWjAAISIiIiIir2EAQkREREREXsMAhIioDOAYECIiKi0YgBARlQEcA0JERKUFAxAiIiIiIvIaBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMAAhIiIiIiKvYQBCRERERERewwCEiIiIiIi8hgEIERERERF5DQMQIiIiIiLyGgYgRERERETkNQxAiIjKAAHh6yoQERG5hAEIERERERF5DQMQIqIyQILk6yoQERG5hAEIERERERF5DQMQIqIygGNAiIiotGAAQkREREREXsMAhIioDOAYECIiKi0YgBARERERkdcwACEiKgM4BoSIiEoLBiBEREREROQ1DECIiIiIiMhrGIAQEREREZHXMACx8NNPP+G5555Dq1atoFarIUkS5s2bZ7d8RkYGRo0ahdjYWKjVasTFxeHNN99EZmam9ypNRERERFRKKHxdAX8zfvx4nD17FhEREYiKisLZs2ftls3KykKXLl2QlJSEXr16YdCgQdi/fz9mzZqFTZs2YfPmzQgICPBi7YmIiIiI/BtbQCzMnTsXZ86cwdWrV/H88887LPv+++8jKSkJY8aMwapVq/Dee+9h1apVGDNmDHbv3o3Zs2d7qdZERIWEYEYsIiLyXwxALPTo0QOxsbFOywkhMHfuXAQHB2PChAlm6yZMmIDg4GDMnTu3pKpJRERERFQqMQApouTkZKSmpqJDhw4ICgoyWxcUFIQOHTrg9OnTOH/+vI9qSERERETkfxiAFFFycjIAICEhweZ6w3JDOSIiIiIi4iD0IktPTwcAhIWF2VwfGhpqVs6W3Nxc5ObmGn/PyMjwYA2JiIiIiPwPW0B8aMaMGQgLCzP+i46O9nWViKgM4Bh0IvJ3By/cwpu/H0BaRo6vq0I+wACkiAwtH/ZaOAytGfZaSABg7NixSE9PN/7jeBEiIiIqDx78LBG/772A138/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' width=800.0/>\n",
|
|
1063
|
+
" </div>\n",
|
|
1064
|
+
" "
|
|
1065
|
+
],
|
|
1066
|
+
"text/plain": [
|
|
1067
|
+
"Canvas(toolbar=Toolbar(toolitems=[('Home', 'Reset original view', 'home', 'home'), ('Back', 'Back to previous …"
|
|
1068
|
+
]
|
|
1069
|
+
},
|
|
1070
|
+
"metadata": {},
|
|
1071
|
+
"output_type": "display_data"
|
|
1072
|
+
}
|
|
1073
|
+
],
|
|
1074
|
+
"source": [
|
|
1075
|
+
"recs = results.records\n",
|
|
1076
|
+
"idx = 0\n",
|
|
1077
|
+
"fig=plt.figure(1, figsize=(8,4), dpi= 100, facecolor='w', edgecolor='k')\n",
|
|
1078
|
+
"fline, = plt.plot(recs[idx].flux, label=f'flux')\n",
|
|
1079
|
+
"mline, = plt.plot(recs[idx].model, label=f'model')\n",
|
|
1080
|
+
"plt.legend(handles=[fline,mline])"
|
|
1081
|
+
]
|
|
1082
|
+
},
|
|
1083
|
+
{
|
|
1084
|
+
"cell_type": "markdown",
|
|
1085
|
+
"metadata": {
|
|
1086
|
+
"toc-hr-collapsed": true
|
|
1087
|
+
},
|
|
1088
|
+
"source": [
|
|
1089
|
+
"## Plot FLUX for all records"
|
|
1090
|
+
]
|
|
1091
|
+
},
|
|
1092
|
+
{
|
|
1093
|
+
"cell_type": "code",
|
|
1094
|
+
"execution_count": 22,
|
|
1095
|
+
"metadata": {
|
|
1096
|
+
"tags": []
|
|
1097
|
+
},
|
|
1098
|
+
"outputs": [
|
|
1099
|
+
{
|
|
1100
|
+
"name": "stdout",
|
|
1101
|
+
"output_type": "stream",
|
|
1102
|
+
"text": [
|
|
1103
|
+
"Ignoring unsupported feature: align_records\n"
|
|
1104
|
+
]
|
|
1105
|
+
}
|
|
1106
|
+
],
|
|
1107
|
+
"source": [
|
|
1108
|
+
"print('Ignoring unsupported feature: align_records')"
|
|
1109
|
+
]
|
|
1110
|
+
},
|
|
1111
|
+
{
|
|
1112
|
+
"cell_type": "code",
|
|
1113
|
+
"execution_count": 23,
|
|
1114
|
+
"metadata": {
|
|
1115
|
+
"tags": []
|
|
1116
|
+
},
|
|
1117
|
+
"outputs": [],
|
|
1118
|
+
"source": [
|
|
1119
|
+
"#import sparcl.gather_2d\n",
|
|
1120
|
+
"#ar_dict, grid = sparcl.gather_2d.align_records(results.records)\n",
|
|
1121
|
+
"#modeldf = pd.DataFrame(data=ar_dict['flux'],columns=grid)\n",
|
|
1122
|
+
"#modeldf.transpose().plot(xlabel='Wavelength', ylabel='Flux', legend=False)"
|
|
1123
|
+
]
|
|
1124
|
+
},
|
|
1125
|
+
{
|
|
1126
|
+
"cell_type": "markdown",
|
|
1127
|
+
"metadata": {},
|
|
1128
|
+
"source": [
|
|
1129
|
+
"# Authorization\n",
|
|
1130
|
+
"Your access to data is affected by how you login (or don't). Both `client.find` and `client.retrieve` allow you to request data (possibly implictly) from specific Datasets. Its possible for your combination of LOGIN and FIND (or RETIEVE) to work now, but fail later without you changing anything. For instance, if you don't login and ask for data from ALL Datasets at a time when all Datasets are public, your FIND will succeed. But if NOIRLab adds a new Dataset that is private, your same find will fail. To avoid the failure, you would have to explicitly request only the public Datasets, or to login as a user that is authorized to access the private Dataset.\n",
|
|
1131
|
+
"\n",
|
|
1132
|
+
"So summarize, there are three cases in which your FIND or RETRIEVE will be authorized:\n",
|
|
1133
|
+
"1. All Datasets are Public (does not matter what you login status is)\n",
|
|
1134
|
+
"2. You have explicitly requested only Public Datasets (does not matter what you login status is)\n",
|
|
1135
|
+
"3. You are logged in and are authorized to access all the Private Datasets you have (explicitly or implicitly) requested.\n",
|
|
1136
|
+
"\n",
|
|
1137
|
+
"You might be authorized to access one Dataset, but not another. So, you must be careful in case #3 above to explictly request the correct Private Dataset(s)."
|
|
1138
|
+
]
|
|
1139
|
+
},
|
|
1140
|
+
{
|
|
1141
|
+
"cell_type": "markdown",
|
|
1142
|
+
"metadata": {},
|
|
1143
|
+
"source": [
|
|
1144
|
+
"## Logging in and logging out"
|
|
1145
|
+
]
|
|
1146
|
+
},
|
|
1147
|
+
{
|
|
1148
|
+
"cell_type": "code",
|
|
1149
|
+
"execution_count": 24,
|
|
1150
|
+
"metadata": {
|
|
1151
|
+
"tags": []
|
|
1152
|
+
},
|
|
1153
|
+
"outputs": [],
|
|
1154
|
+
"source": [
|
|
1155
|
+
"if show_help:\n",
|
|
1156
|
+
" client.login?\n",
|
|
1157
|
+
" client.logout?"
|
|
1158
|
+
]
|
|
1159
|
+
},
|
|
1160
|
+
{
|
|
1161
|
+
"cell_type": "code",
|
|
1162
|
+
"execution_count": 25,
|
|
1163
|
+
"metadata": {
|
|
1164
|
+
"tags": []
|
|
1165
|
+
},
|
|
1166
|
+
"outputs": [
|
|
1167
|
+
{
|
|
1168
|
+
"name": "stdout",
|
|
1169
|
+
"output_type": "stream",
|
|
1170
|
+
"text": [
|
|
1171
|
+
"Logged in successfully with email='test_user_1@noirlab.edu'\n"
|
|
1172
|
+
]
|
|
1173
|
+
}
|
|
1174
|
+
],
|
|
1175
|
+
"source": [
|
|
1176
|
+
"client.login(auth_user, usrpw)"
|
|
1177
|
+
]
|
|
1178
|
+
},
|
|
1179
|
+
{
|
|
1180
|
+
"cell_type": "code",
|
|
1181
|
+
"execution_count": 26,
|
|
1182
|
+
"metadata": {
|
|
1183
|
+
"scrolled": true,
|
|
1184
|
+
"tags": []
|
|
1185
|
+
},
|
|
1186
|
+
"outputs": [
|
|
1187
|
+
{
|
|
1188
|
+
"data": {
|
|
1189
|
+
"text/plain": [
|
|
1190
|
+
"{'Loggedin_As': 'test_user_1@noirlab.edu',\n",
|
|
1191
|
+
" 'Authorized_Datasets': {'BOSS-DR16',\n",
|
|
1192
|
+
" 'DESI-EDR',\n",
|
|
1193
|
+
" 'SDSS-DR16',\n",
|
|
1194
|
+
" 'SDSS-DR17-test'}}"
|
|
1195
|
+
]
|
|
1196
|
+
},
|
|
1197
|
+
"execution_count": 26,
|
|
1198
|
+
"metadata": {},
|
|
1199
|
+
"output_type": "execute_result"
|
|
1200
|
+
}
|
|
1201
|
+
],
|
|
1202
|
+
"source": [
|
|
1203
|
+
"client.authorized"
|
|
1204
|
+
]
|
|
1205
|
+
},
|
|
1206
|
+
{
|
|
1207
|
+
"cell_type": "code",
|
|
1208
|
+
"execution_count": 27,
|
|
1209
|
+
"metadata": {
|
|
1210
|
+
"tags": []
|
|
1211
|
+
},
|
|
1212
|
+
"outputs": [
|
|
1213
|
+
{
|
|
1214
|
+
"name": "stdout",
|
|
1215
|
+
"output_type": "stream",
|
|
1216
|
+
"text": [
|
|
1217
|
+
"Logged-out successfully. Previously logged-in with email test_user_1@noirlab.edu.\n"
|
|
1218
|
+
]
|
|
1219
|
+
}
|
|
1220
|
+
],
|
|
1221
|
+
"source": [
|
|
1222
|
+
"client.logout() # can also be done with client.login(None)"
|
|
1223
|
+
]
|
|
1224
|
+
},
|
|
1225
|
+
{
|
|
1226
|
+
"cell_type": "code",
|
|
1227
|
+
"execution_count": 28,
|
|
1228
|
+
"metadata": {
|
|
1229
|
+
"tags": []
|
|
1230
|
+
},
|
|
1231
|
+
"outputs": [
|
|
1232
|
+
{
|
|
1233
|
+
"data": {
|
|
1234
|
+
"text/plain": [
|
|
1235
|
+
"{'Loggedin_As': 'Anonymous',\n",
|
|
1236
|
+
" 'Authorized_Datasets': {'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}}"
|
|
1237
|
+
]
|
|
1238
|
+
},
|
|
1239
|
+
"execution_count": 28,
|
|
1240
|
+
"metadata": {},
|
|
1241
|
+
"output_type": "execute_result"
|
|
1242
|
+
}
|
|
1243
|
+
],
|
|
1244
|
+
"source": [
|
|
1245
|
+
"client.authorized"
|
|
1246
|
+
]
|
|
1247
|
+
},
|
|
1248
|
+
{
|
|
1249
|
+
"cell_type": "markdown",
|
|
1250
|
+
"metadata": {},
|
|
1251
|
+
"source": [
|
|
1252
|
+
"## FIND"
|
|
1253
|
+
]
|
|
1254
|
+
},
|
|
1255
|
+
{
|
|
1256
|
+
"cell_type": "code",
|
|
1257
|
+
"execution_count": 29,
|
|
1258
|
+
"metadata": {},
|
|
1259
|
+
"outputs": [],
|
|
1260
|
+
"source": [
|
|
1261
|
+
"out = ['sparcl_id', 'data_release']\n",
|
|
1262
|
+
"\n",
|
|
1263
|
+
"def pass_find(user, drs):\n",
|
|
1264
|
+
" client.login(user, usrpw)\n",
|
|
1265
|
+
" print(f'{client.authorized=}')\n",
|
|
1266
|
+
" try:\n",
|
|
1267
|
+
" if drs is None:\n",
|
|
1268
|
+
" found = client.find(outfields=out, limit=2)\n",
|
|
1269
|
+
" else:\n",
|
|
1270
|
+
" found = client.find(outfields=out, constraints=dict(data_release=drs), limit=2)\n",
|
|
1271
|
+
" print(f'\\nSUCCESS: {found.count=} records from FIND: {user=}; {drs=}')\n",
|
|
1272
|
+
" except Exception as err:\n",
|
|
1273
|
+
" raise Exception(f'\\nFAILED to get records from FIND: {user=}; {drs=}')\n",
|
|
1274
|
+
"\n",
|
|
1275
|
+
"def fail_find(user, drs):\n",
|
|
1276
|
+
" client.login(user, usrpw)\n",
|
|
1277
|
+
" print(f'{client.authorized=}')\n",
|
|
1278
|
+
"\n",
|
|
1279
|
+
" try:\n",
|
|
1280
|
+
" found = client.find(outfields=out, constraints=dict(data_release=drs), limit=2)\n",
|
|
1281
|
+
" raise Exception(f'\\nFAILED: Auth wrongly got {found.count} records in FIND: {user=}; {drs=}')\n",
|
|
1282
|
+
" except Exception as err:\n",
|
|
1283
|
+
" print(f'\\nSUCCESS: Find did not get records. \\n{err}')"
|
|
1284
|
+
]
|
|
1285
|
+
},
|
|
1286
|
+
{
|
|
1287
|
+
"cell_type": "markdown",
|
|
1288
|
+
"metadata": {},
|
|
1289
|
+
"source": [
|
|
1290
|
+
"### Pass FIND as Authorized with Default DRs"
|
|
1291
|
+
]
|
|
1292
|
+
},
|
|
1293
|
+
{
|
|
1294
|
+
"cell_type": "code",
|
|
1295
|
+
"execution_count": 30,
|
|
1296
|
+
"metadata": {
|
|
1297
|
+
"tags": []
|
|
1298
|
+
},
|
|
1299
|
+
"outputs": [
|
|
1300
|
+
{
|
|
1301
|
+
"name": "stdout",
|
|
1302
|
+
"output_type": "stream",
|
|
1303
|
+
"text": [
|
|
1304
|
+
"Logged in successfully with email='test_user_1@noirlab.edu'\n",
|
|
1305
|
+
"client.authorized={'Loggedin_As': 'test_user_1@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16', 'SDSS-DR17-test'}}\n",
|
|
1306
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': []}\n",
|
|
1307
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1308
|
+
"Record key counts: {'data_release': 2, 'sparcl_id': 2, '_dr': 2}\n",
|
|
1309
|
+
"\n",
|
|
1310
|
+
"SUCCESS: found.count=2 records from FIND: user='test_user_1@noirlab.edu'; drs=None\n"
|
|
1311
|
+
]
|
|
1312
|
+
}
|
|
1313
|
+
],
|
|
1314
|
+
"source": [
|
|
1315
|
+
"pass_find(auth_user, None)"
|
|
1316
|
+
]
|
|
1317
|
+
},
|
|
1318
|
+
{
|
|
1319
|
+
"cell_type": "markdown",
|
|
1320
|
+
"metadata": {},
|
|
1321
|
+
"source": [
|
|
1322
|
+
"### Pass FIND as Authorized with Priv&Pub DRs"
|
|
1323
|
+
]
|
|
1324
|
+
},
|
|
1325
|
+
{
|
|
1326
|
+
"cell_type": "code",
|
|
1327
|
+
"execution_count": 31,
|
|
1328
|
+
"metadata": {
|
|
1329
|
+
"scrolled": true,
|
|
1330
|
+
"tags": []
|
|
1331
|
+
},
|
|
1332
|
+
"outputs": [
|
|
1333
|
+
{
|
|
1334
|
+
"name": "stdout",
|
|
1335
|
+
"output_type": "stream",
|
|
1336
|
+
"text": [
|
|
1337
|
+
"Logged in successfully with email='test_user_1@noirlab.edu'\n",
|
|
1338
|
+
"client.authorized={'Loggedin_As': 'test_user_1@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16', 'SDSS-DR17-test'}}\n",
|
|
1339
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'BOSS-DR16', 'SDSS-DR17-test']]}\n",
|
|
1340
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"BOSS-DR16\", \"SDSS-DR17-test\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1341
|
+
"Record key counts: {'data_release': 2, 'sparcl_id': 2, '_dr': 2}\n",
|
|
1342
|
+
"\n",
|
|
1343
|
+
"SUCCESS: found.count=2 records from FIND: user='test_user_1@noirlab.edu'; drs=['BOSS-DR16', 'SDSS-DR17-test']\n"
|
|
1344
|
+
]
|
|
1345
|
+
}
|
|
1346
|
+
],
|
|
1347
|
+
"source": [
|
|
1348
|
+
"pass_find(auth_user, [pub_dr,priv_dr])"
|
|
1349
|
+
]
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
"cell_type": "markdown",
|
|
1353
|
+
"metadata": {},
|
|
1354
|
+
"source": [
|
|
1355
|
+
"### Pass FIND as Unauthorized with Default DRs\n",
|
|
1356
|
+
"DRs default to only what are authorized for authenticated user."
|
|
1357
|
+
]
|
|
1358
|
+
},
|
|
1359
|
+
{
|
|
1360
|
+
"cell_type": "code",
|
|
1361
|
+
"execution_count": 32,
|
|
1362
|
+
"metadata": {
|
|
1363
|
+
"tags": []
|
|
1364
|
+
},
|
|
1365
|
+
"outputs": [
|
|
1366
|
+
{
|
|
1367
|
+
"name": "stdout",
|
|
1368
|
+
"output_type": "stream",
|
|
1369
|
+
"text": [
|
|
1370
|
+
"Logged in successfully with email='test_user_2@noirlab.edu'\n",
|
|
1371
|
+
"client.authorized={'Loggedin_As': 'test_user_2@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1372
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': []}\n",
|
|
1373
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1374
|
+
"Record key counts: {'data_release': 2, 'sparcl_id': 2, '_dr': 2}\n",
|
|
1375
|
+
"\n",
|
|
1376
|
+
"SUCCESS: found.count=2 records from FIND: user='test_user_2@noirlab.edu'; drs=None\n"
|
|
1377
|
+
]
|
|
1378
|
+
}
|
|
1379
|
+
],
|
|
1380
|
+
"source": [
|
|
1381
|
+
"pass_find(unauth_user, None)"
|
|
1382
|
+
]
|
|
1383
|
+
},
|
|
1384
|
+
{
|
|
1385
|
+
"cell_type": "markdown",
|
|
1386
|
+
"metadata": {},
|
|
1387
|
+
"source": [
|
|
1388
|
+
"### Fail FIND as Unauthorized with Priv&Pub DRs"
|
|
1389
|
+
]
|
|
1390
|
+
},
|
|
1391
|
+
{
|
|
1392
|
+
"cell_type": "code",
|
|
1393
|
+
"execution_count": 33,
|
|
1394
|
+
"metadata": {
|
|
1395
|
+
"tags": []
|
|
1396
|
+
},
|
|
1397
|
+
"outputs": [
|
|
1398
|
+
{
|
|
1399
|
+
"name": "stdout",
|
|
1400
|
+
"output_type": "stream",
|
|
1401
|
+
"text": [
|
|
1402
|
+
"Logged in successfully with email='test_user_2@noirlab.edu'\n",
|
|
1403
|
+
"client.authorized={'Loggedin_As': 'test_user_2@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1404
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'BOSS-DR16', 'SDSS-DR17-test']]}\n",
|
|
1405
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"BOSS-DR16\", \"SDSS-DR17-test\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1406
|
+
"Exception: response content=b'{\"errorMessage\": \"test_user_2@noirlab.edu is declined access to datasets [\\'SDSS-DR17-test\\']; drs_requested=[\\'BOSS-DR16\\', \\'SDSS-DR17-test\\'] my_auth=[\\'BOSS-DR16\\', \\'DESI-EDR\\', \\'SDSS-DR16\\']\", \"errorCode\": \"NODRACCESS\", \"statusCode\": 400, \"saved_tb\": \"NoneType: None\\\\n\"}'\n",
|
|
1407
|
+
"\n",
|
|
1408
|
+
"SUCCESS: Find did not get records. \n",
|
|
1409
|
+
"[UNKNOWN] test_user_2@noirlab.edu is declined access to datasets ['SDSS-DR17-test']; drs_requested=['BOSS-DR16', 'SDSS-DR17-test'] my_auth=['BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'] [NODRACCESS] None\n"
|
|
1410
|
+
]
|
|
1411
|
+
}
|
|
1412
|
+
],
|
|
1413
|
+
"source": [
|
|
1414
|
+
"fail_find(unauth_user, [pub_dr,priv_dr])"
|
|
1415
|
+
]
|
|
1416
|
+
},
|
|
1417
|
+
{
|
|
1418
|
+
"cell_type": "markdown",
|
|
1419
|
+
"metadata": {},
|
|
1420
|
+
"source": [
|
|
1421
|
+
"### Pass FIND as Unknown with Default DRs\n",
|
|
1422
|
+
"DRs default to only what are authorized for authenticated user."
|
|
1423
|
+
]
|
|
1424
|
+
},
|
|
1425
|
+
{
|
|
1426
|
+
"cell_type": "code",
|
|
1427
|
+
"execution_count": 34,
|
|
1428
|
+
"metadata": {
|
|
1429
|
+
"tags": []
|
|
1430
|
+
},
|
|
1431
|
+
"outputs": [
|
|
1432
|
+
{
|
|
1433
|
+
"name": "stdout",
|
|
1434
|
+
"output_type": "stream",
|
|
1435
|
+
"text": [
|
|
1436
|
+
"Logged in successfully with email='test_user_3@noirlab.edu'\n",
|
|
1437
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1438
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': []}\n",
|
|
1439
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1440
|
+
"Record key counts: {'data_release': 2, 'sparcl_id': 2, '_dr': 2}\n",
|
|
1441
|
+
"\n",
|
|
1442
|
+
"SUCCESS: found.count=2 records from FIND: user='test_user_3@noirlab.edu'; drs=None\n"
|
|
1443
|
+
]
|
|
1444
|
+
}
|
|
1445
|
+
],
|
|
1446
|
+
"source": [
|
|
1447
|
+
"pass_find(non_user, None)"
|
|
1448
|
+
]
|
|
1449
|
+
},
|
|
1450
|
+
{
|
|
1451
|
+
"cell_type": "markdown",
|
|
1452
|
+
"metadata": {},
|
|
1453
|
+
"source": [
|
|
1454
|
+
"### Fail FIND as Unknown with Priv&Pub DRs"
|
|
1455
|
+
]
|
|
1456
|
+
},
|
|
1457
|
+
{
|
|
1458
|
+
"cell_type": "code",
|
|
1459
|
+
"execution_count": 35,
|
|
1460
|
+
"metadata": {
|
|
1461
|
+
"tags": []
|
|
1462
|
+
},
|
|
1463
|
+
"outputs": [
|
|
1464
|
+
{
|
|
1465
|
+
"name": "stdout",
|
|
1466
|
+
"output_type": "stream",
|
|
1467
|
+
"text": [
|
|
1468
|
+
"Logged in successfully with email='test_user_3@noirlab.edu'\n",
|
|
1469
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1470
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'BOSS-DR16', 'SDSS-DR17-test']]}\n",
|
|
1471
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"BOSS-DR16\", \"SDSS-DR17-test\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1472
|
+
"Exception: response content=b'{\"errorMessage\": \"ANONYMOUS is declined access to datasets [\\'SDSS-DR17-test\\']; drs_requested=[\\'BOSS-DR16\\', \\'SDSS-DR17-test\\'] my_auth=[\\'BOSS-DR16\\', \\'DESI-EDR\\', \\'SDSS-DR16\\']\", \"errorCode\": \"NODRACCESS\", \"statusCode\": 400, \"saved_tb\": \"NoneType: None\\\\n\"}'\n",
|
|
1473
|
+
"\n",
|
|
1474
|
+
"SUCCESS: Find did not get records. \n",
|
|
1475
|
+
"[UNKNOWN] ANONYMOUS is declined access to datasets ['SDSS-DR17-test']; drs_requested=['BOSS-DR16', 'SDSS-DR17-test'] my_auth=['BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'] [NODRACCESS] None\n"
|
|
1476
|
+
]
|
|
1477
|
+
}
|
|
1478
|
+
],
|
|
1479
|
+
"source": [
|
|
1480
|
+
"fail_find(non_user, [pub_dr,priv_dr])"
|
|
1481
|
+
]
|
|
1482
|
+
},
|
|
1483
|
+
{
|
|
1484
|
+
"cell_type": "markdown",
|
|
1485
|
+
"metadata": {},
|
|
1486
|
+
"source": [
|
|
1487
|
+
"### Pass FIND as Anonymous with Default DR list \n",
|
|
1488
|
+
"DRs default to only what are authorized for authenticated user."
|
|
1489
|
+
]
|
|
1490
|
+
},
|
|
1491
|
+
{
|
|
1492
|
+
"cell_type": "code",
|
|
1493
|
+
"execution_count": 36,
|
|
1494
|
+
"metadata": {
|
|
1495
|
+
"tags": []
|
|
1496
|
+
},
|
|
1497
|
+
"outputs": [
|
|
1498
|
+
{
|
|
1499
|
+
"name": "stdout",
|
|
1500
|
+
"output_type": "stream",
|
|
1501
|
+
"text": [
|
|
1502
|
+
"Logged-out successfully. Previously logged-in with email test_user_3@noirlab.edu.\n",
|
|
1503
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1504
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': []}\n",
|
|
1505
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1506
|
+
"Record key counts: {'data_release': 2, 'sparcl_id': 2, '_dr': 2}\n",
|
|
1507
|
+
"\n",
|
|
1508
|
+
"SUCCESS: found.count=2 records from FIND: user=None; drs=None\n"
|
|
1509
|
+
]
|
|
1510
|
+
}
|
|
1511
|
+
],
|
|
1512
|
+
"source": [
|
|
1513
|
+
"pass_find(None, None)"
|
|
1514
|
+
]
|
|
1515
|
+
},
|
|
1516
|
+
{
|
|
1517
|
+
"cell_type": "markdown",
|
|
1518
|
+
"metadata": {},
|
|
1519
|
+
"source": [
|
|
1520
|
+
"### Pass FIND as Anonymous with Public DR"
|
|
1521
|
+
]
|
|
1522
|
+
},
|
|
1523
|
+
{
|
|
1524
|
+
"cell_type": "code",
|
|
1525
|
+
"execution_count": 37,
|
|
1526
|
+
"metadata": {
|
|
1527
|
+
"tags": []
|
|
1528
|
+
},
|
|
1529
|
+
"outputs": [
|
|
1530
|
+
{
|
|
1531
|
+
"name": "stdout",
|
|
1532
|
+
"output_type": "stream",
|
|
1533
|
+
"text": [
|
|
1534
|
+
"Logged-out successfully. Previously logged-in with email None.\n",
|
|
1535
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1536
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'BOSS-DR16']]}\n",
|
|
1537
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"BOSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1538
|
+
"Record key counts: {'data_release': 2, 'sparcl_id': 2, '_dr': 2}\n",
|
|
1539
|
+
"\n",
|
|
1540
|
+
"SUCCESS: found.count=2 records from FIND: user=None; drs=['BOSS-DR16']\n"
|
|
1541
|
+
]
|
|
1542
|
+
}
|
|
1543
|
+
],
|
|
1544
|
+
"source": [
|
|
1545
|
+
"pass_find(None, [pub_dr])"
|
|
1546
|
+
]
|
|
1547
|
+
},
|
|
1548
|
+
{
|
|
1549
|
+
"cell_type": "markdown",
|
|
1550
|
+
"metadata": {},
|
|
1551
|
+
"source": [
|
|
1552
|
+
"### Fail FIND as Anonymous with Priv&Pub DRs"
|
|
1553
|
+
]
|
|
1554
|
+
},
|
|
1555
|
+
{
|
|
1556
|
+
"cell_type": "code",
|
|
1557
|
+
"execution_count": 38,
|
|
1558
|
+
"metadata": {
|
|
1559
|
+
"scrolled": true,
|
|
1560
|
+
"tags": []
|
|
1561
|
+
},
|
|
1562
|
+
"outputs": [
|
|
1563
|
+
{
|
|
1564
|
+
"name": "stdout",
|
|
1565
|
+
"output_type": "stream",
|
|
1566
|
+
"text": [
|
|
1567
|
+
"Logged-out successfully. Previously logged-in with email None.\n",
|
|
1568
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1569
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'BOSS-DR16', 'SDSS-DR17-test']]}\n",
|
|
1570
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"BOSS-DR16\", \"SDSS-DR17-test\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1571
|
+
"Exception: response content=b'{\"errorMessage\": \"ANONYMOUS is declined access to datasets [\\'SDSS-DR17-test\\']; drs_requested=[\\'BOSS-DR16\\', \\'SDSS-DR17-test\\'] my_auth=[\\'BOSS-DR16\\', \\'DESI-EDR\\', \\'SDSS-DR16\\']\", \"errorCode\": \"NODRACCESS\", \"statusCode\": 400, \"saved_tb\": \"NoneType: None\\\\n\"}'\n",
|
|
1572
|
+
"\n",
|
|
1573
|
+
"SUCCESS: Find did not get records. \n",
|
|
1574
|
+
"[UNKNOWN] ANONYMOUS is declined access to datasets ['SDSS-DR17-test']; drs_requested=['BOSS-DR16', 'SDSS-DR17-test'] my_auth=['BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'] [NODRACCESS] None\n"
|
|
1575
|
+
]
|
|
1576
|
+
}
|
|
1577
|
+
],
|
|
1578
|
+
"source": [
|
|
1579
|
+
"fail_find(None, [pub_dr, priv_dr])"
|
|
1580
|
+
]
|
|
1581
|
+
},
|
|
1582
|
+
{
|
|
1583
|
+
"cell_type": "markdown",
|
|
1584
|
+
"metadata": {},
|
|
1585
|
+
"source": [
|
|
1586
|
+
"## RETRIEVE"
|
|
1587
|
+
]
|
|
1588
|
+
},
|
|
1589
|
+
{
|
|
1590
|
+
"cell_type": "code",
|
|
1591
|
+
"execution_count": 39,
|
|
1592
|
+
"metadata": {
|
|
1593
|
+
"scrolled": true
|
|
1594
|
+
},
|
|
1595
|
+
"outputs": [
|
|
1596
|
+
{
|
|
1597
|
+
"name": "stdout",
|
|
1598
|
+
"output_type": "stream",
|
|
1599
|
+
"text": [
|
|
1600
|
+
"client=(sparclclient:1.2.2b8, api:11.0, http://localhost:8050/sparc, client_hash=f7bd410278bee26a425387c598dd47e80a8fcdcb, verbose=True, connect_timeout=1.1, read_timeout=5400.0)\n"
|
|
1601
|
+
]
|
|
1602
|
+
}
|
|
1603
|
+
],
|
|
1604
|
+
"source": [
|
|
1605
|
+
"print(f'{client=}')\n",
|
|
1606
|
+
"inc = ['sparcl_id', 'data_release']\n",
|
|
1607
|
+
"\n",
|
|
1608
|
+
"#pub_ids = client.find(constraints=dict(data_release=[pub_dr]),limit=2).ids\n",
|
|
1609
|
+
"#print(f'{pub_ids=}')\n",
|
|
1610
|
+
"#priv_ids = client.find(constraints=dict(data_release=[priv_dr]),limit=2).ids\n",
|
|
1611
|
+
"#print(f'{priv_ids=}')\n",
|
|
1612
|
+
"\n",
|
|
1613
|
+
"def pass_retrieve(user, drs):\n",
|
|
1614
|
+
" client.login(user, usrpw)\n",
|
|
1615
|
+
" print(f'{client.authorized=}')\n",
|
|
1616
|
+
"\n",
|
|
1617
|
+
" if drs is None:\n",
|
|
1618
|
+
" ids = client.find(outfields=['sparcl_id'], limit=2).ids\n",
|
|
1619
|
+
" else:\n",
|
|
1620
|
+
" ids = client.find(outfields=['sparcl_id'], constraints=dict(data_release=drs), limit=2).ids\n",
|
|
1621
|
+
" try:\n",
|
|
1622
|
+
" if drs is None:\n",
|
|
1623
|
+
" got = client.retrieve(uuid_list=ids, include=inc, limit=2)\n",
|
|
1624
|
+
" else:\n",
|
|
1625
|
+
" got = client.retrieve(uuid_list=ids, include=inc, dataset_list=drs, limit=2)\n",
|
|
1626
|
+
" print(f'\\nSUCCESS: {got.count=} records from RETRIEVE: {user=}; {drs=}')\n",
|
|
1627
|
+
" except Exception as err:\n",
|
|
1628
|
+
" raise Exception(f'Auth wrongly refused records from RETRIEVE: {user=}; {drs=}')\n",
|
|
1629
|
+
"\n",
|
|
1630
|
+
"def fail_retrieve(user, drs):\n",
|
|
1631
|
+
" client.login(user, usrpw)\n",
|
|
1632
|
+
" print(f'{client.authorized=}')\n",
|
|
1633
|
+
"\n",
|
|
1634
|
+
" try:\n",
|
|
1635
|
+
" found = client.find(outfields=out, constraints=dict(data_release=drs), limit=2)\n",
|
|
1636
|
+
" raise Exception(f'Auth wrongly got {found.count} records in RETRIEVE: {user=}; {drs=}')\n",
|
|
1637
|
+
" except Exception as err:\n",
|
|
1638
|
+
" print(f'\\nSUCCESS: RETRIEVE did not get records. \\n{err}')"
|
|
1639
|
+
]
|
|
1640
|
+
},
|
|
1641
|
+
{
|
|
1642
|
+
"cell_type": "markdown",
|
|
1643
|
+
"metadata": {},
|
|
1644
|
+
"source": [
|
|
1645
|
+
"### Pass RETRIEVE as Auth with Default DRs"
|
|
1646
|
+
]
|
|
1647
|
+
},
|
|
1648
|
+
{
|
|
1649
|
+
"cell_type": "code",
|
|
1650
|
+
"execution_count": 40,
|
|
1651
|
+
"metadata": {
|
|
1652
|
+
"tags": []
|
|
1653
|
+
},
|
|
1654
|
+
"outputs": [
|
|
1655
|
+
{
|
|
1656
|
+
"name": "stdout",
|
|
1657
|
+
"output_type": "stream",
|
|
1658
|
+
"text": [
|
|
1659
|
+
"Logged in successfully with email='test_user_1@noirlab.edu'\n",
|
|
1660
|
+
"client.authorized={'Loggedin_As': 'test_user_1@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16', 'SDSS-DR17-test'}}\n",
|
|
1661
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id'], 'search': []}\n",
|
|
1662
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1663
|
+
"Record key counts: {'_dr': 2, 'sparcl_id': 2}\n",
|
|
1664
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl\"\n",
|
|
1665
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"000923d5-fe87-11ee-acd2-08002725f1ef\", \"0016db04-fe87-11ee-a58b-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl' | python3 -m json.tool\n",
|
|
1666
|
+
"Got response to post in 0.23809996293857694 seconds\n",
|
|
1667
|
+
"Got 2 spectra in 0.24 seconds (8 spectra/sec)\n",
|
|
1668
|
+
"{'success': True, 'info': [\"Successfully found 2 records in dr_list={'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}\"], 'warnings': []}\n",
|
|
1669
|
+
"\n",
|
|
1670
|
+
"SUCCESS: found.count=20 records from RETRIEVE: user='test_user_1@noirlab.edu'; drs=None\n"
|
|
1671
|
+
]
|
|
1672
|
+
}
|
|
1673
|
+
],
|
|
1674
|
+
"source": [
|
|
1675
|
+
"pass_retrieve(auth_user, None)"
|
|
1676
|
+
]
|
|
1677
|
+
},
|
|
1678
|
+
{
|
|
1679
|
+
"cell_type": "markdown",
|
|
1680
|
+
"metadata": {},
|
|
1681
|
+
"source": [
|
|
1682
|
+
"### Pass RETRIEVE as Auth with Priv&Pub DRs"
|
|
1683
|
+
]
|
|
1684
|
+
},
|
|
1685
|
+
{
|
|
1686
|
+
"cell_type": "code",
|
|
1687
|
+
"execution_count": 41,
|
|
1688
|
+
"metadata": {},
|
|
1689
|
+
"outputs": [
|
|
1690
|
+
{
|
|
1691
|
+
"name": "stdout",
|
|
1692
|
+
"output_type": "stream",
|
|
1693
|
+
"text": [
|
|
1694
|
+
"Logged in successfully with email='test_user_1@noirlab.edu'\n",
|
|
1695
|
+
"client.authorized={'Loggedin_As': 'test_user_1@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16', 'SDSS-DR17-test'}}\n",
|
|
1696
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id'], 'search': [['data_release', 'SDSS-DR17-test', 'BOSS-DR16']]}\n",
|
|
1697
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\"], \"search\": [[\"data_release\", \"SDSS-DR17-test\", \"BOSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1698
|
+
"Record key counts: {'_dr': 2, 'sparcl_id': 2}\n",
|
|
1699
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl&dataset_list=SDSS-DR17-test%2CBOSS-DR16\"\n",
|
|
1700
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"510760cd-fe87-11ee-8470-08002725f1ef\", \"5111ce02-fe87-11ee-bea1-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl&dataset_list=SDSS-DR17-test%2CBOSS-DR16' | python3 -m json.tool\n",
|
|
1701
|
+
"Got response to post in 0.27477827202528715 seconds\n",
|
|
1702
|
+
"Got 2 spectra in 0.27 seconds (7 spectra/sec)\n",
|
|
1703
|
+
"{'success': True, 'info': [\"Successfully found 2 records in dr_list=['SDSS-DR17-test', 'BOSS-DR16']\"], 'warnings': []}\n",
|
|
1704
|
+
"\n",
|
|
1705
|
+
"SUCCESS: found.count=20 records from RETRIEVE: user='test_user_1@noirlab.edu'; drs=['SDSS-DR17-test', 'BOSS-DR16']\n"
|
|
1706
|
+
]
|
|
1707
|
+
}
|
|
1708
|
+
],
|
|
1709
|
+
"source": [
|
|
1710
|
+
"pass_retrieve(auth_user, [priv_dr, pub_dr])"
|
|
1711
|
+
]
|
|
1712
|
+
},
|
|
1713
|
+
{
|
|
1714
|
+
"cell_type": "markdown",
|
|
1715
|
+
"metadata": {},
|
|
1716
|
+
"source": [
|
|
1717
|
+
"### Pass RETRIEVE as Unauth with Default DRs\n",
|
|
1718
|
+
"DRs default to only what are authorized for authenticated user."
|
|
1719
|
+
]
|
|
1720
|
+
},
|
|
1721
|
+
{
|
|
1722
|
+
"cell_type": "code",
|
|
1723
|
+
"execution_count": 42,
|
|
1724
|
+
"metadata": {
|
|
1725
|
+
"tags": []
|
|
1726
|
+
},
|
|
1727
|
+
"outputs": [
|
|
1728
|
+
{
|
|
1729
|
+
"name": "stdout",
|
|
1730
|
+
"output_type": "stream",
|
|
1731
|
+
"text": [
|
|
1732
|
+
"Logged in successfully with email='test_user_2@noirlab.edu'\n",
|
|
1733
|
+
"client.authorized={'Loggedin_As': 'test_user_2@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1734
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id'], 'search': []}\n",
|
|
1735
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1736
|
+
"Record key counts: {'_dr': 2, 'sparcl_id': 2}\n",
|
|
1737
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl\"\n",
|
|
1738
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"000923d5-fe87-11ee-acd2-08002725f1ef\", \"0016db04-fe87-11ee-a58b-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl' | python3 -m json.tool\n",
|
|
1739
|
+
"Got response to post in 0.26971720601432025 seconds\n",
|
|
1740
|
+
"Got 2 spectra in 0.27 seconds (7 spectra/sec)\n",
|
|
1741
|
+
"{'success': True, 'info': [\"Successfully found 2 records in dr_list={'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}\"], 'warnings': []}\n",
|
|
1742
|
+
"\n",
|
|
1743
|
+
"SUCCESS: found.count=20 records from RETRIEVE: user='test_user_2@noirlab.edu'; drs=None\n"
|
|
1744
|
+
]
|
|
1745
|
+
}
|
|
1746
|
+
],
|
|
1747
|
+
"source": [
|
|
1748
|
+
"try:\n",
|
|
1749
|
+
" pass_retrieve(unauth_user, None)\n",
|
|
1750
|
+
"except Exception as err:\n",
|
|
1751
|
+
" display(Markdown(f'#### BUG: {str(err)}'))"
|
|
1752
|
+
]
|
|
1753
|
+
},
|
|
1754
|
+
{
|
|
1755
|
+
"cell_type": "markdown",
|
|
1756
|
+
"metadata": {},
|
|
1757
|
+
"source": [
|
|
1758
|
+
"### Fail RETRIEVE as Unauth with Priv&Pub DRs"
|
|
1759
|
+
]
|
|
1760
|
+
},
|
|
1761
|
+
{
|
|
1762
|
+
"cell_type": "code",
|
|
1763
|
+
"execution_count": 43,
|
|
1764
|
+
"metadata": {
|
|
1765
|
+
"scrolled": true
|
|
1766
|
+
},
|
|
1767
|
+
"outputs": [
|
|
1768
|
+
{
|
|
1769
|
+
"name": "stdout",
|
|
1770
|
+
"output_type": "stream",
|
|
1771
|
+
"text": [
|
|
1772
|
+
"Logged in successfully with email='test_user_2@noirlab.edu'\n",
|
|
1773
|
+
"client.authorized={'Loggedin_As': 'test_user_2@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1774
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'SDSS-DR17-test', 'BOSS-DR16']]}\n",
|
|
1775
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"SDSS-DR17-test\", \"BOSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1776
|
+
"Exception: response content=b'{\"errorMessage\": \"test_user_2@noirlab.edu is declined access to datasets [\\'SDSS-DR17-test\\']; drs_requested=[\\'BOSS-DR16\\', \\'SDSS-DR17-test\\'] my_auth=[\\'BOSS-DR16\\', \\'DESI-EDR\\', \\'SDSS-DR16\\']\", \"errorCode\": \"NODRACCESS\", \"statusCode\": 400, \"saved_tb\": \"NoneType: None\\\\n\"}'\n",
|
|
1777
|
+
"\n",
|
|
1778
|
+
"SUCCESS: RETRIEVE did not get records. \n",
|
|
1779
|
+
"[UNKNOWN] test_user_2@noirlab.edu is declined access to datasets ['SDSS-DR17-test']; drs_requested=['BOSS-DR16', 'SDSS-DR17-test'] my_auth=['BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'] [NODRACCESS] None\n"
|
|
1780
|
+
]
|
|
1781
|
+
}
|
|
1782
|
+
],
|
|
1783
|
+
"source": [
|
|
1784
|
+
"fail_retrieve(unauth_user, [priv_dr, pub_dr])"
|
|
1785
|
+
]
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
"cell_type": "markdown",
|
|
1789
|
+
"metadata": {},
|
|
1790
|
+
"source": [
|
|
1791
|
+
"### Pass RETRIEVE as Unknown with Default DRs\n",
|
|
1792
|
+
"DRs default to only what are authorized for authenticated user."
|
|
1793
|
+
]
|
|
1794
|
+
},
|
|
1795
|
+
{
|
|
1796
|
+
"cell_type": "code",
|
|
1797
|
+
"execution_count": 44,
|
|
1798
|
+
"metadata": {
|
|
1799
|
+
"tags": []
|
|
1800
|
+
},
|
|
1801
|
+
"outputs": [
|
|
1802
|
+
{
|
|
1803
|
+
"name": "stdout",
|
|
1804
|
+
"output_type": "stream",
|
|
1805
|
+
"text": [
|
|
1806
|
+
"Logged in successfully with email='test_user_3@noirlab.edu'\n",
|
|
1807
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1808
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id'], 'search': []}\n",
|
|
1809
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1810
|
+
"Record key counts: {'_dr': 2, 'sparcl_id': 2}\n",
|
|
1811
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl\"\n",
|
|
1812
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"000923d5-fe87-11ee-acd2-08002725f1ef\", \"0016db04-fe87-11ee-a58b-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl' | python3 -m json.tool\n",
|
|
1813
|
+
"Got response to post in 0.3079184840898961 seconds\n",
|
|
1814
|
+
"Got 2 spectra in 0.31 seconds (6 spectra/sec)\n",
|
|
1815
|
+
"{'success': True, 'info': [\"Successfully found 2 records in dr_list={'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}\"], 'warnings': []}\n",
|
|
1816
|
+
"\n",
|
|
1817
|
+
"SUCCESS: found.count=20 records from RETRIEVE: user='test_user_3@noirlab.edu'; drs=None\n"
|
|
1818
|
+
]
|
|
1819
|
+
}
|
|
1820
|
+
],
|
|
1821
|
+
"source": [
|
|
1822
|
+
"try:\n",
|
|
1823
|
+
" pass_retrieve(non_user, None)\n",
|
|
1824
|
+
"except Exception as err:\n",
|
|
1825
|
+
" display(Markdown(f'#### BUG: {str(err)}'))"
|
|
1826
|
+
]
|
|
1827
|
+
},
|
|
1828
|
+
{
|
|
1829
|
+
"cell_type": "markdown",
|
|
1830
|
+
"metadata": {},
|
|
1831
|
+
"source": [
|
|
1832
|
+
"### Fail RETRIEVE as Unknown with Priv&Pub DRs"
|
|
1833
|
+
]
|
|
1834
|
+
},
|
|
1835
|
+
{
|
|
1836
|
+
"cell_type": "code",
|
|
1837
|
+
"execution_count": 45,
|
|
1838
|
+
"metadata": {
|
|
1839
|
+
"scrolled": true
|
|
1840
|
+
},
|
|
1841
|
+
"outputs": [
|
|
1842
|
+
{
|
|
1843
|
+
"name": "stdout",
|
|
1844
|
+
"output_type": "stream",
|
|
1845
|
+
"text": [
|
|
1846
|
+
"Logged in successfully with email='test_user_3@noirlab.edu'\n",
|
|
1847
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1848
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'SDSS-DR17-test', 'BOSS-DR16']]}\n",
|
|
1849
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"SDSS-DR17-test\", \"BOSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1850
|
+
"Exception: response content=b'{\"errorMessage\": \"ANONYMOUS is declined access to datasets [\\'SDSS-DR17-test\\']; drs_requested=[\\'BOSS-DR16\\', \\'SDSS-DR17-test\\'] my_auth=[\\'BOSS-DR16\\', \\'DESI-EDR\\', \\'SDSS-DR16\\']\", \"errorCode\": \"NODRACCESS\", \"statusCode\": 400, \"saved_tb\": \"NoneType: None\\\\n\"}'\n",
|
|
1851
|
+
"\n",
|
|
1852
|
+
"SUCCESS: RETRIEVE did not get records. \n",
|
|
1853
|
+
"[UNKNOWN] ANONYMOUS is declined access to datasets ['SDSS-DR17-test']; drs_requested=['BOSS-DR16', 'SDSS-DR17-test'] my_auth=['BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'] [NODRACCESS] None\n"
|
|
1854
|
+
]
|
|
1855
|
+
}
|
|
1856
|
+
],
|
|
1857
|
+
"source": [
|
|
1858
|
+
"fail_retrieve(non_user, [priv_dr, pub_dr])"
|
|
1859
|
+
]
|
|
1860
|
+
},
|
|
1861
|
+
{
|
|
1862
|
+
"cell_type": "markdown",
|
|
1863
|
+
"metadata": {},
|
|
1864
|
+
"source": [
|
|
1865
|
+
"### Pass RETRIEVE as Anon with Default DRs\n",
|
|
1866
|
+
"DRs default to only what are authorized for authenticated user."
|
|
1867
|
+
]
|
|
1868
|
+
},
|
|
1869
|
+
{
|
|
1870
|
+
"cell_type": "code",
|
|
1871
|
+
"execution_count": 46,
|
|
1872
|
+
"metadata": {
|
|
1873
|
+
"tags": []
|
|
1874
|
+
},
|
|
1875
|
+
"outputs": [
|
|
1876
|
+
{
|
|
1877
|
+
"name": "stdout",
|
|
1878
|
+
"output_type": "stream",
|
|
1879
|
+
"text": [
|
|
1880
|
+
"Logged-out successfully. Previously logged-in with email test_user_3@noirlab.edu.\n",
|
|
1881
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1882
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id'], 'search': []}\n",
|
|
1883
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\"], \"search\": []}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1884
|
+
"Record key counts: {'_dr': 2, 'sparcl_id': 2}\n",
|
|
1885
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl\"\n",
|
|
1886
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"000923d5-fe87-11ee-acd2-08002725f1ef\", \"0016db04-fe87-11ee-a58b-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl' | python3 -m json.tool\n",
|
|
1887
|
+
"Got response to post in 0.03403094399254769 seconds\n",
|
|
1888
|
+
"Got 2 spectra in 0.03 seconds (59 spectra/sec)\n",
|
|
1889
|
+
"{'success': True, 'info': [\"Successfully found 2 records in dr_list={'BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'}\"], 'warnings': []}\n",
|
|
1890
|
+
"\n",
|
|
1891
|
+
"SUCCESS: found.count=20 records from RETRIEVE: user=None; drs=None\n"
|
|
1892
|
+
]
|
|
1893
|
+
}
|
|
1894
|
+
],
|
|
1895
|
+
"source": [
|
|
1896
|
+
"try:\n",
|
|
1897
|
+
" pass_retrieve(None, None)\n",
|
|
1898
|
+
"except Exception as err:\n",
|
|
1899
|
+
" display(Markdown(f'#### BUG: {str(err)}'))"
|
|
1900
|
+
]
|
|
1901
|
+
},
|
|
1902
|
+
{
|
|
1903
|
+
"cell_type": "markdown",
|
|
1904
|
+
"metadata": {},
|
|
1905
|
+
"source": [
|
|
1906
|
+
"### Fail RETRIEVE as Anon with Priv&Pub DR "
|
|
1907
|
+
]
|
|
1908
|
+
},
|
|
1909
|
+
{
|
|
1910
|
+
"cell_type": "code",
|
|
1911
|
+
"execution_count": 47,
|
|
1912
|
+
"metadata": {
|
|
1913
|
+
"tags": []
|
|
1914
|
+
},
|
|
1915
|
+
"outputs": [
|
|
1916
|
+
{
|
|
1917
|
+
"name": "stdout",
|
|
1918
|
+
"output_type": "stream",
|
|
1919
|
+
"text": [
|
|
1920
|
+
"Logged-out successfully. Previously logged-in with email None.\n",
|
|
1921
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1922
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id', 'data_release'], 'search': [['data_release', 'SDSS-DR17-test', 'BOSS-DR16']]}\n",
|
|
1923
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\", \"data_release\"], \"search\": [[\"data_release\", \"SDSS-DR17-test\", \"BOSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1924
|
+
"Exception: response content=b'{\"errorMessage\": \"ANONYMOUS is declined access to datasets [\\'SDSS-DR17-test\\']; drs_requested=[\\'BOSS-DR16\\', \\'SDSS-DR17-test\\'] my_auth=[\\'BOSS-DR16\\', \\'DESI-EDR\\', \\'SDSS-DR16\\']\", \"errorCode\": \"NODRACCESS\", \"statusCode\": 400, \"saved_tb\": \"NoneType: None\\\\n\"}'\n",
|
|
1925
|
+
"\n",
|
|
1926
|
+
"SUCCESS: RETRIEVE did not get records. \n",
|
|
1927
|
+
"[UNKNOWN] ANONYMOUS is declined access to datasets ['SDSS-DR17-test']; drs_requested=['BOSS-DR16', 'SDSS-DR17-test'] my_auth=['BOSS-DR16', 'DESI-EDR', 'SDSS-DR16'] [NODRACCESS] None\n"
|
|
1928
|
+
]
|
|
1929
|
+
}
|
|
1930
|
+
],
|
|
1931
|
+
"source": [
|
|
1932
|
+
"fail_retrieve(None, [priv_dr, pub_dr])"
|
|
1933
|
+
]
|
|
1934
|
+
},
|
|
1935
|
+
{
|
|
1936
|
+
"cell_type": "markdown",
|
|
1937
|
+
"metadata": {},
|
|
1938
|
+
"source": [
|
|
1939
|
+
"### Pass RETRIEVE as Anon with Public DR "
|
|
1940
|
+
]
|
|
1941
|
+
},
|
|
1942
|
+
{
|
|
1943
|
+
"cell_type": "code",
|
|
1944
|
+
"execution_count": 48,
|
|
1945
|
+
"metadata": {
|
|
1946
|
+
"tags": []
|
|
1947
|
+
},
|
|
1948
|
+
"outputs": [
|
|
1949
|
+
{
|
|
1950
|
+
"name": "stdout",
|
|
1951
|
+
"output_type": "stream",
|
|
1952
|
+
"text": [
|
|
1953
|
+
"Logged-out successfully. Previously logged-in with email None.\n",
|
|
1954
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n",
|
|
1955
|
+
"url=http://localhost:8050/sparc/find/?limit=2 sspec={'outfields': ['sparcl_id'], 'search': [['data_release', 'BOSS-DR16']]}\n",
|
|
1956
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '{\"outfields\": [\"sparcl_id\"], \"search\": [[\"data_release\", \"BOSS-DR16\"]]}' 'http://localhost:8050/sparc/find/?limit=2' | python3 -m json.tool\n",
|
|
1957
|
+
"Record key counts: {'_dr': 2, 'sparcl_id': 2}\n",
|
|
1958
|
+
"Using url=\"http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl&dataset_list=BOSS-DR16\"\n",
|
|
1959
|
+
"curl -X 'POST' -H 'Content-Type: application/json' -d '[\"510760cd-fe87-11ee-8470-08002725f1ef\", \"5111ce02-fe87-11ee-bea1-08002725f1ef\"]' 'http://localhost:8050/sparc/spectras/?include=data_release%2Csparcl_id&format=pkl&dataset_list=BOSS-DR16' | python3 -m json.tool\n",
|
|
1960
|
+
"Got response to post in 0.0383652689633891 seconds\n",
|
|
1961
|
+
"Got 2 spectra in 0.04 seconds (52 spectra/sec)\n",
|
|
1962
|
+
"{'success': True, 'info': [\"Successfully found 2 records in dr_list=['BOSS-DR16']\"], 'warnings': []}\n",
|
|
1963
|
+
"\n",
|
|
1964
|
+
"SUCCESS: found.count=20 records from RETRIEVE: user=None; drs=['BOSS-DR16']\n"
|
|
1965
|
+
]
|
|
1966
|
+
}
|
|
1967
|
+
],
|
|
1968
|
+
"source": [
|
|
1969
|
+
"pass_retrieve(None, [pub_dr])"
|
|
1970
|
+
]
|
|
1971
|
+
},
|
|
1972
|
+
{
|
|
1973
|
+
"cell_type": "markdown",
|
|
1974
|
+
"metadata": {},
|
|
1975
|
+
"source": [
|
|
1976
|
+
"# All Done"
|
|
1977
|
+
]
|
|
1978
|
+
},
|
|
1979
|
+
{
|
|
1980
|
+
"cell_type": "code",
|
|
1981
|
+
"execution_count": 49,
|
|
1982
|
+
"metadata": {
|
|
1983
|
+
"tags": []
|
|
1984
|
+
},
|
|
1985
|
+
"outputs": [
|
|
1986
|
+
{
|
|
1987
|
+
"name": "stdout",
|
|
1988
|
+
"output_type": "stream",
|
|
1989
|
+
"text": [
|
|
1990
|
+
"Run finished: 2024-05-02 10:22:39.403970\n"
|
|
1991
|
+
]
|
|
1992
|
+
}
|
|
1993
|
+
],
|
|
1994
|
+
"source": [
|
|
1995
|
+
"print(f'Run finished: {str(datetime.now())}')"
|
|
1996
|
+
]
|
|
1997
|
+
},
|
|
1998
|
+
{
|
|
1999
|
+
"cell_type": "code",
|
|
2000
|
+
"execution_count": 50,
|
|
2001
|
+
"metadata": {
|
|
2002
|
+
"tags": []
|
|
2003
|
+
},
|
|
2004
|
+
"outputs": [
|
|
2005
|
+
{
|
|
2006
|
+
"name": "stdout",
|
|
2007
|
+
"output_type": "stream",
|
|
2008
|
+
"text": [
|
|
2009
|
+
"Logged in successfully with email='test_user_1@noirlab.edu'\n",
|
|
2010
|
+
"\n",
|
|
2011
|
+
"client.authorized={'Loggedin_As': 'test_user_1@noirlab.edu', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16', 'SDSS-DR17-test'}}\n",
|
|
2012
|
+
"\n",
|
|
2013
|
+
"\n",
|
|
2014
|
+
"Logged-out successfully. Previously logged-in with email test_user_1@noirlab.edu.\n",
|
|
2015
|
+
"\n",
|
|
2016
|
+
"client.authorized={'Loggedin_As': 'Anonymous', 'Authorized_Datasets': {'SDSS-DR16', 'DESI-EDR', 'BOSS-DR16'}}\n"
|
|
2017
|
+
]
|
|
2018
|
+
}
|
|
2019
|
+
],
|
|
2020
|
+
"source": [
|
|
2021
|
+
"# DLS-496\n",
|
|
2022
|
+
"client.login(auth_user, usrpw)\n",
|
|
2023
|
+
"print(f'\\n{client.authorized=}\\n\\n')\n",
|
|
2024
|
+
"client.logout() # can also be done with client.login(None)\n",
|
|
2025
|
+
"print(f'\\n{client.authorized=}')"
|
|
2026
|
+
]
|
|
2027
|
+
}
|
|
2028
|
+
],
|
|
2029
|
+
"metadata": {
|
|
2030
|
+
"kernelspec": {
|
|
2031
|
+
"display_name": "Python 3 (ipykernel)",
|
|
2032
|
+
"language": "python",
|
|
2033
|
+
"name": "python3"
|
|
2034
|
+
},
|
|
2035
|
+
"language_info": {
|
|
2036
|
+
"codemirror_mode": {
|
|
2037
|
+
"name": "ipython",
|
|
2038
|
+
"version": 3
|
|
2039
|
+
},
|
|
2040
|
+
"file_extension": ".py",
|
|
2041
|
+
"mimetype": "text/x-python",
|
|
2042
|
+
"name": "python",
|
|
2043
|
+
"nbconvert_exporter": "python",
|
|
2044
|
+
"pygments_lexer": "ipython3",
|
|
2045
|
+
"version": "3.10.12"
|
|
2046
|
+
},
|
|
2047
|
+
"toc": {
|
|
2048
|
+
"base_numbering": 1
|
|
2049
|
+
},
|
|
2050
|
+
"toc-showmarkdowntxt": false
|
|
2051
|
+
},
|
|
2052
|
+
"nbformat": 4,
|
|
2053
|
+
"nbformat_minor": 4
|
|
2054
|
+
}
|