PyThea 0.10.0__tar.gz → 0.11.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.
- {pythea-0.10.0 → pythea-0.11.0}/CHANGELOG.md +10 -0
- {pythea-0.10.0/PyThea.egg-info → pythea-0.11.0}/PKG-INFO +3 -1
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/PyThea_app.py +5 -2
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/_version.py +2 -2
- pythea-0.11.0/PyThea/data/sample_data.py +35 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/pythea_cli.py +21 -2
- pythea-0.11.0/PyThea/test/figure_hashes.json +6 -0
- pythea-0.11.0/PyThea/test/test_figures.py +169 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/test_imports.py +4 -1
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/test_utils.py +47 -3
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/utils.py +1 -4
- {pythea-0.10.0 → pythea-0.11.0/PyThea.egg-info}/PKG-INFO +3 -1
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/SOURCES.txt +2 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/requires.txt +2 -0
- {pythea-0.10.0 → pythea-0.11.0}/environment.yml +2 -0
- {pythea-0.10.0 → pythea-0.11.0}/requirements.txt +2 -0
- pythea-0.10.0/PyThea/data/sample_data.py +0 -15
- {pythea-0.10.0 → pythea-0.11.0}/LICENSE.md +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/MANIFEST.in +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/callbacks.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/config/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/config/app_styles.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/config/config_sliders.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/config/selected_bodies.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/config/selected_imagers.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/data/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/extensions/LICENSE_gcs_python.md +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/extensions/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/extensions/buttons.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/geometrical_models.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/modules.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/aia/utils.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/utils.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/utils.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/map/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/map/maputils.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/Pythea_test.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/__init__.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/conftest.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/test_geometrical_models.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/test/test_remote_clients.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea/version.py +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/.DS_Store +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/dependency_links.txt +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/entry_points.txt +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/not-zip-safe +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/PyThea.egg-info/top_level.txt +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/README.md +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/README_pypi.md +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/pyproject.toml +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/setup.cfg +0 -0
- {pythea-0.10.0 → pythea-0.11.0}/setup.py +0 -0
|
@@ -1,3 +1,13 @@
|
|
|
1
|
+
# v0.11.0 (17-April-2024)
|
|
2
|
+
|
|
3
|
+
## Features
|
|
4
|
+
- Adds tests for ellipsoid location on AIA and STEREO COR images.
|
|
5
|
+
- Adds test_load_fitting_json_file to check the fitting file load and save.
|
|
6
|
+
- Improve PyThea tests on cli.
|
|
7
|
+
|
|
8
|
+
## Major Changes
|
|
9
|
+
- Change the inputs for download_fits from string dates to timerange.
|
|
10
|
+
|
|
1
11
|
# v0.10.0 (17-April-2024)
|
|
2
12
|
|
|
3
13
|
## Features
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyThea
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.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
|
|
@@ -26,6 +26,7 @@ Requires-Dist: scipy
|
|
|
26
26
|
Requires-Dist: aiapy
|
|
27
27
|
Requires-Dist: astropy
|
|
28
28
|
Requires-Dist: astroquery
|
|
29
|
+
Requires-Dist: jplephem
|
|
29
30
|
Requires-Dist: numexpr
|
|
30
31
|
Requires-Dist: sunpy==5.1.2
|
|
31
32
|
Requires-Dist: parfive==2.1.0
|
|
@@ -42,6 +43,7 @@ Requires-Dist: tqdm
|
|
|
42
43
|
Requires-Dist: pyvista
|
|
43
44
|
Requires-Dist: pytest-astropy
|
|
44
45
|
Requires-Dist: pytest-sugar
|
|
46
|
+
Requires-Dist: pytest-mpl
|
|
45
47
|
|
|
46
48
|
# PyThea: A software package to reconstruct the 3D structure of CMEs and shock waves
|
|
47
49
|
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
"""
|
|
19
19
|
|
|
20
20
|
|
|
21
|
+
import datetime
|
|
21
22
|
from copy import copy
|
|
22
23
|
|
|
23
24
|
import astropy.units as u
|
|
@@ -26,6 +27,7 @@ import stqdm # See also https://github.com/tqdm/tqdm
|
|
|
26
27
|
import streamlit as st
|
|
27
28
|
from astropy.coordinates import Distance, SkyCoord, SphericalRepresentation
|
|
28
29
|
from sunpy.coordinates import frames
|
|
30
|
+
from sunpy.net import attrs as a
|
|
29
31
|
|
|
30
32
|
from PyThea.callbacks import load_or_delete_fittings
|
|
31
33
|
from PyThea.config import (app_styles, config_sliders, selected_bodies,
|
|
@@ -247,8 +249,9 @@ def run():
|
|
|
247
249
|
for imager in progress_bar:
|
|
248
250
|
progress_bar.desc = f'Downloaded {imager} images from VSO'
|
|
249
251
|
if imager not in st.session_state.map_:
|
|
250
|
-
|
|
251
|
-
|
|
252
|
+
timerange = a.Time(st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[0]),
|
|
253
|
+
st.session_state.date_process + datetime.timedelta(hours=imaging_time_range[1]))
|
|
254
|
+
st.session_state.map_[imager] = download_fits(timerange, imager)
|
|
252
255
|
st.session_state.map_[imager] = single_imager_maps_process(st.session_state.map_[imager],
|
|
253
256
|
**selected_imagers.imager_dict[imager][1],
|
|
254
257
|
skip='sequence_processing')
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
|
|
4
|
+
import pooch
|
|
5
|
+
|
|
6
|
+
database_dir = os.path.join(Path.home(), 'PyThea')
|
|
7
|
+
github_main_url = 'https://github.com/AthKouloumvakos/PyThea-sample-data'
|
|
8
|
+
|
|
9
|
+
aia_sample_data = pooch.create(
|
|
10
|
+
path=os.path.join(database_dir, 'sample_data'), # The cache folder
|
|
11
|
+
base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
|
|
12
|
+
registry={
|
|
13
|
+
'aia_lev1_1600a_2012_06_06t04_07_29_12z_image_lev1.fits': 'sha256:7e88d8a277ad3dd111c1bcff3c3936d6d5ef5186e05b4bfa7749ee43c05577d5',
|
|
14
|
+
'aia_lev1_1600a_2016_05_09t11_35_51_12z_image_lev1.fits': 'sha256:1c3bb938e9bfb3178cecead1319a92fa661eb70469715a441a849a98039f0b61'
|
|
15
|
+
},
|
|
16
|
+
)
|
|
17
|
+
|
|
18
|
+
stereo_sample_data = pooch.create(
|
|
19
|
+
path=os.path.join(database_dir, 'sample_data'), # The cache folder
|
|
20
|
+
base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
|
|
21
|
+
registry={
|
|
22
|
+
'20120622_235400_d4c2a.fts': 'sha256:940680fe8bea754c9859170585d8299b9b049b631155435a31ecacf5b702d9cf',
|
|
23
|
+
'20140221_235400_d4c2b.fts': 'sha256:13638dedeb2e510c9e2ef11d46b372acb16f9b9645ca1cabf4d0ef8444353adc',
|
|
24
|
+
'20070503_102018_s4c1a.fts': 'sha256:55cf6e3741833a82e41b46e2345bf85a0e5580a2832900eccc41f235d36fc31e',
|
|
25
|
+
'20070503_102018_s4c1b.fts': 'sha256:ca8f4aabaeb7e4bc6f4e5d4819057ddfe3f9f621716224d11acc80d701e3beb8'
|
|
26
|
+
},
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
json_fitting_file_sample_data = pooch.create(
|
|
30
|
+
path=os.path.join(database_dir, 'sample_data'), # The cache folder
|
|
31
|
+
base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
|
|
32
|
+
registry={
|
|
33
|
+
'FLX1p0D20211028T153500MEllipsoid.json': 'sha256:700687ed982317400ec409390571747694237de9688a2816baa7b1770b75c9b1',
|
|
34
|
+
},
|
|
35
|
+
)
|
|
@@ -99,9 +99,28 @@ def update():
|
|
|
99
99
|
|
|
100
100
|
|
|
101
101
|
@main.command('test')
|
|
102
|
-
|
|
102
|
+
@click.option('--mpl', is_flag=True, default=False, help='Run the test including figure tests.')
|
|
103
|
+
@click.option('--remote-data', is_flag=True, default=False, help='Run the test including figure tests.')
|
|
104
|
+
@click.option('--all', is_flag=True, default=False, help='Run the test including figure tests.')
|
|
105
|
+
def main_test(mpl, remote_data, all):
|
|
103
106
|
"""Test PyThea."""
|
|
104
|
-
|
|
107
|
+
|
|
108
|
+
test_directory = os.path.dirname(__file__)
|
|
109
|
+
|
|
110
|
+
print(f'Running a test of PyThea package located in: {test_directory}')
|
|
111
|
+
|
|
112
|
+
if mpl:
|
|
113
|
+
# Run a test of the package including figure tests
|
|
114
|
+
pytest.main(['-W', 'ignore', '--mpl', '--mpl-hash-library=figure_hashes.json', '--pyargs', f'{test_directory}'])
|
|
115
|
+
elif remote_data:
|
|
116
|
+
# Run a test of the package including remote-data tests
|
|
117
|
+
pytest.main(['-W', 'ignore', '--remote-data', '--pyargs', f'{test_directory}'])
|
|
118
|
+
elif all:
|
|
119
|
+
# Run a test of the package including remote-data tests
|
|
120
|
+
pytest.main(['-W', 'ignore', '--mpl', '--mpl-hash-library=figure_hashes.json', '--remote-data', '--pyargs', f'{test_directory}'])
|
|
121
|
+
else:
|
|
122
|
+
# Run a minimum test of the package (figure tests are always true and remote-data tests are skipped)
|
|
123
|
+
pytest.main(['-W', 'ignore', '--pyargs', f'{test_directory}'])
|
|
105
124
|
|
|
106
125
|
|
|
107
126
|
if __name__ == '__main__':
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
{
|
|
2
|
+
"PyThea.test.test_figures.test_ellipsoid_on_AIA_venus": "f1ff774b483a8c934c9353c552278c8823216fc7d9dad4ccc00c74be3f30c4c3",
|
|
3
|
+
"PyThea.test.test_figures.test_ellipsoid_on_AIA_mercury": "f6afda1c769a061b7ab1fc64c4e9c0f4658cdb97c3be83828ba5d98bf1bb182c",
|
|
4
|
+
"PyThea.test.test_figures.test_ellipsoid_on_STEREO_COR1_venus": "18a3af72e9da5b60e435f83ee3ef3f8cd0eb437eaef463329552ff56968f12ff",
|
|
5
|
+
"PyThea.test.test_figures.test_ellipsoid_on_STEREO_COR2_three_planets": "231d5635f57c4d66556674a83f6cbcef7dc94b51846e977c4c2dc3dc244096ac"
|
|
6
|
+
}
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
import astropy.units as u
|
|
2
|
+
import matplotlib.pyplot as plt
|
|
3
|
+
import pytest
|
|
4
|
+
import sunpy.map
|
|
5
|
+
from astropy.coordinates import SkyCoord, solar_system_ephemeris
|
|
6
|
+
from sunpy.coordinates import get_body_heliographic_stonyhurst
|
|
7
|
+
|
|
8
|
+
from PyThea.data.sample_data import aia_sample_data, stereo_sample_data
|
|
9
|
+
from PyThea.geometrical_models import ellipsoid
|
|
10
|
+
from PyThea.sunpy_dev.map.maputils import prepare_maps
|
|
11
|
+
|
|
12
|
+
solar_system_ephemeris.set('de432s')
|
|
13
|
+
|
|
14
|
+
bodies_color_dict = {'mercury': 'darkturquoise',
|
|
15
|
+
'venus': 'darkorchid',
|
|
16
|
+
'earth': 'green',
|
|
17
|
+
'mars': 'maroon',
|
|
18
|
+
'jupiter': 'navy',
|
|
19
|
+
'saturn': 'dodgerblue'}
|
|
20
|
+
|
|
21
|
+
body_radious = {'mercury': 2440.5 * u.km,
|
|
22
|
+
'venus': 6051.8 * u.km,
|
|
23
|
+
'mars': 3396.2 * u.km,
|
|
24
|
+
'jupiter': 71492 * u.km,
|
|
25
|
+
'saturn': 60268 * u.km} # From here: https://nssdc.gsfc.nasa.gov/planetary/factsheet/venusfact.html
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
def model_from_body(body, date, observer_coordinate):
|
|
29
|
+
body_coord = get_body_heliographic_stonyhurst(body, date, observer=observer_coordinate)
|
|
30
|
+
radius = body_radious[body]
|
|
31
|
+
center = SkyCoord(body_coord)
|
|
32
|
+
return ellipsoid(center, radius, radius, radius, 0 * u.degree)
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def make_submap(map_, center, fov):
|
|
36
|
+
center_hpc = center.transform_to(map_.coordinate_frame)
|
|
37
|
+
print(center_hpc)
|
|
38
|
+
bottom_left = SkyCoord(center_hpc.Tx - fov/2, center_hpc.Ty - fov/2, frame=map_.coordinate_frame)
|
|
39
|
+
return map_.submap(bottom_left, width=fov, height=fov)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
@pytest.mark.mpl_image_compare()
|
|
43
|
+
def test_ellipsoid_on_AIA_venus():
|
|
44
|
+
"""
|
|
45
|
+
Tests that the position of Venus is ploted correct at SDO/AIA images when it transited in front of the Sun.
|
|
46
|
+
"""
|
|
47
|
+
fits_file = aia_sample_data.fetch('aia_lev1_1600a_2012_06_06t04_07_29_12z_image_lev1.fits')
|
|
48
|
+
|
|
49
|
+
map_ = sunpy.map.Map(fits_file, sequence=True)
|
|
50
|
+
map_ = prepare_maps(map_)[0]
|
|
51
|
+
|
|
52
|
+
model_shock = model_from_body('venus', map_.date_average, map_.observer_coordinate)
|
|
53
|
+
smap = make_submap(map_, model_shock.center, fov=200*u.arcsec)
|
|
54
|
+
|
|
55
|
+
fig = plt.figure(dpi=200)
|
|
56
|
+
ax = fig.add_subplot(projection=smap)
|
|
57
|
+
smap.plot(axes=ax)
|
|
58
|
+
smap.draw_limb(axes=ax)
|
|
59
|
+
ax.grid(False)
|
|
60
|
+
model_shock.plot(ax, mode='Full')
|
|
61
|
+
ax.set_xlim([0, smap.data.shape[0]])
|
|
62
|
+
ax.set_ylim([0, smap.data.shape[1]])
|
|
63
|
+
|
|
64
|
+
return fig
|
|
65
|
+
|
|
66
|
+
|
|
67
|
+
@pytest.mark.mpl_image_compare()
|
|
68
|
+
def test_ellipsoid_on_AIA_mercury():
|
|
69
|
+
"""
|
|
70
|
+
Tests that the position of Mercury is ploted correct at SDO/AIA images when it transited in front of the Sun.
|
|
71
|
+
"""
|
|
72
|
+
fits_file = aia_sample_data.fetch('aia_lev1_1600a_2016_05_09t11_35_51_12z_image_lev1.fits')
|
|
73
|
+
|
|
74
|
+
map_ = sunpy.map.Map(fits_file, sequence=True)
|
|
75
|
+
map_ = prepare_maps(map_)[0]
|
|
76
|
+
|
|
77
|
+
model_shock = model_from_body('mercury', map_.date_average, map_.observer_coordinate)
|
|
78
|
+
smap = make_submap(map_, model_shock.center, fov=100*u.arcsec)
|
|
79
|
+
|
|
80
|
+
fig = plt.figure(dpi=200)
|
|
81
|
+
ax = fig.add_subplot(projection=smap)
|
|
82
|
+
smap.plot(axes=ax)
|
|
83
|
+
smap.draw_limb(axes=ax)
|
|
84
|
+
ax.grid(False)
|
|
85
|
+
model_shock.plot(ax, mode='Full')
|
|
86
|
+
ax.set_xlim([0, smap.data.shape[0]])
|
|
87
|
+
ax.set_ylim([0, smap.data.shape[1]])
|
|
88
|
+
|
|
89
|
+
return fig
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
@pytest.mark.mpl_image_compare()
|
|
93
|
+
def test_ellipsoid_on_STEREO_COR1_venus():
|
|
94
|
+
"""
|
|
95
|
+
Tests that the position of Venus is correct at STEREO COR1 images. (https://stereo.gsfc.nasa.gov/browse/2019/03/08/planets/)
|
|
96
|
+
"""
|
|
97
|
+
fits_file = [stereo_sample_data.fetch('20070503_102018_s4c1b.fts'),
|
|
98
|
+
stereo_sample_data.fetch('20070503_102018_s4c1a.fts')]
|
|
99
|
+
|
|
100
|
+
maps = sunpy.map.Map(fits_file, sequence=True)
|
|
101
|
+
maps = prepare_maps(maps, polar=True)
|
|
102
|
+
|
|
103
|
+
fig = plt.figure(figsize=(10, 5), dpi=200)
|
|
104
|
+
|
|
105
|
+
for i, map_ in enumerate(maps):
|
|
106
|
+
axis = fig.add_subplot(int(120+i+1), projection=map_)
|
|
107
|
+
|
|
108
|
+
map_.plot(axes=axis)
|
|
109
|
+
map_.draw_limb(axes=axis)
|
|
110
|
+
axis.grid(False)
|
|
111
|
+
|
|
112
|
+
model_shock = model_from_body('mercury', map_.date_average, map_.observer_coordinate)
|
|
113
|
+
axis.plot_coord(model_shock.center, 'o', color='tab:red', fillstyle='none', markersize=8)
|
|
114
|
+
x = map_.world_to_pixel(model_shock.center)[0].value
|
|
115
|
+
y = map_.world_to_pixel(model_shock.center)[1].value+40
|
|
116
|
+
axis.annotate('Mercury', (x, y), xytext=(x, y),
|
|
117
|
+
backgroundcolor='none', color='Black', fontsize=8,
|
|
118
|
+
horizontalalignment='center', verticalalignment='bottom')
|
|
119
|
+
|
|
120
|
+
lon, lat = axis.coords
|
|
121
|
+
lon .set_major_formatter('d.dd')
|
|
122
|
+
lat.set_major_formatter('d.dd')
|
|
123
|
+
|
|
124
|
+
axis.set_xlim([0, map_.data.shape[0]])
|
|
125
|
+
axis.set_ylim([0, map_.data.shape[1]])
|
|
126
|
+
|
|
127
|
+
fig.subplots_adjust(hspace=0.5, wspace=0.35)
|
|
128
|
+
|
|
129
|
+
return fig
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.mark.mpl_image_compare()
|
|
133
|
+
def test_ellipsoid_on_STEREO_COR2_three_planets():
|
|
134
|
+
"""
|
|
135
|
+
Tests that the position of three planets is correct at STEREO COR2 images. (https://stereo.gsfc.nasa.gov/browse/2021/06/22/planets/)
|
|
136
|
+
"""
|
|
137
|
+
fits_file = [stereo_sample_data.fetch('20120622_235400_d4c2a.fts'),
|
|
138
|
+
stereo_sample_data.fetch('20140221_235400_d4c2b.fts')]
|
|
139
|
+
|
|
140
|
+
maps = sunpy.map.Map(fits_file, sequence=True)
|
|
141
|
+
maps = prepare_maps(maps)
|
|
142
|
+
|
|
143
|
+
fig = plt.figure(figsize=(10, 5), dpi=200)
|
|
144
|
+
|
|
145
|
+
for i, map_ in enumerate(maps):
|
|
146
|
+
axis = fig.add_subplot(int(120+i+1), projection=map_)
|
|
147
|
+
|
|
148
|
+
map_.plot(axes=axis, vmin=300, vmax=3000)
|
|
149
|
+
map_.draw_limb(axes=axis)
|
|
150
|
+
axis.grid(False)
|
|
151
|
+
|
|
152
|
+
for body in ['mercury', 'venus', 'mars', 'saturn']:
|
|
153
|
+
model_shock = model_from_body(body, map_.date_average, map_.observer_coordinate)
|
|
154
|
+
axis.plot_coord(model_shock.center, 'o', color=bodies_color_dict[body], fillstyle='none', markersize=8)
|
|
155
|
+
x = map_.world_to_pixel(model_shock.center)[0].value
|
|
156
|
+
y = map_.world_to_pixel(model_shock.center)[1].value+40
|
|
157
|
+
axis.annotate(body.capitalize(), (x, y), xytext=(x, y),
|
|
158
|
+
backgroundcolor='none', color='Black', fontsize=8,
|
|
159
|
+
horizontalalignment='center', verticalalignment='bottom')
|
|
160
|
+
lon, lat = axis.coords
|
|
161
|
+
lon .set_major_formatter('d.dd')
|
|
162
|
+
lat.set_major_formatter('d.dd')
|
|
163
|
+
|
|
164
|
+
axis.set_xlim([0, map_.data.shape[0]])
|
|
165
|
+
axis.set_ylim([0, map_.data.shape[1]])
|
|
166
|
+
|
|
167
|
+
fig.subplots_adjust(hspace=0.5, wspace=0.35)
|
|
168
|
+
|
|
169
|
+
return fig
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import os
|
|
1
2
|
import pkgutil
|
|
2
3
|
|
|
3
4
|
|
|
@@ -23,6 +24,8 @@ def test_imports_all():
|
|
|
23
24
|
except Warning:
|
|
24
25
|
pass
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
test_directory = os.path.dirname(__file__)
|
|
28
|
+
|
|
29
|
+
for imper, nm, ispkg in pkgutil.walk_packages([f'{test_directory}'], 'PyThea.',
|
|
27
30
|
onerror=on_error):
|
|
28
31
|
imper.find_spec(nm)
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Test the utilities
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import json
|
|
5
6
|
from datetime import datetime
|
|
6
7
|
|
|
7
8
|
import matplotlib.dates as mdates
|
|
@@ -12,7 +13,8 @@ from sunpy.coordinates.frames import HeliographicStonyhurst
|
|
|
12
13
|
from sunpy.net import hek
|
|
13
14
|
|
|
14
15
|
from PyThea.config.selected_bodies import bodies_dict
|
|
15
|
-
from PyThea.
|
|
16
|
+
from PyThea.data.sample_data import json_fitting_file_sample_data
|
|
17
|
+
from PyThea.utils import get_hek_flare, model_fittings, parameter_fit
|
|
16
18
|
|
|
17
19
|
|
|
18
20
|
def test_get_hek_flare():
|
|
@@ -20,17 +22,59 @@ def test_get_hek_flare():
|
|
|
20
22
|
Test that the get_hek_flare returns a hek.hek.HEKTable and the results are formated correct.
|
|
21
23
|
"""
|
|
22
24
|
# This test requests the flare info for a date that returns a list of flares and compares against previous results
|
|
23
|
-
selectbox_list, flare_list = get_hek_flare(datetime(2017, 9, 10))
|
|
25
|
+
selectbox_list, flare_list = get_hek_flare(datetime(2017, 9, 10, 0, 0, 0))
|
|
24
26
|
assert type(flare_list) == hek.hek.HEKTable
|
|
25
27
|
assert selectbox_list == ['FLM1.1|2017-09-09T23:53:00', 'FLC9.0|2017-09-10T03:09:00', 'FLC2.9|2017-09-10T09:20:00',
|
|
26
28
|
'FLC1.6|2017-09-10T14:23:00', 'FLC1.0|2017-09-10T15:26:00', 'FLX8.2|2017-09-10T16:06:00']
|
|
27
29
|
|
|
28
30
|
# This test requests the flare info for a date that returns an empty list
|
|
29
|
-
selectbox_list, flare_list = get_hek_flare(datetime(
|
|
31
|
+
selectbox_list, flare_list = get_hek_flare(datetime(2030, 9, 10, 0, 0, 0))
|
|
30
32
|
assert flare_list == []
|
|
31
33
|
assert selectbox_list == ['No events returned']
|
|
32
34
|
|
|
33
35
|
|
|
36
|
+
def test_load_fitting_json_file():
|
|
37
|
+
"""
|
|
38
|
+
Tests that the load_fitting_json_file returns the model_fittings class and storing it to the model_fittings
|
|
39
|
+
will return the same result as the model_fittings.to_json().
|
|
40
|
+
"""
|
|
41
|
+
def compare_json_objects(obj1, obj2, path='', exclude=['date_created', 'version']):
|
|
42
|
+
if exclude:
|
|
43
|
+
for key in exclude:
|
|
44
|
+
obj1.pop(key, None)
|
|
45
|
+
obj2.pop(key, None)
|
|
46
|
+
|
|
47
|
+
for key in set(obj1.keys()) | set(obj2.keys()):
|
|
48
|
+
new_path = f'{path}.{key}' if path else key
|
|
49
|
+
|
|
50
|
+
if key not in obj1 or key not in obj2:
|
|
51
|
+
print(f"Key '{new_path}' is not present in one of the objects.")
|
|
52
|
+
return False
|
|
53
|
+
elif obj1[key] != obj2[key]:
|
|
54
|
+
if isinstance(obj1[key], dict) and isinstance(obj2[key], dict):
|
|
55
|
+
check = compare_json_objects(obj1[key], obj2[key], path=new_path)
|
|
56
|
+
if not check:
|
|
57
|
+
return False
|
|
58
|
+
else:
|
|
59
|
+
print(f"Value mismatch at key '{new_path}': {obj1[key]} != {obj2[key]}")
|
|
60
|
+
return False
|
|
61
|
+
|
|
62
|
+
return True
|
|
63
|
+
|
|
64
|
+
json_fitting_file = json_fitting_file_sample_data.fetch('FLX1p0D20211028T153500MEllipsoid.json')
|
|
65
|
+
with open(json_fitting_file, 'r') as file:
|
|
66
|
+
json_content = file.read()
|
|
67
|
+
fitting_from_json = json.loads(json_content)
|
|
68
|
+
|
|
69
|
+
model_fittings_class = model_fittings.load_from_json(json_fitting_file)
|
|
70
|
+
model_fittings_class_dict = json.loads(model_fittings_class.to_json())
|
|
71
|
+
assert isinstance(model_fittings_class, model_fittings)
|
|
72
|
+
assert model_fittings_class.event_selected == 'FLX1.0|2021-10-28T15:35:00'
|
|
73
|
+
assert model_fittings_class.date_process == '2021-10-28T15:35:00.000000'
|
|
74
|
+
assert model_fittings_class.geometrical_model == 'Ellipsoid'
|
|
75
|
+
assert compare_json_objects(model_fittings_class_dict, fitting_from_json)
|
|
76
|
+
|
|
77
|
+
|
|
34
78
|
def test_get_horizons_coord():
|
|
35
79
|
"""
|
|
36
80
|
Test that get_horizons_coord returns a Skycoord instance, in HeliographicStonyhurst frame, and returns the same coordinates every time.
|
|
@@ -170,13 +170,10 @@ def plot_solar_reference_lines(axis, bodies_list, smap, mode='Limb from Obs.'):
|
|
|
170
170
|
smap.draw_grid(linewidth=1, color='red', system='carrington', alpha=0.8)
|
|
171
171
|
|
|
172
172
|
|
|
173
|
-
def download_fits(
|
|
173
|
+
def download_fits(timerange, imager):
|
|
174
174
|
'''
|
|
175
175
|
Downloads the imaging data (fits files) from VSO
|
|
176
176
|
'''
|
|
177
|
-
timerange = a.Time(date_process + datetime.timedelta(hours=time_range[0]),
|
|
178
|
-
date_process + datetime.timedelta(hours=time_range[1]))
|
|
179
|
-
|
|
180
177
|
maps_ = []
|
|
181
178
|
args = imager_dict[imager][0]
|
|
182
179
|
result = Fido.search(timerange, *args)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: PyThea
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.11.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
|
|
@@ -26,6 +26,7 @@ Requires-Dist: scipy
|
|
|
26
26
|
Requires-Dist: aiapy
|
|
27
27
|
Requires-Dist: astropy
|
|
28
28
|
Requires-Dist: astroquery
|
|
29
|
+
Requires-Dist: jplephem
|
|
29
30
|
Requires-Dist: numexpr
|
|
30
31
|
Requires-Dist: sunpy==5.1.2
|
|
31
32
|
Requires-Dist: parfive==2.1.0
|
|
@@ -42,6 +43,7 @@ Requires-Dist: tqdm
|
|
|
42
43
|
Requires-Dist: pyvista
|
|
43
44
|
Requires-Dist: pytest-astropy
|
|
44
45
|
Requires-Dist: pytest-sugar
|
|
46
|
+
Requires-Dist: pytest-mpl
|
|
45
47
|
|
|
46
48
|
# PyThea: A software package to reconstruct the 3D structure of CMEs and shock waves
|
|
47
49
|
|
|
@@ -49,6 +49,8 @@ PyThea/sunpy_dev/map/maputils.py
|
|
|
49
49
|
PyThea/test/Pythea_test.py
|
|
50
50
|
PyThea/test/__init__.py
|
|
51
51
|
PyThea/test/conftest.py
|
|
52
|
+
PyThea/test/figure_hashes.json
|
|
53
|
+
PyThea/test/test_figures.py
|
|
52
54
|
PyThea/test/test_geometrical_models.py
|
|
53
55
|
PyThea/test/test_imports.py
|
|
54
56
|
PyThea/test/test_remote_clients.py
|
|
@@ -22,7 +22,9 @@ dependencies:
|
|
|
22
22
|
# - opencv-python-headless > Introdused to solve a libGL library error and no longe needed. https://github.com/AthKouloumvakos/PyThea/commit/24fa8a46fd4c4ee33aa84ee617d6f3e6628ac8e8
|
|
23
23
|
- pytest-astropy
|
|
24
24
|
- pytest-sugar
|
|
25
|
+
- pytest-mpl
|
|
25
26
|
- pip
|
|
26
27
|
- pip:
|
|
27
28
|
- pooch
|
|
28
29
|
- stqdm
|
|
30
|
+
- jplephem
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import os
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
|
|
4
|
-
import pooch
|
|
5
|
-
|
|
6
|
-
database_dir = os.path.join(Path.home(), 'PyThea')
|
|
7
|
-
github_main_url = 'https://github.com/AthKouloumvakos/PyThea-sample-data'
|
|
8
|
-
|
|
9
|
-
aia_sample_data = pooch.create(
|
|
10
|
-
path=os.path.join(database_dir, 'sample_data'), # The cache folder
|
|
11
|
-
base_url=f'{github_main_url}/raw/main/data/', # The remote data url on Github
|
|
12
|
-
registry={
|
|
13
|
-
'aia_lev1_1600a_2012_06_06t04_07_29_12z_image_lev1_lowres.fits': 'sha256:396b9ef5cbc1cbe2f2af806758f449cfd36f352826b61295e6330859ac7f7652',
|
|
14
|
-
},
|
|
15
|
-
)
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/lasco/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{pythea-0.10.0 → pythea-0.11.0}/PyThea/sunpy_dev/extern/sunkit_instruments/stereo/__init__.py
RENAMED
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|