pyucalgarysrs 1.0.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,80 @@
1
+ # Copyright 2024 University of Calgary
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """
15
+ The PyUCalgarySRS library provides a way to interact with the UCalgary Space
16
+ Remote Sensing (SRS) Open Data Platform. It enables users to programmatically
17
+ download and read data, and utilize the TREx Auroral Transport Model (ATM).
18
+ This library leverages the UCalgary SRS API for some functions.
19
+
20
+ For more information about the data available and usage examples, visit the
21
+ [Open Data Platform website](https://data.phys.ucalgary.ca).
22
+
23
+ Installation:
24
+ ```console
25
+ $ pip install pyucalgarysrs
26
+ ```
27
+
28
+ Basic usage:
29
+ ```python
30
+ > import pyucalgarysrs
31
+ > srs = pyucalgarysrs.PyUCalgarySRS()
32
+ ```
33
+ """
34
+
35
+ # versioning info
36
+ __version__ = "1.0.0"
37
+
38
+ # documentation
39
+ __pdoc__ = {"pyucalgarysrs": False}
40
+ __all__ = ["PyUCalgarySRS"]
41
+
42
+ # pull in top level class
43
+ from .pyucalgarysrs import PyUCalgarySRS
44
+
45
+ # pull in exceptions
46
+ from .exceptions import (
47
+ SRSError,
48
+ SRSInitializationError,
49
+ SRSPurgeError,
50
+ SRSAPIError,
51
+ SRSUnsupportedReadError,
52
+ SRSDownloadError,
53
+ )
54
+
55
+ # pull in schemas
56
+ from .data.classes import (
57
+ Dataset,
58
+ FileListingResponse,
59
+ FileDownloadResult,
60
+ Calibration,
61
+ CalibrationGenerationInfo,
62
+ Data,
63
+ Skymap,
64
+ SkymapGenerationInfo,
65
+ ProblematicFile,
66
+ Observatory,
67
+ )
68
+ from .models.atm.classes_forward import (
69
+ ATMForwardOutputFlags,
70
+ ATMForwardRequest,
71
+ ATMForwardResult,
72
+ ATMForwardResultRequestInfo,
73
+ )
74
+ from .models.atm.classes_inverse import (
75
+ ATMInverseForwardParams,
76
+ ATMInverseOutputFlags,
77
+ ATMInverseRequest,
78
+ ATMInverseResult,
79
+ ATMInverseResultRequestInfo,
80
+ )
@@ -0,0 +1,487 @@
1
+ # Copyright 2024 University of Calgary
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+ """
15
+ Provides capabilities for downloading and reading data from the UCalgary Space Remote
16
+ Sensing Open Data Platform.
17
+ """
18
+
19
+ import datetime
20
+ from typing import List, Optional, Union
21
+ from . import _list as module_list
22
+ from . import _download as module_download
23
+ from .read import ReadManager
24
+ from .classes import *
25
+
26
+
27
+ class DataManager:
28
+ """
29
+ The DataManager object is initialized within every PyUCalgarySRS object. It acts
30
+ as a way to access the submodules and carry over configuration information in the
31
+ super class.
32
+ """
33
+
34
+ __DEFAULT_DOWNLOAD_N_PARALLEL = 5
35
+
36
+ def __init__(self, srs_obj):
37
+ self.__srs_obj = srs_obj
38
+ self.__list = module_list
39
+ self.__download = module_download
40
+ self.__readers = ReadManager()
41
+
42
+ @property
43
+ def readers(self):
44
+ """
45
+ Access to the `read` submodule from within a PyUCalgarySRS object.
46
+ """
47
+ return self.__readers
48
+
49
+ def list_datasets(self, name: Optional[str] = None, timeout: Optional[int] = None) -> List[Dataset]:
50
+ """
51
+ List available datasets
52
+
53
+ Args:
54
+ name (str):
55
+ Supply a name used for filtering. If that name is found in the available dataset
56
+ names received from the API, it will be included in the results. This parameter is
57
+ optional.
58
+
59
+ timeout (int):
60
+ Represents how many seconds to wait for the API to send data before giving up. The
61
+ default is 3 seconds, or the `api_timeout` value in the super class' `pyucalgarysrs.PyUCalgarySRS`
62
+ object. This parameter is optional.
63
+
64
+ Returns:
65
+ A list of [`Dataset`](classes.html#pyucalgarysrs.data.classes.Dataset)
66
+ objects.
67
+
68
+ Raises:
69
+ pyucalgary.exceptions.SRSAPIError: An API error was encountered.
70
+ """
71
+ return self.__list.list_datasets(self.__srs_obj, name, timeout)
72
+
73
+ def list_observatories(self, instrument_array: str, uid: Optional[str] = None, timeout: Optional[int] = None) -> List[Observatory]:
74
+ """
75
+ List information about observatories
76
+
77
+ Args:
78
+ instrument_array (str):
79
+ The instrument array to list observatories for. Valid values are: themis_asi, rego,
80
+ trex_rgb, trex_nir, and trex_blue.
81
+
82
+ uid (str):
83
+ Supply a observatory unique identifier used for filtering (usually 4-letter site code). If that UID
84
+ is found in the available observatories received from the API, it will be included in the results. This
85
+ parameter is optional.
86
+
87
+ timeout (int):
88
+ Represents how many seconds to wait for the API to send data before giving up. The
89
+ default is 30 seconds, or the `api_timeout` value in the super class' `pyucalgarysrs.PyUCalgarySRS`
90
+ object. This parameter is optional.
91
+
92
+ Returns:
93
+ A list of [`Observatory`](classes.html#pyucalgarysrs.data.classes.Observatory)
94
+ objects.
95
+
96
+ Raises:
97
+ pyucalgary.exceptions.SRSAPIError: An API error was encountered.
98
+ """
99
+ return self.__list.list_observatories(self.__srs_obj, instrument_array, uid, timeout)
100
+
101
+ def list_supported_read_datasets(self) -> List[str]:
102
+ """
103
+ List the datasets which have file reading capabilities supported.
104
+
105
+ Returns:
106
+ A list of the dataset names with file reading support.
107
+ """
108
+ return self.readers.list_supported_datasets()
109
+
110
+ def is_read_supported(self, dataset_name: str) -> bool:
111
+ """
112
+ Check if a given dataset has file reading support.
113
+
114
+ Not all datasets available in the UCalgary Space Remote Sensing Open Data Platform
115
+ have special readfile routines in this library. This is because some datasets are
116
+ in basic formats such as JPG or PNG, so unique functions aren't necessary. We leave
117
+ it up to the user to open these basic files in whichever way they prefer. Use the
118
+ `list_supported_read_datasets()` function to see all datasets that have special
119
+ file reading functionality in this library.
120
+
121
+ Args:
122
+ dataset_name (str):
123
+ The dataset name to check if file reading is supported. This parameter
124
+ is required.
125
+
126
+ Returns:
127
+ Boolean indicating if file reading is supported.
128
+ """
129
+ return self.readers.is_supported(dataset_name)
130
+
131
+ def download(self,
132
+ dataset_name: str,
133
+ start: datetime.datetime,
134
+ end: datetime.datetime,
135
+ site_uid: Optional[str] = None,
136
+ device_uid: Optional[str] = None,
137
+ n_parallel: int = __DEFAULT_DOWNLOAD_N_PARALLEL,
138
+ overwrite: bool = False,
139
+ progress_bar_disable: bool = False,
140
+ progress_bar_ncols: Optional[int] = None,
141
+ progress_bar_ascii: Optional[str] = None,
142
+ progress_bar_desc: Optional[str] = None,
143
+ timeout: Optional[int] = None) -> FileDownloadResult:
144
+ """
145
+ Download data from the UCalgary Space Remote Sensing Open Data Platform.
146
+
147
+ The parameters `dataset_name`, `start`, and `end` are required. All other parameters
148
+ are optional.
149
+
150
+ Note that usage of the site and device UID filters applies differently to some datasets.
151
+ For example, both fields can be used for most raw and keogram data, but only site UID can
152
+ be used for skymap datasets, and only device UID can be used for calibration datasets. If
153
+ fields are specified during a call in which site or device UID is not used, a UserWarning
154
+ is display to provide the user with feedback about this detail.
155
+
156
+ Args:
157
+ dataset_name (str):
158
+ Name of the dataset to download data for. Use the `list_datasets()` function
159
+ to get the possible values for this parameter. One example is "THEMIS_ASI_RAW".
160
+ Note that dataset names are case sensitive. This parameter is required.
161
+
162
+ start (datetime.datetime):
163
+ Start timestamp to use (inclusive), expected to be in UTC. Any timezone data
164
+ will be ignored. This parameter is required.
165
+
166
+ end (datetime.datetime):
167
+ End timestamp to use (inclusive), expected to be in UTC. Any timezone data
168
+ will be ignored. This parameter is required.
169
+
170
+ site_uid (str):
171
+ The site UID to filter for. If specified, data will be downloaded for only the
172
+ site matching the given value. If excluded, data for all available sites will
173
+ be downloaded. An example value could be 'atha', meaning all data from the
174
+ Athabasca observatory will be downloaded for the given dataset name, start, and
175
+ end times. This parameter is optional.
176
+
177
+ device_uid (str):
178
+ The device UID to filter for. If specified, data will be downloaded for only the
179
+ device matching the given value. If excluded, data for all available devices will
180
+ be downloaded. An example value could be 'themis02', meaning all data matching that
181
+ device will be downloaded for the given dataset name, start, and end times. This
182
+ parameter is optional.
183
+
184
+ n_parallel (int):
185
+ Number of data files to download in parallel. Default value is 5. Adjust as needed
186
+ for your internet connection. This parameter is optional.
187
+
188
+ overwrite (bool):
189
+ By default, data will not be re-downloaded if it already exists locally. Use
190
+ the `overwrite` parameter to force re-downloading. Default is `False`. This
191
+ parameter is optional.
192
+
193
+ progress_bar_disable (bool):
194
+ Disable the progress bar. Default is `False`. This parameter is optional.
195
+
196
+ progress_bar_ncols (int):
197
+ Number of columns for the progress bar (straight passthrough of the `ncols`
198
+ parameter in a tqdm progress bar). This parameter is optional. See Notes section
199
+ below for further information.
200
+
201
+ progress_bar_ascii (str):
202
+ ASCII value to use when constructing the visual aspect of the progress bar (straight
203
+ passthrough of the `ascii` parameter in a tqdm progress bar). This parameter is
204
+ optional. See Notes section below for further details.
205
+
206
+ timeout (int):
207
+ Represents how many seconds to wait for the API to send data before giving up. The
208
+ default is 30 seconds, or the `api_timeout` value in the super class' `pyucalgarysrs.PyUCalgarySRS`
209
+ object. This parameter is optional.
210
+
211
+ Returns:
212
+ A `pyucalgarysrs.data.classes.FileDownloadResult` object containing details about what
213
+ data files were downloaded.
214
+
215
+ Raises:
216
+ pyucalgarysrs.exceptions.SRSDownloadError: an error was encountered while downloading a
217
+ specific file
218
+ pyucalgarysrs.exceptions.SRSAPIError: an API error was encountered
219
+
220
+ Notes:
221
+ --------
222
+ The `progress_bar_*` parameters can be used to enable/disable/adjust the progress bar.
223
+ Excluding the `progress_bar_disable` parameter, all others are straight pass-throughs
224
+ to the tqdm progress bar function. The `progress_bar_ncols` parameter allows for
225
+ adjusting the width. The `progress_bar_ascii` parameter allows for adjusting the appearance
226
+ of the progress bar. And the `progress_bar_desc` parameter allows for adjusting the
227
+ description at the beginning of the progress bar. Further details can be found on the
228
+ [tqdm documentation](https://tqdm.github.io/docs/tqdm/#tqdm-objects).
229
+
230
+ Data downloading will use the `download_data_root_path` variable within the super class'
231
+ object ([`PyUCalgarySRS`](../index.html#pyucalgarysrs.PyUCalgarySRS)) to determine where to save data to. If
232
+ you'd like to change this path to somewhere else you can change that variable before your
233
+ download() call, like so:
234
+
235
+ ```python
236
+ import pyucalgarysrs
237
+ srs = pyucalgarysrs.PyUCalgarySRS()
238
+ srs.data_download_root_path = "some_new_path"
239
+ srs.data.download(dataset_name, start, end)
240
+ ```
241
+ """
242
+ return self.__download.download_generic(
243
+ self.__srs_obj,
244
+ dataset_name,
245
+ start,
246
+ end,
247
+ site_uid,
248
+ device_uid,
249
+ n_parallel,
250
+ overwrite,
251
+ progress_bar_disable,
252
+ progress_bar_ncols,
253
+ progress_bar_ascii,
254
+ progress_bar_desc,
255
+ timeout,
256
+ )
257
+
258
+ def download_using_urls(self,
259
+ file_listing_response: FileListingResponse,
260
+ n_parallel: int = __DEFAULT_DOWNLOAD_N_PARALLEL,
261
+ overwrite: bool = False,
262
+ progress_bar_disable: bool = False,
263
+ progress_bar_ncols: Optional[int] = None,
264
+ progress_bar_ascii: Optional[str] = None,
265
+ progress_bar_desc: Optional[str] = None,
266
+ timeout: Optional[int] = None) -> FileDownloadResult:
267
+ """
268
+ Download data from the UCalgary Space Remote Sensing Open Data Platform using
269
+ a FileListingResponse object. This would be used in cases where more customization
270
+ is needed than the generic `download()` function.
271
+
272
+ One example of using this function would start by using `get_urls()` to retrieve the
273
+ list of URLs available for download, then further process this list to fewer files
274
+ based on some other requirement (ie. time down-sampling such as one file per hour).
275
+ Lastly using this function to download the new custom set URLs.
276
+
277
+ Args:
278
+ file_listing_response (FileListingResponse):
279
+ A `pyucalgarysrs.data.classes.FileListingResponse` object returned from a
280
+ `get_urls()` call, which contains a list of URLs to download for a specific
281
+ dataset. This parameter is required.
282
+
283
+ n_parallel (int):
284
+ Number of data files to download in parallel. Default value is 5. Adjust as needed
285
+ for your internet connection. This parameter is optional.
286
+
287
+ overwrite (bool):
288
+ By default, data will not be re-downloaded if it already exists locally. Use
289
+ the `overwrite` parameter to force re-downloading. Default is `False`. This
290
+ parameter is optional.
291
+
292
+ progress_bar_disable (bool):
293
+ Disable the progress bar. Default is `False`. This parameter is optional.
294
+
295
+ progress_bar_ncols (int):
296
+ Number of columns for the progress bar (straight passthrough of the `ncols`
297
+ parameter in a tqdm progress bar). This parameter is optional. See Notes section
298
+ below for further information.
299
+
300
+ progress_bar_ascii (str):
301
+ ASCII value to use when constructing the visual aspect of the progress bar (straight
302
+ passthrough of the `ascii` parameter in a tqdm progress bar). This parameter is
303
+ optional. See Notes section below for further details.
304
+
305
+ timeout (int):
306
+ Represents how many seconds to wait for the API to send data before giving up. The
307
+ default is 30 seconds, or the `api_timeout` value in the super class' `pyucalgarysrs.PyUCalgarySRS`
308
+ object. This parameter is optional.
309
+
310
+ Returns:
311
+ A `pyucalgarysrs.data.classes.FileDownloadResult` object containing details about what
312
+ data files were downloaded.
313
+
314
+ Raises:
315
+ pyucalgarysrs.exceptions.SRSDownloadError: an error was encountered while downloading a
316
+ specific file
317
+ pyucalgarysrs.exceptions.SRSAPIError: an API error was encountered
318
+
319
+ Notes:
320
+ --------
321
+ The `progress_bar_*` parameters can be used to enable/disable/adjust the progress bar.
322
+ Excluding the `progress_bar_disable` parameter, all others are straight pass-throughs
323
+ to the tqdm progress bar function. The `progress_bar_ncols` parameter allows for
324
+ adjusting the width. The `progress_bar_ascii` parameter allows for adjusting the appearance
325
+ of the progress bar. And the `progress_bar_desc` parameter allows for adjusting the
326
+ description at the beginning of the progress bar. Further details can be found on the
327
+ [tqdm documentation](https://tqdm.github.io/docs/tqdm/#tqdm-objects).
328
+
329
+ Data downloading will use the `download_data_root_path` variable within the super class'
330
+ object ([`PyUCalgarySRS`](../pyucalgarysrs.html)) to determine where to save data to. If
331
+ you'd like to change this path to somewhere else you can change that variable before your
332
+ download() call, like so:
333
+
334
+ ```python
335
+ import pyucalgarysrs
336
+ srs = pyucalgarysrs.PyUCalgarySRS()
337
+ srs.data_download_root_path = "some_new_path"
338
+ srs.data.download(dataset_name, start, end)
339
+ ```
340
+ """
341
+ return self.__download.download_using_urls(
342
+ self.__srs_obj,
343
+ file_listing_response,
344
+ n_parallel,
345
+ overwrite,
346
+ progress_bar_disable,
347
+ progress_bar_ncols,
348
+ progress_bar_ascii,
349
+ progress_bar_desc,
350
+ timeout,
351
+ )
352
+
353
+ def get_urls(self,
354
+ dataset_name: str,
355
+ start: datetime.datetime,
356
+ end: datetime.datetime,
357
+ site_uid: Optional[str] = None,
358
+ device_uid: Optional[str] = None,
359
+ timeout: Optional[int] = None) -> FileListingResponse:
360
+ """
361
+ Get URLs of data files
362
+
363
+ The parameters `dataset_name`, `start`, and `end` are required. All other parameters
364
+ are optional.
365
+
366
+ Note that usage of the site and device UID filters applies differently to some datasets.
367
+ For example, both fields can be used for most raw and keogram data, but only site UID can
368
+ be used for skymap datasets, and only device UID can be used for calibration datasets. If
369
+ fields are specified during a call in which site or device UID is not used, a UserWarning
370
+ is display to provide the user with feedback about this detail.
371
+
372
+ Args:
373
+ dataset_name (str):
374
+ Name of the dataset to download data for. Use the `list_datasets()` function
375
+ to get the possible values for this parameter. One example is "THEMIS_ASI_RAW".
376
+ Note that dataset names are case sensitive. This parameter is required.
377
+
378
+ start (datetime.datetime):
379
+ Start timestamp to use (inclusive), expected to be in UTC. Any timezone data
380
+ will be ignored. This parameter is required.
381
+
382
+ end (datetime.datetime):
383
+ End timestamp to use (inclusive), expected to be in UTC. Any timezone data
384
+ will be ignored. This parameter is required.
385
+
386
+ site_uid (str):
387
+ The site UID to filter for. If specified, data will be downloaded for only the
388
+ site matching the given value. If excluded, data for all available sites will
389
+ be downloaded. An example value could be 'atha', meaning all data from the
390
+ Athabasca observatory will be downloaded for the given dataset name, start, and
391
+ end times. This parameter is optional.
392
+
393
+ device_uid (str):
394
+ The device UID to filter for. If specified, data will be downloaded for only the
395
+ device matching the given value. If excluded, data for all available devices will
396
+ be downloaded. An example value could be 'themis02', meaning all data matching that
397
+ device will be downloaded for the given dataset name, start, and end times. This
398
+ parameter is optional.
399
+
400
+ timeout (int):
401
+ Represents how many seconds to wait for the API to send data before giving up. The
402
+ default is 30 seconds, or the `api_timeout` value in the super class' `pyucalgarysrs.PyUCalgarySRS`
403
+ object. This parameter is optional.
404
+
405
+ Returns:
406
+ A `pyucalgarysrs.data.classes.FileListingResponse` object containing a list of the available URLS,
407
+ among other values.
408
+
409
+ Raises:
410
+ pyucalgarysrs.exceptions.SRSAPIError: an API error was encountered
411
+ """
412
+ return self.__download.get_urls(
413
+ self.__srs_obj,
414
+ dataset_name,
415
+ start,
416
+ end,
417
+ site_uid,
418
+ device_uid,
419
+ timeout,
420
+ )
421
+
422
+ def read(self,
423
+ dataset: Dataset,
424
+ file_list: Union[List[str], str],
425
+ n_parallel: int = 1,
426
+ first_record: bool = False,
427
+ no_metadata: bool = False,
428
+ quiet: bool = False) -> Data:
429
+ """
430
+ Read in data files for a given dataset. Note that only one type of dataset's data
431
+ should be read in using a single call.
432
+
433
+ Args:
434
+ dataset (Dataset):
435
+ The dataset object for which the files are associated with. This parameter is
436
+ required.
437
+
438
+ file_list (List[str] or str):
439
+ The files to read in. Absolute paths are recommended, but not technically
440
+ necessary. This can be a single string for a file, or a list of strings to read
441
+ in multiple files. This parameter is required.
442
+
443
+ n_parallel (int):
444
+ Number of data files to read in parallel using multiprocessing. Default value
445
+ is 1. Adjust according to your computer's available resources. This parameter
446
+ is optional.
447
+
448
+ first_record (bool):
449
+ Only read in the first record in each file. This is the same as the first_frame
450
+ parameter in the themis-imager-readfile and trex-imager-readfile libraries, and
451
+ is a read optimization if you only need one image per minute, as opposed to the
452
+ full temporal resolution of data (e.g., 3sec cadence). This parameter is optional.
453
+
454
+ no_metadata (bool):
455
+ Skip reading of metadata. This is a minor optimization if the metadata is not needed.
456
+ Default is `False`. This parameter is optional.
457
+
458
+ quiet (bool):
459
+ Do not print out errors while reading data files, if any are encountered. Any files
460
+ that encounter errors will be, as usual, accessible via the `problematic_files`
461
+ attribute of the returned `pyucalgarysrs.data.classes.Data` object. This parameter
462
+ is optional.
463
+
464
+ Returns:
465
+ A `pyucalgarysrs.data.classes.Data` object containing the data read in, among other
466
+ values.
467
+
468
+ Raises:
469
+ pyucalgarysrs.exceptions.SRSUnsupportedReadError: an unsupported dataset was used when
470
+ trying to read files.
471
+ pyucalgarysrs.exceptions.SRSError: a generic read error was encountered
472
+
473
+ Notes:
474
+ ---------
475
+ For users who are familiar with the themis-imager-readfile and trex-imager-readfile
476
+ libraries, the read function provides a near-identical usage. Further improvements have
477
+ been integrated, and those libraries are anticipated to be deprecated at some point in the
478
+ future.
479
+ """
480
+ return self.readers.read(
481
+ dataset,
482
+ file_list,
483
+ n_parallel=n_parallel,
484
+ first_record=first_record,
485
+ no_metadata=no_metadata,
486
+ quiet=quiet,
487
+ )