PyThea 0.13.0__tar.gz → 1.0.0__tar.gz

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.
Files changed (65) hide show
  1. {pythea-0.13.0 → pythea-1.0.0}/CHANGELOG.md +26 -0
  2. {pythea-0.13.0 → pythea-1.0.0}/PKG-INFO +7 -2
  3. {pythea-0.13.0 → pythea-1.0.0}/PyThea/PyThea_app.py +11 -1
  4. {pythea-0.13.0 → pythea-1.0.0}/PyThea/_version.py +2 -2
  5. {pythea-0.13.0 → pythea-1.0.0}/PyThea/config/__init__.py +5 -0
  6. {pythea-0.13.0 → pythea-1.0.0}/PyThea/config/selected_imagers.py +16 -0
  7. {pythea-0.13.0 → pythea-1.0.0}/PyThea/data/sample_data.py +6 -6
  8. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/Parker_spirals/utils.py +2 -0
  9. {pythea-0.13.0 → pythea-1.0.0}/PyThea/modules.py +5 -0
  10. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/utils.py +6 -1
  11. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/map/maputils.py +26 -9
  12. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/Pythea_test.py +3 -3
  13. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/figure_hashes.json +2 -2
  14. {pythea-0.13.0 → pythea-1.0.0}/PyThea/utils.py +19 -8
  15. pythea-1.0.0/PyThea/utils_database.py +94 -0
  16. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/PKG-INFO +7 -2
  17. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/SOURCES.txt +1 -0
  18. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/requires.txt +1 -0
  19. {pythea-0.13.0 → pythea-1.0.0}/README.md +5 -4
  20. {pythea-0.13.0 → pythea-1.0.0}/README_pypi.md +5 -1
  21. {pythea-0.13.0 → pythea-1.0.0}/environment.yml +1 -0
  22. {pythea-0.13.0 → pythea-1.0.0}/requirements.txt +1 -0
  23. {pythea-0.13.0 → pythea-1.0.0}/setup.py +1 -0
  24. {pythea-0.13.0 → pythea-1.0.0}/.readthedocs.yaml +0 -0
  25. {pythea-0.13.0 → pythea-1.0.0}/LICENSE.md +0 -0
  26. {pythea-0.13.0 → pythea-1.0.0}/MANIFEST.in +0 -0
  27. {pythea-0.13.0 → pythea-1.0.0}/PyThea/__init__.py +0 -0
  28. {pythea-0.13.0 → pythea-1.0.0}/PyThea/callbacks.py +0 -0
  29. {pythea-0.13.0 → pythea-1.0.0}/PyThea/config/app_styles.py +0 -0
  30. {pythea-0.13.0 → pythea-1.0.0}/PyThea/config/config_sliders.py +0 -0
  31. {pythea-0.13.0 → pythea-1.0.0}/PyThea/config/selected_bodies.py +0 -0
  32. {pythea-0.13.0 → pythea-1.0.0}/PyThea/data/__init__.py +0 -0
  33. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/LICENSE_gcs_python.md +0 -0
  34. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/Parker_spirals/__init__.py +0 -0
  35. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/__init__.py +0 -0
  36. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/buttons.py +0 -0
  37. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/hek/__init__.py +0 -0
  38. {pythea-0.13.0 → pythea-1.0.0}/PyThea/extensions/hek/utils.py +0 -0
  39. {pythea-0.13.0 → pythea-1.0.0}/PyThea/geometrical_models.py +0 -0
  40. {pythea-0.13.0 → pythea-1.0.0}/PyThea/pythea_cli.py +0 -0
  41. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/__init__.py +0 -0
  42. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/__init__.py +0 -0
  43. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/__init__.py +0 -0
  44. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/__init__.py +0 -0
  45. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/__init__.py +0 -0
  46. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/utils.py +0 -0
  47. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/__init__.py +0 -0
  48. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/utils.py +0 -0
  49. {pythea-0.13.0 → pythea-1.0.0}/PyThea/sunpy_dev/map/__init__.py +0 -0
  50. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/__init__.py +0 -0
  51. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/conftest.py +0 -0
  52. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/test_extension_utils.py +0 -0
  53. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/test_figures.py +0 -0
  54. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/test_geometrical_models.py +0 -0
  55. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/test_imports.py +0 -0
  56. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/test_remote_clients.py +0 -0
  57. {pythea-0.13.0 → pythea-1.0.0}/PyThea/test/test_utils.py +0 -0
  58. {pythea-0.13.0 → pythea-1.0.0}/PyThea/version.py +0 -0
  59. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/.DS_Store +0 -0
  60. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/dependency_links.txt +0 -0
  61. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/entry_points.txt +0 -0
  62. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/not-zip-safe +0 -0
  63. {pythea-0.13.0 → pythea-1.0.0}/PyThea.egg-info/top_level.txt +0 -0
  64. {pythea-0.13.0 → pythea-1.0.0}/pyproject.toml +0 -0
  65. {pythea-0.13.0 → pythea-1.0.0}/setup.cfg +0 -0
@@ -1,3 +1,29 @@
1
+ # v1.0.0 (19-Nov-2024)
2
+
3
+ ## Features
4
+ - Adds imaging data from Solar Orbiter's SOLOHi.
5
+ - Implements offline fits file loading from local database.
6
+
7
+ ## Minor Changes
8
+ - Updates Test figure hashes.
9
+ - Final changes in README before the major release.
10
+
11
+ ## Bug Fixes
12
+ - Fixes a temporary bug with JSOC and AIA prep
13
+ - Fixes potential bug with maps loading into map sequence.
14
+ - Fixes a bug when fits database is selected but no files downloaded.
15
+ - Fixes a bug with the maps clims.
16
+
17
+ # v0.14.0 (03-Oct-2024)
18
+
19
+ ## Features
20
+ - Adds imaging data from Solar Orbiter EUI and METIS.
21
+ - Implements offline fits file loading from local database.
22
+
23
+ ## Minor Changes
24
+ - Simplifies the configuration of the database directory.
25
+ - Improves Parker Spiral visualization.
26
+
1
27
  # v0.13.0 (14-Jul-2024)
2
28
 
3
29
  ## Features
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyThea
3
- Version: 0.13.0
3
+ Version: 1.0.0
4
4
  Summary: PyThea: A software package to reconstruct the 3D structure of CMEs and shock waves
5
5
  Home-page: https://github.com/AthKouloumvakos/PyThea
6
6
  Author: Athanasios Kouloumvakos
@@ -29,6 +29,7 @@ Requires-Dist: astroquery
29
29
  Requires-Dist: jplephem
30
30
  Requires-Dist: numexpr
31
31
  Requires-Dist: sunpy==5.1.2
32
+ Requires-Dist: sunpy_soar
32
33
  Requires-Dist: parfive==2.1.0
33
34
  Requires-Dist: pooch
34
35
  Requires-Dist: matplotlib
@@ -53,7 +54,7 @@ Requires-Dist: pytest-mpl
53
54
  ![flake8](https://github.com/AthKouloumvakos/PyThea/actions/workflows/flake8.yml/badge.svg)
54
55
  ![pytest](https://github.com/AthKouloumvakos/PyThea/actions/workflows/pytest.yml/badge.svg)
55
56
 
56
- _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO) and Solar Terrestrial Relations Observatory (STEREO).
57
+ _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO), Solar Terrestrial Relations Observatory (STEREO), and Parker Solar Probe.
57
58
 
58
59
  ## 💾 Installation
59
60
 
@@ -152,3 +153,7 @@ If you use _PyThea_ for scientific work or research presented in a publication,
152
153
  ## ⓘ The mythology of Thea:
153
154
 
154
155
  In Greek mythology, Thea, also called Euryphaessa "wide-shining", is the Titaness of sight and the shining light of the clear blue sky. Her brother/consort is Hyperion, a Titan and god of the sun, and together they are the parents of Helios (the Sun), Selene (the Moon), and Eos (the Dawn).
156
+
157
+ ## Development Support:
158
+
159
+ The lead author of this software package Athanasios Kouloumvakos acknowledges financial support from NASA Grant 80NSSC24K0071 for the further development and improvement of PyThea during 2024. This grant was part of the NASA Headquarters Heliophysics Tools and Methods Program in response to NASA ROSES–2022 (NNH22ZDA001N).
@@ -39,6 +39,7 @@ from PyThea.modules import (date_and_event_selection, figure_streamlit,
39
39
  from PyThea.sunpy_dev.map.maputils import get_closest, maps_clims
40
40
  from PyThea.utils import (download_fits, load_fits, model_fittings,
41
41
  plot_fitting_model, single_imager_maps_process)
42
+ from PyThea.utils_database import get_fits_filenames_from_database
42
43
  from PyThea.version import version
43
44
 
44
45
 
@@ -84,6 +85,7 @@ def footer_text():
84
85
  More imaging data have been added:
85
86
  - SDO/AIA images from 211A channel.
86
87
  - PSP/WISPR inner and outer telescope images.
88
+ - SolO/EUI, METIS, and HI(tiles 1&2) images.
87
89
  ''', icon='ℹ️')
88
90
  st.warning('''
89
91
  **NOTE: From PyThea >0.8.1 the JSON fitting files will be slightly different from the old ones.**
@@ -295,7 +297,15 @@ def run():
295
297
  if imager not in st.session_state.map_:
296
298
  timerange = a.Time(st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[0]),
297
299
  st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[1]))
298
- downloaded_files = download_fits(timerange, imager)
300
+
301
+ if st.session_state.offline_mode is False:
302
+ downloaded_files = download_fits(timerange, imager)
303
+ elif st.session_state.offline_mode is True:
304
+ progress_bar.desc = f'Load {imager} images from local database.'
305
+ event_id = st.session_state.event_selected.replace('-', '').replace(':', '').replace('|', 'D').replace('.', 'p') \
306
+ + 'M' + st.session_state.geometrical_model
307
+ downloaded_files = get_fits_filenames_from_database(event_id, timerange, imager)
308
+
299
309
  st.session_state.map_[imager] = load_fits(downloaded_files)
300
310
  st.session_state.map_[imager] = single_imager_maps_process(st.session_state.map_[imager],
301
311
  **selected_imagers.imager_dict[imager]['process'],
@@ -12,5 +12,5 @@ __version__: str
12
12
  __version_tuple__: VERSION_TUPLE
13
13
  version_tuple: VERSION_TUPLE
14
14
 
15
- __version__ = version = '0.13.0'
16
- __version_tuple__ = version_tuple = (0, 13, 0)
15
+ __version__ = version = '1.0.0'
16
+ __version_tuple__ = version_tuple = (1, 0, 0)
@@ -1,3 +1,8 @@
1
+ import os
2
+ from pathlib import Path
3
+
1
4
  from PyThea.config.config_sliders import *
2
5
  from PyThea.config.selected_bodies import *
3
6
  from PyThea.config.selected_imagers import *
7
+
8
+ database_dir_default = os.path.join(Path.home(), 'PyThea')
@@ -4,6 +4,7 @@
4
4
 
5
5
  '''
6
6
  import astropy.units as u
7
+ import sunpy_soar # noqa
7
8
  from sunpy.net import attrs as a
8
9
 
9
10
  imager_dict = {}
@@ -71,3 +72,18 @@ imager_dict['WISPR1'] = {'fido': (a.Instrument.wispr, a.Detector.inner),
71
72
  imager_dict['WISPR2'] = {'fido': (a.Instrument.wispr, a.Detector.outer),
72
73
  'process': {'dimensions': (960*u.pixel, 1024*u.pixel), 'processing_level': 3, 'superpixel': 2},
73
74
  'source': 'PSP', 'instrument': 'WISPR', 'detector': 'Outer'}
75
+
76
+ imager_dict['EUI-FSI'] = {'fido': (a.Instrument('EUI'), a.soar.Product('EUI-FSI174-IMAGE'), a.Level(2)),
77
+ 'process': {'superpixel': 1},
78
+ 'source': 'SOLO', 'instrument': 'EUI-FSI', 'wavelength': '174'}
79
+
80
+ imager_dict['METIS'] = {'fido': (a.Instrument('METIS'), a.soar.Product('METIS-VL-TB'), a.Level(2)),
81
+ 'process': {'dimensions': (1024*u.pixel, 1024*u.pixel), 'superpixel': 2},
82
+ 'source': 'SOLO', 'instrument': 'METIS', 'detector': 'VLD', 'wavelength': 'TB'}
83
+
84
+ for tile in range(1, 5):
85
+ z = 'T' if tile in [1, 2] else 'G'
86
+ imager_dict[f'SOLOHI-T{tile}'] = {'fido': (a.Instrument('SOLOHI'),
87
+ a.soar.Product(f'SOLOHI-{tile}F{z}'), a.Level(2)),
88
+ 'process': {'superpixel': 2},
89
+ 'source': 'SOLO', 'instrument': 'SOLOHI', 'detector': f'T{tile}'}
@@ -1,13 +1,13 @@
1
1
  import os
2
- from pathlib import Path
3
2
 
4
3
  import pooch
5
4
 
6
- database_dir = os.path.join(Path.home(), 'PyThea')
5
+ from PyThea.config import database_dir_default
6
+
7
7
  github_main_url = 'https://github.com/AthKouloumvakos/PyThea-sample-data'
8
8
 
9
9
  aia_sample_data = pooch.create(
10
- path=os.path.join(database_dir, 'sample_data'), # The cache folder
10
+ path=os.path.join(database_dir_default, 'sample_data'), # The cache folder
11
11
  base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
12
12
  registry={
13
13
  'aia_lev1_1600a_2012_06_06t04_07_29_12z_image_lev1.fits': 'sha256:7e88d8a277ad3dd111c1bcff3c3936d6d5ef5186e05b4bfa7749ee43c05577d5',
@@ -16,7 +16,7 @@ aia_sample_data = pooch.create(
16
16
  )
17
17
 
18
18
  stereo_sample_data = pooch.create(
19
- path=os.path.join(database_dir, 'sample_data'), # The cache folder
19
+ path=os.path.join(database_dir_default, 'sample_data'), # The cache folder
20
20
  base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
21
21
  registry={
22
22
  '20120622_235400_d4c2a.fts': 'sha256:940680fe8bea754c9859170585d8299b9b049b631155435a31ecacf5b702d9cf',
@@ -27,7 +27,7 @@ stereo_sample_data = pooch.create(
27
27
  )
28
28
 
29
29
  wispr_sample_data = pooch.create(
30
- path=os.path.join(database_dir, 'sample_data'), # The cache folder
30
+ path=os.path.join(database_dir_default, 'sample_data'), # The cache folder
31
31
  base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
32
32
  registry={
33
33
  'psp_l3_wispr_20210808t103707_v1_1211.fits': 'sha256:85035693c4677e8fa8a3e61b8051d6f0a46e96806b5b0cbdb3efa77652308bda',
@@ -36,7 +36,7 @@ wispr_sample_data = pooch.create(
36
36
  )
37
37
 
38
38
  json_fitting_file_sample_data = pooch.create(
39
- path=os.path.join(database_dir, 'sample_data'), # The cache folder
39
+ path=os.path.join(database_dir_default, 'sample_data'), # The cache folder
40
40
  base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
41
41
  registry={
42
42
  'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:34fced8530875110117ba27a73541d3acd0c90bc8fca99367c1ec4cdfc05ce86',
@@ -41,3 +41,5 @@ def plot_parker_spiral(axis, map, bodies, sw_speed=350 * (u.km / u.second)):
41
41
  axis.plot_coord(spiral_coord[0], markersize=16, linewidth=10, marker='+', color='white')
42
42
 
43
43
  axis.plot_coord(spiral_coord[0], markersize=3, linewidth=4, marker='s', color=bodies_dict[body][1])
44
+
45
+ axis.plot_coord(spiral_coord[-1], markersize=8, linewidth=6, marker='x', color=bodies_dict[body][1])
@@ -24,6 +24,7 @@ import astropy.units as u
24
24
  from sunpy.net import attrs as a
25
25
 
26
26
  from PyThea.callbacks import change_fitting_sliders, change_long_lat_sliders
27
+ from PyThea.config import database_dir_default
27
28
  from PyThea.config.config_sliders import sliders_dict as sd
28
29
  from PyThea.extensions.hek.utils import plot_hek
29
30
  from PyThea.extensions.Parker_spirals.utils import plot_parker_spiral
@@ -121,6 +122,10 @@ def date_and_event_selection(st):
121
122
 
122
123
  st.rerun()
123
124
 
125
+ st.session_state.offline_mode = st.sidebar.checkbox('Work with offline mode active?', value=False)
126
+ if st.session_state.offline_mode:
127
+ st.sidebar.info(f'Fits files will be loaded from PyThea\'s database directory: {database_dir_default}', icon='ℹ️')
128
+
124
129
 
125
130
  def fitting_and_slider_options_container(st):
126
131
  """
@@ -1,3 +1,4 @@
1
+ import warnings
1
2
  from astropy.time import TimeDelta
2
3
  from aiapy.calibrate import fix_observer_location, update_pointing
3
4
 
@@ -5,7 +6,11 @@ __all__ = ['prep_aia']
5
6
 
6
7
 
7
8
  def prep_aia(map_sequence):
8
- map_sequence = [update_pointing(tmap) for tmap in map_sequence]
9
+ try:
10
+ map_sequence = [update_pointing(tmap) for tmap in map_sequence]
11
+ except:
12
+ warnings.warn('Prepare AIA maps failed, script proceeded without update_pointing. Check connection with JSOC.', UserWarning)
13
+
9
14
  map_sequence = [fix_observer_location(tmap) for tmap in map_sequence]
10
15
 
11
16
  for map_ in map_sequence:
@@ -18,6 +18,16 @@ __all__ = ['maps_sequence_processing', 'get_closest', 'normalize_exposure',
18
18
  'prepare_maps', 'difference_maps', 'mask_occulter']
19
19
 
20
20
 
21
+ def check_maps_sequence(map_sequence):
22
+ if map_sequence:
23
+ if isinstance(map_sequence, MapSequence):
24
+ return map_sequence
25
+ else:
26
+ return sunpy.map.Map(map_sequence, sequence=True)
27
+ else:
28
+ return []
29
+
30
+
21
31
  def maps_sequence_processing(map_sequence, **kwargs):
22
32
  """
23
33
  Returns a sequence of maps which is processed as plain images, running or base difference images.
@@ -36,6 +46,7 @@ def maps_sequence_processing(map_sequence, **kwargs):
36
46
  A SunPy map.
37
47
  """
38
48
 
49
+ map_sequence = check_maps_sequence(map_sequence)
39
50
  if len(map_sequence) == 0:
40
51
  return []
41
52
 
@@ -139,6 +150,7 @@ def filter_maps(map_sequence, **kwargs):
139
150
 
140
151
  '''
141
152
 
153
+ map_sequence = check_maps_sequence(map_sequence)
142
154
  if len(map_sequence) == 0:
143
155
  return []
144
156
 
@@ -155,11 +167,7 @@ def filter_maps(map_sequence, **kwargs):
155
167
  map_sequence = [tmap for tmap in map_sequence if tmap.meta['polar'] == kwargs['polar']]
156
168
 
157
169
  if len(map_sequence) != 0:
158
- if isinstance(map_sequence, MapSequence):
159
- return map_sequence
160
- else:
161
- sequence_final = sunpy.map.Map(map_sequence, sequence=True)
162
-
170
+ sequence_final = check_maps_sequence(map_sequence)
163
171
  else:
164
172
  sequence_final = []
165
173
 
@@ -188,6 +196,7 @@ def prepare_maps(map_sequence, **kwargs):
188
196
 
189
197
  '''
190
198
 
199
+ map_sequence = check_maps_sequence(map_sequence)
191
200
  if len(map_sequence) == 0:
192
201
  return []
193
202
 
@@ -246,6 +255,7 @@ def difference_maps(smapi, smapm):
246
255
  if smapm.exposure_time != 1*u.second:
247
256
  smapm = normalize_exposure(smapm)
248
257
  smap_difference = smapi.data - smapm.data
258
+
249
259
  return sunpy.map.Map(smap_difference, smapi.meta)
250
260
 
251
261
 
@@ -300,9 +310,16 @@ def mask_occulter(smap, apply_mask=True, mask_value=0):
300
310
 
301
311
 
302
312
  def maps_clims(images):
303
- if images[1].instrument == 'WISPR':
304
- if images[1].detector == 'Outer':
313
+ i = 0 if len(images) < 2 else 1
314
+
315
+ if images[i].instrument == 'WISPR':
316
+ if images[i].detector == 'Outer':
305
317
  return [14., 14.]
306
- elif images[1].detector == 'Inner':
318
+ elif images[i].detector == 'Inner':
307
319
  return [13., 13.]
308
- return [np.nanquantile(images[1].data, 0.20)-10, np.nanquantile(images[1].data, 0.80)+10]
320
+ elif images[i].instrument == 'Metis':
321
+ return [12.80, 13.00]
322
+ elif images[i].instrument.startswith('SoloHI'):
323
+ return [13.95, 14.05]
324
+
325
+ return [np.nanquantile(images[i].data, 0.20)-10, np.nanquantile(images[i].data, 0.80)+10]
@@ -8,7 +8,8 @@ export PYTHONPATH="${PYTHONPATH}:{top_level_dir_that_pythea_lives}/PyThea"
8
8
  """
9
9
 
10
10
  import os
11
- from pathlib import Path
11
+
12
+ from PyThea.config import database_dir_default
12
13
 
13
14
 
14
15
  def test_database_dir_exists():
@@ -20,5 +21,4 @@ def test_database_dir_exists():
20
21
  print("Skipping test as it's running in GitHub Actions.")
21
22
  return
22
23
 
23
- database_dir = os.path.join(Path.home(), 'PyThea')
24
- assert os.path.exists(database_dir), f"PyThea's database directory '{database_dir}' does not exist."
24
+ assert os.path.exists(database_dir_default), f"PyThea's database directory '{database_dir_default}' does not exist."
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "PyThea.test.test_figures.test_ellipsoid_on_AIA_venus": "f1ff774b483a8c934c9353c552278c8823216fc7d9dad4ccc00c74be3f30c4c3",
3
- "PyThea.test.test_figures.test_ellipsoid_on_AIA_mercury": "f6afda1c769a061b7ab1fc64c4e9c0f4658cdb97c3be83828ba5d98bf1bb182c",
3
+ "PyThea.test.test_figures.test_ellipsoid_on_AIA_mercury": "a70589cd9c052d80532df5f9fbbc6d857333dcd3e2e7acfbe0e73f6b98a2a6ef",
4
4
  "PyThea.test.test_figures.test_ellipsoid_on_STEREO_COR1_venus": "18a3af72e9da5b60e435f83ee3ef3f8cd0eb437eaef463329552ff56968f12ff",
5
5
  "PyThea.test.test_figures.test_ellipsoid_on_STEREO_COR2_three_planets": "231d5635f57c4d66556674a83f6cbcef7dc94b51846e977c4c2dc3dc244096ac",
6
- "PyThea.test.test_figures.test_kinematics_figure": "83e060de53b57e9d34fe50111ba60a44f7c7c7b20faae9a4381654ef1c9ea72d"
6
+ "PyThea.test.test_figures.test_kinematics_figure": "83e060de53b57e9d34fe50111ba60a44f7c7c7b20faae9a4381654ef1c9ea72d",
7
7
  "PyThea.test.test_figures.test_ellipsoid_on_WISPR_Inner_Venus": "8d831b43b0c789cacfcff8386c00af0707bb68d64fca16c6188deca93d3cba87",
8
8
  "PyThea.test.test_figures.test_ellipsoid_on_WISPR_Outer_Mercury": "f94c444f2c6f00cd5dd5deff394d0e233c9e720413fd5570b306b262915c9732"
9
9
  }
@@ -25,7 +25,6 @@ import os
25
25
  import re
26
26
  import warnings
27
27
  from copy import copy
28
- from pathlib import Path
29
28
 
30
29
  import astropy.units as u
31
30
  import matplotlib.colors as colors
@@ -48,6 +47,7 @@ from sunpy.net import attrs as a
48
47
  from sunpy.time import parse_time
49
48
  from sunpy.visualization import drawing
50
49
 
50
+ from PyThea.config import database_dir_default
51
51
  from PyThea.config.selected_bodies import bodies_dict as bodies_dict_default
52
52
  from PyThea.config.selected_imagers import imager_dict as imager_dict_default
53
53
  from PyThea.geometrical_models import ellipsoid, gcs, spheroid
@@ -56,8 +56,6 @@ from PyThea.sunpy_dev.map.maputils import (filter_maps,
56
56
  prepare_maps)
57
57
  from PyThea.version import version
58
58
 
59
- database_dir_default = os.path.join(Path.home(), 'PyThea')
60
-
61
59
 
62
60
  def get_hek_flare(timerange, thresshold='B1.0'):
63
61
  """
@@ -130,7 +128,7 @@ def make_figure(map, cmap='Greys_r', clim=[-20, 20], clip_model=True, **kwargs):
130
128
  if median_filter_value != 1:
131
129
  map = sunpy.map.Map(median_filter(map.data, size=int(median_filter_value)), map.meta)
132
130
 
133
- if map.instrument == 'WISPR':
131
+ if map.instrument in ['WISPR', 'Metis'] or map.instrument.startswith('SoloHI'):
134
132
  clim = [-10**-clim[0], 10**-clim[1]]
135
133
 
136
134
  if cmap == 'default':
@@ -154,9 +152,20 @@ def make_figure(map, cmap='Greys_r', clim=[-20, 20], clip_model=True, **kwargs):
154
152
  if cref.Ty > 0:
155
153
  axis.invert_yaxis()
156
154
 
157
- axis.set_title(re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}',
158
- ' $T_{AGV}:$' + parse_time(map.date_average).strftime('%Y-%m-%d %H:%M:%S'),
159
- map.latex_name), fontsize=10, pad=8)
155
+ if map.instrument == 'SoloHI':
156
+ title = 'SoloHI' + f' Tile-{map.detector}' ' $T_{AGV}:$' + parse_time(map.date_average).strftime('%Y-%m-%d %H:%M:%S')
157
+ elif map.instrument == 'Metis':
158
+ title = re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}',
159
+ ' $T_{AGV}:$' + parse_time(map.date_average).strftime('%Y-%m-%d %H:%M:%S'),
160
+ map.latex_name.replace('VLD', 'METIS-VDL'))
161
+ else:
162
+ title = re.sub(r'\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}',
163
+ ' $T_{AGV}:$' + parse_time(map.date_average).strftime('%Y-%m-%d %H:%M:%S'),
164
+ map.latex_name)
165
+ print(map.instrument)
166
+ print(map.latex_name)
167
+ axis.set_title(title,
168
+ fontsize=10, pad=8)
160
169
 
161
170
  return fig, axis
162
171
 
@@ -275,7 +284,7 @@ def download_fits(timerange, imager, imager_dict=None, database_dir=None):
275
284
  'detector' (optional), and 'wavelength' (optional). The default imager_dict is from
276
285
  PyThea.config.selected_imagers.import imager_dict.
277
286
  database_dir : str, optional
278
- The base directory where the data will be saved. The default is os.path.join(Path.home(), 'PyThea').
287
+ The base directory where the data will be saved. The default is database_dir_default from PyThea.config.
279
288
 
280
289
  Returns
281
290
  -------
@@ -340,6 +349,8 @@ def load_fits(files):
340
349
  for file_path in files:
341
350
  try:
342
351
  map_ = sunpy.map.Map(file_path)
352
+ if isinstance(map_, list): # Added because of METIS
353
+ map_ = map_[0]
343
354
  map_.meta['fits_file'] = os.path.basename(file_path)
344
355
  maps_.append(map_)
345
356
  except RuntimeError as err:
@@ -0,0 +1,94 @@
1
+ """
2
+ PyThea: A software package to reconstruct the 3D structure of CMEs and
3
+ shock waves using multi-viewpoint remote-sensing observations.
4
+ Copyright (C) 2021 Athanasios Kouloumvakos
5
+
6
+ This program is free software: you can redistribute it and/or modify
7
+ it under the terms of the GNU General Public License as published by
8
+ the Free Software Foundation, either version 3 of the License, or
9
+ (at your option) any later version.
10
+
11
+ This program is distributed in the hope that it will be useful,
12
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
+ GNU General Public License for more details.
15
+
16
+ You should have received a copy of the GNU General Public License
17
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
18
+ """
19
+
20
+ import collections.abc
21
+ import json
22
+ import os
23
+ import re
24
+
25
+ from PyThea.config import database_dir_default
26
+ from PyThea.config.selected_imagers import imager_dict
27
+ from PyThea.utils import download_fits
28
+
29
+
30
+ def create_nested_dict(k, v):
31
+ if len(k) == 0:
32
+ return v
33
+ else:
34
+ return {k[0]: create_nested_dict(k[1:], v)}
35
+
36
+
37
+ def load_nested_dict(k, d):
38
+ if len(k) == 0:
39
+ return d
40
+ else:
41
+ if k[0] in d:
42
+ return load_nested_dict(k[1:], d[k[0]])
43
+ else:
44
+ return None
45
+
46
+
47
+ def update_nested_dict(d, u):
48
+ for k, v in u.items():
49
+ if isinstance(v, collections.abc.Mapping):
50
+ d[k] = update_nested_dict(d.get(k, {}), v)
51
+ else:
52
+ d[k] = v
53
+ return d
54
+
55
+
56
+ def get_fits_filenames_from_database(event_id, timerange, imager):
57
+
58
+ db_args = [imager_dict[imager]['source'],
59
+ imager_dict[imager]['instrument'],
60
+ imager_dict[imager].get('detector', imager_dict[imager].get('wavelength'))]
61
+
62
+ # name of the JSON file with the database
63
+ file_id = re.search(r'D(.*?)(?=T)', event_id).group(1)
64
+ filename = os.path.join(database_dir_default, 'data_manager', f'{file_id}_fits_filenames.json')
65
+
66
+ if not os.path.isfile(filename):
67
+ # create file if it doesn't exist
68
+ with open(filename, 'w') as f:
69
+ json.dump({}, f)
70
+
71
+ # load data from file
72
+ with open(filename, 'r') as f:
73
+ database_data = json.load(f)
74
+
75
+ downloaded_files = None
76
+
77
+ if str(timerange) in database_data:
78
+ downloaded_files = load_nested_dict(db_args, database_data[str(timerange)])
79
+
80
+ if downloaded_files is None:
81
+ downloaded_files = download_fits(timerange, imager)
82
+ if not downloaded_files:
83
+ return None
84
+ nested_dict_ = create_nested_dict(db_args, downloaded_files.data)
85
+ nested_dict_ = {str(timerange): nested_dict_}
86
+
87
+ # dictionary stored in JSON file
88
+ database_data = update_nested_dict(database_data, nested_dict_)
89
+
90
+ # write updated data to file
91
+ with open(filename, 'w') as f:
92
+ json.dump(database_data, f, indent=4)
93
+
94
+ return downloaded_files
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: PyThea
3
- Version: 0.13.0
3
+ Version: 1.0.0
4
4
  Summary: PyThea: A software package to reconstruct the 3D structure of CMEs and shock waves
5
5
  Home-page: https://github.com/AthKouloumvakos/PyThea
6
6
  Author: Athanasios Kouloumvakos
@@ -29,6 +29,7 @@ Requires-Dist: astroquery
29
29
  Requires-Dist: jplephem
30
30
  Requires-Dist: numexpr
31
31
  Requires-Dist: sunpy==5.1.2
32
+ Requires-Dist: sunpy_soar
32
33
  Requires-Dist: parfive==2.1.0
33
34
  Requires-Dist: pooch
34
35
  Requires-Dist: matplotlib
@@ -53,7 +54,7 @@ Requires-Dist: pytest-mpl
53
54
  ![flake8](https://github.com/AthKouloumvakos/PyThea/actions/workflows/flake8.yml/badge.svg)
54
55
  ![pytest](https://github.com/AthKouloumvakos/PyThea/actions/workflows/pytest.yml/badge.svg)
55
56
 
56
- _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO) and Solar Terrestrial Relations Observatory (STEREO).
57
+ _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO), Solar Terrestrial Relations Observatory (STEREO), and Parker Solar Probe.
57
58
 
58
59
  ## 💾 Installation
59
60
 
@@ -152,3 +153,7 @@ If you use _PyThea_ for scientific work or research presented in a publication,
152
153
  ## ⓘ The mythology of Thea:
153
154
 
154
155
  In Greek mythology, Thea, also called Euryphaessa "wide-shining", is the Titaness of sight and the shining light of the clear blue sky. Her brother/consort is Hyperion, a Titan and god of the sun, and together they are the parents of Helios (the Sun), Selene (the Moon), and Eos (the Dawn).
156
+
157
+ ## Development Support:
158
+
159
+ The lead author of this software package Athanasios Kouloumvakos acknowledges financial support from NASA Grant 80NSSC24K0071 for the further development and improvement of PyThea during 2024. This grant was part of the NASA Headquarters Heliophysics Tools and Methods Program in response to NASA ROSES–2022 (NNH22ZDA001N).
@@ -17,6 +17,7 @@ PyThea/geometrical_models.py
17
17
  PyThea/modules.py
18
18
  PyThea/pythea_cli.py
19
19
  PyThea/utils.py
20
+ PyThea/utils_database.py
20
21
  PyThea/version.py
21
22
  PyThea.egg-info/.DS_Store
22
23
  PyThea.egg-info/PKG-INFO
@@ -7,6 +7,7 @@ astroquery
7
7
  jplephem
8
8
  numexpr
9
9
  sunpy==5.1.2
10
+ sunpy_soar
10
11
  parfive==2.1.0
11
12
  pooch
12
13
  matplotlib
@@ -10,10 +10,7 @@
10
10
 
11
11
  ![Logo](https://github.com/AthKouloumvakos/PyThea/blob/master/docs/logo/pythea_logo.png)
12
12
 
13
- _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO) and Solar Terrestrial Relations Observatory (STEREO).
14
-
15
- > [!NOTE]
16
- > The lead author of PyThea (A. Kouloumvakos) has been awarded a NASA Grant (80NSSC24K0071) for further developing and improving PyThea, during fiscal year 2024. The awarded proposal is part of the NASA Headquarters Heliophysics Tools and Methods Program in response to NASA ROSES–2022 (NNH22ZDA001N). The proposed software enhancements and new features encompass a range of improvements, including but not limited to: improved code documentation, expanded and improved code testing, improved image processing and visualization, and the incorporation of new solar mission imaging data.
13
+ _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO), Solar Terrestrial Relations Observatory (STEREO), and Parker Solar Probe.
17
14
 
18
15
  ## 💾 Installation
19
16
 
@@ -112,3 +109,7 @@ If you use _PyThea_ for scientific work or research presented in a publication,
112
109
  ## ⓘ The mythology of Thea:
113
110
 
114
111
  In Greek mythology, Thea, also called Euryphaessa "wide-shining", is the Titaness of sight and the shining light of the clear blue sky. Her brother/consort is Hyperion, a Titan and god of the sun, and together they are the parents of Helios (the Sun), Selene (the Moon), and Eos (the Dawn).
112
+
113
+ ## Development Support:
114
+
115
+ The lead author of this software package Athanasios Kouloumvakos acknowledges financial support from NASA Grant 80NSSC24K0071 for the further development and improvement of PyThea during 2024. This grant was part of the NASA Headquarters Heliophysics Tools and Methods Program in response to NASA ROSES–2022 (NNH22ZDA001N).
@@ -7,7 +7,7 @@
7
7
  ![flake8](https://github.com/AthKouloumvakos/PyThea/actions/workflows/flake8.yml/badge.svg)
8
8
  ![pytest](https://github.com/AthKouloumvakos/PyThea/actions/workflows/pytest.yml/badge.svg)
9
9
 
10
- _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO) and Solar Terrestrial Relations Observatory (STEREO).
10
+ _PyThea_ is an open-source software package that can be used to reconstruct the 3D structure of Coronal Mass Ejections (CMEs) and shock waves and determine their kinematics using remote-sensing observations. The tool implements the Graduated Cylindrical Shell (GCS) model that can be used to reconstruct CMEs and two geometrical models, namely a spheroid and ellipsoid model to reconstruct shock waves. It also implements remote-sensing observations from multiple viewpoints such as the Solar and Heliospheric Observatory (SoHO), Solar Terrestrial Relations Observatory (STEREO), and Parker Solar Probe.
11
11
 
12
12
  ## 💾 Installation
13
13
 
@@ -106,3 +106,7 @@ If you use _PyThea_ for scientific work or research presented in a publication,
106
106
  ## ⓘ The mythology of Thea:
107
107
 
108
108
  In Greek mythology, Thea, also called Euryphaessa "wide-shining", is the Titaness of sight and the shining light of the clear blue sky. Her brother/consort is Hyperion, a Titan and god of the sun, and together they are the parents of Helios (the Sun), Selene (the Moon), and Eos (the Dawn).
109
+
110
+ ## Development Support:
111
+
112
+ The lead author of this software package Athanasios Kouloumvakos acknowledges financial support from NASA Grant 80NSSC24K0071 for the further development and improvement of PyThea during 2024. This grant was part of the NASA Headquarters Heliophysics Tools and Methods Program in response to NASA ROSES–2022 (NNH22ZDA001N).
@@ -27,3 +27,4 @@ dependencies:
27
27
  - pip:
28
28
  - pooch
29
29
  - jplephem
30
+ - sunpy_soar
@@ -7,6 +7,7 @@ astroquery
7
7
  jplephem
8
8
  numexpr
9
9
  sunpy==5.1.2
10
+ sunpy_soar
10
11
  parfive==2.1.0
11
12
  pooch
12
13
  matplotlib
@@ -11,6 +11,7 @@ from setuptools import find_packages, setup
11
11
  if not os.path.isdir(os.path.join(Path.home(), 'PyThea')):
12
12
  os.mkdir(os.path.join(Path.home(), 'PyThea'))
13
13
  os.mkdir(os.path.join(Path.home(), 'PyThea', 'data'))
14
+ os.mkdir(os.path.join(Path.home(), 'PyThea', 'data_manager'))
14
15
 
15
16
  with open('README_pypi.md', 'r', encoding='utf8') as f:
16
17
  long_description = f.read()
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes